Debugger: Remember sizes and order of the columns in the debugger views

Task-number: QTCREATORBUG-23341
Change-Id: I405be5361e732eccadebd1f51d90c7a3229a2e5e
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2019-12-09 15:12:55 +01:00
parent ee77b4fca3
commit 53a4c6eda0
3 changed files with 77 additions and 18 deletions

View File

@@ -52,6 +52,7 @@
#include <QContextMenuEvent> #include <QContextMenuEvent>
#include <QDockWidget> #include <QDockWidget>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QHeaderView>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QMenu> #include <QMenu>
#include <QScrollArea> #include <QScrollArea>
@@ -59,6 +60,7 @@
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QTimer> #include <QTimer>
#include <QToolButton> #include <QToolButton>
#include <QTreeView>
using namespace Debugger; using namespace Debugger;
using namespace Core; using namespace Core;
@@ -73,7 +75,8 @@ const char LAST_PERSPECTIVE_KEY[] = "LastPerspective";
const char MAINWINDOW_KEY[] = "Debugger.MainWindow"; const char MAINWINDOW_KEY[] = "Debugger.MainWindow";
const char AUTOHIDE_TITLEBARS_KEY[] = "AutoHideTitleBars"; const char AUTOHIDE_TITLEBARS_KEY[] = "AutoHideTitleBars";
const char SHOW_CENTRALWIDGET_KEY[] = "ShowCentralWidget"; const char SHOW_CENTRALWIDGET_KEY[] = "ShowCentralWidget";
const char STATE_KEY[] = "State"; const char STATE_KEY[] = "State"; // Up to 4.10
const char STATE_KEY2[] = "State2"; // From 4.11 on
const char CHANGED_DOCK_KEY[] = "ChangedDocks"; const char CHANGED_DOCK_KEY[] = "ChangedDocks";
static DebuggerMainWindow *theMainWindow = nullptr; static DebuggerMainWindow *theMainWindow = nullptr;
@@ -166,8 +169,8 @@ public:
QList<QPointer<Perspective>> m_perspectives; QList<QPointer<Perspective>> m_perspectives;
QSet<QString> m_persistentChangedDocks; // Dock Ids of docks with non-default visibility. QSet<QString> m_persistentChangedDocks; // Dock Ids of docks with non-default visibility.
QHash<QString, QByteArray> m_lastPerspectiveStates; // Perspective::id() -> MainWindow::state() QHash<QString, PerspectiveState> m_lastPerspectiveStates; // Perspective::id() -> MainWindow::state()
QHash<QString, QByteArray> m_lastTypePerspectiveStates; // Perspective::settingsId() -> MainWindow::state() QHash<QString, PerspectiveState> m_lastTypePerspectiveStates; // Perspective::settingsId() -> MainWindow::state()
}; };
DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent) DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
@@ -265,6 +268,9 @@ DebuggerMainWindowPrivate::~DebuggerMainWindowPrivate()
DebuggerMainWindow::DebuggerMainWindow() DebuggerMainWindow::DebuggerMainWindow()
: d(new DebuggerMainWindowPrivate(this)) : d(new DebuggerMainWindowPrivate(this))
{ {
qRegisterMetaType<PerspectiveState>("PerspectiveState");
qRegisterMetaTypeStreamOperators<PerspectiveState>("PerspectiveState");
setDockNestingEnabled(true); setDockNestingEnabled(true);
setDockActionsVisible(false); setDockActionsVisible(false);
setDocumentMode(true); setDocumentMode(true);
@@ -437,11 +443,17 @@ void DebuggerMainWindow::restorePersistentSettings()
QSettings *settings = ICore::settings(); QSettings *settings = ICore::settings();
settings->beginGroup(MAINWINDOW_KEY); settings->beginGroup(MAINWINDOW_KEY);
// state2 is current, state is kept for upgradeing from <=4.10
const QHash<QString, QVariant> states2 = settings->value(STATE_KEY2).toHash();
const QHash<QString, QVariant> states = settings->value(STATE_KEY).toHash(); const QHash<QString, QVariant> states = settings->value(STATE_KEY).toHash();
d->m_lastTypePerspectiveStates.clear(); d->m_lastTypePerspectiveStates.clear();
for (const QString &type : states.keys()) { QSet<QString> keys = Utils::toSet(states2.keys());
const QByteArray state = states.value(type).toByteArray(); keys.unite(Utils::toSet(states.keys()));
QTC_ASSERT(!state.isEmpty(), continue); for (const QString &type : keys) {
PerspectiveState state = states2.value(type).value<PerspectiveState>();
if (state.mainWindowState.isEmpty())
state.mainWindowState = states.value(type).toByteArray();
QTC_ASSERT(!state.mainWindowState.isEmpty(), continue);
d->m_lastTypePerspectiveStates.insert(type, state); d->m_lastTypePerspectiveStates.insert(type, state);
} }
@@ -467,16 +479,17 @@ void DebuggerMainWindow::savePersistentSettings() const
QVariantHash states; QVariantHash states;
qCDebug(perspectivesLog) << "PERSPECTIVE TYPES: " << d->m_lastTypePerspectiveStates.keys(); qCDebug(perspectivesLog) << "PERSPECTIVE TYPES: " << d->m_lastTypePerspectiveStates.keys();
for (const QString &type : d->m_lastTypePerspectiveStates.keys()) { for (const QString &type : d->m_lastTypePerspectiveStates.keys()) {
const QByteArray state = d->m_lastTypePerspectiveStates.value(type); const PerspectiveState state = d->m_lastTypePerspectiveStates.value(type);
qCDebug(perspectivesLog) << "PERSPECTIVE TYPE " << type << " HAS STATE: " << !state.isEmpty(); qCDebug(perspectivesLog) << "PERSPECTIVE TYPE " << type
QTC_ASSERT(!state.isEmpty(), continue); << " HAS STATE: " << !state.mainWindowState.isEmpty();
states.insert(type, state); QTC_ASSERT(!state.mainWindowState.isEmpty(), continue);
states.insert(type, QVariant::fromValue(state));
} }
QSettings *settings = ICore::settings(); QSettings *settings = ICore::settings();
settings->beginGroup(MAINWINDOW_KEY); settings->beginGroup(MAINWINDOW_KEY);
settings->setValue(CHANGED_DOCK_KEY, QStringList(Utils::toList(d->m_persistentChangedDocks))); settings->setValue(CHANGED_DOCK_KEY, QStringList(Utils::toList(d->m_persistentChangedDocks)));
settings->setValue(STATE_KEY, states); settings->setValue(STATE_KEY2, states);
settings->setValue(AUTOHIDE_TITLEBARS_KEY, autoHideTitleBars()); settings->setValue(AUTOHIDE_TITLEBARS_KEY, autoHideTitleBars());
settings->setValue(SHOW_CENTRALWIDGET_KEY, isCentralWidgetShown()); settings->setValue(SHOW_CENTRALWIDGET_KEY, isCentralWidgetShown());
settings->endGroup(); settings->endGroup();
@@ -931,11 +944,11 @@ void Perspective::select()
void PerspectivePrivate::restoreLayout() void PerspectivePrivate::restoreLayout()
{ {
qCDebug(perspectivesLog) << "RESTORE LAYOUT FOR " << m_id << settingsId(); qCDebug(perspectivesLog) << "RESTORE LAYOUT FOR " << m_id << settingsId();
QByteArray state = theMainWindow->d->m_lastPerspectiveStates.value(m_id); PerspectiveState state = theMainWindow->d->m_lastPerspectiveStates.value(m_id);
if (state.isEmpty()) { if (state.mainWindowState.isEmpty()) {
qCDebug(perspectivesLog) << "PERSPECTIVE STATE NOT AVAILABLE BY FULL ID."; qCDebug(perspectivesLog) << "PERSPECTIVE STATE NOT AVAILABLE BY FULL ID.";
state = theMainWindow->d->m_lastTypePerspectiveStates.value(settingsId()); state = theMainWindow->d->m_lastTypePerspectiveStates.value(settingsId());
if (state.isEmpty()) { if (state.mainWindowState.isEmpty()) {
qCDebug(perspectivesLog) << "PERSPECTIVE STATE NOT AVAILABLE BY PERSPECTIVE TYPE"; qCDebug(perspectivesLog) << "PERSPECTIVE STATE NOT AVAILABLE BY PERSPECTIVE TYPE";
} else { } else {
qCDebug(perspectivesLog) << "PERSPECTIVE STATE AVAILABLE BY PERSPECTIVE TYPE."; qCDebug(perspectivesLog) << "PERSPECTIVE STATE AVAILABLE BY PERSPECTIVE TYPE.";
@@ -961,19 +974,43 @@ void PerspectivePrivate::restoreLayout()
} }
} }
if (state.isEmpty()) { if (state.mainWindowState.isEmpty()) {
qCDebug(perspectivesLog) << "PERSPECTIVE " << m_id << "RESTORE NOT POSSIBLE, NO STORED STATE"; qCDebug(perspectivesLog) << "PERSPECTIVE " << m_id << "RESTORE NOT POSSIBLE, NO STORED STATE";
} else { } else {
bool result = theMainWindow->restoreState(state); bool result = theMainWindow->restoreState(state.mainWindowState);
qCDebug(perspectivesLog) << "PERSPECTIVE " << m_id << "RESTORED, SUCCESS: " << result; qCDebug(perspectivesLog) << "PERSPECTIVE " << m_id << "RESTORED, SUCCESS: " << result;
} }
for (DockOperation &op : m_dockOperations) {
if (op.operationType != Perspective::Raise) {
QTC_ASSERT(op.dock, continue);
for (QTreeView *tv : op.dock->findChildren<QTreeView *>()) {
if (tv->property(PerspectiveState::savesHeaderKey()).toBool()) {
const QByteArray s = state.headerViewStates.value(op.name()).toByteArray();
if (!s.isEmpty())
tv->header()->restoreState(s);
}
}
}
}
} }
void PerspectivePrivate::saveLayout() void PerspectivePrivate::saveLayout()
{ {
qCDebug(perspectivesLog) << "PERSPECTIVE" << m_id << "SAVE LAYOUT TO " << settingsId(); qCDebug(perspectivesLog) << "PERSPECTIVE" << m_id << "SAVE LAYOUT TO " << settingsId();
theMainWindow->d->m_lastPerspectiveStates.insert(m_id, theMainWindow->saveState()); PerspectiveState state;
theMainWindow->d->m_lastTypePerspectiveStates.insert(settingsId(), theMainWindow->saveState()); state.mainWindowState = theMainWindow->saveState();
for (DockOperation &op : m_dockOperations) {
QTC_ASSERT(op.dock, continue);
for (QTreeView *tv : op.dock->findChildren<QTreeView *>()) {
if (tv->property(PerspectiveState::savesHeaderKey()).toBool()) {
if (QHeaderView *hv = tv->header())
state.headerViewStates.insert(op.name(), hv->saveState());
}
}
}
theMainWindow->d->m_lastPerspectiveStates.insert(m_id, state);
theMainWindow->d->m_lastTypePerspectiveStates.insert(settingsId(), state);
} }
QString PerspectivePrivate::settingsId() const QString PerspectivePrivate::settingsId() const
@@ -1006,4 +1043,9 @@ void OptionalAction::setToolButtonStyle(Qt::ToolButtonStyle style)
m_toolButton->setToolButtonStyle(style); m_toolButton->setToolButtonStyle(style);
} }
const char *PerspectiveState::savesHeaderKey()
{
return "SavesHeader";
}
} // Utils } // Utils

