Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae997d3d75 | ||
|
|
c48cf3875d | ||
|
|
46fb18fc58 | ||
|
|
8da6904dcd | ||
|
|
2a51359159 | ||
|
|
ec48140309 | ||
|
|
fe64f407c0 | ||
|
|
136d6d966c | ||
|
|
de645b3cca | ||
|
|
f6174faebb | ||
|
|
0d3ec46095 | ||
|
|
53fed8b765 | ||
|
|
5752bfb58b | ||
|
|
5378d90ba7 | ||
|
|
ae96bbc0a0 | ||
|
|
c10ff7c688 | ||
|
|
d2fb1579a5 | ||
|
|
156cc71040 | ||
|
|
909c189d7f | ||
|
|
50c529b77f | ||
|
|
84b501205a | ||
|
|
664a1674ab | ||
|
|
0c5ef5e158 | ||
|
|
b776fc24a6 | ||
|
|
c5e7104413 | ||
|
|
2c7764ecf7 | ||
|
|
bed99eacc2 | ||
|
|
dae677e479 | ||
|
|
a05078c947 | ||
|
|
3fcf05fb29 | ||
|
|
cdca8c2ac0 | ||
|
|
53ec8b896a | ||
|
|
6e6c1512a6 | ||
|
|
8e0ea57319 | ||
|
|
9bd55cc15a | ||
|
|
c8d4487a95 | ||
|
|
12b0182337 | ||
|
|
a2b07fd97f | ||
|
|
078905181e | ||
|
|
7c9ed9b624 | ||
|
|
ac164c3a97 | ||
|
|
2b7232c9b3 | ||
|
|
6cc7d79832 | ||
|
|
0b88843d76 | ||
|
|
554f26a614 | ||
|
|
10fbb6f302 | ||
|
|
bf27207dd9 | ||
|
|
97f02d39e6 | ||
|
|
64231d037d | ||
|
|
6eb869014e | ||
|
|
a564ca5ce5 | ||
|
|
365b989364 | ||
|
|
a3baf7dcf6 | ||
|
|
538e690c22 | ||
|
|
b1309da89a | ||
|
|
d2f751ef87 | ||
|
|
35c1b04c58 | ||
|
|
0de1a9ccae | ||
|
|
c45327aafd | ||
|
|
8853c751d6 | ||
|
|
e978a32a09 | ||
|
|
ca5683f5bf | ||
|
|
c630a59afe | ||
|
|
b9b8ff9c76 | ||
|
|
e2c5204d00 | ||
|
|
5ee94d7602 | ||
|
|
69894f3f88 | ||
|
|
641946bff5 | ||
|
|
27dd7a1b75 | ||
|
|
5425f2b9e1 | ||
|
|
4320e350c8 | ||
|
|
8351aa11e7 | ||
|
|
e98fd5bcb3 | ||
|
|
a012af2aac | ||
|
|
df285dd385 | ||
|
|
a6ed4354a9 | ||
|
|
1fccb943fe | ||
|
|
7bd3765fa7 | ||
|
|
9b56ca08e1 | ||
|
|
f7c8384b73 | ||
|
|
957dce5d1f |
18
.cproject
18
.cproject
@@ -71,15 +71,6 @@
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope"/>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.1947822681;cdt.managedbuild.tool.gnu.cpp.compiler.input.1318830536">
|
||||
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.389117097;cdt.managedbuild.tool.gnu.c.compiler.input.1568363924">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
||||
<buildTargets>
|
||||
<target name="Build all" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
@@ -356,4 +347,13 @@
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.1947822681;cdt.managedbuild.tool.gnu.cpp.compiler.input.1318830536">
|
||||
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.389117097;cdt.managedbuild.tool.gnu.c.compiler.input.1568363924">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
</cproject>
|
||||
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
*.pro.user
|
||||
/ build
|
||||
/build
|
||||
*.o
|
||||
*.dylib
|
||||
*.app
|
||||
@@ -8,3 +8,11 @@ moc_*
|
||||
ui_*
|
||||
Makefile
|
||||
|
||||
# IDEs
|
||||
.idea
|
||||
|
||||
# Python
|
||||
.eggs
|
||||
*.pyc
|
||||
*.pyd
|
||||
__pycache__
|
||||
@@ -40,6 +40,7 @@ set(ads_SRCS
|
||||
src/ElidingLabel.cpp
|
||||
src/FloatingDockContainer.cpp
|
||||
src/ads.qrc
|
||||
src/linux/FloatingWidgetTitleBar.cpp
|
||||
)
|
||||
set(ads_INSTALL_INCLUDE
|
||||
src/ads_globals.h
|
||||
@@ -54,6 +55,7 @@ set(ads_INSTALL_INCLUDE
|
||||
src/DockWidgetTab.h
|
||||
src/ElidingLabel.h
|
||||
src/FloatingDockContainer.h
|
||||
src/linux/FloatingWidgetTitleBar.h
|
||||
)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
|
||||
set(ads_PlatformDir "x86")
|
||||
@@ -62,7 +64,7 @@ else()
|
||||
endif()
|
||||
if(BUILD_STATIC)
|
||||
add_library(qtadvanceddocking STATIC ${ads_SRCS})
|
||||
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ADS_STATIC)
|
||||
target_compile_definitions(qtadvanceddocking PUBLIC ADS_STATIC)
|
||||
else()
|
||||
add_library(qtadvanceddocking SHARED ${ads_SRCS})
|
||||
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ADS_SHARED_EXPORT)
|
||||
@@ -78,20 +80,36 @@ install(FILES
|
||||
COMPONENT license
|
||||
)
|
||||
install(TARGETS qtadvanceddocking
|
||||
EXPORT adsBinary
|
||||
RUNTIME DESTINATION bin COMPONENT library
|
||||
LIBRARY DESTINATION lib COMPONENT library
|
||||
ARCHIVE DESTINATION lib COMPONENT library
|
||||
EXPORT adsTargets
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
INCLUDES DESTINATION include
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file("adsConfigVersion.cmake"
|
||||
VERSION ${ads_VERSION}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
install(EXPORT adsTargets
|
||||
FILE adsTargets.cmake
|
||||
NAMESPACE ads::
|
||||
DESTINATION lib/cmake/ads
|
||||
)
|
||||
install(FILES "adsConfig.cmake" "${CMAKE_BINARY_DIR}/adsConfigVersion.cmake"
|
||||
DESTINATION lib/cmake/ads
|
||||
)
|
||||
|
||||
target_include_directories(qtadvanceddocking PUBLIC
|
||||
$<BUILD_INTERFACE:${ads_INCLUDE}>
|
||||
"$<BUILD_INTERFACE:${ads_INCLUDE}>"
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
target_link_libraries(qtadvanceddocking PUBLIC ${ads_LIBS})
|
||||
target_compile_definitions(qtadvanceddocking PRIVATE ${ads_COMPILE_DEFINE})
|
||||
set_target_properties(qtadvanceddocking PROPERTIES
|
||||
VERSION ${ads_VERSION}
|
||||
EXPORT_NAME "Qt Advanced Docking System"
|
||||
EXPORT_NAME "QtAdvancedDockingSystem"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
|
||||
|
||||
10
PyQtAds/QtAds/__init__.py
Normal file
10
PyQtAds/QtAds/__init__.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from .ads import ads
|
||||
from .._version import *
|
||||
|
||||
import inspect
|
||||
|
||||
for name, member in inspect.getmembers(ads):
|
||||
if not name.startswith('_'):
|
||||
globals()[name] = member
|
||||
|
||||
del ads
|
||||
1
PyQtAds/__init__.py
Normal file
1
PyQtAds/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .rc import *
|
||||
9
PyQtAds/_version.py
Normal file
9
PyQtAds/_version.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# THIS FILE IS GENERATED FROM PyQtAds SETUP.PY
|
||||
|
||||
short_version = '2.5.1'
|
||||
version = '2.5.1'
|
||||
full_version = '2.5.1'
|
||||
git_revision = 'c10ff7c688fb50fe9157bad3982164e0f955f9e4'
|
||||
release = True
|
||||
if not release:
|
||||
version = full_version
|
||||
670
PyQtAds/rc.py
Normal file
670
PyQtAds/rc.py
Normal file
@@ -0,0 +1,670 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Resource object code
|
||||
#
|
||||
# Created by: The Resource Compiler for PyQt5 (Qt v5.9.7)
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
qt_resource_data = b"\
|
||||
\x00\x00\x0b\x04\
|
||||
\x3c\
|
||||
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
|
||||
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\
|
||||
\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\
|
||||
\x6e\x6f\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
|
||||
\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
|
||||
\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x30\x2e\x30\x2c\
|
||||
\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
|
||||
\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
|
||||
\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
|
||||
\x20\x20\x2d\x2d\x3e\x0d\x0a\x0d\x0a\x3c\x73\x76\x67\x0d\x0a\x20\
|
||||
\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\
|
||||
\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\
|
||||
\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0d\x0a\x20\
|
||||
\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\
|
||||
\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\
|
||||
\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\x22\x0d\x0a\x20\x20\x20\
|
||||
\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\
|
||||
\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
|
||||
\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\
|
||||
\x61\x78\x2d\x6e\x73\x23\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\
|
||||
\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
|
||||
\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\
|
||||
\x67\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\
|
||||
\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\
|
||||
\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0d\x0a\x20\x20\x20\x78\x6d\
|
||||
\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\
|
||||
\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\
|
||||
\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\
|
||||
\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\
|
||||
\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\
|
||||
\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\
|
||||
\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\
|
||||
\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\
|
||||
\x65\x22\x0d\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\
|
||||
\x31\x2e\x31\x22\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x43\x61\x70\
|
||||
\x61\x5f\x31\x22\x0d\x0a\x20\x20\x20\x78\x3d\x22\x30\x70\x78\x22\
|
||||
\x0d\x0a\x20\x20\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x20\x20\
|
||||
\x20\x77\x69\x64\x74\x68\x3d\x22\x35\x31\x32\x22\x0d\x0a\x20\x20\
|
||||
\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x31\x32\x22\x0d\x0a\x20\
|
||||
\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x35\
|
||||
\x31\x32\x20\x35\x31\x32\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x3a\
|
||||
\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\
|
||||
\x0d\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\
|
||||
\x63\x6e\x61\x6d\x65\x3d\x22\x63\x6c\x6f\x73\x65\x2d\x62\x75\x74\
|
||||
\x74\x6f\x6e\x2e\x73\x76\x67\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\
|
||||
\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\
|
||||
\x2e\x39\x32\x2e\x33\x20\x28\x32\x34\x30\x35\x35\x34\x36\x2c\x20\
|
||||
\x32\x30\x31\x38\x2d\x30\x33\x2d\x31\x31\x29\x22\x3e\x3c\x6d\x65\
|
||||
\x74\x61\x64\x61\x74\x61\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x6d\
|
||||
\x65\x74\x61\x64\x61\x74\x61\x38\x39\x37\x22\x3e\x3c\x72\x64\x66\
|
||||
\x3a\x52\x44\x46\x3e\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0d\x0a\x20\
|
||||
\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\
|
||||
\x22\x22\x3e\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\
|
||||
\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\
|
||||
\x66\x6f\x72\x6d\x61\x74\x3e\x3c\x64\x63\x3a\x74\x79\x70\x65\x0d\
|
||||
\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\
|
||||
\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\
|
||||
\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\
|
||||
\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\
|
||||
\x2f\x3e\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\
|
||||
\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\
|
||||
\x3e\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x3c\x2f\x6d\x65\x74\
|
||||
\x61\x64\x61\x74\x61\x3e\x3c\x64\x65\x66\x73\x0d\x0a\x20\x20\x20\
|
||||
\x69\x64\x3d\x22\x64\x65\x66\x73\x38\x39\x35\x22\x20\x2f\x3e\x3c\
|
||||
\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\
|
||||
\x65\x77\x0d\x0a\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\
|
||||
\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0d\x0a\x20\x20\x20\x62\
|
||||
\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\
|
||||
\x36\x36\x36\x22\x0d\x0a\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\
|
||||
\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0d\x0a\x20\x20\x20\x6f\
|
||||
\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\
|
||||
\x31\x30\x22\x0d\x0a\x20\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\
|
||||
\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0d\x0a\x20\x20\x20\x67\
|
||||
\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\
|
||||
\x30\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\
|
||||
\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0d\
|
||||
\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\
|
||||
\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0d\x0a\x20\x20\x20\
|
||||
\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\
|
||||
\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x32\x30\x22\x0d\x0a\x20\x20\
|
||||
\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\
|
||||
\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x31\x37\x22\x0d\x0a\
|
||||
\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\
|
||||
\x38\x39\x33\x22\x0d\x0a\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\
|
||||
\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0d\x0a\x20\x20\x20\x66\x69\
|
||||
\x74\x2d\x6d\x61\x72\x67\x69\x6e\x2d\x74\x6f\x70\x3d\x22\x30\x22\
|
||||
\x0d\x0a\x20\x20\x20\x66\x69\x74\x2d\x6d\x61\x72\x67\x69\x6e\x2d\
|
||||
\x6c\x65\x66\x74\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\x66\x69\x74\
|
||||
\x2d\x6d\x61\x72\x67\x69\x6e\x2d\x72\x69\x67\x68\x74\x3d\x22\x30\
|
||||
\x22\x0d\x0a\x20\x20\x20\x66\x69\x74\x2d\x6d\x61\x72\x67\x69\x6e\
|
||||
\x2d\x62\x6f\x74\x74\x6f\x6d\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\
|
||||
\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x30\
|
||||
\x2e\x38\x35\x38\x36\x32\x39\x36\x36\x22\x0d\x0a\x20\x20\x20\x69\
|
||||
\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x33\x34\x35\x2e\
|
||||
\x32\x39\x31\x34\x32\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\
|
||||
\x61\x70\x65\x3a\x63\x79\x3d\x22\x33\x32\x2e\x37\x33\x31\x32\x35\
|
||||
\x38\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\
|
||||
\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x2d\x38\x22\x0d\x0a\x20\
|
||||
\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\
|
||||
\x77\x2d\x79\x3d\x22\x2d\x38\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\
|
||||
\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\
|
||||
\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0d\x0a\x20\x20\x20\x69\
|
||||
\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\
|
||||
\x6c\x61\x79\x65\x72\x3d\x22\x43\x61\x70\x61\x5f\x31\x22\x20\x2f\
|
||||
\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\
|
||||
\x36\x30\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\
|
||||
\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x37\x31\x37\x30\
|
||||
\x38\x36\x38\x33\x2c\x30\x2c\x30\x2c\x30\x2e\x37\x31\x37\x30\x38\
|
||||
\x36\x38\x33\x2c\x31\x32\x38\x2c\x31\x32\x38\x29\x22\x3e\x0d\x0a\
|
||||
\x09\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x63\x6c\x6f\x73\
|
||||
\x65\x22\x3e\x0d\x0a\x09\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x0d\
|
||||
\x0a\x20\x20\x20\x70\x6f\x69\x6e\x74\x73\x3d\x22\x33\x35\x37\x2c\
|
||||
\x33\x32\x31\x2e\x33\x20\x32\x31\x34\x2e\x32\x2c\x31\x37\x38\x2e\
|
||||
\x35\x20\x33\x35\x37\x2c\x33\x35\x2e\x37\x20\x33\x32\x31\x2e\x33\
|
||||
\x2c\x30\x20\x31\x37\x38\x2e\x35\x2c\x31\x34\x32\x2e\x38\x20\x33\
|
||||
\x35\x2e\x37\x2c\x30\x20\x30\x2c\x33\x35\x2e\x37\x20\x31\x34\x32\
|
||||
\x2e\x38\x2c\x31\x37\x38\x2e\x35\x20\x30\x2c\x33\x32\x31\x2e\x33\
|
||||
\x20\x33\x35\x2e\x37\x2c\x33\x35\x37\x20\x31\x37\x38\x2e\x35\x2c\
|
||||
\x32\x31\x34\x2e\x32\x20\x33\x32\x31\x2e\x33\x2c\x33\x35\x37\x20\
|
||||
\x22\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x70\x6f\x6c\x79\x67\x6f\
|
||||
\x6e\x38\x35\x37\x22\x20\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\
|
||||
\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\
|
||||
\x3d\x22\x67\x38\x36\x32\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\
|
||||
\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\
|
||||
\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\
|
||||
\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x36\x34\
|
||||
\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
|
||||
\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\
|
||||
\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\
|
||||
\x20\x20\x69\x64\x3d\x22\x67\x38\x36\x36\x22\x0d\x0a\x20\x20\x20\
|
||||
\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\
|
||||
\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\
|
||||
\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\
|
||||
\x67\x38\x36\x38\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\
|
||||
\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\
|
||||
\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\
|
||||
\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x37\x30\x22\x0d\
|
||||
\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\
|
||||
\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\
|
||||
\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\
|
||||
\x69\x64\x3d\x22\x67\x38\x37\x32\x22\x0d\x0a\x20\x20\x20\x74\x72\
|
||||
\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\
|
||||
\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\
|
||||
\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\
|
||||
\x37\x34\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\
|
||||
\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\
|
||||
\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\
|
||||
\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x37\x36\x22\x0d\x0a\x20\
|
||||
\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\
|
||||
\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\
|
||||
\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\
|
||||
\x3d\x22\x67\x38\x37\x38\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\
|
||||
\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\
|
||||
\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\
|
||||
\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x38\x30\
|
||||
\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
|
||||
\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\
|
||||
\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\
|
||||
\x20\x20\x69\x64\x3d\x22\x67\x38\x38\x32\x22\x0d\x0a\x20\x20\x20\
|
||||
\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\
|
||||
\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\
|
||||
\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\
|
||||
\x67\x38\x38\x34\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\
|
||||
\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\
|
||||
\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\
|
||||
\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x38\x36\x22\x0d\
|
||||
\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\
|
||||
\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\
|
||||
\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\
|
||||
\x69\x64\x3d\x22\x67\x38\x38\x38\x22\x0d\x0a\x20\x20\x20\x74\x72\
|
||||
\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\
|
||||
\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\
|
||||
\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\
|
||||
\x39\x30\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\
|
||||
\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\
|
||||
\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
|
||||
\x76\x67\x3e\
|
||||
\x00\x00\x0b\xf7\
|
||||
\x3c\
|
||||
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
|
||||
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\
|
||||
\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\
|
||||
\x6e\x6f\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
|
||||
\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
|
||||
\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x30\x2e\x30\x2c\
|
||||
\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
|
||||
\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
|
||||
\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
|
||||
\x20\x20\x2d\x2d\x3e\x0d\x0a\x0d\x0a\x3c\x73\x76\x67\x0d\x0a\x20\
|
||||
\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\
|
||||
\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\
|
||||
\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0d\x0a\x20\
|
||||
\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\
|
||||
\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\
|
||||
\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\x22\x0d\x0a\x20\x20\x20\
|
||||
\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\
|
||||
\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
|
||||
\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\
|
||||
\x61\x78\x2d\x6e\x73\x23\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\
|
||||
\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
|
||||
\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\
|
||||
\x67\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\
|
||||
\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\
|
||||
\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0d\x0a\x20\x20\x20\x78\x6d\
|
||||
\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\
|
||||
\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\
|
||||
\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\
|
||||
\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\
|
||||
\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\
|
||||
\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\
|
||||
\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\
|
||||
\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\
|
||||
\x65\x22\x0d\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\
|
||||
\x31\x2e\x31\x22\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x43\x61\x70\
|
||||
\x61\x5f\x31\x22\x0d\x0a\x20\x20\x20\x78\x3d\x22\x30\x70\x78\x22\
|
||||
\x0d\x0a\x20\x20\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x20\x20\
|
||||
\x20\x77\x69\x64\x74\x68\x3d\x22\x35\x31\x32\x22\x0d\x0a\x20\x20\
|
||||
\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x31\x32\x22\x0d\x0a\x20\
|
||||
\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x35\
|
||||
\x31\x32\x20\x35\x31\x32\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x3a\
|
||||
\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\
|
||||
\x0d\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\
|
||||
\x63\x6e\x61\x6d\x65\x3d\x22\x63\x6c\x6f\x73\x65\x2d\x62\x75\x74\
|
||||
\x74\x6f\x6e\x2d\x64\x69\x73\x61\x62\x6c\x65\x64\x2e\x73\x76\x67\
|
||||
\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\
|
||||
\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x33\x20\x28\
|
||||
\x32\x34\x30\x35\x35\x34\x36\x2c\x20\x32\x30\x31\x38\x2d\x30\x33\
|
||||
\x2d\x31\x31\x29\x22\x3e\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0d\
|
||||
\x0a\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\
|
||||
\x38\x39\x37\x22\x3e\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x3c\x63\
|
||||
\x63\x3a\x57\x6f\x72\x6b\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x72\
|
||||
\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x3c\x64\x63\x3a\
|
||||
\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\
|
||||
\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\
|
||||
\x3c\x64\x63\x3a\x74\x79\x70\x65\x0d\x0a\x20\x20\x20\x20\x20\x20\
|
||||
\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\
|
||||
\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\
|
||||
\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\
|
||||
\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x3c\x64\x63\x3a\x74\
|
||||
\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\
|
||||
\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x3c\x2f\x72\x64\x66\x3a\
|
||||
\x52\x44\x46\x3e\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x3c\
|
||||
\x64\x65\x66\x73\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\
|
||||
\x73\x38\x39\x35\x22\x20\x2f\x3e\x3c\x73\x6f\x64\x69\x70\x6f\x64\
|
||||
\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0d\x0a\x20\x20\x20\
|
||||
\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\
|
||||
\x66\x66\x22\x0d\x0a\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\
|
||||
\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0d\x0a\x20\
|
||||
\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\
|
||||
\x22\x31\x22\x0d\x0a\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\
|
||||
\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0d\x0a\x20\x20\
|
||||
\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\
|
||||
\x31\x30\x22\x0d\x0a\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\
|
||||
\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0d\x0a\x20\x20\x20\
|
||||
\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\
|
||||
\x63\x69\x74\x79\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\
|
||||
\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\
|
||||
\x3d\x22\x32\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\
|
||||
\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\
|
||||
\x31\x39\x32\x30\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\
|
||||
\x3d\x22\x31\x30\x31\x37\x22\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\
|
||||
\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x38\x39\x33\x22\x0d\x0a\x20\
|
||||
\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\x73\
|
||||
\x65\x22\x0d\x0a\x20\x20\x20\x66\x69\x74\x2d\x6d\x61\x72\x67\x69\
|
||||
\x6e\x2d\x74\x6f\x70\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\x66\x69\
|
||||
\x74\x2d\x6d\x61\x72\x67\x69\x6e\x2d\x6c\x65\x66\x74\x3d\x22\x30\
|
||||
\x22\x0d\x0a\x20\x20\x20\x66\x69\x74\x2d\x6d\x61\x72\x67\x69\x6e\
|
||||
\x2d\x72\x69\x67\x68\x74\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\x66\
|
||||
\x69\x74\x2d\x6d\x61\x72\x67\x69\x6e\x2d\x62\x6f\x74\x74\x6f\x6d\
|
||||
\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\
|
||||
\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x30\x2e\x38\x35\x38\x36\x32\x39\
|
||||
\x36\x36\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\
|
||||
\x3a\x63\x78\x3d\x22\x33\x34\x35\x2e\x32\x39\x31\x34\x32\x22\x0d\
|
||||
\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\
|
||||
\x22\x33\x32\x2e\x37\x33\x31\x32\x35\x38\x22\x0d\x0a\x20\x20\x20\
|
||||
\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\
|
||||
\x78\x3d\x22\x2d\x38\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\
|
||||
\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x2d\x38\
|
||||
\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\
|
||||
\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\
|
||||
\x22\x31\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\
|
||||
\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\
|
||||
\x43\x61\x70\x61\x5f\x31\x22\x20\x2f\x3e\x0d\x0a\x3c\x67\x0d\x0a\
|
||||
\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x36\x30\x22\x0d\x0a\x20\x20\
|
||||
\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\
|
||||
\x69\x78\x28\x30\x2e\x37\x31\x37\x30\x38\x36\x38\x33\x2c\x30\x2c\
|
||||
\x30\x2c\x30\x2e\x37\x31\x37\x30\x38\x36\x38\x33\x2c\x31\x32\x38\
|
||||
\x2c\x31\x32\x38\x29\x22\x0d\x0a\x20\x20\x20\x73\x74\x79\x6c\x65\
|
||||
\x3d\x22\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\
|
||||
\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\
|
||||
\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\
|
||||
\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x35\x30\x31\x39\x36\
|
||||
\x30\x38\x31\x22\x3e\x0d\x0a\x09\x3c\x67\x0d\x0a\x20\x20\x20\x69\
|
||||
\x64\x3d\x22\x63\x6c\x6f\x73\x65\x22\x0d\x0a\x20\x20\x20\x73\x74\
|
||||
\x79\x6c\x65\x3d\x22\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\
|
||||
\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\
|
||||
\x31\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\
|
||||
\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x35\x30\
|
||||
\x31\x39\x36\x30\x38\x31\x22\x3e\x0d\x0a\x09\x09\x3c\x70\x6f\x6c\
|
||||
\x79\x67\x6f\x6e\x0d\x0a\x20\x20\x20\x70\x6f\x69\x6e\x74\x73\x3d\
|
||||
\x22\x33\x35\x37\x2c\x33\x32\x31\x2e\x33\x20\x32\x31\x34\x2e\x32\
|
||||
\x2c\x31\x37\x38\x2e\x35\x20\x33\x35\x37\x2c\x33\x35\x2e\x37\x20\
|
||||
\x33\x32\x31\x2e\x33\x2c\x30\x20\x31\x37\x38\x2e\x35\x2c\x31\x34\
|
||||
\x32\x2e\x38\x20\x33\x35\x2e\x37\x2c\x30\x20\x30\x2c\x33\x35\x2e\
|
||||
\x37\x20\x31\x34\x32\x2e\x38\x2c\x31\x37\x38\x2e\x35\x20\x30\x2c\
|
||||
\x33\x32\x31\x2e\x33\x20\x33\x35\x2e\x37\x2c\x33\x35\x37\x20\x31\
|
||||
\x37\x38\x2e\x35\x2c\x32\x31\x34\x2e\x32\x20\x33\x32\x31\x2e\x33\
|
||||
\x2c\x33\x35\x37\x20\x22\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x70\
|
||||
\x6f\x6c\x79\x67\x6f\x6e\x38\x35\x37\x22\x0d\x0a\x20\x20\x20\x73\
|
||||
\x74\x79\x6c\x65\x3d\x22\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\
|
||||
\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\
|
||||
\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\
|
||||
\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x35\
|
||||
\x30\x31\x39\x36\x30\x38\x31\x22\x20\x2f\x3e\x0d\x0a\x09\x3c\x2f\
|
||||
\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\
|
||||
\x20\x69\x64\x3d\x22\x67\x38\x36\x32\x22\x0d\x0a\x20\x20\x20\x74\
|
||||
\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\
|
||||
\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\
|
||||
\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\
|
||||
\x38\x36\x34\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\
|
||||
\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\
|
||||
\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\
|
||||
\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x36\x36\x22\x0d\x0a\
|
||||
\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\
|
||||
\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\
|
||||
\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\
|
||||
\x64\x3d\x22\x67\x38\x36\x38\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\
|
||||
\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\
|
||||
\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\
|
||||
\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x37\
|
||||
\x30\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
|
||||
\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\
|
||||
\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\
|
||||
\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x37\x32\x22\x0d\x0a\x20\x20\
|
||||
\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\
|
||||
\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\
|
||||
\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\
|
||||
\x22\x67\x38\x37\x34\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\
|
||||
\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\
|
||||
\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\
|
||||
\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x37\x36\x22\
|
||||
\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\
|
||||
\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\
|
||||
\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\
|
||||
\x20\x69\x64\x3d\x22\x67\x38\x37\x38\x22\x0d\x0a\x20\x20\x20\x74\
|
||||
\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\
|
||||
\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\
|
||||
\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\
|
||||
\x38\x38\x30\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\
|
||||
\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\
|
||||
\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\
|
||||
\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x38\x32\x22\x0d\x0a\
|
||||
\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\
|
||||
\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\
|
||||
\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\
|
||||
\x64\x3d\x22\x67\x38\x38\x34\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\
|
||||
\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\
|
||||
\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\
|
||||
\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x38\
|
||||
\x36\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
|
||||
\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\
|
||||
\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\
|
||||
\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x38\x38\x22\x0d\x0a\x20\x20\
|
||||
\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\
|
||||
\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\
|
||||
\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\
|
||||
\x22\x67\x38\x39\x30\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\
|
||||
\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\
|
||||
\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\
|
||||
\x3c\x2f\x73\x76\x67\x3e\
|
||||
\x00\x00\x06\x61\
|
||||
\x0d\
|
||||
\x0a\x2f\x2a\x0d\x0a\x20\x2a\x20\x44\x65\x66\x61\x75\x6c\x74\x20\
|
||||
\x73\x74\x79\x6c\x65\x20\x73\x68\x65\x65\x74\x20\x6f\x6e\x20\x57\
|
||||
\x69\x6e\x64\x6f\x77\x73\x20\x50\x6c\x61\x74\x66\x6f\x72\x6d\x73\
|
||||
\x0d\x0a\x20\x2a\x20\x4e\x6f\x74\x65\x3a\x20\x41\x6c\x77\x61\x79\
|
||||
\x73\x20\x75\x73\x65\x20\x43\x53\x53\x2d\x63\x6c\x61\x73\x73\x65\
|
||||
\x73\x20\x77\x69\x74\x68\x20\x61\x6e\x64\x20\x77\x69\x74\x68\x6f\
|
||||
\x75\x74\x20\x22\x61\x64\x73\x2d\x2d\x22\x20\x6e\x61\x6d\x65\x73\
|
||||
\x70\x61\x63\x65\x20\x74\x6f\x20\x73\x75\x70\x70\x6f\x72\x74\x20\
|
||||
\x51\x74\x34\x20\x26\x20\x51\x74\x35\x0d\x0a\x20\x2a\x2f\x0d\x0a\
|
||||
\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x43\x6f\x6e\x74\
|
||||
\x61\x69\x6e\x65\x72\x57\x69\x64\x67\x65\x74\x0d\x0a\x7b\x0d\x0a\
|
||||
\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\
|
||||
\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\x6b\x29\x3b\x0d\x0a\
|
||||
\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x43\
|
||||
\x6f\x6e\x74\x61\x69\x6e\x65\x72\x57\x69\x64\x67\x65\x74\x20\x51\
|
||||
\x53\x70\x6c\x69\x74\x74\x65\x72\x3a\x3a\x68\x61\x6e\x64\x6c\x65\
|
||||
\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\
|
||||
\x75\x6e\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\
|
||||
\x6b\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\
|
||||
\x44\x6f\x63\x6b\x41\x72\x65\x61\x57\x69\x64\x67\x65\x74\x0d\x0a\
|
||||
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
|
||||
\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\
|
||||
\x77\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x3a\
|
||||
\x20\x31\x70\x78\x20\x73\x6f\x6c\x69\x64\x20\x77\x68\x69\x74\x65\
|
||||
\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\
|
||||
\x63\x6b\x41\x72\x65\x61\x57\x69\x64\x67\x65\x74\x20\x23\x74\x61\
|
||||
\x62\x73\x4d\x65\x6e\x75\x42\x75\x74\x74\x6f\x6e\x3a\x3a\x6d\x65\
|
||||
\x6e\x75\x2d\x69\x6e\x64\x69\x63\x61\x74\x6f\x72\x0d\x0a\x7b\x0d\
|
||||
\x0a\x20\x20\x20\x20\x69\x6d\x61\x67\x65\x3a\x20\x6e\x6f\x6e\x65\
|
||||
\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\
|
||||
\x44\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x0d\x0a\x7b\
|
||||
\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
|
||||
\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\x77\
|
||||
\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x63\
|
||||
\x6f\x6c\x6f\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\
|
||||
\x67\x68\x74\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\
|
||||
\x72\x2d\x73\x74\x79\x6c\x65\x3a\x20\x73\x6f\x6c\x69\x64\x3b\x0d\
|
||||
\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x77\x69\x64\x74\
|
||||
\x68\x3a\x20\x30\x20\x31\x70\x78\x20\x30\x20\x30\x3b\x0d\x0a\x20\
|
||||
\x20\x20\x20\x70\x61\x64\x64\x69\x6e\x67\x3a\x20\x30\x20\x30\x70\
|
||||
\x78\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\
|
||||
\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x5b\x61\x63\x74\
|
||||
\x69\x76\x65\x54\x61\x62\x3d\x22\x74\x72\x75\x65\x22\x5d\x0d\x0a\
|
||||
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
|
||||
\x64\x3a\x20\x71\x6c\x69\x6e\x65\x61\x72\x67\x72\x61\x64\x69\x65\
|
||||
\x6e\x74\x28\x73\x70\x72\x65\x61\x64\x3a\x70\x61\x64\x2c\x20\x78\
|
||||
\x31\x3a\x30\x2c\x20\x79\x31\x3a\x30\x2c\x20\x78\x32\x3a\x30\x2c\
|
||||
\x20\x79\x32\x3a\x30\x2e\x35\x2c\x20\x73\x74\x6f\x70\x3a\x30\x20\
|
||||
\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\x77\x29\x2c\
|
||||
\x20\x73\x74\x6f\x70\x3a\x31\x20\x70\x61\x6c\x65\x74\x74\x65\x28\
|
||||
\x6c\x69\x67\x68\x74\x29\x29\x3b\x0d\x0a\x20\x20\x20\x20\x2f\x2a\
|
||||
\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\x70\x61\x6c\x65\
|
||||
\x74\x74\x65\x28\x68\x69\x67\x68\x6c\x69\x67\x68\x74\x29\x3b\x2a\
|
||||
\x2f\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\
|
||||
\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x20\x51\x4c\x61\x62\
|
||||
\x65\x6c\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x63\x6f\x6c\x6f\x72\
|
||||
\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\x6b\x29\x3b\
|
||||
\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\
|
||||
\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x5b\x61\x63\x74\x69\x76\
|
||||
\x65\x54\x61\x62\x3d\x22\x74\x72\x75\x65\x22\x5d\x20\x51\x4c\x61\
|
||||
\x62\x65\x6c\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x63\x6f\x6c\x6f\
|
||||
\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x66\x6f\x72\x65\x67\
|
||||
\x72\x6f\x75\x6e\x64\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\
|
||||
\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x0d\x0a\
|
||||
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
|
||||
\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\x67\x68\x74\
|
||||
\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x63\
|
||||
\x6f\x6c\x6f\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\
|
||||
\x67\x68\x74\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\
|
||||
\x72\x2d\x73\x74\x79\x6c\x65\x3a\x20\x73\x6f\x6c\x69\x64\x3b\x0d\
|
||||
\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x77\x69\x64\x74\
|
||||
\x68\x3a\x20\x31\x70\x78\x20\x30\x20\x30\x20\x30\x3b\x0d\x0a\x7d\
|
||||
\x0d\x0a\x0d\x0a\x23\x74\x61\x62\x73\x4d\x65\x6e\x75\x42\x75\x74\
|
||||
\x74\x6f\x6e\x2c\x0d\x0a\x23\x63\x6c\x6f\x73\x65\x42\x75\x74\x74\
|
||||
\x6f\x6e\x2c\x0d\x0a\x23\x75\x6e\x64\x6f\x63\x6b\x42\x75\x74\x74\
|
||||
\x6f\x6e\x0d\x0a\x7b\x0d\x0a\x09\x70\x61\x64\x64\x69\x6e\x67\x3a\
|
||||
\x20\x30\x70\x78\x20\x2d\x32\x70\x78\x3b\x0d\x0a\x7d\x0d\x0a\x0d\
|
||||
\x0a\x0d\x0a\x51\x53\x63\x72\x6f\x6c\x6c\x41\x72\x65\x61\x23\x64\
|
||||
\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x53\x63\x72\x6f\x6c\x6c\x41\
|
||||
\x72\x65\x61\x0d\x0a\x7b\x0d\x0a\x09\x70\x61\x64\x64\x69\x6e\x67\
|
||||
\x3a\x20\x30\x70\x78\x3b\x0d\x0a\x09\x62\x6f\x72\x64\x65\x72\x3a\
|
||||
\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\x23\
|
||||
\x74\x61\x62\x43\x6c\x6f\x73\x65\x42\x75\x74\x74\x6f\x6e\x0d\x0a\
|
||||
\x7b\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x6d\x61\x72\x67\x69\
|
||||
\x6e\x2d\x74\x6f\x70\x3a\x20\x32\x70\x78\x3b\x0d\x0a\x20\x20\x20\
|
||||
\x20\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\
|
||||
\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\
|
||||
\x62\x6f\x72\x64\x65\x72\x3a\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x20\
|
||||
\x20\x20\x20\x20\x20\x20\x20\x70\x61\x64\x64\x69\x6e\x67\x3a\x20\
|
||||
\x30\x70\x78\x20\x2d\x32\x70\x78\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\
|
||||
\x23\x74\x61\x62\x43\x6c\x6f\x73\x65\x42\x75\x74\x74\x6f\x6e\x3a\
|
||||
\x68\x6f\x76\x65\x72\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x20\x20\
|
||||
\x20\x20\x62\x6f\x72\x64\x65\x72\x3a\x20\x31\x70\x78\x20\x73\x6f\
|
||||
\x6c\x69\x64\x20\x72\x67\x62\x61\x28\x30\x2c\x20\x30\x2c\x20\x30\
|
||||
\x2c\x20\x33\x32\x29\x3b\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\
|
||||
\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\x72\x67\x62\x61\
|
||||
\x28\x30\x2c\x20\x30\x2c\x20\x30\x2c\x20\x31\x36\x29\x3b\x0d\x0a\
|
||||
\x7d\x0d\x0a\x0d\x0a\x23\x74\x61\x62\x43\x6c\x6f\x73\x65\x42\x75\
|
||||
\x74\x74\x6f\x6e\x3a\x70\x72\x65\x73\x73\x65\x64\x0d\x0a\x7b\x0d\
|
||||
\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\
|
||||
\x75\x6e\x64\x3a\x20\x72\x67\x62\x61\x28\x30\x2c\x20\x30\x2c\x20\
|
||||
\x30\x2c\x20\x33\x32\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\
|
||||
\
|
||||
\x00\x00\x06\x30\
|
||||
\x0d\
|
||||
\x0a\x2f\x2a\x0d\x0a\x20\x2a\x20\x44\x65\x66\x61\x75\x6c\x74\x20\
|
||||
\x73\x74\x79\x6c\x65\x20\x73\x68\x65\x65\x74\x20\x6f\x6e\x20\x57\
|
||||
\x69\x6e\x64\x6f\x77\x73\x20\x50\x6c\x61\x74\x66\x6f\x72\x6d\x73\
|
||||
\x0d\x0a\x20\x2a\x20\x4e\x6f\x74\x65\x3a\x20\x41\x6c\x77\x61\x79\
|
||||
\x73\x20\x75\x73\x65\x20\x43\x53\x53\x2d\x63\x6c\x61\x73\x73\x65\
|
||||
\x73\x20\x77\x69\x74\x68\x20\x61\x6e\x64\x20\x77\x69\x74\x68\x6f\
|
||||
\x75\x74\x20\x22\x61\x64\x73\x2d\x2d\x22\x20\x6e\x61\x6d\x65\x73\
|
||||
\x70\x61\x63\x65\x20\x74\x6f\x20\x73\x75\x70\x70\x6f\x72\x74\x20\
|
||||
\x51\x74\x34\x20\x26\x20\x51\x74\x35\x0d\x0a\x20\x2a\x2f\x0d\x0a\
|
||||
\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x43\x6f\x6e\x74\
|
||||
\x61\x69\x6e\x65\x72\x57\x69\x64\x67\x65\x74\x0d\x0a\x7b\x0d\x0a\
|
||||
\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\
|
||||
\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\x6b\x29\x3b\x0d\x0a\
|
||||
\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x43\
|
||||
\x6f\x6e\x74\x61\x69\x6e\x65\x72\x57\x69\x64\x67\x65\x74\x20\x51\
|
||||
\x53\x70\x6c\x69\x74\x74\x65\x72\x3a\x3a\x68\x61\x6e\x64\x6c\x65\
|
||||
\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\
|
||||
\x75\x6e\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\
|
||||
\x6b\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\
|
||||
\x44\x6f\x63\x6b\x41\x72\x65\x61\x57\x69\x64\x67\x65\x74\x0d\x0a\
|
||||
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
|
||||
\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\
|
||||
\x77\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x3a\
|
||||
\x20\x31\x70\x78\x20\x73\x6f\x6c\x69\x64\x20\x77\x68\x69\x74\x65\
|
||||
\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\
|
||||
\x63\x6b\x41\x72\x65\x61\x57\x69\x64\x67\x65\x74\x20\x23\x74\x61\
|
||||
\x62\x73\x4d\x65\x6e\x75\x42\x75\x74\x74\x6f\x6e\x3a\x3a\x6d\x65\
|
||||
\x6e\x75\x2d\x69\x6e\x64\x69\x63\x61\x74\x6f\x72\x0d\x0a\x7b\x0d\
|
||||
\x0a\x20\x20\x20\x20\x69\x6d\x61\x67\x65\x3a\x20\x6e\x6f\x6e\x65\
|
||||
\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\
|
||||
\x44\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x0d\x0a\x7b\
|
||||
\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
|
||||
\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\x77\
|
||||
\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x63\
|
||||
\x6f\x6c\x6f\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\
|
||||
\x67\x68\x74\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\
|
||||
\x72\x2d\x73\x74\x79\x6c\x65\x3a\x20\x73\x6f\x6c\x69\x64\x3b\x0d\
|
||||
\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x77\x69\x64\x74\
|
||||
\x68\x3a\x20\x30\x20\x31\x70\x78\x20\x30\x20\x30\x3b\x0d\x0a\x20\
|
||||
\x20\x20\x20\x70\x61\x64\x64\x69\x6e\x67\x3a\x20\x30\x20\x30\x70\
|
||||
\x78\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\
|
||||
\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x5b\x61\x63\x74\
|
||||
\x69\x76\x65\x54\x61\x62\x3d\x22\x74\x72\x75\x65\x22\x5d\x0d\x0a\
|
||||
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
|
||||
\x64\x3a\x20\x71\x6c\x69\x6e\x65\x61\x72\x67\x72\x61\x64\x69\x65\
|
||||
\x6e\x74\x28\x73\x70\x72\x65\x61\x64\x3a\x70\x61\x64\x2c\x20\x78\
|
||||
\x31\x3a\x30\x2c\x20\x79\x31\x3a\x30\x2c\x20\x78\x32\x3a\x30\x2c\
|
||||
\x20\x79\x32\x3a\x30\x2e\x35\x2c\x20\x73\x74\x6f\x70\x3a\x30\x20\
|
||||
\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\x77\x29\x2c\
|
||||
\x20\x73\x74\x6f\x70\x3a\x31\x20\x70\x61\x6c\x65\x74\x74\x65\x28\
|
||||
\x6c\x69\x67\x68\x74\x29\x29\x3b\x0d\x0a\x20\x20\x20\x20\x2f\x2a\
|
||||
\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\x70\x61\x6c\x65\
|
||||
\x74\x74\x65\x28\x68\x69\x67\x68\x6c\x69\x67\x68\x74\x29\x3b\x2a\
|
||||
\x2f\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\
|
||||
\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x20\x51\x4c\x61\x62\
|
||||
\x65\x6c\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x63\x6f\x6c\x6f\x72\
|
||||
\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\x6b\x29\x3b\
|
||||
\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\
|
||||
\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x5b\x61\x63\x74\x69\x76\
|
||||
\x65\x54\x61\x62\x3d\x22\x74\x72\x75\x65\x22\x5d\x20\x51\x4c\x61\
|
||||
\x62\x65\x6c\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x63\x6f\x6c\x6f\
|
||||
\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x66\x6f\x72\x65\x67\
|
||||
\x72\x6f\x75\x6e\x64\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\
|
||||
\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x0d\x0a\
|
||||
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
|
||||
\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\x67\x68\x74\
|
||||
\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x63\
|
||||
\x6f\x6c\x6f\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\
|
||||
\x67\x68\x74\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\
|
||||
\x72\x2d\x73\x74\x79\x6c\x65\x3a\x20\x73\x6f\x6c\x69\x64\x3b\x0d\
|
||||
\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x77\x69\x64\x74\
|
||||
\x68\x3a\x20\x31\x70\x78\x20\x30\x20\x30\x20\x30\x3b\x0d\x0a\x7d\
|
||||
\x0d\x0a\x0d\x0a\x23\x74\x61\x62\x73\x4d\x65\x6e\x75\x42\x75\x74\
|
||||
\x74\x6f\x6e\x2c\x0d\x0a\x23\x63\x6c\x6f\x73\x65\x42\x75\x74\x74\
|
||||
\x6f\x6e\x2c\x0d\x0a\x23\x75\x6e\x64\x6f\x63\x6b\x42\x75\x74\x74\
|
||||
\x6f\x6e\x0d\x0a\x7b\x0d\x0a\x09\x70\x61\x64\x64\x69\x6e\x67\x3a\
|
||||
\x20\x30\x70\x78\x20\x2d\x32\x70\x78\x3b\x0d\x0a\x7d\x0d\x0a\x0d\
|
||||
\x0a\x0d\x0a\x51\x53\x63\x72\x6f\x6c\x6c\x41\x72\x65\x61\x23\x64\
|
||||
\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x53\x63\x72\x6f\x6c\x6c\x41\
|
||||
\x72\x65\x61\x0d\x0a\x7b\x0d\x0a\x09\x70\x61\x64\x64\x69\x6e\x67\
|
||||
\x3a\x20\x30\x70\x78\x3b\x0d\x0a\x09\x62\x6f\x72\x64\x65\x72\x3a\
|
||||
\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\x23\
|
||||
\x74\x61\x62\x43\x6c\x6f\x73\x65\x42\x75\x74\x74\x6f\x6e\x0d\x0a\
|
||||
\x7b\x0d\x0a\x09\x6d\x61\x72\x67\x69\x6e\x2d\x74\x6f\x70\x3a\x20\
|
||||
\x32\x70\x78\x3b\x0d\x0a\x09\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
|
||||
\x64\x3a\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x09\x62\x6f\x72\x64\x65\
|
||||
\x72\x3a\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x09\x70\x61\x64\x64\x69\
|
||||
\x6e\x67\x3a\x20\x30\x70\x78\x20\x2d\x32\x70\x78\x3b\x0d\x0a\x7d\
|
||||
\x0d\x0a\x0d\x0a\x23\x74\x61\x62\x43\x6c\x6f\x73\x65\x42\x75\x74\
|
||||
\x74\x6f\x6e\x3a\x68\x6f\x76\x65\x72\x0d\x0a\x7b\x0d\x0a\x09\x62\
|
||||
\x6f\x72\x64\x65\x72\x3a\x20\x31\x70\x78\x20\x73\x6f\x6c\x69\x64\
|
||||
\x20\x72\x67\x62\x61\x28\x30\x2c\x20\x30\x2c\x20\x30\x2c\x20\x33\
|
||||
\x32\x29\x3b\x0d\x0a\x09\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
|
||||
\x3a\x20\x72\x67\x62\x61\x28\x30\x2c\x20\x30\x2c\x20\x30\x2c\x20\
|
||||
\x31\x36\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x23\x74\x61\x62\x43\
|
||||
\x6c\x6f\x73\x65\x42\x75\x74\x74\x6f\x6e\x3a\x70\x72\x65\x73\x73\
|
||||
\x65\x64\x0d\x0a\x7b\x0d\x0a\x09\x62\x61\x63\x6b\x67\x72\x6f\x75\
|
||||
\x6e\x64\x3a\x20\x72\x67\x62\x61\x28\x30\x2c\x20\x30\x2c\x20\x30\
|
||||
\x2c\x20\x33\x32\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\
|
||||
"
|
||||
|
||||
qt_resource_name = b"\
|
||||
\x00\x03\
|
||||
\x00\x00\x67\xb3\
|
||||
\x00\x61\
|
||||
\x00\x64\x00\x73\
|
||||
\x00\x0b\
|
||||
\x0c\x6b\x3c\xf3\
|
||||
\x00\x73\
|
||||
\x00\x74\x00\x79\x00\x6c\x00\x65\x00\x73\x00\x68\x00\x65\x00\x65\x00\x74\x00\x73\
|
||||
\x00\x06\
|
||||
\x07\x03\x7d\xc3\
|
||||
\x00\x69\
|
||||
\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\
|
||||
\x00\x10\
|
||||
\x08\x7c\xee\x07\
|
||||
\x00\x63\
|
||||
\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2d\x00\x62\x00\x75\x00\x74\x00\x74\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
|
||||
\x00\x19\
|
||||
\x03\x4c\x6a\xc7\
|
||||
\x00\x63\
|
||||
\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2d\x00\x62\x00\x75\x00\x74\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x64\x00\x69\x00\x73\x00\x61\
|
||||
\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
|
||||
\x00\x11\
|
||||
\x0c\x15\xf2\x83\
|
||||
\x00\x64\
|
||||
\x00\x65\x00\x66\x00\x61\x00\x75\x00\x6c\x00\x74\x00\x5f\x00\x6c\x00\x69\x00\x6e\x00\x75\x00\x78\x00\x2e\x00\x63\x00\x73\x00\x73\
|
||||
\
|
||||
\x00\x0b\
|
||||
\x0c\xe2\x33\xa3\
|
||||
\x00\x64\
|
||||
\x00\x65\x00\x66\x00\x61\x00\x75\x00\x6c\x00\x74\x00\x2e\x00\x63\x00\x73\x00\x73\
|
||||
"
|
||||
|
||||
qt_resource_struct_v1 = b"\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\
|
||||
\x00\x00\x00\x28\x00\x02\x00\x00\x00\x02\x00\x00\x00\x06\
|
||||
\x00\x00\x00\x0c\x00\x02\x00\x00\x00\x02\x00\x00\x00\x04\
|
||||
\x00\x00\x00\x98\x00\x00\x00\x00\x00\x01\x00\x00\x17\x03\
|
||||
\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x68\
|
||||
\x00\x00\x00\x60\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x08\
|
||||
\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||
"
|
||||
|
||||
qt_resource_struct_v2 = b"\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x28\x00\x02\x00\x00\x00\x02\x00\x00\x00\x06\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x0c\x00\x02\x00\x00\x00\x02\x00\x00\x00\x04\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x98\x00\x00\x00\x00\x00\x01\x00\x00\x17\x03\
|
||||
\x00\x00\x01\x6d\xaf\xb0\x91\x61\
|
||||
\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x68\
|
||||
\x00\x00\x01\x6d\xaf\xb0\x91\x60\
|
||||
\x00\x00\x00\x60\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x08\
|
||||
\x00\x00\x01\x6d\xaf\xb0\x91\x5e\
|
||||
\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||
\x00\x00\x01\x6d\xaf\xb0\x91\x5e\
|
||||
"
|
||||
|
||||
qt_version = QtCore.qVersion().split('.')
|
||||
if qt_version < ['5', '8', '0']:
|
||||
rcc_version = 1
|
||||
qt_resource_struct = qt_resource_struct_v1
|
||||
else:
|
||||
rcc_version = 2
|
||||
qt_resource_struct = qt_resource_struct_v2
|
||||
|
||||
def qInitResources():
|
||||
QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
def qCleanupResources():
|
||||
QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
qInitResources()
|
||||
23
README.md
23
README.md
@@ -1,6 +1,7 @@
|
||||
# Advanced Docking System for Qt
|
||||
[](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
|
||||
[](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master)
|
||||
[](gnu-lgpl-v2.1.md)
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +9,7 @@ Qt Advanced Docking System lets you create customizable layouts using a full
|
||||
featured window docking system similar to what is found in many popular
|
||||
integrated development environements (IDEs) such as Visual Studio.
|
||||
Everything is implemented with standard Qt functionality without any
|
||||
platform specific code. Basic usage of QWidgets an QLayouts and using basic
|
||||
platform specific code. Basic usage of QWidgets and QLayouts and using basic
|
||||
styles as much as possible.
|
||||
|
||||
This work is based on and inspired by the
|
||||
@@ -60,9 +61,22 @@ main window layout.
|
||||

|
||||
|
||||
## Tested Compatible Environments
|
||||
- Windows 10 [](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master)
|
||||
- Ubuntu [](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
|
||||
- macOS [](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
|
||||
### Windows
|
||||
Windows 10 [](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master)
|
||||
|
||||
The library was developed on and for Windows. It is used in a commercial Windows application and is therefore constantly tested.
|
||||
|
||||
### macOS
|
||||
macOS [](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
|
||||
|
||||
The application can be compiled for macOS. A user reported, that the library works on macOS. If have not tested it.
|
||||
|
||||
### Linux
|
||||
Ubuntu [](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
|
||||
|
||||
The application can be compiled for Linux and has been developed and tested with **Kubuntu 18.04**.
|
||||
|
||||

|
||||
|
||||
## Build
|
||||
Open the `ads.pro` with QtCreator and start the build, that's it.
|
||||
@@ -144,5 +158,6 @@ MainWindow::~MainWindow()
|
||||
- Manuel Freiholz
|
||||
|
||||
## License information
|
||||
[](gnu-lgpl-v2.1.md)
|
||||
This project uses the [LGPLv2.1 license](gnu-lgpl-v2.1.md)
|
||||
|
||||
|
||||
5
adsConfig.cmake
Normal file
5
adsConfig.cmake
Normal file
@@ -0,0 +1,5 @@
|
||||
include(CMakeFindDependencyMacro)
|
||||
find_dependency(Qt5Core ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_dependency(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_dependency(Qt5Widgets ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/adsTargets.cmake")
|
||||
316
demo.py
Normal file
316
demo.py
Normal file
@@ -0,0 +1,316 @@
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
from PyQt5.QtCore import (QCoreApplication, QDir, Qt, QSettings, QSignalBlocker,
|
||||
QRect)
|
||||
from PyQt5.QtGui import QGuiApplication
|
||||
from PyQt5.QtWidgets import (QCalendarWidget, QFileSystemModel, QFrame, QLabel,
|
||||
QMenu, QTreeView, QAction, QWidgetAction,
|
||||
QComboBox, QStyle, QSizePolicy, QInputDialog)
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from PyQtAds import QtAds
|
||||
|
||||
|
||||
class _State:
|
||||
label_count = 0
|
||||
calendar_count = 0
|
||||
file_system_count = 0
|
||||
|
||||
|
||||
def create_long_text_label_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||
'''
|
||||
Create long text label dock widget
|
||||
|
||||
Parameters
|
||||
----------
|
||||
view_menu : QMenu
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : QtAds.CDockWidget
|
||||
'''
|
||||
label = QLabel()
|
||||
label.setWordWrap(True)
|
||||
label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
||||
label.setText('''\
|
||||
Label {} {} - Lorem ipsum dolor sit amet, consectetuer
|
||||
adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum
|
||||
sociis natoque penatibus et magnis dis parturient montes, nascetur
|
||||
ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium
|
||||
quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla
|
||||
vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut,
|
||||
imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis
|
||||
pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi.
|
||||
Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu,
|
||||
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
|
||||
quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.
|
||||
'''.format(_State.label_count, str(datetime.datetime.now())))
|
||||
_State.label_count += 1
|
||||
|
||||
dock_widget = QtAds.CDockWidget("Label {}".format(_State.label_count))
|
||||
dock_widget.setWidget(label)
|
||||
|
||||
view_menu.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
|
||||
def create_calendar_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||
'''
|
||||
Create calendar dock widget
|
||||
|
||||
Parameters
|
||||
----------
|
||||
view_menu : QMenu
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : QtAds.CDockWidget
|
||||
'''
|
||||
widget = QCalendarWidget()
|
||||
|
||||
dock_widget = QtAds.CDockWidget("Calendar {}".format(_State.calendar_count))
|
||||
_State.calendar_count += 1
|
||||
dock_widget.setWidget(widget)
|
||||
dock_widget.setToggleViewActionMode(QtAds.CDockWidget.ActionModeShow)
|
||||
view_menu.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
|
||||
def create_file_system_tree_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
||||
'''
|
||||
Create file system tree dock widget
|
||||
|
||||
Parameters
|
||||
----------
|
||||
view_menu : QMenu
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : QtAds.CDockWidget
|
||||
'''
|
||||
widget = QTreeView()
|
||||
widget.setFrameShape(QFrame.NoFrame)
|
||||
|
||||
m = QFileSystemModel(widget)
|
||||
m.setRootPath(QDir.currentPath())
|
||||
widget.setModel(m)
|
||||
|
||||
dock_widget = QtAds.CDockWidget("Filesystem {}".format(_State.file_system_count))
|
||||
_State.file_system_count += 1
|
||||
dock_widget.setWidget(widget)
|
||||
view_menu.addAction(dock_widget.toggleViewAction())
|
||||
return dock_widget
|
||||
|
||||
|
||||
class MainWindow(QtWidgets.QMainWindow):
|
||||
save_perspective_action: QAction
|
||||
perspective_list_action: QWidgetAction
|
||||
perspective_combo_box: QComboBox
|
||||
dock_manager: QtAds.CDockManager
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.save_perspective_action = None
|
||||
self.perspective_list_action = None
|
||||
self.perspective_combo_box = None
|
||||
self.dock_manager = None
|
||||
|
||||
self.setup_ui()
|
||||
|
||||
self.dock_manager = QtAds.CDockManager(self)
|
||||
self.perspective_combo_box.activated[str].connect(self.dock_manager.openPerspective)
|
||||
self.create_content()
|
||||
self.resize(800, 600)
|
||||
self.restore_state()
|
||||
self.restore_perspectives()
|
||||
|
||||
def setup_ui(self):
|
||||
self.setObjectName("MainWindow")
|
||||
self.resize(400, 300)
|
||||
self.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks)
|
||||
self.centralWidget = QtWidgets.QWidget(self)
|
||||
self.centralWidget.setObjectName("centralWidget")
|
||||
self.setCentralWidget(self.centralWidget)
|
||||
self.status_bar = QtWidgets.QStatusBar(self)
|
||||
self.status_bar.setObjectName("statusBar")
|
||||
self.setStatusBar(self.status_bar)
|
||||
self.menu_bar = QtWidgets.QMenuBar(self)
|
||||
self.menu_bar.setGeometry(QRect(0, 0, 400, 21))
|
||||
self.menu_bar.setObjectName("menuBar")
|
||||
self.menu_file = QtWidgets.QMenu(self.menu_bar)
|
||||
self.menu_file.setObjectName("menuFile")
|
||||
self.menu_view = QtWidgets.QMenu(self.menu_bar)
|
||||
self.menu_view.setObjectName("menuView")
|
||||
self.menu_about = QtWidgets.QMenu(self.menu_bar)
|
||||
self.menu_about.setObjectName("menuAbout")
|
||||
self.setMenuBar(self.menu_bar)
|
||||
self.tool_bar = QtWidgets.QToolBar(self)
|
||||
self.tool_bar.setObjectName("toolBar")
|
||||
self.addToolBar(Qt.TopToolBarArea, self.tool_bar)
|
||||
self.action_exit = QtWidgets.QAction(self)
|
||||
self.action_exit.setObjectName("actionExit")
|
||||
self.action_save_state = QtWidgets.QAction(self)
|
||||
self.action_save_state.setObjectName("actionSaveState")
|
||||
self.action_save_state.triggered.connect(self.saveState)
|
||||
|
||||
self.action_restore_state = QtWidgets.QAction(self)
|
||||
self.action_restore_state.setObjectName("actionRestoreState")
|
||||
self.action_restore_state.triggered.connect(self.restore_state)
|
||||
|
||||
self.menu_file.addAction(self.action_exit)
|
||||
self.menu_file.addAction(self.action_save_state)
|
||||
self.menu_file.addAction(self.action_restore_state)
|
||||
self.menu_bar.addAction(self.menu_file.menuAction())
|
||||
self.menu_bar.addAction(self.menu_view.menuAction())
|
||||
self.menu_bar.addAction(self.menu_about.menuAction())
|
||||
|
||||
self.setWindowTitle("MainWindow")
|
||||
self.menu_file.setTitle("File")
|
||||
self.menu_view.setTitle("View")
|
||||
self.menu_about.setTitle("About")
|
||||
self.tool_bar.setWindowTitle("toolBar")
|
||||
self.action_exit.setText("Exit")
|
||||
self.action_save_state.setText("Save State")
|
||||
self.action_restore_state.setText("Restore State")
|
||||
self.create_actions()
|
||||
|
||||
def create_actions(self):
|
||||
'''
|
||||
Creates the toolbar actions
|
||||
'''
|
||||
self.tool_bar.addAction(self.action_save_state)
|
||||
self.action_save_state.setIcon(self.style().standardIcon(QStyle.SP_DialogSaveButton))
|
||||
self.tool_bar.addAction(self.action_restore_state)
|
||||
self.action_restore_state.setIcon(self.style().standardIcon(QStyle.SP_DialogOpenButton))
|
||||
self.save_perspective_action = QAction("Save Perspective", self)
|
||||
self.save_perspective_action.triggered.connect(self.save_perspective)
|
||||
|
||||
self.perspective_list_action = QWidgetAction(self)
|
||||
self.perspective_combo_box = QComboBox(self)
|
||||
self.perspective_combo_box.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||
self.perspective_combo_box.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
|
||||
self.perspective_list_action.setDefaultWidget(self.perspective_combo_box)
|
||||
self.tool_bar.addSeparator()
|
||||
self.tool_bar.addAction(self.perspective_list_action)
|
||||
self.tool_bar.addAction(self.save_perspective_action)
|
||||
|
||||
def create_content(self):
|
||||
'''
|
||||
Fill the dock manager with dock widgets
|
||||
'''
|
||||
# Test container docking
|
||||
view_menu = self.menu_view
|
||||
dock_widget = create_calendar_dock_widget(view_menu)
|
||||
dock_widget.setIcon(self.style().standardIcon(QStyle.SP_DialogOpenButton))
|
||||
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
|
||||
self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, dock_widget)
|
||||
self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, create_long_text_label_dock_widget(view_menu))
|
||||
file_system_widget = create_file_system_tree_dock_widget(view_menu)
|
||||
tool_bar = file_system_widget.createDefaultToolBar()
|
||||
tool_bar.addAction(self.action_save_state)
|
||||
tool_bar.addAction(self.action_restore_state)
|
||||
self.dock_manager.addDockWidget(QtAds.BottomDockWidgetArea, file_system_widget)
|
||||
file_system_widget = create_file_system_tree_dock_widget(view_menu)
|
||||
tool_bar = file_system_widget.createDefaultToolBar()
|
||||
tool_bar.addAction(self.action_save_state)
|
||||
tool_bar.addAction(self.action_restore_state)
|
||||
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetMovable, False)
|
||||
top_dock_area = self.dock_manager.addDockWidget(QtAds.TopDockWidgetArea, file_system_widget)
|
||||
dock_widget = create_calendar_dock_widget(view_menu)
|
||||
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
|
||||
dock_widget.setTabToolTip("Tab ToolTip\nHodie est dies magna")
|
||||
self.dock_manager.addDockWidget(QtAds.CenterDockWidgetArea, dock_widget, top_dock_area)
|
||||
|
||||
# Test dock area docking
|
||||
right_dock_area = self.dock_manager.addDockWidget(
|
||||
QtAds.RightDockWidgetArea,
|
||||
create_long_text_label_dock_widget(view_menu), top_dock_area)
|
||||
self.dock_manager.addDockWidget(
|
||||
QtAds.TopDockWidgetArea,
|
||||
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
||||
|
||||
bottom_dock_area = self.dock_manager.addDockWidget(
|
||||
QtAds.BottomDockWidgetArea,
|
||||
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
||||
|
||||
self.dock_manager.addDockWidget(
|
||||
QtAds.RightDockWidgetArea,
|
||||
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
||||
self.dock_manager.addDockWidget(
|
||||
QtAds.CenterDockWidgetArea,
|
||||
create_long_text_label_dock_widget(view_menu), bottom_dock_area)
|
||||
|
||||
def save_state(self):
|
||||
'''
|
||||
Saves the dock manager state and the main window geometry
|
||||
'''
|
||||
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
||||
settings.setValue("mainWindow/Geometry", self.saveGeometry())
|
||||
settings.setValue("mainWindow/State", self.saveState())
|
||||
settings.setValue("mainWindow/DockingState", self.dock_manager.saveState())
|
||||
|
||||
def save_perspectives(self):
|
||||
'''
|
||||
Save the list of perspectives
|
||||
'''
|
||||
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
||||
self.dock_manager.savePerspectives(settings)
|
||||
|
||||
def restore_state(self):
|
||||
'''
|
||||
Restores the dock manager state
|
||||
'''
|
||||
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
||||
geom = settings.value("mainWindow/Geometry")
|
||||
if geom is not None:
|
||||
self.restoreGeometry(geom)
|
||||
|
||||
state = settings.value("mainWindow/State")
|
||||
if state is not None:
|
||||
self.restoreState(state)
|
||||
|
||||
state = settings.value("mainWindow/DockingState")
|
||||
if state is not None:
|
||||
self.dock_manager.restore_state(state)
|
||||
|
||||
def restore_perspectives(self):
|
||||
'''
|
||||
Restore the perspective listo of the dock manager
|
||||
'''
|
||||
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
||||
self.dock_manager.loadPerspectives(settings)
|
||||
self.perspective_combo_box.clear()
|
||||
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
|
||||
|
||||
def save_perspective(self):
|
||||
perspective_name, ok = QInputDialog.getText(self, 'Save perspective', 'Enter unique name:')
|
||||
if ok and perspective_name:
|
||||
self.dock_manager.addPerspective(perspective_name)
|
||||
_ = QSignalBlocker(self.perspective_combo_box)
|
||||
self.perspective_combo_box.clear()
|
||||
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
|
||||
self.perspective_combo_box.setCurrentText(perspective_name)
|
||||
self.save_perspectives()
|
||||
|
||||
|
||||
def main(app_):
|
||||
main_window = MainWindow()
|
||||
main_window.show()
|
||||
state = main_window.dock_manager.saveState()
|
||||
# print('This is what the saved state looks like in XML:')
|
||||
# print(str(state, 'utf-8'))
|
||||
# print()
|
||||
# main_window.dock_manager.restore_state(state)
|
||||
return main_window
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# logging.basicConfig(level='DEBUG')
|
||||
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
|
||||
QGuiApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
|
||||
app = QtWidgets.QApplication([])
|
||||
window = main(app)
|
||||
window.show()
|
||||
app.exec_()
|
||||
@@ -23,8 +23,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(ads_demo_SRCS
|
||||
main.cpp
|
||||
MainWindow.cpp
|
||||
MainWindow.ui
|
||||
main.qrc
|
||||
mainwindow.ui
|
||||
)
|
||||
add_executable(AdvancedDockingSystemDemo WIN32 ${ads_demo_SRCS})
|
||||
if(BUILD_STATIC)
|
||||
|
||||
@@ -88,6 +88,32 @@ static ads::CDockWidget* createLongTextLabelDockWidget(QMenu* ViewMenu)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function returns a features string with closable (c), movable (m) and floatable (f)
|
||||
* features. i.e. The following string is for a not closable but movable and floatable
|
||||
* widget: c- m+ f+
|
||||
*/
|
||||
static QString featuresString(ads::CDockWidget* DockWidget)
|
||||
{
|
||||
auto f = DockWidget->features();
|
||||
return QString("c%1 m%2 f%3")
|
||||
.arg(f.testFlag(ads::CDockWidget::DockWidgetClosable) ? "+" : "-")
|
||||
.arg(f.testFlag(ads::CDockWidget::DockWidgetMovable) ? "+" : "-")
|
||||
.arg(f.testFlag(ads::CDockWidget::DockWidgetFloatable) ? "+" : "-");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends the string returned by featuresString() to the window title of
|
||||
* the given DockWidget
|
||||
*/
|
||||
static void appendFeaturStringToWindowTitle(ads::CDockWidget* DockWidget)
|
||||
{
|
||||
DockWidget->setWindowTitle(DockWidget->windowTitle()
|
||||
+ QString(" (%1)").arg(featuresString(DockWidget)));
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu)
|
||||
{
|
||||
@@ -110,7 +136,8 @@ static ads::CDockWidget* createFileSystemTreeDockWidget(QMenu* ViewMenu)
|
||||
QFileSystemModel* m = new QFileSystemModel(w);
|
||||
m->setRootPath(QDir::currentPath());
|
||||
w->setModel(m);
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1").arg(FileSystemCount++));
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1")
|
||||
.arg(FileSystemCount++));
|
||||
DockWidget->setWidget(w);
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
@@ -185,6 +212,8 @@ void MainWindowPrivate::createContent()
|
||||
ToolBar->addAction(ui.actionSaveState);
|
||||
ToolBar->addAction(ui.actionRestoreState);
|
||||
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
|
||||
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
|
||||
appendFeaturStringToWindowTitle(FileSystemWidget);
|
||||
auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget);
|
||||
DockWidget = createCalendarDockWidget(ViewMenu);
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);
|
||||
@@ -197,6 +226,13 @@ void MainWindowPrivate::createContent()
|
||||
auto BottomDockArea = DockManager->addDockWidget(ads::BottomDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), RighDockArea);
|
||||
DockManager->addDockWidget(ads::RightDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), BottomDockArea);
|
||||
//DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), BottomDockArea);
|
||||
//DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), BottomDockArea);
|
||||
|
||||
for (auto DockWidget : DockManager->dockWidgetsMap())
|
||||
{
|
||||
_this->connect(DockWidget, SIGNAL(viewToggled(bool)), SLOT(onViewToggled(bool)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -270,19 +306,27 @@ CMainWindow::CMainWindow(QWidget *parent) :
|
||||
d->ui.setupUi(this);
|
||||
d->createActions();
|
||||
|
||||
// uncomment the following line if the tab close button should be
|
||||
// a QToolButton instead of a QPushButton
|
||||
// CDockManager::setConfigFlags(CDockManager::configFlags() | CDockManager::TabCloseButtonIsToolButton);
|
||||
|
||||
// uncomment the following line if you wand a fixed tab width that does
|
||||
// not change if the visibility of the close button changes
|
||||
// CDockManager::setConfigFlag(CDockManager::RetainTabSizeWhenCloseButtonHidden, true);
|
||||
|
||||
// Now create the dock manager and its content
|
||||
d->DockManager = new CDockManager(this);
|
||||
|
||||
// Uncomment the following line to have the old style where the dock
|
||||
// area close button closes the active tab
|
||||
//d->DockManager->setConfigFlags({
|
||||
// CDockManager::DockAreaHasCloseButton | CDockManager::DockAreaCloseButtonClosesTab});
|
||||
// CDockManager::setConfigFlags({CDockManager::DockAreaHasCloseButton
|
||||
// | CDockManager::DockAreaCloseButtonClosesTab});
|
||||
connect(d->PerspectiveComboBox, SIGNAL(activated(const QString&)),
|
||||
d->DockManager, SLOT(openPerspective(const QString&)));
|
||||
|
||||
d->createContent();
|
||||
// Default window geometry
|
||||
resize(800, 600);
|
||||
resize(1280, 720);
|
||||
|
||||
d->restoreState();
|
||||
d->restorePerspectives();
|
||||
@@ -338,3 +382,16 @@ void CMainWindow::savePerspective()
|
||||
d->savePerspectives();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::onViewToggled(bool Open)
|
||||
{
|
||||
auto DockWidget = qobject_cast<ads::CDockWidget*>(sender());
|
||||
if (!DockWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << DockWidget->objectName() << " viewToggled(" << Open << ")";
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ private slots:
|
||||
void on_actionSaveState_triggered(bool);
|
||||
void on_actionRestoreState_triggered(bool);
|
||||
void savePerspective();
|
||||
void onViewToggled(bool Open);
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
@@ -21,7 +21,6 @@ HEADERS += \
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
||||
RESOURCES += main.qrc
|
||||
|
||||
LIBS += -L$${ADS_OUT_ROOT}/lib
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/main"/>
|
||||
</RCC>
|
||||
BIN
doc/linux_kubuntu_1804.png
Normal file
BIN
doc/linux_kubuntu_1804.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 232 KiB |
@@ -23,7 +23,6 @@ HEADERS += \
|
||||
FORMS += \
|
||||
MainWindow.ui
|
||||
|
||||
#RESOURCES += main.qrc
|
||||
|
||||
LIBS += -L$${ADS_OUT_ROOT}/lib
|
||||
|
||||
|
||||
41
recipes/meta.yaml
Normal file
41
recipes/meta.yaml
Normal file
@@ -0,0 +1,41 @@
|
||||
{% set data = load_setup_py_data() %}
|
||||
|
||||
package:
|
||||
name: pyqtads
|
||||
version: {{ data.get('version') }}
|
||||
|
||||
source:
|
||||
path: ../
|
||||
|
||||
build:
|
||||
number: 0
|
||||
script: python setup.py install --single-version-externally-managed --record=record.txt --conda-recipe
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- python
|
||||
- setuptools
|
||||
- pyqt>=5.9
|
||||
- sip>=4.19
|
||||
run:
|
||||
- python
|
||||
- pyqt>=5.9
|
||||
- sip>=4.19
|
||||
- pywin32 [win]
|
||||
|
||||
test:
|
||||
imports:
|
||||
- PyQtAds
|
||||
|
||||
about:
|
||||
home: {{ data.get('url') }}
|
||||
license: {{ data.get('license') }}
|
||||
license_family: LGPL
|
||||
license_file: 'LICENSE.md'
|
||||
summary: {{ data.get('description') }}
|
||||
description: {{ data.get('description') }}
|
||||
doc_url: ''
|
||||
dev_url: {{ data.get('url') }}
|
||||
|
||||
extra:
|
||||
recipe-maintainers: 'nicolas.elie@cnrs.fr'
|
||||
342
setup.py
Normal file
342
setup.py
Normal file
@@ -0,0 +1,342 @@
|
||||
import os
|
||||
import sys
|
||||
import shlex
|
||||
import subprocess
|
||||
import glob
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
from setuptools.extension import Extension
|
||||
from distutils import sysconfig, dir_util, spawn, log
|
||||
from distutils.dep_util import newer
|
||||
import sipdistutils
|
||||
import sipconfig
|
||||
from PyQt5.QtCore import PYQT_CONFIGURATION
|
||||
from PyQt5.pyrcc_main import processResourceFile
|
||||
|
||||
MAJOR = 2
|
||||
MINOR = 5
|
||||
MICRO = 1
|
||||
ISRELEASED = True
|
||||
VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
|
||||
MODULE_NAME = "ads"
|
||||
SRC_PATH = "PyQtAds"
|
||||
|
||||
REQUIRE_PYQT = True
|
||||
if "--conda-recipe" in sys.argv:
|
||||
REQUIRE_PYQT = False
|
||||
sys.argv.remove("--conda-recipe")
|
||||
|
||||
|
||||
class HostPythonConfiguration(object):
|
||||
def __init__(self):
|
||||
self.platform = sys.platform
|
||||
self.version = sys.hexversion>>8
|
||||
|
||||
self.inc_dir = sysconfig.get_python_inc()
|
||||
self.venv_inc_dir = sysconfig.get_python_inc(prefix=sys.prefix)
|
||||
self.module_dir = sysconfig.get_python_lib(plat_specific=1)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
self.data_dir = sys.prefix
|
||||
self.lib_dir = sys.prefix +'\\libs'
|
||||
else:
|
||||
self.data_dir = sys.prefix + '/share'
|
||||
self.lib_dir = sys.prefix + '/lib'
|
||||
|
||||
|
||||
class TargetQtConfiguration(object):
|
||||
def __init__(self, qmake):
|
||||
pipe = os.popen(' '.join([qmake, '-query']))
|
||||
|
||||
for l in pipe:
|
||||
l = l.strip()
|
||||
|
||||
tokens = l.split(':', 1)
|
||||
if isinstance(tokens, list):
|
||||
if len(tokens) != 2:
|
||||
error("Unexpected output from qmake: '%s'\n" % l)
|
||||
|
||||
name, value = tokens
|
||||
else:
|
||||
name = tokens
|
||||
value = None
|
||||
|
||||
name = name.replace('/', '_')
|
||||
setattr(self, name, value)
|
||||
|
||||
pipe.close()
|
||||
|
||||
|
||||
class build_ext(sipdistutils.build_ext):
|
||||
|
||||
description = "Builds the " + MODULE_NAME + " module."
|
||||
|
||||
user_options = sipdistutils.build_ext.user_options + [
|
||||
('qmake-bin=', None, "Path to qmake binary"),
|
||||
('sip-bin=', None, "Path to sip binary"),
|
||||
('qt-include-dir=', None, "Path to Qt headers"),
|
||||
('pyqt-sip-dir=', None, "Path to PyQt's SIP files"),
|
||||
('pyqt-sip-flags=', None, "SIP flags used to generate PyQt bindings"),
|
||||
('sip-dir=', None, "Path to module's SIP files"),
|
||||
('inc-dir=', None, "Path to module's include files")
|
||||
]
|
||||
|
||||
def initialize_options (self):
|
||||
super().initialize_options()
|
||||
self.qmake_bin = 'qmake'
|
||||
self.sip_bin = None
|
||||
self.qt_include_dir = None
|
||||
self.qt_libinfix = ''
|
||||
self.pyqt_sip_dir = None
|
||||
self.pyqt_sip_flags = None
|
||||
self.sip_files_dir = None
|
||||
self.sip_inc_dir = None
|
||||
self.inc_dir = None
|
||||
self.pyconfig = HostPythonConfiguration()
|
||||
self.qtconfig = TargetQtConfiguration(self.qmake_bin)
|
||||
self.config = sipconfig.Configuration()
|
||||
self.config.default_mod_dir = ("/usr/local/lib/python%i.%i/dist-packages" %
|
||||
(sys.version_info.major, sys.version_info.minor))
|
||||
|
||||
def finalize_options (self):
|
||||
super().finalize_options()
|
||||
|
||||
if not self.qt_include_dir:
|
||||
self.qt_include_dir = self.qtconfig.QT_INSTALL_HEADERS
|
||||
|
||||
if not self.qt_libinfix:
|
||||
try:
|
||||
with open(os.path.join(self.qtconfig.QT_INSTALL_PREFIX, 'mkspecs', 'qconfig.pri'), 'r') as f:
|
||||
for line in f.readlines():
|
||||
if line.startswith('QT_LIBINFIX'):
|
||||
self.qt_libinfix = line.split('=')[1].strip('\n').strip()
|
||||
except (FileNotFoundError, IndexError):
|
||||
pass
|
||||
|
||||
if not self.pyqt_sip_dir:
|
||||
self.pyqt_sip_dir = os.path.join(self.pyconfig.data_dir, 'sip', 'PyQt5')
|
||||
|
||||
if not self.pyqt_sip_flags:
|
||||
self.pyqt_sip_flags = PYQT_CONFIGURATION.get('sip_flags', '')
|
||||
|
||||
if not self.sip_files_dir:
|
||||
self.sip_files_dir = os.path.abspath(os.path.join(".", "sip"))
|
||||
|
||||
if not self.sip_inc_dir:
|
||||
self.sip_inc_dir = self.pyconfig.venv_inc_dir
|
||||
|
||||
if not self.inc_dir:
|
||||
self.inc_dir = os.path.abspath(os.path.join(".", "src"))
|
||||
|
||||
if not self.qt_include_dir:
|
||||
raise SystemExit('Could not find Qt5 headers. '
|
||||
'Please specify via --qt-include-dir=')
|
||||
|
||||
if not self.pyqt_sip_dir:
|
||||
raise SystemExit('Could not find PyQt SIP files. '
|
||||
'Please specify containing directory via '
|
||||
'--pyqt-sip-dir=')
|
||||
|
||||
if not self.pyqt_sip_flags:
|
||||
raise SystemExit('Could not find PyQt SIP flags. '
|
||||
'Please specify via --pyqt-sip-flags=')
|
||||
|
||||
def _find_sip(self):
|
||||
"""override _find_sip to allow for manually speficied sip path."""
|
||||
return self.sip_bin or super()._find_sip()
|
||||
|
||||
def _sip_compile(self, sip_bin, source, sbf):
|
||||
cmd = [sip_bin]
|
||||
if hasattr(self, 'sip_opts'):
|
||||
cmd += self.sip_opts
|
||||
if hasattr(self, '_sip_sipfiles_dir'):
|
||||
cmd += ['-I', self._sip_sipfiles_dir()]
|
||||
cmd += [
|
||||
"-I", self.sip_files_dir,
|
||||
"-I", self.pyqt_sip_dir,
|
||||
"-I", self.sip_inc_dir,
|
||||
"-I", self.inc_dir,
|
||||
"-c", self._sip_output_dir(),
|
||||
"-b", sbf,
|
||||
"-w", "-o"]
|
||||
|
||||
cmd += shlex.split(self.pyqt_sip_flags) # use same SIP flags as for PyQt5
|
||||
cmd.append(source)
|
||||
self.spawn(cmd)
|
||||
|
||||
def swig_sources (self, sources, extension=None):
|
||||
if not self.extensions:
|
||||
return
|
||||
|
||||
# Add the local include directory to the include path
|
||||
if extension is not None:
|
||||
extension.extra_compile_args += ['-D', 'QT_CORE_LIB',
|
||||
'-D', 'QT_GUI_LIB',
|
||||
'-D', 'QT_WIDGETS_LIB',
|
||||
'-D', 'ADS_SHARED_EXPORT']
|
||||
extension.include_dirs += [self.qt_include_dir, self.inc_dir,
|
||||
os.path.join(self.qt_include_dir, 'QtCore'),
|
||||
os.path.join(self.qt_include_dir, 'QtGui'),
|
||||
os.path.join(self.qt_include_dir, 'QtWidgets')]
|
||||
extension.libraries += ['Qt5Core' + self.qt_libinfix,
|
||||
'Qt5Gui' + self.qt_libinfix,
|
||||
'Qt5Widgets' + self.qt_libinfix]
|
||||
|
||||
if sys.platform == 'win32':
|
||||
extension.library_dirs += [self.qtconfig.QT_INSTALL_LIBS,
|
||||
self.inc_dir, self._sip_output_dir()]
|
||||
elif sys.platform == 'darwin':
|
||||
extension.extra_compile_args += ['-F' + self.qtconfig.QT_INSTALL_LIBS,
|
||||
'-std=c++11', '-stdlib=libc++', '-mmacosx-version-min=10.9']
|
||||
extension.extra_link_args += ['-F' + self.qtconfig.QT_INSTALL_LIBS,
|
||||
'-mmacosx-version-min=10.9']
|
||||
elif sys.platform == 'linux':
|
||||
extension.extra_compile_args += ['-std=c++11']
|
||||
|
||||
return super().swig_sources(sources, extension)
|
||||
|
||||
def build_extension(self, ext):
|
||||
cppsources = [source for source in ext.sources if source.endswith(".cpp")]
|
||||
|
||||
dir_util.mkpath(self.build_temp, dry_run=self.dry_run)
|
||||
|
||||
# Run moc on all header files.
|
||||
for source in cppsources:
|
||||
header = source.replace(".cpp", ".h")
|
||||
if os.path.exists(header):
|
||||
moc_file = "moc_" + os.path.basename(header).replace(".h", ".cpp")
|
||||
out_file = os.path.join(self.build_temp, moc_file)
|
||||
|
||||
if newer(header, out_file) or self.force:
|
||||
call_arg = ["moc", "-o", out_file, header]
|
||||
spawn.spawn(call_arg, dry_run=self.dry_run)
|
||||
|
||||
if os.path.getsize(out_file) > 0:
|
||||
ext.sources.append(out_file)
|
||||
|
||||
# Add the temp build directory to include path, for compiler to find
|
||||
# the created .moc files
|
||||
ext.include_dirs += [self._sip_output_dir()]
|
||||
|
||||
sipdistutils.build_ext.build_extension(self, ext)
|
||||
|
||||
|
||||
def git_version():
|
||||
'''Return the git revision as a string'''
|
||||
|
||||
def _minimal_ext_cmd(cmd):
|
||||
# construct minimal environment
|
||||
env = {}
|
||||
for k in ['SYSTEMROOT', 'PATH', 'HOME']:
|
||||
v = os.environ.get(k)
|
||||
if v is not None:
|
||||
env[k] = v
|
||||
# LANGUAGE is used on win32
|
||||
env['LANGUAGE'] = 'C'
|
||||
env['LANG'] = 'C'
|
||||
env['LC_ALL'] = 'C'
|
||||
out = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env).communicate()[0]
|
||||
return out
|
||||
|
||||
try:
|
||||
out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD'])
|
||||
GIT_REVISION = out.strip().decode('ascii')
|
||||
except OSError:
|
||||
GIT_REVISION = "Unknown"
|
||||
|
||||
return GIT_REVISION
|
||||
|
||||
|
||||
def get_version_info():
|
||||
# Adding the git rev number needs to be done inside write_version_py(),
|
||||
# otherwise the import of numpy.version messes up the build under Python 3.
|
||||
FULLVERSION = VERSION
|
||||
if os.path.exists('.git'):
|
||||
GIT_REVISION = git_version()
|
||||
elif os.path.exists(os.path.join(SRC_PATH, 'version.py')):
|
||||
# must be a source distribution, use existing version file
|
||||
try:
|
||||
from PyQtAds.version import git_revision as GIT_REVISION
|
||||
except ImportError:
|
||||
raise ImportError("Unable to import git_revision. Try removing " \
|
||||
"%(module)/version.py and the build directory " \
|
||||
"before building." % {'module': SRC_PATH})
|
||||
else:
|
||||
GIT_REVISION = "Unknown"
|
||||
|
||||
if not ISRELEASED:
|
||||
FULLVERSION += '.dev0+' + GIT_REVISION[:7]
|
||||
|
||||
return FULLVERSION, GIT_REVISION
|
||||
|
||||
|
||||
def write_version_py(filename=os.path.join(SRC_PATH, '_version.py')):
|
||||
cnt = ("# THIS FILE IS GENERATED FROM %(module)s SETUP.PY\n\n"
|
||||
"short_version = '%(version)s'\n"
|
||||
"version = '%(version)s'\n"
|
||||
"full_version = '%(full_version)s'\n"
|
||||
"git_revision = '%(git_revision)s'\n"
|
||||
"release = %(isrelease)s\n"
|
||||
"if not release:\n"
|
||||
" version = full_version\n")
|
||||
FULLVERSION, GIT_REVISION = get_version_info()
|
||||
|
||||
with open(filename, 'w') as f:
|
||||
f.write(cnt % {'module': SRC_PATH,
|
||||
'version': VERSION,
|
||||
'full_version': FULLVERSION,
|
||||
'git_revision': GIT_REVISION,
|
||||
'isrelease': str(ISRELEASED)})
|
||||
|
||||
setup_requires = ["PyQt5"] if REQUIRE_PYQT else []
|
||||
cpp_sources = glob.glob(os.path.join('src', '*.cpp'))
|
||||
sip_sources = [os.path.join('sip', MODULE_NAME + '.sip')]
|
||||
if sys.platform == 'linux':
|
||||
cpp_sources += glob.glob(os.path.join('src', 'linux', '*.cpp'))
|
||||
ext_modules = [Extension('PyQtAds.QtAds.ads', cpp_sources + sip_sources)]
|
||||
|
||||
install_requires = ["PyQt5"]
|
||||
if sys.platform == 'win32':
|
||||
install_requires.append("pywin32")
|
||||
|
||||
|
||||
write_version_py(os.path.join(SRC_PATH, '_version.py'))
|
||||
processResourceFile([os.path.join('src', 'ads.qrc')],
|
||||
os.path.join(SRC_PATH, 'rc.py'), False)
|
||||
with open('README.md', 'r') as f:
|
||||
LONG_DESCRIPTION = f.read()
|
||||
|
||||
setup(
|
||||
name = SRC_PATH,
|
||||
author = "Nicolas Elie",
|
||||
author_email = "nicolas.elie@cnrs.fr",
|
||||
url = "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System",
|
||||
version = get_version_info()[0],
|
||||
description = "Advanced Docking System for Qt",
|
||||
long_description = LONG_DESCRIPTION,
|
||||
keywords = ["qt"],
|
||||
license = "LGPLv2+",
|
||||
classifiers = ["Development Status :: 4 - Beta",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)",
|
||||
"Operating System :: OS Independent",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Environment :: Win32 (MS Windows)",
|
||||
"Environment :: MacOS X",
|
||||
"Environment :: X11 Applications :: Qt",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.2",
|
||||
"Programming Language :: Python :: 3.3",
|
||||
"Programming Language :: Python :: 3.4",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7"],
|
||||
ext_modules = ext_modules,
|
||||
cmdclass = {
|
||||
'build_ext': build_ext,
|
||||
},
|
||||
packages = find_packages(),
|
||||
setup_requires = setup_requires,
|
||||
install_requires = install_requires,
|
||||
zip_safe=False
|
||||
)
|
||||
82
simple.py
Normal file
82
simple.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import logging
|
||||
|
||||
from PyQt5 import QtWidgets, QtCore
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQtAds import QtAds
|
||||
|
||||
|
||||
class MainWindow(QtWidgets.QMainWindow):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setup_ui()
|
||||
self.dock_manager = QtAds.CDockManager(self)
|
||||
|
||||
self.dock_widgets = []
|
||||
|
||||
for label_text, area in (
|
||||
('1 Top', QtAds.TopDockWidgetArea),
|
||||
('2 Bottom', QtAds.BottomDockWidgetArea),
|
||||
('3 Left', QtAds.LeftDockWidgetArea),
|
||||
('4 Right', QtAds.RightDockWidgetArea),
|
||||
):
|
||||
# Create example content label - this can be any application specific
|
||||
# widget
|
||||
label = QtWidgets.QLabel()
|
||||
label.setWordWrap(True)
|
||||
label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
||||
label.setText(f"{label_text}: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ")
|
||||
|
||||
# Create a dock widget with the title Label 1 and set the created label
|
||||
# as the dock widget content
|
||||
dock_widget = QtAds.CDockWidget(label_text)
|
||||
dock_widget.setWidget(label)
|
||||
self.dock_widgets.append(dock_widget)
|
||||
|
||||
# Add the toggleViewAction of the dock widget to the menu to give
|
||||
# the user the possibility to show the dock widget if it has been closed
|
||||
self.menu_view.addAction(dock_widget.toggleViewAction())
|
||||
|
||||
# Add the dock widget to the top dock widget area
|
||||
self.dock_manager.addDockWidget(area, dock_widget)
|
||||
|
||||
def setup_ui(self):
|
||||
self.setWindowTitle("MainWindow")
|
||||
self.setObjectName("MainWindow")
|
||||
self.resize(400, 300)
|
||||
self.central_widget = QtWidgets.QWidget(self)
|
||||
self.central_widget.setObjectName("central_widget")
|
||||
self.setCentralWidget(self.central_widget)
|
||||
|
||||
self.menu_bar = QtWidgets.QMenuBar(self)
|
||||
self.menu_bar.setGeometry(QtCore.QRect(0, 0, 400, 21))
|
||||
self.menu_bar.setObjectName("menuBar")
|
||||
|
||||
self.menu_view = QtWidgets.QMenu(self.menu_bar)
|
||||
self.menu_view.setObjectName("menu_view")
|
||||
self.menu_view.setTitle("View")
|
||||
self.setMenuBar(self.menu_bar)
|
||||
|
||||
self.status_bar = QtWidgets.QStatusBar(self)
|
||||
self.status_bar.setObjectName("statusBar")
|
||||
self.setStatusBar(self.status_bar)
|
||||
self.menu_bar.addAction(self.menu_view.menuAction())
|
||||
|
||||
|
||||
def main(app):
|
||||
main = MainWindow()
|
||||
main.show()
|
||||
state = main.dock_manager.saveState()
|
||||
print('This is what the saved state looks like in XML:')
|
||||
print(state)
|
||||
print()
|
||||
main.dock_manager.restoreState(state)
|
||||
return main
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(level='DEBUG')
|
||||
app = QtWidgets.QApplication([])
|
||||
window = main(app)
|
||||
window.show()
|
||||
print('shown')
|
||||
app.exec_()
|
||||
56
sip/DockAreaTabBar.sip
Normal file
56
sip/DockAreaTabBar.sip
Normal file
@@ -0,0 +1,56 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CDockAreaTabBar : QScrollArea
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <DockAreaTabBar.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual void wheelEvent(QWheelEvent* Event);
|
||||
virtual void mousePressEvent(QMouseEvent* ev);
|
||||
virtual void mouseReleaseEvent(QMouseEvent* ev);
|
||||
virtual void mouseMoveEvent(QMouseEvent* ev);
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event);
|
||||
void startFloating(const QPoint& Offset);
|
||||
ads::CFloatingDockContainer* makeAreaFloating(const QPoint& Offset,
|
||||
ads::eDragState DragState);
|
||||
|
||||
public:
|
||||
CDockAreaTabBar(ads::CDockAreaWidget* parent /TransferThis/);
|
||||
virtual ~CDockAreaTabBar();
|
||||
void insertTab(int Index, ads::CDockWidgetTab* Tab /Transfer/);
|
||||
void removeTab(ads::CDockWidgetTab* Tab) /TransferBack/;
|
||||
int count() const;
|
||||
int currentIndex() const;
|
||||
ads::CDockWidgetTab* currentTab() const;
|
||||
ads::CDockWidgetTab* tab(int Index) const;
|
||||
virtual bool eventFilter(QObject *watched, QEvent *event);
|
||||
bool isTabOpen(int Index) const;
|
||||
virtual QSize minimumSizeHint() const;
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
public slots:
|
||||
void setCurrentIndex(int Index);
|
||||
void closeTab(int Index);
|
||||
|
||||
signals:
|
||||
void currentChanging(int Index);
|
||||
void currentChanged(int Index);
|
||||
void tabBarClicked(int index);
|
||||
void tabCloseRequested(int index);
|
||||
void tabClosed(int index);
|
||||
void tabOpened(int index);
|
||||
void tabMoved(int from, int to);
|
||||
void removingTab(int index);
|
||||
void tabInserted(int index);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
32
sip/DockAreaTitleBar.sip
Normal file
32
sip/DockAreaTitleBar.sip
Normal file
@@ -0,0 +1,32 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CDockAreaTitleBar : QFrame
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <DockAreaTitleBar.h>
|
||||
%End
|
||||
|
||||
public slots:
|
||||
void markTabsMenuOutdated();
|
||||
|
||||
|
||||
public:
|
||||
CDockAreaTitleBar(ads::CDockAreaWidget* parent /TransferThis/);
|
||||
virtual ~CDockAreaTitleBar();
|
||||
ads::CDockAreaTabBar* tabBar() const;
|
||||
QAbstractButton* button(ads::TitleBarButton which) const;
|
||||
virtual void setVisible(bool Visible);
|
||||
|
||||
|
||||
signals:
|
||||
void tabBarClicked(int index);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
65
sip/DockAreaWidget.sip
Normal file
65
sip/DockAreaWidget.sip
Normal file
@@ -0,0 +1,65 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CDockAreaWidget : QFrame
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include <DockAreaWidget.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
void insertDockWidget(int index, ads::CDockWidget* DockWidget /Transfer/, bool Activate = true);
|
||||
void addDockWidget(ads::CDockWidget* DockWidget /Transfer/);
|
||||
void removeDockWidget(ads::CDockWidget* DockWidget) /TransferBack/;
|
||||
void toggleDockWidgetView(ads::CDockWidget* DockWidget, bool Open);
|
||||
CDockWidget* nextOpenDockWidget(ads::CDockWidget* DockWidget) const;
|
||||
int index(ads::CDockWidget* DockWidget);
|
||||
void hideAreaWithNoVisibleContent();
|
||||
void updateTitleBarVisibility();
|
||||
void internalSetCurrentDockWidget(ads::CDockWidget* DockWidget /Transfer/);
|
||||
void markTitleBarMenuOutdated();
|
||||
|
||||
protected slots:
|
||||
void toggleView(bool Open);
|
||||
|
||||
public:
|
||||
CDockAreaWidget(ads::CDockManager* DockManager /TransferThis/, ads::CDockContainerWidget* parent /TransferThis/);
|
||||
virtual ~CDockAreaWidget();
|
||||
ads::CDockManager* dockManager() const;
|
||||
ads::CDockContainerWidget* dockContainer() const;
|
||||
QRect titleBarGeometry() const;
|
||||
QRect contentAreaGeometry() const;
|
||||
int dockWidgetsCount() const;
|
||||
QList<ads::CDockWidget*> dockWidgets() const;
|
||||
int openDockWidgetsCount() const;
|
||||
QList<ads::CDockWidget*> openedDockWidgets() const;
|
||||
ads::CDockWidget* dockWidget(int Index) const;
|
||||
int currentIndex() const;
|
||||
int indexOfFirstOpenDockWidget() const;
|
||||
ads::CDockWidget* currentDockWidget() const;
|
||||
void setCurrentDockWidget(ads::CDockWidget* DockWidget /Transfer/);
|
||||
void saveState(QXmlStreamWriter& Stream) const;
|
||||
ads::CDockWidget::DockWidgetFeatures features() const;
|
||||
QAbstractButton* titleBarButton(ads::TitleBarButton which) const;
|
||||
virtual void setVisible(bool Visible);
|
||||
|
||||
public slots:
|
||||
void setCurrentIndex(int index);
|
||||
void closeArea();
|
||||
void closeOtherAreas();
|
||||
|
||||
signals:
|
||||
void tabBarClicked(int index);
|
||||
void currentChanging(int index);
|
||||
void currentChanged(int index);
|
||||
void viewToggled(bool Open);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
154
sip/DockContainerWidget.sip
Normal file
154
sip/DockContainerWidget.sip
Normal file
@@ -0,0 +1,154 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
/**
|
||||
* Container that manages a number of dock areas with single dock widgets
|
||||
* or tabyfied dock widgets in each area.
|
||||
* Each window that support docking has a DockContainerWidget. That means
|
||||
* the main application window and all floating windows are ore contain
|
||||
* an DockContainerWidget.
|
||||
*/
|
||||
class CDockContainerWidget : QFrame
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <DockContainerWidget.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual bool event(QEvent *e);
|
||||
QSplitter* rootSplitter() const;
|
||||
void createRootSplitter();
|
||||
void dropFloatingWidget(ads::CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
|
||||
void addDockArea(ads::CDockAreaWidget* DockAreaWidget /Transfer/, ads::DockWidgetArea area = ads::CenterDockWidgetArea);
|
||||
void removeDockArea(ads::CDockAreaWidget* area /Transfer/);
|
||||
void saveState(QXmlStreamWriter& Stream) const;
|
||||
bool restoreState(QXmlStreamReader& Stream, bool Testing);
|
||||
ads::CDockAreaWidget* lastAddedDockAreaWidget(ads::DockWidgetArea area) const;
|
||||
bool hasTopLevelDockWidget() const;
|
||||
ads::CDockWidget* topLevelDockWidget() const;
|
||||
ads::CDockAreaWidget* topLevelDockArea() const;
|
||||
QList<ads::CDockWidget*> dockWidgets() const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default Constructor
|
||||
*/
|
||||
CDockContainerWidget(ads::CDockManager* DockManager /TransferThis/, QWidget* parent /TransferThis/ = 0);
|
||||
|
||||
/**
|
||||
* Virtual Destructor
|
||||
*/
|
||||
virtual ~CDockContainerWidget();
|
||||
|
||||
/**
|
||||
* Adds dockwidget into the given area.
|
||||
* If DockAreaWidget is not null, then the area parameter indicates the area
|
||||
* into the DockAreaWidget. If DockAreaWidget is null, the Dockwidget will
|
||||
* be dropped into the container.
|
||||
* \return Returns the dock area widget that contains the new DockWidget
|
||||
*/
|
||||
ads::CDockAreaWidget* addDockWidget(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
|
||||
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0);
|
||||
|
||||
/**
|
||||
* Removes dockwidget
|
||||
*/
|
||||
void removeDockWidget(ads::CDockWidget* Dockwidget) /TransferBack/;
|
||||
|
||||
/**
|
||||
* Returns the current zOrderIndex
|
||||
*/
|
||||
virtual unsigned int zOrderIndex() const;
|
||||
|
||||
/**
|
||||
* This function returns true if this container widgets z order index is
|
||||
* higher than the index of the container widget given in Other parameter
|
||||
*/
|
||||
bool isInFrontOf(ads::CDockContainerWidget* Other) const;
|
||||
|
||||
/**
|
||||
* Returns the dock area at teh given global position or 0 if there is no
|
||||
* dock area at this position
|
||||
*/
|
||||
ads::CDockAreaWidget* dockAreaAt(const QPoint& GlobalPos) const;
|
||||
|
||||
/**
|
||||
* Returns the dock area at the given Index or 0 if the index is out of
|
||||
* range
|
||||
*/
|
||||
ads::CDockAreaWidget* dockArea(int Index) const;
|
||||
|
||||
/**
|
||||
* Returns the list of dock areas that are not closed
|
||||
* If all dock widgets in a dock area are closed, the dock area will be closed
|
||||
*/
|
||||
QList<ads::CDockAreaWidget*> openedDockAreas() const;
|
||||
|
||||
/**
|
||||
* Returns the number of dock areas in this container
|
||||
*/
|
||||
int dockAreaCount() const;
|
||||
|
||||
/**
|
||||
* Returns the number of visible dock areas
|
||||
*/
|
||||
int visibleDockAreaCount() const;
|
||||
|
||||
/**
|
||||
* This function returns true, if this container is in a floating widget
|
||||
*/
|
||||
bool isFloating() const;
|
||||
|
||||
/**
|
||||
* Dumps the layout for debugging purposes
|
||||
*/
|
||||
void dumpLayout();
|
||||
|
||||
/**
|
||||
* This functions returns the dock widget features of all dock widget in
|
||||
* this container.
|
||||
* A bitwise and is used to combine the flags of all dock widgets. That
|
||||
* means, if only dock widget does not support a certain flag, the whole
|
||||
* dock are does not support the flag.
|
||||
*/
|
||||
ads::CDockWidget::DockWidgetFeatures features() const;
|
||||
|
||||
/**
|
||||
* If this dock container is in a floating widget, this function returns
|
||||
* the floating widget.
|
||||
* Else, it returns a nullptr.
|
||||
*/
|
||||
ads::CFloatingDockContainer* floatingWidget() const;
|
||||
|
||||
/**
|
||||
* Call this function to close all dock areas except the KeepOpenArea
|
||||
*/
|
||||
void closeOtherAreas(ads::CDockAreaWidget* KeepOpenArea);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* This signal is emitted if one or multiple dock areas has been added to
|
||||
* the internal list of dock areas.
|
||||
* If multiple dock areas are inserted, this signal is emitted only once
|
||||
*/
|
||||
void dockAreasAdded();
|
||||
|
||||
/**
|
||||
* This signal is emitted if one or multiple dock areas has been removed
|
||||
*/
|
||||
void dockAreasRemoved();
|
||||
|
||||
/**
|
||||
* This signal is emitted if a dock area is opened or closed via
|
||||
* toggleView() function
|
||||
*/
|
||||
void dockAreaViewToggled(ads::CDockAreaWidget* DockArea, bool Open);
|
||||
}; // class DockContainerWidget
|
||||
};
|
||||
// namespace ads
|
||||
|
||||
%End
|
||||
205
sip/DockManager.sip
Normal file
205
sip/DockManager.sip
Normal file
@@ -0,0 +1,205 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
%MappedType QMap<QString, ads::CDockWidget*>
|
||||
/TypeHint="Dict[QString, CDockWidget*]", TypeHintValue="{}"/
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qmap.h>
|
||||
%End
|
||||
|
||||
%ConvertFromTypeCode
|
||||
PyObject *d = PyDict_New();
|
||||
|
||||
if (!d)
|
||||
return 0;
|
||||
|
||||
QMap<QString, ads::CDockWidget*>::const_iterator it = sipCpp->constBegin();
|
||||
QMap<QString, ads::CDockWidget*>::const_iterator end = sipCpp->constEnd();
|
||||
|
||||
while (it != end)
|
||||
{
|
||||
QString *k = new QString(it.key());
|
||||
PyObject *kobj = sipConvertFromType(k, sipType_QString,
|
||||
sipTransferObj);
|
||||
|
||||
if (!kobj)
|
||||
{
|
||||
delete k;
|
||||
Py_DECREF(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject *vobj = sipConvertFromType(it.value(), sipType_ads_CDockWidget,
|
||||
sipTransferObj);
|
||||
|
||||
if (!vobj)
|
||||
{
|
||||
Py_DECREF(kobj);
|
||||
Py_DECREF(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rc = PyDict_SetItem(d, kobj, vobj);
|
||||
|
||||
Py_DECREF(vobj);
|
||||
Py_DECREF(kobj);
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
Py_DECREF(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
return d;
|
||||
%End
|
||||
|
||||
%ConvertToTypeCode
|
||||
if (!sipIsErr)
|
||||
return PyDict_Check(sipPy);
|
||||
|
||||
QMap<QString, ads::CDockWidget*> *qm = new QMap<QString, ads::CDockWidget*>;
|
||||
|
||||
Py_ssize_t pos = 0;
|
||||
PyObject *kobj, *vobj;
|
||||
while (PyDict_Next(sipPy, &pos, &kobj, &vobj))
|
||||
{
|
||||
int kstate;
|
||||
QString *k = reinterpret_cast<QString *>(
|
||||
sipForceConvertToType(kobj, sipType_QString, sipTransferObj,
|
||||
SIP_NOT_NONE, &kstate, sipIsErr));
|
||||
|
||||
if (*sipIsErr)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"a dict key has type '%s' but '_TYPE1_' is expected",
|
||||
sipPyTypeName(Py_TYPE(kobj)));
|
||||
|
||||
delete qm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vstate;
|
||||
ads::CDockWidget *v = reinterpret_cast<ads::CDockWidget *>(
|
||||
sipForceConvertToType(vobj, sipType_ads_CDockWidget, sipTransferObj,
|
||||
SIP_NOT_NONE, &vstate, sipIsErr));
|
||||
|
||||
if (*sipIsErr)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"a dict value has type '%s' but '_TYPE2_' is expected",
|
||||
sipPyTypeName(Py_TYPE(vobj)));
|
||||
|
||||
sipReleaseType(k, sipType_QString, kstate);
|
||||
delete qm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
qm->insert(*k, v);
|
||||
|
||||
sipReleaseType(v, sipType_ads_CDockWidget, vstate);
|
||||
sipReleaseType(k, sipType_QString, kstate);
|
||||
}
|
||||
|
||||
*sipCppPtr = qm;
|
||||
|
||||
return sipGetState(sipTransferObj);
|
||||
%End
|
||||
};
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CDockManager : ads::CDockContainerWidget
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include <DockManager.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
void registerFloatingWidget(ads::CFloatingDockContainer* FloatingWidget /Transfer/);
|
||||
void removeFloatingWidget(ads::CFloatingDockContainer* FloatingWidget) /TransferBack/;
|
||||
void registerDockContainer(ads::CDockContainerWidget* DockContainer /Transfer/);
|
||||
void removeDockContainer(ads::CDockContainerWidget* DockContainer /TransferBack/);
|
||||
ads::CDockOverlay* containerOverlay() const;
|
||||
ads::CDockOverlay* dockAreaOverlay() const;
|
||||
|
||||
public:
|
||||
enum eViewMenuInsertionOrder
|
||||
{
|
||||
MenuSortedByInsertion,
|
||||
MenuAlphabeticallySorted
|
||||
};
|
||||
|
||||
enum eConfigFlag
|
||||
{
|
||||
ActiveTabHasCloseButton,
|
||||
DockAreaHasCloseButton,
|
||||
DockAreaCloseButtonClosesTab,
|
||||
OpaqueSplitterResize,
|
||||
XmlAutoFormattingEnabled,
|
||||
XmlCompressionEnabled,
|
||||
TabCloseButtonIsToolButton,
|
||||
AllTabsHaveCloseButton,
|
||||
RetainTabSizeWhenCloseButtonHidden,
|
||||
DefaultConfig,
|
||||
};
|
||||
typedef QFlags<ads::CDockManager::eConfigFlag> ConfigFlags;
|
||||
|
||||
CDockManager(QWidget* parent /TransferThis/ = 0);
|
||||
virtual ~CDockManager();
|
||||
static ads::CDockManager::ConfigFlags configFlags();
|
||||
static void setConfigFlags(const ads::CDockManager::ConfigFlags Flags);
|
||||
static void setConfigFlag(ads::CDockManager::eConfigFlag Flag, bool On = true);
|
||||
ads::CDockAreaWidget* addDockWidget(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
|
||||
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0);
|
||||
ads::CDockAreaWidget* addDockWidgetTab(ads::DockWidgetArea area,
|
||||
ads::CDockWidget* Dockwidget /Transfer/);
|
||||
ads::CDockAreaWidget* addDockWidgetTabToArea(ads::CDockWidget* Dockwidget /Transfer/,
|
||||
ads::CDockAreaWidget* DockAreaWidget /Transfer/);
|
||||
ads::CDockWidget* findDockWidget(const QString& ObjectName) const;
|
||||
void removeDockWidget(ads::CDockWidget* Dockwidget) /TransferBack/;
|
||||
QMap<QString, ads::CDockWidget*> dockWidgetsMap() const;
|
||||
const QList<ads::CDockContainerWidget*> dockContainers() const;
|
||||
const QList<ads::CFloatingDockContainer*> floatingWidgets() const;
|
||||
virtual unsigned int zOrderIndex() const;
|
||||
QByteArray saveState(int version = 0) const;
|
||||
bool restoreState(const QByteArray &state, int version = 0);
|
||||
void addPerspective(const QString& UniquePrespectiveName);
|
||||
void removePerspective(const QString& Name);
|
||||
void removePerspectives(const QStringList& Names);
|
||||
QStringList perspectiveNames() const;
|
||||
void savePerspectives(QSettings& Settings) const;
|
||||
void loadPerspectives(QSettings& Settings);
|
||||
QAction* addToggleViewActionToMenu(QAction* ToggleViewAction /Transfer/,
|
||||
const QString& Group = QString(), const QIcon& GroupIcon = QIcon());
|
||||
QMenu* viewMenu() const;
|
||||
void setViewMenuInsertionOrder(ads::CDockManager::eViewMenuInsertionOrder Order);
|
||||
bool isRestoringState() const;
|
||||
static int startDragDistance();
|
||||
|
||||
public slots:
|
||||
void openPerspective(const QString& PerspectiveName);
|
||||
|
||||
signals:
|
||||
void perspectiveListChanged();
|
||||
void perspectivesRemoved();
|
||||
void restoringState();
|
||||
void stateRestored();
|
||||
void openingPerspective(const QString& PerspectiveName);
|
||||
void perspectiveOpened(const QString& PerspectiveName);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
77
sip/DockOverlay.sip
Normal file
77
sip/DockOverlay.sip
Normal file
@@ -0,0 +1,77 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CDockOverlay : public QFrame
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <DockOverlay.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
|
||||
enum eMode
|
||||
{
|
||||
ModeDockAreaOverlay,
|
||||
ModeContainerOverlay
|
||||
};
|
||||
|
||||
CDockOverlay(QWidget* parent /TransferThis/, eMode Mode = ads::CDockOverlay::ModeDockAreaOverlay);
|
||||
virtual ~CDockOverlay();
|
||||
void setAllowedAreas(ads::DockWidgetAreas areas);
|
||||
ads::DockWidgetAreas allowedAreas() const;
|
||||
ads::DockWidgetArea dropAreaUnderCursor() const;
|
||||
ads::DockWidgetArea showOverlay(QWidget* target);
|
||||
void hideOverlay();
|
||||
void enableDropPreview(bool Enable);
|
||||
QRect dropOverlayRect() const;
|
||||
virtual bool event(QEvent *e);
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *e);
|
||||
virtual void showEvent(QShowEvent* e);
|
||||
virtual void hideEvent(QHideEvent* e);
|
||||
};
|
||||
|
||||
|
||||
class CDockOverlayCross : public QWidget
|
||||
{
|
||||
|
||||
public:
|
||||
enum eIconColor
|
||||
{
|
||||
FrameColor,
|
||||
WindowBackgroundColor,
|
||||
OverlayColor,
|
||||
ArrowColor,
|
||||
ShadowColor
|
||||
};
|
||||
|
||||
protected:
|
||||
QString iconColors() const;
|
||||
QColor iconColor() const;
|
||||
void setIconFrameColor(const QColor& Color);
|
||||
void setIconBackgroundColor(const QColor& Color);
|
||||
void setIconOverlayColor(const QColor& Color);
|
||||
void setIconArrowColor(const QColor& Color);
|
||||
void setIconShadowColor(const QColor& Color);
|
||||
|
||||
public:
|
||||
CDockOverlayCross(ads::CDockOverlay* overlay /TransferThis/);
|
||||
virtual ~CDockOverlayCross();
|
||||
void setIconColor(ads::CDockOverlayCross::eIconColor ColorIndex, const QColor& Color);
|
||||
QColor iconColor(ads::CDockOverlayCross::eIconColor ColorIndex) const;
|
||||
ads::DockWidgetArea cursorLocation() const;
|
||||
void setupOverlayCross(ads::CDockOverlay::eMode Mode);
|
||||
void updateOverlayIcons();
|
||||
void reset();
|
||||
void updatePosition();
|
||||
void setIconColors(const QString& Colors);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
23
sip/DockSplitter.sip
Normal file
23
sip/DockSplitter.sip
Normal file
@@ -0,0 +1,23 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CDockSplitter : QSplitter
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <DockSplitter.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
CDockSplitter(QWidget *parent /TransferThis/ = 0);
|
||||
CDockSplitter(Qt::Orientation orientation, QWidget *parent /TransferThis/ = 0);
|
||||
virtual ~CDockSplitter();
|
||||
bool hasVisibleContent() const;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
101
sip/DockWidget.sip
Normal file
101
sip/DockWidget.sip
Normal file
@@ -0,0 +1,101 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CDockWidget : QFrame
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <DockWidget.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
void setDockManager(ads::CDockManager* DockManager /Transfer/);
|
||||
void setDockArea(ads::CDockAreaWidget* DockArea /Transfer/);
|
||||
void setToggleViewActionChecked(bool Checked);
|
||||
void saveState(QXmlStreamWriter& Stream) const;
|
||||
void flagAsUnassigned();
|
||||
static void emitTopLevelEventForWidget(ads::CDockWidget* TopLevelDockWidget, bool Floating);
|
||||
void emitTopLevelChanged(bool Floating);
|
||||
void setClosedState(bool Closed);
|
||||
void toggleViewInternal(bool Open);
|
||||
|
||||
public:
|
||||
enum DockWidgetFeature
|
||||
{
|
||||
DockWidgetClosable,
|
||||
DockWidgetMovable,
|
||||
DockWidgetFloatable,
|
||||
AllDockWidgetFeatures,
|
||||
NoDockWidgetFeatures
|
||||
};
|
||||
typedef QFlags<ads::CDockWidget::DockWidgetFeature> DockWidgetFeatures;
|
||||
|
||||
enum eState
|
||||
{
|
||||
StateHidden,
|
||||
StateDocked,
|
||||
StateFloating
|
||||
};
|
||||
|
||||
enum eInsertMode
|
||||
{
|
||||
AutoScrollArea,
|
||||
ForceScrollArea,
|
||||
ForceNoScrollArea
|
||||
};
|
||||
|
||||
enum eToggleViewActionMode
|
||||
{
|
||||
ActionModeToggle,
|
||||
ActionModeShow
|
||||
};
|
||||
|
||||
|
||||
CDockWidget(const QString &title, QWidget* parent /TransferThis/ = 0);
|
||||
virtual ~CDockWidget();
|
||||
virtual QSize minimumSizeHint() const;
|
||||
void setWidget(QWidget* widget /Transfer/, ads::CDockWidget::eInsertMode InsertMode = AutoScrollArea);
|
||||
QWidget* takeWidget() /TransferBack/;
|
||||
QWidget* widget() const;
|
||||
ads::CDockWidgetTab* tabWidget() const;
|
||||
void setFeatures(ads::CDockWidget::DockWidgetFeatures features);
|
||||
void setFeature(ads::CDockWidget::DockWidgetFeature flag, bool on);
|
||||
ads::CDockWidget::DockWidgetFeatures features() const;
|
||||
ads::CDockManager* dockManager() const;
|
||||
ads::CDockContainerWidget* dockContainer() const;
|
||||
ads::CDockAreaWidget* dockAreaWidget() const;
|
||||
bool isFloating() const;
|
||||
bool isInFloatingContainer() const;
|
||||
bool isClosed() const;
|
||||
QAction* toggleViewAction() const;
|
||||
void setToggleViewActionMode(ads::CDockWidget::eToggleViewActionMode Mode);
|
||||
void setIcon(const QIcon& Icon);
|
||||
QIcon icon() const;
|
||||
QToolBar* toolBar() const;
|
||||
QToolBar* createDefaultToolBar();
|
||||
void setToolBar(QToolBar* ToolBar);
|
||||
void setToolBarStyle(Qt::ToolButtonStyle Style, ads::CDockWidget::eState State);
|
||||
Qt::ToolButtonStyle toolBarStyle(ads::CDockWidget::eState State) const;
|
||||
void setToolBarIconSize(const QSize& IconSize, ads::CDockWidget::eState State);
|
||||
QSize toolBarIconSize(eState State) const;
|
||||
void setTabToolTip(const QString &text);
|
||||
|
||||
public:
|
||||
virtual bool event(QEvent *e);
|
||||
|
||||
public slots:
|
||||
void toggleView(bool Open = true);
|
||||
|
||||
signals:
|
||||
void viewToggled(bool Open);
|
||||
void closed();
|
||||
void titleChanged(const QString& Title);
|
||||
void topLevelChanged(bool topLevel);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
50
sip/DockWidgetTab.sip
Normal file
50
sip/DockWidgetTab.sip
Normal file
@@ -0,0 +1,50 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CDockWidgetTab : QFrame
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <DockWidgetTab.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent* ev);
|
||||
virtual void mouseReleaseEvent(QMouseEvent* ev);
|
||||
virtual void mouseMoveEvent(QMouseEvent* ev);
|
||||
virtual void contextMenuEvent(QContextMenuEvent* ev);
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event);
|
||||
|
||||
public:
|
||||
CDockWidgetTab(ads::CDockWidget* DockWidget /TransferThis/, QWidget* parent /TransferThis/ = 0);
|
||||
virtual ~CDockWidgetTab();
|
||||
bool isActiveTab() const;
|
||||
void setActiveTab(bool active);
|
||||
ads::CDockWidget* dockWidget() const;
|
||||
void setDockAreaWidget(ads::CDockAreaWidget* DockArea /Transfer/);
|
||||
ads::CDockAreaWidget* dockAreaWidget() const;
|
||||
void setIcon(const QIcon& Icon);
|
||||
const QIcon& icon() const;
|
||||
QString text() const;
|
||||
void setText(const QString& title);
|
||||
bool isClosable() const;
|
||||
virtual bool event(QEvent *e);
|
||||
|
||||
|
||||
public slots:
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
signals:
|
||||
void activeTabChanged();
|
||||
void clicked();
|
||||
void closeRequested();
|
||||
void closeOtherTabsRequested();
|
||||
void moved(const QPoint& GlobalPos);
|
||||
}; // class DockWidgetTab
|
||||
};
|
||||
// namespace ads
|
||||
|
||||
%End
|
||||
40
sip/ElidingLabel.sip
Normal file
40
sip/ElidingLabel.sip
Normal file
@@ -0,0 +1,40 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CElidingLabel : QLabel
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <ElidingLabel.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual void mouseReleaseEvent(QMouseEvent* event);
|
||||
virtual void resizeEvent( QResizeEvent *event );
|
||||
virtual void mouseDoubleClickEvent( QMouseEvent *ev );
|
||||
|
||||
public:
|
||||
CElidingLabel(QWidget* parent /TransferThis/ = 0, Qt::WindowFlags f = 0);
|
||||
CElidingLabel(const QString& text, QWidget* parent /TransferThis/ = 0, Qt::WindowFlags f = 0);
|
||||
virtual ~CElidingLabel();
|
||||
Qt::TextElideMode elideMode() const;
|
||||
void setElideMode(Qt::TextElideMode mode);
|
||||
|
||||
|
||||
public:
|
||||
virtual QSize minimumSizeHint() const;
|
||||
virtual QSize sizeHint() const;
|
||||
void setText(const QString &text);
|
||||
QString text() const;
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
void doubleClicked();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
50
sip/FloatingDockContainer.sip
Normal file
50
sip/FloatingDockContainer.sip
Normal file
@@ -0,0 +1,50 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
class CFloatingDockContainer : QWidget
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include <FloatingDockContainer.h>
|
||||
%End
|
||||
|
||||
protected:
|
||||
void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
|
||||
ads::eDragState DragState, QWidget* MouseEventHandler);
|
||||
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
|
||||
QWidget* MouseEventHandler);
|
||||
void finishDragging();
|
||||
void initFloatingGeometry(const QPoint& DragStartMousePos, const QSize& Size);
|
||||
void moveFloating();
|
||||
bool restoreState(QXmlStreamReader& Stream, bool Testing);
|
||||
void updateWindowTitle();
|
||||
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent *event);
|
||||
virtual void moveEvent(QMoveEvent *event);
|
||||
virtual bool event(QEvent *e);
|
||||
virtual void closeEvent(QCloseEvent *event);
|
||||
virtual void hideEvent(QHideEvent *event);
|
||||
virtual void showEvent(QShowEvent *event);
|
||||
virtual bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
public:
|
||||
CFloatingDockContainer(ads::CDockManager* DockManager /TransferThis/);
|
||||
CFloatingDockContainer(ads::CDockAreaWidget* DockArea /TransferThis/);
|
||||
CFloatingDockContainer(ads::CDockWidget* DockWidget /TransferThis/);
|
||||
virtual ~CFloatingDockContainer();
|
||||
ads::CDockContainerWidget* dockContainer() const;
|
||||
bool isClosable() const;
|
||||
bool hasTopLevelDockWidget() const;
|
||||
ads::CDockWidget* topLevelDockWidget() const;
|
||||
QList<ads::CDockWidget*> dockWidgets() const;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
20
sip/ads.sip
Normal file
20
sip/ads.sip
Normal file
@@ -0,0 +1,20 @@
|
||||
%Module(name=PyQtAds.QtAds.ads, call_super_init=True, keyword_arguments="Optional", use_limited_api=True)
|
||||
%Import QtCore/QtCoremod.sip
|
||||
%DefaultSupertype sip.simplewrapper
|
||||
%Platforms {Linux macOS Windows}
|
||||
|
||||
%Include ads_globals.sip
|
||||
%Include DockWidget.sip
|
||||
%Include DockAreaTabBar.sip
|
||||
%Include DockAreaTitleBar.sip
|
||||
%Include DockAreaWidget.sip
|
||||
%Include DockContainerWidget.sip
|
||||
%Include DockManager.sip
|
||||
%Include DockOverlay.sip
|
||||
%Include DockSplitter.sip
|
||||
%Include DockWidgetTab.sip
|
||||
%Include ElidingLabel.sip
|
||||
%Include FloatingDockContainer.sip
|
||||
%If (Linux)
|
||||
%Include linux/FloatingWidgetTitleBar.sip
|
||||
%End
|
||||
44
sip/ads_globals.sip
Normal file
44
sip/ads_globals.sip
Normal file
@@ -0,0 +1,44 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <ads_globals.h>
|
||||
%End
|
||||
|
||||
enum DockWidgetArea
|
||||
{
|
||||
NoDockWidgetArea,
|
||||
LeftDockWidgetArea,
|
||||
RightDockWidgetArea,
|
||||
TopDockWidgetArea,
|
||||
BottomDockWidgetArea,
|
||||
CenterDockWidgetArea,
|
||||
|
||||
InvalidDockWidgetArea,
|
||||
OuterDockAreas,
|
||||
AllDockAreas
|
||||
};
|
||||
typedef QFlags<ads::DockWidgetArea> DockWidgetAreas;
|
||||
|
||||
|
||||
enum TitleBarButton
|
||||
{
|
||||
TitleBarButtonTabsMenu,
|
||||
TitleBarButtonUndock,
|
||||
TitleBarButtonClose
|
||||
};
|
||||
|
||||
enum eDragState
|
||||
{
|
||||
DraggingInactive,
|
||||
DraggingMousePressed,
|
||||
DraggingTab,
|
||||
DraggingFloatingWidget
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
31
sip/linux/FloatingWidgetTitleBar.sip
Normal file
31
sip/linux/FloatingWidgetTitleBar.sip
Normal file
@@ -0,0 +1,31 @@
|
||||
%Import QtWidgets/QtWidgetsmod.sip
|
||||
|
||||
%If (Qt_5_0_0 -)
|
||||
|
||||
namespace ads
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <FloatingWidgetTitleBar.h>
|
||||
%End
|
||||
|
||||
class CFloatingWidgetTitleBar : QWidget
|
||||
{
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent *ev);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *ev);
|
||||
virtual void mouseMoveEvent(QMouseEvent *ev);
|
||||
|
||||
public:
|
||||
explicit CFloatingWidgetTitleBar(CFloatingDockContainer *parent /TransferThis/ = 0);
|
||||
virtual ~CFloatingWidgetTitleBar();
|
||||
void enableCloseButton(bool Enable);
|
||||
void setTitle(const QString &Text);
|
||||
|
||||
signals:
|
||||
void closeRequested();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
%End
|
||||
@@ -113,7 +113,7 @@ CDockAreaTabBar::CDockAreaTabBar(CDockAreaWidget* parent) :
|
||||
d(new DockAreaTabBarPrivate(this))
|
||||
{
|
||||
d->DockArea = parent;
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
setWidgetResizable(true);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
@@ -171,7 +171,7 @@ void CDockAreaTabBar::mouseReleaseEvent(QMouseEvent* ev)
|
||||
{
|
||||
if (ev->button() == Qt::LeftButton)
|
||||
{
|
||||
qDebug() << "CTabsScrollArea::mouseReleaseEvent";
|
||||
ADS_PRINT("CTabsScrollArea::mouseReleaseEvent");
|
||||
ev->accept();
|
||||
d->FloatingWidget = nullptr;
|
||||
d->DragStartMousePos = QPoint();
|
||||
@@ -205,10 +205,17 @@ void CDockAreaTabBar::mouseMoveEvent(QMouseEvent* ev)
|
||||
return;
|
||||
}
|
||||
|
||||
// If one single dock widget in this area is not floatable then the whole
|
||||
// area is not floatable
|
||||
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int DragDistance = (d->DragStartMousePos - ev->pos()).manhattanLength();
|
||||
if (DragDistance >= CDockManager::startDragDistance())
|
||||
{
|
||||
qDebug() << "CTabsScrollArea::startFloating";
|
||||
ADS_PRINT("CTabsScrollArea::startFloating");
|
||||
startFloating(d->DragStartMousePos);
|
||||
auto Overlay = d->DockArea->dockManager()->containerOverlay();
|
||||
Overlay->setAllowedAreas(OuterDockAreas);
|
||||
@@ -228,6 +235,11 @@ void CDockAreaTabBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
{
|
||||
return;
|
||||
}
|
||||
makeAreaFloating(event->pos(), DraggingInactive);
|
||||
}
|
||||
|
||||
@@ -238,7 +250,7 @@ CFloatingDockContainer* CDockAreaTabBar::makeAreaFloating(const QPoint& Offset,
|
||||
{
|
||||
QSize Size = d->DockArea->size();
|
||||
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(d->DockArea);
|
||||
FloatingWidget->startFloating(Offset, Size, DragState);
|
||||
FloatingWidget->startFloating(Offset, Size, DragState, nullptr);
|
||||
auto TopLevelDockWidget = FloatingWidget->topLevelDockWidget();
|
||||
if (TopLevelDockWidget)
|
||||
{
|
||||
@@ -309,7 +321,7 @@ void CDockAreaTabBar::removeTab(CDockWidgetTab* Tab)
|
||||
{
|
||||
return;
|
||||
}
|
||||
qDebug() << "CDockAreaTabBar::removeTab ";
|
||||
ADS_PRINT("CDockAreaTabBar::removeTab ");
|
||||
int NewCurrentIndex = currentIndex();
|
||||
int RemoveIndex = d->TabsLayout->indexOf(Tab);
|
||||
if (count() == 1)
|
||||
@@ -352,7 +364,7 @@ void CDockAreaTabBar::removeTab(CDockWidgetTab* Tab)
|
||||
d->TabsLayout->removeWidget(Tab);
|
||||
Tab->disconnect(this);
|
||||
Tab->removeEventFilter(this);
|
||||
qDebug() << "NewCurrentIndex " << NewCurrentIndex;
|
||||
ADS_PRINT("NewCurrentIndex " << NewCurrentIndex);
|
||||
if (NewCurrentIndex != d->CurrentIndex)
|
||||
{
|
||||
setCurrentIndex(NewCurrentIndex);
|
||||
@@ -480,7 +492,7 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
|
||||
{
|
||||
if (MousePos.x() > tab(count() - 1)->geometry().right())
|
||||
{
|
||||
qDebug() << "after all tabs";
|
||||
ADS_PRINT("after all tabs");
|
||||
toIndex = count() - 1;
|
||||
}
|
||||
else
|
||||
@@ -493,7 +505,7 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
|
||||
d->TabsLayout->insertWidget(toIndex, MovingTab);
|
||||
if (toIndex >= 0)
|
||||
{
|
||||
qDebug() << "tabMoved from " << fromIndex << " to " << toIndex;
|
||||
ADS_PRINT("tabMoved from " << fromIndex << " to " << toIndex);
|
||||
emit tabMoved(fromIndex, toIndex);
|
||||
setCurrentIndex(toIndex);
|
||||
}
|
||||
@@ -513,8 +525,8 @@ void CDockAreaTabBar::closeTab(int Index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
emit tabCloseRequested(Index);
|
||||
Tab->hide();
|
||||
emit tabCloseRequested(Index);
|
||||
}
|
||||
|
||||
|
||||
@@ -553,6 +565,23 @@ bool CDockAreaTabBar::isTabOpen(int Index) const
|
||||
return !tab(Index)->isHidden();
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
QSize CDockAreaTabBar::minimumSizeHint() const
|
||||
{
|
||||
QSize Size = sizeHint();
|
||||
Size.setWidth(Super::minimumSizeHint().width());// this defines the minimum width of a dock area
|
||||
return Size;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
QSize CDockAreaTabBar::sizeHint() const
|
||||
{
|
||||
QSize Size = Super::sizeHint();
|
||||
Size.setHeight(d->TabsContainerWidget->sizeHint().height());
|
||||
return Size;
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -44,8 +44,12 @@ class CFloatingDockContainer;
|
||||
* Custom tabbar implementation for tab area that is shown on top of a
|
||||
* dock area widget.
|
||||
* The tabbar displays the tab widgets of the contained dock widgets.
|
||||
* We cannot use QTabBar here because it does a lot of fancy animations
|
||||
* that will crash the application if a tab is removed while the animation
|
||||
* has not finished. And we need to remove a tab, if the user drags a
|
||||
* a dock widget out of a group of tabbed widgets
|
||||
*/
|
||||
class CDockAreaTabBar : public QScrollArea
|
||||
class ADS_EXPORT CDockAreaTabBar : public QScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
@@ -61,6 +65,7 @@ private slots:
|
||||
|
||||
protected:
|
||||
virtual void wheelEvent(QWheelEvent* Event) override;
|
||||
|
||||
/**
|
||||
* Stores mouse position to detect dragging
|
||||
*/
|
||||
@@ -96,6 +101,7 @@ protected:
|
||||
|
||||
public:
|
||||
using Super = QScrollArea;
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
*/
|
||||
@@ -150,6 +156,21 @@ public:
|
||||
*/
|
||||
bool isTabOpen(int Index) const;
|
||||
|
||||
/**
|
||||
* Overrides the minimumSizeHint() function of QScrollArea
|
||||
* The minimumSizeHint() is bigger than the sizeHint () for the scroll
|
||||
* area because even if the scrollbars are invisible, the required speace
|
||||
* is reserved in the minimumSizeHint(). This override simply returns
|
||||
* sizeHint();
|
||||
*/
|
||||
virtual QSize minimumSizeHint() const override;
|
||||
|
||||
/**
|
||||
* The function provides a sizeHint that matches the height of the
|
||||
* internal viewport.
|
||||
*/
|
||||
virtual QSize sizeHint() const override;
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* This property sets the index of the tab bar's visible tab
|
||||
|
||||
@@ -95,8 +95,26 @@ struct DockAreaTitleBarPrivate
|
||||
*/
|
||||
bool testConfigFlag(CDockManager::eConfigFlag Flag) const
|
||||
{
|
||||
return DockArea->dockManager()->configFlags().testFlag(Flag);
|
||||
return CDockManager::configFlags().testFlag(Flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to set title bar button icons depending on operating
|
||||
* system and to avoid duplicated code. On windows the standard icons
|
||||
* are blurry since Qt 5.11 so we need to do some additional steps
|
||||
*/
|
||||
void setTitleBarButtonIcon(tTileBarButton* Button, QStyle::StandardPixmap StandarPixmap)
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
Button->setIcon(_this->style()->standardIcon(StandarPixmap));
|
||||
#else
|
||||
QIcon Icon;
|
||||
QPixmap normalPixmap = _this->style()->standardPixmap(StandarPixmap, 0, Button);
|
||||
Icon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
|
||||
Icon.addPixmap(normalPixmap, QIcon::Normal);
|
||||
Button->setIcon(Icon);
|
||||
#endif
|
||||
}
|
||||
};// struct DockAreaTitleBarPrivate
|
||||
|
||||
|
||||
@@ -112,50 +130,47 @@ DockAreaTitleBarPrivate::DockAreaTitleBarPrivate(CDockAreaTitleBar* _public) :
|
||||
//============================================================================
|
||||
void DockAreaTitleBarPrivate::createButtons()
|
||||
{
|
||||
QSizePolicy ButtonSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
// Tabs menu button
|
||||
TabsMenuButton = new tTileBarButton();
|
||||
TabsMenuButton->setObjectName("tabsMenuButton");
|
||||
TabsMenuButton->setAutoRaise(true);
|
||||
TabsMenuButton->setPopupMode(QToolButton::InstantPopup);
|
||||
TabsMenuButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarUnshadeButton));
|
||||
|
||||
setTitleBarButtonIcon(TabsMenuButton, QStyle::SP_TitleBarUnshadeButton);
|
||||
QMenu* TabsMenu = new QMenu(TabsMenuButton);
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
TabsMenu->setToolTipsVisible(true);
|
||||
#endif
|
||||
#endif
|
||||
_this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow()));
|
||||
TabsMenuButton->setMenu(TabsMenu);
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
TabsMenuButton->setToolTip(QObject::tr("List all tabs"));
|
||||
#endif
|
||||
TabsMenuButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
#endif
|
||||
TabsMenuButton->setSizePolicy(ButtonSizePolicy);
|
||||
TopLayout->addWidget(TabsMenuButton, 0);
|
||||
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
|
||||
SLOT(onTabsMenuActionTriggered(QAction*)));
|
||||
|
||||
|
||||
// Undock button
|
||||
UndockButton = new tTileBarButton();
|
||||
UndockButton->setObjectName("undockButton");
|
||||
UndockButton->setAutoRaise(true);
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
UndockButton->setToolTip(QObject::tr("Detach Group"));
|
||||
#endif
|
||||
UndockButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarNormalButton));
|
||||
UndockButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
#endif
|
||||
setTitleBarButtonIcon(UndockButton, QStyle::SP_TitleBarNormalButton);
|
||||
UndockButton->setSizePolicy(ButtonSizePolicy);
|
||||
TopLayout->addWidget(UndockButton, 0);
|
||||
_this->connect(UndockButton, SIGNAL(clicked()), SLOT(onUndockButtonClicked()));
|
||||
|
||||
|
||||
// Close button
|
||||
CloseButton = new tTileBarButton();
|
||||
CloseButton->setObjectName("closeButton");
|
||||
CloseButton->setAutoRaise(true);
|
||||
|
||||
// The standard icons do not look good on high DPI screens
|
||||
QIcon CloseIcon = _this->style()->standardIcon(QStyle::SP_TitleBarCloseButton);
|
||||
QPixmap normalPixmap = _this->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, CloseButton);
|
||||
QPixmap disabledPixmap = internal::createTransparentPixmap(normalPixmap, 0.25);
|
||||
CloseIcon.addPixmap(disabledPixmap, QIcon::Disabled);
|
||||
|
||||
CloseButton->setIcon(CloseIcon);
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
setTitleBarButtonIcon(CloseButton, QStyle::SP_TitleBarCloseButton);
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
if (testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab))
|
||||
{
|
||||
CloseButton->setToolTip(QObject::tr("Close Active Tab"));
|
||||
@@ -164,9 +179,13 @@ void DockAreaTitleBarPrivate::createButtons()
|
||||
{
|
||||
CloseButton->setToolTip(QObject::tr("Close Group"));
|
||||
}
|
||||
#endif
|
||||
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
TopLayout->addWidget(CloseButton, 0);
|
||||
#endif
|
||||
CloseButton->setSizePolicy(ButtonSizePolicy);
|
||||
CloseButton->setIconSize(QSize(16, 16));
|
||||
if (testConfigFlag(CDockManager::DockAreaHasCloseButton))
|
||||
{
|
||||
TopLayout->addWidget(CloseButton, 0);
|
||||
}
|
||||
_this->connect(CloseButton, SIGNAL(clicked()), SLOT(onCloseButtonClicked()));
|
||||
}
|
||||
|
||||
@@ -262,7 +281,7 @@ void CDockAreaTitleBar::onTabsMenuAboutToShow()
|
||||
//============================================================================
|
||||
void CDockAreaTitleBar::onCloseButtonClicked()
|
||||
{
|
||||
qDebug() << "CDockAreaTitleBar::onCloseButtonClicked";
|
||||
ADS_PRINT("CDockAreaTitleBar::onCloseButtonClicked");
|
||||
if (d->testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab))
|
||||
{
|
||||
d->TabBar->closeTab(d->TabBar->currentIndex());
|
||||
@@ -277,7 +296,10 @@ void CDockAreaTitleBar::onCloseButtonClicked()
|
||||
//============================================================================
|
||||
void CDockAreaTitleBar::onUndockButtonClicked()
|
||||
{
|
||||
d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
|
||||
if (d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
{
|
||||
d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -332,9 +354,10 @@ void CDockAreaTitleBar::setVisible(bool Visible)
|
||||
void CDockAreaTitleBar::showContextMenu(const QPoint& pos)
|
||||
{
|
||||
QMenu Menu(this);
|
||||
Menu.addAction(tr("Detach Area"), this, SLOT(onUndockButtonClicked()));
|
||||
auto Action = Menu.addAction(tr("Detach Area"), this, SLOT(onUndockButtonClicked()));
|
||||
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable));
|
||||
Menu.addSeparator();
|
||||
auto Action = Menu.addAction(tr("Close Area"), this, SLOT(onCloseButtonClicked()));
|
||||
Action = Menu.addAction(tr("Close Area"), this, SLOT(onCloseButtonClicked()));
|
||||
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable));
|
||||
Menu.addAction(tr("Close Other Areas"), d->DockArea, SLOT(closeOtherAreas()));
|
||||
Menu.exec(mapToGlobal(pos));
|
||||
|
||||
@@ -43,9 +43,11 @@ class CDockAreaWidget;
|
||||
struct DockAreaTitleBarPrivate;
|
||||
|
||||
/**
|
||||
* Title bar of a dock area
|
||||
* Title bar of a dock area.
|
||||
* The title bar contains a tabbar with all tabs for a dock widget group and
|
||||
* with a tabs menu button, a undock button and a close button.
|
||||
*/
|
||||
class CDockAreaTitleBar : public QFrame
|
||||
class ADS_EXPORT CDockAreaTitleBar : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
@@ -61,6 +63,10 @@ private slots:
|
||||
void showContextMenu(const QPoint& pos);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Call this slot to tell the title bar that it should update the tabs menu
|
||||
* the next time it is shown.
|
||||
*/
|
||||
void markTabsMenuOutdated();
|
||||
|
||||
|
||||
@@ -87,7 +93,8 @@ public:
|
||||
QAbstractButton* button(TitleBarButton which) const;
|
||||
|
||||
/**
|
||||
* This function is here for debug reasons
|
||||
* Marks the tabs menu outdated before it calls its base class
|
||||
* implementation
|
||||
*/
|
||||
virtual void setVisible(bool Visible) override;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <DockWidgetTab.h>
|
||||
#include "DockWidgetTab.h"
|
||||
#include "DockAreaWidget.h"
|
||||
|
||||
#include <QStackedLayout>
|
||||
@@ -63,8 +63,11 @@ static const char* const INDEX_PROPERTY = "index";
|
||||
static const char* const ACTION_PROPERTY = "action";
|
||||
|
||||
/**
|
||||
* New dock area layout mimics stack layout but only inserts the current
|
||||
* widget into the internal QLayout object
|
||||
* Internal dock area layout mimics stack layout but only inserts the current
|
||||
* widget into the internal QLayout object.
|
||||
* \warning Only the current widget has a parent. All other widgets
|
||||
* do not have a parent. That means, a widget that is in this layout may
|
||||
* return nullptr for its parent() function if it is not the current widget.
|
||||
*/
|
||||
class CDockAreaLayout
|
||||
{
|
||||
@@ -118,7 +121,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given widget from the lyout
|
||||
* Removes the given widget from the layout
|
||||
*/
|
||||
void removeWidget(QWidget* Widget)
|
||||
{
|
||||
@@ -241,7 +244,7 @@ struct DockAreaWidgetPrivate
|
||||
DockAreaLayout* ContentsLayout = nullptr;
|
||||
CDockAreaTitleBar* TitleBar = nullptr;
|
||||
CDockManager* DockManager = nullptr;
|
||||
bool UpdateCloseButton = false;
|
||||
bool UpdateTitleBarButtons = false;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -295,9 +298,9 @@ struct DockAreaWidgetPrivate
|
||||
}
|
||||
|
||||
/**
|
||||
* Udpates the enable state of the close button
|
||||
* Udpates the enable state of the close and detach button
|
||||
*/
|
||||
void updateCloseButtonState();
|
||||
void updateTitleBarButtonStates();
|
||||
};
|
||||
// struct DockAreaWidgetPrivate
|
||||
|
||||
@@ -322,17 +325,19 @@ void DockAreaWidgetPrivate::createTitleBar()
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockAreaWidgetPrivate::updateCloseButtonState()
|
||||
void DockAreaWidgetPrivate::updateTitleBarButtonStates()
|
||||
{
|
||||
if (_this->isHidden())
|
||||
{
|
||||
UpdateCloseButton = true;
|
||||
UpdateTitleBarButtons = true;
|
||||
return;
|
||||
}
|
||||
|
||||
TitleBar->button(TitleBarButtonClose)->setEnabled(
|
||||
_this->features().testFlag(CDockWidget::DockWidgetClosable));
|
||||
UpdateCloseButton = false;
|
||||
TitleBar->button(TitleBarButtonUndock)->setEnabled(
|
||||
_this->features().testFlag(CDockWidget::DockWidgetFloatable));
|
||||
UpdateTitleBarButtons = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -354,7 +359,7 @@ CDockAreaWidget::CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget
|
||||
//============================================================================
|
||||
CDockAreaWidget::~CDockAreaWidget()
|
||||
{
|
||||
qDebug() << "~CDockAreaWidget()";
|
||||
ADS_PRINT("~CDockAreaWidget()");
|
||||
delete d->ContentsLayout;
|
||||
delete d;
|
||||
}
|
||||
@@ -400,28 +405,29 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
|
||||
setCurrentIndex(index);
|
||||
}
|
||||
DockWidget->setDockArea(this);
|
||||
d->updateCloseButtonState();
|
||||
d->updateTitleBarButtonStates();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
|
||||
{
|
||||
qDebug() << "CDockAreaWidget::removeDockWidget";
|
||||
ADS_PRINT("CDockAreaWidget::removeDockWidget");
|
||||
auto NextOpenDockWidget = nextOpenDockWidget(DockWidget);
|
||||
|
||||
d->ContentsLayout->removeWidget(DockWidget);
|
||||
auto TabWidget = DockWidget->tabWidget();
|
||||
TabWidget->hide();
|
||||
d->tabBar()->removeTab(TabWidget);
|
||||
CDockContainerWidget* DockContainer = dockContainer();
|
||||
if (NextOpenDockWidget)
|
||||
{
|
||||
setCurrentDockWidget(NextOpenDockWidget);
|
||||
}
|
||||
else if (d->ContentsLayout->isEmpty())
|
||||
else if (d->ContentsLayout->isEmpty() && DockContainer->dockAreaCount() > 1)
|
||||
{
|
||||
qDebug() << "Dock Area empty";
|
||||
dockContainer()->removeDockArea(this);
|
||||
ADS_PRINT("Dock Area empty");
|
||||
DockContainer->removeDockArea(this);
|
||||
this->deleteLater();
|
||||
}
|
||||
else
|
||||
@@ -432,16 +438,15 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
|
||||
hideAreaWithNoVisibleContent();
|
||||
}
|
||||
|
||||
d->updateCloseButtonState();
|
||||
d->updateTitleBarButtonStates();
|
||||
updateTitleBarVisibility();
|
||||
auto TopLevelDockWidget = dockContainer()->topLevelDockWidget();
|
||||
auto TopLevelDockWidget = DockContainer->topLevelDockWidget();
|
||||
if (TopLevelDockWidget)
|
||||
{
|
||||
TopLevelDockWidget->emitTopLevelChanged(true);
|
||||
}
|
||||
|
||||
#if (ADS_DEBUG_LEVEL > 0)
|
||||
CDockContainerWidget* DockContainer = dockContainer();
|
||||
DockContainer->dumpLayout();
|
||||
#endif
|
||||
}
|
||||
@@ -481,7 +486,7 @@ void CDockAreaWidget::hideAreaWithNoVisibleContent()
|
||||
//============================================================================
|
||||
void CDockAreaWidget::onTabCloseRequested(int Index)
|
||||
{
|
||||
qDebug() << "CDockAreaWidget::onTabCloseRequested " << Index;
|
||||
ADS_PRINT("CDockAreaWidget::onTabCloseRequested " << Index);
|
||||
dockWidget(Index)->toggleView(false);
|
||||
}
|
||||
|
||||
@@ -644,11 +649,11 @@ CDockWidget* CDockAreaWidget::dockWidget(int Index) const
|
||||
//============================================================================
|
||||
void CDockAreaWidget::reorderDockWidget(int fromIndex, int toIndex)
|
||||
{
|
||||
qDebug() << "CDockAreaWidget::reorderDockWidget";
|
||||
ADS_PRINT("CDockAreaWidget::reorderDockWidget");
|
||||
if (fromIndex >= d->ContentsLayout->count() || fromIndex < 0
|
||||
|| toIndex >= d->ContentsLayout->count() || toIndex < 0 || fromIndex == toIndex)
|
||||
{
|
||||
qDebug() << "Invalid index for tab movement" << fromIndex << toIndex;
|
||||
ADS_PRINT("Invalid index for tab movement" << fromIndex << toIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -703,8 +708,8 @@ void CDockAreaWidget::saveState(QXmlStreamWriter& s) const
|
||||
auto CurrentDockWidget = currentDockWidget();
|
||||
QString Name = CurrentDockWidget ? CurrentDockWidget->objectName() : "";
|
||||
s.writeAttribute("Current", Name);
|
||||
qDebug() << "CDockAreaWidget::saveState TabCount: " << d->ContentsLayout->count()
|
||||
<< " Current: " << Name;
|
||||
ADS_PRINT("CDockAreaWidget::saveState TabCount: " << d->ContentsLayout->count()
|
||||
<< " Current: " << Name);
|
||||
for (int i = 0; i < d->ContentsLayout->count(); ++i)
|
||||
{
|
||||
dockWidget(i)->saveState(s);
|
||||
@@ -765,9 +770,9 @@ void CDockAreaWidget::toggleView(bool Open)
|
||||
void CDockAreaWidget::setVisible(bool Visible)
|
||||
{
|
||||
Super::setVisible(Visible);
|
||||
if (d->UpdateCloseButton)
|
||||
if (d->UpdateTitleBarButtons)
|
||||
{
|
||||
d->updateCloseButtonState();
|
||||
d->updateTitleBarButtonStates();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,12 +185,12 @@ public:
|
||||
QList<CDockWidget*> dockWidgets() const;
|
||||
|
||||
/**
|
||||
* Returns the number of dock widgets in this area
|
||||
* Returns the number of open dock widgets in this area
|
||||
*/
|
||||
int openDockWidgetsCount() const;
|
||||
|
||||
/**
|
||||
* Returns a list of dock widgets that are not closed
|
||||
* Returns a list of dock widgets that are not closed.
|
||||
*/
|
||||
QList<CDockWidget*> openedDockWidgets() const;
|
||||
|
||||
@@ -236,8 +236,10 @@ public:
|
||||
* This functions returns the dock widget features of all dock widget in
|
||||
* this area.
|
||||
* A bitwise and is used to combine the flags of all dock widgets. That
|
||||
* means, if only dock widget does not support a certain flag, the whole
|
||||
* dock are does not support the flag.
|
||||
* means, if only one single dock widget does not support a certain flag,
|
||||
* the whole dock are does not support the flag. I.e. if one single
|
||||
* dock widget in this area is not closabe, the whole dock are is not
|
||||
* closable.
|
||||
*/
|
||||
CDockWidget::DockWidgetFeatures features() const;
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ public:
|
||||
CDockSplitter* newSplitter(Qt::Orientation orientation, QWidget* parent = nullptr)
|
||||
{
|
||||
CDockSplitter* s = new CDockSplitter(orientation, parent);
|
||||
s->setOpaqueResize(DockManager->configFlags().testFlag(CDockManager::OpaqueSplitterResize));
|
||||
s->setOpaqueResize(CDockManager::configFlags().testFlag(CDockManager::OpaqueSplitterResize));
|
||||
s->setChildrenCollapsible(false);
|
||||
return s;
|
||||
}
|
||||
@@ -557,8 +557,8 @@ void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidge
|
||||
s.writeStartElement("Splitter");
|
||||
s.writeAttribute("Orientation", (Splitter->orientation() == Qt::Horizontal) ? "-" : "|");
|
||||
s.writeAttribute("Count", QString::number(Splitter->count()));
|
||||
qDebug() << "NodeSplitter orient: " << Splitter->orientation()
|
||||
<< " WidgetCont: " << Splitter->count();
|
||||
ADS_PRINT("NodeSplitter orient: " << Splitter->orientation()
|
||||
<< " WidgetCont: " << Splitter->count());
|
||||
for (int i = 0; i < Splitter->count(); ++i)
|
||||
{
|
||||
saveChildNodesState(s, Splitter->widget(i));
|
||||
@@ -608,8 +608,8 @@ bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
qDebug() << "Restore NodeSplitter Orientation: " << Orientation <<
|
||||
" WidgetCount: " << WidgetCount;
|
||||
ADS_PRINT("Restore NodeSplitter Orientation: " << Orientation <<
|
||||
" WidgetCount: " << WidgetCount);
|
||||
QSplitter* Splitter = nullptr;
|
||||
if (!Testing)
|
||||
{
|
||||
@@ -632,7 +632,7 @@ bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s,
|
||||
else if (s.name() == "Sizes")
|
||||
{
|
||||
QString sSizes = s.readElementText().trimmed();
|
||||
qDebug() << "Sizes: " << sSizes;
|
||||
ADS_PRINT("Sizes: " << sSizes);
|
||||
QTextStream TextStream(&sSizes);
|
||||
while (!TextStream.atEnd())
|
||||
{
|
||||
@@ -656,8 +656,8 @@ bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s,
|
||||
continue;
|
||||
}
|
||||
|
||||
qDebug() << "ChildNode isVisible " << ChildNode->isVisible()
|
||||
<< " isVisibleTo " << ChildNode->isVisibleTo(Splitter);
|
||||
ADS_PRINT("ChildNode isVisible " << ChildNode->isVisible()
|
||||
<< " isVisibleTo " << ChildNode->isVisibleTo(Splitter));
|
||||
Splitter->addWidget(ChildNode);
|
||||
Visible |= ChildNode->isVisibleTo(Splitter);
|
||||
}
|
||||
@@ -695,16 +695,17 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
|
||||
QWidget*& CreatedWidget, bool Testing)
|
||||
{
|
||||
bool Ok;
|
||||
#ifdef ADS_DEBUG_PRINT
|
||||
int Tabs = s.attributes().value("Tabs").toInt(&Ok);
|
||||
if (!Ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QString CurrentDockWidget = s.attributes().value("Current").toString();
|
||||
qDebug() << "Restore NodeDockArea Tabs: " << Tabs << " Current: "
|
||||
<< CurrentDockWidget;
|
||||
ADS_PRINT("Restore NodeDockArea Tabs: " << Tabs << " Current: "
|
||||
<< CurrentDockWidget);
|
||||
|
||||
CDockAreaWidget* DockArea = nullptr;
|
||||
if (!Testing)
|
||||
@@ -738,15 +739,15 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
|
||||
continue;
|
||||
}
|
||||
|
||||
qDebug() << "Dock Widget found - parent " << DockWidget->parent();
|
||||
ADS_PRINT("Dock Widget found - parent " << DockWidget->parent());
|
||||
// We hide the DockArea here to prevent the short display (the flashing)
|
||||
// of the dock areas during application startup
|
||||
DockArea->hide();
|
||||
DockArea->addDockWidget(DockWidget);
|
||||
DockWidget->setToggleViewActionChecked(!Closed);
|
||||
DockWidget->setClosedState(Closed);
|
||||
DockWidget->setProperty("closed", Closed);
|
||||
DockWidget->setProperty("dirty", false);
|
||||
DockWidget->setProperty(internal::ClosedProperty, Closed);
|
||||
DockWidget->setProperty(internal::DirtyProperty, false);
|
||||
}
|
||||
|
||||
if (Testing)
|
||||
@@ -780,17 +781,17 @@ bool DockContainerWidgetPrivate::restoreChildNodes(QXmlStreamReader& s,
|
||||
if (s.name() == "Splitter")
|
||||
{
|
||||
Result = restoreSplitter(s, CreatedWidget, Testing);
|
||||
qDebug() << "Splitter";
|
||||
ADS_PRINT("Splitter");
|
||||
}
|
||||
else if (s.name() == "Area")
|
||||
{
|
||||
Result = restoreDockArea(s, CreatedWidget, Testing);
|
||||
qDebug() << "DockAreaWidget";
|
||||
ADS_PRINT("DockAreaWidget");
|
||||
}
|
||||
else
|
||||
{
|
||||
s.skipCurrentElement();
|
||||
qDebug() << "Unknown element";
|
||||
ADS_PRINT("Unknown element");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -862,15 +863,17 @@ void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
|
||||
buf.fill(' ', level * 4);
|
||||
if (Splitter)
|
||||
{
|
||||
#ifdef ADS_DEBUG_PRINT
|
||||
qDebug("%sSplitter %s v: %s c: %s",
|
||||
(const char*)buf,
|
||||
(Splitter->orientation() == Qt::Vertical) ? "--" : "|",
|
||||
Splitter->isHidden() ? " " : "v",
|
||||
QString::number(Splitter->count()).toStdString().c_str());
|
||||
std::cout << (const char*)buf << "Splitter "
|
||||
<< ((Splitter->orientation() == Qt::Vertical) ? "--" : "|") << " "
|
||||
<< (Splitter->isHidden() ? " " : "v") << " "
|
||||
<< QString::number(Splitter->count()).toStdString() << std::endl;
|
||||
std::cout << (const char*)buf << "Splitter "
|
||||
<< ((Splitter->orientation() == Qt::Vertical) ? "--" : "|") << " "
|
||||
<< (Splitter->isHidden() ? " " : "v") << " "
|
||||
<< QString::number(Splitter->count()).toStdString() << std::endl;
|
||||
#endif
|
||||
for (int i = 0; i < Splitter->count(); ++i)
|
||||
{
|
||||
dumpRecursive(level + 1, Splitter->widget(i));
|
||||
@@ -883,6 +886,7 @@ void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#ifdef ADS_DEBUG_PRINT
|
||||
qDebug("%sDockArea", (const char*)buf);
|
||||
std::cout << (const char*)buf
|
||||
<< (DockArea->isHidden() ? " " : "v")
|
||||
@@ -896,7 +900,8 @@ void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
|
||||
std::cout << (DockWidget->isHidden() ? " " : "v");
|
||||
std::cout << (DockWidget->isClosed() ? "c" : " ") << " ";
|
||||
std::cout << DockWidget->windowTitle().toStdString() << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(level);
|
||||
@@ -912,6 +917,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetAr
|
||||
if (CenterDockWidgetArea == area)
|
||||
{
|
||||
TargetDockArea->addDockWidget(Dockwidget);
|
||||
TargetDockArea->updateTitleBarVisibility();
|
||||
return TargetDockArea;
|
||||
}
|
||||
|
||||
@@ -923,12 +929,12 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetAr
|
||||
int index = TargetAreaSplitter ->indexOf(TargetDockArea);
|
||||
if (TargetAreaSplitter->orientation() == InsertParam.orientation())
|
||||
{
|
||||
qDebug() << "TargetAreaSplitter->orientation() == InsertParam.orientation()";
|
||||
ADS_PRINT("TargetAreaSplitter->orientation() == InsertParam.orientation()");
|
||||
TargetAreaSplitter->insertWidget(index + InsertParam.insertOffset(), NewDockArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "TargetAreaSplitter->orientation() != InsertParam.orientation()";
|
||||
ADS_PRINT("TargetAreaSplitter->orientation() != InsertParam.orientation()");
|
||||
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
|
||||
NewSplitter->addWidget(TargetDockArea);
|
||||
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
|
||||
@@ -998,6 +1004,15 @@ CDockAreaWidget* CDockContainerWidget::addDockWidget(DockWidgetArea area, CDockW
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CDockContainerWidget::removeDockWidget(CDockWidget* Dockwidget)
|
||||
{
|
||||
CDockAreaWidget* Area = Dockwidget->dockAreaWidget();
|
||||
if (Area)
|
||||
{
|
||||
Area->removeDockWidget(Dockwidget);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
unsigned int CDockContainerWidget::zOrderIndex() const
|
||||
@@ -1047,7 +1062,7 @@ void CDockContainerWidget::addDockArea(CDockAreaWidget* DockAreaWidget,
|
||||
//============================================================================
|
||||
void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
||||
{
|
||||
qDebug() << "CDockContainerWidget::removeDockArea";
|
||||
ADS_PRINT("CDockContainerWidget::removeDockArea");
|
||||
area->disconnect(this);
|
||||
d->DockAreas.removeAll(area);
|
||||
CDockSplitter* Splitter = internal::findParent<CDockSplitter*>(area);
|
||||
@@ -1057,6 +1072,12 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
||||
area->setParent(nullptr);
|
||||
internal::hideEmptyParentSplitters(Splitter);
|
||||
|
||||
// Remove this area from cached areas
|
||||
const auto& cache = d->LastAddedAreaCache;
|
||||
if (auto p = std::find(cache, cache+sizeof(cache)/sizeof(cache[0]), area)) {
|
||||
d->LastAddedAreaCache[std::distance(cache, p)] = nullptr;
|
||||
}
|
||||
|
||||
// If splitter has more than 1 widgets, we are finished and can leave
|
||||
if (Splitter->count() > 1)
|
||||
{
|
||||
@@ -1067,7 +1088,7 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
||||
// avoid too many empty splitters
|
||||
if (Splitter == d->RootSplitter)
|
||||
{
|
||||
qDebug() << "Removed from RootSplitter";
|
||||
ADS_PRINT("Removed from RootSplitter");
|
||||
// If splitter is empty, we are finished
|
||||
if (!Splitter->count())
|
||||
{
|
||||
@@ -1089,11 +1110,11 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
||||
QLayoutItem* li = d->Layout->replaceWidget(Splitter, ChildSplitter);
|
||||
d->RootSplitter = ChildSplitter;
|
||||
delete li;
|
||||
qDebug() << "RootSplitter replaced by child splitter";
|
||||
ADS_PRINT("RootSplitter replaced by child splitter");
|
||||
}
|
||||
else if (Splitter->count() == 1)
|
||||
{
|
||||
qDebug() << "Replacing splitter with content";
|
||||
ADS_PRINT("Replacing splitter with content");
|
||||
QSplitter* ParentSplitter = internal::findParent<QSplitter*>(Splitter);
|
||||
auto Sizes = ParentSplitter->sizes();
|
||||
QWidget* widget = Splitter->widget(0);
|
||||
@@ -1172,7 +1193,7 @@ int CDockContainerWidget::visibleDockAreaCount() const
|
||||
void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWidget,
|
||||
const QPoint& TargetPos)
|
||||
{
|
||||
qDebug() << "CDockContainerWidget::dropFloatingWidget";
|
||||
ADS_PRINT("CDockContainerWidget::dropFloatingWidget");
|
||||
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
|
||||
auto dropArea = InvalidDockWidgetArea;
|
||||
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
|
||||
@@ -1192,7 +1213,7 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
|
||||
if (dropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
qDebug() << "Dock Area Drop Content: " << dropArea;
|
||||
ADS_PRINT("Dock Area Drop Content: " << dropArea);
|
||||
d->dropIntoSection(FloatingWidget, DockArea, dropArea);
|
||||
}
|
||||
}
|
||||
@@ -1201,7 +1222,7 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
if (InvalidDockWidgetArea == dropArea)
|
||||
{
|
||||
dropArea = ContainerDropArea;
|
||||
qDebug() << "Container Drop Content: " << dropArea;
|
||||
ADS_PRINT("Container Drop Content: " << dropArea);
|
||||
if (dropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
d->dropIntoContainer(FloatingWidget, dropArea);
|
||||
@@ -1243,8 +1264,8 @@ QList<CDockAreaWidget*> CDockContainerWidget::openedDockAreas() const
|
||||
//============================================================================
|
||||
void CDockContainerWidget::saveState(QXmlStreamWriter& s) const
|
||||
{
|
||||
qDebug() << "CDockContainerWidget::saveState isFloating "
|
||||
<< isFloating();
|
||||
ADS_PRINT("CDockContainerWidget::saveState isFloating "
|
||||
<< isFloating());
|
||||
|
||||
s.writeStartElement("Container");
|
||||
s.writeAttribute("Floating", QString::number(isFloating() ? 1 : 0));
|
||||
@@ -1267,18 +1288,19 @@ void CDockContainerWidget::saveState(QXmlStreamWriter& s) const
|
||||
bool CDockContainerWidget::restoreState(QXmlStreamReader& s, bool Testing)
|
||||
{
|
||||
bool IsFloating = s.attributes().value("Floating").toInt();
|
||||
qDebug() << "Restore CDockContainerWidget Floating" << IsFloating;
|
||||
ADS_PRINT("Restore CDockContainerWidget Floating" << IsFloating);
|
||||
|
||||
QWidget*NewRootSplitter {};
|
||||
if (!Testing)
|
||||
{
|
||||
d->VisibleDockAreaCount = -1;// invalidate the dock area count
|
||||
d->DockAreas.clear();
|
||||
std::fill(std::begin(d->LastAddedAreaCache),std::end(d->LastAddedAreaCache), nullptr);
|
||||
}
|
||||
|
||||
if (IsFloating)
|
||||
{
|
||||
qDebug() << "Restore floating widget";
|
||||
ADS_PRINT("Restore floating widget");
|
||||
if (!s.readNextStartElement() || s.name() != "Geometry")
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -50,7 +50,10 @@ struct FloatingDockContainerPrivate;
|
||||
|
||||
/**
|
||||
* Container that manages a number of dock areas with single dock widgets
|
||||
* or tabyfied dock widgets in each area
|
||||
* or tabyfied dock widgets in each area.
|
||||
* Each window that support docking has a DockContainerWidget. That means
|
||||
* the main application window and all floating windows are ore contain
|
||||
* an DockContainerWidget.
|
||||
*/
|
||||
class ADS_EXPORT CDockContainerWidget : public QFrame
|
||||
{
|
||||
@@ -166,6 +169,11 @@ public:
|
||||
CDockAreaWidget* addDockWidget(DockWidgetArea area, CDockWidget* Dockwidget,
|
||||
CDockAreaWidget* DockAreaWidget = nullptr);
|
||||
|
||||
/**
|
||||
* Removes dockwidget
|
||||
*/
|
||||
void removeDockWidget(CDockWidget* Dockwidget);
|
||||
|
||||
/**
|
||||
* Returns the current zOrderIndex
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <DockWidgetTab.h>
|
||||
#include "DockWidgetTab.h"
|
||||
#include "DockManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
namespace ads
|
||||
{
|
||||
static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultConfig;
|
||||
|
||||
/**
|
||||
* Private data class of CDockManager class (pimpl)
|
||||
*/
|
||||
@@ -72,7 +74,6 @@ struct DockManagerPrivate
|
||||
QMenu* ViewMenu;
|
||||
CDockManager::eViewMenuInsertionOrder MenuInsertionOrder = CDockManager::MenuAlphabeticallySorted;
|
||||
bool RestoringState = false;
|
||||
CDockManager::ConfigFlags ConfigFlags = CDockManager::DefaultConfig;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -101,7 +102,7 @@ struct DockManagerPrivate
|
||||
|
||||
void hideFloatingWidgets()
|
||||
{
|
||||
// Hide updates of floating widgets from use
|
||||
// Hide updates of floating widgets from user
|
||||
for (auto FloatingWidget : FloatingWidgets)
|
||||
{
|
||||
FloatingWidget->hide();
|
||||
@@ -145,7 +146,11 @@ DockManagerPrivate::DockManagerPrivate(CDockManager* _public) :
|
||||
void DockManagerPrivate::loadStylesheet()
|
||||
{
|
||||
QString Result;
|
||||
#ifdef Q_OS_LINUX
|
||||
QFile StyleSheetFile(":ads/stylesheets/default_linux.css");
|
||||
#else
|
||||
QFile StyleSheetFile(":ads/stylesheets/default.css");
|
||||
#endif
|
||||
StyleSheetFile.open(QIODevice::ReadOnly);
|
||||
QTextStream StyleSheetStream(&StyleSheetFile);
|
||||
Result = StyleSheetStream.readAll();
|
||||
@@ -170,7 +175,7 @@ bool DockManagerPrivate::restoreContainer(int Index, QXmlStreamReader& stream, b
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "d->Containers[i]->restoreState ";
|
||||
ADS_PRINT("d->Containers[i]->restoreState ");
|
||||
auto Container = Containers[Index];
|
||||
if (Container->isFloating())
|
||||
{
|
||||
@@ -207,7 +212,7 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi
|
||||
{
|
||||
return false;
|
||||
}
|
||||
qDebug() << s.attributes().value("Version");
|
||||
ADS_PRINT(s.attributes().value("Version"));
|
||||
bool ok;
|
||||
int v = s.attributes().value("Version").toInt(&ok);
|
||||
if (!ok || v != version)
|
||||
@@ -216,8 +221,10 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi
|
||||
}
|
||||
|
||||
bool Result = true;
|
||||
#ifdef ADS_DEBUG_PRINT
|
||||
int DockContainers = s.attributes().value("Containers").toInt();
|
||||
qDebug() << DockContainers;
|
||||
#endif
|
||||
ADS_PRINT(DockContainers);
|
||||
int DockContainerCount = 0;
|
||||
while (s.readNextStartElement())
|
||||
{
|
||||
@@ -257,13 +264,14 @@ void DockManagerPrivate::restoreDockWidgetsOpenState()
|
||||
// toggle view action the next time
|
||||
for (auto DockWidget : DockWidgetsMap)
|
||||
{
|
||||
if (DockWidget->property("dirty").toBool())
|
||||
if (DockWidget->property(internal::DirtyProperty).toBool())
|
||||
{
|
||||
DockWidget->flagAsUnassigned();
|
||||
emit DockWidget->viewToggled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
DockWidget->toggleViewInternal(!DockWidget->property("closed").toBool());
|
||||
DockWidget->toggleViewInternal(!DockWidget->property(internal::ClosedProperty).toBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -336,11 +344,12 @@ void DockManagerPrivate::emitTopLevelEvents()
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
|
||||
bool DockManagerPrivate::restoreState(const QByteArray& State, int version)
|
||||
{
|
||||
QByteArray state = State.startsWith("<?xml") ? State : qUncompress(State);
|
||||
if (!checkFormat(state, version))
|
||||
{
|
||||
qDebug() << "checkFormat: Error checking format!!!!!!!";
|
||||
ADS_PRINT("checkFormat: Error checking format!!!!!!!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -350,7 +359,7 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
|
||||
|
||||
if (!restoreStateFromXml(state, version))
|
||||
{
|
||||
qDebug() << "restoreState: Error restoring state!!!!!!!";
|
||||
ADS_PRINT("restoreState: Error restoring state!!!!!!!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -425,7 +434,7 @@ CDockManager::~CDockManager()
|
||||
void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget)
|
||||
{
|
||||
d->FloatingWidgets.append(FloatingWidget);
|
||||
qDebug() << "d->FloatingWidgets.count() " << d->FloatingWidgets.count();
|
||||
ADS_PRINT("d->FloatingWidgets.count() " << d->FloatingWidgets.count());
|
||||
}
|
||||
|
||||
|
||||
@@ -489,11 +498,12 @@ unsigned int CDockManager::zOrderIndex() const
|
||||
|
||||
|
||||
//============================================================================
|
||||
QByteArray CDockManager::saveState(eXmlMode XmlMode, int version) const
|
||||
QByteArray CDockManager::saveState(int version) const
|
||||
{
|
||||
QByteArray xmldata;
|
||||
QXmlStreamWriter s(&xmldata);
|
||||
s.setAutoFormatting(XmlAutoFormattingEnabled == XmlMode);
|
||||
auto ConfigFlags = CDockManager::configFlags();
|
||||
s.setAutoFormatting(ConfigFlags.testFlag(XmlAutoFormattingEnabled));
|
||||
s.writeStartDocument();
|
||||
s.writeStartElement("QtAdvancedDockingSystem");
|
||||
s.writeAttribute("Version", QString::number(version));
|
||||
@@ -506,7 +516,8 @@ QByteArray CDockManager::saveState(eXmlMode XmlMode, int version) const
|
||||
s.writeEndElement();
|
||||
s.writeEndDocument();
|
||||
|
||||
return xmldata;
|
||||
return ConfigFlags.testFlag(XmlCompressionEnabled)
|
||||
? qCompress(xmldata, 9) : xmldata;
|
||||
}
|
||||
|
||||
|
||||
@@ -565,9 +576,13 @@ CDockAreaWidget* CDockManager::addDockWidgetTab(DockWidgetArea area,
|
||||
{
|
||||
return addDockWidget(ads::CenterDockWidgetArea, Dockwidget, AreaWidget);
|
||||
}
|
||||
else if (!openedDockAreas().isEmpty())
|
||||
{
|
||||
return addDockWidget(area, Dockwidget, openedDockAreas().last());
|
||||
}
|
||||
else
|
||||
{
|
||||
return addDockWidget(area, Dockwidget, AreaWidget);
|
||||
return addDockWidget(area, Dockwidget, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,6 +601,12 @@ CDockWidget* CDockManager::findDockWidget(const QString& ObjectName) const
|
||||
return d->DockWidgetsMap.value(ObjectName, nullptr);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CDockManager::removeDockWidget(CDockWidget* Dockwidget)
|
||||
{
|
||||
d->DockWidgetsMap.remove(Dockwidget->objectName());
|
||||
CDockContainerWidget::removeDockWidget(Dockwidget);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
QMap<QString, CDockWidget*> CDockManager::dockWidgetsMap() const
|
||||
@@ -747,16 +768,23 @@ int CDockManager::startDragDistance()
|
||||
|
||||
|
||||
//===========================================================================
|
||||
CDockManager::ConfigFlags CDockManager::configFlags() const
|
||||
CDockManager::ConfigFlags CDockManager::configFlags()
|
||||
{
|
||||
return d->ConfigFlags;
|
||||
return StaticConfigFlags;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockManager::setConfigFlags(const ConfigFlags Flags)
|
||||
{
|
||||
d->ConfigFlags = Flags;
|
||||
StaticConfigFlags = Flags;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockManager::setConfigFlag(eConfigFlag Flag, bool On)
|
||||
{
|
||||
internal::setFlag(StaticConfigFlags, Flag, On);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,7 +51,16 @@ struct DockWidgetTabPrivate;
|
||||
struct DockAreaWidgetPrivate;
|
||||
|
||||
/**
|
||||
* The central dock manager that maintains the complete docking system
|
||||
* The central dock manager that maintains the complete docking system.
|
||||
* With the configuration flags you can globally control the functionality
|
||||
* of the docking system. The dock manager uses an internal stylesheet to
|
||||
* style its components like splitters, tabs and buttons. If you want to
|
||||
* disable this stylesheet because your application uses its own,
|
||||
* just call the function for settings the stylesheet with an empty
|
||||
* string.
|
||||
* \code
|
||||
* DockManager->setStyleSheet("");
|
||||
* \endcode
|
||||
**/
|
||||
class ADS_EXPORT CDockManager : public CDockContainerWidget
|
||||
{
|
||||
@@ -108,23 +117,22 @@ public:
|
||||
MenuAlphabeticallySorted
|
||||
};
|
||||
|
||||
enum eXmlMode
|
||||
{
|
||||
XmlAutoFormattingDisabled,
|
||||
XmlAutoFormattingEnabled
|
||||
};
|
||||
|
||||
/**
|
||||
* These global configuration flags configure some global dock manager
|
||||
* settings.
|
||||
*/
|
||||
enum eConfigFlag
|
||||
{
|
||||
ActiveTabHasCloseButton = 0x01, //!< If this flag is set, the active tab in a tab area has a close button
|
||||
DockAreaHasCloseButton = 0x02, //!< If the flag is set each dock area has a close button
|
||||
DockAreaCloseButtonClosesTab = 0x04,//!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete cock area
|
||||
OpaqueSplitterResize = 0x08, //!< See QSplitter::setOpaqueResize() documentation
|
||||
DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton | OpaqueSplitterResize, ///< the default configuration
|
||||
ActiveTabHasCloseButton = 0x0001, //!< If this flag is set, the active tab in a tab area has a close button
|
||||
DockAreaHasCloseButton = 0x0002, //!< If the flag is set each dock area has a close button
|
||||
DockAreaCloseButtonClosesTab = 0x0004,//!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete cock area
|
||||
OpaqueSplitterResize = 0x0008, //!< See QSplitter::setOpaqueResize() documentation
|
||||
XmlAutoFormattingEnabled = 0x0010,//!< If enabled, the XML writer automatically adds line-breaks and indentation to empty sections between elements (ignorable whitespace).
|
||||
XmlCompressionEnabled = 0x0020,//!< If enabled, the XML output will be compressed and is not human readable anymore
|
||||
TabCloseButtonIsToolButton = 0x0040,//! If enabled the tab close buttons will be QToolButtons instead of QPushButtons - disabled by default
|
||||
AllTabsHaveCloseButton = 0x0080, //!< if this flag is set, then all tabs that are closable show a close button
|
||||
RetainTabSizeWhenCloseButtonHidden = 0x0100, //!< if this flag is set, the space for the close button is reserved even if the close button is not visible
|
||||
DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton | OpaqueSplitterResize | XmlCompressionEnabled, ///< the default configuration
|
||||
};
|
||||
Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag)
|
||||
|
||||
@@ -133,7 +141,7 @@ public:
|
||||
* If the given parent is a QMainWindow, the dock manager sets itself as the
|
||||
* central widget.
|
||||
* Before you create any dock widgets, you should properly setup the
|
||||
* configuration flags via setConfigFlags()
|
||||
* configuration flags via setConfigFlags().
|
||||
*/
|
||||
CDockManager(QWidget* parent = 0);
|
||||
|
||||
@@ -145,13 +153,18 @@ public:
|
||||
/**
|
||||
* This function returns the global configuration flags
|
||||
*/
|
||||
ConfigFlags configFlags() const;
|
||||
static ConfigFlags configFlags();
|
||||
|
||||
/**
|
||||
* Sets the global configuration flags for the whole docking system.
|
||||
* Call this function before you create your first dock widget.
|
||||
*/
|
||||
void setConfigFlags(const ConfigFlags Flags);
|
||||
static void setConfigFlags(const ConfigFlags Flags);
|
||||
|
||||
/**
|
||||
* Set a certain config flag
|
||||
*/
|
||||
static void setConfigFlag(eConfigFlag Flag, bool On = true);
|
||||
|
||||
/**
|
||||
* Adds dockwidget into the given area.
|
||||
@@ -192,6 +205,11 @@ public:
|
||||
*/
|
||||
CDockWidget* findDockWidget(const QString& ObjectName) const;
|
||||
|
||||
/**
|
||||
* Remove the given Dock from the dock manager
|
||||
*/
|
||||
void removeDockWidget(CDockWidget* Dockwidget);
|
||||
|
||||
/**
|
||||
* This function returns a readable reference to the internal dock
|
||||
* widgets map so that it is possible to iterate over all dock widgets
|
||||
@@ -223,7 +241,7 @@ public:
|
||||
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have
|
||||
* a more compact XML output - i.e. for storage in ini files.
|
||||
*/
|
||||
QByteArray saveState(eXmlMode XmlMode = XmlAutoFormattingDisabled, int version = 0) const;
|
||||
QByteArray saveState(int version = 0) const;
|
||||
|
||||
/**
|
||||
* Restores the state of this dockmanagers dockwidgets.
|
||||
|
||||
@@ -132,6 +132,21 @@ struct DockOverlayCrossPrivate
|
||||
return Color;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
/**
|
||||
* Helper function that returns the drop indicator width depending on the
|
||||
* operating system
|
||||
*/
|
||||
qreal dropIndicatiorWidth(QLabel* l) const
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
Q_UNUSED(l)
|
||||
return 40;
|
||||
#else
|
||||
return static_cast<qreal>(l->fontMetrics().height()) * 3.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
QWidget* createDropIndicatorWidget(DockWidgetArea DockWidgetArea,
|
||||
@@ -140,7 +155,7 @@ struct DockOverlayCrossPrivate
|
||||
QLabel* l = new QLabel();
|
||||
l->setObjectName("DockWidgetAreaLabel");
|
||||
|
||||
const qreal metric = static_cast<qreal>(l->fontMetrics().height()) * 3.f;
|
||||
const qreal metric = dropIndicatiorWidth(l);
|
||||
const QSizeF size(metric, metric);
|
||||
|
||||
l->setPixmap(createHighDpiDropIndicatorPixmap(size, DockWidgetArea, Mode));
|
||||
@@ -154,7 +169,7 @@ struct DockOverlayCrossPrivate
|
||||
void updateDropIndicatorIcon(QWidget* DropIndicatorWidget)
|
||||
{
|
||||
QLabel* l = qobject_cast<QLabel*>(DropIndicatorWidget);
|
||||
const qreal metric = static_cast<qreal>(l->fontMetrics().height()) * 3.f;
|
||||
const qreal metric = dropIndicatiorWidth(l);
|
||||
const QSizeF size(metric, metric);
|
||||
|
||||
int Area = l->property("dockWidgetArea").toInt();
|
||||
|
||||
@@ -245,9 +245,6 @@ public:
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent* e) override;
|
||||
void setAreaWidgets(const QHash<DockWidgetArea, QWidget*>& widgets);
|
||||
|
||||
private:
|
||||
|
||||
}; // CDockOverlayCross
|
||||
|
||||
} // namespace ads
|
||||
|
||||
@@ -68,7 +68,7 @@ CDockSplitter::CDockSplitter(Qt::Orientation orientation, QWidget *parent)
|
||||
//============================================================================
|
||||
CDockSplitter::~CDockSplitter()
|
||||
{
|
||||
qDebug() << "~CDockSplitter";
|
||||
ADS_PRINT("~CDockSplitter");
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ namespace ads
|
||||
struct DockSplitterPrivate;
|
||||
|
||||
/**
|
||||
* Splitter used internally instead of QSplitter
|
||||
* Splitter used internally instead of QSplitter with some additional
|
||||
* fuctionality.
|
||||
*/
|
||||
class ADS_EXPORT CDockSplitter : public QSplitter
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <DockWidgetTab.h>
|
||||
#include "DockWidgetTab.h"
|
||||
#include "DockWidget.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
@@ -214,7 +214,7 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
|
||||
setObjectName(title);
|
||||
|
||||
d->TabWidget = new CDockWidgetTab(this);
|
||||
d->ToggleViewAction = new QAction(title, nullptr);
|
||||
d->ToggleViewAction = new QAction(title, this);
|
||||
d->ToggleViewAction->setCheckable(true);
|
||||
connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this,
|
||||
SLOT(toggleView(bool)));
|
||||
@@ -224,7 +224,7 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
|
||||
//============================================================================
|
||||
CDockWidget::~CDockWidget()
|
||||
{
|
||||
qDebug() << "~CDockWidget()";
|
||||
ADS_PRINT("~CDockWidget()");
|
||||
delete d;
|
||||
}
|
||||
|
||||
@@ -243,21 +243,35 @@ void CDockWidget::setToggleViewActionChecked(bool Checked)
|
||||
void CDockWidget::setWidget(QWidget* widget, eInsertMode InsertMode)
|
||||
{
|
||||
QScrollArea* ScrollAreaWidget = qobject_cast<QScrollArea*>(widget);
|
||||
if (ScrollAreaWidget || ForceNoScrollArea != InsertMode)
|
||||
if (ScrollAreaWidget || ForceNoScrollArea == InsertMode)
|
||||
{
|
||||
d->Layout->addWidget(widget);
|
||||
if (ScrollAreaWidget && ScrollAreaWidget->viewport())
|
||||
{
|
||||
ScrollAreaWidget->viewport()->setProperty("dockWidgetContent", true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d->setupScrollArea();
|
||||
d->ScrollArea->setWidget(widget);
|
||||
}
|
||||
else
|
||||
{
|
||||
d->Layout->addWidget(widget);
|
||||
}
|
||||
|
||||
d->Widget = widget;
|
||||
d->Widget->setProperty("dockWidgetContent", true);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
QWidget* CDockWidget::takeWidget()
|
||||
{
|
||||
d->ScrollArea->takeWidget();
|
||||
d->Layout->removeWidget(d->Widget);
|
||||
d->Widget->setParent(nullptr);
|
||||
return d->Widget;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
QWidget* CDockWidget::widget() const
|
||||
{
|
||||
@@ -275,25 +289,21 @@ CDockWidgetTab* CDockWidget::tabWidget() const
|
||||
//============================================================================
|
||||
void CDockWidget::setFeatures(DockWidgetFeatures features)
|
||||
{
|
||||
if (d->Features == features)
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->Features = features;
|
||||
d->TabWidget->onDockWidgetFeaturesChanged();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockWidget::setFeature(DockWidgetFeature flag, bool on)
|
||||
{
|
||||
#if QT_VERSION >= 0x050700
|
||||
d->Features.setFlag(flag, on);
|
||||
#else
|
||||
if(on)
|
||||
{
|
||||
d->Features |= flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
d->Features &= ~flag;
|
||||
}
|
||||
#endif
|
||||
auto Features = features();
|
||||
internal::setFlag(Features, flag, on);
|
||||
setFeatures(Features);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
enum DockWidgetFeature
|
||||
{
|
||||
DockWidgetClosable = 0x01,
|
||||
DockWidgetMovable = 0x02,
|
||||
DockWidgetMovable = 0x02,///< this feature is not properly implemented yet and is ignored
|
||||
DockWidgetFloatable = 0x04,
|
||||
AllDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable,
|
||||
NoDockWidgetFeatures = 0x00
|
||||
@@ -238,6 +238,11 @@ public:
|
||||
*/
|
||||
void setWidget(QWidget* widget, eInsertMode InsertMode = AutoScrollArea);
|
||||
|
||||
/**
|
||||
* Remove the widget from the dock and give ownership back to the caller
|
||||
*/
|
||||
QWidget* takeWidget();
|
||||
|
||||
/**
|
||||
* Returns the widget for the dock widget. This function returns zero if
|
||||
* the widget has not been set.
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <ElidingLabel.h>
|
||||
#include "ElidingLabel.h"
|
||||
#include "DockWidgetTab.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
@@ -55,7 +55,6 @@ namespace ads
|
||||
{
|
||||
|
||||
using tTabLabel = CElidingLabel;
|
||||
using tCloseButton = QPushButton;
|
||||
|
||||
/**
|
||||
* Private data class of CDockWidgetTab class (pimpl)
|
||||
@@ -72,7 +71,7 @@ struct DockWidgetTabPrivate
|
||||
eDragState DragState = DraggingInactive;
|
||||
CFloatingDockContainer* FloatingWidget = nullptr;
|
||||
QIcon Icon;
|
||||
tCloseButton* CloseButton = nullptr;
|
||||
QAbstractButton* CloseButton = nullptr;
|
||||
QSpacerItem* IconTextSpacer;
|
||||
|
||||
/**
|
||||
@@ -120,7 +119,24 @@ struct DockWidgetTabPrivate
|
||||
*/
|
||||
bool testConfigFlag(CDockManager::eConfigFlag Flag) const
|
||||
{
|
||||
return DockArea->dockManager()->configFlags().testFlag(Flag);
|
||||
return CDockManager::configFlags().testFlag(Flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the close button as QPushButton or as QToolButton
|
||||
*/
|
||||
QAbstractButton* createCloseButton() const
|
||||
{
|
||||
if (testConfigFlag(CDockManager::TabCloseButtonIsToolButton))
|
||||
{
|
||||
auto Button = new QToolButton();
|
||||
Button->setAutoRaise(true);
|
||||
return Button;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new QPushButton();
|
||||
}
|
||||
}
|
||||
};
|
||||
// struct DockWidgetTabPrivate
|
||||
@@ -143,19 +159,19 @@ void DockWidgetTabPrivate::createLayout()
|
||||
TitleLabel->setObjectName("dockWidgetTabLabel");
|
||||
TitleLabel->setAlignment(Qt::AlignCenter);
|
||||
|
||||
CloseButton = new tCloseButton();
|
||||
CloseButton = createCloseButton();
|
||||
CloseButton->setObjectName("tabCloseButton");
|
||||
// The standard icons do does not look good on high DPI screens
|
||||
QIcon CloseIcon = _this->style()->standardIcon(QStyle::SP_TitleBarCloseButton);
|
||||
QIcon CloseIcon;
|
||||
QPixmap normalPixmap = _this->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, CloseButton);
|
||||
QPixmap disabledPixmap = internal::createTransparentPixmap(normalPixmap, 0.25);
|
||||
CloseIcon.addPixmap(disabledPixmap, QIcon::Disabled);
|
||||
CloseIcon.addPixmap(normalPixmap, QIcon::Normal);
|
||||
CloseIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
|
||||
CloseButton->setIcon(CloseIcon);
|
||||
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
CloseButton->setVisible(false);
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
_this->onDockWidgetFeaturesChanged();
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
CloseButton->setToolTip(QObject::tr("Close Tab"));
|
||||
#endif
|
||||
#endif
|
||||
_this->connect(CloseButton, SIGNAL(clicked()), SIGNAL(closeRequested()));
|
||||
|
||||
QFontMetrics fm(TitleLabel->font());
|
||||
@@ -192,9 +208,9 @@ void DockWidgetTabPrivate::moveTab(QMouseEvent* ev)
|
||||
bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
|
||||
{
|
||||
auto dockContainer = DockWidget->dockContainer();
|
||||
qDebug() << "isFloating " << dockContainer->isFloating();
|
||||
qDebug() << "areaCount " << dockContainer->dockAreaCount();
|
||||
qDebug() << "widgetCount " << DockWidget->dockAreaWidget()->dockWidgetsCount();
|
||||
ADS_PRINT("isFloating " << dockContainer->isFloating());
|
||||
ADS_PRINT("areaCount " << dockContainer->dockAreaCount());
|
||||
ADS_PRINT("widgetCount " << DockWidget->dockAreaWidget()->dockWidgetsCount());
|
||||
// if this is the last dock widget inside of this floating widget,
|
||||
// then it does not make any sense, to make it floating because
|
||||
// it is already floating
|
||||
@@ -205,7 +221,7 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "startFloating";
|
||||
ADS_PRINT("startFloating");
|
||||
DragState = DraggingState;
|
||||
QSize Size = DockArea->size();
|
||||
CFloatingDockContainer* FloatingWidget = nullptr;
|
||||
@@ -223,7 +239,7 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
|
||||
|
||||
if (DraggingFloatingWidget == DraggingState)
|
||||
{
|
||||
FloatingWidget->startDragging(DragStartMousePosition, Size);
|
||||
FloatingWidget->startDragging(DragStartMousePosition, Size, _this);
|
||||
auto Overlay = DockWidget->dockManager()->containerOverlay();
|
||||
Overlay->setAllowedAreas(OuterDockAreas);
|
||||
this->FloatingWidget = FloatingWidget;
|
||||
@@ -250,7 +266,7 @@ CDockWidgetTab::CDockWidgetTab(CDockWidget* DockWidget, QWidget *parent) :
|
||||
//============================================================================
|
||||
CDockWidgetTab::~CDockWidgetTab()
|
||||
{
|
||||
qDebug() << "~CDockWidgetTab()";
|
||||
ADS_PRINT("~CDockWidgetTab()");
|
||||
delete d;
|
||||
}
|
||||
|
||||
@@ -327,7 +343,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
|
||||
}
|
||||
|
||||
// Floating is only allowed for widgets that are movable
|
||||
if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetMovable))
|
||||
if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
{
|
||||
d->startFloating();
|
||||
}
|
||||
@@ -351,9 +367,10 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
|
||||
|
||||
d->DragStartMousePosition = ev->pos();
|
||||
QMenu Menu(this);
|
||||
Menu.addAction(tr("Detach"), this, SLOT(onDetachActionTriggered()));
|
||||
auto Action = Menu.addAction(tr("Detach"), this, SLOT(onDetachActionTriggered()));
|
||||
Action->setEnabled(d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable));
|
||||
Menu.addSeparator();
|
||||
auto Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested()));
|
||||
Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested()));
|
||||
Action->setEnabled(isClosable());
|
||||
Menu.addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
|
||||
Menu.exec(mapToGlobal(ev->pos()));
|
||||
@@ -371,8 +388,10 @@ bool CDockWidgetTab::isActiveTab() const
|
||||
void CDockWidgetTab::setActiveTab(bool active)
|
||||
{
|
||||
bool DockWidgetClosable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetClosable);
|
||||
bool TabHasCloseButton = d->testConfigFlag(CDockManager::ActiveTabHasCloseButton);
|
||||
d->CloseButton->setVisible(active && DockWidgetClosable && TabHasCloseButton);
|
||||
bool ActiveTabHasCloseButton = d->testConfigFlag(CDockManager::ActiveTabHasCloseButton);
|
||||
bool AllTabsHaveCloseButton = d->testConfigFlag(CDockManager::AllTabsHaveCloseButton);
|
||||
bool TabHasCloseButton = (ActiveTabHasCloseButton && active) | AllTabsHaveCloseButton;
|
||||
d->CloseButton->setVisible(DockWidgetClosable && TabHasCloseButton);
|
||||
if (d->IsActiveTab == active)
|
||||
{
|
||||
return;
|
||||
@@ -442,7 +461,7 @@ void CDockWidgetTab::setIcon(const QIcon& Icon)
|
||||
d->Icon = Icon;
|
||||
if (d->IconLabel)
|
||||
{
|
||||
d->IconLabel->setPixmap(Icon.pixmap(this->windowHandle(), QSize(16, 16)));
|
||||
d->IconLabel->setPixmap(Icon.pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this)));
|
||||
d->IconLabel->setVisible(true);
|
||||
}
|
||||
}
|
||||
@@ -468,7 +487,8 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
// If this is the last dock area in a dock container it does not make
|
||||
// sense to move it to a new floating widget and leave this one
|
||||
// empty
|
||||
if (!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
|
||||
if ((!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
|
||||
&& d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
{
|
||||
d->DragStartMousePosition = event->pos();
|
||||
d->startFloating(DraggingInactive);
|
||||
@@ -504,13 +524,15 @@ bool CDockWidgetTab::isClosable() const
|
||||
//===========================================================================
|
||||
void CDockWidgetTab::onDetachActionTriggered()
|
||||
{
|
||||
if (!d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->DragStartMousePosition = mapFromGlobal(QCursor::pos());
|
||||
d->startFloating(DraggingInactive);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CDockWidgetTab::event(QEvent *e)
|
||||
{
|
||||
@@ -525,6 +547,17 @@ bool CDockWidgetTab::event(QEvent *e)
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockWidgetTab::onDockWidgetFeaturesChanged()
|
||||
{
|
||||
auto Features = d->DockWidget->features();
|
||||
auto SizePolicy = d->CloseButton->sizePolicy();
|
||||
SizePolicy.setRetainSizeWhenHidden(Features.testFlag(CDockWidget::DockWidgetClosable)
|
||||
&& d->testConfigFlag(CDockManager::RetainTabSizeWhenCloseButtonHidden));
|
||||
d->CloseButton->setSizePolicy(SizePolicy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace ads
|
||||
|
||||
@@ -53,6 +53,8 @@ class ADS_EXPORT CDockWidgetTab : public QFrame
|
||||
private:
|
||||
DockWidgetTabPrivate* d; ///< private data (pimpl)
|
||||
friend struct DockWidgetTabPrivate;
|
||||
friend class CDockWidget;
|
||||
void onDockWidgetFeaturesChanged();
|
||||
|
||||
private slots:
|
||||
void onDetachActionTriggered();
|
||||
@@ -125,7 +127,6 @@ public:
|
||||
*/
|
||||
QString text() const;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the tab text
|
||||
*/
|
||||
@@ -136,16 +137,14 @@ public:
|
||||
*/
|
||||
bool isClosable() const;
|
||||
|
||||
|
||||
/**
|
||||
* Track event ToolTipChange and set child ToolTip
|
||||
*/
|
||||
virtual bool event(QEvent *e) override;
|
||||
|
||||
|
||||
public slots:
|
||||
|
||||
virtual void setVisible(bool visible) override;
|
||||
|
||||
virtual void setVisible(bool visible) override;
|
||||
|
||||
signals:
|
||||
void activeTabChanged();
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <ElidingLabel.h>
|
||||
#include "ElidingLabel.h"
|
||||
#include <QMouseEvent>
|
||||
|
||||
|
||||
@@ -157,7 +157,11 @@ QSize CElidingLabel::minimumSizeHint() const
|
||||
return QLabel::minimumSizeHint();
|
||||
}
|
||||
const QFontMetrics &fm = fontMetrics();
|
||||
QSize size(fm.width(d->Text.left(2) + "…"), fm.height());
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
||||
QSize size(fm.horizontalAdvance(d->Text.left(2) + "…"), fm.height());
|
||||
#else
|
||||
QSize size(fm.width(d->Text.left(2) + "…"), fm.height());
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -170,7 +174,11 @@ QSize CElidingLabel::sizeHint() const
|
||||
return QLabel::sizeHint();
|
||||
}
|
||||
const QFontMetrics& fm = fontMetrics();
|
||||
QSize size(fm.width(d->Text), QLabel::sizeHint().height());
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
||||
QSize size(fm.horizontalAdvance(d->Text), QLabel::sizeHint().height());
|
||||
#else
|
||||
QSize size(fm.width(d->Text), QLabel::sizeHint().height());
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
//============================================================================
|
||||
#include <QLabel>
|
||||
|
||||
#include "ads_globals.h"
|
||||
|
||||
namespace ads
|
||||
{
|
||||
struct ElidingLabelPrivate;
|
||||
@@ -41,7 +43,7 @@ struct ElidingLabelPrivate;
|
||||
* and reading the text via a pointer to the base class QLabel does not work
|
||||
* properly
|
||||
*/
|
||||
class CElidingLabel : public QLabel
|
||||
class ADS_EXPORT CElidingLabel : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*******************************************************************************
|
||||
** Qt Advanced Docking System
|
||||
** Copyright (C) 2017 Uwe Kindler
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU Lesser General Public
|
||||
** License as published by the Free Software Foundation; either
|
||||
** version 2.1 of the License, or (at your option) any later version.
|
||||
**
|
||||
** This library is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
** Lesser General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU Lesser General Public
|
||||
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
** Qt Advanced Docking System
|
||||
** Copyright (C) 2017 Uwe Kindler
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU Lesser General Public
|
||||
** License as published by the Free Software Foundation; either
|
||||
** version 2.1 of the License, or (at your option) any later version.
|
||||
**
|
||||
** This library is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
** Lesser General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU Lesser General Public
|
||||
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
//============================================================================
|
||||
/// \file FloatingDockContainer.cpp
|
||||
@@ -24,7 +23,6 @@
|
||||
/// \brief Implementation of CFloatingDockContainer class
|
||||
//============================================================================
|
||||
|
||||
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
@@ -45,7 +43,10 @@
|
||||
#include "DockWidget.h"
|
||||
#include "DockOverlay.h"
|
||||
|
||||
#include <iostream>
|
||||
#ifdef Q_OS_LINUX
|
||||
#include "linux/FloatingWidgetTitleBar.h"
|
||||
#include <xcb/xcb.h>
|
||||
#endif
|
||||
|
||||
namespace ads
|
||||
{
|
||||
@@ -55,22 +56,26 @@ static unsigned int zOrderCounter = 0;
|
||||
*/
|
||||
struct FloatingDockContainerPrivate
|
||||
{
|
||||
CFloatingDockContainer* _this;
|
||||
CDockContainerWidget* DockContainer;
|
||||
CFloatingDockContainer *_this;
|
||||
CDockContainerWidget *DockContainer;
|
||||
unsigned int zOrderIndex = ++zOrderCounter;
|
||||
QPointer<CDockManager> DockManager;
|
||||
eDragState DraggingState = DraggingInactive;
|
||||
QPoint DragStartMousePosition;
|
||||
CDockContainerWidget* DropContainer = nullptr;
|
||||
CDockAreaWidget* SingleDockArea = nullptr;
|
||||
CDockContainerWidget *DropContainer = nullptr;
|
||||
CDockAreaWidget *SingleDockArea = nullptr;
|
||||
#ifdef Q_OS_LINUX
|
||||
QWidget* MouseEventHandler = nullptr;
|
||||
CFloatingWidgetTitleBar* TitleBar = nullptr;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
*/
|
||||
FloatingDockContainerPrivate(CFloatingDockContainer* _public);
|
||||
FloatingDockContainerPrivate(CFloatingDockContainer *_public);
|
||||
|
||||
void titleMouseReleaseEvent();
|
||||
void updateDropOverlays(const QPoint& GlobalPos);
|
||||
void updateDropOverlays(const QPoint &GlobalPos);
|
||||
|
||||
/**
|
||||
* Tests is a certain state is active
|
||||
@@ -84,20 +89,26 @@ struct FloatingDockContainerPrivate
|
||||
{
|
||||
DraggingState = StateId;
|
||||
}
|
||||
|
||||
void setWindowTitle(const QString &Text)
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
TitleBar->setTitle(Text);
|
||||
#else
|
||||
_this->setWindowTitle(Text);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
// struct FloatingDockContainerPrivate
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
FloatingDockContainerPrivate::FloatingDockContainerPrivate(CFloatingDockContainer* _public) :
|
||||
FloatingDockContainerPrivate::FloatingDockContainerPrivate(
|
||||
CFloatingDockContainer *_public) :
|
||||
_this(_public)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
{
|
||||
@@ -107,25 +118,31 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
return;
|
||||
}
|
||||
|
||||
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea
|
||||
|| DockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea)
|
||||
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor()
|
||||
!= InvalidDockWidgetArea
|
||||
|| DockManager->containerOverlay()->dropAreaUnderCursor()
|
||||
!= InvalidDockWidgetArea)
|
||||
{
|
||||
// Resize the floating widget to the size of the highlighted drop area
|
||||
// rectangle
|
||||
CDockOverlay* Overlay = DockManager->containerOverlay();
|
||||
CDockOverlay *Overlay = DockManager->containerOverlay();
|
||||
if (!Overlay->dropOverlayRect().isValid())
|
||||
{
|
||||
Overlay = DockManager->dockAreaOverlay();
|
||||
}
|
||||
|
||||
QRect Rect = Overlay->dropOverlayRect();
|
||||
int FrameWidth = (_this->frameSize().width() - _this->rect().width()) / 2;
|
||||
int TitleBarHeight = _this->frameSize().height() - _this->rect().height() - FrameWidth;
|
||||
int FrameWidth = (_this->frameSize().width() - _this->rect().width())
|
||||
/ 2;
|
||||
int TitleBarHeight = _this->frameSize().height()
|
||||
- _this->rect().height() - FrameWidth;
|
||||
if (Rect.isValid())
|
||||
{
|
||||
QPoint TopLeft = Overlay->mapToGlobal(Rect.topLeft());
|
||||
TopLeft.ry() += TitleBarHeight;
|
||||
_this->setGeometry(QRect(TopLeft, QSize(Rect.width(), Rect.height() - TitleBarHeight)));
|
||||
_this->setGeometry(
|
||||
QRect(TopLeft,
|
||||
QSize(Rect.width(), Rect.height() - TitleBarHeight)));
|
||||
QApplication::processEvents();
|
||||
}
|
||||
DropContainer->dropFloatingWidget(_this, QCursor::pos());
|
||||
@@ -135,101 +152,113 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
DockManager->dockAreaOverlay()->hideOverlay();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
|
||||
void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
{
|
||||
if (!_this->isVisible() || !DockManager)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto Containers = DockManager->dockContainers();
|
||||
CDockContainerWidget* TopContainer = nullptr;
|
||||
for (auto ContainerWidget : Containers)
|
||||
{
|
||||
if (!ContainerWidget->isVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto Containers = DockManager->dockContainers();
|
||||
CDockContainerWidget *TopContainer = nullptr;
|
||||
for (auto ContainerWidget : Containers)
|
||||
{
|
||||
if (!ContainerWidget->isVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DockContainer == ContainerWidget)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (DockContainer == ContainerWidget)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QPoint MappedPos = ContainerWidget->mapFromGlobal(GlobalPos);
|
||||
if (ContainerWidget->rect().contains(MappedPos))
|
||||
{
|
||||
if (!TopContainer || ContainerWidget->isInFrontOf(TopContainer))
|
||||
{
|
||||
TopContainer = ContainerWidget;
|
||||
}
|
||||
}
|
||||
}
|
||||
QPoint MappedPos = ContainerWidget->mapFromGlobal(GlobalPos);
|
||||
if (ContainerWidget->rect().contains(MappedPos))
|
||||
{
|
||||
if (!TopContainer || ContainerWidget->isInFrontOf(TopContainer))
|
||||
{
|
||||
TopContainer = ContainerWidget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropContainer = TopContainer;
|
||||
auto ContainerOverlay = DockManager->containerOverlay();
|
||||
auto DockAreaOverlay = DockManager->dockAreaOverlay();
|
||||
DropContainer = TopContainer;
|
||||
auto ContainerOverlay = DockManager->containerOverlay();
|
||||
auto DockAreaOverlay = DockManager->dockAreaOverlay();
|
||||
|
||||
if (!TopContainer)
|
||||
{
|
||||
ContainerOverlay->hideOverlay();
|
||||
DockAreaOverlay->hideOverlay();
|
||||
return;
|
||||
}
|
||||
if (!TopContainer)
|
||||
{
|
||||
ContainerOverlay->hideOverlay();
|
||||
DockAreaOverlay->hideOverlay();
|
||||
return;
|
||||
}
|
||||
|
||||
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
|
||||
ContainerOverlay->setAllowedAreas(VisibleDockAreas > 1 ?
|
||||
OuterDockAreas : AllDockAreas);
|
||||
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
|
||||
ContainerOverlay->setAllowedAreas(
|
||||
VisibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
||||
DockWidgetArea ContainerArea = ContainerOverlay->showOverlay(TopContainer);
|
||||
ContainerOverlay->enableDropPreview(ContainerArea != InvalidDockWidgetArea);
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
if (DockArea && DockArea->isVisible() && VisibleDockAreas > 0)
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(true);
|
||||
DockAreaOverlay->setAllowedAreas((VisibleDockAreas == 1) ?
|
||||
NoDockWidgetArea : AllDockAreas);
|
||||
DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea);
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
if (DockArea && DockArea->isVisible() && VisibleDockAreas > 0)
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(true);
|
||||
DockAreaOverlay->setAllowedAreas(
|
||||
(VisibleDockAreas == 1) ? NoDockWidgetArea : AllDockAreas);
|
||||
DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea);
|
||||
|
||||
// A CenterDockWidgetArea for the dockAreaOverlay() indicates that
|
||||
// the mouse is in the title bar. If the ContainerArea is valid
|
||||
// then we ignore the dock area of the dockAreaOverlay() and disable
|
||||
// the drop preview
|
||||
if ((Area == CenterDockWidgetArea) && (ContainerArea != InvalidDockWidgetArea))
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(false);
|
||||
ContainerOverlay->enableDropPreview(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ContainerOverlay->enableDropPreview(InvalidDockWidgetArea == Area);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DockAreaOverlay->hideOverlay();
|
||||
}
|
||||
// A CenterDockWidgetArea for the dockAreaOverlay() indicates that
|
||||
// the mouse is in the title bar. If the ContainerArea is valid
|
||||
// then we ignore the dock area of the dockAreaOverlay() and disable
|
||||
// the drop preview
|
||||
if ((Area == CenterDockWidgetArea)
|
||||
&& (ContainerArea != InvalidDockWidgetArea))
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(false);
|
||||
ContainerOverlay->enableDropPreview(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ContainerOverlay->enableDropPreview(InvalidDockWidgetArea == Area);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DockAreaOverlay->hideOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CFloatingDockContainer::CFloatingDockContainer(CDockManager* DockManager) :
|
||||
QWidget(DockManager, Qt::Window),
|
||||
CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
|
||||
tFloatingWidgetBase(DockManager),
|
||||
d(new FloatingDockContainerPrivate(this))
|
||||
{
|
||||
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
|
||||
d->DockManager = DockManager;
|
||||
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
l->setSpacing(0);
|
||||
setLayout(l);
|
||||
d->DockContainer = new CDockContainerWidget(DockManager, this);
|
||||
connect(d->DockContainer, SIGNAL(dockAreasAdded()), this,
|
||||
SLOT(onDockAreasAddedOrRemoved()));
|
||||
connect(d->DockContainer, SIGNAL(dockAreasRemoved()), this,
|
||||
SLOT(onDockAreasAddedOrRemoved()));
|
||||
|
||||
d->DockContainer = new CDockContainerWidget(DockManager, this);
|
||||
connect(d->DockContainer, SIGNAL(dockAreasAdded()), this, SLOT(onDockAreasAddedOrRemoved()));
|
||||
connect(d->DockContainer, SIGNAL(dockAreasRemoved()), this, SLOT(onDockAreasAddedOrRemoved()));
|
||||
#ifdef Q_OS_LINUX
|
||||
d->TitleBar = new CFloatingWidgetTitleBar(this);
|
||||
setWindowFlags(windowFlags() | Qt::Tool);
|
||||
QDockWidget::setWidget(d->DockContainer);
|
||||
QDockWidget::setFloating(true);
|
||||
QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||
setTitleBarWidget(d->TitleBar);
|
||||
connect(d->TitleBar, SIGNAL(closeRequested()), SLOT(close()));
|
||||
#else
|
||||
setWindowFlags(
|
||||
Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
|
||||
QBoxLayout *l = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
l->setSpacing(0);
|
||||
setLayout(l);
|
||||
l->addWidget(d->DockContainer);
|
||||
#endif
|
||||
|
||||
DockManager->registerFloatingWidget(this);
|
||||
|
||||
// We install an event filter to detect mouse release events because we
|
||||
@@ -238,26 +267,30 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager* DockManager) :
|
||||
qApp->installEventFilter(this);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CFloatingDockContainer::CFloatingDockContainer(CDockAreaWidget* DockArea) :
|
||||
CFloatingDockContainer::CFloatingDockContainer(CDockAreaWidget *DockArea) :
|
||||
CFloatingDockContainer(DockArea->dockManager())
|
||||
{
|
||||
d->DockContainer->addDockArea(DockArea);
|
||||
#ifdef Q_OS_LINUX
|
||||
d->TitleBar->enableCloseButton(isClosable());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CFloatingDockContainer::CFloatingDockContainer(CDockWidget* DockWidget) :
|
||||
CFloatingDockContainer::CFloatingDockContainer(CDockWidget *DockWidget) :
|
||||
CFloatingDockContainer(DockWidget->dockManager())
|
||||
{
|
||||
d->DockContainer->addDockWidget(CenterDockWidgetArea, DockWidget);
|
||||
#ifdef Q_OS_LINUX
|
||||
d->TitleBar->enableCloseButton(isClosable());
|
||||
#endif
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CFloatingDockContainer::~CFloatingDockContainer()
|
||||
{
|
||||
qDebug() << "~CFloatingDockContainer";
|
||||
ADS_PRINT("~CFloatingDockContainer");
|
||||
if (d->DockManager)
|
||||
{
|
||||
d->DockManager->removeFloatingWidget(this);
|
||||
@@ -265,27 +298,24 @@ CFloatingDockContainer::~CFloatingDockContainer()
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockContainerWidget* CFloatingDockContainer::dockContainer() const
|
||||
{
|
||||
return d->DockContainer;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::changeEvent(QEvent *event)
|
||||
{
|
||||
QWidget::changeEvent(event);
|
||||
if ((event->type() == QEvent::ActivationChange) && isActiveWindow())
|
||||
{
|
||||
qDebug() << "FloatingWidget::changeEvent QEvent::ActivationChange ";
|
||||
{
|
||||
ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange ");
|
||||
d->zOrderIndex = ++zOrderCounter;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
||||
{
|
||||
@@ -293,51 +323,62 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
||||
switch (d->DraggingState)
|
||||
{
|
||||
case DraggingMousePressed:
|
||||
d->setState(DraggingFloatingWidget);
|
||||
d->updateDropOverlays(QCursor::pos());
|
||||
break;
|
||||
d->setState(DraggingFloatingWidget);
|
||||
d->updateDropOverlays(QCursor::pos());
|
||||
break;
|
||||
|
||||
case DraggingFloatingWidget:
|
||||
d->updateDropOverlays(QCursor::pos());
|
||||
break;
|
||||
d->updateDropOverlays(QCursor::pos());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
qDebug() << "CFloatingDockContainer closeEvent";
|
||||
ADS_PRINT("CFloatingDockContainer closeEvent");
|
||||
d->setState(DraggingInactive);
|
||||
|
||||
if (isClosable())
|
||||
{
|
||||
// In Qt version after 5.9.2 there seems to be a bug that causes the
|
||||
// QWidget::event() function to not receive any NonClientArea mouse
|
||||
// events anymore after a close/show cycle. The bug is reported here:
|
||||
// https://bugreports.qt.io/browse/QTBUG-73295
|
||||
// The following code is a workaround for Qt versions > 5.9.2 that seems
|
||||
// to work
|
||||
#if (QT_VERSION > 0x050902)
|
||||
if (isClosable())
|
||||
{
|
||||
// In Qt version after 5.9.2 there seems to be a bug that causes the
|
||||
// QWidget::event() function to not receive any NonClientArea mouse
|
||||
// events anymore after a close/show cycle. The bug is reported here:
|
||||
// https://bugreports.qt.io/browse/QTBUG-73295
|
||||
// The following code is a workaround for Qt versions > 5.9.2 that seems
|
||||
// to work
|
||||
// Starting from Qt version 5.12.2 this seems to work again. But
|
||||
// now the QEvent::NonClientAreaMouseButtonPress function returns always
|
||||
// Qt::RightButton even if the left button was pressed
|
||||
#ifndef Q_OS_LINUX
|
||||
#if (QT_VERSION > QT_VERSION_CHECK(5, 9, 2) && QT_VERSION < QT_VERSION_CHECK(5, 12, 2))
|
||||
event->ignore();
|
||||
this->hide();
|
||||
#else
|
||||
Super::closeEvent(event);
|
||||
#endif
|
||||
#else // Q_OS_LINUX
|
||||
Super::closeEvent(event);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::hideEvent(QHideEvent *event)
|
||||
{
|
||||
Super::hideEvent(event);
|
||||
// Prevent toogleView() events during restore state
|
||||
if (d->DockManager->isRestoringState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto DockArea : d->DockContainer->openedDockAreas())
|
||||
{
|
||||
for (auto DockWidget : DockArea->openedDockWidgets())
|
||||
@@ -347,69 +388,78 @@ void CFloatingDockContainer::hideEvent(QHideEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::showEvent(QShowEvent *event)
|
||||
{
|
||||
Super::showEvent(event);
|
||||
/*for (auto DockArea : d->DockContainer->openedDockAreas())
|
||||
{
|
||||
for (auto DockWidget : DockArea->openedDockWidgets())
|
||||
{
|
||||
DockWidget->setToggleViewActionChecked(true);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CFloatingDockContainer::event(QEvent *e)
|
||||
{
|
||||
switch (d->DraggingState)
|
||||
{
|
||||
case DraggingInactive:
|
||||
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons() == Qt::LeftButton)
|
||||
{
|
||||
// Normally we would check here, if the left mouse button is pressed.
|
||||
// But from QT version 5.12.2 on the mouse events from
|
||||
// QEvent::NonClientAreaMouseButtonPress return the wrong mouse button
|
||||
// The event always returns Qt::RightButton even if the left button
|
||||
// is clicked.
|
||||
// It is really great to work around the whole NonClientMouseArea
|
||||
// bugs
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 2))
|
||||
if (e->type()
|
||||
== QEvent::NonClientAreaMouseButtonPress /*&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/)
|
||||
{
|
||||
qDebug() << "FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type();
|
||||
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
|
||||
d->setState(DraggingMousePressed);
|
||||
}
|
||||
break;
|
||||
#else
|
||||
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons().testFlag(Qt::LeftButton))
|
||||
{
|
||||
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
|
||||
d->setState(DraggingMousePressed);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case DraggingMousePressed:
|
||||
switch (e->type())
|
||||
{
|
||||
case QEvent::NonClientAreaMouseButtonDblClick:
|
||||
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonDblClick";
|
||||
d->setState(DraggingInactive);
|
||||
break;
|
||||
ADS_PRINT("FloatingWidget::event QEvent::NonClientAreaMouseButtonDblClick");
|
||||
d->setState(DraggingInactive);
|
||||
break;
|
||||
|
||||
case QEvent::Resize:
|
||||
// If the first event after the mouse press is a resize event, then
|
||||
// the user resizes the window instead of dragging it around.
|
||||
// But there is one exception. If the window is maximized,
|
||||
// then dragging the window via title bar will cause the widget to
|
||||
// leave the maximized state. This in turn will trigger a resize event.
|
||||
// To know, if the resize event was triggered by user via moving a
|
||||
// corner of the window frame or if it was caused by a windows state
|
||||
// change, we check, if we are not in maximized state.
|
||||
if (!isMaximized())
|
||||
{
|
||||
d->setState(DraggingInactive);
|
||||
}
|
||||
break;
|
||||
// If the first event after the mouse press is a resize event, then
|
||||
// the user resizes the window instead of dragging it around.
|
||||
// But there is one exception. If the window is maximized,
|
||||
// then dragging the window via title bar will cause the widget to
|
||||
// leave the maximized state. This in turn will trigger a resize event.
|
||||
// To know, if the resize event was triggered by user via moving a
|
||||
// corner of the window frame or if it was caused by a windows state
|
||||
// change, we check, if we are not in maximized state.
|
||||
if (!isMaximized())
|
||||
{
|
||||
d->setState(DraggingInactive);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case DraggingFloatingWidget:
|
||||
if (e->type() == QEvent::NonClientAreaMouseButtonRelease)
|
||||
{
|
||||
qDebug() << "FloatingWidget::event QEvent::NonClientAreaMouseButtonRelease";
|
||||
ADS_PRINT("FloatingWidget::event QEvent::NonClientAreaMouseButtonRelease");
|
||||
d->titleMouseReleaseEvent();
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -421,100 +471,120 @@ bool CFloatingDockContainer::event(QEvent *e)
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
Q_UNUSED(watched);
|
||||
if (event->type() == QEvent::MouseButtonRelease && d->isState(DraggingFloatingWidget))
|
||||
if (event->type() == QEvent::MouseButtonRelease
|
||||
&& d->isState(DraggingFloatingWidget))
|
||||
{
|
||||
qDebug() << "FloatingWidget::eventFilter QEvent::MouseButtonRelease";
|
||||
ADS_PRINT("FloatingWidget::eventFilter QEvent::MouseButtonRelease");
|
||||
finishDragging();
|
||||
d->titleMouseReleaseEvent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::startFloating(const QPoint& DragStartMousePos, const QSize& Size,
|
||||
eDragState DragState)
|
||||
void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
|
||||
const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)
|
||||
{
|
||||
#ifndef Q_OS_LINUX
|
||||
Q_UNUSED(MouseEventHandler)
|
||||
#endif
|
||||
resize(Size);
|
||||
d->setState(DragState);
|
||||
d->DragStartMousePosition = DragStartMousePos;
|
||||
#ifdef Q_OS_LINUX
|
||||
// I have not found a way on Linux to display the floating widget behind the
|
||||
// dock overlay. That means if the user drags this floating widget around,
|
||||
// it is always painted in front of the dock overlay and dock overlay cross.
|
||||
// and the user will not see the dock overlay. To work around this issue,
|
||||
// the window opacity is set to 0.6 to make the dock overlay visible
|
||||
// again. If someone has an idea, how to place the dragged floating widget
|
||||
// behind the dock overlay, then a pull request would be welcome.
|
||||
if (DraggingFloatingWidget == DragState)
|
||||
{
|
||||
setAttribute(Qt::WA_X11NetWmWindowTypeDock, true);
|
||||
setWindowOpacity(0.6);
|
||||
d->MouseEventHandler = MouseEventHandler;
|
||||
if (d->MouseEventHandler)
|
||||
{
|
||||
d->MouseEventHandler->grabMouse();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
moveFloating();
|
||||
show();
|
||||
show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::moveFloating()
|
||||
{
|
||||
int BorderSize = (frameSize().width() - size().width()) / 2;
|
||||
const QPoint moveToPos = QCursor::pos() - d->DragStartMousePosition - QPoint(BorderSize, 0);
|
||||
const QPoint moveToPos = QCursor::pos() - d->DragStartMousePosition
|
||||
- QPoint(BorderSize, 0);
|
||||
move(moveToPos);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CFloatingDockContainer::isClosable() const
|
||||
{
|
||||
return d->DockContainer->features().testFlag(CDockWidget::DockWidgetClosable);
|
||||
return d->DockContainer->features().testFlag(
|
||||
CDockWidget::DockWidgetClosable);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::onDockAreasAddedOrRemoved()
|
||||
{
|
||||
qDebug() << "CFloatingDockContainer::onDockAreasAddedOrRemoved()";
|
||||
ADS_PRINT("CFloatingDockContainer::onDockAreasAddedOrRemoved()");
|
||||
auto TopLevelDockArea = d->DockContainer->topLevelDockArea();
|
||||
if (TopLevelDockArea)
|
||||
{
|
||||
d->SingleDockArea = TopLevelDockArea;
|
||||
this->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
|
||||
d->setWindowTitle(
|
||||
d->SingleDockArea->currentDockWidget()->windowTitle());
|
||||
connect(d->SingleDockArea, SIGNAL(currentChanged(int)), this,
|
||||
SLOT(onDockAreaCurrentChanged(int)));
|
||||
SLOT(onDockAreaCurrentChanged(int)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d->SingleDockArea)
|
||||
{
|
||||
disconnect(d->SingleDockArea, SIGNAL(currentChanged(int)), this,
|
||||
SLOT(onDockAreaCurrentChanged(int)));
|
||||
SLOT(onDockAreaCurrentChanged(int)));
|
||||
d->SingleDockArea = nullptr;
|
||||
}
|
||||
this->setWindowTitle(qApp->applicationDisplayName());
|
||||
d->setWindowTitle(qApp->applicationDisplayName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::updateWindowTitle()
|
||||
{
|
||||
auto TopLevelDockArea = d->DockContainer->topLevelDockArea();
|
||||
if (TopLevelDockArea)
|
||||
{
|
||||
this->setWindowTitle(TopLevelDockArea->currentDockWidget()->windowTitle());
|
||||
d->setWindowTitle(TopLevelDockArea->currentDockWidget()->windowTitle());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setWindowTitle(qApp->applicationDisplayName());
|
||||
d->setWindowTitle(qApp->applicationDisplayName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::onDockAreaCurrentChanged(int Index)
|
||||
{
|
||||
Q_UNUSED(Index);
|
||||
this->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
|
||||
d->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CFloatingDockContainer::restoreState(QXmlStreamReader& Stream, bool Testing)
|
||||
bool CFloatingDockContainer::restoreState(QXmlStreamReader &Stream,
|
||||
bool Testing)
|
||||
{
|
||||
if (!d->DockContainer->restoreState(Stream, Testing))
|
||||
{
|
||||
@@ -525,27 +595,39 @@ bool CFloatingDockContainer::restoreState(QXmlStreamReader& Stream, bool Testing
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CFloatingDockContainer::hasTopLevelDockWidget() const
|
||||
{
|
||||
return d->DockContainer->hasTopLevelDockWidget();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockWidget* CFloatingDockContainer::topLevelDockWidget() const
|
||||
{
|
||||
return d->DockContainer->topLevelDockWidget();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
QList<CDockWidget*> CFloatingDockContainer::dockWidgets() const
|
||||
{
|
||||
return d->DockContainer->dockWidgets();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::finishDragging()
|
||||
{
|
||||
ADS_PRINT("CFloatingDockContainer::finishDragging");
|
||||
#ifdef Q_OS_LINUX
|
||||
setAttribute(Qt::WA_X11NetWmWindowTypeDock, false);
|
||||
setWindowOpacity(1);
|
||||
activateWindow();
|
||||
if (d->MouseEventHandler)
|
||||
{
|
||||
d->MouseEventHandler->releaseMouse();
|
||||
d->MouseEventHandler = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
||||
|
||||
@@ -29,10 +29,16 @@
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <QWidget>
|
||||
|
||||
#include "ads_globals.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <QDockWidget>
|
||||
#define tFloatingWidgetBase QDockWidget
|
||||
#else
|
||||
#include <QWidget>
|
||||
#define tFloatingWidgetBase QWidget
|
||||
#endif
|
||||
|
||||
class QXmlStreamReader;
|
||||
|
||||
namespace ads
|
||||
@@ -49,13 +55,15 @@ class CDockWidgetTab;
|
||||
struct DockWidgetTabPrivate;
|
||||
class CDockAreaTitleBar;
|
||||
struct DockAreaTitleBarPrivate;
|
||||
class CFloatingWidgetTitleBar;
|
||||
|
||||
/**
|
||||
* This implements a floating widget that is a dock container that accepts
|
||||
* docking of dock widgets like the main window and that can be docked into
|
||||
* another dock container
|
||||
* another dock container.
|
||||
* Every floating window of the docking system is a FloatingDockContainer.
|
||||
*/
|
||||
class ADS_EXPORT CFloatingDockContainer : public QWidget
|
||||
class ADS_EXPORT CFloatingDockContainer : public tFloatingWidgetBase
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
@@ -70,6 +78,7 @@ private:
|
||||
friend struct DockAreaTitleBarPrivate;
|
||||
friend class CDockWidget;
|
||||
friend class CDockAreaWidget;
|
||||
friend class CFloatingWidgetTitleBar;
|
||||
|
||||
private slots:
|
||||
void onDockAreasAddedOrRemoved();
|
||||
@@ -82,23 +91,30 @@ protected:
|
||||
* depending on the start position given in Pos parameter
|
||||
*/
|
||||
void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
|
||||
eDragState DragState);
|
||||
eDragState DragState, QWidget* MouseEventHandler);
|
||||
|
||||
/**
|
||||
* Call this function to start dragging the floating widget
|
||||
*/
|
||||
void startDragging(const QPoint& DragStartMousePos, const QSize& Size)
|
||||
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
|
||||
QWidget* MouseEventHandler)
|
||||
{
|
||||
startFloating(DragStartMousePos, Size, DraggingFloatingWidget);
|
||||
startFloating(DragStartMousePos, Size, DraggingFloatingWidget, MouseEventHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function if you explecitely want to signal that dragging has
|
||||
* finished
|
||||
*/
|
||||
void finishDragging();
|
||||
|
||||
/**
|
||||
* Call this function if you just want to initialize the position
|
||||
* and size of the floating widget
|
||||
*/
|
||||
void initFloatingGeometry(const QPoint& DragStartMousePos, const QSize& Size)
|
||||
{
|
||||
startFloating(DragStartMousePos, Size, DraggingInactive);
|
||||
startFloating(DragStartMousePos, Size, DraggingInactive, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
<file>stylesheets/default.css</file>
|
||||
<file>images/close-button.svg</file>
|
||||
<file>images/close-button-disabled.svg</file>
|
||||
<file>stylesheets/default_linux.css</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -45,6 +45,15 @@
|
||||
#define ADS_EXPORT
|
||||
#endif
|
||||
|
||||
// Define ADS_DEBUG_PRINT to enable a lot of debug output
|
||||
#ifdef ADS_DEBUG_PRINT
|
||||
#define ADS_PRINT(s) qDebug() << s
|
||||
#else
|
||||
#define ADS_PRINT(s)
|
||||
#endif
|
||||
|
||||
// Set ADS_DEBUG_LEVEL to enable additional debug output and to enable layout
|
||||
// dumps to qDebug and std::cout after layout changes
|
||||
#define ADS_DEBUG_LEVEL 0
|
||||
|
||||
class QSplitter;
|
||||
@@ -91,6 +100,8 @@ namespace internal
|
||||
{
|
||||
static const bool RestoreTesting = true;
|
||||
static const bool Restore = false;
|
||||
static const char* const ClosedProperty = "close";
|
||||
static const char* const DirtyProperty = "dirty";
|
||||
|
||||
/**
|
||||
* Replace the from widget in the given splitter with the To widget
|
||||
@@ -153,6 +164,27 @@ T findParent(const QWidget* w)
|
||||
*/
|
||||
QPixmap createTransparentPixmap(const QPixmap& Source, qreal Opacity);
|
||||
|
||||
|
||||
/**
|
||||
* Helper function for settings flags in a QFlags instance.
|
||||
*/
|
||||
template <class T>
|
||||
void setFlag(T& Flags, typename T::enum_type flag, bool on = true)
|
||||
{
|
||||
#if QT_VERSION >= 0x050700
|
||||
Flags.setFlag(flag, on);
|
||||
#else
|
||||
if(on)
|
||||
{
|
||||
Flags |= flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
Flags &= ~flag;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ads
|
||||
|
||||
|
||||
183
src/linux/FloatingWidgetTitleBar.cpp
Normal file
183
src/linux/FloatingWidgetTitleBar.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
/*******************************************************************************
|
||||
** Qt Advanced Docking System
|
||||
** Copyright (C) 2017 Uwe Kindler
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU Lesser General Public
|
||||
** License as published by the Free Software Foundation; either
|
||||
** version 2.1 of the License, or (at your option) any later version.
|
||||
**
|
||||
** This library is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
** Lesser General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU Lesser General Public
|
||||
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
//============================================================================
|
||||
/// \file FloatingWidgetTitleBar.cpp
|
||||
/// \author Uwe Kindler
|
||||
/// \date 13.05.2019
|
||||
/// \brief Implementation of CFloatingWidgetTitleBar class
|
||||
//============================================================================
|
||||
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include "FloatingWidgetTitleBar.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QToolButton>
|
||||
#include <QPixmap>
|
||||
#include <QStyle>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "ads_globals.h"
|
||||
#include "ElidingLabel.h"
|
||||
#include "FloatingDockContainer.h"
|
||||
|
||||
namespace ads
|
||||
{
|
||||
|
||||
using tTabLabel = CElidingLabel;
|
||||
using tCloseButton = QPushButton;
|
||||
|
||||
/**
|
||||
* @brief Private data class of public interface CFloatingWidgetTitleBar
|
||||
*/
|
||||
struct FloatingWidgetTitleBarPrivate
|
||||
{
|
||||
CFloatingWidgetTitleBar *_this; ///< public interface class
|
||||
QLabel *IconLabel = nullptr;
|
||||
tTabLabel *TitleLabel;
|
||||
tCloseButton *CloseButton = nullptr;
|
||||
CFloatingDockContainer *FloatingWidget = nullptr;
|
||||
eDragState DragState = DraggingInactive;
|
||||
|
||||
FloatingWidgetTitleBarPrivate(CFloatingWidgetTitleBar *_public) :
|
||||
_this(_public)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the complete layout including all controls
|
||||
*/
|
||||
void createLayout();
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
void FloatingWidgetTitleBarPrivate::createLayout()
|
||||
{
|
||||
TitleLabel = new tTabLabel();
|
||||
TitleLabel->setElideMode(Qt::ElideRight);
|
||||
TitleLabel->setText("DockWidget->windowTitle()");
|
||||
TitleLabel->setObjectName("floatingTitleLabel");
|
||||
TitleLabel->setAlignment(Qt::AlignLeft);
|
||||
|
||||
CloseButton = new tCloseButton();
|
||||
CloseButton->setObjectName("floatingTitleCloseButton");
|
||||
CloseButton->setFlat(true);
|
||||
|
||||
// The standard icons do does not look good on high DPI screens
|
||||
QIcon CloseIcon;
|
||||
QPixmap normalPixmap = _this->style()->standardPixmap(
|
||||
QStyle::SP_TitleBarCloseButton, 0, CloseButton);
|
||||
CloseIcon.addPixmap(normalPixmap, QIcon::Normal);
|
||||
CloseIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25),
|
||||
QIcon::Disabled);
|
||||
CloseButton->setIcon(
|
||||
_this->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
|
||||
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
CloseButton->setVisible(true);
|
||||
CloseButton->setFocusPolicy(Qt::NoFocus);
|
||||
_this->connect(CloseButton, SIGNAL(clicked()), SIGNAL(closeRequested()));
|
||||
|
||||
QFontMetrics fm(TitleLabel->font());
|
||||
int Spacing = qRound(fm.height() / 4.0);
|
||||
|
||||
// Fill the layout
|
||||
QBoxLayout *Layout = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
Layout->setContentsMargins(6, 0, 0, 0);
|
||||
Layout->setSpacing(0);
|
||||
_this->setLayout(Layout);
|
||||
Layout->addWidget(TitleLabel, 1);
|
||||
Layout->addSpacing(Spacing);
|
||||
Layout->addWidget(CloseButton);
|
||||
Layout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
TitleLabel->setVisible(true);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CFloatingWidgetTitleBar::CFloatingWidgetTitleBar(CFloatingDockContainer *parent) :
|
||||
QWidget(parent),
|
||||
d(new FloatingWidgetTitleBarPrivate(this))
|
||||
{
|
||||
d->FloatingWidget = parent;
|
||||
d->createLayout();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CFloatingWidgetTitleBar::~CFloatingWidgetTitleBar()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CFloatingWidgetTitleBar::mousePressEvent(QMouseEvent *ev)
|
||||
{
|
||||
if (ev->button() == Qt::LeftButton)
|
||||
{
|
||||
d->DragState = DraggingFloatingWidget;
|
||||
d->FloatingWidget->startDragging(ev->pos(), d->FloatingWidget->size(),
|
||||
this);
|
||||
return;
|
||||
}
|
||||
Super::mousePressEvent(ev);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CFloatingWidgetTitleBar::mouseReleaseEvent(QMouseEvent *ev)
|
||||
{
|
||||
d->DragState = DraggingInactive;
|
||||
Super::mouseReleaseEvent(ev);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CFloatingWidgetTitleBar::mouseMoveEvent(QMouseEvent *ev)
|
||||
{
|
||||
if (!(ev->buttons() & Qt::LeftButton) || DraggingInactive == d->DragState)
|
||||
{
|
||||
d->DragState = DraggingInactive;
|
||||
Super::mouseMoveEvent(ev);
|
||||
return;
|
||||
}
|
||||
|
||||
// move floating window
|
||||
if (DraggingFloatingWidget == d->DragState)
|
||||
{
|
||||
d->FloatingWidget->moveFloating();
|
||||
Super::mouseMoveEvent(ev);
|
||||
return;
|
||||
}
|
||||
Super::mouseMoveEvent(ev);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CFloatingWidgetTitleBar::enableCloseButton(bool Enable)
|
||||
{
|
||||
d->CloseButton->setEnabled(Enable);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CFloatingWidgetTitleBar::setTitle(const QString &Text)
|
||||
{
|
||||
d->TitleLabel->setText(Text);
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
85
src/linux/FloatingWidgetTitleBar.h
Normal file
85
src/linux/FloatingWidgetTitleBar.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef FLOATINGWIDGETTITLEBAR_H
|
||||
#define FLOATINGWIDGETTITLEBAR_H
|
||||
/*******************************************************************************
|
||||
** Qt Advanced Docking System
|
||||
** Copyright (C) 2017 Uwe Kindler
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU Lesser General Public
|
||||
** License as published by the Free Software Foundation; either
|
||||
** version 2.1 of the License, or (at your option) any later version.
|
||||
**
|
||||
** This library is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
** Lesser General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU Lesser General Public
|
||||
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
//============================================================================
|
||||
/// \file FloatingWidgetTitleBar.h
|
||||
/// \author Uwe Kindler
|
||||
/// \date 13.05.2019
|
||||
/// \brief Declaration of CFloatingWidgetTitleBar class
|
||||
//============================================================================
|
||||
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <QWidget>
|
||||
|
||||
namespace ads
|
||||
{
|
||||
class CFloatingDockContainer;
|
||||
|
||||
struct FloatingWidgetTitleBarPrivate;
|
||||
|
||||
|
||||
/**
|
||||
* Titlebar for floating widgets to capture non client are mouse events.
|
||||
* Linux does not support NonClieantArea mouse events like
|
||||
* QEvent::NonClientAreaMouseButtonPress. Because these events are required
|
||||
* for the docking system to work properly, we use our own titlebar here to
|
||||
* capture the required mouse events.
|
||||
*/
|
||||
class CFloatingWidgetTitleBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
FloatingWidgetTitleBarPrivate *d; ///< private data (pimpl)
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent *ev) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *ev) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent *ev) override;
|
||||
|
||||
public:
|
||||
using Super = QWidget;
|
||||
explicit CFloatingWidgetTitleBar(CFloatingDockContainer *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Virtual Destructor
|
||||
*/
|
||||
virtual ~CFloatingWidgetTitleBar();
|
||||
|
||||
/**
|
||||
* Enables / disables the window close button.
|
||||
*/
|
||||
void enableCloseButton(bool Enable);
|
||||
|
||||
/**
|
||||
* Sets the window title, that means, the text of the internal tile label.
|
||||
*/
|
||||
void setTitle(const QString &Text);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* This signal is emitted, if the close button is clicked.
|
||||
*/
|
||||
void closeRequested();
|
||||
};
|
||||
} // namespace ads
|
||||
#endif // FLOATINGWIDGETTITLEBAR_H
|
||||
13
src/src.pro
13
src/src.pro
@@ -41,9 +41,8 @@ HEADERS += \
|
||||
DockSplitter.h \
|
||||
DockAreaTitleBar.h \
|
||||
ElidingLabel.h
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SOURCES += \
|
||||
ads_globals.cpp \
|
||||
DockAreaWidget.cpp \
|
||||
@@ -58,6 +57,12 @@ SOURCES += \
|
||||
DockAreaTitleBar.cpp \
|
||||
ElidingLabel.cpp
|
||||
|
||||
|
||||
unix {
|
||||
HEADERS += linux/FloatingWidgetTitleBar.h
|
||||
SOURCES += linux/FloatingWidgetTitleBar.cpp
|
||||
}
|
||||
|
||||
isEmpty(PREFIX){
|
||||
PREFIX=..\installed
|
||||
warning("Install Prefix not set")
|
||||
@@ -66,3 +71,5 @@ headers.path=$$PREFIX/include
|
||||
headers.files=$$HEADERS
|
||||
target.path=$$PREFIX/lib
|
||||
INSTALLS += headers target
|
||||
|
||||
DISTFILES +=
|
||||
|
||||
@@ -63,7 +63,7 @@ ads--CDockWidget
|
||||
#closeButton,
|
||||
#undockButton
|
||||
{
|
||||
padding: 0 -2px;
|
||||
padding: 0px -2px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
96
src/stylesheets/default_linux.css
Normal file
96
src/stylesheets/default_linux.css
Normal file
@@ -0,0 +1,96 @@
|
||||
|
||||
/*
|
||||
* Default style sheet on Windows Platforms
|
||||
* Note: Always use CSS-classes with and without "ads--" namespace to support Qt4 & Qt5
|
||||
*/
|
||||
|
||||
ads--CDockContainerWidget
|
||||
{
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockContainerWidget QSplitter::handle
|
||||
{
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget
|
||||
{
|
||||
background: palette(window);
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
ads--CDockAreaWidget #tabsMenuButton::menu-indicator
|
||||
{
|
||||
image: none;
|
||||
}
|
||||
|
||||
|
||||
ads--CDockWidgetTab
|
||||
{
|
||||
background: palette(window);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 0 1px 0 0;
|
||||
padding: 0 0px;
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"]
|
||||
{
|
||||
background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:0.5, stop:0 palette(window), stop:1 palette(light));
|
||||
/*background: palette(highlight);*/
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab QLabel
|
||||
{
|
||||
color: palette(dark);
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"] QLabel
|
||||
{
|
||||
color: palette(foreground);
|
||||
}
|
||||
|
||||
ads--CDockWidget
|
||||
{
|
||||
background: palette(light);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
|
||||
#tabsMenuButton,
|
||||
#closeButton,
|
||||
#undockButton
|
||||
{
|
||||
padding: 0px -2px;
|
||||
}
|
||||
|
||||
|
||||
QScrollArea#dockWidgetScrollArea
|
||||
{
|
||||
padding: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
#tabCloseButton
|
||||
{
|
||||
margin-top: 2px;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0px -2px;
|
||||
}
|
||||
|
||||
#tabCloseButton:hover
|
||||
{
|
||||
border: 1px solid rgba(0, 0, 0, 32);
|
||||
background: rgba(0, 0, 0, 16);
|
||||
}
|
||||
|
||||
#tabCloseButton:pressed
|
||||
{
|
||||
background: rgba(0, 0, 0, 32);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user