diff --git a/src/widget/contentdialog.cpp b/src/widget/contentdialog.cpp index e4d95bff1..ae0097d76 100644 --- a/src/widget/contentdialog.cpp +++ b/src/widget/contentdialog.cpp @@ -156,6 +156,7 @@ FriendWidget* ContentDialog::addFriend(std::shared_ptr chatroom, auto frnd = chatroom->getFriend(); auto friendId = frnd->getId(); auto friendWidget = new FriendWidget(chatroom, compact); + friendWidgets[friendId] = friendWidget; friendLayout->addFriendWidget(friendWidget, frnd->getStatus()); friendChatForms[friendId] = form; @@ -174,7 +175,8 @@ GroupWidget* ContentDialog::addGroup(std::shared_ptr chatroom, Ge const auto g = chatroom->getGroup(); const auto groupId = g->getId(); const auto compact = Settings::getInstance().getCompactLayout(); - GroupWidget* groupWidget = new GroupWidget(chatroom, compact); + auto groupWidget = new GroupWidget(chatroom, compact); + groupWidgets[groupId] = groupWidget; groupLayout.addSortedWidget(groupWidget); groupChatForms[groupId] = form; @@ -186,11 +188,9 @@ GroupWidget* ContentDialog::addGroup(std::shared_ptr chatroom, Ge return groupWidget; } -/** - * TODO: Pass id, store widgets in ContentDialog - */ -void ContentDialog::removeFriend(FriendWidget* chatroomWidget) +void ContentDialog::removeFriend(int friendId) { + auto chatroomWidget = qobject_cast(friendWidgets[friendId]); disconnect(chatroomWidget->getFriend(), &Friend::aliasChanged, this, &ContentDialog::updateFriendWidget); @@ -211,13 +211,15 @@ void ContentDialog::removeFriend(FriendWidget* chatroomWidget) } else { update(); } + + friendWidgets.remove(friendId); + friendChatForms.remove(friendId); + closeIfEmpty(); } -/** - * TODO: Pass id, store widgets in ContentDialog - */ -void ContentDialog::removeGroup(GroupWidget* chatroomWidget) +void ContentDialog::removeGroup(int groupId) { + auto chatroomWidget = qobject_cast(groupWidgets[groupId]); // Need to find replacement to show here instead. if (activeChatroomWidget == chatroomWidget) { cycleContacts(true, false); @@ -233,6 +235,17 @@ void ContentDialog::removeGroup(GroupWidget* chatroomWidget) } else { update(); } + + groupWidgets.remove(groupId); + groupChatForms.remove(groupId); + closeIfEmpty(); +} + +void ContentDialog::closeIfEmpty() +{ + if (friendWidgets.isEmpty() && groupWidgets.isEmpty()) { + close(); + } } int ContentDialog::chatroomWidgetCount() const @@ -463,10 +476,11 @@ void ContentDialog::dragEnterEvent(QDragEnterEvent* event) int friendId = contact->getId(); // If friend is already in a dialog then you can't drop friend where it already is. - if (!ContentDialogManager::getInstance()->hasFriendWidget(this, friendId, frnd)) { + if (!hasFriendWidget(friendId)) { event->acceptProposedAction(); } } else if (group) { + qDebug() << event->mimeData()->formats(); if (!event->mimeData()->hasFormat("groupId")) { return; } @@ -477,7 +491,7 @@ void ContentDialog::dragEnterEvent(QDragEnterEvent* event) return; } - if (!ContentDialogManager::getInstance()->hasFriendWidget(this, groupId, group)) { + if (!hasGroupWidget(groupId)) { event->acceptProposedAction(); } } @@ -495,8 +509,6 @@ void ContentDialog::dropEvent(QDropEvent* event) return; } - int friendId = contact->getId(); - ContentDialogManager::getInstance()->removeFriend(friendId); Widget::getInstance()->addFriendDialog(contact, this); ensureSplitterVisible(); } else if (group) { @@ -510,7 +522,6 @@ void ContentDialog::dropEvent(QDropEvent* event) return; } - ContentDialogManager::getInstance()->removeGroup(groupId); Widget::getInstance()->addGroupDialog(contact, this); ensureSplitterVisible(); } @@ -588,8 +599,7 @@ void ContentDialog::activate(GenericChatroomWidget* widget) void ContentDialog::updateFriendWidget(uint32_t friendId, QString alias) { Friend* f = FriendList::findFriend(friendId); - // TODO: getFriendWidget from own container - FriendWidget* friendWidget = ContentDialogManager::getInstance()->getFriendWidget(friendId); + FriendWidget* friendWidget = qobject_cast(friendWidgets[friendId]); Status status = f->getStatus(); friendLayout->addFriendWidget(friendWidget, status); @@ -631,22 +641,14 @@ void ContentDialog::saveSplitterState() Settings::getInstance().setDialogSplitterState(splitter->saveState()); } -/** - * @brief Check if current ContentDialog instance and chatroom widget associated with user. - * @param id User Id. - * @param chatroomWidget Widget which should be a pair for current dialog. - * @param list List with contact info. - * @return True, if chatroomWidget is pair for current instance. - */ -bool ContentDialog::hasWidget(int id, const GenericChatroomWidget* chatroomWidget, - const QHash& list) const +bool ContentDialog::hasFriendWidget(int friendId) const { - auto iter = list.find(id); - if (iter == list.end()) { - return false; - } + return friendWidgets.contains(friendId); +} - return std::get<0>(*iter) == this && std::get<1>(*iter) == chatroomWidget; +bool ContentDialog::hasGroupWidget(int groupId) const +{ + return groupWidgets.contains(groupId); } /** diff --git a/src/widget/contentdialog.h b/src/widget/contentdialog.h index 029b3bd03..ba18ee56f 100644 --- a/src/widget/contentdialog.h +++ b/src/widget/contentdialog.h @@ -58,8 +58,8 @@ public: FriendWidget* addFriend(std::shared_ptr chatroom, GenericChatForm* form); GroupWidget* addGroup(std::shared_ptr chatroom, GenericChatForm* form); - void removeFriend(FriendWidget* chatroomWidget); - void removeGroup(GroupWidget* chatroomWidget); + void removeFriend(int friendId); + void removeGroup(int groupId); int chatroomWidgetCount() const; void ensureSplitterVisible(); void updateTitleAndStatusIcon(); @@ -71,9 +71,8 @@ public: void addFriendWidget(FriendWidget* widget, Status status); bool isActiveWidget(GenericChatroomWidget* widget); - bool hasWidget(int id, const GenericChatroomWidget* chatroomWidget, - const QHash& list) const; - + bool hasFriendWidget(int friendId) const; + bool hasGroupWidget(int groupId) const; signals: void friendDialogShown(const Friend* f); @@ -104,6 +103,7 @@ private slots: void onGroupchatPositionChanged(bool top); private: + void closeIfEmpty(); void closeEvent(QCloseEvent* event) override; void retranslateUi(); @@ -121,6 +121,9 @@ private: QSize videoSurfaceSize; int videoCount; + QHash friendWidgets; + QHash groupWidgets; + QHash friendChatForms; QHash groupChatForms; diff --git a/src/widget/contentdialogmanager.cpp b/src/widget/contentdialogmanager.cpp index 9b86bed94..581b06db3 100644 --- a/src/widget/contentdialogmanager.cpp +++ b/src/widget/contentdialogmanager.cpp @@ -21,6 +21,17 @@ void removeDialog(ContentDialog* dialog, QHash& infos) } } } + +void removeDialog(ContentDialog* dialog, QHash& dialogs) +{ + for (auto it = dialogs.begin(); it != dialogs.end();) { + if (*it == dialog) { + it = dialogs.erase(it); + } else { + ++it; + } + } +} } ContentDialogManager* ContentDialogManager::instance; @@ -48,9 +59,10 @@ FriendWidget* ContentDialogManager::addFriendToDialog(ContentDialog* dialog, ContentDialog* lastDialog = getFriendDialog(friendId); if (lastDialog) { - lastDialog->removeFriend(friendWidget); + lastDialog->removeFriend(friendId); } + friendDialogs[friendId] = dialog; friendList.insert(friendId, std::make_tuple(dialog, friendWidget)); return friendWidget; } @@ -63,9 +75,10 @@ GroupWidget* ContentDialogManager::addGroupToDialog(ContentDialog* dialog, ContentDialog* lastDialog = getGroupDialog(groupId); if (lastDialog) { - lastDialog->removeGroup(groupWidget); + lastDialog->removeGroup(groupId); } + groupDialogs[groupId] = dialog; groupList.insert(groupId, std::make_tuple(dialog, groupWidget)); return groupWidget; } @@ -80,7 +93,7 @@ void ContentDialogManager::removeFriend(int friendId) auto friendWidget = static_cast(std::get<1>(iter.value())); auto dialog = getFriendDialog(friendId); - dialog->removeFriend(friendWidget); + dialog->removeFriend(friendId); friendList.remove(friendId); } @@ -93,7 +106,7 @@ void ContentDialogManager::removeGroup(int groupId) auto groupWidget = static_cast(std::get<1>(iter.value())); auto dialog = getGroupDialog(groupId); - dialog->removeGroup(groupWidget); + dialog->removeGroup(groupId); groupList.remove(groupId); } @@ -163,7 +176,6 @@ void ContentDialogManager::updateFriendStatus(int friendId) void ContentDialogManager::updateFriendStatusMessage(int friendId, const QString& message) { auto iter = friendList.find(friendId); - if (iter == friendList.end()) { return; } @@ -282,25 +294,7 @@ void ContentDialogManager::onDialogClose() removeDialog(dialog, friendList); removeDialog(dialog, groupList); -} -bool ContentDialogManager::hasFriendWidget(ContentDialog* dialog, int friendId, const GenericChatroomWidget* chatroomWidget) const -{ - return dialog->hasWidget(friendId, chatroomWidget, friendList); -} - -bool ContentDialogManager::hasGroupWidget(ContentDialog* dialog, int groupId, const GenericChatroomWidget* chatroomWidget) const -{ - return dialog->hasWidget(groupId, chatroomWidget, groupList); -} - -FriendWidget* ContentDialogManager::getFriendWidget(int friendId) const -{ - auto iter = friendList.find(friendId); - if (iter == friendList.end()) { - return nullptr; - } - - GenericChatroomWidget* widget = std::get<1>(*iter); - return qobject_cast(widget); + removeDialog(dialog, friendDialogs); + removeDialog(dialog, groupDialogs); } \ No newline at end of file diff --git a/src/widget/contentdialogmanager.h b/src/widget/contentdialogmanager.h index f7b82ada6..9b35a8600 100644 --- a/src/widget/contentdialogmanager.h +++ b/src/widget/contentdialogmanager.h @@ -53,11 +53,6 @@ public: static ContentDialogManager* getInstance(); - bool hasFriendWidget(ContentDialog* dialog, int friendId, const GenericChatroomWidget* chatroomWidget) const; - bool hasGroupWidget(ContentDialog* dialog, int groupId, const GenericChatroomWidget* chatroomWidget) const; - - FriendWidget* getFriendWidget(int friendId) const; - private slots: void onDialogClose(); void onDialogActivate(); @@ -70,6 +65,10 @@ private: ContentDialog* getDialog(int id, const QHash& list) const; ContentDialog* currentDialog = nullptr; + + QHash friendDialogs; + QHash groupDialogs; + QHash friendList; QHash groupList; diff --git a/src/widget/friendwidget.cpp b/src/widget/friendwidget.cpp index 7cc1d1aed..3d901b049 100644 --- a/src/widget/friendwidget.cpp +++ b/src/widget/friendwidget.cpp @@ -115,7 +115,7 @@ void FriendWidget::onContextMenuCalled(QContextMenuEvent* event) } // TODO: move to model - if (contentDialog && ContentDialogManager::getInstance()->hasFriendWidget(contentDialog, friendId, this)) { + if (contentDialog && contentDialog->hasFriendWidget(friendId)) { const auto removeChatWindow = menu.addAction(tr("Remove chat from this window")); connect(removeChatWindow, &QAction::triggered, this, &FriendWidget::removeChatWindow); } @@ -170,7 +170,7 @@ void FriendWidget::onContextMenuCalled(QContextMenuEvent* event) menu.addSeparator(); // TODO: move to model - if (!contentDialog || !ContentDialogManager::getInstance()->hasFriendWidget(contentDialog, friendId, this)) { + if (!contentDialog || !contentDialog->hasFriendWidget(friendId)) { const auto removeAction = menu.addAction(tr("Remove friend", "Menu to remove the friend from our friendlist")); connect(removeAction, &QAction::triggered, this, [=]() { emit removeFriend(friendId); }, diff --git a/src/widget/groupwidget.cpp b/src/widget/groupwidget.cpp index 3c779faa0..fe1471152 100644 --- a/src/widget/groupwidget.cpp +++ b/src/widget/groupwidget.cpp @@ -95,7 +95,7 @@ void GroupWidget::contextMenuEvent(QContextMenuEvent* event) openChatWindow = menu.addAction(tr("Open chat in new window")); } - if (contentDialog && ContentDialogManager::getInstance()->hasGroupWidget(contentDialog, groupId, this)) { + if (contentDialog && contentDialog->hasGroupWidget(groupId)) { removeChatWindow = menu.addAction(tr("Remove chat from this window")); } diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 421469182..475cc818b 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -1131,12 +1131,12 @@ void Widget::onFriendAliasChanged(uint32_t friendId, const QString& alias) void Widget::onChatroomWidgetClicked(GenericChatroomWidget* widget) { - openDialog(widget, false); + openDialog(widget, /* newWindow = */ false); } void Widget::openNewDialog(GenericChatroomWidget* widget) { - openDialog(widget, true); + openDialog(widget, /* newWindow = */ true); } void Widget::openDialog(GenericChatroomWidget* widget, bool newWindow) @@ -1248,7 +1248,7 @@ void Widget::addFriendDialog(const Friend* frnd, ContentDialog* dialog) auto form = chatForms[friendId]; auto chatroom = friendChatrooms[friendId]; - FriendWidget* friendWidget = dialog->addFriend(chatroom, form); + FriendWidget* friendWidget = ContentDialogManager::getInstance()->addFriendToDialog(dialog, chatroom, form); friendWidget->setStatusMsg(widget->getStatusMsg()); @@ -1259,7 +1259,7 @@ void Widget::addFriendDialog(const Friend* frnd, ContentDialog* dialog) #endif connect(friendWidget, &FriendWidget::removeFriend, this, widgetRemoveFriend); connect(friendWidget, &FriendWidget::middleMouseClicked, dialog, - [=]() { ContentDialogManager::getInstance()->removeFriend(friendId); }); + [=]() { dialog->removeFriend(friendId); }); connect(friendWidget, &FriendWidget::copyFriendIdToClipboard, this, &Widget::copyFriendIdToClipboard); connect(friendWidget, &FriendWidget::newWindowOpened, this, &Widget::openNewDialog); @@ -1304,7 +1304,8 @@ void Widget::addGroupDialog(Group* group, ContentDialog* dialog) auto chatForm = groupChatForms[groupId].data(); auto chatroom = groupChatrooms[groupId]; - auto groupWidget = dialog->addGroup(chatroom, chatForm); + auto groupWidget = ContentDialogManager::getInstance()->addGroupToDialog(dialog, chatroom, chatForm); + #if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) auto removeGroup = QOverload::of(&Widget::removeGroup); #else @@ -1313,7 +1314,7 @@ void Widget::addGroupDialog(Group* group, ContentDialog* dialog) connect(groupWidget, &GroupWidget::removeGroup, this, removeGroup); connect(groupWidget, &GroupWidget::chatroomWidgetClicked, chatForm, &GroupChatForm::focusInput); connect(groupWidget, &GroupWidget::middleMouseClicked, dialog, - [=]() { ContentDialogManager::getInstance()->removeGroup(groupId); }); + [=]() { dialog->removeGroup(groupId); }); connect(groupWidget, &GroupWidget::chatroomWidgetClicked, chatForm, &ChatForm::focusInput); connect(groupWidget, &GroupWidget::newWindowOpened, this, &Widget::openNewDialog);