| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815 |
- /****************************************************************************
- **
- ** Copyright (C) 2020 Uwe Kindler
- ** Contact: https://www.qt.io/licensing/
- **
- ** This file is part of Qt Creator.
- **
- ** Commercial License Usage
- ** Licensees holding valid commercial Qt licenses may use this file in
- ** accordance with the commercial license agreement provided with the
- ** Software or, alternatively, in accordance with the terms contained in
- ** a written agreement between you and The Qt Company. For licensing terms
- ** and conditions see https://www.qt.io/terms-conditions. For further
- ** information use the contact form at https://www.qt.io/contact-us.
- **
- ** GNU Lesser General Public License Usage
- ** Alternatively, this file may be used under the terms of the GNU Lesser
- ** General Public License version 2.1 or (at your option) any later version.
- ** The licenses are as published by the Free Software Foundation
- ** and appearing in the file LICENSE.LGPLv21 included in the packaging
- ** of this file. Please review the following information to ensure
- ** the GNU Lesser General Public License version 2.1 requirements
- ** will be met: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- **
- ** GNU General Public License Usage
- ** Alternatively, this file may be used under the terms of the GNU
- ** General Public License version 3 or (at your option) any later version
- ** approved by the KDE Free Qt Foundation. The licenses are as published by
- ** the Free Software Foundation and appearing in the file LICENSE.GPL3
- ** included in the packaging of this file. Please review the following
- ** information to ensure the GNU General Public License requirements will
- ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
- **
- ****************************************************************************/
- #include "dockmanager.h"
- #include "ads_globals.h"
- #include "dockareawidget.h"
- #include "dockingstatereader.h"
- #include "dockoverlay.h"
- #include "dockwidget.h"
- #include "dockwidgettab.h"
- #include "floatingdockcontainer.h"
- #include "iconprovider.h"
- #include "workspacedialog.h"
- #include <utils/qtcassert.h>
- #include <algorithm>
- #include <iostream>
- #include <QAction>
- #include <QApplication>
- #include <QDateTime>
- #include <QDir>
- #include <QFile>
- #include <QFileInfo>
- #include <QList>
- #include <QLoggingCategory>
- #include <QMainWindow>
- #include <QMap>
- #include <QMenu>
- #include <QMessageBox>
- #include <QSettings>
- #include <QVariant>
- #include <QXmlStreamWriter>
- static Q_LOGGING_CATEGORY(adsLog, "qtc.qmldesigner.advanceddockingsystem", QtDebugMsg)
- namespace ADS
- {
- static DockManager::ConfigFlags g_staticConfigFlags = DockManager::DefaultNonOpaqueConfig;
- /**
- * Private data class of DockManager class (pimpl)
- */
- struct DockManagerPrivate
- {
- DockManager *q;
- QList<FloatingDockContainer *> m_floatingWidgets;
- QList<DockContainerWidget *> m_containers;
- DockOverlay *m_containerOverlay;
- DockOverlay *m_dockAreaOverlay;
- QMap<QString, DockWidget *> m_dockWidgetsMap;
- bool m_restoringState = false;
- QVector<FloatingDockContainer *> m_uninitializedFloatingWidgets;
- QString m_workspaceName;
- bool m_workspaceListDirty = true;
- QStringList m_workspaces;
- QHash<QString, QDateTime> m_workspaceDateTimes;
- QString m_workspaceToRestoreAtStartup;
- bool m_autorestoreLastWorkspace; // This option is set in the Workspace Manager!
- QSettings *m_settings;
- /**
- * Private data constructor
- */
- DockManagerPrivate(DockManager *parent);
- /**
- * Checks if the given data stream is a valid docking system state
- * file.
- */
- bool checkFormat(const QByteArray &state, int version);
- /**
- * Restores the state
- */
- bool restoreStateFromXml(const QByteArray &state,
- int version,
- bool testing = internal::restore);
- /**
- * Restore state
- */
- bool restoreState(const QByteArray &state, int version);
- void restoreDockWidgetsOpenState();
- void restoreDockAreasIndices();
- void emitTopLevelEvents();
- void hideFloatingWidgets()
- {
- // Hide updates of floating widgets from user
- for (auto floatingWidget : m_floatingWidgets) { // TODO qAsConst()
- floatingWidget->hide();
- }
- }
- void markDockWidgetsDirty()
- {
- for (auto dockWidget : m_dockWidgetsMap) { // TODO qAsConst()
- dockWidget->setProperty("dirty", true);
- }
- }
- /**
- * Restores the container with the given index
- */
- bool restoreContainer(int index, DockingStateReader &stream, bool testing);
- void workspaceLoadingProgress();
- };
- // struct DockManagerPrivate
- DockManagerPrivate::DockManagerPrivate(DockManager *parent)
- : q(parent)
- {}
- bool DockManagerPrivate::restoreContainer(int index, DockingStateReader &stream, bool testing)
- {
- if (testing) {
- index = 0;
- }
- bool result = false;
- if (index >= m_containers.count()) {
- FloatingDockContainer *floatingWidget = new FloatingDockContainer(q);
- result = floatingWidget->restoreState(stream, testing);
- } else {
- qCInfo(adsLog) << "d->m_containers[i]->restoreState ";
- auto container = m_containers[index];
- if (container->isFloating()) {
- result = container->floatingWidget()->restoreState(stream, testing);
- } else {
- result = container->restoreState(stream, testing);
- }
- }
- return result;
- }
- bool DockManagerPrivate::checkFormat(const QByteArray &state, int version)
- {
- return restoreStateFromXml(state, version, internal::restoreTesting);
- }
- bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int version, bool testing)
- {
- Q_UNUSED(version) // TODO version is not needed, why is it in here in the first place?
- if (state.isEmpty()) {
- return false;
- }
- DockingStateReader stateReader(state);
- stateReader.readNextStartElement();
- if (stateReader.name() != "QtAdvancedDockingSystem") {
- return false;
- }
- qCInfo(adsLog) << stateReader.attributes().value("version");
- bool ok;
- int v = stateReader.attributes().value("version").toInt(&ok);
- if (!ok || v > CurrentVersion) {
- return false;
- }
- stateReader.setFileVersion(v);
- bool result = true;
- #ifdef ADS_DEBUG_PRINT
- int dockContainers = stateReader.attributes().value("containers").toInt();
- qCInfo(adsLog) << dockContainers;
- #endif
- int dockContainerCount = 0;
- while (stateReader.readNextStartElement()) {
- if (stateReader.name() == "container") {
- result = restoreContainer(dockContainerCount, stateReader, testing);
- if (!result) {
- break;
- }
- dockContainerCount++;
- }
- }
- if (!testing) {
- // Delete remaining empty floating widgets
- int floatingWidgetIndex = dockContainerCount - 1;
- int deleteCount = m_floatingWidgets.count() - floatingWidgetIndex;
- for (int i = 0; i < deleteCount; ++i) {
- m_floatingWidgets[floatingWidgetIndex + i]->deleteLater();
- q->removeDockContainer(m_floatingWidgets[floatingWidgetIndex + i]->dockContainer());
- }
- }
- return result;
- }
- void DockManagerPrivate::restoreDockWidgetsOpenState()
- {
- // All dock widgets, that have not been processed in the restore state
- // function are invisible to the user now and have no assigned dock area
- // They do not belong to any dock container, until the user toggles the
- // toggle view action the next time
- for (auto dockWidget : m_dockWidgetsMap) {
- if (dockWidget->property(internal::dirtyProperty).toBool()) {
- dockWidget->flagAsUnassigned();
- emit dockWidget->viewToggled(false);
- } else {
- dockWidget->toggleViewInternal(
- !dockWidget->property(internal::closedProperty).toBool());
- }
- }
- }
- void DockManagerPrivate::restoreDockAreasIndices()
- {
- // Now all dock areas are properly restored and we setup the index of
- // The dock areas because the previous toggleView() action has changed
- // the dock area index
- int count = 0;
- for (auto dockContainer : m_containers) {
- count++;
- for (int i = 0; i < dockContainer->dockAreaCount(); ++i) {
- DockAreaWidget *dockArea = dockContainer->dockArea(i);
- QString dockWidgetName = dockArea->property("currentDockWidget").toString();
- DockWidget *dockWidget = nullptr;
- if (!dockWidgetName.isEmpty()) {
- dockWidget = q->findDockWidget(dockWidgetName);
- }
- if (!dockWidget || dockWidget->isClosed()) {
- int index = dockArea->indexOfFirstOpenDockWidget();
- if (index < 0) {
- continue;
- }
- dockArea->setCurrentIndex(index);
- } else {
- dockArea->internalSetCurrentDockWidget(dockWidget);
- }
- }
- }
- }
- void DockManagerPrivate::emitTopLevelEvents()
- {
- // Finally we need to send the topLevelChanged() signals for all dock
- // widgets if top level changed
- for (auto dockContainer : m_containers) {
- DockWidget *topLevelDockWidget = dockContainer->topLevelDockWidget();
- if (topLevelDockWidget) {
- topLevelDockWidget->emitTopLevelChanged(true);
- } else {
- for (int i = 0; i < dockContainer->dockAreaCount(); ++i) {
- auto dockArea = dockContainer->dockArea(i);
- for (auto dockWidget : dockArea->dockWidgets()) {
- dockWidget->emitTopLevelChanged(false);
- }
- }
- }
- }
- }
- bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
- {
- QByteArray currentState = state.startsWith("<?xml") ? state : qUncompress(state);
- if (!checkFormat(currentState, version)) {
- qCInfo(adsLog) << "checkFormat: Error checking format!!!";
- return false;
- }
- // Hide updates of floating widgets from use
- hideFloatingWidgets();
- markDockWidgetsDirty();
- if (!restoreStateFromXml(currentState, version)) {
- qCInfo(adsLog) << "restoreState: Error restoring state!!!";
- return false;
- }
- restoreDockWidgetsOpenState();
- restoreDockAreasIndices();
- emitTopLevelEvents();
- return true;
- }
- DockManager::DockManager(QWidget *parent)
- : DockContainerWidget(this, parent)
- , d(new DockManagerPrivate(this))
- {
- connect(this, &DockManager::workspaceListChanged, this, [=] {
- d->m_workspaceListDirty = true;
- });
- createRootSplitter();
- QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parent);
- if (mainWindow) {
- mainWindow->setCentralWidget(this);
- }
- d->m_dockAreaOverlay = new DockOverlay(this, DockOverlay::ModeDockAreaOverlay);
- d->m_containerOverlay = new DockOverlay(this, DockOverlay::ModeContainerOverlay);
- d->m_containers.append(this);
- //d->loadStylesheet();
- }
- DockManager::~DockManager()
- {
- // If the factory default workspace is still loaded, create a default workspace just in case
- // the layout changed as there is no tracking of layout changes.
- if (isFactoryDefaultWorkspace(d->m_workspaceName)
- && !isDefaultWorkspace(d->m_workspaceName)) {
- createWorkspace(Constants::DEFAULT_NAME);
- openWorkspace(Constants::DEFAULT_NAME);
- }
- emit aboutToUnloadWorkspace(d->m_workspaceName);
- save();
- for (auto floatingWidget : d->m_floatingWidgets) {
- delete floatingWidget;
- }
- delete d;
- }
- DockManager::ConfigFlags DockManager::configFlags() { return g_staticConfigFlags; }
- void DockManager::setConfigFlags(const ConfigFlags flags) { g_staticConfigFlags = flags; }
- void DockManager::setConfigFlag(eConfigFlag flag, bool on)
- {
- internal::setFlag(g_staticConfigFlags, flag, on);
- }
- bool DockManager::testConfigFlag(eConfigFlag flag)
- {
- return configFlags().testFlag(flag);
- }
- IconProvider &DockManager::iconProvider()
- {
- static IconProvider instance;
- return instance;
- }
- int DockManager::startDragDistance()
- {
- return static_cast<int>(QApplication::startDragDistance() * 1.5);
- }
- void DockManager::setSettings(QSettings *settings) { d->m_settings = settings; }
- DockAreaWidget *DockManager::addDockWidget(DockWidgetArea area,
- DockWidget *dockWidget,
- DockAreaWidget *dockAreaWidget)
- {
- d->m_dockWidgetsMap.insert(dockWidget->objectName(), dockWidget);
- return DockContainerWidget::addDockWidget(area, dockWidget, dockAreaWidget);
- }
- DockAreaWidget *DockManager::addDockWidgetTab(DockWidgetArea area, DockWidget *dockWidget)
- {
- DockAreaWidget *areaWidget = lastAddedDockAreaWidget(area);
- if (areaWidget) {
- return addDockWidget(ADS::CenterDockWidgetArea, dockWidget, areaWidget);
- } else if (!openedDockAreas().isEmpty()) {
- return addDockWidget(area, dockWidget, openedDockAreas().last());
- } else {
- return addDockWidget(area, dockWidget, nullptr);
- }
- }
- DockAreaWidget *DockManager::addDockWidgetTabToArea(DockWidget *dockWidget,
- DockAreaWidget *dockAreaWidget)
- {
- return addDockWidget(ADS::CenterDockWidgetArea, dockWidget, dockAreaWidget);
- }
- FloatingDockContainer *DockManager::addDockWidgetFloating(DockWidget *dockWidget)
- {
- d->m_dockWidgetsMap.insert(dockWidget->objectName(), dockWidget);
- DockAreaWidget *oldDockArea = dockWidget->dockAreaWidget();
- if (oldDockArea) {
- oldDockArea->removeDockWidget(dockWidget);
- }
- dockWidget->setDockManager(this);
- FloatingDockContainer *floatingWidget = new FloatingDockContainer(dockWidget);
- floatingWidget->resize(dockWidget->size());
- if (isVisible()) {
- floatingWidget->show();
- } else {
- d->m_uninitializedFloatingWidgets.append(floatingWidget);
- }
- return floatingWidget;
- }
- void DockManager::registerFloatingWidget(FloatingDockContainer *floatingWidget)
- {
- d->m_floatingWidgets.append(floatingWidget);
- emit floatingWidgetCreated(floatingWidget);
- qCInfo(adsLog) << "d->FloatingWidgets.count() " << d->m_floatingWidgets.count();
- }
- void DockManager::removeFloatingWidget(FloatingDockContainer *floatingWidget)
- {
- d->m_floatingWidgets.removeAll(floatingWidget);
- }
- void DockManager::registerDockContainer(DockContainerWidget *dockContainer)
- {
- d->m_containers.append(dockContainer);
- }
- void DockManager::removeDockContainer(DockContainerWidget *dockContainer)
- {
- if (this != dockContainer) {
- d->m_containers.removeAll(dockContainer);
- }
- }
- DockOverlay *DockManager::containerOverlay() const { return d->m_containerOverlay; }
- DockOverlay *DockManager::dockAreaOverlay() const { return d->m_dockAreaOverlay; }
- const QList<DockContainerWidget *> DockManager::dockContainers() const
- {
- return d->m_containers;
- }
- const QList<FloatingDockContainer *> DockManager::floatingWidgets() const
- {
- return d->m_floatingWidgets;
- }
- unsigned int DockManager::zOrderIndex() const { return 0; }
- QByteArray DockManager::saveState(int version) const
- {
- QByteArray xmlData;
- QXmlStreamWriter stream(&xmlData);
- auto configFlags = DockManager::configFlags();
- stream.setAutoFormatting(configFlags.testFlag(XmlAutoFormattingEnabled));
- stream.writeStartDocument();
- stream.writeStartElement("QtAdvancedDockingSystem");
- stream.writeAttribute("version", QString::number(version));
- stream.writeAttribute("containers", QString::number(d->m_containers.count()));
- for (auto container : d->m_containers) {
- container->saveState(stream);
- }
- stream.writeEndElement();
- stream.writeEndDocument();
- return xmlData;
- }
- bool DockManager::restoreState(const QByteArray &state, int version)
- {
- // Prevent multiple calls as long as state is not restore. This may
- // happen, if QApplication::processEvents() is called somewhere
- if (d->m_restoringState) {
- return false;
- }
- // We hide the complete dock manager here. Restoring the state means
- // that DockWidgets are removed from the DockArea internal stack layout
- // which in turn means, that each time a widget is removed the stack
- // will show and raise the next available widget which in turn
- // triggers show events for the dock widgets. To avoid this we hide the
- // dock manager. Because there will be no processing of application
- // events until this function is finished, the user will not see this
- // hiding
- bool isHidden = this->isHidden();
- if (!isHidden) {
- hide();
- }
- d->m_restoringState = true;
- emit restoringState();
- bool result = d->restoreState(state, version);
- d->m_restoringState = false;
- emit stateRestored();
- if (!isHidden) {
- show();
- }
- return result;
- }
- void DockManager::showEvent(QShowEvent *event)
- {
- Super::showEvent(event);
- if (d->m_uninitializedFloatingWidgets.empty()) {
- return;
- }
- for (auto floatingWidget : d->m_uninitializedFloatingWidgets) {
- floatingWidget->show();
- }
- d->m_uninitializedFloatingWidgets.clear();
- }
- DockWidget *DockManager::findDockWidget(const QString &objectName) const
- {
- return d->m_dockWidgetsMap.value(objectName, nullptr);
- }
- void DockManager::removeDockWidget(DockWidget *dockWidget)
- {
- emit dockWidgetAboutToBeRemoved(dockWidget);
- d->m_dockWidgetsMap.remove(dockWidget->objectName());
- DockContainerWidget::removeDockWidget(dockWidget);
- emit dockWidgetRemoved(dockWidget);
- }
- QMap<QString, DockWidget *> DockManager::dockWidgetsMap() const { return d->m_dockWidgetsMap; }
- bool DockManager::isRestoringState() const { return d->m_restoringState; }
- void DockManager::showWorkspaceMananger()
- {
- // Save current workspace
- save();
- WorkspaceDialog workspaceDialog(this, parentWidget());
- workspaceDialog.setAutoLoadWorkspace(autoRestorLastWorkspace());
- workspaceDialog.exec();
- QTC_ASSERT(d->m_settings, return );
- d->m_settings->setValue(Constants::AUTO_RESTORE_WORKSPACE_SETTINGS_KEY,
- workspaceDialog.autoLoadWorkspace());
- }
- bool DockManager::isFactoryDefaultWorkspace(const QString &workspace) const
- {
- return workspace == QLatin1String(Constants::FACTORY_DEFAULT_NAME);
- }
- bool DockManager::isDefaultWorkspace(const QString &workspace) const
- {
- return workspace == QLatin1String(Constants::DEFAULT_NAME);
- }
- bool DockManager::save()
- {
- if (isFactoryDefaultWorkspace(activeWorkspace()))
- return true;
- emit aboutToSaveWorkspace();
- bool result = write(saveState(), parentWidget());
- if (result) {
- d->m_workspaceDateTimes.insert(activeWorkspace(), QDateTime::currentDateTime());
- } else {
- QMessageBox::warning(parentWidget(),
- tr("Cannot Save Session"),
- tr("Could not save session to file %1")
- .arg(workspaceNameToFileName(d->m_workspaceName)));
- }
- return result;
- }
- QString DockManager::activeWorkspace() const { return d->m_workspaceName; }
- QString DockManager::lastWorkspace() const
- {
- QTC_ASSERT(d->m_settings, return {});
- return d->m_settings->value(Constants::STARTUP_WORKSPACE_SETTINGS_KEY).toString();
- }
- bool DockManager::autoRestorLastWorkspace() const
- {
- QTC_ASSERT(d->m_settings, return false);
- return d->m_settings->value(Constants::AUTO_RESTORE_WORKSPACE_SETTINGS_KEY).toBool();
- }
- const QString m_dirName = QLatin1String("workspaces");
- const QString m_fileExt = QLatin1String(".wrk"); // TODO
- QStringList DockManager::workspaces()
- {
- if (d->m_workspaces.isEmpty() || d->m_workspaceListDirty) {
- auto tmp = QSet<QString>::fromList(d->m_workspaces);
- QTC_ASSERT(d->m_settings, return {});
- QDir workspaceDir(QFileInfo(d->m_settings->fileName()).path() + QLatin1Char('/')
- + m_dirName);
- QFileInfoList workspaceFiles
- = workspaceDir.entryInfoList(QStringList() << QLatin1String("*.wrk"),
- QDir::NoFilter,
- QDir::Time); // TODO Choose different extension
- for (const QFileInfo &fileInfo : workspaceFiles) {
- QString filename = fileInfo.completeBaseName();
- filename.replace("_", " ");
- d->m_workspaceDateTimes.insert(filename, fileInfo.lastModified());
- //if (name != QLatin1String(Constants::DEFAULT_NAME))
- tmp.insert(filename);
- }
- //d->m_workspaces.prepend(QLatin1String(Constants::DEFAULT_NAME));
- d->m_workspaceListDirty = false;
- d->m_workspaces = tmp.toList();
- }
- return d->m_workspaces;
- }
- QDateTime DockManager::workspaceDateTime(const QString &workspace) const
- {
- return d->m_workspaceDateTimes.value(workspace);
- }
- QString DockManager::workspaceNameToFileName(const QString &workspaceName) const
- {
- QTC_ASSERT(d->m_settings, return {});
- QString workspaceNameCopy = workspaceName;
- return (QFileInfo(d->m_settings->fileName()).path() + QLatin1Char('/') + m_dirName
- + QLatin1Char('/') + workspaceNameCopy.replace(" ", "_") + QLatin1String(".wrk"));
- }
- /**
- * Creates \a workspace, but does not actually create the file.
- */
- bool DockManager::createWorkspace(const QString &workspace)
- {
- if (workspaces().contains(workspace))
- return false;
- d->m_workspaces.insert(1, workspace);
- d->m_workspaceDateTimes.insert(workspace, QDateTime::currentDateTime());
- emit workspaceListChanged();
- return true;
- }
- bool DockManager::openWorkspace(const QString &workspace)
- {
- // Do nothing if we have that workspace already loaded, exception if the
- // workspace is the default virgin workspace we still want to be able to
- // load the default workspace.
- if (workspace == d->m_workspaceName) // && !isFactoryDefaultWorkspace(workspace))
- return true;
- if (!workspaces().contains(workspace))
- return false;
- // Check if the currently active workspace isn't empty and try to save it
- if (!d->m_workspaceName.isEmpty()) {
- // Allow everyone to set something in the workspace and before saving
- emit aboutToUnloadWorkspace(d->m_workspaceName);
- if (!save()) {
- return false;
- }
- }
- // Try loading the file
- QByteArray data;
- QString fileName = workspaceNameToFileName(workspace);
- if (QFileInfo(fileName).exists()) {
- QFile file(fileName);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- QMessageBox::warning(parentWidget(),
- tr("Cannot Restore Workspace"),
- tr("Could not restore workspace %1").arg(fileName));
- return false;
- }
- data = file.readAll();
- file.close();
- }
- emit openingWorkspace(workspace);
- // If data was loaded from file try to restore its state
- if (!data.isNull() && !restoreState(data)) {
- return false;
- }
- d->m_workspaceName = workspace;
- emit workspaceLoaded(workspace);
- return true;
- }
- /**
- * \brief Shows a dialog asking the user to confirm deleting the workspace \p workspace
- */
- bool DockManager::confirmWorkspaceDelete(const QStringList &workspace)
- {
- const QString title = workspace.size() == 1 ? tr("Delete Workspace")
- : tr("Delete Workspaces");
- const QString question = workspace.size() == 1
- ? tr("Delete workspace %1?").arg(workspace.first())
- : tr("Delete these workspaces?\n %1")
- .arg(workspace.join("\n "));
- return QMessageBox::question(parentWidget(),
- title,
- question,
- QMessageBox::Yes | QMessageBox::No)
- == QMessageBox::Yes;
- }
- /**
- * Deletes \a workspace name from workspace list and the file from disk.
- */
- bool DockManager::deleteWorkspace(const QString &workspace)
- {
- // Remove workspace from internal list
- if (!d->m_workspaces.contains(workspace))
- return false;
- d->m_workspaces.removeOne(workspace);
- emit workspacesRemoved();
- emit workspaceListChanged();
- // Remove corresponding workspace file
- QFile fi(workspaceNameToFileName(workspace));
- if (fi.exists())
- return fi.remove();
- return false; // TODO If we allow temporary workspaces without writing them to file
- // directly, this needs to be true otherwise in all those cases it will return false.
- }
- void DockManager::deleteWorkspaces(const QStringList &workspaces)
- {
- for (const QString &workspace : workspaces)
- deleteWorkspace(workspace);
- }
- bool DockManager::cloneWorkspace(const QString &original, const QString &clone)
- {
- if (!d->m_workspaces.contains(original))
- return false;
- QFile fi(workspaceNameToFileName(original));
- // If the file does not exist, we can still clone
- if (!fi.exists() || fi.copy(workspaceNameToFileName(clone))) {
- d->m_workspaces.insert(1, clone);
- d->m_workspaceDateTimes.insert(clone,
- QFileInfo(workspaceNameToFileName(clone)).lastModified());
- return true;
- }
- return false;
- }
- bool DockManager::renameWorkspace(const QString &original, const QString &newName)
- {
- if (!cloneWorkspace(original, newName))
- return false;
- if (original == activeWorkspace())
- openWorkspace(newName);
- return deleteWorkspace(original);
- }
- bool DockManager::write(const QByteArray &data, QString *errorString) const
- {
- QString fileName = workspaceNameToFileName(activeWorkspace());
- QDir tmp;
- tmp.mkpath(QFileInfo(fileName).path());
- QFile fileSaver(fileName);
- if (fileSaver.open(QFile::WriteOnly | QIODevice::Text)) {
- fileSaver.write(data);
- fileSaver.close();
- return true;
- } else {
- *errorString = fileSaver.errorString();
- return false;
- }
- }
- #ifdef QT_GUI_LIB
- bool DockManager::write(const QByteArray &data, QWidget *parent) const
- {
- QString errorString;
- const bool success = write(data, &errorString);
- if (!success)
- QMessageBox::critical(parent,
- QCoreApplication::translate("Utils::FileSaverBase", "File Error"),
- errorString);
- return success;
- }
- #endif // QT_GUI_LIB
- } // namespace ADS
|