diff --git a/src/friend.cpp b/src/friend.cpp index 247d1720d..272cdcb1c 100644 --- a/src/friend.cpp +++ b/src/friend.cpp @@ -58,6 +58,8 @@ void Friend::setName(QString name) if (widget->isActive()) GUI::setWindowTitle(name); + + emit displayedNameChanged(getFriendWidget(), getStatus(), hasNewEvents); } } @@ -71,6 +73,8 @@ void Friend::setAlias(QString name) if (widget->isActive()) GUI::setWindowTitle(dispName); + + emit displayedNameChanged(getFriendWidget(), getStatus(), hasNewEvents); } void Friend::setStatusMessage(QString message) diff --git a/src/friend.h b/src/friend.h index b259b6975..944a078ee 100644 --- a/src/friend.h +++ b/src/friend.h @@ -17,14 +17,16 @@ #ifndef FRIEND_H #define FRIEND_H +#include #include #include "corestructs.h" struct FriendWidget; class ChatForm; -struct Friend +struct Friend : QObject { + Q_OBJECT public: Friend(int FriendId, const ToxID &UserId); Friend(const Friend& other)=delete; @@ -49,6 +51,9 @@ public: ChatForm *getChatForm(); FriendWidget *getFriendWidget(); +signals: + void displayedNameChanged(FriendWidget* widget, Status s, int hasNewEvents); + private: QString userAlias, userName; ToxID userID; diff --git a/src/misc/settings.cpp b/src/misc/settings.cpp index 9640d41b8..94f2f8455 100644 --- a/src/misc/settings.cpp +++ b/src/misc/settings.cpp @@ -217,6 +217,7 @@ void Settings::load() QStandardPaths::locate(QStandardPaths::HomeLocation, QString(), QStandardPaths::LocateDirectory) ).toString(); compactLayout = s.value("compactLayout", false).toBool(); + groupchatPosition = s.value("groupchatPosition", true).toBool(); s.endGroup(); s.beginGroup("Advanced"); @@ -385,6 +386,7 @@ void Settings::saveGlobal(QString path) s.setValue("groupAlwaysNotify", groupAlwaysNotify); s.setValue("fauxOfflineMessaging", fauxOfflineMessaging); s.setValue("compactLayout", compactLayout); + s.setValue("groupchatPosition", groupchatPosition); s.setValue("autoSaveEnabled", autoSaveEnabled); s.setValue("globalAutoAcceptDir", globalAutoAcceptDir); s.endGroup(); @@ -1174,6 +1176,16 @@ void Settings::setCompactLayout(bool value) emit compactLayoutChanged(); } +bool Settings::getGroupchatPosition() const +{ + return groupchatPosition; +} + +void Settings::setGroupchatPosition(bool value) +{ + groupchatPosition = value; +} + int Settings::getThemeColor() const { return themeColor; diff --git a/src/misc/settings.h b/src/misc/settings.h index bd7bbbf74..95a7f38d4 100644 --- a/src/misc/settings.h +++ b/src/misc/settings.h @@ -245,6 +245,9 @@ public: bool getCompactLayout() const; void setCompactLayout(bool compact); + bool getGroupchatPosition() const; + void setGroupchatPosition(bool value); + public: void save(bool writePersonal = true); void save(QString path, bool writePersonal = true); @@ -272,6 +275,7 @@ private: bool fauxOfflineMessaging; bool compactLayout; + bool groupchatPosition; bool enableIPv6; QString translation; static bool makeToxPortable; diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index eba3e5bb0..e88d615c2 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -77,6 +77,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) : bodyUI->groupAlwaysNotify->setChecked(Settings::getInstance().getGroupAlwaysNotify()); bodyUI->cbFauxOfflineMessaging->setChecked(Settings::getInstance().getFauxOfflineMessaging()); bodyUI->cbCompactLayout->setChecked(Settings::getInstance().getCompactLayout()); + bodyUI->cbGroupchatPosition->setChecked(Settings::getInstance().getGroupchatPosition()); for (auto entry : SmileyPack::listSmileyPacks()) { @@ -154,7 +155,8 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) : connect(bodyUI->reconnectButton, &QPushButton::clicked, this, &GeneralForm::onReconnectClicked); connect(bodyUI->cbFauxOfflineMessaging, &QCheckBox::stateChanged, this, &GeneralForm::onFauxOfflineMessaging); connect(bodyUI->cbCompactLayout, &QCheckBox::stateChanged, this, &GeneralForm::onCompactLayout); - + connect(bodyUI->cbGroupchatPosition, &QCheckBox::stateChanged, this, &GeneralForm::onGroupchatPositionChanged); + // prevent stealing mouse whell scroll // scrolling event won't be transmitted to comboboxes or qspinboxes when scrolling // you can scroll through general settings without accidentially chaning theme/skin/icons etc. @@ -394,6 +396,12 @@ void GeneralForm::onCompactLayout() emit parent->compactToggled(bodyUI->cbCompactLayout->isChecked()); } +void GeneralForm::onGroupchatPositionChanged() +{ + Settings::getInstance().setGroupchatPosition(bodyUI->cbGroupchatPosition->isChecked()); + emit parent->groupchatPositionToggled(bodyUI->cbGroupchatPosition->isChecked()); +} + void GeneralForm::onThemeColorChanged(int) { int index = bodyUI->themeColorCBox->currentIndex(); diff --git a/src/widget/form/settings/generalform.h b/src/widget/form/settings/generalform.h index 33e74d807..1a30927ae 100644 --- a/src/widget/form/settings/generalform.h +++ b/src/widget/form/settings/generalform.h @@ -60,6 +60,7 @@ private slots: void onSetGroupAlwaysNotify(); void onFauxOfflineMessaging(); void onCompactLayout(); + void onGroupchatPositionChanged(); void onThemeColorChanged(int); private: diff --git a/src/widget/form/settings/generalsettings.ui b/src/widget/form/settings/generalsettings.ui index 5e774846e..56d72f191 100644 --- a/src/widget/form/settings/generalsettings.ui +++ b/src/widget/form/settings/generalsettings.ui @@ -374,7 +374,7 @@ instead of system taskbar. Messages you are trying to send to your friends when they are not online -will be sent to them when they will appear online to you. +will be sent to them when they appear online to you. Faux offline messaging @@ -391,6 +391,16 @@ will be sent to them when they will appear online to you. + + + + If checked, groupchats will be placed at the top of the friends list, otherwise, they'll be placed below online friends. + + + Place groupchats at top of friend list + + + diff --git a/src/widget/form/settingswidget.h b/src/widget/form/settingswidget.h index 1cdafabbe..32364a1af 100644 --- a/src/widget/form/settingswidget.h +++ b/src/widget/form/settingswidget.h @@ -44,6 +44,7 @@ public: signals: void setShowSystemTray(bool newValue); void compactToggled(bool compact); + void groupchatPositionToggled(bool groupchatPosition); private slots: void onTabChanged(int); diff --git a/src/widget/friendlistwidget.cpp b/src/widget/friendlistwidget.cpp index 667143b3d..5ba9f2598 100644 --- a/src/widget/friendlistwidget.cpp +++ b/src/widget/friendlistwidget.cpp @@ -16,8 +16,11 @@ #include "friendlistwidget.h" #include #include +#include "src/friend.h" +#include "src/friendlist.h" +#include "src/widget/friendwidget.h" -FriendListWidget::FriendListWidget(QWidget *parent) : +FriendListWidget::FriendListWidget(QWidget *parent, bool groupchatPosition) : QWidget(parent) { mainLayout = new QGridLayout(); @@ -30,7 +33,7 @@ FriendListWidget::FriendListWidget(QWidget *parent) : groupLayout->setSpacing(0); groupLayout->setMargin(0); - for (Status s : {Status::Online, Status::Away, Status::Busy, Status::Offline}) + for (Status s : {Status::Online, Status::Offline}) { QVBoxLayout *l = new QVBoxLayout(); l->setSpacing(0); @@ -39,11 +42,18 @@ FriendListWidget::FriendListWidget(QWidget *parent) : layouts[static_cast(s)] = l; } - mainLayout->addLayout(layouts[static_cast(Status::Online)], 0, 0); - mainLayout->addLayout(groupLayout, 1, 0); - mainLayout->addLayout(layouts[static_cast(Status::Away)], 2, 0); - mainLayout->addLayout(layouts[static_cast(Status::Busy)], 3, 0); - mainLayout->addLayout(layouts[static_cast(Status::Offline)], 4, 0); + if(groupchatPosition) + { + mainLayout->addLayout(groupLayout, 0, 0); + mainLayout->addLayout(layouts[static_cast(Status::Online)], 1, 0); + mainLayout->addLayout(layouts[static_cast(Status::Offline)], 2, 0); + } + else + { + mainLayout->addLayout(layouts[static_cast(Status::Online)], 0, 0); + mainLayout->addLayout(groupLayout, 1, 0); + mainLayout->addLayout(layouts[static_cast(Status::Offline)], 2, 0); + } } QVBoxLayout* FriendListWidget::getGroupLayout() @@ -57,15 +67,43 @@ QVBoxLayout* FriendListWidget::getFriendLayout(Status s) if (res != layouts.end()) return res.value(); - qDebug() << "Friend Status: " << static_cast(s) << " not found!"; + //qDebug() << "Friend Status: " << static_cast(s) << " not found!"; return layouts[static_cast(Status::Online)]; } +void FriendListWidget::onGroupchatPositionChanged(bool top) +{ + mainLayout->removeItem(groupLayout); + mainLayout->removeItem(getFriendLayout(Status::Online)); + if(top) + { + mainLayout->addLayout(groupLayout, 0, 0); + mainLayout->addLayout(layouts[static_cast(Status::Online)], 1, 0); + } + else + { + mainLayout->addLayout(layouts[static_cast(Status::Online)], 0, 0); + mainLayout->addLayout(groupLayout, 1, 0); + } +} + void FriendListWidget::moveWidget(QWidget *w, Status s, int hasNewEvents) { - mainLayout->removeWidget(w); - if (hasNewEvents == 0) - getFriendLayout(s)->addWidget(w); - else - getFriendLayout(s)->insertWidget(0, w); + QVBoxLayout* l = getFriendLayout(s); + l->removeWidget(w); + Friend* g = FriendList::findFriend(dynamic_cast(w)->friendId); + for(int i = 0; i < l->count(); i++) + { + FriendWidget* w1 = dynamic_cast(l->itemAt(i)->widget()); + if(w1 != NULL) + { + Friend* f = FriendList::findFriend(w1->friendId); + if(f->getDisplayedName().localeAwareCompare(g->getDisplayedName()) > 0) + { + l->insertWidget(i,w); + return; + } + } + } + l->addWidget(w); } diff --git a/src/widget/friendlistwidget.h b/src/widget/friendlistwidget.h index 1dbddd45c..70101b885 100644 --- a/src/widget/friendlistwidget.h +++ b/src/widget/friendlistwidget.h @@ -29,15 +29,15 @@ class FriendListWidget : public QWidget { Q_OBJECT public: - explicit FriendListWidget(QWidget *parent = 0); - + explicit FriendListWidget(QWidget *parent = 0, bool groupchatPosition = true); QVBoxLayout* getGroupLayout(); QVBoxLayout* getFriendLayout(Status s); - void moveWidget(QWidget *w, Status s, int hasNewEvents); signals: public slots: + void onGroupchatPositionChanged(bool top); + void moveWidget(QWidget *w, Status s, int hasNewEvents); private: QHash layouts; diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 5804e2561..1d4b3f5c8 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -144,7 +144,7 @@ void Widget::init() ui->statusHead->setStyleSheet(Style::getStylesheet(":/ui/window/statusPanel.css")); - contactListWidget = new FriendListWidget(); + contactListWidget = new FriendListWidget(0, Settings::getInstance().getGroupchatPosition()); ui->friendList->setWidget(contactListWidget); ui->friendList->setLayoutDirection(Qt::RightToLeft); @@ -197,6 +197,7 @@ void Widget::init() addFriendForm->show(*ui); + connect(settingsWidget, &SettingsWidget::groupchatPositionToggled, contactListWidget, &FriendListWidget::onGroupchatPositionChanged); #if (AUTOUPDATE_ENABLED) if (Settings::getInstance().getCheckUpdates()) AutoUpdater::checkUpdatesAsyncInteractive(); @@ -561,10 +562,10 @@ void Widget::addFriend(int friendId, const QString &userId) //qDebug() << "Widget: Adding friend with id" << userId; ToxID userToxId = ToxID::fromString(userId); Friend* newfriend = FriendList::addFriend(friendId, userToxId); - QLayout* layout = contactListWidget->getFriendLayout(Status::Offline); - layout->addWidget(newfriend->getFriendWidget()); + contactListWidget->moveWidget(newfriend->getFriendWidget(),Status::Offline,0); Core* core = Nexus::getCore(); + connect(newfriend, &Friend::displayedNameChanged, contactListWidget, &FriendListWidget::moveWidget); connect(settingsWidget, &SettingsWidget::compactToggled, newfriend->getFriendWidget(), &GenericChatroomWidget::onCompactChanged); connect(newfriend->getFriendWidget(), SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*))); connect(newfriend->getFriendWidget(), SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int))); @@ -625,11 +626,21 @@ void Widget::onFriendStatusChanged(int friendId, Status status) Friend* f = FriendList::findFriend(friendId); if (!f) return; - - contactListWidget->moveWidget(f->getFriendWidget(), status, f->getEventFlag()); - + bool isActualChange = f->getStatus() != status; + if(isActualChange) + { + if(f->getStatus() == Status::Offline) + { + contactListWidget->moveWidget(f->getFriendWidget(), Status::Online, f->getEventFlag()); + } + else if(status == Status::Offline) + { + contactListWidget->moveWidget(f->getFriendWidget(), Status::Offline, f->getEventFlag()); + } + } + f->setStatus(status); f->getFriendWidget()->updateStatusLight();