Outline: Redo save/restore of settings

The OutlineStackWidget stored its position in the outline to be able
to save/restore settings specific to the sub-widget (IOutlineWidget).
However, the index can get out sync if another NavigationWidget
with a lower index number is split, and the relative position changes.

The change therefore avoids saving an index, and rather keeps the sum
of all sub-widget settings in a QVariantMap, only reading and writing
to the global settings object if necessary.

The settings are also not stored in the [General] section anymore,
but in a subgroup [Sidebar.Outline.X], where X is the index of the
outline in the view. This avoids having to always iterate over all
keys. No effort has been made to take over the old settings. I doubt
anyone will notice, though.

Change-Id: I85017cbb3e32b0a16da43ce6339deb7a053d6b09
Task-number: QTCREATORBUG-13614
Reviewed-by: Daniel Teske <daniel.teske@theqtcompany.com>
This commit is contained in:
Kai Koehne
2014-12-09 11:12:17 +01:00
parent 036f4f00eb
commit 32fa850a6d
5 changed files with 37 additions and 34 deletions

View File

@@ -160,19 +160,17 @@ void QmlJSOutlineWidget::setCursorSynchronization(bool syncWithCursor)
updateSelectionInTree(m_editor->outlineModelIndex()); updateSelectionInTree(m_editor->outlineModelIndex());
} }
void QmlJSOutlineWidget::restoreSettings(int position) void QmlJSOutlineWidget::restoreSettings(const QVariantMap &map)
{ {
QSettings *settings = Core::ICore::settings(); bool showBindings = map.value(QString::fromLatin1("QmlJSOutline.ShowBindings"), true).toBool();
bool showBindings = settings->value(
QString::fromLatin1("QmlJSOutline.%1.ShowBindings").arg(position), true).toBool();
m_showBindingsAction->setChecked(showBindings); m_showBindingsAction->setChecked(showBindings);
} }
void QmlJSOutlineWidget::saveSettings(int position) QVariantMap QmlJSOutlineWidget::settings() const
{ {
QSettings *settings = Core::ICore::settings(); QVariantMap map;
settings->setValue(QString::fromLatin1("QmlJSOutline.%1.ShowBindings").arg(position), map.insert(QLatin1String("QmlJSOutline.ShowBindings"), m_showBindingsAction->isChecked());
m_showBindingsAction->isChecked()); return map;
} }
void QmlJSOutlineWidget::modelUpdated() void QmlJSOutlineWidget::modelUpdated()

View File

@@ -74,8 +74,8 @@ public:
// IOutlineWidget // IOutlineWidget
virtual QList<QAction*> filterMenuActions() const; virtual QList<QAction*> filterMenuActions() const;
virtual void setCursorSynchronization(bool syncWithCursor); virtual void setCursorSynchronization(bool syncWithCursor);
virtual void restoreSettings(int position); virtual void restoreSettings(const QVariantMap &map);
virtual void saveSettings(int position); virtual QVariantMap settings() const;
private slots: private slots:
void modelUpdated(); void modelUpdated();

View File

