From 59a8ea13e7bfc2151a49108eaa45c23795c402d9 Mon Sep 17 00:00:00 2001 From: Jookia <166291@gmail.com> Date: Sun, 22 Mar 2015 18:59:42 +1100 Subject: [PATCH 1/3] Implemented cycling through contacts. I've implemented this by having the contacts list container return all contact widgets in the order they appear each time it's time to cycle. It's perhaps inefficient but given cycling isn't done often I don't see a need to optimize. This code does make the assumption that the friends list isn't empty, which I'd guess would be the case if there's an active conversation. --- src/widget/friendlistwidget.cpp | 9 +++++++++ src/widget/friendlistwidget.h | 5 +++++ src/widget/widget.cpp | 22 +++++++++++++++++++--- src/widget/widget.h | 1 + 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/widget/friendlistwidget.cpp b/src/widget/friendlistwidget.cpp index 5a5e481bb..6478b733b 100644 --- a/src/widget/friendlistwidget.cpp +++ b/src/widget/friendlistwidget.cpp @@ -80,6 +80,15 @@ void FriendListWidget::onGroupchatPositionChanged(bool top) mainLayout->addLayout(groupLayout, 0, 0); mainLayout->addLayout(layouts[static_cast(Status::Online)], 1, 0); } + + return friends; +} + +void FriendListWidget::moveWidget(QWidget *w, Status s, int hasNewEvents) +{ + mainLayout->removeWidget(w); + if (hasNewEvents == 0) + getFriendLayout(s)->addWidget(w); else { mainLayout->addLayout(layouts[static_cast(Status::Online)], 0, 0); diff --git a/src/widget/friendlistwidget.h b/src/widget/friendlistwidget.h index ff098ce44..3af98d7d1 100644 --- a/src/widget/friendlistwidget.h +++ b/src/widget/friendlistwidget.h @@ -19,7 +19,9 @@ #include #include +#include #include "src/core/corestructs.h" +#include "src/widget/genericchatroomwidget.h" class QVBoxLayout; class QGridLayout; @@ -32,6 +34,9 @@ public: explicit FriendListWidget(QWidget *parent = 0, bool groupchatPosition = true); QVBoxLayout* getGroupLayout(); QVBoxLayout* getFriendLayout(Status s); + void moveWidget(QWidget *w, Status s, int hasNewEvents); + + QList getAllFriends(); signals: diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 218694ecb..17473fd05 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -1235,6 +1235,23 @@ void Widget::onSplitterMoved(int pos, int index) saveSplitterGeometry(); } +void Widget::cycleContacts(int offset) +{ + if (!activeChatroomWidget) + return; + + FriendListWidget* friendList = static_cast(ui->friendList->widget()); + QList friends = friendList->getAllFriends(); + + int activeIndex = friends.indexOf(activeChatroomWidget); + int bounded = (activeIndex + offset) % friends.length(); + + if(bounded < 0) + bounded += friends.length(); + + emit friends[bounded]->chatroomWidgetClicked(friends[bounded]); +} + void Widget::processOfflineMsgs() { if (OfflineMsgEngine::globalMutex.tryLock()) @@ -1271,13 +1288,12 @@ void Widget::reloadTheme() void Widget::nextContact() { - // dont know how to get current/previous/next contact from friendlistwidget - qDebug() << "next contact"; + cycleContacts(1); } void Widget::previousContact() { - qDebug() << "previous contact"; + cycleContacts(-1); } QString Widget::getStatusIconPath(Status status) diff --git a/src/widget/widget.h b/src/widget/widget.h index 62ad53b4b..a8736e1ba 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -158,6 +158,7 @@ private: void removeGroup(Group* g, bool fake = false); void saveWindowGeometry(); void saveSplitterGeometry(); + void cycleContacts(int offset); SystemTrayIcon *icon; QMenu *trayMenu; QAction *statusOnline, From f6a2925331bf53f0f77c73fc805ab918bce59ec2 Mon Sep 17 00:00:00 2001 From: Jookia <166291@gmail.com> Date: Sun, 22 Mar 2015 19:09:26 +1100 Subject: [PATCH 2/3] Tabs with modifiers are passed up from chat boxes. In Qt chat boxes filter out events related to text editing, including tabs. Unfortunately tabs with modifiers like those used to cycle through contacts are being filtered despite not being used for anything. This fixes the keybind for cycling forward through contacts (Ctrl+Tab). --- src/widget/tool/chattextedit.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/widget/tool/chattextedit.cpp b/src/widget/tool/chattextedit.cpp index 08526fc5b..46cd72ff2 100644 --- a/src/widget/tool/chattextedit.cpp +++ b/src/widget/tool/chattextedit.cpp @@ -25,12 +25,17 @@ ChatTextEdit::ChatTextEdit(QWidget *parent) : } void ChatTextEdit::keyPressEvent(QKeyEvent * event) -{ +{ int key = event->key(); if ((key == Qt::Key_Enter || key == Qt::Key_Return) && !(event->modifiers() & Qt::ShiftModifier)) emit enterPressed(); else if (key == Qt::Key_Tab) - emit tabPressed(); + { + if (event->modifiers()) + event->ignore(); + else + emit tabPressed(); + } else if (key == Qt::Key_Up && this->toPlainText().isEmpty()) { this->setText(lastMessage); From 1d58f476f7b28c5b0e966c46e94c1d56190c376f Mon Sep 17 00:00:00 2001 From: Jookia <166291@gmail.com> Date: Sun, 22 Mar 2015 19:16:32 +1100 Subject: [PATCH 3/3] Add keyboard bindings for cycling contacts. I've moved the key bindings in the main widget instead of the chat form given it doesn't seem to be the chat form's responsibility to handle switching between conversations it shouldn't know about in the first place. I've also included new shortcuts to provide a more familiar feel to most people. All in all this provides Ctrl+Tab and Ctrl+Shift+Tab for cycling as well as Ctrl+PgUp and Ctrl+PgDown for cycling. This mimics common application behaviour. --- src/widget/form/genericchatform.cpp | 12 ---------- src/widget/form/genericchatform.h | 2 -- src/widget/friendlistwidget.cpp | 35 +++++++++++++++++++++-------- src/widget/friendlistwidget.h | 1 - src/widget/widget.cpp | 4 ++++ 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index d6ca5a4f5..6341dea5e 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -169,24 +169,12 @@ GenericChatForm::GenericChatForm(QWidget *parent) connect(emoteButton, &QPushButton::clicked, this, &GenericChatForm::onEmoteButtonClicked); connect(chatWidget, &ChatLog::customContextMenuRequested, this, &GenericChatForm::onChatContextMenuRequested); - new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(previousContact())); - new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(nextContact())); new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_L, this, SLOT(clearChatArea())); chatWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatArea.css")); headWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatHead.css")); } -void GenericChatForm::previousContact() -{ - parent->previousContact(); -} - -void GenericChatForm::nextContact() -{ - parent->nextContact(); -} - bool GenericChatForm::isEmpty() { return chatWidget->isEmpty(); diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index 00eb06cf2..34da7957e 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -76,8 +76,6 @@ protected slots: void clearChatArea(bool); void clearChatArea(); void onSelectAllClicked(); - void previousContact(); - void nextContact(); protected: QString resolveToxID(const ToxID &id); diff --git a/src/widget/friendlistwidget.cpp b/src/widget/friendlistwidget.cpp index 6478b733b..0ccfa656e 100644 --- a/src/widget/friendlistwidget.cpp +++ b/src/widget/friendlistwidget.cpp @@ -80,15 +80,6 @@ void FriendListWidget::onGroupchatPositionChanged(bool top) mainLayout->addLayout(groupLayout, 0, 0); mainLayout->addLayout(layouts[static_cast(Status::Online)], 1, 0); } - - return friends; -} - -void FriendListWidget::moveWidget(QWidget *w, Status s, int hasNewEvents) -{ - mainLayout->removeWidget(w); - if (hasNewEvents == 0) - getFriendLayout(s)->addWidget(w); else { mainLayout->addLayout(layouts[static_cast(Status::Online)], 0, 0); @@ -96,6 +87,32 @@ void FriendListWidget::moveWidget(QWidget *w, Status s, int hasNewEvents) } } +QList FriendListWidget::getAllFriends() +{ + QList friends; + + for (int i = 0; i < mainLayout->count(); ++i) + { + QLayout* subLayout = mainLayout->itemAt(i)->layout(); + + if(!subLayout) + continue; + + for (int j = 0; j < subLayout->count(); ++j) + { + GenericChatroomWidget* widget = + reinterpret_cast(subLayout->itemAt(j)->widget()); + + if(!widget) + continue; + + friends.append(widget); + } + } + + return friends; +} + void FriendListWidget::moveWidget(QWidget *w, Status s) { QVBoxLayout* l = getFriendLayout(s); diff --git a/src/widget/friendlistwidget.h b/src/widget/friendlistwidget.h index 3af98d7d1..bbc299bbe 100644 --- a/src/widget/friendlistwidget.h +++ b/src/widget/friendlistwidget.h @@ -34,7 +34,6 @@ public: explicit FriendListWidget(QWidget *parent = 0, bool groupchatPosition = true); QVBoxLayout* getGroupLayout(); QVBoxLayout* getFriendLayout(Status s); - void moveWidget(QWidget *w, Status s, int hasNewEvents); QList getAllFriends(); diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 17473fd05..57a133746 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -200,6 +200,10 @@ void Widget::init() // keyboard shortcuts new QShortcut(Qt::CTRL + Qt::Key_Q, this, SLOT(close())); + new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab, this, SLOT(previousContact())); + new QShortcut(Qt::CTRL + Qt::Key_Tab, this, SLOT(nextContact())); + new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(previousContact())); + new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(nextContact())); addFriendForm->show(*ui); setWindowTitle(tr("Add friend"));