Compare commits

..

43 Commits
3.6.3 ... 3.7.2

Author SHA1 Message Date
Uwe Kindler
487e23e190 Fixed MSVC build 2021-06-19 14:47:17 +02:00
Uwe Kindler
511132ee4f Fixxed issue #294 - Tab refresh problem with a QGLWidget 2021-06-17 20:32:45 +02:00
Uwe Kindler
edc89555bc Removed eclipse specific file 2021-06-17 20:32:12 +02:00
Rodrigo Oliva
ad30211dae Update icon label tooltip when the tab tooltip changes (#322)
Co-authored-by: Rodrigo Oliva <Rodrigo.Oliva@king.com>
2021-05-26 06:59:36 +02:00
Nick D'Ademo
48406da6ea fix building. (#323) 2021-05-25 18:12:24 +02:00
Rui Oliveira
aff0bd6e25 Add Qt6 support on CMake (#319) 2021-04-28 22:52:45 +02:00
jporcher
3969d28d92 Fix crash in dockindock (#317)
* Add dockdepth1 example

* Fix compilation (include assert.h)

* Replace dockdepth1 by dockindock

* Fix crash when dockindock example is closed. Due to code in dockindock supposed to fix memory leaks: now leaks were fixed in CDockManager (https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/307), the code from dockindock ends up deleting objects already deleted by parent.
2021-04-27 11:16:09 +02:00
Uwe Kindler
b39cd2d81b Fixed emptydockarea example 2021-04-27 07:47:03 +02:00
jporcher
0e8e563654 Add dockindock example (#308)
* Add dockdepth1 example

* Fix compilation (include assert.h)

* Replace dockdepth1 by dockindock
2021-04-21 06:37:19 +02:00
jporcher
2f041a0eed Fix memory leaks (#314) 2021-04-20 14:25:30 +02:00
Uwe Kindler
ffa0105d3e Fixed emission perspectiveListChanged signal after loading of perspective list and added perspectiveListLoaded signal 2021-04-13 07:05:17 +02:00
Uwe Kindler
6179832a2b Updated Qt DesignStudio showcase image and video link 2021-03-03 22:51:58 +01:00
Walter Bormans
13853573ea Additional Qt keyword conversion. (#299)
This comit is an addtion to pull request #295. Not all Qt keywords were included.

Co-authored-by: Walter Bormans <walter.bormans@paradoxcat.com>
2021-01-22 06:18:34 +01:00
Uwe Kindler
b6b4c626e8 Fixed user-guide.md emptydockarea code to match the real example 2021-01-16 15:06:32 +01:00
Uwe Kindler
bd41ec1627 Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2021-01-16 15:01:02 +01:00
Uwe Kindler
b54dab7df2 Fixed the empty dock area example to test procramatic docking with empty dock area 2021-01-16 15:00:44 +01:00
Walter Bormans
e66ef604a7 Removes reliance on special Qt keywords. (#295)
This allows Qt Advanced Docking system to be compiled with the QT_NO_KEYWORDS definition.
This can help avoid conflicts with other dependancies for a project.

Co-authored-by: Walter Bormans <walter.bormans@paradoxcat.com>
2021-01-15 09:08:27 +01:00
Uwe Kindler
e03674fd4b Fixed a typo in user-guide.md 2021-01-11 13:50:47 +01:00
Uwe Kindler
3f69fedd1f Added documentation for emptx dock area feature 2021-01-11 13:46:26 +01:00
Uwe Kindler
a614e3cc3d Fixed CDockAreaWidget::nextOpenDockWidget() function to properly return a DockWidget with tab if this is possible
Added new emptydockarea example
2021-01-11 11:07:03 +01:00
Uwe Kindler
ebde50b492 Fixed FloatingDockContainer Linux build for Qt6 2021-01-10 10:22:54 +01:00
Uwe Kindler
2a6bd306cb Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2021-01-09 19:03:14 +01:00
Uwe Kindler
8a27a5596b Added new CDockWidget flag CDockWidget::NoTab to hide the tab from the dock area title bar 2021-01-09 19:02:25 +01:00
Nicolas Elie
f835ffd978 Update Python bindings (#289)
* Update Python bindings

* Add X11Extras to setup.py for Linux builds

* Update Python Bindings

* Update Python bindings
2021-01-04 14:01:28 +01:00
Uwe Kindler
97215705f5 Improved documentation for Linux support 2021-01-03 18:16:38 +01:00
Uwe Kindler
6ee97e64d7 Disabled Qt6 build in appveyor - it does not work properly yet 2021-01-03 17:14:39 +01:00
Uwe Kindler
a1c4812619 Try to fix Qt6 build 2021-01-03 17:09:06 +01:00
Uwe Kindler
b0c8edbd82 Added Qt6 MinGW build to .appveyor.yml 2021-01-03 15:50:16 +01:00
Uwe Kindler
a4190ecbf0 Added missing ads.pri fle 2021-01-02 23:17:44 +01:00
Uwe Kindler
d8c6efaada Fixed signal connection of perspective combobox 2021-01-02 21:05:05 +01:00
Uwe Kindler
0312682e07 Fixed wrong pixmap is null test in ElidingLabel 2021-01-02 20:50:26 +01:00
Uwe Kindler
8d14068df7 Fixed QMouseEvent::globalPos() warning 2021-01-02 20:29:59 +01:00
Uwe Kindler
fe1d9a493f Fixed warning in centralwidget example because of missing svg file 2021-01-02 19:51:50 +01:00
Uwe Kindler
e55ad49db8 Created ads.pri to ease linking of ads library 2021-01-02 19:48:34 +01:00
Uwe Kindler
018ce2001e Fixed all Qt6 build issues 2021-01-02 18:06:45 +01:00
Uwe Kindler
c8fe4c46dd Fixed DockAreaWidget minimumSizeHint 2020-12-23 16:16:13 +01:00
Uwe Kindler
1781fa671d Updated build settings 2020-12-23 16:15:47 +01:00
Uwe Kindler
75910e910e Fixed centralwidget example to properly close all floating widgets on main window close 2020-11-26 08:07:31 +01:00
Uwe Kindler
899e06be1c Merge branch 'master' of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System 2020-11-23 12:57:23 +01:00
spking11
66687dc8b6 Add utf-8 support for msvc within cmake. (#280)
Co-authored-by: spking11 <spking11@foxmail.com>
2020-11-23 12:55:19 +01:00
Uwe Kindler
b8fe620276 Merge branch 'master' into adddockwidget_fix 2020-11-23 08:04:11 +01:00
spking11
1a50ea9892 Add utf-8 support for msvc to resolve building error in some windows systems. (#277) 2020-11-21 17:29:36 +01:00
Uwe Kindler
0a096869fe Fixed adding of dock widgets to floating widget 2020-11-21 15:08:30 +01:00
72 changed files with 2156 additions and 306 deletions

1
.gitignore vendored
View File

@@ -383,3 +383,4 @@ FodyWeavers.xsd
/ build
/Settings.ini
.vscode/settings.json
/.settings

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795" name="Default">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider-reference id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorMinGW" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" keep-relative-paths="false" name="CDT GCC Build Output Parser" parameter="(g?cc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
</extension>
</configuration>
</project>

View File

@@ -15,7 +15,13 @@ integrated development environments (IDEs) such as Visual Studio.
## New and Noteworthy
The [release 3.6.0](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/tag/3.6.0)
The [release 3.7](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/tag/3.7.0)
adds the following features:
- support for **Qt6.**
- support for [empty dock area](doc/user-guide.md#empty-dock-area)
The [release 3.6](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/tag/3.6.0)
adds some nice new features:
- support for [central widget](doc/user-guide.md#central-widget) concept
@@ -29,7 +35,7 @@ adds some nice new features:
Both features are contributions from ADS users. Read the [documentation](doc/user-guide.md)
to learn more about both new features.
The [release 3.5.0](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/tag/3.5.0)
The [release 3.5](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/tag/3.5.0)
adds the new [focus highlighting](doc/user-guide.md#focushighlighting) feature.
This optional feature enables highlighting of the focused dock widget like you
know it from Visual Studio.
@@ -56,6 +62,7 @@ know it from Visual Studio.
- [Supports deletion of dynamically created dock widgets](#supports-deletion-of-dynamically-created-dock-widgets)
- [Python PyQt5 Bindings](#python-pyqt5-bindings)
- [Tested Compatible Environments](#tested-compatible-environments)
- [Supported Qt Versions](#supported-qt-versions)
- [Windows](#windows)
- [macOS](#macos)
- [Linux](#linux)
@@ -81,8 +88,8 @@ There is no central widget like in the Qt docking system. You can dock on every
border of the main window or you can dock into each dock area - so you are
free to dock almost everywhere.
![Dropping widgets](doc/preview-dragndrop.png)\
\
![Dropping widgets](doc/preview-dragndrop.png)
![Dropping widgets](doc/preview-dragndrop_dark.png)
### Docking inside floating windows
@@ -90,8 +97,8 @@ free to dock almost everywhere.
There is no difference between the main window and a floating window. Docking
into floating windows is supported.
![Docking inside floating windows](doc/floating-widget-dragndrop.png)\
\
![Docking inside floating windows](doc/floating-widget-dragndrop.png)
![Docking inside floating windows](doc/floating-widget-dragndrop_dark.png)
### Grouped dragging
@@ -100,8 +107,8 @@ When dragging the titlebar of a dock, all the tabs that are tabbed with it are
going to be dragged. So you can move complete groups of tabbed widgets into
a floating widget or from one dock area to another one.
![Grouped dragging](doc/grouped-dragging.gif)\
\
![Grouped dragging](doc/grouped-dragging.gif)
![Grouped dragging](doc/grouped-dragging_dark.png)
### Perspectives for fast switching of the complete main window layout
@@ -112,13 +119,13 @@ perspective to make your own custom perspective. Later you can simply
select a perspective from the perspective list to quickly switch the complete
main window layout.
![Perspective](doc/perspectives.gif)\
\
![Perspective](doc/perspectives.gif)
![Perspective](doc/perspectives_dark.png)
### Opaque and non-opaque splitter resizing
The advanced docking system uses standard QSplitters as resize separators and thus supports opaque and non-opaque resizing functionality of QSplitter. In some rare cases, for very complex widgets or on slow machines resizing via separator on the fly may cause flicking and glaring of rendered content inside a widget. The global dock manager flag `OpaqueSplitterResize` configures the resizing behaviour of the splitters. If this flag is set, then widgets are resized dynamically (opaquely) while interactively moving the splitters.
The advanced docking system uses standard QSplitters as resize separators and thus supports opaque and non-opaque resizing functionality of QSplitter. In some rare cases, for very complex widgets or on slow machines resizing via separator on the fly may cause flicking and glaring of rendered content inside a widget. The global dock manager flag `OpaqueSplitterResize` configures the resizing behaviour of the splitters. If this flag is set, then widgets are resized dynamically (opaquely) while interactively moving the splitters.
![Opaque resizing](doc/opaque_resizing.gif)
@@ -171,6 +178,10 @@ Latest working version: [3.5.2](https://github.com/githubuser0xFFFF/Qt-Advanced-
## Tested Compatible Environments
### Supported Qt Versions
The library supports **Qt5** and **Qt6**.
### Windows
Windows 10 [![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master)
@@ -187,15 +198,23 @@ The application can be compiled for macOS. A user reported, that the library wor
### Linux
Ubuntu [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
[![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
[![Build status](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/workflows/linux-builds/badge.svg)](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/actions?query=workflow%3Alinux-builds)
The application can be compiled for Linux and has been developed and tested with **Kubuntu 18.04** and **Kubuntu 19.10**.
Unfortunately, there is no such thing as a Linux operating system. Linux is a heterogeneous environment with a variety of different distributions. So it is not possible to support "Linux" like this is possible for Windows. It is only possible to support and test a small subset of Linux distributions. The library can be compiled for and has been developed and tested with the following Linux distributions:
- **Kubuntu 18.04 and 19.10**
- **Ubuntu 18.04, 19.10 and 20.04**
There are some requirements for the Linux distribution that have to be met:
- an X server that supports ARGB visuals and a compositing window manager. This is required to display the translucent dock overlays ([https://doc.qt.io/qt-5/qwidget.html#creating-translucent-windows](https://doc.qt.io/qt-5/qwidget.html#creating-translucent-windows)). If your Linux distribution does not support this, or if you disable this feature, you will very likely see issue [#95](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/95).
- Wayland is not properly supported by Qt yet. If you use Wayland, then you should set the session type to x11: `XDG_SESSION_TYPE=x11 ./AdvancedDockingSystemDemo`. You will find more details about this in issue [#288](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/288).
Screenshot Kubuntu:
![Advanced Docking on Kubuntu Linux](doc/linux_kubuntu_1804.png)
and with **Ubuntu 19.10**
Screenshot Ubuntu:
![Advanced Docking on Ubuntu Linux](doc/linux_ubuntu_1910.png)
## Build
@@ -335,7 +354,7 @@ Taken from the [Qt Blog](https://www.qt.io/blog/qt-design-studio-1.5-beta-releas
> The most obvious change in [Qt Design Studio 1.5](https://www.qt.io/blog/qt-design-studio-1.5-beta-released) is the integration of dock widgets using the Qt Advanced Docking System. This allows the user to fully customize the workspace and also to undock any view into its own top level window. This especially improves the usability when using multiple screens.
![Qt Design Studio](doc/showcase_qt_design_studio.png)
[![Qt Design Studio](doc/showcase_qt_design_studio_video.png)](https://youtu.be/za9KBWcFXEw?t=84)
### [QmixElements](https://www.cetoni.com/products/qmixelements/)

21
ads.pri Normal file
View File

@@ -0,0 +1,21 @@
CONFIG(debug, debug|release){
win32 {
LIBS += -lqtadvanceddockingd
}
else:mac {
LIBS += -lqtadvanceddocking_debug
}
else {
LIBS += -lqtadvanceddocking
}
}
else{
LIBS += -lqtadvanceddocking
}
unix:!macx {
LIBS += -lxcb
QT += x11extras
}

View File

@@ -1,9 +1,10 @@
cmake_minimum_required(VERSION 3.5)
project(ads_demo VERSION ${VERSION_SHORT})
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
if(WIN32)
find_package(Qt5 5.5 COMPONENTS AxContainer REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
if(WIN32 AND QT_VERSION_MAJOR LESS 6)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS AxContainer REQUIRED)
endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(ads_demo_SRCS
@@ -16,9 +17,11 @@ set(ads_demo_SRCS
)
add_executable(AdvancedDockingSystemDemo WIN32 ${ads_demo_SRCS})
target_include_directories(AdvancedDockingSystemDemo PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src")
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
if(WIN32)
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt5::AxContainer)
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
if(WIN32 AND QT_VERSION_MAJOR LESS 6)
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::AxContainer)
endif()
target_link_libraries(AdvancedDockingSystemDemo PRIVATE qtadvanceddocking)
set_target_properties(AdvancedDockingSystemDemo PROPERTIES

View File

@@ -58,11 +58,15 @@
#include <QMessageBox>
#include <QMenu>
#include <QToolButton>
#include <QToolBar>
#include <QPointer>
#ifdef Q_OS_WIN
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QAxWidget>
#endif
#endif
#include <QMap>
#include <QElapsedTimer>
@@ -166,7 +170,8 @@ struct MainWindowPrivate
QComboBox* PerspectiveComboBox = nullptr;
ads::CDockManager* DockManager = nullptr;
ads::CDockWidget* WindowTitleTestDockWidget = nullptr;
ads::CDockWidget* LastDockedEditor = nullptr;
QPointer<ads::CDockWidget> LastDockedEditor;
QPointer<ads::CDockWidget> LastCreatedFloatingEditor;
MainWindowPrivate(CMainWindow* _public) : _this(_public) {}
@@ -353,6 +358,7 @@ struct MainWindowPrivate
#ifdef Q_OS_WIN
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
/**
* Creates an ActiveX widget on windows
*/
@@ -366,6 +372,7 @@ struct MainWindowPrivate
return DockWidget;
}
#endif
#endif
};
@@ -444,10 +451,12 @@ void MainWindowPrivate::createContent()
DockWidget->connect(Action, SIGNAL(triggered()), SLOT(raise()));
#ifdef Q_OS_WIN
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
if (!ads::CDockManager::testConfigFlag(ads::CDockManager::OpaqueUndocking))
{
DockManager->addDockWidget(ads::CenterDockWidgetArea, createActiveXWidget(), RighDockArea);
}
#endif
#endif
for (auto DockWidget : DockManager->dockWidgetsMap())
@@ -608,8 +617,13 @@ CMainWindow::CMainWindow(QWidget *parent) :
// Now create the dock manager and its content
d->DockManager = new CDockManager(this);
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
connect(d->PerspectiveComboBox, SIGNAL(activated(const QString&)),
d->DockManager, SLOT(openPerspective(const QString&)));
#else
connect(d->PerspectiveComboBox, SIGNAL(textActivated(const QString&)),
d->DockManager, SLOT(openPerspective(const QString&)));
#endif
d->createContent();
// Default window geometry - center on screen
@@ -719,18 +733,30 @@ void CMainWindow::createEditor()
{
auto FloatingWidget = d->DockManager->addDockWidgetFloating(DockWidget);
FloatingWidget->move(QPoint(20, 20));
d->LastCreatedFloatingEditor = DockWidget;
d->LastDockedEditor.clear();
}
else
{
ads::CDockAreaWidget* EditorArea = d->LastDockedEditor ? d->LastDockedEditor->dockAreaWidget() : nullptr;
if (EditorArea)
{
std::cout << "DockAreaCount before: " << EditorArea->dockContainer()->dockAreaCount() << std::endl;
d->DockManager->setConfigFlag(ads::CDockManager::EqualSplitOnInsertion, true);
d->DockManager->addDockWidget(ads::RightDockWidgetArea, DockWidget, EditorArea);
std::cout << "DockAreaCount after: " << DockWidget->dockContainer()->dockAreaCount() << std::endl;
}
else
{
d->DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget);
if (d->LastCreatedFloatingEditor)
{
std::cout << "LastCreated" << std::endl;
d->DockManager->addDockWidget(ads::RightDockWidgetArea, DockWidget, d->LastCreatedFloatingEditor->dockAreaWidget());
}
else
{
d->DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget);
}
}
d->LastDockedEditor = DockWidget;
}

View File

@@ -4,8 +4,12 @@ TARGET = AdvancedDockingSystemDemo
DESTDIR = $${ADS_OUT_ROOT}/lib
QT += core gui widgets
win32 {
QT += axcontainer
include(../ads.pri)
lessThan(QT_MAJOR_VERSION, 6) {
win32 {
QT += axcontainer
}
}
CONFIG += c++14
@@ -35,26 +39,5 @@ RESOURCES += demo.qrc
LIBS += -L$${ADS_OUT_ROOT}/lib
# Dependency: AdvancedDockingSystem (shared)
CONFIG(debug, debug|release){
win32 {
LIBS += -lqtadvanceddockingd
}
else:mac {
LIBS += -lqtadvanceddocking_debug
}
else {
LIBS += -lqtadvanceddocking
}
}
else{
LIBS += -lqtadvanceddocking
}
unix:!macx {
LIBS += -lxcb
QT += x11extras
}
INCLUDEPATH += ../src
DEPENDPATH += ../src

View File

@@ -359,6 +359,7 @@ class MainWindow(MainWindowUI, MainWindowBase):
floating = sender.property("Floating")
dock_widget = self.create_editor_widget()
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetDeleteOnClose, True)
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetForceCloseWithArea, True)
dock_widget.closeRequested.connect(self.on_editor_close_requested)
if floating:

View File

@@ -35,9 +35,11 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
int main(int argc, char *argv[])
{
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#if QT_VERSION >= 0x050600
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
#endif
std::shared_ptr<int> b;
QApplication a(argc, argv);

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 KiB

View File

@@ -28,6 +28,7 @@
- [`FloatingContainerForceNativeTitleBar` (Linux only)](#floatingcontainerforcenativetitlebar-linux-only)
- [`FloatingContainerForceQWidgetTitleBar` (Linux only)](#floatingcontainerforceqwidgettitlebar-linux-only)
- [Central Widget](#central-widget)
- [Empty Dock Area](#empty-dock-area)
- [Custom Close Handling](#custom-close-handling)
- [Styling](#styling)
- [Disabling the Internal Style Sheet](#disabling-the-internal-style-sheet)
@@ -500,6 +501,33 @@ See the `centralwidget` example to learn how it works.
> are already other dock widgets registered. So `setCentralWidget` should be
> the first function that you call when adding dock widgets.
## Empty Dock Area
Some applications require a fixed DockArea that is always visible, even if it
does not contain any DockWidgets. I.e. the DockArea is in this case a kind
of central widget that is always visible (see this
[issue](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/199)).
Since version 3.7.1 the advanced docking system supports this feature. The
`emptydockarea` example shows how this can be implemented with the library. You
just need to create a dock widget and set the feature flag `CDockWidget::NoTab`.
This permanently hides the tab widget of this area and removes it from the tab
menu. For this special dock widget you should also disable all other features
(movable, closable and floatable) to prevent closing and moving of this widget.
If you use the `CDockManager::setCentralWidget` function like in the example
code below, then you don't need to disable these features because this is done
in the `setCentralWidget` function.
```c++
QLabel* label = new QLabel();
label->setText("This is a DockArea which is always visible, even if it does not contain any DockWidgets.");
label->setAlignment(Qt::AlignCenter);
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget");
CentralDockWidget->setWidget(label);
CentralDockWidget->setFeature(ads::CDockWidget::NoTab, true);// set the flag before adding the widget to dock manager
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
```
## Custom Close Handling
Normally clicking the close button of a dock widget will just hide the widget and the user can show it again using the `toggleView()` action of the dock widget. This is meant for user interfaces with a static amount of widgets. But the advanced docking system also supports dynamic dock widgets that will get deleted on close. If you set the dock widget flag `DockWidgetDeleteOnClose` for a certain dock widget, then it will be deleted as soon as you close this dock widget. This enables the implementation of user interfaces with dynamically created editors, like in word processing applications or source code development tools.

View File

@@ -3,4 +3,6 @@ project(QtADSExamples LANGUAGES CXX VERSION ${VERSION_SHORT})
add_subdirectory(simple)
add_subdirectory(sidebar)
add_subdirectory(deleteonclose)
add_subdirectory(centralwidget)
add_subdirectory(centralwidget)
add_subdirectory(emptydockarea)
add_subdirectory(dockindock)

View File

@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_centralwidget VERSION ${VERSION_SHORT})
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(CentralWidgetExample WIN32
main.cpp
@@ -9,7 +10,9 @@ add_executable(CentralWidgetExample WIN32
)
target_include_directories(CentralWidgetExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(CentralWidgetExample PRIVATE qtadvanceddocking)
target_link_libraries(CentralWidgetExample PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
target_link_libraries(CentralWidgetExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(CentralWidgetExample PROPERTIES
AUTOMOC ON
AUTORCC ON

View File

@@ -106,6 +106,11 @@ class MainWindow(MainWindowUI, MainWindowBase):
self.perspective_combobox.clear()
self.perspective_combobox.addItems(self.dock_manager.perspectiveNames())
self.perspective_combobox.setCurrentText(perspective_name)
def closeEvent(self, event: QCloseEvent):
self.dock_manager.deleteLater()
super().closeEvent(event)
if __name__ == '__main__':
app = QApplication(sys.argv)

View File

@@ -28,28 +28,7 @@ FORMS += \
mainwindow.ui
LIBS += -L$${ADS_OUT_ROOT}/lib
# Dependency: AdvancedDockingSystem (shared)
CONFIG(debug, debug|release){
win32 {
LIBS += -lqtadvanceddockingd
}
else:mac {
LIBS += -lqtadvanceddocking_debug
}
else {
LIBS += -lqtadvanceddocking
}
}
else{
LIBS += -lqtadvanceddocking
}
unix:!macx {
LIBS += -lxcb
QT += x11extras
}
include(../../ads.pri)
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@@ -26,17 +26,6 @@
using namespace ads;
/**
* Helper function to create an SVG icon
*/
static QIcon svgIcon(const QString& File)
{
// This is a workaround, because in item views SVG icons are not
// properly scaled and look blurry or pixelate
QIcon SvgIcon(File);
SvgIcon.addPixmap(SvgIcon.pixmap(92));
return SvgIcon;
}
CMainWindow::CMainWindow(QWidget *parent)
: QMainWindow(parent)
@@ -57,27 +46,26 @@ CMainWindow::CMainWindow(QWidget *parent)
CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
// create other dock widgets
QTreeView* fileTree = new QTreeView();
fileTree->setFrameShape(QFrame::NoFrame);
QFileSystemModel* fileModel = new QFileSystemModel(fileTree);
fileModel->setRootPath(QDir::currentPath());
fileTree->setModel(fileModel);
CDockWidget* DataDockWidget = new CDockWidget("File system");
DataDockWidget->setWidget(fileTree);
DataDockWidget->resize(150, 250);
DataDockWidget->setMinimumSize(100, 250);
auto* fileArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, DataDockWidget, CentralDockArea);
ui->menuView->addAction(DataDockWidget->toggleViewAction());
QTableWidget* table = new QTableWidget();
table->setColumnCount(3);
table->setRowCount(10);
CDockWidget* TableDockWidget = new CDockWidget("Table");
CDockWidget* TableDockWidget = new CDockWidget("Table 1");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
TableDockWidget->setMinimumSize(200,150);
DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, TableDockWidget, fileArea);
auto TableArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, TableDockWidget);
ui->menuView->addAction(TableDockWidget->toggleViewAction());
table = new QTableWidget();
table->setColumnCount(5);
table->setRowCount(1020);
TableDockWidget = new CDockWidget("Table 2");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
TableDockWidget->setMinimumSize(200,150);
DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, TableDockWidget, TableArea);
ui->menuView->addAction(TableDockWidget->toggleViewAction());
QTableWidget* propertiesTable = new QTableWidget();
@@ -103,7 +91,6 @@ CMainWindow::~CMainWindow()
void CMainWindow::createPerspectiveUi()
{
SavePerspectiveAction = new QAction("Create Perspective", this);
SavePerspectiveAction->setIcon(svgIcon(":/adsdemo/images/picture_in_picture.svg"));
connect(SavePerspectiveAction, SIGNAL(triggered()), SLOT(savePerspective()));
PerspectiveListAction = new QWidgetAction(this);
PerspectiveComboBox = new QComboBox(this);
@@ -133,3 +120,14 @@ void CMainWindow::savePerspective()
PerspectiveComboBox->setCurrentText(PerspectiveName);
}
//============================================================================
void CMainWindow::closeEvent(QCloseEvent* event)
{
// Delete dock manager here to delete all floating widgets. This ensures
// that all top level windows of the dock manager are properly closed
DockManager->deleteLater();
QMainWindow::closeEvent(event);
}

View File

@@ -21,6 +21,9 @@ public:
CMainWindow(QWidget *parent = nullptr);
~CMainWindow();
protected:
virtual void closeEvent(QCloseEvent* event) override;
private:
QAction* SavePerspectiveAction = nullptr;
QWidgetAction* PerspectiveListAction = nullptr;

View File

@@ -1,13 +1,16 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_deleteonclose VERSION ${VERSION_SHORT})
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(DeleteOnCloseTest WIN32
main.cpp
)
target_include_directories(DeleteOnCloseTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(DeleteOnCloseTest PRIVATE qtadvanceddocking)
target_link_libraries(DeleteOnCloseTest PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
target_link_libraries(DeleteOnCloseTest PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(DeleteOnCloseTest PROPERTIES
AUTOMOC ON
CXX_STANDARD 14

View File

@@ -17,28 +17,7 @@ SOURCES += main.cpp
LIBS += -L$${ADS_OUT_ROOT}/lib
# Dependency: AdvancedDockingSystem (shared)
CONFIG(debug, debug|release){
win32 {
LIBS += -lqtadvanceddockingd
}
else:mac {
LIBS += -lqtadvanceddocking_debug
}
else {
LIBS += -lqtadvanceddocking
}
}
else{
LIBS += -lqtadvanceddocking
}
unix:!macx {
LIBS += -lxcb
QT += x11extras
}
include(../../ads.pri)
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_dockindock VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(DockInDockExample WIN32
dockindock.cpp
dockindockmanager.cpp
perspectiveactions.cpp
perspectives.cpp
main.cpp
mainframe.cpp
)
target_include_directories(DockInDockExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(DockInDockExample PRIVATE qtadvanceddocking)
target_link_libraries(DockInDockExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(DockInDockExample PROPERTIES
AUTOMOC ON
AUTORCC ON
AUTOUIC ON
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT}
EXPORT_NAME "Qt Advanced Docking System Simple Example"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
)

View File

@@ -0,0 +1,296 @@
#include "dockindock.h"
#include "perspectives.h"
#include "dockindockmanager.h"
#include "perspectiveactions.h"
#include <QMenu>
#include <QDir>
#include <QVBoxLayout>
#include <QMainWindow>
#include <QMessageBox>
#include <QInputDialog>
#include <set>
#include <assert.h>
using namespace QtAdsUtl;
DockInDockWidget::DockInDockWidget( QWidget* parent, bool canCreateNewGroups, PerspectivesManager* perspectivesManager ) :
DockInDockWidget( parent, (DockInDockWidget*)NULL, perspectivesManager )
{
m_canCreateNewGroups = canCreateNewGroups;
m_topLevelDockWidget = this;
}
DockInDockWidget::DockInDockWidget( QWidget* parent, DockInDockWidget* topLevelDockWidget, PerspectivesManager* perspectivesManager ) :
baseClass( parent ),
m_topLevelDockWidget( topLevelDockWidget ),
m_canCreateNewGroups( (topLevelDockWidget) ? topLevelDockWidget->m_canCreateNewGroups : false ),
m_perspectivesManager( perspectivesManager )
{
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins( 0,0,0,0 );
layout->addWidget( m_mgr = new DockInDockManager(*this) );
}
DockInDockWidget::~DockInDockWidget()
{
}
ads::CDockAreaWidget* DockInDockWidget::addTabWidget( QWidget* widget, const QString& name, ads::CDockAreaWidget* after )
{
return addTabWidget( widget, name, QIcon(), after );
}
ads::CDockAreaWidget* DockInDockWidget::addTabWidget( QWidget* widget, const QString& name, QIcon icon, ads::CDockAreaWidget* after )
{
for ( auto existing : getTopLevelDockWidget()->getManager()->allDockWidgets(true,true) )
{
if ( existing.second->objectName() == name )
{
QMessageBox::critical( this, "Error", "Name '" + name + "' already in use" );
return NULL;
}
}
ads::CDockWidget* DockWidget = new ads::CDockWidget(name);
DockWidget->setWidget(widget);
DockWidget->setIcon( icon );
// Add the dock widget to the top dock widget area
return m_mgr->addDockWidget(ads::CenterDockWidgetArea, DockWidget, after);
}
bool DockInDockWidget::isTopLevel()
{
return objectName().isEmpty();
}
QString DockInDockWidget::getGroupNameError( const QString& groupName )
{
if ( groupName.isEmpty() )
{
return "Group must have a non-empty name";
}
std::vector<DockInDockManager*> dockManagers = m_mgr->allManagers( true, true );
for ( auto mgr : dockManagers )
{
if ( mgr->getGroupName() == groupName )
return "Group name '" + groupName + "' already used";
}
return "";
}
DockInDockWidget* DockInDockWidget::createGroup( const QString& groupName, ads::CDockAreaWidget*& insertPos )
{
return createGroup( groupName, QIcon(), insertPos );
}
DockInDockWidget* DockInDockWidget::createGroup( const QString& groupName, QIcon icon, ads::CDockAreaWidget*& insertPos )
{
QString error = getGroupNameError( groupName );
if ( !error.isEmpty() )
{
QMessageBox::critical( NULL, "Error", error );
return NULL;
}
DockInDockWidget* child = new DockInDockWidget( this, m_topLevelDockWidget, m_perspectivesManager );
child->setObjectName( groupName );
ads::CDockWidget* DockWidget = new ads::CDockWidget(groupName);
DockWidget->setWidget(child);
DockWidget->setIcon(icon);
insertPos = m_mgr->addDockWidget(ads::CenterDockWidgetArea, DockWidget, insertPos);
return child;
}
void DockInDockWidget::destroyGroup( DockInDockWidget* widgetToRemove )
{
auto topLevelWidget = widgetToRemove->getTopLevelDockWidget();
if ( topLevelWidget && topLevelWidget != widgetToRemove )
{
// reaffect all child docks to top-level
for ( auto dockwidget : widgetToRemove->getManager()->getWidgetsInGUIOrder() ) // don't use allDockWidgets to preserve sub-groups
{
MoveDockWidgetAction::move( dockwidget, topLevelWidget->getManager() );
}
assert( widgetToRemove->getManager()->allDockWidgets( true, true ).empty() );
// find widget's parent:
for ( auto dockwidget : topLevelWidget->getManager()->allDockWidgets( true, true ) )
{
if ( dockwidget.second->widget() == widgetToRemove )
{
dockwidget.first->removeDockWidget( dockwidget.second );
delete dockwidget.second;
//delete widgetToRemove; automatically deleted when dockWidget is deleted
widgetToRemove = NULL;
break;
}
}
assert( widgetToRemove == NULL );
}
else
{
assert( false );
}
}
void DockInDockWidget::attachViewMenu( QMenu* menu )
{
connect( menu, SIGNAL(aboutToShow()), this, SLOT(autoFillAttachedViewMenu()) );
}
void DockInDockWidget::autoFillAttachedViewMenu()
{
QMenu* menu = dynamic_cast<QMenu*>( QObject::sender() );
if ( menu )
{
menu->clear();
setupViewMenu( menu );
}
else
{
assert( false );
}
}
void DockInDockWidget::setupViewMenu( QMenu* menu )
{
std::vector<DockInDockManager*> dockManagers = m_mgr->allManagers( true, true );
bool hasPerspectivesMenu = false;
if ( getTopLevelDockWidget() == this )
hasPerspectivesMenu = (m_perspectivesManager != NULL);
else
assert( false );
QMenu* organize = menu;
if ( hasPerspectivesMenu )
organize = menu->addMenu( "Organize" );
setupMenu( organize, dockManagers );
if ( hasPerspectivesMenu )
{
QMenu* perspectives = menu->addMenu( "Perspectives" );
fillPerspectivesMenu( perspectives );
}
}
void DockInDockWidget::setupMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo )
{
m_mgr->fillViewMenu( menu, moveTo );
menu->addSeparator();
auto moveMenu = menu->addMenu( "Move" );
m_mgr->fillMoveMenu( moveMenu, moveTo );
}
void DockInDockWidget::fillPerspectivesMenu( QMenu* menu )
{
menu->addAction( "Create perspective...", this, SLOT(createPerspective()) );
QStringList perspectiveNames;
if ( m_perspectivesManager )
perspectiveNames = m_perspectivesManager->perspectiveNames();
if ( !perspectiveNames.isEmpty() )
{
QMenu* load = menu->addMenu( "Load perspective" );
for ( auto name : perspectiveNames )
load->addAction( new LoadPerspectiveAction( load, name, *this ) );
QMenu* remove = menu->addMenu( "Remove perspective" );
for ( auto name : perspectiveNames )
remove->addAction( new RemovePerspectiveAction( remove, name, *this ) );
}
}
void DockInDockWidget::setNewPerspectiveDefaultName( const QString& defaultName )
{
m_newPerspectiveDefaultName = defaultName;
}
void DockInDockWidget::createPerspective()
{
if ( !m_perspectivesManager )
return;
QString name = m_newPerspectiveDefaultName;
if ( !m_newPerspectiveDefaultName.isEmpty() )
{
int index = 2;
while ( m_perspectivesManager->perspectiveNames().contains( name ) )
{
name = m_newPerspectiveDefaultName + " (" + QString::number(index) + ")";
++index;
}
}
while ( true )
{
bool ok = false;
name = QInputDialog::getText( NULL, "Create perspective", "Enter perspective name", QLineEdit::Normal, name, &ok );
if ( ok )
{
if ( name.isEmpty() )
{
QMessageBox::critical( NULL, "Error", "Perspective name cannot be empty" );
continue;
}
else if ( m_perspectivesManager->perspectiveNames().contains( name ) )
{
if ( QMessageBox::critical( NULL, "Error", "Perspective '" + name + "' already exists, overwrite it?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::No )
continue;
}
m_perspectivesManager->addPerspective( name, *this );
break;
}
else
{
break;
}
}
}
static void dumpStatus( std::ostream& str, ads::CDockWidget* widget, const std::string& tab, std::string suffix )
{
DockInDockManager* asMgr = DockInDockManager::dockInAManager( widget );
if ( asMgr )
{
asMgr->parent().dumpStatus( str, tab );
}
else
{
str << tab << widget->objectName().toStdString() << suffix << std::endl;
}
}
void DockInDockWidget::dumpStatus( std::ostream& str, std::string tab )
{
str << tab << "Group: " << getManager()->getGroupName().toStdString() << std::endl;
tab += " ";
std::set<ads::CDockWidget*> visibleWidgets;
for ( auto widget : getManager()->getWidgetsInGUIOrder() )
{
visibleWidgets.insert( widget );
::dumpStatus( str, widget, tab, "" );
}
for ( auto closed : getManager()->dockWidgetsMap() )
{
if ( visibleWidgets.find( closed ) == visibleWidgets.end() )
{
::dumpStatus( str, closed, tab, " (closed)" );
}
}
}

View File

@@ -0,0 +1,80 @@
#pragma once
#include <QWidget>
#include <QMap>
#include <memory>
#include <ostream>
class QMenu;
namespace ads
{
class CDockAreaWidget;
}
namespace QtAdsUtl
{
class DockInDockManager;
class PerspectivesManager;
// tab of tab example for https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/306
class DockInDockWidget : public QWidget
{
typedef QWidget baseClass;
Q_OBJECT
public:
DockInDockWidget( QWidget* parent, bool canCreateNewGroups, PerspectivesManager* perspectivesManager );
~DockInDockWidget() override;
ads::CDockAreaWidget* addTabWidget( QWidget* widget, const QString& name, ads::CDockAreaWidget* after );
DockInDockWidget* createGroup( const QString& groupName, ads::CDockAreaWidget*& insertPos );
ads::CDockAreaWidget* addTabWidget( QWidget* widget, const QString& name, QIcon icon, ads::CDockAreaWidget* after );
DockInDockWidget* createGroup( const QString& groupName, QIcon icon, ads::CDockAreaWidget*& insertPos );
QString getGroupNameError( const QString& groupName );
void destroyGroup( DockInDockWidget* widget );
/** Manually fill a given view menu */
void setupViewMenu( QMenu* menu );
/** Attach a view menu that will be automatically fill */
void attachViewMenu( QMenu* menu );
bool isTopLevel();
void setupMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo );
inline DockInDockManager* getManager() { return m_mgr; }
inline DockInDockWidget* getTopLevelDockWidget() { return m_topLevelDockWidget; }
inline bool canCreateNewGroups() const { return m_canCreateNewGroups; }
void dumpStatus( std::ostream& str, std::string tab = "" );
inline PerspectivesManager* getPerspectivesManager() { return m_perspectivesManager; }
void setNewPerspectiveDefaultName( const QString& defaultName );
private slots:
void autoFillAttachedViewMenu();
void createPerspective();
private:
DockInDockManager* m_mgr;
DockInDockWidget* m_topLevelDockWidget;
bool m_canCreateNewGroups;
DockInDockWidget( QWidget* parent, DockInDockWidget* topLevelDockWidget, PerspectivesManager* perspectivesManager );
PerspectivesManager* m_perspectivesManager;
QString m_newPerspectiveDefaultName;
void fillPerspectivesMenu( QMenu* menu );
};
}

View File

@@ -0,0 +1,35 @@
ADS_OUT_ROOT = $${OUT_PWD}/../..
QT += core gui widgets
TARGET = DockInDock
DESTDIR = $${ADS_OUT_ROOT}/lib
TEMPLATE = app
CONFIG += c++14
CONFIG += debug_and_release
adsBuildStatic {
DEFINES += ADS_STATIC
}
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
dockindock.cpp \
dockindockmanager.cpp \
perspectiveactions.cpp \
perspectives.cpp \
main.cpp \
mainframe.cpp
HEADERS += \
dockindock.h \
dockindockmanager.h \
perspectiveactions.h \
perspectives.h \
mainframe.h
LIBS += -L$${ADS_OUT_ROOT}/lib
include(../../ads.pri)
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@@ -0,0 +1,334 @@
#include "dockindockmanager.h"
#include "dockindock.h"
#include "DockAreaWidget.h"
#include <QMenu>
#include <QInputDialog>
#include <QSettings>
#include <QMessageBox>
#include <assert.h>
using namespace QtAdsUtl;
/////////////////////////////////////
// DockInDockManager
/////////////////////////////////////
DockInDockManager::DockInDockManager( DockInDockWidget& parent ) :
baseClass( &parent ),
m_parent( parent )
{
}
DockInDockManager::~DockInDockManager()
{
}
void DockInDockManager::fillViewMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo )
{
auto widgetsMap = dockWidgetsMap();
for ( auto iter = widgetsMap.begin(); iter != widgetsMap.end(); ++iter )
{
auto widget = iter.value()->widget();
auto action = iter.value()->toggleViewAction();
DockInDockWidget* asMgr = dynamic_cast<DockInDockWidget*>( widget );
if ( asMgr )
{
auto subMenu = menu->addMenu( iter.key() );
subMenu->addAction( action );
subMenu->addSeparator();
asMgr->setupMenu( subMenu, moveTo );
}
else
{
menu->addAction(action);
}
}
if ( parent().canCreateNewGroups() )
{
// see how this works, to create it in the right place,
// and also to have load perspective work when some groups are missing
menu->addSeparator();
menu->addAction( new QtAdsUtl::CreateChildDockAction( m_parent, menu ) );
if ( parent().getTopLevelDockWidget()->getManager() != this )
menu->addAction( new QtAdsUtl::DestroyGroupAction( &m_parent, menu ) );
}
}
void DockInDockManager::fillMoveMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo )
{
auto widgetsMap = dockWidgetsMap();
for ( auto iter = widgetsMap.begin(); iter != widgetsMap.end(); ++iter )
{
auto subMenu = menu->addMenu( iter.key() );
for ( auto mgr : moveTo )
{
// iterate over all possible target managers
if ( mgr == this )
{
// if dock is already in mgr, no reason to move it there
}
else if ( mgr == dockInAManager( iter.value() ) )
{
// if target is the group itself, can't move it there, would make no sense
}
else
{
subMenu->addAction( new MoveDockWidgetAction( iter.value(), mgr, subMenu ) );
}
}
}
}
void DockInDockManager::addPerspectiveRec( const QString& name )
{
std::vector<DockInDockManager*> managers = allManagers( true, true );
for ( auto child : managers )
child->addPerspective( name );
}
void DockInDockManager::openPerspectiveRec( const QString& name )
{
std::vector<DockInDockManager*> managers = allManagers( true, true );
for ( auto child : managers )
child->openPerspective( name );
}
QString DockInDockManager::getGroupName()
{
return parent().objectName();
}
#define CHILD_PREFIX QString("Child-")
QString DockInDockManager::getPersistGroupName()
{
QString group = "Top";
if ( !getGroupName().isEmpty() )
group = CHILD_PREFIX + getGroupName();
return group;
}
QString DockInDockManager::getGroupNameFromPersistGroupName( QString persistGroupName )
{
if ( persistGroupName.startsWith( CHILD_PREFIX ) )
{
persistGroupName = persistGroupName.mid( CHILD_PREFIX.size() );
}
else
{
assert( false );
}
return persistGroupName;
}
void DockInDockManager::loadPerspectivesRec(QSettings& Settings)
{
std::vector<DockInDockManager*> children = allManagers( true, true );
for ( auto mgr : children )
{
Settings.beginGroup(mgr->getPersistGroupName());
mgr->loadPerspectives( Settings );
Settings.endGroup();
}
}
void DockInDockManager::savePerspectivesRec(QSettings& Settings) const
{
std::vector<DockInDockManager*> children = allManagers( true, true );
for ( auto mgr : children )
{
Settings.beginGroup(mgr->getPersistGroupName());
mgr->savePerspectives( Settings );
Settings.endGroup();
}
}
void DockInDockManager::removePerspectivesRec()
{
std::vector<DockInDockManager*> managers = allManagers( true, true );
for ( auto child : managers )
child->removePerspectives( child->perspectiveNames() );
}
DockInDockManager* DockInDockManager::dockInAManager( ads::CDockWidget* widget )
{
DockInDockWidget* dockWidget = widget ? dynamic_cast<DockInDockWidget*>( widget->widget() ) : NULL;
return ( dockWidget ) ? dockWidget->getManager() : NULL;
}
void DockInDockManager::childManagers( std::vector<DockInDockManager*>& managers, bool rec ) const
{
auto widgets = getWidgetsInGUIOrder();
for ( auto widget : widgets )
{
DockInDockManager* asMgr = dockInAManager( widget );
if ( asMgr )
{
managers.push_back( asMgr );
if ( rec )
asMgr->childManagers( managers, rec );
}
}
}
std::vector<DockInDockManager*> DockInDockManager::allManagers( bool includeThis, bool rec ) const
{
std::vector<DockInDockManager*> managers;
if ( includeThis )
managers.push_back( const_cast<DockInDockManager*>(this) );
childManagers( managers, rec );
return managers;
}
std::vector<std::pair<DockInDockManager*,ads::CDockWidget*>> DockInDockManager::allDockWidgets( bool includeThis, bool rec ) const
{
std::vector<std::pair<DockInDockManager*,ads::CDockWidget*>> widgets;
for ( auto mgr : allManagers( includeThis, rec ) )
{
for ( auto widget : mgr->getWidgetsInGUIOrder() )
widgets.push_back( std::make_pair(mgr, widget) );
}
return widgets;
}
QMap<QString,QStringList> DockInDockManager::getGroupContents()
{
QMap<QString,QStringList> result;
std::vector<DockInDockManager*> managers = allManagers( true, true );
for ( auto mgr : managers )
{
result[mgr->getPersistGroupName()] = mgr->dockWidgetsMap().keys();
}
return result;
}
ads::CDockAreaWidget* DockInDockManager::getInsertDefaultPos()
{
ads::CDockAreaWidget* defaultPos = NULL;
if ( dockAreaCount() != 0 )
defaultPos = dockArea(dockAreaCount()-1);
return defaultPos;
}
std::vector<ads::CDockWidget*> DockInDockManager::getWidgetsInGUIOrder() const
{
std::vector<ads::CDockWidget*> result;
result.reserve( dockWidgetsMap().size() );
for ( int i = 0; i != dockAreaCount(); ++i )
{
for ( auto widget : dockArea(i)->dockWidgets() )
result.push_back( widget );
}
return result;
}
/////////////////////////////////////
// CreateChildDockAction
/////////////////////////////////////
CreateChildDockAction::CreateChildDockAction( DockInDockWidget& dockInDock, QMenu* menu ) :
QAction("New group...", menu),
m_dockInDock( dockInDock )
{
connect( this, SIGNAL(triggered()), this, SLOT(createGroup()) );
}
void CreateChildDockAction::createGroup()
{
QString name = "";
while ( true )
{
bool ok = false;
name = QInputDialog::getText( NULL, this->text(), "Enter group name", QLineEdit::Normal, name, &ok );
if ( ok )
{
QString error = "";
if ( m_dockInDock.getTopLevelDockWidget() )
error = m_dockInDock.getTopLevelDockWidget()->getGroupNameError( name );
else
assert( false );
if ( error.isEmpty() )
{
ads::CDockAreaWidget* insertPos = NULL;
m_dockInDock.createGroup( name, insertPos );
break;
}
else
{
QMessageBox::critical( NULL, "Error", error );
continue;
}
}
else
{
break;
}
}
}
/////////////////////////////////////
// DestroyGroupAction
/////////////////////////////////////
DestroyGroupAction::DestroyGroupAction( DockInDockWidget* widget, QMenu* menu ) :
QAction("Destroy " + widget->getManager()->getGroupName(), menu),
m_widget( widget )
{
connect( this, SIGNAL(triggered()), this, SLOT(destroyGroup()) );
}
void DestroyGroupAction::destroyGroup()
{
m_widget->getTopLevelDockWidget()->destroyGroup( m_widget );
}
/////////////////////////////////////
// MoveDockWidgetAction
/////////////////////////////////////
MoveDockWidgetAction::MoveDockWidgetAction( ads::CDockWidget* widget, DockInDockManager* moveTo, QMenu* menu ) :
QAction(menu),
m_widget( widget ),
m_moveTo( moveTo )
{
if ( moveTo->parent().isTopLevel() )
{
setText( "To top" );
}
else
{
setText( "To " + moveTo->parent().objectName() );
}
connect( this, SIGNAL(triggered()), this, SLOT(move()) );
}
void MoveDockWidgetAction::move()
{
move( m_widget, m_moveTo );
}
void MoveDockWidgetAction::move( ads::CDockWidget* widget, DockInDockManager* moveTo )
{
if ( widget && moveTo )
{
widget->dockManager()->removeDockWidget( widget );
moveTo->addDockWidget(ads::CenterDockWidgetArea, widget, moveTo->getInsertDefaultPos());
}
else
{
assert( false );
}
}

View File

@@ -0,0 +1,96 @@
#pragma once
#include "DockManager.h"
#include <QAction>
#include <QMap>
namespace QtAdsUtl
{
class DockInDockWidget;
class DockInDockManager : public ads::CDockManager
{
Q_OBJECT
typedef ads::CDockManager baseClass;
public:
DockInDockManager( DockInDockWidget& parent );
~DockInDockManager() override;
void fillViewMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo );
void fillMoveMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo );
void addPerspectiveRec( const QString& name );
void openPerspectiveRec( const QString& name );
void removePerspectivesRec();
void loadPerspectivesRec(QSettings& Settings);
void savePerspectivesRec(QSettings& Settings) const;
static DockInDockManager* dockInAManager( ads::CDockWidget* widget );
inline DockInDockWidget& parent() { return m_parent; }
void childManagers( std::vector<DockInDockManager*>& managers, bool rec ) const;
std::vector<DockInDockManager*> allManagers( bool includeThis, bool rec ) const;
std::vector<std::pair<DockInDockManager*,ads::CDockWidget*>> allDockWidgets( bool includeThis, bool rec ) const;
QString getGroupName();
QString getPersistGroupName();
static QString getGroupNameFromPersistGroupName( QString persistGroupName );
QMap<QString,QStringList> getGroupContents();
ads::CDockAreaWidget* getInsertDefaultPos();
std::vector<ads::CDockWidget*> getWidgetsInGUIOrder() const;
private:
DockInDockWidget& m_parent;
};
class CreateChildDockAction : public QAction
{
Q_OBJECT
public:
CreateChildDockAction( DockInDockWidget& dockInDock, QMenu* menu );
public slots:
void createGroup();
private:
DockInDockWidget& m_dockInDock;
};
class DestroyGroupAction : public QAction
{
Q_OBJECT
public:
DestroyGroupAction( DockInDockWidget* widget, QMenu* menu );
public slots:
void destroyGroup();
private:
DockInDockWidget* m_widget;
};
class MoveDockWidgetAction : public QAction
{
Q_OBJECT
public:
MoveDockWidgetAction( ads::CDockWidget* widget, DockInDockManager* moveTo, QMenu* menu );
static void move( ads::CDockWidget* widget, DockInDockManager* moveTo );
public slots:
void move();
private:
ads::CDockWidget* m_widget;
DockInDockManager* m_moveTo;
};
}

View File

@@ -0,0 +1,11 @@
#include <QApplication>
#include "../../examples/simple/MainWindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,76 @@
#include "mainframe.h"
#include "dockindock.h"
#include "perspectives.h"
#include <QLabel>
#include <QMenuBar>
#include <QMessageBox>
#include <QSettings>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
m_perspectivesManager( new QtAdsUtl::PerspectivesManager( "persist" ) )
{
resize( 400, 400 );
setCentralWidget( m_dockManager = new QtAdsUtl::DockInDockWidget(this,true,m_perspectivesManager.get()) );
m_dockManager->attachViewMenu( menuBar()->addMenu( "View" ) );
ads::CDockAreaWidget* previousDockWidget = NULL;
for ( int i = 0; i != 3; ++i )
{
// Create example content label - this can be any application specific
// widget
QLabel* l = new QLabel();
l->setWordWrap(true);
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
previousDockWidget = m_dockManager->addTabWidget( l, "Top label " + QString::number(i), previousDockWidget );
}
auto lastTopLevelDock = previousDockWidget;
for ( int j = 0; j != 2; ++j )
{
QtAdsUtl::DockInDockWidget* groupManager = m_dockManager->createGroup( "Group " + QString::number(j), lastTopLevelDock );
previousDockWidget = NULL;
for ( int i = 0; i != 3; ++i )
{
// Create example content label - this can be any application specific
// widget
QLabel* l = new QLabel();
l->setWordWrap(true);
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
previousDockWidget = groupManager->addTabWidget( l, "ZInner " + QString::number(j) + "/" + QString::number(i), previousDockWidget );
}
// create sub-group
auto subGroup = groupManager->createGroup( "SubGroup " + QString::number(j), previousDockWidget );
previousDockWidget = NULL;
for ( int i = 0; i != 3; ++i )
{
// Create example content label - this can be any application specific
// widget
QLabel* l = new QLabel();
l->setWordWrap(true);
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
previousDockWidget = subGroup->addTabWidget( l, "SubInner " + QString::number(j) + "/" + QString::number(i), previousDockWidget );
}
}
m_perspectivesManager->loadPerspectives();
}
MainWindow::~MainWindow()
{
m_perspectivesManager->savePerspectives();
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include <QMainWindow>
#include <QAction>
#include <QSettings>
#include <memory>
namespace QtAdsUtl
{
class DockInDockWidget;
class PerspectivesManager;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QtAdsUtl::DockInDockWidget* m_dockManager;
std::unique_ptr<QtAdsUtl::PerspectivesManager> m_perspectivesManager;
};

View File

@@ -0,0 +1,39 @@
#include "perspectiveactions.h"
#include "dockindock.h"
#include "perspectives.h"
#include <QMenu>
using namespace QtAdsUtl;
//////////////////////////////
// LoadPerspectiveAction
//////////////////////////////
LoadPerspectiveAction::LoadPerspectiveAction( QMenu* parent, const QString& name, QtAdsUtl::DockInDockWidget& dockManager ) :
QAction( name, parent ),
name( name ),
dockManager( dockManager )
{
connect( this, SIGNAL(triggered()), this, SLOT(load()) );
}
void LoadPerspectiveAction::load()
{
dockManager.getPerspectivesManager()->openPerspective( name, dockManager );
}
//////////////////////////////
// RemovePerspectiveAction
//////////////////////////////
RemovePerspectiveAction::RemovePerspectiveAction( QMenu* parent, const QString& name, QtAdsUtl::DockInDockWidget& dockManager ) :
QAction( name, parent ),
name( name ),
dockManager( dockManager )
{
connect( this, SIGNAL(triggered()), this, SLOT(remove()) );
}
void RemovePerspectiveAction::remove()
{
dockManager.getPerspectivesManager()->removePerspective( name );
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include <QAction>
namespace QtAdsUtl
{
class DockInDockWidget;
class LoadPerspectiveAction : public QAction
{
Q_OBJECT
public:
LoadPerspectiveAction( QMenu* parent, const QString& name, QtAdsUtl::DockInDockWidget& dockManager );
public slots:
void load();
private:
QString name;
QtAdsUtl::DockInDockWidget& dockManager;
};
class RemovePerspectiveAction : public QAction
{
Q_OBJECT
public:
RemovePerspectiveAction( QMenu* parent, const QString& name, QtAdsUtl::DockInDockWidget& dockManager );
public slots:
void remove();
private:
QString name;
QtAdsUtl::DockInDockWidget& dockManager;
};
}

View File

@@ -0,0 +1,278 @@
#include "perspectives.h"
#include "dockindock.h"
#include "dockindockmanager.h"
#include <QSettings>
#include <QFile>
#include <QDir>
#include <assert.h>
#define GROUP_PREFIX QString("Group")
using namespace QtAdsUtl;
PerspectivesManager::PerspectivesManager( const QString& perspectivesFolder ) :
m_perspectivesFolder( perspectivesFolder )
{
}
PerspectivesManager::~PerspectivesManager()
{
// remove temp files:
for ( auto perspective : m_perspectives )
{
QString fileName = perspective.settings->fileName();
perspective.settings.reset();
QFile::remove(fileName);
}
}
QStringList PerspectivesManager::perspectiveNames() const
{
return m_perspectives.keys();
}
void PerspectivesManager::addPerspective( const QString& name, DockInDockWidget& widget )
{
if ( !m_perspectivesFolder.isEmpty() )
{
m_perspectives[name].settings = getSettingsObject( getSettingsFileName( name, true ) );
m_perspectives[name].groups = widget.getManager()->getGroupContents();
// save perspective internally
widget.getManager()->addPerspectiveRec( name );
// store it in QSettings object
widget.getManager()->savePerspectivesRec( *(m_perspectives[name].settings) );
// remove internal perspectives
widget.getManager()->removePerspectives( widget.getManager()->perspectiveNames() );
}
else
{
assert( false );
}
emit perspectivesListChanged();
}
ads::CDockWidget* findWidget( QString name, const std::vector<DockInDockManager*>& managers )
{
for ( auto mgr : managers )
{
auto widget = mgr->findDockWidget(name);
if ( widget )
return widget;
}
return NULL;
}
void PerspectivesManager::openPerspective( const QString& name, DockInDockWidget& widget )
{
assert( widget.getTopLevelDockWidget() == &widget );
if ( !m_perspectivesFolder.isEmpty() )
{
if ( m_perspectives.contains( name ) )
{
emit openingPerspective();
if ( widget.canCreateNewGroups() )
{
auto curGroups = widget.getManager()->allManagers(true,true);
for ( auto group : m_perspectives[name].groups.keys() )
{
bool found = false;
for ( auto curgroup : curGroups )
{
if ( curgroup->getPersistGroupName() == group )
{
found = true;
break;
}
}
if ( !found )
{
group = DockInDockManager::getGroupNameFromPersistGroupName( group );
// restore group in file but not in GUI yet
ads::CDockAreaWidget* insertPos = NULL;
widget.createGroup( group, insertPos );
}
}
curGroups = widget.getManager()->allManagers(false,true);
for ( auto curgroup : curGroups )
{
if ( !m_perspectives[name].groups.keys().contains( curgroup->getPersistGroupName() ) )
{
widget.destroyGroup( &curgroup->parent() );
}
}
}
auto managers = widget.getManager()->allManagers(true,true);
for ( auto group : m_perspectives[name].groups.keys() )
{
for ( auto mgr : managers )
{
if ( mgr->getPersistGroupName() == group )
{
for ( QString widgetName : m_perspectives[name].groups[group] )
{
ads::CDockWidget* widget = findWidget( widgetName, { mgr } );
if ( widget )
{
// OK, widget is already in the good manager!
}
else
{
widget = findWidget( widgetName, managers );
if ( widget )
{
// move dock widget in the same group as it used to be when perspective was saved
// this guarantee load/open perspectives will work smartly
MoveDockWidgetAction::move( widget, mgr );
}
}
}
}
}
}
// internally load perspectives from QSettings
widget.getManager()->loadPerspectivesRec( *(m_perspectives[name].settings) );
// load perspective (update GUI)
widget.getManager()->openPerspectiveRec( name );
// remove internal perspectives
widget.getManager()->removePerspectives( widget.getManager()->perspectiveNames() );
emit openedPerspective();
}
}
else
{
assert( false );
}
}
void PerspectivesManager::removePerspectives()
{
m_perspectives.clear();
emit perspectivesListChanged();
}
void PerspectivesManager::removePerspective( const QString& name )
{
m_perspectives.remove( name );
emit perspectivesListChanged();
}
QString PerspectivesManager::getSettingsFileName( const QString& perspective, bool temp ) const
{
auto name = ( perspective.isEmpty() ) ? "perspectives.ini" : "perspective_" + perspective + (temp?".tmp":".ini");
return m_perspectivesFolder + "/" + name;
}
std::shared_ptr<QSettings> PerspectivesManager::getSettingsObject( const QString& filePath ) const
{
return std::make_shared<QSettings>(filePath, QSettings::IniFormat);
}
void PerspectivesManager::loadPerspectives()
{
if ( !m_perspectivesFolder.isEmpty() )
{
QDir().mkpath( m_perspectivesFolder );
m_perspectives.clear();
auto mainSettings = getSettingsObject( getSettingsFileName( "", false ) );
std::string debug = mainSettings->fileName().toStdString();
int Size = mainSettings->beginReadArray("Perspectives");
for (int i = 0; i < Size; ++i)
{
mainSettings->setArrayIndex(i);
QString perspective = mainSettings->value("Name").toString();
if ( !perspective.isEmpty() )
{
// load perspective file:
auto toLoad = getSettingsFileName( perspective, false );
auto loaded = getSettingsFileName( perspective, true );
#ifdef _DEBUG
std::string debug1 = loaded.toStdString();
std::string debug2 = toLoad.toStdString();
#endif
QFile::remove( loaded );
if ( !QFile::copy( toLoad, loaded ) )
assert( false );
m_perspectives[perspective].settings = getSettingsObject( loaded );
// load group info:
mainSettings->beginGroup(GROUP_PREFIX);
for ( auto key : mainSettings->allKeys() )
m_perspectives[perspective].groups[key] = mainSettings->value( key ).toStringList();
mainSettings->endGroup();
}
else
{
assert( false );
}
}
mainSettings->endArray();
}
emit perspectivesListChanged();
}
void PerspectivesManager::savePerspectives() const
{
if ( !m_perspectivesFolder.isEmpty() )
{
auto mainSettings = getSettingsObject( getSettingsFileName( "", false ) );
// Save list of perspective and group organization
mainSettings->beginWriteArray("Perspectives", m_perspectives.size());
int i = 0;
for ( auto perspective : m_perspectives.keys() )
{
mainSettings->setArrayIndex(i);
mainSettings->setValue("Name", perspective);
mainSettings->beginGroup(GROUP_PREFIX);
for ( auto group : m_perspectives[perspective].groups.keys() )
{
mainSettings->setValue( group, m_perspectives[perspective].groups[group] );
}
mainSettings->endGroup();
++i;
}
mainSettings->endArray();
// Save perspectives themselves
for ( auto perspectiveName : m_perspectives.keys() )
{
auto toSave = getSettingsFileName( perspectiveName, false );
QSettings& settings = *(m_perspectives[perspectiveName].settings);
settings.sync();
#ifdef _DEBUG
std::string debug1 = settings.fileName().toStdString();
std::string debug2 = toSave.toStdString();
#endif
QFile::remove( toSave );
if ( !QFile::copy( settings.fileName(), toSave ) )
assert( false );
}
}
}

View File

@@ -0,0 +1,59 @@
#pragma once
#include <QObject>
#include <QMap>
#include <QString>
#include <memory>
class QMenu;
class QSettings;
namespace QtAdsUtl
{
class DockInDockWidget;
class PerspectivesManager : public QObject
{
Q_OBJECT
public:
PerspectivesManager( const QString& perspectivesFolder );
virtual ~PerspectivesManager();
QStringList perspectiveNames() const;
void addPerspective( const QString& name, DockInDockWidget& widget );
void openPerspective( const QString& name, DockInDockWidget& widget );
void removePerspectives();
void removePerspective( const QString& name );
void loadPerspectives();
void savePerspectives() const;
signals:
void perspectivesListChanged();
void openingPerspective();
void openedPerspective();
private:
// Partially bypass ADS perspective management, store list here
// and then ADS will only have one perspective loaded
// this is because all docking widgets must exist when a perspective is loaded
// we will guarantee that!
class PerspectiveInfo
{
public:
std::shared_ptr<QSettings> settings;
QMap<QString,QStringList> groups;
};
QMap<QString,PerspectiveInfo> m_perspectives;
QString m_perspectivesFolder;
QString getSettingsFileName( const QString& perspective, bool temp ) const;
std::shared_ptr<QSettings> getSettingsObject( const QString& filePath ) const;
};
}

View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_centralwidget VERSION ${VERSION_SHORT})
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(EmptyDockAreaExample WIN32
main.cpp
mainwindow.cpp
mainwindow.ui
)
target_include_directories(EmptyDockAreaExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(EmptyDockAreaExample PRIVATE qtadvanceddocking)
target_link_libraries(EmptyDockAreaExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(EmptyDockAreaExample PROPERTIES
AUTOMOC ON
AUTORCC ON
AUTOUIC ON
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT}
EXPORT_NAME "Qt Advanced Docking System Empty Dock Area Example"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
)

View File

@@ -0,0 +1,34 @@
ADS_OUT_ROOT = $${OUT_PWD}/../..
QT += core gui widgets
TARGET = EmptyDockareaExample
DESTDIR = $${ADS_OUT_ROOT}/lib
TEMPLATE = app
CONFIG += c++14
CONFIG += debug_and_release
adsBuildStatic {
DEFINES += ADS_STATIC
}
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
LIBS += -L$${ADS_OUT_ROOT}/lib
include(../../ads.pri)
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@@ -0,0 +1,10 @@
#include <mainwindow.h>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CMainWindow w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,135 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWidgetAction>
#include <QLabel>
#include <QCalendarWidget>
#include <QTreeView>
#include <QFileSystemModel>
#include <QTableWidget>
#include <QHBoxLayout>
#include <QRadioButton>
#include <QPushButton>
#include <QInputDialog>
#include <QFileDialog>
#include <QSettings>
#include <QMessageBox>
#include <QPlainTextEdit>
#include <QToolBar>
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
#include "DockAreaTabBar.h"
#include "FloatingDockContainer.h"
#include "DockComponentsFactory.h"
using namespace ads;
CMainWindow::CMainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::CMainWindow)
{
ui->setupUi(this);
CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true);
CDockManager::setConfigFlag(CDockManager::XmlCompressionEnabled, false);
CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true);
DockManager = new CDockManager(this);
// Set central widget
QLabel* label = new QLabel();
label->setText("This is a DockArea which is always visible, even if it does not contain any DockWidgets.");
label->setAlignment(Qt::AlignCenter);
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget");
CentralDockWidget->setWidget(label);
CentralDockWidget->setFeature(ads::CDockWidget::NoTab, true);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
// create other dock widgets
QTableWidget* table = new QTableWidget();
table->setColumnCount(3);
table->setRowCount(10);
CDockWidget* TableDockWidget = new CDockWidget("Table 1");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
TableDockWidget->setMinimumSize(200,150);
DockManager->addDockWidgetTabToArea(TableDockWidget, CentralDockArea);
auto TableArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, TableDockWidget);
ui->menuView->addAction(TableDockWidget->toggleViewAction());
table = new QTableWidget();
table->setColumnCount(5);
table->setRowCount(1020);
TableDockWidget = new CDockWidget("Table 2");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
TableDockWidget->setMinimumSize(200,150);
DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, TableDockWidget, TableArea);
ui->menuView->addAction(TableDockWidget->toggleViewAction());
QTableWidget* propertiesTable = new QTableWidget();
propertiesTable->setColumnCount(3);
propertiesTable->setRowCount(10);
CDockWidget* PropertiesDockWidget = new CDockWidget("Properties");
PropertiesDockWidget->setWidget(propertiesTable);
PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
PropertiesDockWidget->resize(250, 150);
PropertiesDockWidget->setMinimumSize(200,150);
DockManager->addDockWidget(DockWidgetArea::RightDockWidgetArea, PropertiesDockWidget, CentralDockArea);
ui->menuView->addAction(PropertiesDockWidget->toggleViewAction());
createPerspectiveUi();
}
CMainWindow::~CMainWindow()
{
delete ui;
}
void CMainWindow::createPerspectiveUi()
{
SavePerspectiveAction = new QAction("Create Perspective", this);
connect(SavePerspectiveAction, SIGNAL(triggered()), SLOT(savePerspective()));
PerspectiveListAction = new QWidgetAction(this);
PerspectiveComboBox = new QComboBox(this);
PerspectiveComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
PerspectiveComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
connect(PerspectiveComboBox, SIGNAL(activated(const QString&)),
DockManager, SLOT(openPerspective(const QString&)));
PerspectiveListAction->setDefaultWidget(PerspectiveComboBox);
ui->toolBar->addSeparator();
ui->toolBar->addAction(PerspectiveListAction);
ui->toolBar->addAction(SavePerspectiveAction);
}
void CMainWindow::savePerspective()
{
QString PerspectiveName = QInputDialog::getText(this, "Save Perspective", "Enter unique name:");
if (PerspectiveName.isEmpty())
{
return;
}
DockManager->addPerspective(PerspectiveName);
QSignalBlocker Blocker(PerspectiveComboBox);
PerspectiveComboBox->clear();
PerspectiveComboBox->addItems(DockManager->perspectiveNames());
PerspectiveComboBox->setCurrentText(PerspectiveName);
}
//============================================================================
void CMainWindow::closeEvent(QCloseEvent* event)
{
// Delete dock manager here to delete all floating widgets. This ensures
// that all top level windows of the dock manager are properly closed
DockManager->deleteLater();
QMainWindow::closeEvent(event);
}

View File

@@ -0,0 +1,43 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QComboBox>
#include <QWidgetAction>
#include "DockManager.h"
#include "DockAreaWidget.h"
#include "DockWidget.h"
QT_BEGIN_NAMESPACE
namespace Ui { class CMainWindow; }
QT_END_NAMESPACE
class CMainWindow : public QMainWindow
{
Q_OBJECT
public:
CMainWindow(QWidget *parent = nullptr);
~CMainWindow();
protected:
virtual void closeEvent(QCloseEvent* event) override;
private:
QAction* SavePerspectiveAction = nullptr;
QWidgetAction* PerspectiveListAction = nullptr;
QComboBox* PerspectiveComboBox = nullptr;
Ui::CMainWindow *ui;
ads::CDockManager* DockManager;
ads::CDockAreaWidget* StatusDockArea;
ads::CDockWidget* TimelineDockWidget;
void createPerspectiveUi();
private slots:
void savePerspective();
};
#endif // MAINWINDOW_H

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CMainWindow</class>
<widget class="QMainWindow" name="CMainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>757</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuView">
<property name="title">
<string>View</string>
</property>
</widget>
<addaction name="menuView"/>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -4,4 +4,6 @@ SUBDIRS = \
centralwidget \
simple \
sidebar \
deleteonclose
deleteonclose \
emptydockarea \
dockindock

View File

@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_sidebar VERSION ${VERSION_SHORT})
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(SidebarExample WIN32
main.cpp
@@ -9,7 +10,9 @@ add_executable(SidebarExample WIN32
)
target_include_directories(SidebarExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(SidebarExample PRIVATE qtadvanceddocking)
target_link_libraries(SidebarExample PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
target_link_libraries(SidebarExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(SidebarExample PROPERTIES
AUTOMOC ON
AUTORCC ON

View File

@@ -25,28 +25,7 @@ FORMS += \
LIBS += -L$${ADS_OUT_ROOT}/lib
# Dependency: AdvancedDockingSystem (shared)
CONFIG(debug, debug|release){
win32 {
LIBS += -lqtadvanceddockingd
}
else:mac {
LIBS += -lqtadvanceddocking_debug
}
else {
LIBS += -lqtadvanceddocking
}
}
else{
LIBS += -lqtadvanceddocking
}
unix:!macx {
LIBS += -lxcb
QT += x11extras
}
include(../../ads.pri)
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_simple VERSION ${VERSION_SHORT})
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(SimpleExample WIN32
main.cpp
@@ -9,7 +10,9 @@ add_executable(SimpleExample WIN32
)
target_include_directories(SimpleExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(SimpleExample PRIVATE qtadvanceddocking)
target_link_libraries(SimpleExample PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
target_link_libraries(SimpleExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(SimpleExample PROPERTIES
AUTOMOC ON
AUTORCC ON

View File

@@ -25,28 +25,7 @@ FORMS += \
LIBS += -L$${ADS_OUT_ROOT}/lib
# Dependency: AdvancedDockingSystem (shared)
CONFIG(debug, debug|release){
win32 {
LIBS += -lqtadvanceddockingd
}
else:mac {
LIBS += -lqtadvanceddocking_debug
}
else {
LIBS += -lqtadvanceddocking
}
}
else{
LIBS += -lqtadvanceddocking
}
unix:!macx {
LIBS += -lxcb
QT += x11extras
}
include(../../ads.pri)
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@@ -135,7 +135,6 @@ protected:
ads::CDockOverlay* dockAreaOverlay() const;
void notifyWidgetOrAreaRelocation(QWidget* RelocatedWidget);
void notifyFloatingWidgetDrop(ads::CFloatingDockContainer* FloatingWidget);
ads::CDockWidget* focusedDockWidget() const;
virtual void showEvent(QShowEvent *event);
@@ -217,6 +216,9 @@ public:
void setViewMenuInsertionOrder(ads::CDockManager::eViewMenuInsertionOrder Order);
bool isRestoringState() const;
static int startDragDistance();
ads::CDockWidget* focusedDockWidget() const;
QList<int> splitterSizes(ads::CDockAreaWidget *ContainedArea) const;
void setSplitterSizes(ads::CDockAreaWidget *ContainedArea, const QList<int>& sizes);
public slots:
void openPerspective(const QString& PerspectiveName);

View File

@@ -35,6 +35,8 @@ public:
virtual bool event(QEvent *e);
void setElideMode(Qt::TextElideMode mode);
void updateStyle();
QSize iconSize() const;
void setIconSize(const QSize& Size);
public slots:
virtual void setVisible(bool visible);

View File

@@ -1,8 +1,9 @@
cmake_minimum_required(VERSION 3.5)
project(QtAdvancedDockingSystem LANGUAGES CXX VERSION ${VERSION_SHORT})
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
if (UNIX AND NOT APPLE)
find_package(Qt5 5.5 COMPONENTS X11Extras REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS X11Extras REQUIRED)
endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
if(BUILD_STATIC)
@@ -48,6 +49,7 @@ set(ads_HEADERS
IconProvider.h
DockComponentsFactory.h
)
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
if (UNIX AND NOT APPLE)
set(ads_SRCS linux/FloatingWidgetTitleBar.cpp ${ads_SRCS})
set(ads_HEADERS linux/FloatingWidgetTitleBar.h ${ads_HEADERS})
@@ -59,12 +61,14 @@ else()
add_library(qtadvanceddocking SHARED ${ads_SRCS} ${ads_HEADERS})
target_compile_definitions(qtadvanceddocking PRIVATE ADS_SHARED_EXPORT)
endif()
target_link_libraries(qtadvanceddocking PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
target_link_libraries(qtadvanceddocking PUBLIC Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets)
if(UNIX AND NOT APPLE)
target_link_libraries(qtadvanceddocking PUBLIC Qt5::X11Extras)
target_link_libraries(qtadvanceddocking PUBLIC Qt${QT_VERSION_MAJOR}::X11Extras)
target_link_libraries(qtadvanceddocking PRIVATE xcb)
endif()
set_target_properties(qtadvanceddocking PROPERTIES
set_target_properties(qtadvanceddocking PROPERTIES
AUTOMOC ON
AUTORCC ON
CXX_STANDARD 14
@@ -83,13 +87,13 @@ write_basic_package_version_file(
COMPATIBILITY SameMajorVersion
)
install(FILES ${ads_HEADERS}
DESTINATION include
DESTINATION include
COMPONENT headers
)
install(FILES
install(FILES
"${CMAKE_SOURCE_DIR}/LICENSE"
"${CMAKE_SOURCE_DIR}/gnu-lgpl-v2.1.md"
DESTINATION license
DESTINATION license
COMPONENT license
)
install(TARGETS qtadvanceddocking

View File

@@ -180,11 +180,11 @@ void CDockAreaTabBar::setCurrentIndex(int index)
return;
}
emit currentChanging(index);
Q_EMIT currentChanging(index);
d->CurrentIndex = index;
d->updateTabs();
updateGeometry();
emit currentChanged(index);
Q_EMIT currentChanged(index);
}
@@ -206,7 +206,7 @@ void CDockAreaTabBar::insertTab(int Index, CDockWidgetTab* Tab)
connect(Tab, SIGNAL(moved(const QPoint&)), this, SLOT(onTabWidgetMoved(const QPoint&)));
connect(Tab, SIGNAL(elidedChanged(bool)), this, SIGNAL(elidedChanged(bool)));
Tab->installEventFilter(this);
emit tabInserted(Index);
Q_EMIT tabInserted(Index);
if (Index <= d->CurrentIndex)
{
setCurrentIndex(d->CurrentIndex + 1);
@@ -266,7 +266,7 @@ void CDockAreaTabBar::removeTab(CDockWidgetTab* Tab)
}
}
emit removingTab(RemoveIndex);
Q_EMIT removingTab(RemoveIndex);
d->TabsLayout->removeWidget(Tab);
Tab->disconnect(this);
Tab->removeEventFilter(this);
@@ -320,7 +320,7 @@ void CDockAreaTabBar::onTabClicked()
return;
}
setCurrentIndex(index);
emit tabBarClicked(index);
Q_EMIT tabBarClicked(index);
}
@@ -409,7 +409,7 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
d->TabsLayout->removeWidget(MovingTab);
d->TabsLayout->insertWidget(toIndex, MovingTab);
ADS_PRINT("tabMoved from " << fromIndex << " to " << toIndex);
emit tabMoved(fromIndex, toIndex);
Q_EMIT tabMoved(fromIndex, toIndex);
setCurrentIndex(toIndex);
}
else
@@ -432,7 +432,7 @@ void CDockAreaTabBar::closeTab(int Index)
{
return;
}
emit tabCloseRequested(Index);
Q_EMIT tabCloseRequested(Index);
}
@@ -449,12 +449,12 @@ bool CDockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
switch (event->type())
{
case QEvent::Hide:
emit tabClosed(d->TabsLayout->indexOf(Tab));
Q_EMIT tabClosed(d->TabsLayout->indexOf(Tab));
updateGeometry();
break;
case QEvent::Show:
emit tabOpened(d->TabsLayout->indexOf(Tab));
Q_EMIT tabOpened(d->TabsLayout->indexOf(Tab));
updateGeometry();
break;

View File

@@ -58,7 +58,7 @@ private:
friend struct DockAreaTabBarPrivate;
friend class CDockAreaTitleBar;
private slots:
private Q_SLOTS:
void onTabClicked();
void onTabCloseRequested();
void onCloseOtherTabsRequested();
@@ -140,7 +140,7 @@ public:
*/
virtual QSize sizeHint() const override;
public slots:
public Q_SLOTS:
/**
* This property sets the index of the tab bar's visible tab
*/
@@ -152,7 +152,7 @@ public slots:
*/
void closeTab(int Index);
signals:
Q_SIGNALS:
/**
* This signal is emitted when the tab bar's current tab is about to be changed. The new
* current has the given index, or -1 if there isn't a new one.

View File

@@ -382,7 +382,7 @@ void CDockAreaTitleBar::onTabsMenuActionTriggered(QAction* Action)
{
int Index = Action->data().toInt();
d->TabBar->setCurrentIndex(Index);
emit tabBarClicked(Index);
Q_EMIT tabBarClicked(Index);
}

View File

@@ -54,7 +54,7 @@ private:
DockAreaTitleBarPrivate* d; ///< private data (pimpl)
friend struct DockAreaTitleBarPrivate;
private slots:
private Q_SLOTS:
void onTabsMenuAboutToShow();
void onCloseButtonClicked();
void onUndockButtonClicked();
@@ -88,7 +88,7 @@ protected:
*/
virtual void contextMenuEvent(QContextMenuEvent *event) override;
public slots:
public Q_SLOTS:
/**
* Call this slot to tell the title bar that it should update the tabs menu
* the next time it is shown.
@@ -148,7 +148,7 @@ public:
*/
int indexOf(QWidget *widget) const;
signals:
Q_SIGNALS:
/**
* This signal is emitted if a tab in the tab bar is clicked by the user
* or if the user clicks on a tab item in the title bar tab menu.

View File

@@ -324,7 +324,6 @@ struct DockAreaWidgetPrivate
}
}
};
// struct DockAreaWidgetPrivate
//============================================================================
@@ -379,7 +378,7 @@ CDockAreaWidget::CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget
d->ContentsLayout = new DockAreaLayout(d->Layout);
if (d->DockManager)
{
emit d->DockManager->dockAreaCreated(this);
Q_EMIT d->DockManager->dockAreaCreated(this);
}
}
@@ -605,11 +604,11 @@ void CDockAreaWidget::setCurrentIndex(int index)
return;
}
emit currentChanging(index);
Q_EMIT currentChanging(index);
TabBar->setCurrentIndex(index);
d->ContentsLayout->setCurrentIndex(index);
d->ContentsLayout->currentWidget()->show();
emit currentChanged(index);
Q_EMIT currentChanged(index);
}
@@ -809,18 +808,49 @@ CDockWidget* CDockAreaWidget::nextOpenDockWidget(CDockWidget* DockWidget) const
auto OpenDockWidgets = openedDockWidgets();
if (OpenDockWidgets.count() > 1 || (OpenDockWidgets.count() == 1 && OpenDockWidgets[0] != DockWidget))
{
CDockWidget* NextDockWidget;
if (OpenDockWidgets.last() == DockWidget)
{
NextDockWidget = OpenDockWidgets[OpenDockWidgets.count() - 2];
CDockWidget* NextDockWidget = OpenDockWidgets[OpenDockWidgets.count() - 2];
// search backwards for widget with tab
for (int i = OpenDockWidgets.count() - 2; i >= 0; --i)
{
auto dw = OpenDockWidgets[i];
if (!dw->features().testFlag(CDockWidget::NoTab))
{
return dw;
}
}
// return widget without tab
return NextDockWidget;
}
else
{
int NextIndex = OpenDockWidgets.indexOf(DockWidget) + 1;
NextDockWidget = OpenDockWidgets[NextIndex];
}
int IndexOfDockWidget = OpenDockWidgets.indexOf(DockWidget);
CDockWidget* NextDockWidget = OpenDockWidgets[IndexOfDockWidget + 1];
// search forwards for widget with tab
for (int i = IndexOfDockWidget + 1; i < OpenDockWidgets.count(); ++i)
{
auto dw = OpenDockWidgets[i];
if (!dw->features().testFlag(CDockWidget::NoTab))
{
return dw;
}
}
return NextDockWidget;
// search backwards for widget with tab
for (int i = IndexOfDockWidget - 1; i >= 0; --i)
{
auto dw = OpenDockWidgets[i];
if (!dw->features().testFlag(CDockWidget::NoTab))
{
return dw;
}
}
// return widget without tab
return NextDockWidget;
}
}
else
{
@@ -858,7 +888,7 @@ void CDockAreaWidget::toggleView(bool Open)
{
setVisible(Open);
emit viewToggled(Open);
Q_EMIT viewToggled(Open);
}
@@ -974,7 +1004,19 @@ bool CDockAreaWidget::isCentralWidgetArea() const
//============================================================================
QSize CDockAreaWidget::minimumSizeHint() const
{
return d->MinSizeHint.isValid() ? d->MinSizeHint : Super::minimumSizeHint();
if (!d->MinSizeHint.isValid())
{
return Super::minimumSizeHint();
}
if (d->TitleBar->isVisible())
{
return d->MinSizeHint + QSize(0, d->TitleBar->minimumSizeHint().height());
}
else
{
return d->MinSizeHint;
}
}
@@ -988,6 +1030,21 @@ void CDockAreaWidget::onDockWidgetFeaturesChanged()
}
#ifdef Q_OS_WIN
//============================================================================
bool CDockAreaWidget::event(QEvent *e)
{
switch (e->type())
{
case QEvent::PlatformSurface: return true;
default:
break;
}
return Super::event(e);
}
#endif
} // namespace ads
//---------------------------------------------------------------------------

View File

@@ -67,7 +67,7 @@ private:
friend class CDockManager;
void onDockWidgetFeaturesChanged();
private slots:
private Q_SLOTS:
void onTabCloseRequested(int Index);
/**
@@ -77,6 +77,17 @@ private slots:
void reorderDockWidget(int fromIndex, int toIndex);
protected:
#ifdef Q_OS_WIN
/**
* Reimplements QWidget::event to handle QEvent::PlatformSurface
* This is here to fix issue #294 Tab refresh problem with a QGLWidget
* that exists since Qt version 5.12.7. So this function is here to
* work around a Qt issue.
*/
virtual bool event(QEvent *event) override;
#endif
/**
* Inserts a dock widget into dock area.
* All dockwidgets in the dock area tabified in a stacked layout with tabs.
@@ -138,7 +149,7 @@ protected:
*/
void markTitleBarMenuOutdated();
protected slots:
protected Q_SLOTS:
void toggleView(bool Open);
public:
@@ -312,7 +323,7 @@ public:
*/
bool isCentralWidgetArea() const;
public slots:
public Q_SLOTS:
/**
* This activates the tab for the given tab index.
* If the dock widget for the given tab is not visible, the this function
@@ -330,7 +341,7 @@ public slots:
*/
void closeOtherAreas();
signals:
Q_SIGNALS:
/**
* This signal is emitted when user clicks on a tab at an index.
*/

View File

@@ -284,13 +284,13 @@ public:
void emitDockAreasRemoved()
{
onVisibleDockAreaCountChanged();
emit _this->dockAreasRemoved();
Q_EMIT _this->dockAreasRemoved();
}
void emitDockAreasAdded()
{
onVisibleDockAreaCountChanged();
emit _this->dockAreasAdded();
Q_EMIT _this->dockAreasAdded();
}
/**
@@ -341,7 +341,7 @@ public:
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(_this->sender());
VisibleDockAreaCount += Visible ? 1 : -1;
onVisibleDockAreaCountChanged();
emit _this->dockAreaViewToggled(DockArea, Visible);
Q_EMIT _this->dockAreaViewToggled(DockArea, Visible);
}
}; // struct DockContainerWidgetPrivate
@@ -917,15 +917,15 @@ bool DockContainerWidgetPrivate::restoreSplitter(CDockingStateReader& s,
{
QWidget* ChildNode = nullptr;
bool Result = true;
if (s.name() == "Splitter")
if (s.name() == QLatin1String("Splitter"))
{
Result = restoreSplitter(s, ChildNode, Testing);
}
else if (s.name() == "Area")
else if (s.name() == QLatin1String("Area"))
{
Result = restoreDockArea(s, ChildNode, Testing);
}
else if (s.name() == "Sizes")
else if (s.name() == QLatin1String("Sizes"))
{
QString sSizes = s.readElementText().trimmed();
ADS_PRINT("Sizes: " << sSizes);
@@ -1026,7 +1026,7 @@ bool DockContainerWidgetPrivate::restoreDockArea(CDockingStateReader& s,
while (s.readNextStartElement())
{
if (s.name() != "Widget")
if (s.name() != QLatin1String("Widget"))
{
continue;
}
@@ -1089,12 +1089,12 @@ bool DockContainerWidgetPrivate::restoreChildNodes(CDockingStateReader& s,
bool Result = true;
while (s.readNextStartElement())
{
if (s.name() == "Splitter")
if (s.name() == QLatin1String("Splitter"))
{
Result = restoreSplitter(s, CreatedWidget, Testing);
ADS_PRINT("Splitter");
}
else if (s.name() == "Area")
else if (s.name() == QLatin1String("Area"))
{
Result = restoreDockArea(s, CreatedWidget, Testing);
ADS_PRINT("DockAreaWidget");
@@ -1253,7 +1253,6 @@ CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetA
{
adjustSplitterSizesOnInsertion(TargetAreaSplitter);
}
}
else
{
@@ -1273,8 +1272,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetA
}
}
appendDockAreas({NewDockArea});
emitDockAreasAdded();
addDockAreasToList({NewDockArea});
return NewDockArea;
}
@@ -1666,7 +1664,7 @@ bool CDockContainerWidget::restoreState(CDockingStateReader& s, bool Testing)
if (IsFloating)
{
ADS_PRINT("Restore floating widget");
if (!s.readNextStartElement() || s.name() != "Geometry")
if (!s.readNextStartElement() || s.name() != QLatin1String("Geometry"))
{
return false;
}

View File

@@ -265,7 +265,7 @@ public:
*/
void closeOtherAreas(CDockAreaWidget* KeepOpenArea);
signals:
Q_SIGNALS:
/**
* This signal is emitted if one or multiple dock areas has been added to
* the internal list of dock areas.

View File

@@ -174,7 +174,7 @@ void DockFocusControllerPrivate::updateDockWidgetFocus(CDockWidget* DockWidget)
ForceFocusChangedSignal = false;
if (DockWidget->isVisible())
{
emit DockManager->focusedDockWidgetChanged(old, DockWidget);
Q_EMIT DockManager->focusedDockWidgetChanged(old, DockWidget);
}
else
{
@@ -193,7 +193,7 @@ void CDockFocusController::onDockWidgetVisibilityChanged(bool Visible)
disconnect(Sender, SIGNAL(visibilityChanged(bool)), this, SLOT(onDockWidgetVisibilityChanged(bool)));
if (DockWidget && Visible)
{
emit d->DockManager->focusedDockWidgetChanged(d->OldFocusedDockWidget, DockWidget);
Q_EMIT d->DockManager->focusedDockWidgetChanged(d->OldFocusedDockWidget, DockWidget);
}
}

View File

@@ -30,7 +30,7 @@ private:
DockFocusControllerPrivate* d; ///< private data (pimpl)
friend struct DockFocusControllerPrivate;
private slots:
private Q_SLOTS:
void onApplicationFocusChanged(QWidget *old, QWidget *now);
void onFocusedDockAreaViewToggled(bool Open);
void onStateRestored();
@@ -83,7 +83,7 @@ public:
*/
CDockWidget* focusedDockWidget() const;
public slots:
public Q_SLOTS:
/**
* Request a focus change to the given dock widget
*/

View File

@@ -250,7 +250,7 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi
}
CDockingStateReader s(state);
s.readNextStartElement();
if (s.name() != "QtAdvancedDockingSystem")
if (s.name() != QLatin1String("QtAdvancedDockingSystem"))
{
return false;
}
@@ -304,7 +304,7 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi
int DockContainerCount = 0;
while (s.readNextStartElement())
{
if (s.name() == "Container")
if (s.name() == QLatin1String("Container"))
{
Result = restoreContainer(DockContainerCount, s, Testing);
if (!Result)
@@ -343,7 +343,7 @@ void DockManagerPrivate::restoreDockWidgetsOpenState()
if (DockWidget->property(internal::DirtyProperty).toBool())
{
DockWidget->flagAsUnassigned();
emit DockWidget->viewToggled(false);
Q_EMIT DockWidget->viewToggled(false);
}
else
{
@@ -505,6 +505,20 @@ CDockManager::CDockManager(QWidget *parent) :
//============================================================================
CDockManager::~CDockManager()
{
// fix memory leaks, see https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/307
std::vector<ads::CDockAreaWidget*> areas;
for ( int i = 0; i != dockAreaCount(); ++i )
{
areas.push_back( dockArea(i) );
}
for ( auto area : areas )
{
for ( auto widget : area->dockWidgets() )
delete widget;
delete area;
}
auto FloatingWidgets = d->FloatingWidgets;
for (auto FloatingWidget : FloatingWidgets)
{
@@ -582,7 +596,7 @@ bool CDockManager::eventFilter(QObject *obj, QEvent *e)
void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget)
{
d->FloatingWidgets.append(FloatingWidget);
emit floatingWidgetCreated(FloatingWidget);
Q_EMIT floatingWidgetCreated(FloatingWidget);
ADS_PRINT("d->FloatingWidgets.count() " << d->FloatingWidgets.count());
}
@@ -699,14 +713,14 @@ bool CDockManager::restoreState(const QByteArray &state, int version)
hide();
}
d->RestoringState = true;
emit restoringState();
Q_EMIT restoringState();
bool Result = d->restoreState(state, version);
d->RestoringState = false;
if (!IsHidden)
{
show();
}
emit stateRestored();
Q_EMIT stateRestored();
return Result;
}
@@ -732,7 +746,7 @@ CFloatingDockContainer* CDockManager::addDockWidgetFloating(CDockWidget* Dockwid
{
d->UninitializedFloatingWidgets.append(FloatingWidget);
}
emit dockWidgetAdded(Dockwidget);
Q_EMIT dockWidgetAdded(Dockwidget);
return FloatingWidget;
}
@@ -759,8 +773,9 @@ CDockAreaWidget* CDockManager::addDockWidget(DockWidgetArea area,
CDockWidget* Dockwidget, CDockAreaWidget* DockAreaWidget)
{
d->DockWidgetsMap.insert(Dockwidget->objectName(), Dockwidget);
auto AreaOfAddedDockWidget = CDockContainerWidget::addDockWidget(area, Dockwidget, DockAreaWidget);
emit dockWidgetAdded(Dockwidget);
auto Container = DockAreaWidget ? DockAreaWidget->dockContainer(): this;
auto AreaOfAddedDockWidget = Container->addDockWidget(area, Dockwidget, DockAreaWidget);
Q_EMIT dockWidgetAdded(Dockwidget);
return AreaOfAddedDockWidget;
}
@@ -802,11 +817,11 @@ CDockWidget* CDockManager::findDockWidget(const QString& ObjectName) const
//============================================================================
void CDockManager::removeDockWidget(CDockWidget* Dockwidget)
{
emit dockWidgetAboutToBeRemoved(Dockwidget);
Q_EMIT dockWidgetAboutToBeRemoved(Dockwidget);
d->DockWidgetsMap.remove(Dockwidget->objectName());
CDockContainerWidget::removeDockWidget(Dockwidget);
Dockwidget->setDockManager(nullptr);
emit dockWidgetRemoved(Dockwidget);
Q_EMIT dockWidgetRemoved(Dockwidget);
}
//============================================================================
@@ -820,7 +835,7 @@ QMap<QString, CDockWidget*> CDockManager::dockWidgetsMap() const
void CDockManager::addPerspective(const QString& UniquePrespectiveName)
{
d->Perspectives.insert(UniquePrespectiveName, saveState());
emit perspectiveListChanged();
Q_EMIT perspectiveListChanged();
}
@@ -842,8 +857,8 @@ void CDockManager::removePerspectives(const QStringList& Names)
if (Count)
{
emit perspectivesRemoved();
emit perspectiveListChanged();
Q_EMIT perspectivesRemoved();
Q_EMIT perspectiveListChanged();
}
}
@@ -864,9 +879,9 @@ void CDockManager::openPerspective(const QString& PerspectiveName)
return;
}
emit openingPerspective(PerspectiveName);
Q_EMIT openingPerspective(PerspectiveName);
restoreState(Iterator.value());
emit perspectiveOpened(PerspectiveName);
Q_EMIT perspectiveOpened(PerspectiveName);
}
@@ -911,6 +926,8 @@ void CDockManager::loadPerspectives(QSettings& Settings)
}
Settings.endArray();
Q_EMIT perspectiveListChanged();
Q_EMIT perspectiveListLoaded();
}

View File

@@ -506,7 +506,7 @@ public:
*/
void setSplitterSizes(CDockAreaWidget *ContainedArea, const QList<int>& sizes);
public slots:
public Q_SLOTS:
/**
* Opens the perspective with the given name.
*/
@@ -519,12 +519,19 @@ public slots:
*/
void setDockWidgetFocused(CDockWidget* DockWidget);
signals:
Q_SIGNALS:
/**
* This signal is emitted if the list of perspectives changed
* This signal is emitted if the list of perspectives changed.
* The list of perspectives changes if perspectives are added, removed
* or if the perspective list has been loaded
*/
void perspectiveListChanged();
/**
* This signal is emitted if the perspective list has been loaded
*/
void perspectiveListLoaded();
/**
* This signal is emitted if perspectives have been removed
*/

View File

@@ -806,10 +806,15 @@ void CDockOverlayCross::setIconColors(const QString& Colors)
{"Arrow", CDockOverlayCross::ArrowColor},
{"Shadow", CDockOverlayCross::ShadowColor}};
auto ColorList = Colors.split(' ', QString::SkipEmptyParts);
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
auto SkipEmptyParts = QString::SkipEmptyParts;
#else
auto SkipEmptyParts = Qt::SkipEmptyParts;
#endif
auto ColorList = Colors.split(' ', SkipEmptyParts);
for (const auto& ColorListEntry : ColorList)
{
auto ComponentColor = ColorListEntry.split('=', QString::SkipEmptyParts);
auto ComponentColor = ColorListEntry.split('=', SkipEmptyParts);
int Component = ColorCompenentStringMap.value(ComponentColor[0], -1);
if (Component < 0)
{

View File

@@ -31,7 +31,7 @@
#include <QDebug>
#include <QChildEvent>
#include <QVariant>
#include "DockAreaWidget.h"
namespace ads
@@ -52,7 +52,7 @@ CDockSplitter::CDockSplitter(QWidget *parent)
: QSplitter(parent),
d(new DockSplitterPrivate(this))
{
setProperty("ads-splitter", true);
setProperty("ads-splitter", QVariant(true));
setChildrenCollapsible(false);
}

View File

@@ -338,7 +338,7 @@ void CDockWidget::setFeatures(DockWidgetFeatures features)
return;
}
d->Features = features;
emit featuresChanged(d->Features);
Q_EMIT featuresChanged(d->Features);
d->TabWidget->onDockWidgetFeaturesChanged();
if(CDockAreaWidget* DockArea = dockAreaWidget())
DockArea->onDockWidgetFeaturesChanged();
@@ -538,9 +538,9 @@ void CDockWidget::toggleViewInternal(bool Open)
if (!Open)
{
emit closed();
Q_EMIT closed();
}
emit viewToggled(Open);
Q_EMIT viewToggled(Open);
}
@@ -580,11 +580,11 @@ bool CDockWidget::event(QEvent *e)
switch (e->type())
{
case QEvent::Hide:
emit visibilityChanged(false);
Q_EMIT visibilityChanged(false);
break;
case QEvent::Show:
emit visibilityChanged(geometry().right() >= 0 && geometry().bottom() >= 0);
Q_EMIT visibilityChanged(geometry().right() >= 0 && geometry().bottom() >= 0);
break;
case QEvent::WindowTitleChange :
@@ -602,7 +602,7 @@ bool CDockWidget::event(QEvent *e)
{
d->DockArea->markTitleBarMenuOutdated();//update tabs menu
}
emit titleChanged(title);
Q_EMIT titleChanged(title);
}
break;
@@ -785,7 +785,7 @@ void CDockWidget::emitTopLevelChanged(bool Floating)
if (Floating != d->IsFloatingTopLevel)
{
d->IsFloatingTopLevel = Floating;
emit topLevelChanged(d->IsFloatingTopLevel);
Q_EMIT topLevelChanged(d->IsFloatingTopLevel);
}
}
@@ -843,7 +843,7 @@ bool CDockWidget::closeDockWidgetInternal(bool ForceClose)
{
if (!ForceClose)
{
emit closeRequested();
Q_EMIT closeRequested();
}
if (!ForceClose && features().testFlag(CDockWidget::CustomCloseHandling))
@@ -869,7 +869,7 @@ bool CDockWidget::closeDockWidgetInternal(bool ForceClose)
}
}
deleteDockWidget();
emit closed();
Q_EMIT closed();
}
else
{

View File

@@ -58,7 +58,7 @@ private:
DockWidgetPrivate* d; ///< private data (pimpl)
friend struct DockWidgetPrivate;
private slots:
private Q_SLOTS:
/**
* Adjusts the toolbar icon sizes according to the floating state
*/
@@ -154,6 +154,7 @@ public:
CustomCloseHandling = 0x10, ///< clicking the close button will not close the dock widget but emits the closeRequested() signal instead
DockWidgetFocusable = 0x20, ///< if this is enabled, a dock widget can get focus highlighting
DockWidgetForceCloseWithArea = 0x40, ///< dock widget will be closed when the dock area hosting it is closed
NoTab = 0x80, ///< dock widget tab will never be shown if this flag is set
DefaultDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable | DockWidgetFocusable,
AllDockWidgetFeatures = DefaultDockWidgetFeatures | DockWidgetDeleteOnClose | CustomCloseHandling,
DockWidgetAlwaysCloseAndDelete = DockWidgetForceCloseWithArea | DockWidgetDeleteOnClose,
@@ -483,7 +484,7 @@ public: // reimplements QFrame -----------------------------------------------
*/
virtual bool event(QEvent *e) override;
public slots:
public Q_SLOTS:
/**
* This property controls whether the dock widget is open or closed.
* The toogleViewAction triggers this slot
@@ -544,7 +545,7 @@ public slots:
void showNormal();
signals:
Q_SIGNALS:
/**
* This signal is emitted if the dock widget is opened or closed
*/

View File

@@ -259,7 +259,7 @@ void DockWidgetTabPrivate::createLayout()
void DockWidgetTabPrivate::moveTab(QMouseEvent* ev)
{
ev->accept();
QPoint Distance = ev->globalPos() - GlobalDragStartMousePosition;
QPoint Distance = internal::globalPositionOf(ev) - GlobalDragStartMousePosition;
Distance.setY(0);
auto TargetPos = Distance + TabDragStartPosition;
TargetPos.rx() = qMax(TargetPos.x(), 0);
@@ -351,9 +351,9 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev)
if (ev->button() == Qt::LeftButton)
{
ev->accept();
d->saveDragStartMousePosition(ev->globalPos());
d->saveDragStartMousePosition(internal::globalPositionOf(ev));
d->DragState = DraggingMousePressed;
emit clicked();
Q_EMIT clicked();
return;
}
Super::mousePressEvent(ev);
@@ -377,7 +377,7 @@ void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
// End of tab moving, emit signal
if (d->DockArea)
{
emit moved(ev->globalPos());
Q_EMIT moved(internal::globalPositionOf(ev));
}
break;
@@ -422,7 +422,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
auto MappedPos = mapToParent(ev->pos());
bool MouseOutsideBar = (MappedPos.x() < 0) || (MappedPos.x() > parentWidget()->rect().right());
// Maybe a fixed drag distance is better here ?
int DragDistanceY = qAbs(d->GlobalDragStartMousePosition.y() - ev->globalPos().y());
int DragDistanceY = qAbs(d->GlobalDragStartMousePosition.y() - internal::globalPositionOf(ev).y());
if (DragDistanceY >= CDockManager::startDragDistance() || MouseOutsideBar)
{
// If this is the last dock area in a dock container with only
@@ -454,7 +454,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
return;
}
else if (d->DockArea->openDockWidgetsCount() > 1
&& (ev->globalPos() - d->GlobalDragStartMousePosition).manhattanLength() >= QApplication::startDragDistance()) // Wait a few pixels before start moving
&& (internal::globalPositionOf(ev) - d->GlobalDragStartMousePosition).manhattanLength() >= QApplication::startDragDistance()) // Wait a few pixels before start moving
{
// If we start dragging the tab, we save its inital position to
// restore it later
@@ -538,7 +538,7 @@ void CDockWidgetTab::setActiveTab(bool active)
update();
updateGeometry();
emit activeTabChanged();
Q_EMIT activeTabChanged();
}
@@ -618,7 +618,7 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
if ((!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
&& d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{
d->saveDragStartMousePosition(event->globalPos());
d->saveDragStartMousePosition(internal::globalPositionOf(event));
d->startFloating(DraggingInactive);
}
@@ -629,7 +629,7 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
//============================================================================
void CDockWidgetTab::setVisible(bool visible)
{
// Just here for debugging to insert debug output
visible &= !d->DockWidget->features().testFlag(CDockWidget::NoTab);
Super::setVisible(visible);
}
@@ -677,6 +677,9 @@ bool CDockWidgetTab::event(QEvent *e)
{
const auto text = toolTip();
d->TitleLabel->setToolTip(text);
if (d->IconLabel) {
d->IconLabel->setToolTip(text);
}
}
#endif
return Super::event(e);

View File

@@ -60,7 +60,7 @@ private:
friend class CDockManager;
void onDockWidgetFeaturesChanged();
private slots:
private Q_SLOTS:
void detachDockWidget();
protected:
@@ -175,10 +175,10 @@ public:
*/
void setIconSize(const QSize& Size);
public slots:
public Q_SLOTS:
virtual void setVisible(bool visible) override;
signals:
Q_SIGNALS:
void activeTabChanged();
void clicked();
void closeRequested();

View File

@@ -74,7 +74,7 @@ void ElidingLabelPrivate::elideText(int Width)
IsElided = str != Text;
if(IsElided != WasElided)
{
emit _this->elidedChanged(IsElided);
Q_EMIT _this->elidedChanged(IsElided);
}
_this->QLabel::setText(str);
}
@@ -136,7 +136,7 @@ void CElidingLabel::mouseReleaseEvent(QMouseEvent* event)
return;
}
emit clicked();
Q_EMIT clicked();
}
@@ -144,7 +144,7 @@ void CElidingLabel::mouseReleaseEvent(QMouseEvent* event)
void CElidingLabel::mouseDoubleClickEvent( QMouseEvent *ev )
{
Q_UNUSED(ev)
emit doubleClicked();
Q_EMIT doubleClicked();
Super::mouseDoubleClickEvent(ev);
}
@@ -163,7 +163,12 @@ void CElidingLabel::resizeEvent(QResizeEvent *event)
//============================================================================
QSize CElidingLabel::minimumSizeHint() const
{
if (pixmap() != nullptr || d->isModeElideNone())
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
bool HasPixmap = !pixmap().isNull();
#else
bool HasPixmap = (pixmap() != nullptr);
#endif
if (HasPixmap || d->isModeElideNone())
{
return QLabel::minimumSizeHint();
}
@@ -180,7 +185,12 @@ QSize CElidingLabel::minimumSizeHint() const
//============================================================================
QSize CElidingLabel::sizeHint() const
{
if (pixmap() != nullptr || d->isModeElideNone())
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
bool HasPixmap = !pixmap().isNull();
#else
bool HasPixmap = (pixmap() != nullptr);
#endif
if (HasPixmap || d->isModeElideNone())
{
return QLabel::sizeHint();
}

View File

@@ -58,8 +58,8 @@ protected:
public:
using Super = QLabel;
CElidingLabel(QWidget* parent = 0, Qt::WindowFlags f = 0);
CElidingLabel(const QString& text, QWidget* parent = 0, Qt::WindowFlags f = 0);
CElidingLabel(QWidget* parent = 0, Qt::WindowFlags f = Qt::WindowFlags ());
CElidingLabel(const QString& text, QWidget* parent = 0, Qt::WindowFlags f = Qt::WindowFlags ());
virtual ~CElidingLabel();
/**
@@ -84,7 +84,7 @@ public: // reimplements QLabel ----------------------------------------------
void setText(const QString &text);
QString text() const;
signals:
Q_SIGNALS:
/**
* This signal is emitted if the user clicks on the label (i.e. pressed
* down then released while the mouse cursor is inside the label)

View File

@@ -609,7 +609,8 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
#ifdef Q_OS_LINUX
QDockWidget::setWidget(d->DockContainer);
QDockWidget::setFloating(true);
QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
QDockWidget::setFeatures(QDockWidget::DockWidgetClosable
| QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
bool native_window = true;
@@ -733,8 +734,11 @@ void CFloatingDockContainer::changeEvent(QEvent *event)
#ifdef Q_OS_WIN
//============================================================================
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
bool CFloatingDockContainer::nativeEvent(const QByteArray &eventType, void *message, long *result)
#else
bool CFloatingDockContainer::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
#endif
{
QWidget::nativeEvent(eventType, message, result);
MSG *msg = static_cast<MSG*>(message);

View File

@@ -118,7 +118,7 @@ private:
friend class CDockAreaWidget;
friend class CFloatingWidgetTitleBar;
private slots:
private Q_SLOTS:
void onDockAreasAddedOrRemoved();
void onDockAreaCurrentChanged(int Index);
@@ -194,7 +194,11 @@ protected: // reimplements QWidget
/**
* Native event filter for handling WM_MOVING messages on Windows
*/
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
#else
virtual bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
#endif
#endif

View File

@@ -60,7 +60,7 @@ struct FloatingDragPreviewPrivate
void cancelDragging()
{
Canceled = true;
emit _this->draggingCanceled();
Q_EMIT _this->draggingCanceled();
DockManager->containerOverlay()->hideOverlay();
DockManager->dockAreaOverlay()->hideOverlay();
_this->close();

View File

@@ -32,7 +32,7 @@ private:
FloatingDragPreviewPrivate* d;
friend struct FloatingDragPreviewPrivate;
private slots:
private Q_SLOTS:
/**
* Cancel non opaque undocking if application becomes inactive
*/
@@ -92,7 +92,7 @@ public: // implements IFloatingWidget -----------------------------------------
*/
virtual void finishDragging() override;
signals:
Q_SIGNALS:
/**
* This signal is emitted, if dragging has been canceled by escape key
* or by active application switching via task manager

View File

@@ -36,6 +36,7 @@
#include <QWidget>
#include <QDebug>
#include <QStyle>
#include <QMouseEvent>
#ifdef Q_OS_LINUX
#include <xcb/xcb.h>
@@ -179,7 +180,7 @@ void hideEmptyParentSplitters(CDockSplitter* FirstParentSplitter);
class CDockInsertParam : public QPair<Qt::Orientation, bool>
{
public:
using QPair::QPair;
using QPair<Qt::Orientation, bool>::QPair;
Qt::Orientation orientation() const {return this->first;}
bool append() const {return this->second;}
int insertOffset() const {return append() ? 1 : 0;}
@@ -260,6 +261,19 @@ void setToolTip(QObjectPtr obj, const QString &tip)
}
/**
* Helper function for access to mouse event global position in Qt5 and
*/
inline QPoint globalPositionOf(QMouseEvent* ev)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return ev->globalPosition().toPoint();
#else
return ev->globalPos();
#endif
}
/**
* Helper function to set the icon of a certain button.
* Use this function to set the icons for the dock area and dock widget buttons.

View File

@@ -23,7 +23,8 @@ windows {
}
# MSVC
*-msvc* {
}
QMAKE_CXXFLAGS += /utf-8
}
}
RESOURCES += ads.qrc