From 1109e0347e05c0823f7e114bc3be8100c06f0db2 Mon Sep 17 00:00:00 2001 From: TheSpiritXIII Date: Fri, 3 Jul 2015 09:16:27 -0400 Subject: [PATCH] Multi-window: Fix segfault for removing last friend on window friend list --- src/widget/contentdialog.cpp | 90 +++++++++++++++++-------------- src/widget/contentdialog.h | 2 +- src/widget/tool/croppinglabel.cpp | 31 +++++++++-- src/widget/tool/croppinglabel.h | 2 +- 4 files changed, 79 insertions(+), 46 deletions(-) diff --git a/src/widget/contentdialog.cpp b/src/widget/contentdialog.cpp index a3f46f89c..80175d728 100644 --- a/src/widget/contentdialog.cpp +++ b/src/widget/contentdialog.cpp @@ -244,7 +244,33 @@ void ContentDialog::removeGroup(int groupId) disconnect(group, &Group::titleChanged, this, &ContentDialog::updateGroupWidget); disconnect(group, &Group::userListChanged, this, &ContentDialog::updateGroupWidget); - remove(groupId, groupList); + auto iter = groupList.find(groupId); + + if (iter == groupList.end()) + return; + + GenericChatroomWidget* chatroomWidget = std::get<1>(iter.value()); + + if (activeChatroomWidget == chatroomWidget) + { + // Need to find replacement to show here instead. + cycleContacts(true, false); + } + + groupLayout.removeSortedWidget(chatroomWidget); + chatroomWidget->deleteLater(); + groupList.remove(groupId); + + if (chatroomWidgetCount() == 0) + { + contentLayout->clear(); + activeChatroomWidget = nullptr; + deleteLater(); + } + else + { + update(); + } } bool ContentDialog::hasFriendWidget(int friendId, GenericChatroomWidget* chatroomWidget) @@ -292,6 +318,21 @@ void ContentDialog::cycleContacts(bool forward, bool loop) index = groupLayout.indexOfSortedWidget(activeChatroomWidget); } + if (!loop && index == currentLayout->count() - 1) + { + bool groupsOnTop = Settings::getInstance().getGroupchatPosition(); + bool offlineEmpty = friendLayout->getLayoutOffline()->count() == 0; + bool onlineEmpty = offlineEmpty && ((friendLayout->getLayoutOnline()->count() == 0 && groupsOnTop) || !groupsOnTop); + bool groupsEmpty = offlineEmpty && ((groupLayout.getLayout()->count() == 0 && !groupsOnTop) || groupsOnTop); + + if ((currentLayout == friendLayout->getLayoutOffline()) + || (currentLayout == friendLayout->getLayoutOnline() && groupsEmpty) + || (currentLayout == groupLayout.getLayout() && onlineEmpty)) + { + forward = !forward; + } + } + index += forward ? 1 : -1; for (;;) @@ -305,13 +346,13 @@ void ContentDialog::cycleContacts(bool forward, bool loop) } else if (index >= currentLayout->count()) { - if (!loop && currentLayout == friendLayout->getLayoutOffline()) + /*if (!loop && currentLayout == friendLayout->getLayoutOffline()) { forward = !forward; // Go backward. index += forward ? 2 : -2; // Go back to where started and then one. continue; // Recheck bounds. } - else + else*/ { currentLayout = nextLayout(currentLayout, forward); index = 0; @@ -512,6 +553,12 @@ void ContentDialog::moveEvent(QMoveEvent* event) QDialog::moveEvent(event); } +void ContentDialog::keyPressEvent(QKeyEvent* event) +{ + if(event->key() != Qt::Key_Escape) + QDialog::keyPressEvent(event); // Ignore escape keyboard shortcut. +} + void ContentDialog::onChatroomWidgetClicked(GenericChatroomWidget *widget, bool group) { if (group) @@ -593,43 +640,6 @@ void ContentDialog::saveSplitterState() Settings::getInstance().setDialogSplitterState(splitter->saveState()); } -void ContentDialog::remove(int id, const QHash > &list) -{ - auto iter = list.find(id); - - if (iter == list.end()) - return; - - GenericChatroomWidget* chatroomWidget = std::get<1>(iter.value()); - - if (activeChatroomWidget == chatroomWidget) - { - // Need to find replacement to show here instead. - if (chatroomWidgetCount() > 1) - { - int index = groupLayout.indexOfSortedWidget(chatroomWidget) - 1; - - // Don't let it go below 0. If it does, then we're first. Go second. - if (index < 0) - index = 1; - - GenericChatroomWidget* chatroomWidget = static_cast(groupLayout.getLayout()->itemAt(index)->widget()); - onChatroomWidgetClicked(chatroomWidget, false); - } - else - { - contentLayout->clear(); - activeChatroomWidget = nullptr; - deleteLater(); - } - } - - groupLayout.removeSortedWidget(chatroomWidget); - chatroomWidget->deleteLater(); - friendList.remove(id); - update(); -} - bool ContentDialog::hasWidget(int id, GenericChatroomWidget* chatroomWidget, const QHash>& list) { auto iter = list.find(id); diff --git a/src/widget/contentdialog.h b/src/widget/contentdialog.h index ab360ecc8..d33512f3a 100644 --- a/src/widget/contentdialog.h +++ b/src/widget/contentdialog.h @@ -79,6 +79,7 @@ protected: void changeEvent(QEvent* event) override; void resizeEvent(QResizeEvent* event) override; void moveEvent(QMoveEvent* event) override; + void keyPressEvent(QKeyEvent* event) override; private slots: void onChatroomWidgetClicked(GenericChatroomWidget* widget, bool group); @@ -92,7 +93,6 @@ private: void saveSplitterState(); QLayout* nextLayout(QLayout* layout, bool forward) const; - void remove(int id, const QHash>& list); 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); diff --git a/src/widget/tool/croppinglabel.cpp b/src/widget/tool/croppinglabel.cpp index 7eb6b3a00..ad151462e 100644 --- a/src/widget/tool/croppinglabel.cpp +++ b/src/widget/tool/croppinglabel.cpp @@ -20,6 +20,7 @@ #include "croppinglabel.h" #include #include +#include CroppingLabel::CroppingLabel(QWidget* parent) : QLabel(parent) @@ -29,13 +30,31 @@ CroppingLabel::CroppingLabel(QWidget* parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - textEdit = new QLineEdit(this); + class LineEdit : public QLineEdit + { + public: + LineEdit(QWidget* parent = 0) : + QLineEdit(parent) + {} + + protected: + void keyPressEvent(QKeyEvent* event) override + { + if (event->key() == Qt::Key_Escape) + clearFocus(); + + QLineEdit::keyPressEvent(event); + } + }; + + textEdit = new LineEdit(this); textEdit->hide(); textEdit->setInputMethodHints(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhPreferLatin); - connect(textEdit, &QLineEdit::editingFinished, this, &CroppingLabel::editingFinished); + connect(textEdit, &QLineEdit::returnPressed, this, &CroppingLabel::editingFinished); + connect(textEdit, &QLineEdit::editingFinished, this, &CroppingLabel::hideTextEdit); } void CroppingLabel::editBegin() @@ -114,6 +133,12 @@ void CroppingLabel::setElidedText() QLabel::setText(elidedText); } +void CroppingLabel::hideTextEdit() +{ + textEdit->hide(); + blockPaintEvents = false; +} + void CroppingLabel::showTextEdit() { blockPaintEvents = true; @@ -142,7 +167,5 @@ void CroppingLabel::editingFinished() if (origText != newText) emit editFinished(textEdit->text()); - textEdit->hide(); - blockPaintEvents = false; emit editRemoved(); } diff --git a/src/widget/tool/croppinglabel.h b/src/widget/tool/croppinglabel.h index 6a731f662..83d86322b 100644 --- a/src/widget/tool/croppinglabel.h +++ b/src/widget/tool/croppinglabel.h @@ -49,7 +49,7 @@ signals: protected: void paintEvent(QPaintEvent* paintEvent) override; void setElidedText(); - void hideTextEdit(bool acceptText); + void hideTextEdit(); void showTextEdit(); virtual void resizeEvent(QResizeEvent *ev) final override; virtual QSize sizeHint() const final override;