forked from qt-creator/qt-creator
479 lines
18 KiB
C
479 lines
18 KiB
C
|
|
/****************************************************************************
|
||
|
|
**
|
||
|
|
** 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.
|
||
|
|
**
|
||
|
|
****************************************************************************/
|
||
|
|
|
||
|
|
#pragma once
|
||
|
|
|
||
|
|
#include "ads_globals.h"
|
||
|
|
#include "dockcontainerwidget.h"
|
||
|
|
#include "dockwidget.h"
|
||
|
|
#include "floatingdockcontainer.h"
|
||
|
|
|
||
|
|
#include <utils/persistentsettings.h>
|
||
|
|
|
||
|
|
#include <QByteArray>
|
||
|
|
#include <QDateTime>
|
||
|
|
#include <QFlags>
|
||
|
|
#include <QList>
|
||
|
|
#include <QMap>
|
||
|
|
#include <QString>
|
||
|
|
#include <QStringList>
|
||
|
|
#include <QtGui/QIcon>
|
||
|
|
#include <qobjectdefs.h>
|
||
|
|
|
||
|
|
class QSettings;
|
||
|
|
class QMenu;
|
||
|
|
|
||
|
|
namespace ADS {
|
||
|
|
|
||
|
|
namespace Constants {
|
||
|
|
const char FACTORY_DEFAULT_NAME[] = "factorydefault";
|
||
|
|
const char DEFAULT_NAME[] = "default";
|
||
|
|
const char STARTUP_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/StartupWorkspace";
|
||
|
|
const char AUTO_RESTORE_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/AutoRestoreLastWorkspace";
|
||
|
|
} // namespace Constants
|
||
|
|
|
||
|
|
struct DockManagerPrivate;
|
||
|
|
class FloatingDockContainer;
|
||
|
|
struct FloatingDockContainerPrivate;
|
||
|
|
class DockComponentsFactory;
|
||
|
|
class DockContainerWidget;
|
||
|
|
class DockContainerWidgetPrivate;
|
||
|
|
class DockOverlay;
|
||
|
|
class DockAreaTabBar;
|
||
|
|
class DockWidgetTab;
|
||
|
|
struct DockWidgetTabPrivate;
|
||
|
|
struct DockAreaWidgetPrivate;
|
||
|
|
class IconProvider;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The central dock manager that maintains the complete docking system.
|
||
|
|
* With the configuration flags you can globally control the functionality
|
||
|
|
* of the docking system. The dock manager uses an internal stylesheet to
|
||
|
|
* style its components like splitters, tabs and buttons. If you want to
|
||
|
|
* disable this stylesheet because your application uses its own,
|
||
|
|
* just call the function for settings the stylesheet with an empty
|
||
|
|
* string.
|
||
|
|
* \code
|
||
|
|
* dockManager->setStyleSheet("");
|
||
|
|
* \endcode
|
||
|
|
**/
|
||
|
|
class ADS_EXPORT DockManager : public DockContainerWidget
|
||
|
|
{
|
||
|
|
Q_OBJECT
|
||
|
|
private:
|
||
|
|
DockManagerPrivate *d; ///< private data (pimpl)
|
||
|
|
friend struct DockManagerPrivate;
|
||
|
|
friend class FloatingDockContainer;
|
||
|
|
friend struct FloatingDockContainerPrivate;
|
||
|
|
friend class DockContainerWidget;
|
||
|
|
friend class DockContainerWidgetPrivate;
|
||
|
|
friend class DockAreaTabBar;
|
||
|
|
friend class DockWidgetTab;
|
||
|
|
friend struct DockAreaWidgetPrivate;
|
||
|
|
friend struct DockWidgetTabPrivate;
|
||
|
|
friend class FloatingDragPreview;
|
||
|
|
friend struct FloatingDragPreviewPrivate;
|
||
|
|
friend class DockAreaTitleBar;
|
||
|
|
|
||
|
|
protected:
|
||
|
|
/**
|
||
|
|
* Registers the given floating widget in the internal list of
|
||
|
|
* floating widgets
|
||
|
|
*/
|
||
|
|
void registerFloatingWidget(FloatingDockContainer *floatingWidget);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove the given floating widget from the list of registered floating
|
||
|
|
* widgets
|
||
|
|
*/
|
||
|
|
void removeFloatingWidget(FloatingDockContainer *floatingWidget);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Registers the given dock container widget
|
||
|
|
*/
|
||
|
|
void registerDockContainer(DockContainerWidget *dockContainer);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove dock container from the internal list of registered dock
|
||
|
|
* containers
|
||
|
|
*/
|
||
|
|
void removeDockContainer(DockContainerWidget *dockContainer);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Overlay for containers
|
||
|
|
*/
|
||
|
|
DockOverlay *containerOverlay() const;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Overlay for dock areas
|
||
|
|
*/
|
||
|
|
DockOverlay *dockAreaOverlay() const;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Show the floating widgets that has been created floating
|
||
|
|
*/
|
||
|
|
virtual void showEvent(QShowEvent *event) override;
|
||
|
|
|
||
|
|
public:
|
||
|
|
using Super = DockContainerWidget;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* These global configuration flags configure some global dock manager
|
||
|
|
* settings.
|
||
|
|
*/
|
||
|
|
enum eConfigFlag {
|
||
|
|
ActiveTabHasCloseButton
|
||
|
|
= 0x0001, //!< If this flag is set, the active tab in a tab area has a close button
|
||
|
|
DockAreaHasCloseButton
|
||
|
|
= 0x0002, //!< If the flag is set each dock area has a close button
|
||
|
|
DockAreaCloseButtonClosesTab
|
||
|
|
= 0x0004, //!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete dock area
|
||
|
|
OpaqueSplitterResize
|
||
|
|
= 0x0008, //!< See QSplitter::setOpaqueResize() documentation
|
||
|
|
XmlAutoFormattingEnabled
|
||
|
|
= 0x0010, //!< If enabled, the XML writer automatically adds line-breaks and indentation to empty sections between elements (ignorable whitespace).
|
||
|
|
XmlCompressionEnabled
|
||
|
|
= 0x0020, //!< If enabled, the XML output will be compressed and is not human readable anymore
|
||
|
|
TabCloseButtonIsToolButton
|
||
|
|
= 0x0040, //! If enabled the tab close buttons will be QToolButtons instead of QPushButtons - disabled by default
|
||
|
|
AllTabsHaveCloseButton
|
||
|
|
= 0x0080, //!< if this flag is set, then all tabs that are closable show a close button
|
||
|
|
RetainTabSizeWhenCloseButtonHidden
|
||
|
|
= 0x0100, //!< if this flag is set, the space for the close button is reserved even if the close button is not visible
|
||
|
|
OpaqueUndocking
|
||
|
|
= 0x0200, ///< If enabled, the widgets are immediately undocked into floating widgets, if disabled, only a draw preview is undocked and the real undocking is deferred until the mouse is released
|
||
|
|
DragPreviewIsDynamic
|
||
|
|
= 0x0400, ///< If opaque undocking is disabled, this flag defines the behavior of the drag preview window, if this flag is enabled, the preview will be adjusted dynamically to the drop area
|
||
|
|
DragPreviewShowsContentPixmap
|
||
|
|
= 0x0800, ///< If opaque undocking is disabled, the created drag preview window shows a copy of the content of the dock widget / dock are that is dragged
|
||
|
|
DragPreviewHasWindowFrame
|
||
|
|
= 0x1000, ///< If opaque undocking is disabled, then this flag configures if the drag preview is frameless or looks like a real window
|
||
|
|
AlwaysShowTabs
|
||
|
|
= 0x2000, ///< If this option is enabled, the tab of a dock widget is always displayed - even if it is the only visible dock widget in a floating widget.
|
||
|
|
DockAreaHasUndockButton
|
||
|
|
= 0x4000, //!< If the flag is set each dock area has an undock button
|
||
|
|
DockAreaHasTabsMenuButton
|
||
|
|
= 0x8000, //!< If the flag is set each dock area has a tabs menu button
|
||
|
|
DockAreaHideDisabledButtons
|
||
|
|
= 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back)
|
||
|
|
DockAreaDynamicTabsMenuButtonVisibility
|
||
|
|
= 0x20000, //!< If the flag is set dock area will disable a tabs menu button when there is only one tab in the area
|
||
|
|
FloatingContainerHasWidgetTitle
|
||
|
|
= 0x40000,
|
||
|
|
FloatingContainerHasWidgetIcon
|
||
|
|
= 0x80000,
|
||
|
|
|
||
|
|
DefaultDockAreaButtons = DockAreaHasCloseButton
|
||
|
|
| DockAreaHasUndockButton
|
||
|
|
| DockAreaHasTabsMenuButton,///< default configuration of dock area title bar buttons
|
||
|
|
|
||
|
|
DefaultBaseConfig = DefaultDockAreaButtons
|
||
|
|
| ActiveTabHasCloseButton
|
||
|
|
| XmlCompressionEnabled
|
||
|
|
| FloatingContainerHasWidgetTitle,///< default base configuration settings
|
||
|
|
|
||
|
|
DefaultOpaqueConfig = DefaultBaseConfig
|
||
|
|
| OpaqueSplitterResize
|
||
|
|
| OpaqueUndocking, ///< the default configuration with opaque operations - this may cause issues if ActiveX or Qt 3D windows are involved
|
||
|
|
|
||
|
|
DefaultNonOpaqueConfig = DefaultBaseConfig
|
||
|
|
| DragPreviewShowsContentPixmap, ///< the default configuration for non opaque operations
|
||
|
|
|
||
|
|
NonOpaqueWithWindowFrame = DefaultNonOpaqueConfig
|
||
|
|
| DragPreviewHasWindowFrame ///< the default configuration for non opaque operations that show a real window with frame
|
||
|
|
};
|
||
|
|
Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag)
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Default Constructor.
|
||
|
|
* If the given parent is a QMainWindow, the dock manager sets itself as the
|
||
|
|
* central widget.
|
||
|
|
* Before you create any dock widgets, you should properly setup the
|
||
|
|
* configuration flags via setConfigFlags().
|
||
|
|
*/
|
||
|
|
DockManager(QWidget *parent = nullptr);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Virtual Destructor
|
||
|
|
*/
|
||
|
|
virtual ~DockManager() override;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This function returns the global configuration flags
|
||
|
|
*/
|
||
|
|
static ConfigFlags configFlags();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the global configuration flags for the whole docking system.
|
||
|
|
* Call this function before you create your first dock widget.
|
||
|
|
*/
|
||
|
|
static void setConfigFlags(const ConfigFlags flags);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set a certain config flag
|
||
|
|
*/
|
||
|
|
static void setConfigFlag(eConfigFlag flag, bool on = true);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns true if the given config flag is set
|
||
|
|
*/
|
||
|
|
static bool testConfigFlag(eConfigFlag flag);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the global icon provider.
|
||
|
|
* The icon provider enables the use of custom icons in case using
|
||
|
|
* styleheets for icons is not an option.
|
||
|
|
*/
|
||
|
|
static IconProvider &iconProvider();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The distance the user needs to move the mouse with the left button
|
||
|
|
* hold down before a dock widget start floating
|
||
|
|
*/
|
||
|
|
static int startDragDistance();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the QtCreator settings.
|
||
|
|
*/
|
||
|
|
void setSettings(QSettings *settings);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds dockwidget into the given area.
|
||
|
|
* If DockAreaWidget is not null, then the area parameter indicates the area
|
||
|
|
* into the DockAreaWidget. If DockAreaWidget is null, the Dockwidget will
|
||
|
|
* be dropped into the container. If you would like to add a dock widget
|
||
|
|
* tabified, then you need to add it to an existing dock area object
|
||
|
|
* into the CenterDockWidgetArea. The following code shows this:
|
||
|
|
* \code
|
||
|
|
* DockManager->addDockWidget(ads::CenterDockWidgetArea, NewDockWidget,
|
||
|
|
* ExisitingDockArea);
|
||
|
|
* \endcode
|
||
|
|
* \return Returns the dock area widget that contains the new DockWidget
|
||
|
|
*/
|
||
|
|
DockAreaWidget *addDockWidget(DockWidgetArea area,
|
||
|
|
DockWidget *dockWidget,
|
||
|
|
DockAreaWidget *dockAreaWidget = nullptr);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This function will add the given Dockwidget to the given dock area as
|
||
|
|
* a new tab.
|
||
|
|
* If no dock area widget exists for the given area identifier, a new
|
||
|
|
* dock area widget is created.
|
||
|
|
*/
|
||
|
|
DockAreaWidget *addDockWidgetTab(DockWidgetArea area, DockWidget *dockWidget);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This function will add the given Dockwidget to the given DockAreaWidget
|
||
|
|
* as a new tab.
|
||
|
|
*/
|
||
|
|
DockAreaWidget *addDockWidgetTabToArea(DockWidget *dockWidget, DockAreaWidget *dockAreaWidget);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds the given DockWidget floating and returns the created
|
||
|
|
* CFloatingDockContainer instance.
|
||
|
|
*/
|
||
|
|
FloatingDockContainer *addDockWidgetFloating(DockWidget *dockWidget);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Searches for a registered doc widget with the given ObjectName
|
||
|
|
* \return Return the found dock widget or nullptr if a dock widget with the
|
||
|
|
* given name is not registered
|
||
|
|
*/
|
||
|
|
DockWidget *findDockWidget(const QString &objectName) const;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove the given Dock from the dock manager
|
||
|
|
*/
|
||
|
|
void removeDockWidget(DockWidget *dockWidget);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This function returns a readable reference to the internal dock
|
||
|
|
* widgets map so that it is possible to iterate over all dock widgets
|
||
|
|
*/
|
||
|
|
QMap<QString, DockWidget *> dockWidgetsMap() const;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the list of all active and visible dock containers
|
||
|
|
* Dock containers are the main dock manager and all floating widgets
|
||
|
|
*/
|
||
|
|
const QList<DockContainerWidget *> dockContainers() const;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the list of all floating widgets
|
||
|
|
*/
|
||
|
|
const QList<FloatingDockContainer *> floatingWidgets() const;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This function always return 0 because the main window is always behind
|
||
|
|
* any floating widget
|
||
|
|
*/
|
||
|
|
virtual unsigned int zOrderIndex() const override;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Saves the current state of the dockmanger and all its dock widgets
|
||
|
|
* into the returned QByteArray.
|
||
|
|
* The XmlMode enables / disables the auto formatting for the XmlStreamWriter.
|
||
|
|
* If auto formatting is enabled, the output is intended and line wrapped.
|
||
|
|
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have
|
||
|
|
* a more compact XML output - i.e. for storage in ini files.
|
||
|
|
*/
|
||
|
|
QByteArray saveState(int version = Version1) const;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Restores the state of this dockmanagers dockwidgets.
|
||
|
|
* The version number is compared with that stored in state. If they do
|
||
|
|
* not match, the dockmanager's state is left unchanged, and this function
|
||
|
|
* returns false; otherwise, the state is restored, and this function
|
||
|
|
* returns true.
|
||
|
|
*/
|
||
|
|
bool restoreState(const QByteArray &state, int version = Version1);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This function returns true between the restoringState() and
|
||
|
|
* stateRestored() signals.
|
||
|
|
*/
|
||
|
|
bool isRestoringState() const;
|
||
|
|
|
||
|
|
signals:
|
||
|
|
/**
|
||
|
|
* This signal is emitted if the list of perspectives changed
|
||
|
|
*/
|
||
|
|
void workspaceListChanged();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This signal is emitted if perspectives have been removed
|
||
|
|
*/
|
||
|
|
void workspacesRemoved();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This signal is emitted, if the restore function is called, just before
|
||
|
|
* the dock manager starts restoring the state.
|
||
|
|
* If this function is called, nothing has changed yet
|
||
|
|
*/
|
||
|
|
void restoringState();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This signal is emitted if the state changed in restoreState.
|
||
|
|
* The signal is emitted if the restoreState() function is called or
|
||
|
|
* if the openWorkspace() function is called
|
||
|
|
*/
|
||
|
|
void stateRestored();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This signal is emitted, if the dock manager starts opening a
|
||
|
|
* perspective.
|
||
|
|
* Opening a perspective may take more than a second if there are
|
||
|
|
* many complex widgets. The application may use this signal
|
||
|
|
* to show some progress indicator or to change the mouse cursor
|
||
|
|
* into a busy cursor.
|
||
|
|
*/
|
||
|
|
void openingWorkspace(const QString &workspaceName);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This signal is emitted if the dock manager finished opening a
|
||
|
|
* perspective
|
||
|
|
*/
|
||
|
|
void workspaceOpened(const QString &workspaceName);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This signal is emitted, if a new floating widget has been created.
|
||
|
|
* An application can use this signal to e.g. subscribe to events of
|
||
|
|
* the newly created window.
|
||
|
|
*/
|
||
|
|
void floatingWidgetCreated(FloatingDockContainer *floatingWidget);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This signal is emitted, if a new DockArea has been created.
|
||
|
|
* An application can use this signal to set custom icons or custom
|
||
|
|
* tooltips for the DockArea buttons.
|
||
|
|
*/
|
||
|
|
void dockAreaCreated(DockAreaWidget *dockArea);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This signal is emitted just before the given dock widget is removed
|
||
|
|
* from the
|
||
|
|
*/
|
||
|
|
void dockWidgetAboutToBeRemoved(DockWidget *dockWidget);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This signal is emitted if a dock widget has been removed with the remove
|
||
|
|
* removeDockWidget() function.
|
||
|
|
* If this signal is emitted, the dock widget has been removed from the
|
||
|
|
* docking system but it is not deleted yet.
|
||
|
|
*/
|
||
|
|
void dockWidgetRemoved(DockWidget *dockWidget);
|
||
|
|
|
||
|
|
public:
|
||
|
|
void showWorkspaceMananger();
|
||
|
|
|
||
|
|
// higher level workspace management
|
||
|
|
QString activeWorkspace() const;
|
||
|
|
QString lastWorkspace() const;
|
||
|
|
bool autoRestorLastWorkspace() const;
|
||
|
|
QStringList workspaces();
|
||
|
|
QDateTime workspaceDateTime(const QString &workspace) const;
|
||
|
|
Utils::FilePath workspaceNameToFileName(const QString &workspaceName) const;
|
||
|
|
|
||
|
|
bool createWorkspace(const QString &workspace);
|
||
|
|
|
||
|
|
bool openWorkspace(const QString &workspace);
|
||
|
|
|
||
|
|
bool confirmWorkspaceDelete(const QStringList &workspaces);
|
||
|
|
bool deleteWorkspace(const QString &workspace);
|
||
|
|
void deleteWorkspaces(const QStringList &workspaces);
|
||
|
|
|
||
|
|
bool cloneWorkspace(const QString &original, const QString &clone);
|
||
|
|
bool renameWorkspace(const QString &original, const QString &newName);
|
||
|
|
|
||
|
|
bool save();
|
||
|
|
|
||
|
|
bool isFactoryDefaultWorkspace(const QString &workspace) const;
|
||
|
|
bool isDefaultWorkspace(const QString &workspace) const;
|
||
|
|
|
||
|
|
signals:
|
||
|
|
void aboutToUnloadWorkspace(QString workspaceName);
|
||
|
|
void aboutToLoadWorkspace(QString workspaceName);
|
||
|
|
void workspaceLoaded(QString workspaceName);
|
||
|
|
void aboutToSaveWorkspace();
|
||
|
|
|
||
|
|
private:
|
||
|
|
bool write(const QByteArray &data, QString *errorString) const;
|
||
|
|
#ifdef QT_GUI_LIB
|
||
|
|
bool write(const QByteArray &data, QWidget *parent) const;
|
||
|
|
#endif
|
||
|
|
}; // class DockManager
|
||
|
|
|
||
|
|
} // namespace ADS
|