Compare commits
44 Commits
python6
...
python-bui
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e7a2110b1 | ||
|
|
243146fe49 | ||
|
|
370d139dfc | ||
|
|
c4e7db34a4 | ||
|
|
a4f6b72157 | ||
|
|
de3ca6dba5 | ||
|
|
bdfcfdd0fe | ||
|
|
dbf357ce66 | ||
|
|
e950cf7fc3 | ||
|
|
8dfad1c910 | ||
|
|
107d4e973c | ||
|
|
e33766a4fa | ||
|
|
6a550c6c4a | ||
|
|
a0fc2a8ce7 | ||
|
|
ab257b3468 | ||
|
|
e6bdb28484 | ||
|
|
c52446f3b0 | ||
|
|
9cadfb26d9 | ||
|
|
7d5ea8f908 | ||
|
|
161b33370e | ||
|
|
8dd7a90b34 | ||
|
|
7ff865a36f | ||
|
|
d0b8ee606a | ||
|
|
c6c3b16fd2 | ||
|
|
64a6cbb2e4 | ||
|
|
e1cf532437 | ||
|
|
67f2127710 | ||
|
|
9111b424a1 | ||
|
|
772b51216f | ||
|
|
a79a2f5ecb | ||
|
|
585c0d64ed | ||
|
|
7ddb95a417 | ||
|
|
02648eb54e | ||
|
|
54a1050fbb | ||
|
|
f997b2d2f0 | ||
|
|
8f61e57b57 | ||
|
|
cfcff6f2d7 | ||
|
|
44d7cc0588 | ||
|
|
c91275d091 | ||
|
|
69c88919c0 | ||
|
|
e0e6f55868 | ||
|
|
7698584ee0 | ||
|
|
d034722ba9 | ||
|
|
e1e07c95ba |
68
.vscode/launch.json
vendored
68
.vscode/launch.json
vendored
@@ -1,68 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "(gdb) QtWidgets example",
|
|
||||||
"type": "cppdbg",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceFolder}/build/bin/kddockwidgets_example",
|
|
||||||
"args": [],
|
|
||||||
"stopAtEntry": false,
|
|
||||||
"cwd": "${workspaceFolder}",
|
|
||||||
"environment": [],
|
|
||||||
"externalConsole": false,
|
|
||||||
"MIMode": "gdb",
|
|
||||||
"setupCommands": [
|
|
||||||
{
|
|
||||||
"description": "Enable pretty-printing for gdb",
|
|
||||||
"text": "-enable-pretty-printing",
|
|
||||||
"ignoreFailures": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "(gdb) QtQuick example",
|
|
||||||
"type": "cppdbg",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceFolder}/build/bin/kddockwidgets_example_quick",
|
|
||||||
"args": [],
|
|
||||||
"stopAtEntry": false,
|
|
||||||
"cwd": "${workspaceFolder}",
|
|
||||||
"environment": [],
|
|
||||||
"externalConsole": false,
|
|
||||||
"MIMode": "gdb",
|
|
||||||
"setupCommands": [
|
|
||||||
{
|
|
||||||
"description": "Enable pretty-printing for gdb",
|
|
||||||
"text": "-enable-pretty-printing",
|
|
||||||
"ignoreFailures": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "(vs) kddockwidgets_example",
|
|
||||||
"type": "cppvsdbg",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceFolder}/build/bin/kddockwidgets_example.exe",
|
|
||||||
"args": [],
|
|
||||||
"stopAtEntry": false,
|
|
||||||
"cwd": "${workspaceFolder}",
|
|
||||||
"environment": [],
|
|
||||||
"externalConsole": false,
|
|
||||||
"sourceFileMap" : {
|
|
||||||
"C:\\Users\\qt\\work\\qt\\qtbase\\src" : "D:\\Qt\\5.14.2\\Src\\qtbase\\src"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "(vs) tst_docks",
|
|
||||||
"type": "cppvsdbg",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceFolder}/build/bin/tst_docks.exe",
|
|
||||||
"args": ["tst_moreTitleBarCornerCases", "-platform", "windows"],
|
|
||||||
"stopAtEntry": false,
|
|
||||||
"cwd": "${workspaceFolder}",
|
|
||||||
"environment": [],
|
|
||||||
"externalConsole": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools",
|
|
||||||
"files.associations": {
|
|
||||||
"qevent": "cpp"
|
|
||||||
},
|
|
||||||
"cmake.configureSettings": {
|
|
||||||
"KDDockWidgets_DEVELOPER_MODE" : "ON",
|
|
||||||
"KDDockWidgets_QTQUICK" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,9 @@
|
|||||||
"cacheVariables": {
|
"cacheVariables": {
|
||||||
"CMAKE_BUILD_TYPE": "Debug",
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'"
|
"ECM_ENABLE_SANITIZERS" : "'address;undefined'",
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||||
|
"KDDockWidgets_UNITY_BUILD" : "OFF"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -53,7 +55,9 @@
|
|||||||
"CMAKE_BUILD_TYPE": "Debug",
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
"KDDockWidgets_QTQUICK": "ON",
|
"KDDockWidgets_QTQUICK": "ON",
|
||||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'"
|
"ECM_ENABLE_SANITIZERS" : "'address;undefined'",
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||||
|
"KDDockWidgets_UNITY_BUILD" : "OFF"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -109,6 +113,8 @@
|
|||||||
"CMAKE_BUILD_TYPE": "Debug",
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
"KDDockWidgets_QT6": "ON",
|
"KDDockWidgets_QT6": "ON",
|
||||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||||
|
"KDDockWidgets_UNITY_BUILD" : "OFF",
|
||||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'"
|
"ECM_ENABLE_SANITIZERS" : "'address;undefined'"
|
||||||
},
|
},
|
||||||
"environment": {
|
"environment": {
|
||||||
|
|||||||
@@ -4,9 +4,16 @@
|
|||||||
- The enum KDDockWidgets::AddingOption has been deprecated, use
|
- The enum KDDockWidgets::AddingOption has been deprecated, use
|
||||||
KDDockWidgets::InitialVisibilityOption instead
|
KDDockWidgets::InitialVisibilityOption instead
|
||||||
- You can now pass a preferred initial size to MainWindow::addDockWidget() (#95)
|
- You can now pass a preferred initial size to MainWindow::addDockWidget() (#95)
|
||||||
|
- Added DockWidgetBase::Option_DeleteOnClose
|
||||||
|
- Added Config::Flag_CloseOnlyCurrentTab
|
||||||
|
- PySide6 support
|
||||||
|
- Layout restorer now restores maximzied/minimized state too (#81)
|
||||||
|
- Fixed dock indicators sometimes not appearing on Windows (#103)
|
||||||
|
- Fixed Flag_NativeTitleBar not working
|
||||||
|
|
||||||
* v1.2.1 (unreleased)
|
* v1.2.1 (unreleased)
|
||||||
- Support for resizing dock widgets when they are in overlay/popup mode (autohide/sidebar feature)
|
- Support for resizing dock widgets when they are in overlay/popup mode (autohide/sidebar feature)
|
||||||
|
- Fixed title bar close button enabled state not being restored with Layout saver (#137)
|
||||||
|
|
||||||
* v1.2.0 (17 December 2020)
|
* v1.2.0 (17 December 2020)
|
||||||
- Wayland support
|
- Wayland support
|
||||||
|
|||||||
42
dev-qtquick.code-workspace
Normal file
42
dev-qtquick.code-workspace
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"C_Cpp.default.compileCommands": "${workspaceFolder}/build-dev-qtquick/compile_commands.json",
|
||||||
|
"C_Cpp.default.cStandard": "c17",
|
||||||
|
"files.trimTrailingWhitespace": true
|
||||||
|
},
|
||||||
|
"tasks": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "cmake",
|
||||||
|
"command": "cmake",
|
||||||
|
"args": [
|
||||||
|
"--preset=dev-qtquick"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/"
|
||||||
|
},
|
||||||
|
"group": "build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "make",
|
||||||
|
"command": "cmake",
|
||||||
|
"args": [
|
||||||
|
"--build",
|
||||||
|
"${workspaceFolder}/build-dev-qtquick"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/"
|
||||||
|
},
|
||||||
|
"group": "build"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
42
dev-qtwidgets.code-workspace
Normal file
42
dev-qtwidgets.code-workspace
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"C_Cpp.default.compileCommands": "${workspaceFolder}/build-dev-qtwidgets/compile_commands.json",
|
||||||
|
"C_Cpp.default.cStandard": "c17",
|
||||||
|
"files.trimTrailingWhitespace": true
|
||||||
|
},
|
||||||
|
"tasks": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "cmake",
|
||||||
|
"command": "cmake",
|
||||||
|
"args": [
|
||||||
|
"--preset=dev-qtwidgets"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/"
|
||||||
|
},
|
||||||
|
"group": "build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "make",
|
||||||
|
"command": "cmake",
|
||||||
|
"args": [
|
||||||
|
"--build",
|
||||||
|
"${workspaceFolder}/build-dev-qtwidgets"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/"
|
||||||
|
},
|
||||||
|
"group": "build"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
48
dev-qtwidgets6.code-workspace
Normal file
48
dev-qtwidgets6.code-workspace
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"C_Cpp.default.compileCommands": "${workspaceFolder}/build-dev-qtwidgets6/compile_commands.json",
|
||||||
|
"C_Cpp.default.cStandard": "c17",
|
||||||
|
"files.trimTrailingWhitespace": true
|
||||||
|
},
|
||||||
|
"tasks": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "cmake",
|
||||||
|
"command": "cmake",
|
||||||
|
"args": [
|
||||||
|
"--preset=dev-qtwidgets6"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/"
|
||||||
|
},
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "make",
|
||||||
|
"command": "cmake",
|
||||||
|
"args": [
|
||||||
|
"--build",
|
||||||
|
"${workspaceFolder}/build-dev-qtwidgets6"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/"
|
||||||
|
},
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of KDDockWidgets.
|
|
||||||
|
|
||||||
SPDX-FileCopyrightText: 2020-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
|
||||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
|
||||||
|
|
||||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is an helper script which simply reads CMakePresets.json and builds those
|
|
||||||
* presets. It's just for quickly checking that every supported setup builds
|
|
||||||
* without having to wait for CI (or in case you don't have access to KDAB CI)
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* $ dart build-all.dart <kddw-source-directory> [--unity] [--tests]
|
|
||||||
*/
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
String s_sourceDirectory = "";
|
|
||||||
bool s_testUnityVariations = false;
|
|
||||||
bool s_runTests = true;
|
|
||||||
|
|
||||||
class Preset {
|
|
||||||
final String name;
|
|
||||||
final String buildDir;
|
|
||||||
Preset.fromJson(var jsonData)
|
|
||||||
: name = jsonData['name'],
|
|
||||||
buildDir = jsonData['binaryDir'] {
|
|
||||||
}
|
|
||||||
|
|
||||||
String buildDirectory() {
|
|
||||||
return buildDir.replaceAll("\${sourceDir}", s_sourceDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> cmakeConfigArguments(bool isUnityBuild) {
|
|
||||||
return [
|
|
||||||
"-G",
|
|
||||||
"Ninja",
|
|
||||||
"-B",
|
|
||||||
buildDirectory(),
|
|
||||||
"-S",
|
|
||||||
s_sourceDirectory,
|
|
||||||
"--preset=" + name,
|
|
||||||
'-DKDDockWidgets_UNITY_BUILD=${isUnityBuild ? "ON" : "OFF"}'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> cmakeBuildArguments() {
|
|
||||||
return ["--build", buildDirectory()];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds twice. One with unity build and one without.
|
|
||||||
Future<bool> build() async {
|
|
||||||
if (!await buildSingle(true)) return false;
|
|
||||||
if (s_testUnityVariations) if (!await buildSingle(false)) return false;
|
|
||||||
if (s_runTests && !await runTests()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> buildSingle(bool isUnityBuild) async {
|
|
||||||
if (!await runCMake(cmakeConfigArguments(isUnityBuild))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await runCMake(cmakeBuildArguments())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> runTests() async {
|
|
||||||
print("Running: ctest");
|
|
||||||
|
|
||||||
final savedCwd = Directory.current;
|
|
||||||
Directory.current = buildDirectory();
|
|
||||||
ProcessResult result = await Process.run('ctest', ["-j8"]);
|
|
||||||
Directory.current = savedCwd;
|
|
||||||
|
|
||||||
if (result.exitCode != 0) {
|
|
||||||
print(result.stdout);
|
|
||||||
print(result.stderr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the contents of the CMakePresets.json file
|
|
||||||
String cmakePresetsJson(presetsFile) {
|
|
||||||
var file = File(presetsFile);
|
|
||||||
if (!file.existsSync()) {
|
|
||||||
throw Exception('Not existent file');
|
|
||||||
}
|
|
||||||
return file.readAsStringSync();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Preset> readPresets(var presetsFile) {
|
|
||||||
var presets = List<Preset>();
|
|
||||||
|
|
||||||
final jsonData = jsonDecode(cmakePresetsJson(presetsFile));
|
|
||||||
for (var presetData in jsonData['configurePresets']) {
|
|
||||||
presets.add(Preset.fromJson(presetData));
|
|
||||||
}
|
|
||||||
return presets;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> runCMake(var cmd) async {
|
|
||||||
print("Running: cmake " + cmd.join(' '));
|
|
||||||
ProcessResult result = await Process.run('cmake', cmd);
|
|
||||||
if (result.exitCode != 0) {
|
|
||||||
print(result.stdout);
|
|
||||||
print(result.stderr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> main(List<String> arguments) async {
|
|
||||||
if (arguments.length == 0) {
|
|
||||||
print("Usage: build-all.dart <src-directory> [--unity] [--tests]");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
s_sourceDirectory = arguments[0];
|
|
||||||
s_testUnityVariations = arguments.contains("--unity");
|
|
||||||
s_runTests = arguments.contains("--tests");
|
|
||||||
final presetsFile = s_sourceDirectory + '/CMakePresets.json';
|
|
||||||
|
|
||||||
if (FileSystemEntity.typeSync(presetsFile) == FileSystemEntityType.notFound) {
|
|
||||||
print('ERROR: CMakePresets.json file not found in the source directory');
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var presets = readPresets(presetsFile);
|
|
||||||
for (var preset in presets) {
|
|
||||||
if (preset.name == 'python')
|
|
||||||
continue; // TODO: blacklisted as it's not building on my setup yet
|
|
||||||
|
|
||||||
if (!await preset.build()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Success!!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -52,13 +52,14 @@ static MyWidget *newMyWidget()
|
|||||||
|
|
||||||
MyMainWindow::MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
|
MyMainWindow::MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
|
||||||
bool dockWidget0IsNonClosable, bool nonDockableDockWidget9, bool restoreIsRelative,
|
bool dockWidget0IsNonClosable, bool nonDockableDockWidget9, bool restoreIsRelative,
|
||||||
bool maxSizeForDockWidget8,
|
bool maxSizeForDockWidget8, bool dockwidget5DoesntCloseBeforeRestore,
|
||||||
const QString &affinityName, QWidget *parent)
|
const QString &affinityName, QWidget *parent)
|
||||||
: MainWindow(uniqueName, options, parent)
|
: MainWindow(uniqueName, options, parent)
|
||||||
, m_dockWidget0IsNonClosable(dockWidget0IsNonClosable)
|
, m_dockWidget0IsNonClosable(dockWidget0IsNonClosable)
|
||||||
, m_dockWidget9IsNonDockable(nonDockableDockWidget9)
|
, m_dockWidget9IsNonDockable(nonDockableDockWidget9)
|
||||||
, m_restoreIsRelative(restoreIsRelative)
|
, m_restoreIsRelative(restoreIsRelative)
|
||||||
, m_maxSizeForDockWidget8(maxSizeForDockWidget8)
|
, m_maxSizeForDockWidget8(maxSizeForDockWidget8)
|
||||||
|
, m_dockwidget5DoesntCloseBeforeRestore(dockwidget5DoesntCloseBeforeRestore)
|
||||||
{
|
{
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||||
qsrand(time(nullptr));
|
qsrand(time(nullptr));
|
||||||
@@ -164,13 +165,18 @@ KDDockWidgets::DockWidgetBase *MyMainWindow::newDockWidget()
|
|||||||
|
|
||||||
// Passing options is optional, we just want to illustrate Option_NotClosable here
|
// Passing options is optional, we just want to illustrate Option_NotClosable here
|
||||||
KDDockWidgets::DockWidget::Options options = KDDockWidgets::DockWidget::Option_None;
|
KDDockWidgets::DockWidget::Options options = KDDockWidgets::DockWidget::Option_None;
|
||||||
|
KDDockWidgets::DockWidget::LayoutSaverOptions layoutSaverOptions = KDDockWidgets::DockWidget::LayoutSaverOption::None;
|
||||||
|
|
||||||
if (count == 0 && m_dockWidget0IsNonClosable)
|
if (count == 0 && m_dockWidget0IsNonClosable)
|
||||||
options |= KDDockWidgets::DockWidget::Option_NotClosable;
|
options |= KDDockWidgets::DockWidget::Option_NotClosable;
|
||||||
|
|
||||||
if (count == 9 && m_dockWidget9IsNonDockable)
|
if (count == 9 && m_dockWidget9IsNonDockable)
|
||||||
options |= KDDockWidgets::DockWidget::Option_NotDockable;
|
options |= KDDockWidgets::DockWidget::Option_NotDockable;
|
||||||
|
|
||||||
auto dock = new KDDockWidgets::DockWidget(QStringLiteral("DockWidget #%1").arg(count), options);
|
if (count == 5 && m_dockwidget5DoesntCloseBeforeRestore)
|
||||||
|
layoutSaverOptions |= KDDockWidgets::DockWidget::LayoutSaverOption::Skip;
|
||||||
|
|
||||||
|
auto dock = new KDDockWidgets::DockWidget(QStringLiteral("DockWidget #%1").arg(count), options, layoutSaverOptions);
|
||||||
dock->setAffinities(affinities()); // optional, just to show the feature. Pass -mi to the example to see incompatible dock widgets
|
dock->setAffinities(affinities()); // optional, just to show the feature. Pass -mi to the example to see incompatible dock widgets
|
||||||
|
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class MyMainWindow : public KDDockWidgets::MainWindow
|
|||||||
public:
|
public:
|
||||||
explicit MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
|
explicit MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
|
||||||
bool dockWidget0IsNonClosable, bool nonDockableDockWidget9, bool restoreIsRelative,
|
bool dockWidget0IsNonClosable, bool nonDockableDockWidget9, bool restoreIsRelative,
|
||||||
bool maxSizeForDockWidget8,
|
bool maxSizeForDockWidget8, bool dockwidget5DoesntCloseBeforeRestore,
|
||||||
const QString &affinityName = {}, // Usually not needed. Just here to show the feature.
|
const QString &affinityName = {}, // Usually not needed. Just here to show the feature.
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
~MyMainWindow() override;
|
~MyMainWindow() override;
|
||||||
@@ -33,5 +33,6 @@ private:
|
|||||||
const bool m_dockWidget9IsNonDockable;
|
const bool m_dockWidget9IsNonDockable;
|
||||||
const bool m_restoreIsRelative;
|
const bool m_restoreIsRelative;
|
||||||
const bool m_maxSizeForDockWidget8;
|
const bool m_maxSizeForDockWidget8;
|
||||||
|
const bool m_dockwidget5DoesntCloseBeforeRestore;
|
||||||
KDDockWidgets::DockWidget::List m_dockwidgets;
|
KDDockWidgets::DockWidget::List m_dockwidgets;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,6 +111,14 @@ int main(int argc, char **argv)
|
|||||||
QCommandLineOption autoHideSupport("w", QCoreApplication::translate("main", "Enables auto-hide/minimization to side-bar support"));
|
QCommandLineOption autoHideSupport("w", QCoreApplication::translate("main", "Enables auto-hide/minimization to side-bar support"));
|
||||||
parser.addOption(autoHideSupport);
|
parser.addOption(autoHideSupport);
|
||||||
|
|
||||||
|
QCommandLineOption closeOnlyCurrentTab("close-only-current-tab",
|
||||||
|
QCoreApplication::translate("main", "The title bar's close button will only close the current tab instead of all. Illustrates using Config::Flag_CloseOnlyCurrentTab"));
|
||||||
|
parser.addOption(closeOnlyCurrentTab);
|
||||||
|
|
||||||
|
QCommandLineOption dontCloseBeforeRestore("dont-close-widget-before-restore",
|
||||||
|
QCoreApplication::translate("main", "DockWidget #5 wont be closed before a restore. Illustrates LayoutSaverOption::DontCloseBeforeRestore"));
|
||||||
|
parser.addOption(dontCloseBeforeRestore);
|
||||||
|
|
||||||
#if defined(DOCKS_DEVELOPER_MODE)
|
#if defined(DOCKS_DEVELOPER_MODE)
|
||||||
parser.addOption(centralFrame);
|
parser.addOption(centralFrame);
|
||||||
|
|
||||||
@@ -177,6 +185,9 @@ int main(int argc, char **argv)
|
|||||||
if (parser.isSet(autoHideSupport))
|
if (parser.isSet(autoHideSupport))
|
||||||
flags |= Config::Flag_AutoHideSupport;
|
flags |= Config::Flag_AutoHideSupport;
|
||||||
|
|
||||||
|
if (parser.isSet(closeOnlyCurrentTab))
|
||||||
|
flags |= Config::Flag_CloseOnlyCurrentTab;
|
||||||
|
|
||||||
if (parser.isSet(noTitleBars))
|
if (parser.isSet(noTitleBars))
|
||||||
flags |= KDDockWidgets::Config::Flag_HideTitleBarWhenTabsVisible;
|
flags |= KDDockWidgets::Config::Flag_HideTitleBarWhenTabsVisible;
|
||||||
|
|
||||||
@@ -227,6 +238,7 @@ int main(int argc, char **argv)
|
|||||||
const bool restoreIsRelative = parser.isSet(relativeRestore);
|
const bool restoreIsRelative = parser.isSet(relativeRestore);
|
||||||
const bool nonDockableDockWidget9 = parser.isSet(nonDockable);
|
const bool nonDockableDockWidget9 = parser.isSet(nonDockable);
|
||||||
const bool maxSizeForDockWidget8 = parser.isSet(maxSizeOption);
|
const bool maxSizeForDockWidget8 = parser.isSet(maxSizeOption);
|
||||||
|
const bool dontCloseDockWidget5BeforeRestore = parser.isSet(dontCloseBeforeRestore);
|
||||||
const bool usesMainWindowsWithAffinity = parser.isSet(multipleMainWindows);
|
const bool usesMainWindowsWithAffinity = parser.isSet(multipleMainWindows);
|
||||||
|
|
||||||
#ifdef KDDOCKWIDGETS_SUPPORTS_NESTED_MAINWINDOWS
|
#ifdef KDDOCKWIDGETS_SUPPORTS_NESTED_MAINWINDOWS
|
||||||
@@ -236,7 +248,8 @@ int main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
MyMainWindow mainWindow(QStringLiteral("MyMainWindow"), options, nonClosableDockWidget0,
|
MyMainWindow mainWindow(QStringLiteral("MyMainWindow"), options, nonClosableDockWidget0,
|
||||||
nonDockableDockWidget9, restoreIsRelative, maxSizeForDockWidget8);
|
nonDockableDockWidget9, restoreIsRelative, maxSizeForDockWidget8,
|
||||||
|
dontCloseDockWidget5BeforeRestore);
|
||||||
mainWindow.setWindowTitle("Main Window 1");
|
mainWindow.setWindowTitle("Main Window 1");
|
||||||
mainWindow.resize(1200, 1200);
|
mainWindow.resize(1200, 1200);
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
@@ -254,7 +267,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
auto mainWindow2 = new MyMainWindow(QStringLiteral("MyMainWindow-2"), options,
|
auto mainWindow2 = new MyMainWindow(QStringLiteral("MyMainWindow-2"), options,
|
||||||
nonClosableDockWidget0, nonDockableDockWidget9,
|
nonClosableDockWidget0, nonDockableDockWidget9,
|
||||||
restoreIsRelative, maxSizeForDockWidget8, affinity);
|
restoreIsRelative, maxSizeForDockWidget8,
|
||||||
|
dontCloseDockWidget5BeforeRestore, affinity);
|
||||||
if (affinity.isEmpty())
|
if (affinity.isEmpty())
|
||||||
mainWindow2->setWindowTitle("Main Window 2");
|
mainWindow2->setWindowTitle("Main Window 2");
|
||||||
else
|
else
|
||||||
@@ -267,7 +281,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
const QString affinity = QStringLiteral("Inner-DockWidgets-2");
|
const QString affinity = QStringLiteral("Inner-DockWidgets-2");
|
||||||
auto dockableMainWindow = new MyMainWindow(QStringLiteral("MyMainWindow-2"), options,
|
auto dockableMainWindow = new MyMainWindow(QStringLiteral("MyMainWindow-2"), options,
|
||||||
false, false, restoreIsRelative, false, affinity);
|
false, false, restoreIsRelative, false,
|
||||||
|
false, affinity);
|
||||||
|
|
||||||
dockableMainWindow->setAffinities({ affinity });
|
dockableMainWindow->setAffinities({ affinity });
|
||||||
|
|
||||||
|
|||||||
@@ -75,4 +75,4 @@ create_python_bindings(
|
|||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.cmake ${CMAKE_CURRENT_BINARY_DIR}/__init__.py @ONLY)
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.cmake ${CMAKE_CURRENT_BINARY_DIR}/__init__.py @ONLY)
|
||||||
|
|
||||||
# install
|
# install
|
||||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py DESTINATION ${${PROJECT_NAME}_PYTHON_BINDINGS_INSTALL_PREFIX}/PyKDDockWidgets)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/__init__.py DESTINATION ${${PROJECT_NAME}_PYTHON_BINDINGS_INSTALL_PREFIX}/PyKDDockWidgets)
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ public:
|
|||||||
Flag_AutoHideSupport = 0x8000 | Flag_TitleBarNoFloatButton, ///< Supports minimizing dock widgets to the side-bar.
|
Flag_AutoHideSupport = 0x8000 | Flag_TitleBarNoFloatButton, ///< Supports minimizing dock widgets to the side-bar.
|
||||||
///< By default it also turns off the float button, but you can remove Flag_TitleBarNoFloatButton to have both.
|
///< By default it also turns off the float button, but you can remove Flag_TitleBarNoFloatButton to have both.
|
||||||
Flag_KeepAboveIfNotUtilityWindow = 0x10000, ///< Only meaningful if Flag_DontUseUtilityFloatingWindows is set. If floating windows are normal windows, you might still want them to keep above and not minimize when you focus the main window.
|
Flag_KeepAboveIfNotUtilityWindow = 0x10000, ///< Only meaningful if Flag_DontUseUtilityFloatingWindows is set. If floating windows are normal windows, you might still want them to keep above and not minimize when you focus the main window.
|
||||||
|
Flag_CloseOnlyCurrentTab = 0x20000, ///< The TitleBar's close button will only close the current tab, instead of all of them
|
||||||
Flag_Default = Flag_AeroSnapWithClientDecos ///< The defaults
|
Flag_Default = Flag_AeroSnapWithClientDecos ///< The defaults
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(Flags, Flag)
|
Q_DECLARE_FLAGS(Flags, Flag)
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ public:
|
|||||||
* when visible, or stays without a parent when hidden. This allows to support docking
|
* when visible, or stays without a parent when hidden. This allows to support docking
|
||||||
* to different main windows.
|
* to different main windows.
|
||||||
*/
|
*/
|
||||||
explicit DockWidget(const QString &uniqueName, Options options = DockWidgetBase::Options());
|
explicit DockWidget(const QString &uniqueName, Options options = DockWidgetBase::Options(),
|
||||||
|
LayoutSaverOptions layoutSaverOptions = LayoutSaverOptions());
|
||||||
|
|
||||||
///@brief destructor
|
///@brief destructor
|
||||||
~DockWidget() override;
|
~DockWidget() override;
|
||||||
|
|||||||
@@ -40,11 +40,13 @@ using namespace KDDockWidgets;
|
|||||||
class DockWidgetBase::Private
|
class DockWidgetBase::Private
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Private(const QString &dockName, DockWidgetBase::Options options_, DockWidgetBase *qq)
|
Private(const QString &dockName, DockWidgetBase::Options options_,
|
||||||
|
LayoutSaverOptions layoutSaverOptions_, DockWidgetBase *qq)
|
||||||
: name(dockName)
|
: name(dockName)
|
||||||
, title(dockName)
|
, title(dockName)
|
||||||
, q(qq)
|
, q(qq)
|
||||||
, options(options_)
|
, options(options_)
|
||||||
|
, layoutSaverOptions(layoutSaverOptions_)
|
||||||
, toggleAction(new QAction(q))
|
, toggleAction(new QAction(q))
|
||||||
, floatAction(new QAction(q))
|
, floatAction(new QAction(q))
|
||||||
{
|
{
|
||||||
@@ -98,6 +100,11 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SideBar* sideBar() const
|
||||||
|
{
|
||||||
|
return DockRegistry::self()->sideBarForDockWidget(q);
|
||||||
|
}
|
||||||
|
|
||||||
QPoint defaultCenterPosForFloating();
|
QPoint defaultCenterPosForFloating();
|
||||||
|
|
||||||
void updateTitle();
|
void updateTitle();
|
||||||
@@ -126,6 +133,7 @@ public:
|
|||||||
QWidgetOrQuick *widget = nullptr;
|
QWidgetOrQuick *widget = nullptr;
|
||||||
DockWidgetBase *const q;
|
DockWidgetBase *const q;
|
||||||
DockWidgetBase::Options options;
|
DockWidgetBase::Options options;
|
||||||
|
const LayoutSaverOptions layoutSaverOptions;
|
||||||
QAction *const toggleAction;
|
QAction *const toggleAction;
|
||||||
QAction *const floatAction;
|
QAction *const floatAction;
|
||||||
LastPositions m_lastPositions;
|
LastPositions m_lastPositions;
|
||||||
@@ -135,9 +143,10 @@ public:
|
|||||||
QSize m_lastOverlayedSize = QSize(0, 0);
|
QSize m_lastOverlayedSize = QSize(0, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
DockWidgetBase::DockWidgetBase(const QString &name, Options options)
|
DockWidgetBase::DockWidgetBase(const QString &name, Options options,
|
||||||
|
LayoutSaverOptions layoutSaverOptions)
|
||||||
: QWidgetAdapter(nullptr, Qt::Tool)
|
: QWidgetAdapter(nullptr, Qt::Tool)
|
||||||
, d(new Private(name, options, this))
|
, d(new Private(name, options, layoutSaverOptions, this))
|
||||||
{
|
{
|
||||||
d->init();
|
d->init();
|
||||||
DockRegistry::self()->registerDockWidget(this);
|
DockRegistry::self()->registerDockWidget(this);
|
||||||
@@ -343,6 +352,11 @@ DockWidgetBase::Options DockWidgetBase::options() const
|
|||||||
return d->options;
|
return d->options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DockWidgetBase::LayoutSaverOptions DockWidgetBase::layoutSaverOptions() const
|
||||||
|
{
|
||||||
|
return d->layoutSaverOptions;
|
||||||
|
}
|
||||||
|
|
||||||
void DockWidgetBase::setOptions(Options options)
|
void DockWidgetBase::setOptions(Options options)
|
||||||
{
|
{
|
||||||
if ((d->options & Option_NotDockable) != (options & Option_NotDockable)) {
|
if ((d->options & Option_NotDockable) != (options & Option_NotDockable)) {
|
||||||
@@ -354,7 +368,7 @@ void DockWidgetBase::setOptions(Options options)
|
|||||||
d->options = options;
|
d->options = options;
|
||||||
Q_EMIT optionsChanged(options);
|
Q_EMIT optionsChanged(options);
|
||||||
if (auto tb = titleBar())
|
if (auto tb = titleBar())
|
||||||
tb->updateCloseButton();
|
tb->updateButtons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,6 +537,11 @@ SideBarLocation DockWidgetBase::sideBarLocation() const
|
|||||||
return DockRegistry::self()->sideBarLocationForDockWidget(this);
|
return DockRegistry::self()->sideBarLocationForDockWidget(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DockWidgetBase::isInSideBar() const
|
||||||
|
{
|
||||||
|
return sideBarLocation() != SideBarLocation::None;
|
||||||
|
}
|
||||||
|
|
||||||
bool DockWidgetBase::hasPreviousDockedLocation() const
|
bool DockWidgetBase::hasPreviousDockedLocation() const
|
||||||
{
|
{
|
||||||
return d->m_lastPositions.isValid();
|
return d->m_lastPositions.isValid();
|
||||||
@@ -538,6 +557,11 @@ DockWidgetBase *DockWidgetBase::byName(const QString &uniqueName)
|
|||||||
return DockRegistry::self()->dockByName(uniqueName);
|
return DockRegistry::self()->dockByName(uniqueName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DockWidgetBase::skipsRestore() const
|
||||||
|
{
|
||||||
|
return d->layoutSaverOptions & LayoutSaverOption::Skip;
|
||||||
|
}
|
||||||
|
|
||||||
FloatingWindow *DockWidgetBase::morphIntoFloatingWindow()
|
FloatingWindow *DockWidgetBase::morphIntoFloatingWindow()
|
||||||
{
|
{
|
||||||
if (auto fw = floatingWindow())
|
if (auto fw = floatingWindow())
|
||||||
@@ -645,12 +669,18 @@ void DockWidgetBase::Private::updateTitle()
|
|||||||
|
|
||||||
void DockWidgetBase::Private::toggle(bool enabled)
|
void DockWidgetBase::Private::toggle(bool enabled)
|
||||||
{
|
{
|
||||||
|
if (SideBar *sb = sideBar()) {
|
||||||
|
// The widget is in the sidebar, let's toggle its overlayed state
|
||||||
|
sb->toggleOverlay(q);
|
||||||
|
} else {
|
||||||
|
// The most common case. The dock widget is not in the sidebar. just close or open it.
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
show();
|
show();
|
||||||
} else {
|
} else {
|
||||||
q->close();
|
q->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DockWidgetBase::Private::updateToggleAction()
|
void DockWidgetBase::Private::updateToggleAction()
|
||||||
{
|
{
|
||||||
@@ -708,6 +738,9 @@ void DockWidgetBase::Private::close()
|
|||||||
sb->removeDockWidget(q);
|
sb->removeDockWidget(q);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options & DockWidgetBase::Option_DeleteOnClose)
|
||||||
|
q->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DockWidgetBase::Private::restoreToPreviousPosition()
|
bool DockWidgetBase::Private::restoreToPreviousPosition()
|
||||||
|
|||||||
@@ -75,10 +75,19 @@ public:
|
|||||||
enum Option {
|
enum Option {
|
||||||
Option_None = 0, ///< No option, the default
|
Option_None = 0, ///< No option, the default
|
||||||
Option_NotClosable = 1, ///< The DockWidget can't be closed on the [x], only programatically
|
Option_NotClosable = 1, ///< The DockWidget can't be closed on the [x], only programatically
|
||||||
Option_NotDockable = 2 ///< The DockWidget can't be docked, it's always floating
|
Option_NotDockable = 2, ///< The DockWidget can't be docked, it's always floating
|
||||||
|
Option_DeleteOnClose = 4 ///< Deletes the DockWidget when closed
|
||||||
|
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(Options, Option)
|
Q_DECLARE_FLAGS(Options, Option)
|
||||||
|
|
||||||
|
/// @brief Options which will affect LayoutSaver save/restore
|
||||||
|
enum class LayoutSaverOption {
|
||||||
|
None = 0, ///< Just use the defaults
|
||||||
|
Skip = 1, ///< The dock widget won't participate in save/restore. Currently only available for floating windows.
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(LayoutSaverOptions, LayoutSaverOption)
|
||||||
|
|
||||||
enum class IconPlace {
|
enum class IconPlace {
|
||||||
TitleBar = 1,
|
TitleBar = 1,
|
||||||
TabBar = 2,
|
TabBar = 2,
|
||||||
@@ -91,12 +100,15 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief constructs a new DockWidget
|
* @brief constructs a new DockWidget
|
||||||
* @param uniqueName the name of the dockwidget, should be unique. Use title for user visible text.
|
* @param uniqueName the name of the dockwidget, should be unique. Use title for user visible text.
|
||||||
* @param options optional options controlling behaviour
|
* @param options options controlling certain behaviours
|
||||||
|
* @param layoutSaverOptions options to control save/restore
|
||||||
*
|
*
|
||||||
* There's no parent argument. The DockWidget is either parented to FloatingWindow or MainWindow
|
* There's no parent argument. The DockWidget is either parented to FloatingWindow or MainWindow
|
||||||
* when visible, or stays without a parent when hidden.
|
* when visible, or stays without a parent when hidden.
|
||||||
*/
|
*/
|
||||||
explicit DockWidgetBase(const QString &uniqueName, Options options = DockWidgetBase::Options());
|
explicit DockWidgetBase(const QString &uniqueName,
|
||||||
|
Options options = DockWidgetBase::Options(),
|
||||||
|
LayoutSaverOptions layoutSaverOptions = LayoutSaverOptions());
|
||||||
|
|
||||||
///@brief destructor
|
///@brief destructor
|
||||||
~DockWidgetBase() override;
|
~DockWidgetBase() override;
|
||||||
@@ -198,6 +210,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
Options options() const;
|
Options options() const;
|
||||||
|
|
||||||
|
/// @brief returns the per-dockwidget options which will affect LayoutSaver
|
||||||
|
/// These are the options which were passed to the constructor
|
||||||
|
KDDockWidgets::DockWidgetBase::LayoutSaverOptions layoutSaverOptions() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setter for the options.
|
* @brief Setter for the options.
|
||||||
* Only Option_NotClosable is allowed to change after construction. For the other options use
|
* Only Option_NotClosable is allowed to change after construction. For the other options use
|
||||||
@@ -322,7 +338,7 @@ public:
|
|||||||
bool isMainWindow() const;
|
bool isMainWindow() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns whether this dock widget is docked into a main window.
|
* @brief Returns whether this dock widget is docked into a main window (as opposed to floating)
|
||||||
*
|
*
|
||||||
* Note that isFloating() returning false might either mean the dock widget is docked into a
|
* Note that isFloating() returning false might either mean the dock widget is docked into a
|
||||||
* main window or into a floating window (groupped/nested with other dock widgets. Use this function
|
* main window or into a floating window (groupped/nested with other dock widgets. Use this function
|
||||||
@@ -331,6 +347,7 @@ public:
|
|||||||
bool isInMainWindow() const;
|
bool isInMainWindow() const;
|
||||||
|
|
||||||
/// @brief Returns the main window this dock widget is in. nullptr if it's not inside a main window
|
/// @brief Returns the main window this dock widget is in. nullptr if it's not inside a main window
|
||||||
|
/// Also returns nullptr if it's minimized to a sidebar
|
||||||
MainWindowBase *mainWindow() const;
|
MainWindowBase *mainWindow() const;
|
||||||
|
|
||||||
///@brief Returns whether This or any child of this dock widget is focused
|
///@brief Returns whether This or any child of this dock widget is focused
|
||||||
@@ -350,15 +367,22 @@ public:
|
|||||||
*/
|
*/
|
||||||
void moveToSideBar();
|
void moveToSideBar();
|
||||||
|
|
||||||
/// @brief Returns whether this dock widget is overlayed on top of the main window, instead of
|
/// @brief Returns whether this dock widget is overlayed from the side-bar.
|
||||||
/// docked into the layout. This is only relevant when using the auto-hide and side-bar feature.
|
///
|
||||||
|
/// This is only relevant when using the auto-hide and side-bar feature.
|
||||||
|
/// Not to be confused with "floating", which means top-level window.
|
||||||
bool isOverlayed() const;
|
bool isOverlayed() const;
|
||||||
|
|
||||||
///@brief Returns whether this dock widget is in a side bar, and which.
|
///@brief Returns whether this dock widget is in a side bar, and which.
|
||||||
/// SideBarLocation::None is returned if it's not in a sidebar.
|
/// SideBarLocation::None is returned if it's not in a sidebar.
|
||||||
/// This is only relevant when using the auto-hide and side-bar feature.
|
/// This is only relevant when using the auto-hide and side-bar feature.
|
||||||
|
/// @sa isInSideBar
|
||||||
SideBarLocation sideBarLocation() const;
|
SideBarLocation sideBarLocation() const;
|
||||||
|
|
||||||
|
/// @brief Returns where this dockwidget is in a sidebar
|
||||||
|
/// Similar to sideBarLocation(), but returns a bool
|
||||||
|
bool isInSideBar() const;
|
||||||
|
|
||||||
/// @brief Returns whether this floating dock widget knows its previous docked location
|
/// @brief Returns whether this floating dock widget knows its previous docked location
|
||||||
/// Result only makes sense if it's floating.
|
/// Result only makes sense if it's floating.
|
||||||
///
|
///
|
||||||
@@ -375,6 +399,9 @@ public:
|
|||||||
/// nullptr is returned if the dock widget isn't found.
|
/// nullptr is returned if the dock widget isn't found.
|
||||||
static DockWidgetBase* byName(const QString &uniqueName);
|
static DockWidgetBase* byName(const QString &uniqueName);
|
||||||
|
|
||||||
|
/// @brief Returns whether this widget has the LayoutSaverOption::Skip flag
|
||||||
|
bool skipsRestore() const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
#ifdef KDDOCKWIDGETS_QTWIDGETS
|
#ifdef KDDOCKWIDGETS_QTWIDGETS
|
||||||
///@brief signal emitted when the parent changed
|
///@brief signal emitted when the parent changed
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ public:
|
|||||||
QQuickItem *const m_visualItem;
|
QQuickItem *const m_visualItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
DockWidgetQuick::DockWidgetQuick(const QString &name, Options options)
|
DockWidgetQuick::DockWidgetQuick(const QString &name, Options options, LayoutSaverOptions layoutSaverOptions)
|
||||||
: DockWidgetBase(name, options)
|
: DockWidgetBase(name, options, layoutSaverOptions)
|
||||||
, d(new Private(this))
|
, d(new Private(this))
|
||||||
{
|
{
|
||||||
// To mimic what QtWidgets does when creating a new QWidget.
|
// To mimic what QtWidgets does when creating a new QWidget.
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ public:
|
|||||||
* There's no parent argument. The DockWidget is either parented to FloatingWindow or MainWindow
|
* There's no parent argument. The DockWidget is either parented to FloatingWindow or MainWindow
|
||||||
* when visible, or stays without a parent when hidden.
|
* when visible, or stays without a parent when hidden.
|
||||||
*/
|
*/
|
||||||
explicit DockWidgetQuick(const QString &uniqueName, Options options = {});
|
explicit DockWidgetQuick(const QString &uniqueName, Options options = {},
|
||||||
|
LayoutSaverOptions layoutSaverOptions = LayoutSaverOptions());
|
||||||
|
|
||||||
///@brief destructor
|
///@brief destructor
|
||||||
~DockWidgetQuick() override;
|
~DockWidgetQuick() override;
|
||||||
|
|||||||
@@ -69,6 +69,9 @@ public:
|
|||||||
return m_affinityNames.isEmpty() || affinities.isEmpty() || DockRegistry::self()->affinitiesMatch(m_affinityNames, affinities);
|
return m_affinityNames.isEmpty() || affinities.isEmpty() || DockRegistry::self()->affinitiesMatch(m_affinityNames, affinities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void floatWidgetsWhichSkipRestore(const QStringList &mainWindowNames);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void deserializeWindowGeometry(const T &saved, QWidgetOrQuick *topLevel);
|
void deserializeWindowGeometry(const T &saved, QWidgetOrQuick *topLevel);
|
||||||
void deleteEmptyFrames();
|
void deleteEmptyFrames();
|
||||||
@@ -229,9 +232,12 @@ bool LayoutSaver::restoreLayout(const QByteArray &data)
|
|||||||
if (d->m_restoreOptions & RestoreOption_RelativeToMainWindow)
|
if (d->m_restoreOptions & RestoreOption_RelativeToMainWindow)
|
||||||
layout.scaleSizes();
|
layout.scaleSizes();
|
||||||
|
|
||||||
|
d->floatWidgetsWhichSkipRestore(layout.mainWindowNames());
|
||||||
|
|
||||||
// Hide all dockwidgets and unparent them from any layout before starting restore
|
// Hide all dockwidgets and unparent them from any layout before starting restore
|
||||||
// We only close the stuff that the loaded JSON knows about. Unknown widgets might be newer.
|
// We only close the stuff that the loaded JSON knows about. Unknown widgets might be newer.
|
||||||
d->m_dockRegistry->clear(d->m_dockRegistry->dockWidgets(layout.dockWidgetNames()),
|
|
||||||
|
d->m_dockRegistry->clear(d->m_dockRegistry->dockWidgets(layout.dockWidgetsToClose()),
|
||||||
d->m_dockRegistry->mainWindows(layout.mainWindowNames()),
|
d->m_dockRegistry->mainWindows(layout.mainWindowNames()),
|
||||||
d->m_affinityNames);
|
d->m_affinityNames);
|
||||||
|
|
||||||
@@ -258,14 +264,15 @@ bool LayoutSaver::restoreLayout(const QByteArray &data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. Restore FloatingWindows
|
// 2. Restore FloatingWindows
|
||||||
for (const LayoutSaver::FloatingWindow &fw : qAsConst(layout.floatingWindows)) {
|
for (LayoutSaver::FloatingWindow &fw : layout.floatingWindows) {
|
||||||
if (!d->matchesAffinity(fw.affinities))
|
if (!d->matchesAffinity(fw.affinities) || fw.skipsRestore())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MainWindowBase *parent = fw.parentIndex == -1 ? nullptr
|
MainWindowBase *parent = fw.parentIndex == -1 ? nullptr
|
||||||
: DockRegistry::self()->mainwindows().at(fw.parentIndex);
|
: DockRegistry::self()->mainwindows().at(fw.parentIndex);
|
||||||
|
|
||||||
auto floatingWindow = Config::self().frameworkWidgetFactory()->createFloatingWindow(parent);
|
auto floatingWindow = Config::self().frameworkWidgetFactory()->createFloatingWindow(parent);
|
||||||
|
fw.floatingWindowInstance = floatingWindow;
|
||||||
d->deserializeWindowGeometry(fw, floatingWindow);
|
d->deserializeWindowGeometry(fw, floatingWindow);
|
||||||
if (!floatingWindow->deserialize(fw)) {
|
if (!floatingWindow->deserialize(fw)) {
|
||||||
qWarning() << Q_FUNC_INFO << "Failed to deserialize floating window";
|
qWarning() << Q_FUNC_INFO << "Failed to deserialize floating window";
|
||||||
@@ -332,6 +339,24 @@ void LayoutSaver::Private::deserializeWindowGeometry(const T &saved, QWidgetOrQu
|
|||||||
topLevel->setVisible(saved.isVisible);
|
topLevel->setVisible(saved.isVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LayoutSaver::Private::floatWidgetsWhichSkipRestore(const QStringList &mainWindowNames)
|
||||||
|
{
|
||||||
|
// Widgets with the DockWidget::LayoutSaverOption::Skip flag skip restore completely.
|
||||||
|
// If they were visible before they need to remain visible now.
|
||||||
|
// If they were previously docked we need to float them, as the main window they were on will
|
||||||
|
// be loading a new layout.
|
||||||
|
|
||||||
|
for (MainWindowBase *mw : DockRegistry::self()->mainWindows(mainWindowNames)) {
|
||||||
|
const KDDockWidgets::DockWidgetBase::List docks = mw->multiSplitter()->dockWidgets();
|
||||||
|
for (auto dw : docks) {
|
||||||
|
if (dw->skipsRestore()) {
|
||||||
|
dw->setFloating(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void LayoutSaver::Private::deleteEmptyFrames()
|
void LayoutSaver::Private::deleteEmptyFrames()
|
||||||
{
|
{
|
||||||
// After a restore it can happen that some DockWidgets didn't exist, so weren't restored.
|
// After a restore it can happen that some DockWidgets didn't exist, so weren't restored.
|
||||||
@@ -471,6 +496,14 @@ LayoutSaver::MainWindow LayoutSaver::Layout::mainWindowForIndex(int index) const
|
|||||||
return mainWindows.at(index);
|
return mainWindows.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LayoutSaver::FloatingWindow LayoutSaver::Layout::floatingWindowForIndex(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= floatingWindows.size())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return floatingWindows.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
QStringList LayoutSaver::Layout::mainWindowNames() const
|
QStringList LayoutSaver::Layout::mainWindowNames() const
|
||||||
{
|
{
|
||||||
QStringList names;
|
QStringList names;
|
||||||
@@ -493,6 +526,35 @@ QStringList LayoutSaver::Layout::dockWidgetNames() const
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList LayoutSaver::Layout::dockWidgetsToClose() const
|
||||||
|
{
|
||||||
|
// Before restoring a layout we close all dock widgets, unless they're a floating window with the DontCloseBeforeRestore flag
|
||||||
|
|
||||||
|
QStringList names;
|
||||||
|
names.reserve(allDockWidgets.size());
|
||||||
|
auto registry = DockRegistry::self();
|
||||||
|
for (const auto &dw : allDockWidgets) {
|
||||||
|
if (DockWidgetBase *dockWidget = registry->dockByName(dw->uniqueName)) {
|
||||||
|
|
||||||
|
bool doClose = true;
|
||||||
|
|
||||||
|
if (dockWidget->skipsRestore()) {
|
||||||
|
if (auto fw = dockWidget->floatingWindow()) {
|
||||||
|
if (fw->allDockWidgetsHave(DockWidgetBase::LayoutSaverOption::Skip)) {
|
||||||
|
// All dock widgets in this floating window skips float, so we can honour it for all.
|
||||||
|
doClose = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doClose)
|
||||||
|
names << dw->uniqueName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
bool LayoutSaver::Frame::isValid() const
|
bool LayoutSaver::Frame::isValid() const
|
||||||
{
|
{
|
||||||
if (isNull)
|
if (isNull)
|
||||||
@@ -528,6 +590,26 @@ bool LayoutSaver::Frame::isValid() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LayoutSaver::Frame::hasSingleDockWidget() const
|
||||||
|
{
|
||||||
|
return dockWidgets.size() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LayoutSaver::Frame::skipsRestore() const
|
||||||
|
{
|
||||||
|
return std::all_of(dockWidgets.cbegin(), dockWidgets.cend(), [] (LayoutSaver::DockWidget::Ptr dw) {
|
||||||
|
return dw->skipsRestore();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutSaver::DockWidget::Ptr LayoutSaver::Frame::singleDockWidget() const
|
||||||
|
{
|
||||||
|
if (!hasSingleDockWidget())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return dockWidgets.first();
|
||||||
|
}
|
||||||
|
|
||||||
void LayoutSaver::Frame::scaleSizes(const ScalingInfo &scalingInfo)
|
void LayoutSaver::Frame::scaleSizes(const ScalingInfo &scalingInfo)
|
||||||
{
|
{
|
||||||
scalingInfo.applyFactorsTo(geometry);
|
scalingInfo.applyFactorsTo(geometry);
|
||||||
@@ -583,6 +665,14 @@ void LayoutSaver::DockWidget::scaleSizes(const ScalingInfo &scalingInfo)
|
|||||||
lastPosition.scaleSizes(scalingInfo);
|
lastPosition.scaleSizes(scalingInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LayoutSaver::DockWidget::skipsRestore() const
|
||||||
|
{
|
||||||
|
if (DockWidgetBase *dw = DockRegistry::self()->dockByName(uniqueName))
|
||||||
|
return dw->skipsRestore();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap LayoutSaver::DockWidget::toVariantMap() const
|
QVariantMap LayoutSaver::DockWidget::toVariantMap() const
|
||||||
{
|
{
|
||||||
QVariantMap map;
|
QVariantMap map;
|
||||||
@@ -621,6 +711,21 @@ bool LayoutSaver::FloatingWindow::isValid() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LayoutSaver::FloatingWindow::hasSingleDockWidget() const
|
||||||
|
{
|
||||||
|
return multiSplitterLayout.hasSingleDockWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutSaver::DockWidget::Ptr LayoutSaver::FloatingWindow::singleDockWidget() const
|
||||||
|
{
|
||||||
|
return multiSplitterLayout.singleDockWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LayoutSaver::FloatingWindow::skipsRestore() const
|
||||||
|
{
|
||||||
|
return multiSplitterLayout.skipsRestore();
|
||||||
|
}
|
||||||
|
|
||||||
void LayoutSaver::FloatingWindow::scaleSizes(const ScalingInfo &scalingInfo)
|
void LayoutSaver::FloatingWindow::scaleSizes(const ScalingInfo &scalingInfo)
|
||||||
{
|
{
|
||||||
scalingInfo.applyFactorsTo(/*by-ref*/geometry);
|
scalingInfo.applyFactorsTo(/*by-ref*/geometry);
|
||||||
@@ -698,6 +803,7 @@ QVariantMap LayoutSaver::MainWindow::toVariantMap() const
|
|||||||
map.insert(QStringLiteral("screenSize"), Layouting::sizeToMap(screenSize));
|
map.insert(QStringLiteral("screenSize"), Layouting::sizeToMap(screenSize));
|
||||||
map.insert(QStringLiteral("isVisible"), isVisible);
|
map.insert(QStringLiteral("isVisible"), isVisible);
|
||||||
map.insert(QStringLiteral("affinities"), stringListToVariant(affinities));
|
map.insert(QStringLiteral("affinities"), stringListToVariant(affinities));
|
||||||
|
map.insert(QStringLiteral("windowState"), windowState);
|
||||||
|
|
||||||
for (SideBarLocation loc : { SideBarLocation::North, SideBarLocation::East, SideBarLocation::West, SideBarLocation::South }) {
|
for (SideBarLocation loc : { SideBarLocation::North, SideBarLocation::East, SideBarLocation::West, SideBarLocation::South }) {
|
||||||
const QStringList dockWidgets = dockWidgetsPerSideBar.value(loc);
|
const QStringList dockWidgets = dockWidgetsPerSideBar.value(loc);
|
||||||
@@ -718,6 +824,7 @@ void LayoutSaver::MainWindow::fromVariantMap(const QVariantMap &map)
|
|||||||
screenSize = Layouting::mapToSize(map.value(QStringLiteral("screenSize")).toMap());
|
screenSize = Layouting::mapToSize(map.value(QStringLiteral("screenSize")).toMap());
|
||||||
isVisible = map.value(QStringLiteral("isVisible")).toBool();
|
isVisible = map.value(QStringLiteral("isVisible")).toBool();
|
||||||
affinities = variantToStringList(map.value(QStringLiteral("affinities")).toList());
|
affinities = variantToStringList(map.value(QStringLiteral("affinities")).toList());
|
||||||
|
windowState = Qt::WindowState(map.value(QStringLiteral("windowState"), Qt::WindowNoState).toInt());
|
||||||
|
|
||||||
// Compatibility hack. Old json format had a single "affinityName" instead of an "affinities" list:
|
// Compatibility hack. Old json format had a single "affinityName" instead of an "affinities" list:
|
||||||
const QString affinityName = map.value(QStringLiteral("affinityName")).toString();
|
const QString affinityName = map.value(QStringLiteral("affinityName")).toString();
|
||||||
@@ -747,6 +854,26 @@ bool LayoutSaver::MultiSplitter::isValid() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LayoutSaver::MultiSplitter::hasSingleDockWidget() const
|
||||||
|
{
|
||||||
|
return frames.size() == 1 && frames.cbegin()->hasSingleDockWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutSaver::DockWidget::Ptr LayoutSaver::MultiSplitter::singleDockWidget() const
|
||||||
|
{
|
||||||
|
if (!hasSingleDockWidget())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return frames.cbegin()->singleDockWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LayoutSaver::MultiSplitter::skipsRestore() const
|
||||||
|
{
|
||||||
|
return std::all_of(frames.cbegin(), frames.cend(), [] (const LayoutSaver::Frame &frame) {
|
||||||
|
return frame.skipsRestore();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void LayoutSaver::MultiSplitter::scaleSizes(const ScalingInfo &)
|
void LayoutSaver::MultiSplitter::scaleSizes(const ScalingInfo &)
|
||||||
{
|
{
|
||||||
// scalingInfo.applyFactorsTo(/*by-ref*/size);
|
// scalingInfo.applyFactorsTo(/*by-ref*/size);
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
|
|
||||||
namespace KDDockWidgets {
|
namespace KDDockWidgets {
|
||||||
|
|
||||||
|
class FloatingWindow;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename T::List fromVariantList(const QVariantList &listV)
|
typename T::List fromVariantList(const QVariantList &listV)
|
||||||
{
|
{
|
||||||
@@ -137,6 +139,8 @@ struct DOCKS_EXPORT LayoutSaver::DockWidget
|
|||||||
return dw;
|
return dw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool skipsRestore() const;
|
||||||
|
|
||||||
QVariantMap toVariantMap() const;
|
QVariantMap toVariantMap() const;
|
||||||
void fromVariantMap(const QVariantMap &map);
|
void fromVariantMap(const QVariantMap &map);
|
||||||
|
|
||||||
@@ -173,6 +177,12 @@ struct LayoutSaver::Frame
|
|||||||
{
|
{
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
|
bool hasSingleDockWidget() const;
|
||||||
|
bool skipsRestore() const;
|
||||||
|
|
||||||
|
/// @brief in case this frame only has one frame, returns the name of that dock widget
|
||||||
|
LayoutSaver::DockWidget::Ptr singleDockWidget() const;
|
||||||
|
|
||||||
/// Iterates through the layout and patches all absolute sizes. See RestoreOption_RelativeToMainWindow.
|
/// Iterates through the layout and patches all absolute sizes. See RestoreOption_RelativeToMainWindow.
|
||||||
void scaleSizes(const ScalingInfo &scalingInfo);
|
void scaleSizes(const ScalingInfo &scalingInfo);
|
||||||
|
|
||||||
@@ -192,6 +202,11 @@ struct LayoutSaver::Frame
|
|||||||
struct LayoutSaver::MultiSplitter
|
struct LayoutSaver::MultiSplitter
|
||||||
{
|
{
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
|
bool hasSingleDockWidget() const;
|
||||||
|
LayoutSaver::DockWidget::Ptr singleDockWidget() const;
|
||||||
|
bool skipsRestore() const;
|
||||||
|
|
||||||
/// Iterates through the layout and patches all absolute sizes. See RestoreOption_RelativeToMainWindow.
|
/// Iterates through the layout and patches all absolute sizes. See RestoreOption_RelativeToMainWindow.
|
||||||
void scaleSizes(const ScalingInfo &scalingInfo);
|
void scaleSizes(const ScalingInfo &scalingInfo);
|
||||||
|
|
||||||
@@ -208,6 +223,10 @@ struct LayoutSaver::FloatingWindow
|
|||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
|
bool hasSingleDockWidget() const;
|
||||||
|
LayoutSaver::DockWidget::Ptr singleDockWidget() const;
|
||||||
|
bool skipsRestore() const;
|
||||||
|
|
||||||
/// Iterates through the layout and patches all absolute sizes. See RestoreOption_RelativeToMainWindow.
|
/// Iterates through the layout and patches all absolute sizes. See RestoreOption_RelativeToMainWindow.
|
||||||
void scaleSizes(const ScalingInfo &);
|
void scaleSizes(const ScalingInfo &);
|
||||||
|
|
||||||
@@ -221,6 +240,9 @@ struct LayoutSaver::FloatingWindow
|
|||||||
int screenIndex;
|
int screenIndex;
|
||||||
QSize screenSize; // for relative-size restoring
|
QSize screenSize; // for relative-size restoring
|
||||||
bool isVisible = true;
|
bool isVisible = true;
|
||||||
|
|
||||||
|
// The instance that was created during a restore:
|
||||||
|
KDDockWidgets::FloatingWindow *floatingWindowInstance = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LayoutSaver::MainWindow
|
struct LayoutSaver::MainWindow
|
||||||
@@ -245,6 +267,7 @@ public:
|
|||||||
int screenIndex;
|
int screenIndex;
|
||||||
QSize screenSize; // for relative-size restoring
|
QSize screenSize; // for relative-size restoring
|
||||||
bool isVisible;
|
bool isVisible;
|
||||||
|
Qt::WindowState windowState = Qt::WindowNoState;
|
||||||
|
|
||||||
ScalingInfo scalingInfo;
|
ScalingInfo scalingInfo;
|
||||||
};
|
};
|
||||||
@@ -301,9 +324,11 @@ public:
|
|||||||
static LayoutSaver::Layout* s_currentLayoutBeingRestored;
|
static LayoutSaver::Layout* s_currentLayoutBeingRestored;
|
||||||
|
|
||||||
LayoutSaver::MainWindow mainWindowForIndex(int index) const;
|
LayoutSaver::MainWindow mainWindowForIndex(int index) const;
|
||||||
|
LayoutSaver::FloatingWindow floatingWindowForIndex(int index) const;
|
||||||
|
|
||||||
QStringList mainWindowNames() const;
|
QStringList mainWindowNames() const;
|
||||||
QStringList dockWidgetNames() const;
|
QStringList dockWidgetNames() const;
|
||||||
|
QStringList dockWidgetsToClose() const;
|
||||||
|
|
||||||
int serializationVersion = KDDOCKWIDGETS_SERIALIZATION_VERSION;
|
int serializationVersion = KDDOCKWIDGETS_SERIALIZATION_VERSION;
|
||||||
LayoutSaver::MainWindow::List mainWindows;
|
LayoutSaver::MainWindow::List mainWindows;
|
||||||
|
|||||||
@@ -594,6 +594,12 @@ bool MainWindowBase::deserialize(const LayoutSaver::MainWindow &mw)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mw.windowState != Qt::WindowNoState) {
|
||||||
|
if (auto w = windowHandle()) {
|
||||||
|
w->setWindowState(mw.windowState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Commented-out for now, we dont' want to restore the popup/overlay. popups are perishable
|
// Commented-out for now, we dont' want to restore the popup/overlay. popups are perishable
|
||||||
//if (!mw.overlayedDockWidget.isEmpty())
|
//if (!mw.overlayedDockWidget.isEmpty())
|
||||||
// overlayOnSideBar(DockRegistry::self()->dockByName(mw.overlayedDockWidget));
|
// overlayOnSideBar(DockRegistry::self()->dockByName(mw.overlayedDockWidget));
|
||||||
@@ -613,6 +619,8 @@ LayoutSaver::MainWindow MainWindowBase::serialize() const
|
|||||||
m.screenSize = screenSizeForWidget(this);
|
m.screenSize = screenSizeForWidget(this);
|
||||||
m.multiSplitterLayout = dropArea()->serialize();
|
m.multiSplitterLayout = dropArea()->serialize();
|
||||||
m.affinities = d->affinities;
|
m.affinities = d->affinities;
|
||||||
|
m.windowState = windowHandle() ? windowHandle()->windowState()
|
||||||
|
: Qt::WindowNoState;
|
||||||
|
|
||||||
for (SideBarLocation loc : { SideBarLocation::North, SideBarLocation::East, SideBarLocation::West, SideBarLocation::South }) {
|
for (SideBarLocation loc : { SideBarLocation::North, SideBarLocation::East, SideBarLocation::West, SideBarLocation::South }) {
|
||||||
if (SideBar *sb = sideBar(loc)) {
|
if (SideBar *sb = sideBar(loc)) {
|
||||||
|
|||||||
@@ -605,7 +605,7 @@ bool DragController::eventFilter(QObject *o, QEvent *e)
|
|||||||
switch (e->type()) {
|
switch (e->type()) {
|
||||||
case QEvent::NonClientAreaMouseButtonPress: {
|
case QEvent::NonClientAreaMouseButtonPress: {
|
||||||
if (auto fw = qobject_cast<FloatingWindow*>(o)) {
|
if (auto fw = qobject_cast<FloatingWindow*>(o)) {
|
||||||
if (fw->isInDragArea(Qt5Qt6Compat::eventGlobalPos(me))) {
|
if (KDDockWidgets::usesNativeTitleBar() || fw->isInDragArea(Qt5Qt6Compat::eventGlobalPos(me))) {
|
||||||
m_nonClientDrag = true;
|
m_nonClientDrag = true;
|
||||||
return activeState()->handleMouseButtonPress(draggableForQObject(o), Qt5Qt6Compat::eventGlobalPos(me), me->pos());
|
return activeState()->handleMouseButtonPress(draggableForQObject(o), Qt5Qt6Compat::eventGlobalPos(me), me->pos());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ private:
|
|||||||
|
|
||||||
Draggable::List m_draggables;
|
Draggable::List m_draggables;
|
||||||
Draggable *m_draggable = nullptr;
|
Draggable *m_draggable = nullptr;
|
||||||
QPointer<QWidget> m_draggableGuard; // Just so we know if the draggable was destroyed for some reason
|
QPointer<WidgetType> m_draggableGuard; // Just so we know if the draggable was destroyed for some reason
|
||||||
std::unique_ptr<WindowBeingDragged> m_windowBeingDragged;
|
std::unique_ptr<WindowBeingDragged> m_windowBeingDragged;
|
||||||
DropArea *m_currentDropArea = nullptr;
|
DropArea *m_currentDropArea = nullptr;
|
||||||
bool m_nonClientDrag = false;
|
bool m_nonClientDrag = false;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "DockRegistry_p.h"
|
#include "DockRegistry_p.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "FrameworkWidgetFactory.h"
|
#include "FrameworkWidgetFactory.h"
|
||||||
|
#include "DragController_p.h"
|
||||||
|
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QAbstractNativeEventFilter>
|
#include <QAbstractNativeEventFilter>
|
||||||
@@ -215,10 +216,19 @@ void FloatingWindow::setupWindow()
|
|||||||
#if defined(Q_OS_WIN) && defined(KDDOCKWIDGETS_QTWIDGETS)
|
#if defined(Q_OS_WIN) && defined(KDDOCKWIDGETS_QTWIDGETS)
|
||||||
bool FloatingWindow::nativeEvent(const QByteArray &eventType, void *message, Qt5Qt6Compat::qintptr *result)
|
bool FloatingWindow::nativeEvent(const QByteArray &eventType, void *message, Qt5Qt6Compat::qintptr *result)
|
||||||
{
|
{
|
||||||
if (!m_inDtor && !m_deleteScheduled && KDDockWidgets::usesAeroSnapWithCustomDecos()) {
|
if (m_inDtor || m_deleteScheduled)
|
||||||
|
return QWidget::nativeEvent(eventType, message, result);
|
||||||
|
|
||||||
|
if (KDDockWidgets::usesAeroSnapWithCustomDecos()) {
|
||||||
// To enable aero snap we need to tell Windows where's our custom title bar
|
// To enable aero snap we need to tell Windows where's our custom title bar
|
||||||
if (WidgetResizeHandler::handleWindowsNativeEvent(this, eventType, message, result))
|
if (WidgetResizeHandler::handleWindowsNativeEvent(this, eventType, message, result))
|
||||||
return true;
|
return true;
|
||||||
|
} else if (KDDockWidgets::usesNativeTitleBar()) {
|
||||||
|
auto msg = static_cast<MSG *>(message);
|
||||||
|
if (msg->message == WM_SIZING) {
|
||||||
|
// Cancel any drag if we're resizing
|
||||||
|
Q_EMIT DragController::instance()->dragCanceled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QWidget::nativeEvent(eventType, message, result);
|
return QWidget::nativeEvent(eventType, message, result);
|
||||||
@@ -301,8 +311,8 @@ bool FloatingWindow::isInDragArea(QPoint globalPoint) const
|
|||||||
// A click near the border will still send a Qt::NonClientMousePressEvent. We shouldn't
|
// A click near the border will still send a Qt::NonClientMousePressEvent. We shouldn't
|
||||||
// interpret that as a drag, as it's for a native resize.
|
// interpret that as a drag, as it's for a native resize.
|
||||||
// Keep track of how we handled the WM_NCHITTEST
|
// Keep track of how we handled the WM_NCHITTEST
|
||||||
if (m_lastHitTest != 0 && m_lastHitTest != HTCAPTION)
|
if (usesAeroSnapWithCustomDecos())
|
||||||
return false;
|
return m_lastHitTest == HTCAPTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return dragRect().contains(globalPoint);
|
return dragRect().contains(globalPoint);
|
||||||
@@ -341,6 +351,14 @@ bool FloatingWindow::hasSingleDockWidget() const
|
|||||||
return frame->dockWidgetCount() == 1;
|
return frame->dockWidgetCount() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Frame *FloatingWindow::singleFrame() const
|
||||||
|
{
|
||||||
|
const Frame::List frames = this->frames();
|
||||||
|
|
||||||
|
return frames.isEmpty() ? nullptr
|
||||||
|
: frames.first();
|
||||||
|
}
|
||||||
|
|
||||||
bool FloatingWindow::beingDeleted() const
|
bool FloatingWindow::beingDeleted() const
|
||||||
{
|
{
|
||||||
if (m_deleteScheduled || m_inDtor)
|
if (m_deleteScheduled || m_inDtor)
|
||||||
@@ -395,6 +413,8 @@ void FloatingWindow::updateTitleBarVisibility()
|
|||||||
|
|
||||||
for (Frame *frame : frames())
|
for (Frame *frame : frames())
|
||||||
frame->updateTitleBarVisibility();
|
frame->updateTitleBarVisibility();
|
||||||
|
|
||||||
|
m_titleBar->updateButtons();
|
||||||
} else {
|
} else {
|
||||||
visible = false;
|
visible = false;
|
||||||
}
|
}
|
||||||
@@ -501,3 +521,35 @@ bool FloatingWindow::event(QEvent *ev)
|
|||||||
|
|
||||||
return QWidgetAdapter::event(ev);
|
return QWidgetAdapter::event(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FloatingWindow::allDockWidgetsHave(DockWidgetBase::Option option) const
|
||||||
|
{
|
||||||
|
const Frame::List frames = this->frames();
|
||||||
|
return std::all_of(frames.begin(), frames.end(), [option] (Frame *frame) {
|
||||||
|
return frame->allDockWidgetsHave(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FloatingWindow::anyDockWidgetsHas(DockWidgetBase::Option option) const
|
||||||
|
{
|
||||||
|
const Frame::List frames = this->frames();
|
||||||
|
return std::any_of(frames.begin(), frames.end(), [option] (Frame *frame) {
|
||||||
|
return frame->anyDockWidgetsHas(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FloatingWindow::allDockWidgetsHave(DockWidgetBase::LayoutSaverOption option) const
|
||||||
|
{
|
||||||
|
const Frame::List frames = this->frames();
|
||||||
|
return std::all_of(frames.begin(), frames.end(), [option] (Frame *frame) {
|
||||||
|
return frame->allDockWidgetsHave(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FloatingWindow::anyDockWidgetsHas(DockWidgetBase::LayoutSaverOption option) const
|
||||||
|
{
|
||||||
|
const Frame::List frames = this->frames();
|
||||||
|
return std::any_of(frames.begin(), frames.end(), [option] (Frame *frame) {
|
||||||
|
return frame->anyDockWidgetsHas(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -97,6 +97,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool hasSingleDockWidget() const;
|
bool hasSingleDockWidget() const;
|
||||||
|
|
||||||
|
/// @brief If this floating window has only one Frame, it's returned, otherwise nullptr
|
||||||
|
Frame* singleFrame() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns whether a deleteLater has already been issued
|
* @brief Returns whether a deleteLater has already been issued
|
||||||
*/
|
*/
|
||||||
@@ -131,6 +134,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
QRect dragRect() const;
|
QRect dragRect() const;
|
||||||
|
|
||||||
|
///@brief Returns whether all dock widgets have the specified option set
|
||||||
|
bool allDockWidgetsHave(DockWidgetBase::Option) const;
|
||||||
|
|
||||||
|
///@brief Returns whether at least one dock widget has the specified option set
|
||||||
|
bool anyDockWidgetsHas(DockWidgetBase::Option) const;
|
||||||
|
|
||||||
|
///@brief Returns whether all dock widgets have the specified layout saver option set
|
||||||
|
bool allDockWidgetsHave(DockWidgetBase::LayoutSaverOption) const;
|
||||||
|
|
||||||
|
///@brief Returns whether at least one dock widget has the specified layout saver option set
|
||||||
|
bool anyDockWidgetsHas(DockWidgetBase::LayoutSaverOption) const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void activatedChanged();
|
void activatedChanged();
|
||||||
void numFramesChanged();
|
void numFramesChanged();
|
||||||
|
|||||||
@@ -720,3 +720,37 @@ TabWidget *Frame::tabWidget() const
|
|||||||
{
|
{
|
||||||
return m_tabWidget;
|
return m_tabWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///@brief Returns whether all dock widgets have the specified option set
|
||||||
|
bool Frame::allDockWidgetsHave(DockWidgetBase::Option option) const
|
||||||
|
{
|
||||||
|
const DockWidgetBase::List docks = dockWidgets();
|
||||||
|
return std::all_of(docks.cbegin(), docks.cend(), [option] (DockWidgetBase *dw) {
|
||||||
|
return dw->options() & option;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
///@brief Returns whether at least one dock widget has the specified option set
|
||||||
|
bool Frame::anyDockWidgetsHas(DockWidgetBase::Option option) const
|
||||||
|
{
|
||||||
|
const DockWidgetBase::List docks = dockWidgets();
|
||||||
|
return std::any_of(docks.cbegin(), docks.cend(), [option] (DockWidgetBase *dw) {
|
||||||
|
return dw->options() & option;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Frame::allDockWidgetsHave(DockWidgetBase::LayoutSaverOption option) const
|
||||||
|
{
|
||||||
|
const DockWidgetBase::List docks = dockWidgets();
|
||||||
|
return std::all_of(docks.cbegin(), docks.cend(), [option] (DockWidgetBase *dw) {
|
||||||
|
return dw->layoutSaverOptions() & option;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Frame::anyDockWidgetsHas(DockWidgetBase::LayoutSaverOption option) const
|
||||||
|
{
|
||||||
|
const DockWidgetBase::List docks = dockWidgets();
|
||||||
|
return std::any_of(docks.cbegin(), docks.cend(), [option] (DockWidgetBase *dw) {
|
||||||
|
return dw->layoutSaverOptions() & option;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "kddockwidgets/docks_export.h"
|
#include "kddockwidgets/docks_export.h"
|
||||||
#include "kddockwidgets/QWidgetAdapter.h"
|
#include "kddockwidgets/QWidgetAdapter.h"
|
||||||
#include "kddockwidgets/FocusScope.h"
|
#include "kddockwidgets/FocusScope.h"
|
||||||
|
#include "kddockwidgets/DockWidgetBase.h"
|
||||||
#include "../LayoutSaver_p.h"
|
#include "../LayoutSaver_p.h"
|
||||||
#include "multisplitter/Widget.h"
|
#include "multisplitter/Widget.h"
|
||||||
|
|
||||||
@@ -239,6 +240,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual QRect dragRect() const;
|
virtual QRect dragRect() const;
|
||||||
|
|
||||||
|
///@brief Returns whether all dock widgets have the specified option set
|
||||||
|
bool allDockWidgetsHave(DockWidgetBase::Option) const;
|
||||||
|
|
||||||
|
///@brief Returns whether at least one dock widget has the specified option set
|
||||||
|
bool anyDockWidgetsHas(DockWidgetBase::Option) const;
|
||||||
|
|
||||||
|
///@brief Returns whether all dock widgets have the specified layout saver option set
|
||||||
|
bool allDockWidgetsHave(DockWidgetBase::LayoutSaverOption) const;
|
||||||
|
|
||||||
|
///@brief Returns whether at least one dock widget has the specified layout saver option set
|
||||||
|
bool anyDockWidgetsHas(DockWidgetBase::LayoutSaverOption) const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void currentDockWidgetChanged(KDDockWidgets::DockWidgetBase *);
|
void currentDockWidgetChanged(KDDockWidgets::DockWidgetBase *);
|
||||||
void numDockWidgetsChanged();
|
void numDockWidgetsChanged();
|
||||||
|
|||||||
@@ -126,10 +126,13 @@ void Position::deserialize(const LayoutSaver::Position &lp)
|
|||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
continue; // Skip
|
continue; // Skip
|
||||||
} else {
|
} else {
|
||||||
const auto floatingWindows = DockRegistry::self()->floatingWindows();
|
auto serializedFw = LayoutSaver::Layout::s_currentLayoutBeingRestored->floatingWindowForIndex(index);
|
||||||
if (index >= 0 && index < floatingWindows.size()) {
|
if (serializedFw.isValid()) {
|
||||||
FloatingWindow *fw = floatingWindows.at(index);
|
if (FloatingWindow *fw = serializedFw.floatingWindowInstance) {
|
||||||
layout = fw->multiSplitter();
|
layout = fw->multiSplitter();
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "Invalid floating window position to restore" << index;
|
qWarning() << "Invalid floating window position to restore" << index;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -51,10 +51,7 @@ TitleBar::TitleBar(FloatingWindow *parent)
|
|||||||
, m_floatingWindow(parent)
|
, m_floatingWindow(parent)
|
||||||
, m_supportsAutoHide(Config::self().flags() & Config::Flag_AutoHideSupport)
|
, m_supportsAutoHide(Config::self().flags() & Config::Flag_AutoHideSupport)
|
||||||
{
|
{
|
||||||
connect(m_floatingWindow, &FloatingWindow::numFramesChanged, this, &TitleBar::updateCloseButton);
|
connect(m_floatingWindow, &FloatingWindow::numFramesChanged, this, &TitleBar::updateButtons);
|
||||||
connect(m_floatingWindow, &FloatingWindow::numFramesChanged, this, &TitleBar::updateFloatButton);
|
|
||||||
connect(m_floatingWindow, &FloatingWindow::numFramesChanged, this, &TitleBar::updateMaximizeButton);
|
|
||||||
connect(m_floatingWindow, &FloatingWindow::numFramesChanged, this, &TitleBar::updateMinimizeButton);
|
|
||||||
connect(m_floatingWindow, &FloatingWindow::windowStateChanged, this, &TitleBar::updateMaximizeButton);
|
connect(m_floatingWindow, &FloatingWindow::windowStateChanged, this, &TitleBar::updateMaximizeButton);
|
||||||
connect(m_floatingWindow, &FloatingWindow::activatedChanged , this, &TitleBar::isFocusedChanged);
|
connect(m_floatingWindow, &FloatingWindow::activatedChanged , this, &TitleBar::isFocusedChanged);
|
||||||
init();
|
init();
|
||||||
@@ -69,8 +66,8 @@ void TitleBar::init()
|
|||||||
// repaint
|
// repaint
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
updateCloseButton();
|
|
||||||
updateFloatButton();
|
updateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
TitleBar::~TitleBar()
|
TitleBar::~TitleBar()
|
||||||
@@ -91,6 +88,15 @@ bool TitleBar::onDoubleClicked()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TitleBar::updateButtons()
|
||||||
|
{
|
||||||
|
updateCloseButton();
|
||||||
|
updateFloatButton();
|
||||||
|
updateMaximizeButton();
|
||||||
|
updateMinimizeButton();
|
||||||
|
updateAutoHideButton();
|
||||||
|
}
|
||||||
|
|
||||||
void TitleBar::updateCloseButton()
|
void TitleBar::updateCloseButton()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -284,17 +290,41 @@ QIcon TitleBar::icon() const
|
|||||||
|
|
||||||
void TitleBar::onCloseClicked()
|
void TitleBar::onCloseClicked()
|
||||||
{
|
{
|
||||||
|
const bool closeOnlyCurrentTab = Config::self().flags() & Config::Flag_CloseOnlyCurrentTab;
|
||||||
|
|
||||||
if (m_frame) {
|
if (m_frame) {
|
||||||
|
if (closeOnlyCurrentTab) {
|
||||||
|
if (DockWidgetBase *dw = m_frame->currentDockWidget()) {
|
||||||
|
dw->close();
|
||||||
|
} else {
|
||||||
|
// Doesn't happen
|
||||||
|
qWarning() << Q_FUNC_INFO << "Frame with no dock widgets";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (m_frame->isTheOnlyFrame() && !m_frame->isInMainWindow()) {
|
if (m_frame->isTheOnlyFrame() && !m_frame->isInMainWindow()) {
|
||||||
m_frame->window()->close();
|
m_frame->window()->close();
|
||||||
} else {
|
} else {
|
||||||
m_frame->close();
|
m_frame->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (m_floatingWindow) {
|
||||||
|
|
||||||
if (m_floatingWindow)
|
if (closeOnlyCurrentTab) {
|
||||||
|
if (Frame *f = m_floatingWindow->singleFrame()) {
|
||||||
|
if (DockWidgetBase *dw = f->currentDockWidget()) {
|
||||||
|
dw->close();
|
||||||
|
} else {
|
||||||
|
// Doesn't happen
|
||||||
|
qWarning() << Q_FUNC_INFO << "Frame with no dock widgets";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
m_floatingWindow->close();
|
m_floatingWindow->close();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
m_floatingWindow->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool TitleBar::isFloating() const
|
bool TitleBar::isFloating() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
FloatingWindow *floatingWindow() const { return m_floatingWindow; }
|
FloatingWindow *floatingWindow() const { return m_floatingWindow; }
|
||||||
|
|
||||||
/// @brief updates the close button enabled state
|
/// @brief updates the close button enabled state
|
||||||
void updateCloseButton();
|
void updateButtons();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void titleChanged();
|
void titleChanged();
|
||||||
@@ -123,7 +123,6 @@ protected:
|
|||||||
QString floatButtonToolTip() const;
|
QString floatButtonToolTip() const;
|
||||||
|
|
||||||
virtual void updateMaximizeButton() {}
|
virtual void updateMaximizeButton() {}
|
||||||
|
|
||||||
virtual void updateMinimizeButton() {}
|
virtual void updateMinimizeButton() {}
|
||||||
virtual void updateAutoHideButton() {}
|
virtual void updateAutoHideButton() {}
|
||||||
|
|
||||||
@@ -140,6 +139,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
friend class ::TestDocks;
|
friend class ::TestDocks;
|
||||||
void updateFloatButton();
|
void updateFloatButton();
|
||||||
|
void updateCloseButton();
|
||||||
void setCloseButtonEnabled(bool);
|
void setCloseButtonEnabled(bool);
|
||||||
void setFloatButtonVisible(bool);
|
void setFloatButtonVisible(bool);
|
||||||
void setFloatButtonToolTip(const QString &);
|
void setFloatButtonToolTip(const QString &);
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ public:
|
|||||||
QVBoxLayout *const layout;
|
QVBoxLayout *const layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
DockWidget::DockWidget(const QString &name, Options options)
|
DockWidget::DockWidget(const QString &name, Options options, LayoutSaverOptions layoutSaverOptions)
|
||||||
: DockWidgetBase(name, options)
|
: DockWidgetBase(name, options, layoutSaverOptions)
|
||||||
, d(new Private(this))
|
, d(new Private(this))
|
||||||
{
|
{
|
||||||
connect(this, &DockWidgetBase::widgetChanged, this, [this] (QWidget *w) {
|
connect(this, &DockWidgetBase::widgetChanged, this, [this] (QWidget *w) {
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ private Q_SLOTS:
|
|||||||
void tst_resizeWindow();
|
void tst_resizeWindow();
|
||||||
void tst_restoreEmpty();
|
void tst_restoreEmpty();
|
||||||
void tst_restoreCentralFrame();
|
void tst_restoreCentralFrame();
|
||||||
|
void tst_restoreMaximizedState();
|
||||||
void tst_shutdown();
|
void tst_shutdown();
|
||||||
void tst_doubleClose();
|
void tst_doubleClose();
|
||||||
void tst_dockInternal();
|
void tst_dockInternal();
|
||||||
@@ -130,8 +131,13 @@ private Q_SLOTS:
|
|||||||
void tst_lastFloatingPositionIsRestored();
|
void tst_lastFloatingPositionIsRestored();
|
||||||
void tst_restoreSimple();
|
void tst_restoreSimple();
|
||||||
void tst_restoreSimplest();
|
void tst_restoreSimplest();
|
||||||
|
void tst_restoreNonClosable();
|
||||||
void tst_invalidLayoutAfterRestore();
|
void tst_invalidLayoutAfterRestore();
|
||||||
|
void tst_dontCloseDockWidgetBeforeRestore();
|
||||||
|
void tst_dontCloseDockWidgetBeforeRestore2();
|
||||||
|
void tst_dontCloseDockWidgetBeforeRestore3();
|
||||||
|
|
||||||
|
void tst_closeOnlyCurrentTab();
|
||||||
void tst_tabWidgetCurrentIndex();
|
void tst_tabWidgetCurrentIndex();
|
||||||
void tst_doubleClickTabToDetach();
|
void tst_doubleClickTabToDetach();
|
||||||
void tst_propagateResize2();
|
void tst_propagateResize2();
|
||||||
@@ -237,6 +243,7 @@ private Q_SLOTS:
|
|||||||
void tst_dragByTabBar_data();
|
void tst_dragByTabBar_data();
|
||||||
void tst_titleBarFocusedWhenTabsChange();
|
void tst_titleBarFocusedWhenTabsChange();
|
||||||
void tst_dock2FloatingWidgetsTabbed();
|
void tst_dock2FloatingWidgetsTabbed();
|
||||||
|
void tst_deleteOnClose();
|
||||||
|
|
||||||
#ifdef KDDOCKWIDGETS_QTWIDGETS
|
#ifdef KDDOCKWIDGETS_QTWIDGETS
|
||||||
// TODO: Port these to QtQuick
|
// TODO: Port these to QtQuick
|
||||||
@@ -252,6 +259,7 @@ private Q_SLOTS:
|
|||||||
void tst_negativeAnchorPositionWhenEmbedded_data();
|
void tst_negativeAnchorPositionWhenEmbedded_data();
|
||||||
void tst_closeRemovesFromSideBar();
|
void tst_closeRemovesFromSideBar();
|
||||||
void tst_restoreSideBar();
|
void tst_restoreSideBar();
|
||||||
|
void tst_toggleActionOnSideBar();
|
||||||
|
|
||||||
// And fix these
|
// And fix these
|
||||||
void tst_floatingWindowDeleted();
|
void tst_floatingWindowDeleted();
|
||||||
@@ -535,8 +543,8 @@ void TestDocks::tst_detachPos()
|
|||||||
// Tests a situation where detaching a dock widget would send it to a bogus position
|
// Tests a situation where detaching a dock widget would send it to a bogus position
|
||||||
EnsureTopLevelsDeleted e;
|
EnsureTopLevelsDeleted e;
|
||||||
auto m = createMainWindow(QSize(501, 500), MainWindowOption_None);
|
auto m = createMainWindow(QSize(501, 500), MainWindowOption_None);
|
||||||
auto dock1 = createDockWidget("1", new MyWidget(QStringLiteral("1"), Qt::black), {}, /** show = */false); // we're creating the dock widgets without showing them as floating initially, so it doesn't record the previous floating position
|
auto dock1 = createDockWidget("1", new MyWidget(QStringLiteral("1"), Qt::black), {}, {}, /** show = */false); // we're creating the dock widgets without showing them as floating initially, so it doesn't record the previous floating position
|
||||||
auto dock2 = createDockWidget("2", new MyWidget(QStringLiteral("2"), Qt::black), {}, /** show = */false);
|
auto dock2 = createDockWidget("2", new MyWidget(QStringLiteral("2"), Qt::black), {}, {}, /** show = */false);
|
||||||
|
|
||||||
QVERIFY(!dock1->isVisible());
|
QVERIFY(!dock1->isVisible());
|
||||||
QVERIFY(!dock2->isVisible());
|
QVERIFY(!dock2->isVisible());
|
||||||
@@ -821,6 +829,24 @@ void TestDocks::tst_restoreCentralFrame()
|
|||||||
QVERIFY(!frame->titleBar()->isVisible());
|
QVERIFY(!frame->titleBar()->isVisible());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestDocks::tst_restoreMaximizedState()
|
||||||
|
{
|
||||||
|
EnsureTopLevelsDeleted e;
|
||||||
|
auto m = createMainWindow();
|
||||||
|
|
||||||
|
m->showMaximized();
|
||||||
|
|
||||||
|
QCOMPARE(m->windowHandle()->windowState(), Qt::WindowMaximized);
|
||||||
|
LayoutSaver saver;
|
||||||
|
|
||||||
|
const QByteArray saved = saver.serializeLayout();
|
||||||
|
m->showNormal();
|
||||||
|
QVERIFY(m->windowHandle()->windowState() != Qt::WindowMaximized);
|
||||||
|
|
||||||
|
saver.restoreLayout(saved);
|
||||||
|
QCOMPARE(m->windowHandle()->windowState(), Qt::WindowMaximized);
|
||||||
|
}
|
||||||
|
|
||||||
void TestDocks::tst_setFloatingSimple()
|
void TestDocks::tst_setFloatingSimple()
|
||||||
{
|
{
|
||||||
EnsureTopLevelsDeleted e;
|
EnsureTopLevelsDeleted e;
|
||||||
@@ -1285,7 +1311,7 @@ void TestDocks::tst_28NestedWidgets()
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (DockDescriptor &desc : docksToCreate) {
|
for (DockDescriptor &desc : docksToCreate) {
|
||||||
desc.createdDock = createDockWidget(QString("%1").arg(i), new QPushButton(QString("%1").arg(i).toLatin1()), {}, false);
|
desc.createdDock = createDockWidget(QString("%1").arg(i), new QPushButton(QString("%1").arg(i).toLatin1()), {}, {}, false);
|
||||||
|
|
||||||
DockWidgetBase *relativeTo = nullptr;
|
DockWidgetBase *relativeTo = nullptr;
|
||||||
if (desc.relativeToIndex != -1)
|
if (desc.relativeToIndex != -1)
|
||||||
@@ -1357,7 +1383,7 @@ void TestDocks::tst_startHidden()
|
|||||||
|
|
||||||
EnsureTopLevelsDeleted e;
|
EnsureTopLevelsDeleted e;
|
||||||
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
||||||
auto dock1 = createDockWidget("1", new QPushButton("1"), {}, /*show=*/false);
|
auto dock1 = createDockWidget("1", new QPushButton("1"), {}, {}, /*show=*/false);
|
||||||
m->addDockWidget(dock1, Location_OnRight, nullptr, InitialVisibilityOption::StartHidden);
|
m->addDockWidget(dock1, Location_OnRight, nullptr, InitialVisibilityOption::StartHidden);
|
||||||
delete dock1;
|
delete dock1;
|
||||||
}
|
}
|
||||||
@@ -1367,8 +1393,8 @@ void TestDocks::tst_startHidden2()
|
|||||||
EnsureTopLevelsDeleted e;
|
EnsureTopLevelsDeleted e;
|
||||||
{
|
{
|
||||||
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
||||||
auto dock1 = createDockWidget("dock1", new QPushButton("one"), {}, false);
|
auto dock1 = createDockWidget("dock1", new QPushButton("one"), {}, {}, false);
|
||||||
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, false);
|
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, {}, false);
|
||||||
|
|
||||||
auto dropArea = m->dropArea();
|
auto dropArea = m->dropArea();
|
||||||
MultiSplitter *layout = dropArea;
|
MultiSplitter *layout = dropArea;
|
||||||
@@ -1396,9 +1422,9 @@ void TestDocks::tst_startHidden2()
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
||||||
auto dock1 = createDockWidget("dock1", new QPushButton("one"), {}, false);
|
auto dock1 = createDockWidget("dock1", new QPushButton("one"), {}, {}, false);
|
||||||
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, false);
|
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, {}, false);
|
||||||
auto dock3 = createDockWidget("dock3", new QPushButton("three"), {}, false);
|
auto dock3 = createDockWidget("dock3", new QPushButton("three"), {}, {}, false);
|
||||||
|
|
||||||
auto dropArea = m->dropArea();
|
auto dropArea = m->dropArea();
|
||||||
MultiSplitter *layout = dropArea;
|
MultiSplitter *layout = dropArea;
|
||||||
@@ -1480,9 +1506,9 @@ void TestDocks::tst_negativeAnchorPosition2()
|
|||||||
auto dropArea = m->dropArea();
|
auto dropArea = m->dropArea();
|
||||||
MultiSplitter *layout = dropArea;
|
MultiSplitter *layout = dropArea;
|
||||||
|
|
||||||
auto dock1 = createDockWidget("1", new QPushButton("1"), {}, /*show=*/false);
|
auto dock1 = createDockWidget("1", new QPushButton("1"), {}, {}, /*show=*/false);
|
||||||
auto dock2 = createDockWidget("2", new QPushButton("2"), {}, /*show=*/false);
|
auto dock2 = createDockWidget("2", new QPushButton("2"), {}, {}, /*show=*/false);
|
||||||
auto dock3 = createDockWidget("3", new QPushButton("3"), {}, /*show=*/false);
|
auto dock3 = createDockWidget("3", new QPushButton("3"), {}, {}, /*show=*/false);
|
||||||
|
|
||||||
m->addDockWidget(dock1, Location_OnLeft);
|
m->addDockWidget(dock1, Location_OnLeft);
|
||||||
m->addDockWidget(dock2, Location_OnRight, nullptr, InitialVisibilityOption::StartHidden);
|
m->addDockWidget(dock2, Location_OnRight, nullptr, InitialVisibilityOption::StartHidden);
|
||||||
@@ -1694,8 +1720,8 @@ void TestDocks::tst_addAsPlaceholder()
|
|||||||
{
|
{
|
||||||
EnsureTopLevelsDeleted e;
|
EnsureTopLevelsDeleted e;
|
||||||
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
||||||
auto dock1 = createDockWidget("dock1", new QPushButton("one"), {}, false);
|
auto dock1 = createDockWidget("dock1", new QPushButton("one"), {}, {}, false);
|
||||||
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, false);
|
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, {}, false);
|
||||||
|
|
||||||
m->addDockWidget(dock1, Location_OnBottom);
|
m->addDockWidget(dock1, Location_OnBottom);
|
||||||
m->addDockWidget(dock2, Location_OnTop, nullptr, InitialVisibilityOption::StartHidden);
|
m->addDockWidget(dock2, Location_OnTop, nullptr, InitialVisibilityOption::StartHidden);
|
||||||
@@ -1724,7 +1750,7 @@ void TestDocks::tst_removeItem()
|
|||||||
EnsureTopLevelsDeleted e;
|
EnsureTopLevelsDeleted e;
|
||||||
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
||||||
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
|
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
|
||||||
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, false);
|
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, {}, false);
|
||||||
auto dock3 = createDockWidget("dock3", new QPushButton("three"));
|
auto dock3 = createDockWidget("dock3", new QPushButton("three"));
|
||||||
|
|
||||||
m->addDockWidget(dock1, Location_OnBottom);
|
m->addDockWidget(dock1, Location_OnBottom);
|
||||||
@@ -3451,6 +3477,57 @@ void TestDocks::tst_restoreSimplest()
|
|||||||
QVERIFY(layout->checkSanity());
|
QVERIFY(layout->checkSanity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestDocks::tst_restoreNonClosable()
|
||||||
|
{
|
||||||
|
// Tests that restoring state also restores the Option_NotClosable option
|
||||||
|
|
||||||
|
{
|
||||||
|
// Basic case:
|
||||||
|
|
||||||
|
EnsureTopLevelsDeleted e;
|
||||||
|
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
||||||
|
auto dock1 = createDockWidget("one", new QTextEdit(), DockWidgetBase::Option_NotClosable);
|
||||||
|
QCOMPARE(dock1->options(), DockWidgetBase::Option_NotClosable);
|
||||||
|
|
||||||
|
LayoutSaver saver;
|
||||||
|
const QByteArray saved = saver.serializeLayout();
|
||||||
|
QVERIFY(saver.restoreLayout(saved));
|
||||||
|
QCOMPARE(dock1->options(), DockWidgetBase::Option_NotClosable);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Case from issue #137
|
||||||
|
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None);
|
||||||
|
|
||||||
|
auto dock1 = createDockWidget("1", new QTextEdit());
|
||||||
|
auto dock2 = createDockWidget("2", new QTextEdit(), DockWidgetBase::Option_NotClosable);
|
||||||
|
auto dock3 = createDockWidget("3", new QTextEdit());
|
||||||
|
|
||||||
|
m->addDockWidget(dock1, Location_OnLeft);
|
||||||
|
m->addDockWidget(dock2, Location_OnLeft);
|
||||||
|
m->addDockWidget(dock3, Location_OnLeft);
|
||||||
|
|
||||||
|
QCOMPARE(dock2->options(), DockWidgetBase::Option_NotClosable);
|
||||||
|
dock2->setFloating(true);
|
||||||
|
QCOMPARE(dock2->options(), DockWidgetBase::Option_NotClosable);
|
||||||
|
|
||||||
|
TitleBar *tb = dock2->frame()->actualTitleBar();
|
||||||
|
QVERIFY(tb->isVisible());
|
||||||
|
QVERIFY(!tb->closeButtonEnabled());
|
||||||
|
|
||||||
|
LayoutSaver saver;
|
||||||
|
const QByteArray saved = saver.serializeLayout();
|
||||||
|
|
||||||
|
QVERIFY(saver.restoreLayout(saved));
|
||||||
|
QCOMPARE(dock2->options(), DockWidgetBase::Option_NotClosable);
|
||||||
|
|
||||||
|
tb = dock2->frame()->actualTitleBar();
|
||||||
|
QVERIFY(tb->isVisible());
|
||||||
|
|
||||||
|
QVERIFY(!tb->closeButtonEnabled());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TestDocks::tst_resizeViaAnchorsAfterPlaceholderCreation()
|
void TestDocks::tst_resizeViaAnchorsAfterPlaceholderCreation()
|
||||||
{
|
{
|
||||||
EnsureTopLevelsDeleted e;
|
EnsureTopLevelsDeleted e;
|
||||||
@@ -3781,10 +3858,10 @@ void TestDocks::tst_restoreWithAffinity()
|
|||||||
auto m2 = createMainWindow(QSize(500, 500));
|
auto m2 = createMainWindow(QSize(500, 500));
|
||||||
m2->setAffinities({ "a2" });
|
m2->setAffinities({ "a2" });
|
||||||
|
|
||||||
auto dock1 = createDockWidget("1", new QPushButton("1"), {}, true, "a1");
|
auto dock1 = createDockWidget("1", new QPushButton("1"), {}, {}, true, "a1");
|
||||||
m1->addDockWidget(dock1, Location_OnLeft);
|
m1->addDockWidget(dock1, Location_OnLeft);
|
||||||
|
|
||||||
auto dock2 = createDockWidget("2", new QPushButton("2"), {}, true, "a2");
|
auto dock2 = createDockWidget("2", new QPushButton("2"), {}, {}, true, "a2");
|
||||||
dock2->setFloating(true);
|
dock2->setFloating(true);
|
||||||
dock2->show();
|
dock2->show();
|
||||||
|
|
||||||
@@ -3893,7 +3970,7 @@ void TestDocks::tst_restoreWithDockFactory()
|
|||||||
|
|
||||||
// Now try with a factory func
|
// Now try with a factory func
|
||||||
DockWidgetFactoryFunc func = [] (const QString &) {
|
DockWidgetFactoryFunc func = [] (const QString &) {
|
||||||
return createDockWidget("1", new QPushButton("1"), {}, /*show=*/ false);
|
return createDockWidget("1", new QPushButton("1"), {}, {}, /*show=*/ false);
|
||||||
};
|
};
|
||||||
|
|
||||||
KDDockWidgets::Config::self().setDockWidgetFactoryFunc(func);
|
KDDockWidgets::Config::self().setDockWidgetFactoryFunc(func);
|
||||||
@@ -4988,7 +5065,7 @@ void TestDocks::tst_closeRemovesFromSideBar()
|
|||||||
|
|
||||||
QVERIFY(!dw1->isOverlayed());
|
QVERIFY(!dw1->isOverlayed());
|
||||||
QVERIFY(!dw1->isVisible());
|
QVERIFY(!dw1->isVisible());
|
||||||
QVERIFY(dw1->sideBarLocation() != SideBarLocation::None);
|
QVERIFY(dw1->isInSideBar());
|
||||||
|
|
||||||
SideBar *sb = m1->sideBarForDockWidget(dw1);
|
SideBar *sb = m1->sideBarForDockWidget(dw1);
|
||||||
QVERIFY(sb);
|
QVERIFY(sb);
|
||||||
@@ -5072,6 +5149,40 @@ void TestDocks::tst_restoreSideBar()
|
|||||||
delete fw1;
|
delete fw1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestDocks::tst_toggleActionOnSideBar()
|
||||||
|
{
|
||||||
|
// When a dock widget is in the sidebar and we use DockWidget::toggleAction() then it should
|
||||||
|
// toggle visibility without removing it from the sidebar
|
||||||
|
|
||||||
|
EnsureTopLevelsDeleted e;
|
||||||
|
KDDockWidgets::Config::self().setFlags(KDDockWidgets::Config::Flag_AutoHideSupport);
|
||||||
|
auto m1 = createMainWindow(QSize(1000, 1000), MainWindowOption_None, "MW1");
|
||||||
|
auto dw1 = new DockWidgetType("1");
|
||||||
|
m1->addDockWidget(dw1, Location_OnBottom);
|
||||||
|
dw1->moveToSideBar();
|
||||||
|
|
||||||
|
QVERIFY(!dw1->isVisible());
|
||||||
|
QVERIFY(!dw1->isOverlayed());
|
||||||
|
QVERIFY(dw1->isInSideBar());
|
||||||
|
QVERIFY(!dw1->isInMainWindow());
|
||||||
|
|
||||||
|
QAction *action = dw1->toggleAction();
|
||||||
|
action->trigger();
|
||||||
|
|
||||||
|
QVERIFY(dw1->isVisible());
|
||||||
|
QVERIFY(dw1->isOverlayed());
|
||||||
|
QVERIFY(dw1->isInMainWindow());
|
||||||
|
|
||||||
|
QVERIFY(dw1->isInSideBar());
|
||||||
|
action->trigger();
|
||||||
|
|
||||||
|
QVERIFY(!dw1->isOverlayed());
|
||||||
|
QVERIFY(!dw1->isInMainWindow());
|
||||||
|
|
||||||
|
QVERIFY(dw1->isInSideBar());
|
||||||
|
QVERIFY(!dw1->isInMainWindow());
|
||||||
|
}
|
||||||
|
|
||||||
void TestDocks::tst_embeddedMainWindow()
|
void TestDocks::tst_embeddedMainWindow()
|
||||||
{
|
{
|
||||||
EnsureTopLevelsDeleted e;
|
EnsureTopLevelsDeleted e;
|
||||||
@@ -5790,6 +5901,155 @@ void TestDocks::tst_invalidLayoutAfterRestore()
|
|||||||
layout->checkSanity();
|
layout->checkSanity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestDocks::tst_dontCloseDockWidgetBeforeRestore()
|
||||||
|
{
|
||||||
|
EnsureTopLevelsDeleted e;
|
||||||
|
auto m = createMainWindow();
|
||||||
|
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
|
||||||
|
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, DockWidgetBase::LayoutSaverOption::Skip);
|
||||||
|
auto dock3 = createDockWidget("dock3", new QPushButton("three"), {}, DockWidgetBase::LayoutSaverOption::Skip);
|
||||||
|
auto dock4 = createDockWidget("4", new QPushButton("4"), {}, {}, /*show=*/ false);
|
||||||
|
|
||||||
|
m->addDockWidget(dock1, Location_OnBottom);
|
||||||
|
m->addDockWidget(dock2, Location_OnBottom);
|
||||||
|
|
||||||
|
// Dock #3 floats, while #1 and #2 are docked.
|
||||||
|
dock3->setFloating(true);
|
||||||
|
QVERIFY(dock3->isOpen());
|
||||||
|
QVERIFY(dock3->isFloating());
|
||||||
|
QVERIFY(!dock3->isInMainWindow());
|
||||||
|
|
||||||
|
LayoutSaver saver;
|
||||||
|
const QByteArray saved = saver.serializeLayout();
|
||||||
|
dock3->close();
|
||||||
|
|
||||||
|
// Not open anymore
|
||||||
|
QVERIFY(!dock3->isOpen());
|
||||||
|
|
||||||
|
QVERIFY(saver.restoreLayout(saved));
|
||||||
|
|
||||||
|
// #3 is still closed, the restore will skip it
|
||||||
|
QVERIFY(!dock3->isOpen());
|
||||||
|
QVERIFY(!dock3->isInMainWindow());
|
||||||
|
|
||||||
|
auto dock5 = createDockWidget("5", new QPushButton("5"), {}, DockWidgetBase::LayoutSaverOption::Skip);
|
||||||
|
|
||||||
|
dock4->show();
|
||||||
|
dock5->show();
|
||||||
|
|
||||||
|
QVERIFY(saver.restoreLayout(saved));
|
||||||
|
QVERIFY(!dock4->isOpen());
|
||||||
|
QVERIFY(dock5->isOpen()); // #5 is still open, it ignored restore
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestDocks::tst_dontCloseDockWidgetBeforeRestore2()
|
||||||
|
{
|
||||||
|
// In this case we have a floating window with two dock widgets tabbed, both having LayoutSaverOption::Skip
|
||||||
|
// Meaning the whole window should be skipped
|
||||||
|
|
||||||
|
EnsureTopLevelsDeleted e;
|
||||||
|
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, DockWidgetBase::LayoutSaverOption::Skip);
|
||||||
|
auto dock3 = createDockWidget("dock3", new QPushButton("three"), {}, DockWidgetBase::LayoutSaverOption::Skip);
|
||||||
|
|
||||||
|
dock2->close();
|
||||||
|
dock3->close();
|
||||||
|
|
||||||
|
LayoutSaver saver;
|
||||||
|
const QByteArray saved = saver.serializeLayout(); // This layout has 0 docks visible
|
||||||
|
|
||||||
|
dock2->show();
|
||||||
|
dock3->show();
|
||||||
|
QVERIFY(saver.restoreLayout(saved));
|
||||||
|
QVERIFY(dock2->isVisible()); // They're still visible
|
||||||
|
QVERIFY(dock3->isVisible());
|
||||||
|
|
||||||
|
// Now tab and restore again
|
||||||
|
dock2->addDockWidgetAsTab(dock3);
|
||||||
|
QVERIFY(saver.restoreLayout(saved));
|
||||||
|
QVERIFY(dock2->isOpen());
|
||||||
|
QVERIFY(dock3->isOpen());
|
||||||
|
QVERIFY(dock3->isVisible());
|
||||||
|
QCOMPARE(dock3->frame(), dock2->frame());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestDocks::tst_dontCloseDockWidgetBeforeRestore3()
|
||||||
|
{
|
||||||
|
EnsureTopLevelsDeleted e;
|
||||||
|
auto m = createMainWindow();
|
||||||
|
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
|
||||||
|
auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, DockWidgetBase::LayoutSaverOption::Skip);
|
||||||
|
dock1->close();
|
||||||
|
dock2->close();
|
||||||
|
|
||||||
|
LayoutSaver saver;
|
||||||
|
const QByteArray saved = saver.serializeLayout(); // This layout has 0 docks visible
|
||||||
|
|
||||||
|
m->addDockWidget(dock1, Location_OnBottom);
|
||||||
|
m->addDockWidget(dock2, Location_OnBottom);
|
||||||
|
|
||||||
|
QVERIFY(saver.restoreLayout(saved));
|
||||||
|
|
||||||
|
QVERIFY(!dock1->isOpen()); // Gets closed by the restore
|
||||||
|
QVERIFY(dock2->isOpen()); // Dock2 remains open, it ignores restore
|
||||||
|
QVERIFY(dock2->isFloating());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestDocks::tst_closeOnlyCurrentTab()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// Case of a floating window with tabs
|
||||||
|
EnsureTopLevelsDeleted e;
|
||||||
|
KDDockWidgets::Config::self().setFlags(KDDockWidgets::Config::Flag_CloseOnlyCurrentTab);
|
||||||
|
|
||||||
|
auto dock1 = createDockWidget("1", new QPushButton("1"));
|
||||||
|
auto dock2 = createDockWidget("2", new QPushButton("2"));
|
||||||
|
auto dock3 = createDockWidget("3", new QPushButton("3"));
|
||||||
|
|
||||||
|
/// Floating window with 3 tabs
|
||||||
|
dock1->addDockWidgetAsTab(dock2);
|
||||||
|
dock1->addDockWidgetAsTab(dock3);
|
||||||
|
|
||||||
|
TitleBar *tb = dock1->titleBar();
|
||||||
|
QVERIFY(tb->isVisible());
|
||||||
|
dock1->setAsCurrentTab();
|
||||||
|
Frame *frame = dock1->frame();
|
||||||
|
QCOMPARE(frame->currentIndex(), 0);
|
||||||
|
|
||||||
|
tb->onCloseClicked();
|
||||||
|
|
||||||
|
QVERIFY(!dock1->isOpen());
|
||||||
|
QVERIFY(dock2->isOpen());
|
||||||
|
QVERIFY(dock3->isOpen());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Case of a floating window with tabs
|
||||||
|
EnsureTopLevelsDeleted e;
|
||||||
|
KDDockWidgets::Config::self().setFlags(KDDockWidgets::Config::Flag_CloseOnlyCurrentTab);
|
||||||
|
|
||||||
|
auto m = createMainWindow();
|
||||||
|
auto dock1 = createDockWidget("1", new QPushButton("1"));
|
||||||
|
auto dock2 = createDockWidget("2", new QPushButton("2"));
|
||||||
|
auto dock3 = createDockWidget("3", new QPushButton("3"));
|
||||||
|
|
||||||
|
m->addDockWidget(dock1, Location_OnLeft);
|
||||||
|
m->addDockWidget(dock2, Location_OnRight);
|
||||||
|
|
||||||
|
dock2->addDockWidgetAsTab(dock3);
|
||||||
|
Frame *frame = dock2->frame();
|
||||||
|
QCOMPARE(frame->currentIndex(), 1);
|
||||||
|
TitleBar *tb = frame->titleBar();
|
||||||
|
QVERIFY(tb->isVisible());
|
||||||
|
tb->onCloseClicked();
|
||||||
|
|
||||||
|
QVERIFY(!dock3->isOpen());
|
||||||
|
QVERIFY(dock2->isOpen());
|
||||||
|
QVERIFY(dock1->isOpen());
|
||||||
|
QCOMPARE(frame->dockWidgetCount(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void TestDocks::tst_tabWidgetCurrentIndex()
|
void TestDocks::tst_tabWidgetCurrentIndex()
|
||||||
{
|
{
|
||||||
EnsureTopLevelsDeleted e;
|
EnsureTopLevelsDeleted e;
|
||||||
@@ -6487,4 +6747,37 @@ void TestDocks::tst_dock2FloatingWidgetsTabbed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestDocks::tst_deleteOnClose()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// Tests that DockWidget::close() deletes itself if Option_DeleteOnClose is set
|
||||||
|
QPointer<DockWidgetBase> dock1 = createDockWidget("1", new MyWidget2(QSize(400, 400)), DockWidgetBase::Option_DeleteOnClose);
|
||||||
|
dock1->show();
|
||||||
|
dock1->close();
|
||||||
|
|
||||||
|
QVERIFY(Testing::waitForDeleted(dock1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Tests that if it's closed via LayoutSaver it's also destroyed when having Option_DeleteOnClose
|
||||||
|
|
||||||
|
QPointer<DockWidgetBase> dock1 = createDockWidget("1", new MyWidget2(QSize(400, 400)), DockWidgetBase::Option_DeleteOnClose, {}, /*show=*/ false);
|
||||||
|
QPointer<DockWidgetBase> dock2 = createDockWidget("2", new MyWidget2(QSize(400, 400)), {}, {}, /*show=*/ false);
|
||||||
|
LayoutSaver saver;
|
||||||
|
const QByteArray saved = saver.serializeLayout();
|
||||||
|
dock1->show();
|
||||||
|
dock2->show();
|
||||||
|
QVERIFY(dock1->isVisible());
|
||||||
|
QVERIFY(dock2->isVisible());
|
||||||
|
|
||||||
|
QVERIFY(saver.restoreLayout(saved));
|
||||||
|
QVERIFY(!dock1->isVisible());
|
||||||
|
QVERIFY(!dock2->isVisible());
|
||||||
|
|
||||||
|
QVERIFY(Testing::waitForDeleted(dock1));
|
||||||
|
QVERIFY(dock2.data());
|
||||||
|
delete dock2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#include "tst_docks.moc"
|
#include "tst_docks.moc"
|
||||||
|
|||||||
@@ -70,11 +70,13 @@ KDDockWidgets::Tests::createMainWindow(QSize sz, KDDockWidgets::MainWindowOption
|
|||||||
}
|
}
|
||||||
|
|
||||||
DockWidgetBase *KDDockWidgets::Tests::createDockWidget(const QString &name, QWidgetOrQuick *w,
|
DockWidgetBase *KDDockWidgets::Tests::createDockWidget(const QString &name, QWidgetOrQuick *w,
|
||||||
DockWidgetBase::Options options, bool show,
|
DockWidgetBase::Options options,
|
||||||
|
DockWidgetBase::LayoutSaverOptions layoutSaverOptions,
|
||||||
|
bool show,
|
||||||
const QString &affinityName)
|
const QString &affinityName)
|
||||||
{
|
{
|
||||||
w->setFocusPolicy(Qt::StrongFocus);
|
w->setFocusPolicy(Qt::StrongFocus);
|
||||||
auto dock = new DockWidgetType(name, options);
|
auto dock = new DockWidgetType(name, options, layoutSaverOptions);
|
||||||
dock->setAffinityName(affinityName);
|
dock->setAffinityName(affinityName);
|
||||||
dock->setWidget(w);
|
dock->setWidget(w);
|
||||||
dock->setObjectName(name);
|
dock->setObjectName(name);
|
||||||
@@ -132,7 +134,7 @@ std::unique_ptr<MainWindowBase> KDDockWidgets::Tests::createMainWindow(QVector<D
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (DockDescriptor &desc : docks) {
|
for (DockDescriptor &desc : docks) {
|
||||||
desc.createdDock = createDockWidget(QStringLiteral("%1-%2").arg(i).arg(count), createGuestWidget(i), {}, false);
|
desc.createdDock = createDockWidget(QStringLiteral("%1-%2").arg(i).arg(count), createGuestWidget(i), {}, {}, false);
|
||||||
DockWidgetBase *relativeTo = nullptr;
|
DockWidgetBase *relativeTo = nullptr;
|
||||||
if (desc.relativeToIndex != -1)
|
if (desc.relativeToIndex != -1)
|
||||||
relativeTo = docks.at(desc.relativeToIndex).createdDock;
|
relativeTo = docks.at(desc.relativeToIndex).createdDock;
|
||||||
|
|||||||
@@ -136,8 +136,8 @@ std::unique_ptr<MainWindowBase> createMainWindow(QSize sz = {1000, 1000},
|
|||||||
std::unique_ptr<KDDockWidgets::MainWindowBase> createMainWindow(QVector<DockDescriptor> &docks);
|
std::unique_ptr<KDDockWidgets::MainWindowBase> createMainWindow(QVector<DockDescriptor> &docks);
|
||||||
|
|
||||||
KDDockWidgets::DockWidgetBase *createDockWidget(const QString &name, QWidgetOrQuick *w,
|
KDDockWidgets::DockWidgetBase *createDockWidget(const QString &name, QWidgetOrQuick *w,
|
||||||
DockWidgetBase::Options options = {}, bool show = true,
|
DockWidgetBase::Options options = {}, DockWidgetBase::LayoutSaverOptions layoutSaverOptions = {},
|
||||||
const QString &affinityName = {});
|
bool show = true, const QString &affinityName = {});
|
||||||
KDDockWidgets::DockWidgetBase *createDockWidget(const QString &name, QColor color = Qt::black);
|
KDDockWidgets::DockWidgetBase *createDockWidget(const QString &name, QColor color = Qt::black);
|
||||||
|
|
||||||
void nestDockWidget(DockWidgetBase *dock, DropArea *dropArea, Frame *relativeTo,
|
void nestDockWidget(DockWidgetBase *dock, DropArea *dropArea, Frame *relativeTo,
|
||||||
|
|||||||
Reference in New Issue
Block a user