Merge pull request #1394 from Fizztastic/fix_1387
Add LineEditCompleter to Tab_Game
This commit is contained in:
commit
9c28cdd1f5
7 changed files with 224 additions and 154 deletions
|
@ -97,6 +97,7 @@ SET(cockatrice_SOURCES
|
||||||
src/shortcutssettings.cpp
|
src/shortcutssettings.cpp
|
||||||
src/sequenceEdit/sequenceedit.cpp
|
src/sequenceEdit/sequenceedit.cpp
|
||||||
src/sequenceEdit/shortcutstab.cpp
|
src/sequenceEdit/shortcutstab.cpp
|
||||||
|
src/lineeditcompleter.cpp
|
||||||
${VERSION_STRING_CPP}
|
${VERSION_STRING_CPP}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
132
cockatrice/src/lineeditcompleter.cpp
Normal file
132
cockatrice/src/lineeditcompleter.cpp
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
#include <QStringListModel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QCompleter>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QTextCursor>
|
||||||
|
#include <QAbstractItemView>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QStringListModel>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QFocusEvent>
|
||||||
|
#include "lineeditcompleter.h"
|
||||||
|
|
||||||
|
LineEditCompleter::LineEditCompleter(QWidget *parent)
|
||||||
|
: QLineEdit(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineEditCompleter::focusOutEvent(QFocusEvent * e){
|
||||||
|
QLineEdit::focusOutEvent(e);
|
||||||
|
if (c->popup()->isVisible()){
|
||||||
|
//Remove Popup
|
||||||
|
c->popup()->hide();
|
||||||
|
//Truncate the line to last space or whole string
|
||||||
|
QString textValue = text();
|
||||||
|
int lastIndex = textValue.length();
|
||||||
|
int lastWordStartIndex = textValue.lastIndexOf(" ") + 1;
|
||||||
|
int leftShift = qMin(lastIndex, lastWordStartIndex);
|
||||||
|
setText(textValue.left(leftShift));
|
||||||
|
//Insert highlighted line from popup
|
||||||
|
insert(c->completionModel()->index(c->popup()->currentIndex().row(), 0).data().toString() + " ");
|
||||||
|
//Set focus back to the textbox since tab was pressed
|
||||||
|
setFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineEditCompleter::keyPressEvent(QKeyEvent * event)
|
||||||
|
{
|
||||||
|
switch (event->key()){
|
||||||
|
case Qt::Key_Return:
|
||||||
|
case Qt::Key_Enter:
|
||||||
|
case Qt::Key_Escape:
|
||||||
|
if (c->popup()->isVisible()){
|
||||||
|
event->ignore();
|
||||||
|
//Remove Popup
|
||||||
|
c->popup()->hide();
|
||||||
|
//Truncate the line to last space or whole string
|
||||||
|
QString textValue = text();
|
||||||
|
int lastIndexof = qMax(0, textValue.lastIndexOf(" "));
|
||||||
|
QString finalString = textValue.left(lastIndexof);
|
||||||
|
//Add a space if there's a word
|
||||||
|
if (finalString != "")
|
||||||
|
finalString += " ";
|
||||||
|
setText(finalString);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_Space:
|
||||||
|
if (c->popup()->isVisible()){
|
||||||
|
event->ignore();
|
||||||
|
//Remove Popup
|
||||||
|
c->popup()->hide();
|
||||||
|
//Truncate the line to last space or whole string
|
||||||
|
QString textValue = text();
|
||||||
|
int lastIndex = textValue.length();
|
||||||
|
int lastWordStartIndex = textValue.lastIndexOf(" ") + 1;
|
||||||
|
int leftShift = qMin(lastIndex, lastWordStartIndex);
|
||||||
|
setText(textValue.left(leftShift));
|
||||||
|
//Insert highlighted line from popup
|
||||||
|
insert(c->completionModel()->index(c->popup()->currentIndex().row(), 0).data().toString() + " ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit::keyPressEvent(event);
|
||||||
|
QString textValue = text();
|
||||||
|
//Wait until the first character after @
|
||||||
|
if (!c || text().right(1).contains("@"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Set new completion prefix
|
||||||
|
c->setCompletionPrefix(cursorWord(text()));
|
||||||
|
if (c->completionPrefix().length() < 1){
|
||||||
|
c->popup()->hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Draw completion box
|
||||||
|
QRect cr = cursorRect();
|
||||||
|
cr.setWidth(c->popup()->sizeHintForColumn(0) + c->popup()->verticalScrollBar()->sizeHint().width());
|
||||||
|
c->complete(cr);
|
||||||
|
|
||||||
|
//Select first item in the completion popup
|
||||||
|
QItemSelectionModel* sm = new QItemSelectionModel(c->completionModel());
|
||||||
|
c->popup()->setSelectionModel(sm);
|
||||||
|
sm->select(c->completionModel()->index(0, 0), QItemSelectionModel::ClearAndSelect);
|
||||||
|
sm->setCurrentIndex(c->completionModel()->index(0, 0), QItemSelectionModel::NoUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LineEditCompleter::cursorWord(const QString &line) const
|
||||||
|
{
|
||||||
|
return line.mid(line.left(cursorPosition()).lastIndexOf(" ") + 1,
|
||||||
|
cursorPosition() - line.left(cursorPosition()).lastIndexOf(" ") - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineEditCompleter::insertCompletion(QString arg)
|
||||||
|
{
|
||||||
|
QString s_arg = arg + " ";
|
||||||
|
setText(text().replace(text().left(cursorPosition()).lastIndexOf(" ") + 1,
|
||||||
|
cursorPosition() - text().left(cursorPosition()).lastIndexOf(" ") - 1, s_arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineEditCompleter::setCompleter(QCompleter* completer)
|
||||||
|
{
|
||||||
|
c = completer;
|
||||||
|
c->setWidget(this);
|
||||||
|
connect(c, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineEditCompleter::setCompletionList(QStringList completionList)
|
||||||
|
{
|
||||||
|
if (!c || c->popup()->isVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QStringListModel *model;
|
||||||
|
model = (QStringListModel*)(c->model());
|
||||||
|
if (model == NULL)
|
||||||
|
model = new QStringListModel();
|
||||||
|
model->setStringList(completionList);
|
||||||
|
}
|
26
cockatrice/src/lineeditcompleter.h
Normal file
26
cockatrice/src/lineeditcompleter.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef LINEEDITCOMPLETER_H
|
||||||
|
#define LINEEDITCOMPLETER_H
|
||||||
|
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QFocusEvent>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
class LineEditCompleter : public QLineEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
QString cursorWord(const QString& line) const;
|
||||||
|
QCompleter* c;
|
||||||
|
private slots:
|
||||||
|
void insertCompletion(QString);
|
||||||
|
protected:
|
||||||
|
void keyPressEvent(QKeyEvent * event);
|
||||||
|
void focusOutEvent(QFocusEvent * e);
|
||||||
|
public:
|
||||||
|
explicit LineEditCompleter(QWidget *parent = 0);
|
||||||
|
void setCompleter(QCompleter*);
|
||||||
|
void setCompletionList(QStringList);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,6 +8,8 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QCompleter>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
#include "dlg_creategame.h"
|
#include "dlg_creategame.h"
|
||||||
#include "tab_game.h"
|
#include "tab_game.h"
|
||||||
|
@ -31,6 +33,7 @@
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
#include "carddatabase.h"
|
#include "carddatabase.h"
|
||||||
#include "replay_timeline_widget.h"
|
#include "replay_timeline_widget.h"
|
||||||
|
#include "lineeditcompleter.h"
|
||||||
|
|
||||||
#include <google/protobuf/descriptor.h>
|
#include <google/protobuf/descriptor.h>
|
||||||
#include "pending_command.h"
|
#include "pending_command.h"
|
||||||
|
@ -463,8 +466,9 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_client
|
||||||
connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
|
connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
|
||||||
connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||||
connect(messageLog, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
connect(messageLog, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
||||||
|
connect(settingsCache, SIGNAL(chatMentionCompleterChanged()), this, SLOT(actCompleterChanged()));
|
||||||
sayLabel = new QLabel;
|
sayLabel = new QLabel;
|
||||||
sayEdit = new QLineEdit;
|
sayEdit = new LineEditCompleter;
|
||||||
sayLabel->setBuddy(sayEdit);
|
sayLabel->setBuddy(sayEdit);
|
||||||
|
|
||||||
QHBoxLayout *hLayout = new QHBoxLayout;
|
QHBoxLayout *hLayout = new QHBoxLayout;
|
||||||
|
@ -555,6 +559,17 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_client
|
||||||
|
|
||||||
for (int i = gameInfo.game_types_size() - 1; i >= 0; i--)
|
for (int i = gameInfo.game_types_size() - 1; i >= 0; i--)
|
||||||
gameTypes.append(roomGameTypes.find(gameInfo.game_types(i)).value());
|
gameTypes.append(roomGameTypes.find(gameInfo.game_types(i)).value());
|
||||||
|
|
||||||
|
completer = new QCompleter(autocompleteUserList, sayEdit);
|
||||||
|
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
completer->setMaxVisibleItems(5);
|
||||||
|
|
||||||
|
#if QT_VERSION >= 0x050000
|
||||||
|
completer->setFilterMode(Qt::MatchStartsWith);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sayEdit->setCompleter(completer);
|
||||||
|
actCompleterChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGame::addMentionTag(QString value) {
|
void TabGame::addMentionTag(QString value) {
|
||||||
|
@ -721,6 +736,9 @@ void TabGame::actLeaveGame()
|
||||||
|
|
||||||
void TabGame::actSay()
|
void TabGame::actSay()
|
||||||
{
|
{
|
||||||
|
if (completer->popup()->isVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
if (!sayEdit->text().isEmpty()) {
|
if (!sayEdit->text().isEmpty()) {
|
||||||
Command_GameSay cmd;
|
Command_GameSay cmd;
|
||||||
cmd.set_message(sayEdit->text().toStdString());
|
cmd.set_message(sayEdit->text().toStdString());
|
||||||
|
@ -779,11 +797,21 @@ void TabGame::actRotateViewCCW()
|
||||||
scene->adjustPlayerRotation(1);
|
scene->adjustPlayerRotation(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabGame::actCompleterChanged()
|
||||||
|
{
|
||||||
|
settingsCache->getChatMentionCompleter() ? completer->setCompletionRole(2) : completer->setCompletionRole(1);
|
||||||
|
}
|
||||||
|
|
||||||
Player *TabGame::addPlayer(int playerId, const ServerInfo_User &info)
|
Player *TabGame::addPlayer(int playerId, const ServerInfo_User &info)
|
||||||
{
|
{
|
||||||
bool local = ((clients.size() > 1) || (playerId == localPlayerId));
|
bool local = ((clients.size() > 1) || (playerId == localPlayerId));
|
||||||
Player *newPlayer = new Player(info, playerId, local, this);
|
Player *newPlayer = new Player(info, playerId, local, this);
|
||||||
connect(newPlayer, SIGNAL(openDeckEditor(const DeckLoader *)), this, SIGNAL(openDeckEditor(const DeckLoader *)));
|
connect(newPlayer, SIGNAL(openDeckEditor(const DeckLoader *)), this, SIGNAL(openDeckEditor(const DeckLoader *)));
|
||||||
|
QString newPlayerName = "@" + newPlayer->getName();
|
||||||
|
if (!autocompleteUserList.contains(newPlayerName)){
|
||||||
|
autocompleteUserList << newPlayerName;
|
||||||
|
sayEdit->setCompletionList(autocompleteUserList);
|
||||||
|
}
|
||||||
scene->addPlayer(newPlayer);
|
scene->addPlayer(newPlayer);
|
||||||
|
|
||||||
connect(newPlayer, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *)));
|
connect(newPlayer, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *)));
|
||||||
|
@ -803,7 +831,6 @@ Player *TabGame::addPlayer(int playerId, const ServerInfo_User &info)
|
||||||
|
|
||||||
players.insert(playerId, newPlayer);
|
players.insert(playerId, newPlayer);
|
||||||
emit playerAdded(newPlayer);
|
emit playerAdded(newPlayer);
|
||||||
|
|
||||||
return newPlayer;
|
return newPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,6 +1005,9 @@ void TabGame::eventSpectatorSay(const Event_GameSay &event, int eventPlayerId, c
|
||||||
|
|
||||||
void TabGame::eventSpectatorLeave(const Event_Leave & /*event*/, int eventPlayerId, const GameEventContext & /*context*/)
|
void TabGame::eventSpectatorLeave(const Event_Leave & /*event*/, int eventPlayerId, const GameEventContext & /*context*/)
|
||||||
{
|
{
|
||||||
|
QString playerName = "@" + QString::fromStdString(spectators.value(eventPlayerId).name());
|
||||||
|
if (autocompleteUserList.removeOne(playerName))
|
||||||
|
sayEdit->setCompletionList(autocompleteUserList);
|
||||||
messageLog->logLeaveSpectator(QString::fromStdString(spectators.value(eventPlayerId).name()));
|
messageLog->logLeaveSpectator(QString::fromStdString(spectators.value(eventPlayerId).name()));
|
||||||
playerListWidget->removePlayer(eventPlayerId);
|
playerListWidget->removePlayer(eventPlayerId);
|
||||||
spectators.remove(eventPlayerId);
|
spectators.remove(eventPlayerId);
|
||||||
|
@ -992,6 +1022,11 @@ void TabGame::eventGameStateChanged(const Event_GameStateChanged &event, int /*e
|
||||||
const ServerInfo_Player &playerInfo = event.player_list(i);
|
const ServerInfo_Player &playerInfo = event.player_list(i);
|
||||||
const ServerInfo_PlayerProperties &prop = playerInfo.properties();
|
const ServerInfo_PlayerProperties &prop = playerInfo.properties();
|
||||||
const int playerId = prop.player_id();
|
const int playerId = prop.player_id();
|
||||||
|
QString playerName = "@" + QString::fromStdString(prop.user_info().name());
|
||||||
|
if (!autocompleteUserList.contains(playerName)){
|
||||||
|
autocompleteUserList << playerName;
|
||||||
|
sayEdit->setCompletionList(autocompleteUserList);
|
||||||
|
}
|
||||||
if (prop.spectator()) {
|
if (prop.spectator()) {
|
||||||
if (!spectators.contains(playerId)) {
|
if (!spectators.contains(playerId)) {
|
||||||
spectators.insert(playerId, prop.user_info());
|
spectators.insert(playerId, prop.user_info());
|
||||||
|
@ -1099,11 +1134,18 @@ void TabGame::eventJoin(const Event_Join &event, int /*eventPlayerId*/, const Ga
|
||||||
{
|
{
|
||||||
const ServerInfo_PlayerProperties &playerInfo = event.player_properties();
|
const ServerInfo_PlayerProperties &playerInfo = event.player_properties();
|
||||||
const int playerId = playerInfo.player_id();
|
const int playerId = playerInfo.player_id();
|
||||||
|
QString playerName = QString::fromStdString(playerInfo.user_info().name());
|
||||||
|
if (!autocompleteUserList.contains("@" + playerName)){
|
||||||
|
autocompleteUserList << "@" + playerName;
|
||||||
|
sayEdit->setCompletionList(autocompleteUserList);
|
||||||
|
}
|
||||||
|
|
||||||
if (players.contains(playerId))
|
if (players.contains(playerId))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (playerInfo.spectator()) {
|
if (playerInfo.spectator()) {
|
||||||
spectators.insert(playerId, playerInfo.user_info());
|
spectators.insert(playerId, playerInfo.user_info());
|
||||||
messageLog->logJoinSpectator(QString::fromStdString(playerInfo.user_info().name()));
|
messageLog->logJoinSpectator(playerName);
|
||||||
} else {
|
} else {
|
||||||
Player *newPlayer = addPlayer(playerId, playerInfo.user_info());
|
Player *newPlayer = addPlayer(playerId, playerInfo.user_info());
|
||||||
messageLog->logJoin(newPlayer);
|
messageLog->logJoin(newPlayer);
|
||||||
|
@ -1118,6 +1160,10 @@ void TabGame::eventLeave(const Event_Leave & /*event*/, int eventPlayerId, const
|
||||||
if (!player)
|
if (!player)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
QString playerName = "@" + player->getName();
|
||||||
|
if(autocompleteUserList.removeOne(playerName))
|
||||||
|
sayEdit->setCompletionList(autocompleteUserList);
|
||||||
|
|
||||||
messageLog->logLeave(player);
|
messageLog->logLeave(player);
|
||||||
playerListWidget->removePlayer(eventPlayerId);
|
playerListWidget->removePlayer(eventPlayerId);
|
||||||
players.remove(eventPlayerId);
|
players.remove(eventPlayerId);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QCompleter>
|
||||||
#include "tab.h"
|
#include "tab.h"
|
||||||
#include "pb/serverinfo_game.pb.h"
|
#include "pb/serverinfo_game.pb.h"
|
||||||
|
|
||||||
|
@ -54,6 +55,7 @@ class QHBoxLayout;
|
||||||
class GameReplay;
|
class GameReplay;
|
||||||
class ServerInfo_User;
|
class ServerInfo_User;
|
||||||
class PendingCommand;
|
class PendingCommand;
|
||||||
|
class LineEditCompleter;
|
||||||
|
|
||||||
class ToggleButton : public QPushButton {
|
class ToggleButton : public QPushButton {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -117,6 +119,8 @@ private:
|
||||||
CardItem *activeCard;
|
CardItem *activeCard;
|
||||||
bool gameClosed;
|
bool gameClosed;
|
||||||
QStringList gameTypes;
|
QStringList gameTypes;
|
||||||
|
QCompleter *completer;
|
||||||
|
QStringList autocompleteUserList;
|
||||||
|
|
||||||
// Replay related members
|
// Replay related members
|
||||||
GameReplay *replay;
|
GameReplay *replay;
|
||||||
|
@ -131,7 +135,7 @@ private:
|
||||||
QLabel *timeElapsedLabel;
|
QLabel *timeElapsedLabel;
|
||||||
MessageLogWidget *messageLog;
|
MessageLogWidget *messageLog;
|
||||||
QLabel *sayLabel;
|
QLabel *sayLabel;
|
||||||
QLineEdit *sayEdit;
|
LineEditCompleter *sayEdit;
|
||||||
PhasesToolbar *phasesToolbar;
|
PhasesToolbar *phasesToolbar;
|
||||||
GameScene *scene;
|
GameScene *scene;
|
||||||
GameView *gameView;
|
GameView *gameView;
|
||||||
|
@ -200,7 +204,10 @@ private slots:
|
||||||
|
|
||||||
void addMentionTag(QString value);
|
void addMentionTag(QString value);
|
||||||
void commandFinished(const Response &response);
|
void commandFinished(const Response &response);
|
||||||
|
|
||||||
void refreshShortcuts();
|
void refreshShortcuts();
|
||||||
|
|
||||||
|
void actCompleterChanged();
|
||||||
public:
|
public:
|
||||||
TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, const Event_GameJoined &event, const QMap<int, QString> &_roomGameTypes);
|
TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, const Event_GameJoined &event, const QMap<int, QString> &_roomGameTypes);
|
||||||
TabGame(TabSupervisor *_tabSupervisor, GameReplay *replay);
|
TabGame(TabSupervisor *_tabSupervisor, GameReplay *replay);
|
||||||
|
|
|
@ -13,12 +13,6 @@
|
||||||
#include <QSystemTrayIcon>
|
#include <QSystemTrayIcon>
|
||||||
#include <QCompleter>
|
#include <QCompleter>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QTextCursor>
|
|
||||||
#include <QAbstractItemView>
|
|
||||||
#include <QScrollBar>
|
|
||||||
#include <QStringListModel>
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QFocusEvent>
|
|
||||||
#include "tab_supervisor.h"
|
#include "tab_supervisor.h"
|
||||||
#include "tab_room.h"
|
#include "tab_room.h"
|
||||||
#include "tab_userlists.h"
|
#include "tab_userlists.h"
|
||||||
|
@ -28,6 +22,7 @@
|
||||||
#include "gameselector.h"
|
#include "gameselector.h"
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "lineeditcompleter.h"
|
||||||
|
|
||||||
#include "get_pb_extension.h"
|
#include "get_pb_extension.h"
|
||||||
#include "pb/room_commands.pb.h"
|
#include "pb/room_commands.pb.h"
|
||||||
|
@ -61,7 +56,7 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, ServerI
|
||||||
connect(chatView, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
connect(chatView, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
||||||
connect(settingsCache, SIGNAL(chatMentionCompleterChanged()), this, SLOT(actCompleterChanged()));
|
connect(settingsCache, SIGNAL(chatMentionCompleterChanged()), this, SLOT(actCompleterChanged()));
|
||||||
sayLabel = new QLabel;
|
sayLabel = new QLabel;
|
||||||
sayEdit = new CustomLineEdit;
|
sayEdit = new LineEditCompleter;
|
||||||
sayLabel->setBuddy(sayEdit);
|
sayLabel->setBuddy(sayEdit);
|
||||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
|
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
|
||||||
|
|
||||||
|
@ -256,7 +251,7 @@ void TabRoom::processJoinRoomEvent(const Event_JoinRoom &event)
|
||||||
userList->sortItems();
|
userList->sortItems();
|
||||||
if (!autocompleteUserList.contains("@" + QString::fromStdString(event.user_info().name()))){
|
if (!autocompleteUserList.contains("@" + QString::fromStdString(event.user_info().name()))){
|
||||||
autocompleteUserList << "@" + QString::fromStdString(event.user_info().name());
|
autocompleteUserList << "@" + QString::fromStdString(event.user_info().name());
|
||||||
sayEdit->updateCompleterModel(autocompleteUserList);
|
sayEdit->setCompletionList(autocompleteUserList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +259,7 @@ void TabRoom::processLeaveRoomEvent(const Event_LeaveRoom &event)
|
||||||
{
|
{
|
||||||
userList->deleteUser(QString::fromStdString(event.name()));
|
userList->deleteUser(QString::fromStdString(event.name()));
|
||||||
autocompleteUserList.removeOne("@" + QString::fromStdString(event.name()));
|
autocompleteUserList.removeOne("@" + QString::fromStdString(event.name()));
|
||||||
sayEdit->updateCompleterModel(autocompleteUserList);
|
sayEdit->setCompletionList(autocompleteUserList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabRoom::processRoomSayEvent(const Event_RoomSay &event)
|
void TabRoom::processRoomSayEvent(const Event_RoomSay &event)
|
||||||
|
@ -301,125 +296,4 @@ PendingCommand *TabRoom::prepareRoomCommand(const ::google::protobuf::Message &c
|
||||||
void TabRoom::sendRoomCommand(PendingCommand *pend)
|
void TabRoom::sendRoomCommand(PendingCommand *pend)
|
||||||
{
|
{
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomLineEdit::CustomLineEdit(QWidget *parent)
|
|
||||||
: QLineEdit(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomLineEdit::focusOutEvent(QFocusEvent * e){
|
|
||||||
QLineEdit::focusOutEvent(e);
|
|
||||||
if (c->popup()->isVisible()){
|
|
||||||
//Remove Popup
|
|
||||||
c->popup()->hide();
|
|
||||||
//Truncate the line to last space or whole string
|
|
||||||
QString textValue = text();
|
|
||||||
int lastIndex = textValue.length();
|
|
||||||
int lastWordStartIndex = textValue.lastIndexOf(" ") + 1;
|
|
||||||
int leftShift = qMin(lastIndex, lastWordStartIndex);
|
|
||||||
setText(textValue.left(leftShift));
|
|
||||||
//Insert highlighted line from popup
|
|
||||||
insert(c->completionModel()->index(c->popup()->currentIndex().row(), 0).data().toString() + " ");
|
|
||||||
//Set focus back to the textbox since tab was pressed
|
|
||||||
setFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomLineEdit::keyPressEvent(QKeyEvent * event)
|
|
||||||
{
|
|
||||||
switch (event->key()){
|
|
||||||
case Qt::Key_Return:
|
|
||||||
case Qt::Key_Enter:
|
|
||||||
case Qt::Key_Escape:
|
|
||||||
if (c->popup()->isVisible()){
|
|
||||||
event->ignore();
|
|
||||||
//Remove Popup
|
|
||||||
c->popup()->hide();
|
|
||||||
//Truncate the line to last space or whole string
|
|
||||||
QString textValue = text();
|
|
||||||
int lastIndexof = textValue.lastIndexOf(" ");
|
|
||||||
QString finalString = textValue.left(lastIndexof);
|
|
||||||
//Add a space if there's a word
|
|
||||||
if (finalString != "")
|
|
||||||
finalString += " ";
|
|
||||||
setText(finalString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::Key_Space:
|
|
||||||
if (c->popup()->isVisible()){
|
|
||||||
event->ignore();
|
|
||||||
//Remove Popup
|
|
||||||
c->popup()->hide();
|
|
||||||
//Truncate the line to last space or whole string
|
|
||||||
QString textValue = text();
|
|
||||||
int lastIndex = textValue.length();
|
|
||||||
int lastWordStartIndex = textValue.lastIndexOf(" ") + 1;
|
|
||||||
int leftShift = qMin(lastIndex, lastWordStartIndex);
|
|
||||||
setText(textValue.left(leftShift));
|
|
||||||
//Insert highlighted line from popup
|
|
||||||
insert(c->completionModel()->index(c->popup()->currentIndex().row(), 0).data().toString() + " ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QLineEdit::keyPressEvent(event);
|
|
||||||
//Wait until the first character after @
|
|
||||||
if (!c || text().right(1).contains("@"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Set new completion prefix
|
|
||||||
c->setCompletionPrefix(cursorWord(text()));
|
|
||||||
if (c->completionPrefix().length() < 1){
|
|
||||||
c->popup()->hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Draw completion box
|
|
||||||
QRect cr = cursorRect();
|
|
||||||
cr.setWidth(c->popup()->sizeHintForColumn(0) + c->popup()->verticalScrollBar()->sizeHint().width());
|
|
||||||
c->complete(cr);
|
|
||||||
|
|
||||||
//Select first item in the completion popup
|
|
||||||
QItemSelectionModel* sm = new QItemSelectionModel(c->completionModel());
|
|
||||||
c->popup()->setSelectionModel(sm);
|
|
||||||
sm->select(c->completionModel()->index(0, 0), QItemSelectionModel::ClearAndSelect);
|
|
||||||
sm->setCurrentIndex(c->completionModel()->index(0, 0), QItemSelectionModel::NoUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CustomLineEdit::cursorWord(const QString &line) const
|
|
||||||
{
|
|
||||||
return line.mid(line.left(cursorPosition()).lastIndexOf(" ") + 1,
|
|
||||||
cursorPosition() - line.left(cursorPosition()).lastIndexOf(" ") - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomLineEdit::insertCompletion(QString arg)
|
|
||||||
{
|
|
||||||
QString s_arg = arg + " ";
|
|
||||||
setText(text().replace(text().left(cursorPosition()).lastIndexOf(" ") + 1,
|
|
||||||
cursorPosition() - text().left(cursorPosition()).lastIndexOf(" ") - 1, s_arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomLineEdit::setCompleter(QCompleter* completer)
|
|
||||||
{
|
|
||||||
c = completer;
|
|
||||||
c->setWidget(this);
|
|
||||||
connect(c, SIGNAL(activated(QString)),this, SLOT(insertCompletion(QString)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomLineEdit::updateCompleterModel(QStringList completionList)
|
|
||||||
{
|
|
||||||
if (!c || c->popup()->isVisible())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QStringListModel *model;
|
|
||||||
model = (QStringListModel*)(c->model());
|
|
||||||
if (model == NULL)
|
|
||||||
model = new QStringListModel();
|
|
||||||
QStringList updatedList = completionList;
|
|
||||||
model->setStringList(updatedList);
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define TAB_ROOM_H
|
#define TAB_ROOM_H
|
||||||
|
|
||||||
#include "tab.h"
|
#include "tab.h"
|
||||||
|
#include "lineeditcompleter.h"
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
@ -28,7 +29,7 @@ class GameSelector;
|
||||||
class Response;
|
class Response;
|
||||||
class PendingCommand;
|
class PendingCommand;
|
||||||
class ServerInfo_User;
|
class ServerInfo_User;
|
||||||
class CustomLineEdit;
|
class LineEditCompleter;
|
||||||
|
|
||||||
class TabRoom : public Tab {
|
class TabRoom : public Tab {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -43,7 +44,7 @@ private:
|
||||||
UserList *userList;
|
UserList *userList;
|
||||||
ChatView *chatView;
|
ChatView *chatView;
|
||||||
QLabel *sayLabel;
|
QLabel *sayLabel;
|
||||||
CustomLineEdit *sayEdit;
|
LineEditCompleter *sayEdit;
|
||||||
QGroupBox *chatGroupBox;
|
QGroupBox *chatGroupBox;
|
||||||
|
|
||||||
QMenu *roomMenu;
|
QMenu *roomMenu;
|
||||||
|
@ -91,21 +92,4 @@ public:
|
||||||
void sendRoomCommand(PendingCommand *pend);
|
void sendRoomCommand(PendingCommand *pend);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CustomLineEdit : public QLineEdit
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
private:
|
|
||||||
QString cursorWord(const QString& line) const;
|
|
||||||
QCompleter* c;
|
|
||||||
private slots:
|
|
||||||
void insertCompletion(QString);
|
|
||||||
protected:
|
|
||||||
void keyPressEvent(QKeyEvent * event);
|
|
||||||
void focusOutEvent(QFocusEvent * e);
|
|
||||||
public:
|
|
||||||
explicit CustomLineEdit(QWidget *parent = 0);
|
|
||||||
void setCompleter(QCompleter*);
|
|
||||||
void updateCompleterModel(QStringList);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue