1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Multi-window: Fix segfault for removing last friend on window friend list

This commit is contained in:
TheSpiritXIII 2015-07-03 09:16:27 -04:00 committed by tux3
parent f825985856
commit 1109e0347e
4 changed files with 79 additions and 46 deletions

View File

@ -244,7 +244,33 @@ void ContentDialog::removeGroup(int groupId)
disconnect(group, &Group::titleChanged, this, &ContentDialog::updateGroupWidget); disconnect(group, &Group::titleChanged, this, &ContentDialog::updateGroupWidget);
disconnect(group, &Group::userListChanged, 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) bool ContentDialog::hasFriendWidget(int friendId, GenericChatroomWidget* chatroomWidget)
@ -292,6 +318,21 @@ void ContentDialog::cycleContacts(bool forward, bool loop)
index = groupLayout.indexOfSortedWidget(activeChatroomWidget); 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; index += forward ? 1 : -1;
for (;;) for (;;)
@ -305,13 +346,13 @@ void ContentDialog::cycleContacts(bool forward, bool loop)
} }
else if (index >= currentLayout->count()) else if (index >= currentLayout->count())
{ {
if (!loop && currentLayout == friendLayout->getLayoutOffline()) /*if (!loop && currentLayout == friendLayout->getLayoutOffline())
{ {
forward = !forward; // Go backward. forward = !forward; // Go backward.
index += forward ? 2 : -2; // Go back to where started and then one. index += forward ? 2 : -2; // Go back to where started and then one.
continue; // Recheck bounds. continue; // Recheck bounds.
} }
else else*/
{ {
currentLayout = nextLayout(currentLayout, forward); currentLayout = nextLayout(currentLayout, forward);
index = 0; index = 0;
@ -512,6 +553,12 @@ void ContentDialog::moveEvent(QMoveEvent* event)
QDialog::moveEvent(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) void ContentDialog::onChatroomWidgetClicked(GenericChatroomWidget *widget, bool group)
{ {
if (group) if (group)
@ -593,43 +640,6 @@ void ContentDialog::saveSplitterState()
Settings::getInstance().setDialogSplitterState(splitter->saveState()); Settings::getInstance().setDialogSplitterState(splitter->saveState());
} }
void ContentDialog::remove(int id, const QHash<int, std::tuple<ContentDialog *, GenericChatroomWidget *> > &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<GenericChatroomWidget*>(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<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list) bool ContentDialog::hasWidget(int id, GenericChatroomWidget* chatroomWidget, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list)
{ {
auto iter = list.find(id); auto iter = list.find(id);

View File

@ -79,6 +79,7 @@ protected:
void changeEvent(QEvent* event) override; void changeEvent(QEvent* event) override;
void resizeEvent(QResizeEvent* event) override; void resizeEvent(QResizeEvent* event) override;
void moveEvent(QMoveEvent* event) override; void moveEvent(QMoveEvent* event) override;
void keyPressEvent(QKeyEvent* event) override;
private slots: private slots:
void onChatroomWidgetClicked(GenericChatroomWidget* widget, bool group); void onChatroomWidgetClicked(GenericChatroomWidget* widget, bool group);
@ -92,7 +93,6 @@ private:
void saveSplitterState(); void saveSplitterState();
QLayout* nextLayout(QLayout* layout, bool forward) const; QLayout* nextLayout(QLayout* layout, bool forward) const;
void remove(int id, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list);
bool hasWidget(int id, GenericChatroomWidget* chatroomWidget, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list); bool hasWidget(int id, GenericChatroomWidget* chatroomWidget, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list);
static bool existsWidget(int id, bool focus, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list); static bool existsWidget(int id, bool focus, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list);
static void updateStatus(int id, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list); static void updateStatus(int id, const QHash<int, std::tuple<ContentDialog*, GenericChatroomWidget*>>& list);

View File

@ -20,6 +20,7 @@
#include "croppinglabel.h" #include "croppinglabel.h"
#include <QResizeEvent> #include <QResizeEvent>
#include <QLineEdit> #include <QLineEdit>
#include <QKeyEvent>
CroppingLabel::CroppingLabel(QWidget* parent) CroppingLabel::CroppingLabel(QWidget* parent)
: QLabel(parent) : QLabel(parent)
@ -29,13 +30,31 @@ CroppingLabel::CroppingLabel(QWidget* parent)
{ {
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 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->hide();
textEdit->setInputMethodHints(Qt::ImhNoAutoUppercase textEdit->setInputMethodHints(Qt::ImhNoAutoUppercase
| Qt::ImhNoPredictiveText | Qt::ImhNoPredictiveText
| Qt::ImhPreferLatin); | 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() void CroppingLabel::editBegin()
@ -114,6 +133,12 @@ void CroppingLabel::setElidedText()
QLabel::setText(elidedText); QLabel::setText(elidedText);
} }
void CroppingLabel::hideTextEdit()
{
textEdit->hide();
blockPaintEvents = false;
}
void CroppingLabel::showTextEdit() void CroppingLabel::showTextEdit()
{ {
blockPaintEvents = true; blockPaintEvents = true;
@ -142,7 +167,5 @@ void CroppingLabel::editingFinished()
if (origText != newText) if (origText != newText)
emit editFinished(textEdit->text()); emit editFinished(textEdit->text());
textEdit->hide();
blockPaintEvents = false;
emit editRemoved(); emit editRemoved();
} }

View File

@ -49,7 +49,7 @@ signals:
protected: protected:
void paintEvent(QPaintEvent* paintEvent) override; void paintEvent(QPaintEvent* paintEvent) override;
void setElidedText(); void setElidedText();
void hideTextEdit(bool acceptText); void hideTextEdit();
void showTextEdit(); void showTextEdit();
virtual void resizeEvent(QResizeEvent *ev) final override; virtual void resizeEvent(QResizeEvent *ev) final override;
virtual QSize sizeHint() const final override; virtual QSize sizeHint() const final override;