@@ -33,6 +33,7 @@
#include <texteditor/texteditor_global.h> #include <texteditor/texteditor_global.h>
#include <QWidget> #include <QWidget>
#include <QVariantMap>
namespace Core { class IEditor; } namespace Core { class IEditor; }
@@ -47,8 +48,8 @@ public:
virtual QList<QAction*> filterMenuActions() const = 0; virtual QList<QAction*> filterMenuActions() const = 0;
virtual void setCursorSynchronization(bool syncWithCursor) = 0; virtual void setCursorSynchronization(bool syncWithCursor) = 0;
virtual void restoreSettings(int position) { Q_UNUSED(position); } virtual void restoreSettings(const QVariantMap & /*map*/) { }
virtual void saveSettings(int position) { Q_UNUSED(position); } virtual QVariantMap settings() const { return QVariantMap(); }
}; };
class TEXTEDITOR_EXPORT IOutlineWidgetFactory : public QObject { class TEXTEDITOR_EXPORT IOutlineWidgetFactory : public QObject {

View File

@@ -45,8 +45,7 @@ namespace Internal {
OutlineWidgetStack::OutlineWidgetStack(OutlineFactory *factory) : OutlineWidgetStack::OutlineWidgetStack(OutlineFactory *factory) :
QStackedWidget(), QStackedWidget(),
m_factory(factory), m_factory(factory),
m_syncWithEditor(true), m_syncWithEditor(true)
m_position(-1)
{ {
QLabel *label = new QLabel(tr("No outline available"), this); QLabel *label = new QLabel(tr("No outline available"), this);
label->setAlignment(Qt::AlignCenter); label->setAlignment(Qt::AlignCenter);
@@ -91,32 +90,37 @@ QToolButton *OutlineWidgetStack::filterButton()
return m_filterButton; return m_filterButton;
} }
static inline QString outLineKey(int position)
{
return QLatin1String("Outline.") + QString::number(position) + QLatin1String(".SyncWithEditor");
}
void OutlineWidgetStack::restoreSettings(int position) void OutlineWidgetStack::restoreSettings(int position)
{ {
m_position = position; // save it so that we can save/restore in updateCurrentEditor
QSettings *settings = Core::ICore::settings(); QSettings *settings = Core::ICore::settings();
const bool toggleSync = settings->value(outLineKey(position), true).toBool(); settings->beginGroup(QLatin1String("Sidebar.Outline.") + QString::number(position));
toggleSyncButton()->setChecked(toggleSync);
bool syncWithEditor = true;
m_widgetSettings.clear();
foreach (const QString &key, settings->allKeys()) {
if (key == QLatin1String("SyncWithEditor")) {
syncWithEditor = settings->value(key).toBool();
continue;
}
m_widgetSettings.insert(key, settings->value(key));
}
settings->endGroup();
toggleSyncButton()->setChecked(syncWithEditor);
if (IOutlineWidget *outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget())) if (IOutlineWidget *outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget()))
outlineWidget->restoreSettings(position); outlineWidget->restoreSettings(m_widgetSettings);
} }
void OutlineWidgetStack::saveSettings(int position) void OutlineWidgetStack::saveSettings(int position)
{ {
Q_ASSERT(position == m_position);
QSettings *settings = Core::ICore::settings(); QSettings *settings = Core::ICore::settings();
settings->setValue(outLineKey(position), toggleSyncButton()->isEnabled()); settings->beginGroup(QLatin1String("Sidebar.Outline.") + QString::number(position));
if (IOutlineWidget *outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget())) settings->setValue(QLatin1String("SyncWithEditor"), toggleSyncButton()->isChecked());
outlineWidget->saveSettings(position); for (auto iter = m_widgetSettings.constBegin(); iter != m_widgetSettings.constEnd(); ++iter)
settings->setValue(iter.key(), iter.value());
settings->endGroup();
} }
bool OutlineWidgetStack::isCursorSynchronized() const bool OutlineWidgetStack::isCursorSynchronized() const
@@ -158,14 +162,14 @@ void OutlineWidgetStack::updateCurrentEditor(Core::IEditor *editor)
if (newWidget != currentWidget()) { if (newWidget != currentWidget()) {
// delete old widget // delete old widget
if (IOutlineWidget *outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget())) { if (IOutlineWidget *outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget())) {
if (m_position > -1) QVariantMap widgetSettings = outlineWidget->settings();
outlineWidget->saveSettings(m_position); for (auto iter = widgetSettings.constBegin(); iter != widgetSettings.constEnd(); ++iter)
m_widgetSettings.insert(iter.key(), iter.value());
removeWidget(outlineWidget); removeWidget(outlineWidget);
delete outlineWidget; delete outlineWidget;
} }
if (newWidget) { if (newWidget) {
if (m_position > -1) newWidget->restoreSettings(m_widgetSettings);
newWidget->restoreSettings(m_position);
newWidget->setCursorSynchronization(m_syncWithEditor); newWidget->setCursorSynchronization(m_syncWithEditor);
addWidget(newWidget); addWidget(newWidget);
setCurrentWidget(newWidget); setCurrentWidget(newWidget);

View File

@@ -71,8 +71,8 @@ private:
QToolButton *m_toggleSync; QToolButton *m_toggleSync;
QToolButton *m_filterButton; QToolButton *m_filterButton;
QMenu *m_filterMenu; QMenu *m_filterMenu;
QVariantMap m_widgetSettings;
bool m_syncWithEditor; bool m_syncWithEditor;
int m_position;
}; };
class OutlineFactory : public Core::INavigationWidgetFactory class OutlineFactory : public Core::INavigationWidgetFactory