View File

@@ -59,6 +59,20 @@ public:
QPointer<QToolButton> m_toolButton; QPointer<QToolButton> m_toolButton;
}; };
class PerspectiveState
{
public:
static const char *savesHeaderKey();
QByteArray mainWindowState;
QVariantHash headerViewStates;
friend QDataStream &operator>>(QDataStream &ds, PerspectiveState &state)
{ return ds >> state.mainWindowState >> state.headerViewStates; }
friend QDataStream &operator<<(QDataStream &ds, const PerspectiveState &state)
{ return ds << state.mainWindowState << state.headerViewStates; }
};
class DEBUGGER_EXPORT Perspective : public QObject class DEBUGGER_EXPORT Perspective : public QObject
{ {
public: public:
@@ -150,3 +164,5 @@ private:
}; };
} // Utils } // Utils
Q_DECLARE_METATYPE(Utils::PerspectiveState)

View File

@@ -2063,6 +2063,7 @@ QWidget *DebuggerPluginPrivate::addSearch(BaseTreeView *treeView)
{ {
QAction *act = action(UseAlternatingRowColors); QAction *act = action(UseAlternatingRowColors);
treeView->setAlternatingRowColors(act->isChecked()); treeView->setAlternatingRowColors(act->isChecked());
treeView->setProperty(PerspectiveState::savesHeaderKey(), true);
connect(act, &QAction::toggled, treeView, &BaseTreeView::setAlternatingRowColors); connect(act, &QAction::toggled, treeView, &BaseTreeView::setAlternatingRowColors);
return ItemViewFind::createSearchableWrapper(treeView); return ItemViewFind::createSearchableWrapper(treeView);