From a231532bd06a4a47432b5bc20d6d34028ca66941 Mon Sep 17 00:00:00 2001 From: Diadlo Date: Sun, 26 Feb 2017 01:06:07 +0300 Subject: [PATCH] fix: Add splitter restorer Added splitter restorer, which reset splitter state if it's broken Fix #2587 --- CMakeLists.txt | 2 + qtox.pro | 2 + src/widget/contentdialog.cpp | 20 +++++----- src/widget/splitterrestorer.cpp | 70 +++++++++++++++++++++++++++++++++ src/widget/splitterrestorer.h | 37 +++++++++++++++++ src/widget/widget.cpp | 23 ++++------- 6 files changed, 128 insertions(+), 26 deletions(-) create mode 100644 src/widget/splitterrestorer.cpp create mode 100644 src/widget/splitterrestorer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 55ce8ed12..66b5bff6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -386,6 +386,8 @@ set(${PROJECT_NAME}_SOURCES src/widget/passwordedit.h src/widget/qrwidget.cpp src/widget/qrwidget.h + src/widget/splitterrestorer.cpp + src/widget/splitterrestorer.h src/widget/style.cpp src/widget/style.h src/widget/systemtrayicon.cpp diff --git a/qtox.pro b/qtox.pro index 189bd45f1..d1596caf5 100644 --- a/qtox.pro +++ b/qtox.pro @@ -514,6 +514,7 @@ HEADERS += \ src/widget/notificationscrollarea.h \ src/widget/passwordedit.h \ src/widget/qrwidget.h \ + src/widget/splitterrestorer.h \ src/widget/style.h \ src/widget/systemtrayicon.h \ src/widget/systemtrayicon_private.h \ @@ -633,6 +634,7 @@ SOURCES += \ src/widget/notificationscrollarea.cpp \ src/widget/passwordedit.cpp \ src/widget/qrwidget.cpp \ + src/widget/splitterrestorer.cpp \ src/widget/style.cpp \ src/widget/systemtrayicon.cpp \ src/widget/tool/activatedialog.cpp \ diff --git a/src/widget/contentdialog.cpp b/src/widget/contentdialog.cpp index 18474ab32..94855fc7a 100644 --- a/src/widget/contentdialog.cpp +++ b/src/widget/contentdialog.cpp @@ -18,6 +18,7 @@ */ #include "contentdialog.h" +#include "splitterrestorer.h" #include #include @@ -94,29 +95,26 @@ ContentDialog::ContentDialog(SettingsWidget* settingsWidget, QWidget* parent) splitter->setCollapsible(1, false); boxLayout->addWidget(splitter); - connect(splitter, &QSplitter::splitterMoved, this, &ContentDialog::saveSplitterState); - const Settings& s = Settings::getInstance(); connect(&s, &Settings::groupchatPositionChanged, this, &ContentDialog::onGroupchatPositionChanged); + connect(splitter, &QSplitter::splitterMoved, this, &ContentDialog::saveSplitterState); setMinimumSize(500, 220); setAttribute(Qt::WA_DeleteOnClose); - QByteArray geometry = Settings::getInstance().getDialogGeometry(); + QByteArray geometry = s.getDialogGeometry(); - if (!geometry.isNull()) + if (!geometry.isNull()) { restoreGeometry(geometry); - else + } else { resize(720, 400); + } - - QByteArray splitterState = Settings::getInstance().getDialogSplitterState(); - - if (!splitterState.isNull()) - splitter->restoreState(splitterState); + QByteArray splitterState = s.getDialogSplitterState(); + SplitterRestorer restorer(splitter); + restorer.restore(splitterState, size()); currentDialog = this; - setAcceptDrops(true); new QShortcut(Qt::CTRL + Qt::Key_Q, this, SLOT(close())); diff --git a/src/widget/splitterrestorer.cpp b/src/widget/splitterrestorer.cpp new file mode 100644 index 000000000..35b044257 --- /dev/null +++ b/src/widget/splitterrestorer.cpp @@ -0,0 +1,70 @@ +/* + Copyright © 2017 by The qTox Project Contributors + + This file is part of qTox, a Qt-based graphical interface for Tox. + + qTox is libre software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + qTox is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with qTox. If not, see . +*/ + +#include "src/widget/splitterrestorer.h" + +#include + +/** + * @class SplitterRestorer + * @brief Restore splitter from saved state and reset to default + */ + +/** + * @brief The width of the default splitter handles. + * By default, this property contains a value that depends on the user's + * platform and style preferences. + */ +static int defaultWidth = 0; + +/** + * @brief Width of left splitter size in percents. + */ +const static int leftWidthPercent = 33; + +SplitterRestorer::SplitterRestorer(QSplitter* splitter) + : splitter{splitter} +{ + if (defaultWidth == 0) { + defaultWidth = QSplitter().handleWidth(); + } +} + +/** + * @brief Restore splitter from state. And reset in case of error. + * Set the splitter to a reasonnable width by default and on first start + * @param state State saved by QSplitter::saveState() + * @param windowSize Widnow size (used to calculate splitter size) + */ +void SplitterRestorer::restore(const QByteArray& state, const QSize& windowSize) +{ + bool brokenSplitter = !splitter->restoreState(state) || + splitter->orientation() != Qt::Horizontal || + splitter->handleWidth() > defaultWidth; + + if (splitter->count() == 2 && brokenSplitter) { + splitter->setOrientation(Qt::Horizontal); + splitter->setHandleWidth(defaultWidth); + splitter->resize(windowSize); + QList sizes = splitter->sizes(); + sizes[0] = splitter->width() * leftWidthPercent / 100; + sizes[1] = splitter->width() - sizes[0]; + splitter->setSizes(sizes); + } +} diff --git a/src/widget/splitterrestorer.h b/src/widget/splitterrestorer.h new file mode 100644 index 000000000..fc61cc175 --- /dev/null +++ b/src/widget/splitterrestorer.h @@ -0,0 +1,37 @@ +/* + Copyright © 2017 by The qTox Project Contributors + + This file is part of qTox, a Qt-based graphical interface for Tox. + + qTox is libre software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + qTox is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with qTox. If not, see . +*/ + +#ifndef SPLITTERRESTORER_H +#define SPLITTERRESTORER_H + +class QSize; +class QSplitter; +class QByteArray; + +class SplitterRestorer +{ +public: + explicit SplitterRestorer(QSplitter* splitter); + void restore(const QByteArray& state, const QSize& windowSize); + +private: + QSplitter* splitter; +}; + +#endif // SPLITTERRESTORER_H diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index b317413eb..3312af654 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -46,6 +46,7 @@ #include "friendwidget.h" #include "groupwidget.h" #include "maskablepixmapwidget.h" +#include "splitterrestorer.h" #include "src/audio/audio.h" #include "src/core/core.h" #include "src/core/coreav.h" @@ -346,7 +347,7 @@ void Widget::init() #endif contentLayout = nullptr; - onSeparateWindowChanged(Settings::getInstance().getSeparateWindow(), false); + onSeparateWindowChanged(s.getSeparateWindow(), false); ui->addButton->setCheckable(true); ui->groupButton->setCheckable(true); @@ -359,21 +360,13 @@ void Widget::init() } //restore window state - restoreGeometry(Settings::getInstance().getWindowGeometry()); - restoreState(Settings::getInstance().getWindowState()); - if (!ui->mainSplitter->restoreState(Settings::getInstance().getSplitterState())) - { - // Set the status panel (friendlist) to a reasonnable width by default/on first start - constexpr int spWidthPc = 33; - ui->mainSplitter->resize(size()); - QList sizes = ui->mainSplitter->sizes(); - sizes[0] = ui->mainSplitter->width()*spWidthPc/100; - sizes[1] = ui->mainSplitter->width() - sizes[0]; - ui->mainSplitter->setSizes(sizes); - } + restoreGeometry(s.getWindowGeometry()); + restoreState(s.getWindowState()); + SplitterRestorer restorer(ui->mainSplitter); + restorer.restore(s.getSplitterState(), size()); #if (AUTOUPDATE_ENABLED) - if (Settings::getInstance().getCheckUpdates()) + if (s.getCheckUpdates()) AutoUpdater::checkUpdatesAsyncInteractive(); #endif @@ -400,7 +393,7 @@ void Widget::init() retranslateUi(); Translator::registerHandler(std::bind(&Widget::retranslateUi, this), this); - if (!Settings::getInstance().getShowSystemTray()) + if (!s.getShowSystemTray()) { show(); }