From 2e0944b7ccdfc11c5209fe34bf70110dd6991c0e Mon Sep 17 00:00:00 2001 From: poixen Date: Tue, 5 Jul 2016 23:30:59 +0200 Subject: [PATCH] card completion --- cockatrice/src/dlg_settings.cpp | 2 +- cockatrice/src/lineeditcompleter.cpp | 151 ++++++++++++++++++++++----- cockatrice/src/lineeditcompleter.h | 10 +- cockatrice/src/tab_game.cpp | 16 +-- cockatrice/src/tab_room.cpp | 36 +++++-- cockatrice/src/tab_room.h | 5 +- 6 files changed, 168 insertions(+), 52 deletions(-) diff --git a/cockatrice/src/dlg_settings.cpp b/cockatrice/src/dlg_settings.cpp index 81e88c1c0..3b0f53ad6 100644 --- a/cockatrice/src/dlg_settings.cpp +++ b/cockatrice/src/dlg_settings.cpp @@ -791,7 +791,7 @@ void MessagesSettingsPage::retranslateUi() chatGroupBox->setTitle(tr("Chat settings")); highlightGroupBox->setTitle(tr("Custom alert words")); chatMentionCheckBox.setText(tr("Enable chat mentions")); - chatMentionCompleterCheckbox.setText(tr("Enable mention completer")); + chatMentionCompleterCheckbox.setText(tr("Enable mention mentionCompleter")); messageShortcuts->setTitle(tr("In-game message macros")); ignoreUnregUsersMainChat.setText(tr("Ignore chat room messages sent by unregistered users")); ignoreUnregUserMessages.setText(tr("Ignore private messages sent by unregistered users")); diff --git a/cockatrice/src/lineeditcompleter.cpp b/cockatrice/src/lineeditcompleter.cpp index e3eec7e76..220b86817 100644 --- a/cockatrice/src/lineeditcompleter.cpp +++ b/cockatrice/src/lineeditcompleter.cpp @@ -9,16 +9,16 @@ #include #include -LineEditCompleter::LineEditCompleter(QWidget *parent) : QLineEdit(parent), c(nullptr) +LineEditCompleter::LineEditCompleter(QWidget *parent) : QLineEdit(parent) { } void LineEditCompleter::focusOutEvent(QFocusEvent *e) { QLineEdit::focusOutEvent(e); - if (c->popup()->isVisible()) { + if (mentionCompleter->popup()->isVisible()) { // Remove Popup - c->popup()->hide(); + mentionCompleter->popup()->hide(); // Truncate the line to last space or whole string QString textValue = text(); int lastIndex = textValue.length(); @@ -26,7 +26,28 @@ void LineEditCompleter::focusOutEvent(QFocusEvent *e) 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() + " "); + insert(mentionCompleter->completionModel() + ->index(mentionCompleter->popup()->currentIndex().row(), 0) + .data() + .toString() + + " "); + // Set focus back to the textbox since tab was pressed + setFocus(); + } + + if (cardCompleter->popup()->isVisible()) { + // Remove Popup + cardCompleter->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( + cardCompleter->completionModel()->index(cardCompleter->popup()->currentIndex().row(), 0).data().toString() + + " "); // Set focus back to the textbox since tab was pressed setFocus(); } @@ -38,10 +59,24 @@ void LineEditCompleter::keyPressEvent(QKeyEvent *event) case Qt::Key_Return: case Qt::Key_Enter: case Qt::Key_Escape: - if (c->popup()->isVisible()) { + if (mentionCompleter->popup()->isVisible()) { event->ignore(); // Remove Popup - c->popup()->hide(); + mentionCompleter->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; + } + if (cardCompleter->popup()->isVisible()) { + event->ignore(); + // Remove Popup + cardCompleter->popup()->hide(); // Truncate the line to last space or whole string QString textValue = text(); int lastIndexof = qMax(0, textValue.lastIndexOf(" ")); @@ -54,10 +89,10 @@ void LineEditCompleter::keyPressEvent(QKeyEvent *event) } break; case Qt::Key_Space: - if (c->popup()->isVisible()) { + if (mentionCompleter->popup()->isVisible()) { event->ignore(); // Remove Popup - c->popup()->hide(); + mentionCompleter->popup()->hide(); // Truncate the line to last space or whole string QString textValue = text(); int lastIndex = textValue.length(); @@ -65,7 +100,29 @@ void LineEditCompleter::keyPressEvent(QKeyEvent *event) 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() + " "); + insert(mentionCompleter->completionModel() + ->index(mentionCompleter->popup()->currentIndex().row(), 0) + .data() + .toString() + + " "); + return; + } + if (cardCompleter->popup()->isVisible()) { + event->ignore(); + // Remove Popup + cardCompleter->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(cardCompleter->completionModel() + ->index(cardCompleter->popup()->currentIndex().row(), 0) + .data() + .toString() + + " "); return; } break; @@ -74,30 +131,59 @@ void LineEditCompleter::keyPressEvent(QKeyEvent *event) } QLineEdit::keyPressEvent(event); - // return if the completer is null or if the most recently typed char was '@'. + + // return if the mentionCompleter is null or if the most recently typed char was '@'. // Only want the popup AFTER typing the first char of the mention. - if (!c || text().right(1).contains("@")) { - c->popup()->hide(); + if (mentionCompleter && !text().right(1).contains("@")) { + processMention(); + } else { + mentionCompleter->popup()->hide(); + } + + if (cardCompleter && !text().right(2).contains("[[")) { + processCard(); + } else { + cardCompleter->popup()->hide(); + } + + return; +} + +void LineEditCompleter::processMention() const +{ + // Set new completion prefix + mentionCompleter->setCompletionPrefix(cursorWord(text())); + if (mentionCompleter->completionPrefix().length() < 1) { + mentionCompleter->popup()->hide(); return; } - // Set new completion prefix - c->setCompletionPrefix(cursorWord(text())); - if (c->completionPrefix().length() < 1) { - c->popup()->hide(); + // Select first item in the completion popup + QItemSelectionModel *sm = new QItemSelectionModel(mentionCompleter->completionModel()); + mentionCompleter->popup()->setSelectionModel(sm); + sm->select(mentionCompleter->completionModel()->index(0, 0), QItemSelectionModel::ClearAndSelect); + sm->setCurrentIndex(mentionCompleter->completionModel()->index(0, 0), QItemSelectionModel::NoUpdate); +} + +void LineEditCompleter::processCard() const +{ + cardCompleter->setCompletionPrefix(cursorWord(text())); + if (cardCompleter->completionPrefix().length() < 2) { + cardCompleter->popup()->hide(); return; } // Draw completion box QRect cr = cursorRect(); - cr.setWidth(c->popup()->sizeHintForColumn(0) + c->popup()->verticalScrollBar()->sizeHint().width()); - c->complete(cr); + cr.setWidth(cardCompleter->popup()->sizeHintForColumn(0) + + cardCompleter->popup()->verticalScrollBar()->sizeHint().width()); + cardCompleter->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); + QItemSelectionModel *sm = new QItemSelectionModel(cardCompleter->completionModel()); + cardCompleter->popup()->setSelectionModel(sm); + sm->select(cardCompleter->completionModel()->index(0, 0), QItemSelectionModel::ClearAndSelect); + sm->setCurrentIndex(cardCompleter->completionModel()->index(0, 0), QItemSelectionModel::NoUpdate); } QString LineEditCompleter::cursorWord(const QString &line) const @@ -113,20 +199,27 @@ void LineEditCompleter::insertCompletion(QString arg) cursorPosition() - text().left(cursorPosition()).lastIndexOf(" ") - 1, s_arg)); } -void LineEditCompleter::setCompleter(QCompleter *completer) +void LineEditCompleter::setMentionCompleter(QCompleter *completer) { - c = completer; - c->setWidget(this); - connect(c, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString))); + mentionCompleter = completer; + mentionCompleter->setWidget(this); + connect(mentionCompleter, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString))); } -void LineEditCompleter::setCompletionList(QStringList completionList) +void LineEditCompleter::setCardCompleter(QCompleter *completer) { - if (!c || c->popup()->isVisible()) + cardCompleter = completer; + cardCompleter->setWidget(this); + connect(cardCompleter, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString))); +} + +void LineEditCompleter::setMentionCompletionList(QStringList completionList) +{ + if (!mentionCompleter || mentionCompleter->popup()->isVisible()) return; QStringListModel *model; - model = (QStringListModel *)(c->model()); + model = (QStringListModel *)(mentionCompleter->model()); if (model == NULL) model = new QStringListModel(); model->setStringList(completionList); diff --git a/cockatrice/src/lineeditcompleter.h b/cockatrice/src/lineeditcompleter.h index cd020b689..e94bda5c8 100644 --- a/cockatrice/src/lineeditcompleter.h +++ b/cockatrice/src/lineeditcompleter.h @@ -11,7 +11,10 @@ class LineEditCompleter : public QLineEdit Q_OBJECT private: QString cursorWord(const QString &line) const; - QCompleter *c; + void processMention() const; + void processCard() const; + QCompleter *mentionCompleter; + QCompleter *cardCompleter; private slots: void insertCompletion(QString); @@ -21,8 +24,9 @@ protected: public: explicit LineEditCompleter(QWidget *parent = 0); - void setCompleter(QCompleter *); - void setCompletionList(QStringList); + void setMentionCompleter(QCompleter *mentionCompleter); + void setCardCompleter(QCompleter *cardCompleter); + void setMentionCompletionList(QStringList completionList); }; #endif \ No newline at end of file diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index 7f564328b..1d5ca979a 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -718,7 +718,7 @@ Player *TabGame::addPlayer(int playerId, const ServerInfo_User &info) QString newPlayerName = "@" + newPlayer->getName(); if (sayEdit && !autocompleteUserList.contains(newPlayerName)) { autocompleteUserList << newPlayerName; - sayEdit->setCompletionList(autocompleteUserList); + sayEdit->setMentionCompletionList(autocompleteUserList); } scene->addPlayer(newPlayer); @@ -942,8 +942,9 @@ void TabGame::eventSpectatorSay(const Event_GameSay &event, int eventPlayerId, c void TabGame::eventSpectatorLeave(const Event_Leave &event, int eventPlayerId, const GameEventContext & /*context*/) { QString playerName = "@" + QString::fromStdString(spectators.value(eventPlayerId).name()); - if (sayEdit && autocompleteUserList.removeOne(playerName)) - sayEdit->setCompletionList(autocompleteUserList); + if (sayEdit && autocompleteUserList.removeOne(playerName)) { + sayEdit->setMentionCompletionList(autocompleteUserList); + } messageLog->logLeaveSpectator(QString::fromStdString(spectators.value(eventPlayerId).name()), getLeaveReason(event.reason())); playerListWidget->removePlayer(eventPlayerId); @@ -964,7 +965,7 @@ void TabGame::eventGameStateChanged(const Event_GameStateChanged &event, QString playerName = "@" + QString::fromStdString(prop.user_info().name()); if (sayEdit && !autocompleteUserList.contains(playerName)) { autocompleteUserList << playerName; - sayEdit->setCompletionList(autocompleteUserList); + sayEdit->setMentionCompletionList(autocompleteUserList); } if (prop.spectator()) { if (!spectators.contains(playerId)) { @@ -1078,7 +1079,7 @@ void TabGame::eventJoin(const Event_Join &event, int /*eventPlayerId*/, const Ga QString playerName = QString::fromStdString(playerInfo.user_info().name()); if (sayEdit && !autocompleteUserList.contains("@" + playerName)) { autocompleteUserList << "@" + playerName; - sayEdit->setCompletionList(autocompleteUserList); + sayEdit->setMentionCompletionList(autocompleteUserList); } if (players.contains(playerId)) @@ -1120,8 +1121,9 @@ void TabGame::eventLeave(const Event_Leave &event, int eventPlayerId, const Game return; QString playerName = "@" + player->getName(); - if (sayEdit && autocompleteUserList.removeOne(playerName)) - sayEdit->setCompletionList(autocompleteUserList); + if (sayEdit && autocompleteUserList.removeOne(playerName)) { + sayEdit->setMentionCompletionList(autocompleteUserList); + } messageLog->logLeave(player, getLeaveReason(event.reason())); playerListWidget->removePlayer(eventPlayerId); diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp index c1112c7c4..4333a949a 100644 --- a/cockatrice/src/tab_room.cpp +++ b/cockatrice/src/tab_room.cpp @@ -1,5 +1,6 @@ #include "tab_room.h" #include "abstractclient.h" +#include "carddatabase.h" #include "chatview/chatview.h" #include "dlg_settings.h" #include "gameselector.h" @@ -110,16 +111,26 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, } userList->sortItems(); + foreach (CardInfoPtr cardInfo, db->getCardList()) { + autocompleteCardList.append("[[" + cardInfo->getCorrectedName() + "]]"); + } + const int gameListSize = info.game_list_size(); for (int i = 0; i < gameListSize; ++i) gameSelector->processGameInfo(info.game_list(i)); - completer = new QCompleter(autocompleteUserList, sayEdit); - completer->setCaseSensitivity(Qt::CaseInsensitive); - completer->setMaxVisibleItems(5); - completer->setFilterMode(Qt::MatchStartsWith); + mentionCompleter = new QCompleter(autocompleteUserList, sayEdit); + mentionCompleter->setCaseSensitivity(Qt::CaseInsensitive); + mentionCompleter->setMaxVisibleItems(5); + mentionCompleter->setFilterMode(Qt::MatchStartsWith); + sayEdit->setMentionCompleter(mentionCompleter); + + cardCompleter = new QCompleter(autocompleteCardList, sayEdit); + cardCompleter->setCaseSensitivity(Qt::CaseInsensitive); + cardCompleter->setMaxVisibleItems(5); + cardCompleter->setFilterMode(Qt::MatchStartsWith); + sayEdit->setCardCompleter(cardCompleter); - sayEdit->setCompleter(completer); actCompleterChanged(); connect(&settingsCache->shortcuts(), SIGNAL(shortCutchanged()), this, SLOT(refreshShortcuts())); refreshShortcuts(); @@ -186,8 +197,9 @@ void TabRoom::sendMessage() { if (sayEdit->text().isEmpty()) { return; - } else if (completer->popup()->isVisible()) { - completer->popup()->hide(); + } else if (mentionCompleter->popup()->isVisible() || cardCompleter->popup()->isVisible()) { + mentionCompleter->popup()->hide(); + cardCompleter->popup()->hide(); return; } else { Command_RoomSay cmd; @@ -227,7 +239,8 @@ void TabRoom::actOpenChatSettings() void TabRoom::actCompleterChanged() { - settingsCache->getChatMentionCompleter() ? completer->setCompletionRole(2) : completer->setCompletionRole(1); + settingsCache->getChatMentionCompleter() ? mentionCompleter->setCompletionRole(2) + : mentionCompleter->setCompletionRole(1); } void TabRoom::processRoomEvent(const RoomEvent &event) @@ -262,7 +275,7 @@ void TabRoom::processJoinRoomEvent(const Event_JoinRoom &event) userList->sortItems(); if (!autocompleteUserList.contains("@" + QString::fromStdString(event.user_info().name()))) { autocompleteUserList << "@" + QString::fromStdString(event.user_info().name()); - sayEdit->setCompletionList(autocompleteUserList); + sayEdit->setMentionCompletionList(autocompleteUserList); } } @@ -270,7 +283,7 @@ void TabRoom::processLeaveRoomEvent(const Event_LeaveRoom &event) { userList->deleteUser(QString::fromStdString(event.name())); autocompleteUserList.removeOne("@" + QString::fromStdString(event.name())); - sayEdit->setCompletionList(autocompleteUserList); + sayEdit->setMentionCompletionList(autocompleteUserList); } void TabRoom::processRoomSayEvent(const Event_RoomSay &event) @@ -294,11 +307,12 @@ void TabRoom::processRoomSayEvent(const Event_RoomSay &event) if (event.message_type() == Event_RoomSay::ChatHistory && !settingsCache->getRoomHistory()) return; - if (event.message_type() == Event_RoomSay::ChatHistory) + if (event.message_type() == Event_RoomSay::ChatHistory) { message = "[" + QString(QDateTime::fromMSecsSinceEpoch(event.time_of()).toLocalTime().toString("d MMM yyyy HH:mm:ss")) + "] " + message; + } chatView->appendMessage(message, event.message_type(), senderName, userLevel, userPrivLevel, true); emit userEvent(false); diff --git a/cockatrice/src/tab_room.h b/cockatrice/src/tab_room.h index 75fc03b46..931ca2708 100644 --- a/cockatrice/src/tab_room.h +++ b/cockatrice/src/tab_room.h @@ -61,7 +61,10 @@ private: QString sanitizeHtml(QString dirty) const; QStringList autocompleteUserList; - QCompleter *completer; + QStringList autocompleteCardList; + QCompleter *mentionCompleter; + QCompleter *cardCompleter; + signals: void roomClosing(TabRoom *tab); void openMessageDialog(const QString &userName, bool focus);