From add8d51a2913fa6979674247696da9d397d252b5 Mon Sep 17 00:00:00 2001 From: Diadlo Date: Sun, 26 Feb 2017 17:22:28 +0300 Subject: [PATCH] refactor: ContentDialog refactoring --- src/core/corestructs.h | 2 +- src/widget/contentdialog.cpp | 515 +++++++++++++++++++---------------- src/widget/contentdialog.h | 38 +-- src/widget/friendwidget.cpp | 7 +- src/widget/groupwidget.cpp | 8 +- src/widget/widget.cpp | 17 +- 6 files changed, 319 insertions(+), 268 deletions(-) diff --git a/src/core/corestructs.h b/src/core/corestructs.h index 93ec81041..71ebbfcf7 100644 --- a/src/core/corestructs.h +++ b/src/core/corestructs.h @@ -7,7 +7,7 @@ class QFile; class QTimer; -enum class Status : int +enum class Status { Online = 0, Away, diff --git a/src/widget/contentdialog.cpp b/src/widget/contentdialog.cpp index 72f4de3f4..e8b1d139b 100644 --- a/src/widget/contentdialog.cpp +++ b/src/widget/contentdialog.cpp @@ -44,38 +44,50 @@ #include "src/widget/translator.h" #include "tool/adjustingscrollarea.h" +QString ContentDialog::username = ""; ContentDialog* ContentDialog::currentDialog = nullptr; QHash> ContentDialog::friendList; QHash> ContentDialog::groupList; +static const int minWidget = 220; +static const int minHeight = 220; +static const QSize minSize(minHeight, minWidget); +static const QSize defaultSize(720, 400); + ContentDialog::ContentDialog(SettingsWidget* settingsWidget, QWidget* parent) : ActivateDialog(parent, Qt::Window) + , splitter{new QSplitter(this)} + , friendLayout{new FriendListLayout(this)} , activeChatroomWidget(nullptr) , settingsWidget(settingsWidget) , videoSurfaceSize(QSize()) , videoCount(0) { - QVBoxLayout* boxLayout = new QVBoxLayout(this); - boxLayout->setMargin(0); - boxLayout->setSpacing(0); - - splitter = new QSplitter(this); + const Settings& s = Settings::getInstance(); setStyleSheet(Style::getStylesheet(":/ui/contentDialog/contentDialog.css")); - splitter->setHandleWidth(6); + + friendLayout->setMargin(0); + friendLayout->setSpacing(0); + + layouts = { + friendLayout->getLayoutOnline(), + groupLayout.getLayout(), + friendLayout->getLayoutOffline() + }; + + if (s.getGroupchatPosition()) { + layouts.swap(0, 1); + } QWidget* friendWidget = new QWidget(); friendWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); friendWidget->setAutoFillBackground(true); - - friendLayout = new FriendListLayout(); - friendLayout->setMargin(0); - friendLayout->setSpacing(0); friendWidget->setLayout(friendLayout); - onGroupchatPositionChanged(Settings::getInstance().getGroupchatPosition()); + onGroupchatPositionChanged(s.getGroupchatPosition()); QScrollArea* friendScroll = new QScrollArea(this); - friendScroll->setMinimumWidth(220); + friendScroll->setMinimumWidth(minWidget); friendScroll->setFrameStyle(QFrame::NoFrame); friendScroll->setLayoutDirection(Qt::RightToLeft); friendScroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -85,6 +97,7 @@ ContentDialog::ContentDialog(SettingsWidget* settingsWidget, QWidget* parent) QWidget* contentWidget = new QWidget(this); contentWidget->setAutoFillBackground(true); + contentLayout = new ContentLayout(contentWidget); contentLayout->setMargin(0); contentLayout->setSpacing(0); @@ -93,13 +106,13 @@ ContentDialog::ContentDialog(SettingsWidget* settingsWidget, QWidget* parent) splitter->addWidget(contentWidget); splitter->setStretchFactor(1, 1); splitter->setCollapsible(1, false); + + QVBoxLayout* boxLayout = new QVBoxLayout(this); + boxLayout->setMargin(0); + boxLayout->setSpacing(0); boxLayout->addWidget(splitter); - const Settings& s = Settings::getInstance(); - connect(&s, &Settings::groupchatPositionChanged, this, &ContentDialog::onGroupchatPositionChanged); - connect(splitter, &QSplitter::splitterMoved, this, &ContentDialog::saveSplitterState); - - setMinimumSize(500, 220); + setMinimumSize(minSize); setAttribute(Qt::WA_DeleteOnClose); QByteArray geometry = s.getDialogGeometry(); @@ -107,12 +120,11 @@ ContentDialog::ContentDialog(SettingsWidget* settingsWidget, QWidget* parent) if (!geometry.isNull()) { restoreGeometry(geometry); } else { - resize(720, 400); + resize(defaultSize); } - QByteArray splitterState = s.getDialogSplitterState(); SplitterRestorer restorer(splitter); - restorer.restore(splitterState, size()); + restorer.restore(s.getDialogSettingsGeometry(), size()); currentDialog = this; setAcceptDrops(true); @@ -123,35 +135,30 @@ ContentDialog::ContentDialog(SettingsWidget* settingsWidget, QWidget* parent) new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(previousContact())); new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(nextContact())); - connect(Core::getInstance(), &Core::usernameSet, this, &ContentDialog::updateTitleAndStatusIcon); + connect(&s, &Settings::groupchatPositionChanged, this, &ContentDialog::onGroupchatPositionChanged); + connect(splitter, &QSplitter::splitterMoved, this, &ContentDialog::saveSplitterState); Translator::registerHandler(std::bind(&ContentDialog::retranslateUi, this), this); } +void ContentDialog::removeCurrent(QHash& infos) { + for (auto it = infos.begin(); it != infos.end(); ) { + if (std::get<0>(*it) == this) { + it = infos.erase(it); + } else { + ++it; + } + } +} + ContentDialog::~ContentDialog() { - if (currentDialog == this) + if (currentDialog == this) { currentDialog = nullptr; - - auto friendIt = friendList.begin(); - - while (friendIt != friendList.end()) { - if (std::get<0>(friendIt.value()) == this) { - friendIt = friendList.erase(friendIt); - continue; - } - ++friendIt; } - auto groupIt = groupList.begin(); - - while (groupIt != groupList.end()) { - if (std::get<0>(groupIt.value()) == this) { - groupIt = groupList.erase(groupIt); - continue; - } - ++groupIt; - } + removeCurrent(friendList); + removeCurrent(groupList); Translator::unregister(this); } @@ -159,24 +166,19 @@ ContentDialog::~ContentDialog() FriendWidget* ContentDialog::addFriend(int friendId, QString id) { FriendWidget* friendWidget = new FriendWidget(friendId, id); - friendLayout->addFriendWidget(friendWidget, FriendList::findFriend(friendId)->getStatus()); - Friend* frnd = friendWidget->getFriend(); + friendLayout->addFriendWidget(friendWidget, frnd->getStatus()); connect(frnd, &Friend::aliasChanged, this, &ContentDialog::updateFriendWidget); connect(friendWidget, &FriendWidget::chatroomWidgetClicked, this, &ContentDialog::onChatroomWidgetClicked); connect(friendWidget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), frnd->getChatForm(), SLOT(focusInput())); - connect(Core::getInstance(), &Core::friendAvatarChanged, friendWidget, - &FriendWidget::onAvatarChange); - connect(Core::getInstance(), &Core::friendAvatarRemoved, friendWidget, - &FriendWidget::onAvatarRemoved); ContentDialog* lastDialog = getFriendDialog(friendId); - - if (lastDialog != nullptr) + if (lastDialog) { lastDialog->removeFriend(friendId); + } friendList.insert(friendId, std::make_tuple(this, friendWidget)); // FIXME: emit should be removed @@ -198,8 +200,9 @@ GroupWidget* ContentDialog::addGroup(int groupId, const QString& name) ContentDialog* lastDialog = getGroupDialog(groupId); - if (lastDialog != nullptr) + if (lastDialog) { lastDialog->removeGroup(groupId); + } groupList.insert(groupId, std::make_tuple(this, groupWidget)); // FIXME: emit should be removed @@ -211,17 +214,18 @@ GroupWidget* ContentDialog::addGroup(int groupId, const QString& name) void ContentDialog::removeFriend(int friendId) { auto iter = friendList.find(friendId); - - if (iter == friendList.end()) + if (iter == friendList.end()) { return; + } FriendWidget* chatroomWidget = static_cast(std::get<1>(iter.value())); disconnect(chatroomWidget->getFriend(), &Friend::aliasChanged, this, &ContentDialog::updateFriendWidget); // Need to find replacement to show here instead. - if (activeChatroomWidget == chatroomWidget) + if (activeChatroomWidget == chatroomWidget) { cycleContacts(true, false); + } friendLayout->removeFriendWidget(chatroomWidget, Status::Offline); friendLayout->removeFriendWidget(chatroomWidget, Status::Online); @@ -248,15 +252,16 @@ void ContentDialog::removeGroup(int groupId) } auto iter = groupList.find(groupId); - - if (iter == groupList.end()) + if (iter == groupList.end()) { return; + } GenericChatroomWidget* chatroomWidget = std::get<1>(iter.value()); // Need to find replacement to show here instead. - if (activeChatroomWidget == chatroomWidget) + if (activeChatroomWidget == chatroomWidget) { cycleContacts(true, false); + } groupLayout.removeSortedWidget(chatroomWidget); chatroomWidget->deleteLater(); @@ -288,75 +293,90 @@ int ContentDialog::chatroomWidgetCount() const void ContentDialog::ensureSplitterVisible() { - if (splitter->sizes().at(0) == 0) + if (splitter->sizes().at(0) == 0) { splitter->setSizes({1, 1}); + } update(); } -void ContentDialog::cycleContacts(bool forward, bool loop) +int ContentDialog::getCurrentLayout(QLayout*& layout) { - Settings::getInstance().getGroupchatPosition(); - - int index; - QLayout* currentLayout; - if (activeChatroomWidget->getFriend()) { - currentLayout = friendLayout->getLayoutOnline(); - index = friendLayout->indexOfFriendWidget(activeChatroomWidget, true); - if (index == -1) { - currentLayout = friendLayout->getLayoutOffline(); - index = friendLayout->indexOfFriendWidget(activeChatroomWidget, false); - } - } else { - currentLayout = groupLayout.getLayout(); - index = groupLayout.indexOfSortedWidget(activeChatroomWidget); + layout = friendLayout->getLayoutOnline(); + int index = friendLayout->indexOfFriendWidget(activeChatroomWidget, true); + if (index != -1) { + return index; } - if (!loop && index == currentLayout->count() - 1) { + layout = friendLayout->getLayoutOffline(); + index = friendLayout->indexOfFriendWidget(activeChatroomWidget, false); + if (index != -1) { + return index; + } + + layout = groupLayout.getLayout(); + index = groupLayout.indexOfSortedWidget(activeChatroomWidget); + if (index != -1) { + return index; + } + + layout = nullptr; + return -1; +} + +void ContentDialog::cycleContacts(bool forward, bool inverse) +{ + QLayout* currentLayout; + int index = getCurrentLayout(currentLayout); + if (!currentLayout || index == -1) { + return; + } + + if (!inverse && index == currentLayout->count() - 1) { bool groupsOnTop = Settings::getInstance().getGroupchatPosition(); bool offlineEmpty = friendLayout->getLayoutOffline()->isEmpty(); - bool onlineEmpty = - offlineEmpty && (friendLayout->getLayoutOnline()->isEmpty() || !groupsOnTop); - bool groupsEmpty = offlineEmpty && (groupLayout.getLayout()->isEmpty() || groupsOnTop); + bool onlineEmpty = friendLayout->getLayoutOnline()->isEmpty(); + bool groupsEmpty = groupLayout.getLayout()->isEmpty(); + bool isCurOffline = currentLayout == friendLayout->getLayoutOffline(); + bool isCurOnline = currentLayout == friendLayout->getLayoutOnline(); + bool isCurGroup = currentLayout == groupLayout.getLayout(); + bool nextIsEmpty = isCurOnline && offlineEmpty && (groupsEmpty || groupsOnTop) || + isCurGroup && offlineEmpty && (onlineEmpty || !groupsOnTop) || + isCurOffline; - if ((currentLayout == friendLayout->getLayoutOffline()) - || (currentLayout == friendLayout->getLayoutOnline() && groupsEmpty) - || (currentLayout == groupLayout.getLayout() && onlineEmpty)) { + if (nextIsEmpty) { forward = !forward; } } index += forward ? 1 : -1; - - for (;;) { - // Bounds checking. + // If goes out of the layout, then go to the next and skip empty. This loop goes more + // then 1 time, because for empty layout index will be out of interval (0 < 0 || 0 >= 0) + while (index < 0 || index >= currentLayout->count()) { + int oldCount = currentLayout->count(); + currentLayout = nextLayout(currentLayout, forward); + int newCount = currentLayout->count(); if (index < 0) { - currentLayout = nextLayout(currentLayout, forward); - index = currentLayout->count() - 1; - continue; - } else if (index >= currentLayout->count()) { - currentLayout = nextLayout(currentLayout, forward); + index = newCount - 1; + } else if (index >= oldCount) { index = 0; - continue; } + } - GenericChatroomWidget* chatWidget = - qobject_cast(currentLayout->itemAt(index)->widget()); - - if (chatWidget != nullptr && chatWidget != activeChatroomWidget) { - // FIXME: emit should be removed - emit chatWidget->chatroomWidgetClicked(chatWidget, false); - } - - return; + QWidget* widget = currentLayout->itemAt(index)->widget(); + GenericChatroomWidget* chatWidget = qobject_cast(widget); + if (chatWidget && chatWidget != activeChatroomWidget) { + // FIXME: emit should be removed + emit chatWidget->chatroomWidgetClicked(chatWidget, false); } } void ContentDialog::onVideoShow(QSize size) { ++videoCount; - if (videoCount > 1) + if (videoCount > 1) { return; + } videoSurfaceSize = size; QSize minSize = minimumSize(); @@ -366,8 +386,9 @@ void ContentDialog::onVideoShow(QSize size) void ContentDialog::onVideoHide() { videoCount--; - if (videoCount > 0) + if (videoCount > 0) { return; + } QSize minSize = minimumSize(); setMinimumSize(minSize - videoSurfaceSize); @@ -379,25 +400,37 @@ ContentDialog* ContentDialog::current() return currentDialog; } -bool ContentDialog::existsFriendWidget(int friendId, bool focus) +bool ContentDialog::existsFriendWidget(int friendId) { - return existsWidget(friendId, focus, friendList); + return existsWidget(friendId, friendList); } -bool ContentDialog::existsGroupWidget(int groupId, bool focus) +bool ContentDialog::existsGroupWidget(int groupId) { - return existsWidget(groupId, focus, groupList); + return existsWidget(groupId, groupList); +} + +void ContentDialog::focusFriend(int friendId) +{ + focusDialog(friendId, friendList); +} + +void ContentDialog::focusGroup(int groupId) +{ + focusDialog(groupId, groupList); } void ContentDialog::updateFriendStatus(int friendId) { updateStatus(friendId, friendList); ContentDialog* contentDialog = getFriendDialog(friendId); - if (contentDialog != nullptr) { - FriendWidget* friendWidget = - static_cast(std::get<1>(friendList.find(friendId).value())); - contentDialog->friendLayout->addFriendWidget(friendWidget, - FriendList::findFriend(friendId)->getStatus()); + if (contentDialog) { + auto iter = friendList.find(friendId).value(); + GenericChatroomWidget* widget = std::get<1>(iter); + FriendWidget* friendWidget = static_cast(widget); + + Friend* f = FriendList::findFriend(friendId); + contentDialog->friendLayout->addFriendWidget(friendWidget, f->getStatus()); } } @@ -405,8 +438,9 @@ void ContentDialog::updateFriendStatusMessage(int friendId, const QString& messa { auto iter = friendList.find(friendId); - if (iter == friendList.end()) + if (iter == friendList.end()) { return; + } std::get<1>(iter.value())->setStatusMsg(message); } @@ -436,42 +470,43 @@ ContentDialog* ContentDialog::getGroupDialog(int groupId) return getDialog(groupId, groupList); } -void ContentDialog::updateTitleAndStatusIcon(const QString& username) +void ContentDialog::updateTitleAndStatusIcon() { - if (displayWidget != nullptr) { - - setWindowTitle(displayWidget->getTitle() + QStringLiteral(" - ") + username); - - // it's null when it's a groupchat - if (displayWidget->getFriend() == nullptr) { - setWindowIcon(QIcon(":/img/group.svg")); - return; - } - - Status currentStatus = displayWidget->getFriend()->getStatus(); - - switch (currentStatus) { - case Status::Online: - setWindowIcon(QIcon(":/img/status/dot_online.svg")); - break; - case Status::Away: - setWindowIcon(QIcon(":/img/status/dot_away.svg")); - break; - case Status::Busy: - setWindowIcon(QIcon(":/img/status/dot_busy.svg")); - break; - case Status::Offline: - setWindowIcon(QIcon(":/img/status/dot_offline.svg")); - break; - } - } else + if (!activeChatroomWidget) { setWindowTitle(username); + return; + } + + setWindowTitle(activeChatroomWidget->getTitle() + QStringLiteral(" - ") + username); + + bool isGroupchat = activeChatroomWidget->getGroup() != nullptr; + if (isGroupchat) { + setWindowIcon(QIcon(":/img/group.svg")); + return; + } + + Status currentStatus = activeChatroomWidget->getFriend()->getStatus(); + + QMap icons { + {Status::Online, QIcon(":/img/status/dot_online.svg")}, + {Status::Away, QIcon(":/img/status/dot_away.svg")}, + {Status::Busy, QIcon(":/img/status/dot_busy.svg")}, + {Status::Offline, QIcon(":/img/status/dot_offline.svg")} + }; + + setWindowIcon(icons[currentStatus]); } -void ContentDialog::updateTitle(GenericChatroomWidget* chatroomWidget) +/** + * @brief Update layouts order according to settings. + * @param groupOnTop If true move groupchat layout on the top. Move under online otherwise. + */ +void ContentDialog::reorderLayouts(bool newGroupOnTop) { - displayWidget = chatroomWidget; - updateTitleAndStatusIcon(Core::getInstance()->getUsername()); + bool oldGroupOnTop = layouts.first() == groupLayout.getLayout(); + if (newGroupOnTop != oldGroupOnTop) { + layouts.swap(0, 1); + } } void ContentDialog::previousContact() @@ -484,14 +519,21 @@ void ContentDialog::nextContact() cycleContacts(true); } +void ContentDialog::setUsername(const QString& newName) +{ + username = newName; + updateTitleAndStatusIcon(); +} + bool ContentDialog::event(QEvent* event) { switch (event->type()) { case QEvent::WindowActivate: - if (activeChatroomWidget != nullptr) { + if (activeChatroomWidget) { activeChatroomWidget->resetEventFlags(); activeChatroomWidget->updateStatusLight(); - updateTitle(activeChatroomWidget); + + updateTitleAndStatusIcon(); Friend* frnd = activeChatroomWidget->getFriend(); Group* group = activeChatroomWidget->getGroup(); @@ -523,27 +565,32 @@ void ContentDialog::dragEnterEvent(QDragEnterEvent* event) if (frnd) { ToxId toxId(event->mimeData()->text()); Friend* contact = FriendList::findFriend(toxId.getPublicKey()); - if (!contact) + if (!contact) { return; + } int friendId = contact->getFriendId(); auto iter = friendList.find(friendId); // If friend is already in a dialog then you can't drop friend where it already is. - if (iter == friendList.end() || std::get<0>(iter.value()) != this) + if (iter == friendList.end() || std::get<0>(iter.value()) != this) { event->acceptProposedAction(); + } } else if (group) { - if (!event->mimeData()->hasFormat("groupId")) + if (!event->mimeData()->hasFormat("groupId")) { return; + } int groupId = event->mimeData()->data("groupId").toInt(); Group* contact = GroupList::findGroup(groupId); - if (!contact) + if (!contact) { return; + } auto iter = groupList.find(groupId); - if (iter == groupList.end() || std::get<0>(iter.value()) != this) + if (iter == groupList.end() || std::get<0>(iter.value()) != this) { event->acceptProposedAction(); + } } } @@ -555,28 +602,33 @@ void ContentDialog::dropEvent(QDropEvent* event) if (frnd) { ToxId toxId(event->mimeData()->text()); Friend* contact = FriendList::findFriend(toxId.getPublicKey()); - if (!contact) + if (!contact) { return; + } int friendId = contact->getFriendId(); auto iter = friendList.find(friendId); - if (iter != friendList.end()) + if (iter != friendList.end()) { std::get<0>(iter.value())->removeFriend(friendId); + } Widget::getInstance()->addFriendDialog(contact, this); ensureSplitterVisible(); } else if (group) { - if (!event->mimeData()->hasFormat("groupId")) + if (!event->mimeData()->hasFormat("groupId")) { return; + } int groupId = event->mimeData()->data("groupId").toInt(); Group* contact = GroupList::findGroup(groupId); - if (!contact) + if (!contact) { return; + } auto iter = friendList.find(groupId); - if (iter != friendList.end()) + if (iter != friendList.end()) { std::get<0>(iter.value())->removeGroup(groupId); + } Widget::getInstance()->addGroupDialog(contact, this); ensureSplitterVisible(); @@ -587,8 +639,9 @@ void ContentDialog::changeEvent(QEvent* event) { QWidget::changeEvent(event); if (event->type() == QEvent::ActivationChange) { - if (isActiveWindow()) + if (isActiveWindow()) { currentDialog = this; + } } } @@ -606,8 +659,10 @@ void ContentDialog::moveEvent(QMoveEvent* event) void ContentDialog::keyPressEvent(QKeyEvent* event) { - if (event->key() != Qt::Key_Escape) - QDialog::keyPressEvent(event); // Ignore escape keyboard shortcut. + // Ignore escape keyboard shortcut. + if (event->key() != Qt::Key_Escape) { + QDialog::keyPressEvent(event); + } } void ContentDialog::onChatroomWidgetClicked(GenericChatroomWidget* widget, bool group) @@ -616,7 +671,7 @@ void ContentDialog::onChatroomWidgetClicked(GenericChatroomWidget* widget, bool ContentDialog* contentDialog = new ContentDialog(settingsWidget); contentDialog->show(); - if (widget->getFriend() != nullptr) { + if (widget->getFriend()) { removeFriend(widget->getFriend()->getFriendId()); Widget::getInstance()->addFriendDialog(widget->getFriend(), contentDialog); } else { @@ -631,13 +686,15 @@ void ContentDialog::onChatroomWidgetClicked(GenericChatroomWidget* widget, bool } // If we clicked on the currently active widget, don't reload and relayout everything - if (activeChatroomWidget == widget) + if (activeChatroomWidget == widget) { return; + } contentLayout->clear(); - if (activeChatroomWidget != nullptr) + if (activeChatroomWidget) { activeChatroomWidget->setAsInactiveChatroom(); + } activeChatroomWidget = widget; @@ -645,7 +702,8 @@ void ContentDialog::onChatroomWidgetClicked(GenericChatroomWidget* widget, bool widget->setAsActiveChatroom(); widget->resetEventFlags(); widget->updateStatusLight(); - updateTitle(widget); + + updateTitleAndStatusIcon(); } void ContentDialog::updateFriendWidget(uint32_t friendId, QString alias) @@ -661,23 +719,23 @@ void ContentDialog::updateFriendWidget(uint32_t friendId, QString alias) void ContentDialog::updateGroupWidget(GroupWidget* w) { - std::get<1>(groupList.find(w->groupId).value())->setName(w->getName()); - static_cast(std::get<1>(groupList.find(w->groupId).value()))->onUserListChanged(); + ContactInfo info = groupList.find(w->groupId).value(); + GroupWidget* widget = static_cast(std::get<1>(info)); + + QString name = w->getName(); + widget->setName(name); + widget->onUserListChanged(); } void ContentDialog::onGroupchatPositionChanged(bool top) { friendLayout->removeItem(groupLayout.getLayout()); - - if (top) - friendLayout->insertLayout(0, groupLayout.getLayout()); - else - friendLayout->insertLayout(1, groupLayout.getLayout()); + friendLayout->insertLayout(top ? 0 : 1, groupLayout.getLayout()); } void ContentDialog::retranslateUi() { - updateTitleAndStatusIcon(Core::getInstance()->getUsername()); + updateTitleAndStatusIcon(); } void ContentDialog::saveDialogGeometry() @@ -691,111 +749,86 @@ void ContentDialog::saveSplitterState() } bool ContentDialog::hasWidget(int id, GenericChatroomWidget* chatroomWidget, - const QHash>& list) + const QHash& list) { auto iter = list.find(id); - - if (iter == list.end() || std::get<0>(iter.value()) != this) + if (iter == list.end()) { return false; - - return chatroomWidget == std::get<1>(iter.value()); -} - -bool ContentDialog::existsWidget(int id, bool focus, - const QHash>& list) -{ - auto iter = list.find(id); - if (iter == list.end()) - return false; - - if (focus) { - if (std::get<0>(iter.value())->windowState() & Qt::WindowMinimized) - std::get<0>(iter.value())->showNormal(); - - std::get<0>(iter.value())->raise(); - std::get<0>(iter.value())->activateWindow(); - std::get<0>(iter.value())->onChatroomWidgetClicked(std::get<1>(iter.value()), false); } - return true; + return std::get<0>(*iter) == this && + std::get<1>(*iter) == chatroomWidget; } -void ContentDialog::updateStatus(int id, - const QHash>& list) +void ContentDialog::focusDialog(int id, const QHash& list) { auto iter = list.find(id); - - if (iter == list.end()) + if (iter == list.end()) { return; + } - GenericChatroomWidget* chatroomWidget = std::get<1>(iter.value()); + ContentDialog* dialog = std::get<0>(*iter); + if (dialog->windowState() & Qt::WindowMinimized) { + dialog->showNormal(); + } + + dialog->raise(); + dialog->activateWindow(); + dialog->onChatroomWidgetClicked(std::get<1>(iter.value()), false); +} + +bool ContentDialog::existsWidget(int id, const QHash& list) +{ + auto iter = list.find(id); + return iter != list.end(); +} + +void ContentDialog::updateStatus(int id, const QHash& list) +{ + auto iter = list.find(id); + if (iter == list.end()) { + return; + } + + GenericChatroomWidget* chatroomWidget = std::get<1>(*iter); chatroomWidget->updateStatusLight(); - if (chatroomWidget->isActive()) - std::get<0>(iter.value())->updateTitle(chatroomWidget); + if (chatroomWidget->isActive()) { + ContentDialog* dialog = std::get<0>(*iter); + dialog->updateTitleAndStatusIcon(); + } } -bool ContentDialog::isWidgetActive( - int id, const QHash>& list) +bool ContentDialog::isWidgetActive(int id, const QHash& list) { auto iter = list.find(id); - - if (iter == list.end()) + if (iter == list.end()) { return false; + } return std::get<0>(iter.value())->activeChatroomWidget == std::get<1>(iter.value()); } -ContentDialog* -ContentDialog::getDialog(int id, - const QHash>& list) +ContentDialog* ContentDialog::getDialog(int id, const QHash& list) { auto iter = list.find(id); - - if (iter == list.end()) + if (iter == list.end()) { return nullptr; + } return std::get<0>(iter.value()); } QLayout* ContentDialog::nextLayout(QLayout* layout, bool forward) const { - if (layout == groupLayout.getLayout()) { - if (forward) { - if (Settings::getInstance().getGroupchatPosition()) - return friendLayout->getLayoutOnline(); - - return friendLayout->getLayoutOffline(); - } else { - if (Settings::getInstance().getGroupchatPosition()) - return friendLayout->getLayoutOffline(); - - return friendLayout->getLayoutOnline(); - } - } else if (layout == friendLayout->getLayoutOnline()) { - if (forward) { - if (Settings::getInstance().getGroupchatPosition()) - return friendLayout->getLayoutOffline(); - - return groupLayout.getLayout(); - } else { - if (Settings::getInstance().getGroupchatPosition()) - return groupLayout.getLayout(); - - return friendLayout->getLayoutOffline(); - } - } else if (layout == friendLayout->getLayoutOffline()) { - if (forward) { - if (Settings::getInstance().getGroupchatPosition()) - return groupLayout.getLayout(); - - return friendLayout->getLayoutOnline(); - } else { - if (Settings::getInstance().getGroupchatPosition()) - return friendLayout->getLayoutOnline(); - - return groupLayout.getLayout(); - } + int index = layouts.indexOf(layout); + if (index == -1) { + return nullptr; } - return nullptr; + + int next = forward ? index + 1 : index - 1; + size_t size = layouts.size(); + next = (next + size) % size; + + return layouts[next]; } diff --git a/src/widget/contentdialog.h b/src/widget/contentdialog.h index 0dcea104a..95c4bcd2c 100644 --- a/src/widget/contentdialog.h +++ b/src/widget/contentdialog.h @@ -33,6 +33,7 @@ class QSet; class QSplitter; class QVBoxLayout; +class ContentDialog; class ContentLayout; class GenericChatroomWidget; class FriendWidget; @@ -42,6 +43,8 @@ class SettingsWidget; class Friend; class Group; +using ContactInfo = std::tuple; + class ContentDialog : public ActivateDialog { Q_OBJECT @@ -57,14 +60,17 @@ public: bool hasGroupWidget(int groupId, GenericChatroomWidget* chatroomWidget); int chatroomWidgetCount() const; void ensureSplitterVisible(); + void updateTitleAndStatusIcon(); void cycleContacts(bool forward, bool loop = true); void onVideoShow(QSize size); void onVideoHide(); static ContentDialog* current(); - static bool existsFriendWidget(int friendId, bool focus); - static bool existsGroupWidget(int groupId, bool focus); + static bool existsFriendWidget(int friendId); + static bool existsGroupWidget(int groupId); + static void focusFriend(int friendId); + static void focusGroup(int groupId); static void updateFriendStatus(int friendId); static void updateFriendStatusMessage(int friendId, const QString& message); static void updateGroupStatus(int groupId); @@ -79,10 +85,10 @@ signals: void activated(); public slots: - void updateTitleAndStatusIcon(const QString& username); - void updateTitle(GenericChatroomWidget* chatroomWidget); + void reorderLayouts(bool newGroupOnTop); void previousContact(); void nextContact(); + void setUsername(const QString& newName); protected: bool event(QEvent* event) final override; @@ -104,31 +110,31 @@ private: void saveDialogGeometry(); void saveSplitterState(); QLayout* nextLayout(QLayout* layout, bool forward) const; + int getCurrentLayout(QLayout*& layout); bool hasWidget(int id, GenericChatroomWidget* chatroomWidget, - const QHash>& list); - static bool existsWidget(int id, bool focus, - const QHash>& list); - static void - updateStatus(int id, const QHash>& list); - static bool - isWidgetActive(int id, const QHash>& list); - static ContentDialog* - getDialog(int id, const QHash>& list); + const QHash& list); + void removeCurrent(QHash& infos); + static bool existsWidget(int id, const QHash& list); + static void focusDialog(int id, const QHash& list); + static void updateStatus(int id, const QHash& list); + static bool isWidgetActive(int id, const QHash& list); + static ContentDialog* getDialog(int id, const QHash& list); + QList layouts; QSplitter* splitter; FriendListLayout* friendLayout; GenericChatItemLayout groupLayout; ContentLayout* contentLayout; GenericChatroomWidget* activeChatroomWidget; - GenericChatroomWidget* displayWidget = nullptr; SettingsWidget* settingsWidget; QSize videoSurfaceSize; int videoCount; + static QString username; static ContentDialog* currentDialog; - static QHash> friendList; - static QHash> groupList; + static QHash friendList; + static QHash groupList; }; #endif // CONTENTDIALOG_H diff --git a/src/widget/friendwidget.cpp b/src/widget/friendwidget.cpp index 7ff027960..90176a63e 100644 --- a/src/widget/friendwidget.cpp +++ b/src/widget/friendwidget.cpp @@ -363,7 +363,12 @@ void FriendWidget::search(const QString& searchString, bool hide) bool FriendWidget::chatFormIsSet(bool focus) const { Friend* f = FriendList::findFriend(friendId); - return ContentDialog::existsFriendWidget(friendId, focus) || f->getChatForm()->isVisible(); + if (focus) { + ContentDialog::focusFriend(friendId); + } + + bool exist = ContentDialog::existsFriendWidget(friendId); + return exist || f->getChatForm()->isVisible(); } void FriendWidget::setChatForm(ContentLayout* contentLayout) diff --git a/src/widget/groupwidget.cpp b/src/widget/groupwidget.cpp index ffdd1681d..3c956e178 100644 --- a/src/widget/groupwidget.cpp +++ b/src/widget/groupwidget.cpp @@ -200,9 +200,13 @@ Group* GroupWidget::getGroup() const bool GroupWidget::chatFormIsSet(bool focus) const { - (void)focus; Group* g = GroupList::findGroup(groupId); - return ContentDialog::existsGroupWidget(groupId, focus) || g->getChatForm()->isVisible(); + if (focus) { + ContentDialog::focusGroup(groupId); + } + + bool exist = ContentDialog::existsGroupWidget(groupId); + return exist || g->getChatForm()->isVisible(); } void GroupWidget::setChatForm(ContentLayout* contentLayout) diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 78ebfa1e7..a879d905a 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -1457,16 +1457,19 @@ ContentDialog* Widget::createContentDialog() const ContentDialog* contentDialog = new ContentDialog(settingsWidget); connect(contentDialog, &ContentDialog::friendDialogShown, this, &Widget::onFriendDialogShown); connect(contentDialog, &ContentDialog::groupDialogShown, this, &Widget::onGroupDialogShown); + connect(Core::getInstance(), &Core::usernameSet, contentDialog, &ContentDialog::setUsername); + + Settings& s = Settings::getInstance(); + connect(&s, &Settings::groupchatPositionChanged, contentDialog, &ContentDialog::reorderLayouts); #ifdef Q_OS_MAC - connect(contentDialog, &ContentDialog::destroyed, &Nexus::getInstance(), - &Nexus::updateWindowsClosed); - connect(contentDialog, &ContentDialog::windowStateChanged, &Nexus::getInstance(), - &Nexus::onWindowStateChanged); - connect(contentDialog->windowHandle(), &QWindow::windowTitleChanged, &Nexus::getInstance(), - &Nexus::updateWindows); - Nexus::getInstance().updateWindows(); + Nexus &n = Nexus::getInstance(); + connect(contentDialog, &ContentDialog::destroyed, &n, &Nexus::updateWindowsClosed); + connect(contentDialog, &ContentDialog::windowStateChanged, &n, &Nexus::onWindowStateChanged); + connect(contentDialog->windowHandle(), &QWindow::windowTitleChanged, &n, &Nexus::updateWindows); + n.updateWindows(); #endif + return contentDialog; }