Compare commits
448 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3407945f19 | ||
|
|
ce01e6b4a6 | ||
|
|
3428a4b8b4 | ||
|
|
2b9377b5ee | ||
|
|
d4a18003d9 | ||
|
|
2c15d5dacd | ||
|
|
f236de3277 | ||
|
|
93394577d0 | ||
|
|
f387c6aebc | ||
|
|
41173d067b | ||
|
|
5b60e39ed3 | ||
|
|
1916bd726d | ||
|
|
3efc5f2ada | ||
|
|
3eba02597c | ||
|
|
65eeffd5e1 | ||
|
|
ff1439c719 | ||
|
|
7ba20f37b7 | ||
|
|
a4ef161f4f | ||
|
|
8a16230213 | ||
|
|
8113bf63ba | ||
|
|
2770837adc | ||
|
|
c4872c6b10 | ||
|
|
efb9b879dd | ||
|
|
d10d59a8e2 | ||
|
|
b61f50982a | ||
|
|
ae72f5e47d | ||
|
|
9d7c692398 | ||
|
|
474dd13855 | ||
|
|
72496ebd48 | ||
|
|
b727274cd9 | ||
|
|
094fa37135 | ||
|
|
6a8b26f415 | ||
|
|
acb423872a | ||
|
|
505f14a601 | ||
|
|
05c58a4ca9 | ||
|
|
b8ed70fa33 | ||
|
|
b510686fe2 | ||
|
|
50652b05b0 | ||
|
|
66795f2b12 | ||
|
|
bc5e0ba7d8 | ||
|
|
d722482913 | ||
|
|
1d68e27558 | ||
|
|
1dbd3f3f06 | ||
|
|
68b0958119 | ||
|
|
6c3f82547d | ||
|
|
9fe8f291fb | ||
|
|
102e65a548 | ||
|
|
4f62794946 | ||
|
|
dd06d84206 | ||
|
|
d4c179c48e | ||
|
|
ff68ad95a6 | ||
|
|
8f696ea36a | ||
|
|
ce1e8c8beb | ||
|
|
98ebdbea50 | ||
|
|
418d0740d2 | ||
|
|
50c3066eaa | ||
|
|
29ebc83b35 | ||
|
|
03bd4a4505 | ||
|
|
407af06a4a | ||
|
|
9af9e43a5d | ||
|
|
4c928071af | ||
|
|
ea03b988e0 | ||
|
|
e1044c3e91 | ||
|
|
8057d25f35 | ||
|
|
592193fc91 | ||
|
|
5cf4aa77d8 | ||
|
|
616e50c3f5 | ||
|
|
1de42a9766 | ||
|
|
f07fcddd78 | ||
|
|
225ab943bb | ||
|
|
3fe31ca62d | ||
|
|
d1f17e60f7 | ||
|
|
8f78e608d1 | ||
|
|
a5e8011222 | ||
|
|
0305d8a221 | ||
|
|
25e8d8691f | ||
|
|
084c5c5995 | ||
|
|
65c080ae8e | ||
|
|
f9927cef29 | ||
|
|
5778dfe929 | ||
|
|
c33c09eab1 | ||
|
|
2150ebf45e | ||
|
|
6021ee8094 | ||
|
|
eebb2a6297 | ||
|
|
0fb1363b1a | ||
|
|
2ca03cc56d | ||
|
|
4a2768015c | ||
|
|
861ce67725 | ||
|
|
c530a4a4ec | ||
|
|
2378f46067 | ||
|
|
ea707369a0 | ||
|
|
7640e9bdcf | ||
|
|
4a0266bc76 | ||
|
|
6d1f97649e | ||
|
|
2af4b1f75c | ||
|
|
c0cde1e31e | ||
|
|
ee809da7a7 | ||
|
|
a253e4a0b5 | ||
|
|
779c4b928c | ||
|
|
056f04d408 | ||
|
|
e085a29484 | ||
|
|
ffd35cbce3 | ||
|
|
8c1f065f3f | ||
|
|
5af6b4e324 | ||
|
|
b47a777f5c | ||
|
|
5b3a0a28df | ||
|
|
02143eac71 | ||
|
|
5e230d8874 | ||
|
|
a45a035bb3 | ||
|
|
05f8ce15a2 | ||
|
|
45af8867b2 | ||
|
|
8e522ce311 | ||
|
|
178603e3ba | ||
|
|
552cee514d | ||
|
|
4105f70089 | ||
|
|
0bd34a5a6e | ||
|
|
a5dd566b37 | ||
|
|
1724f7f5ec | ||
|
|
6cd09addae | ||
|
|
93382350db | ||
|
|
db90e5415f | ||
|
|
9679fd67cc | ||
|
|
c84c98f49a | ||
|
|
716acd5f68 | ||
|
|
e782b4813b | ||
|
|
b27a24b3c4 | ||
|
|
18c65cdf34 | ||
|
|
e049cb0353 | ||
|
|
8d42e7777d | ||
|
|
e682ab8ea5 | ||
|
|
c6ff7f5230 | ||
|
|
309fe1a14a | ||
|
|
6b45274686 | ||
|
|
0f72fabe67 | ||
|
|
d3ad17d2c6 | ||
|
|
a8e0f1904f | ||
|
|
2ee7deb6d5 | ||
|
|
2e88d8651e | ||
|
|
232b6b9a61 | ||
|
|
5978aaaedc | ||
|
|
3332f6050e | ||
|
|
a1de28c969 | ||
|
|
8af53b4199 | ||
|
|
bddf4c417d | ||
|
|
e345773cfc | ||
|
|
c1816bf507 | ||
|
|
4f97e07eb6 | ||
|
|
2fe542c3ef | ||
|
|
07f9c6d016 | ||
|
|
8ea7c265a7 | ||
|
|
3cd12ce1d3 | ||
|
|
1be8f2861d | ||
|
|
e15af4101a | ||
|
|
4504457da2 | ||
|
|
f497944d2c | ||
|
|
aee9fb1c95 | ||
|
|
316d9a00b5 | ||
|
|
b353c210ee | ||
|
|
490e853435 | ||
|
|
7393addf64 | ||
|
|
a2b9650469 | ||
|
|
ca39ab0b44 | ||
|
|
ae997d3d75 | ||
|
|
c48cf3875d | ||
|
|
46fb18fc58 | ||
|
|
8da6904dcd | ||
|
|
2a51359159 | ||
|
|
ec48140309 | ||
|
|
fe64f407c0 | ||
|
|
136d6d966c | ||
|
|
05ff005613 | ||
|
|
3ff154aff1 | ||
|
|
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 | ||
|
|
49a7682e74 | ||
|
|
e25bf2eac2 | ||
|
|
f7c8384b73 | ||
|
|
9bd06401d9 | ||
|
|
b44a7e75ca | ||
|
|
c9645ef85b | ||
|
|
fd09a681c4 | ||
|
|
e113790bbe | ||
|
|
957dce5d1f | ||
|
|
e352ce559b | ||
|
|
0c3ef64d3e | ||
|
|
f72e2ce058 | ||
|
|
befdcce343 | ||
|
|
6fc8964ffc | ||
|
|
6cb1f33451 | ||
|
|
ee616c2541 | ||
|
|
7dd2a3c83c | ||
|
|
9db502e652 | ||
|
|
1ad6caeb8a | ||
|
|
4dde545c8f | ||
|
|
b7a5918974 | ||
|
|
ddfa6c2a43 | ||
|
|
275520ae29 | ||
|
|
1078387f5d | ||
|
|
c33dddbd47 | ||
|
|
2570a880af | ||
|
|
40a8d9e6b4 | ||
|
|
9af6622466 | ||
|
|
4fa89374c4 | ||
|
|
1aaa56ef29 | ||
|
|
d298a47bda | ||
|
|
146b65206a | ||
|
|
616ad9f86e | ||
|
|
aa9762718c | ||
|
|
f26bee6677 | ||
|
|
fb18de4868 | ||
|
|
e204e10113 | ||
|
|
a06a14d6cd | ||
|
|
88d4bea2c1 | ||
|
|
b8ad2f7577 | ||
|
|
32e5d599f7 | ||
|
|
48382ccd82 | ||
|
|
e37e4fdf57 | ||
|
|
c9a97534a8 | ||
|
|
8f54dd2a82 | ||
|
|
c0d6f959ec | ||
|
|
8570139cd1 | ||
|
|
b38919e909 | ||
|
|
b19cc98c84 | ||
|
|
f3f5b668e5 | ||
|
|
82d15fbe29 | ||
|
|
01533a9f85 | ||
|
|
fb9f1d851b | ||
|
|
6fb80fdeb7 | ||
|
|
e94cf9bcb7 | ||
|
|
da0ec6dd4b | ||
|
|
80efed693e | ||
|
|
653f475e72 | ||
|
|
87e3777e37 | ||
|
|
71f66ea6dc | ||
|
|
0b3f419c80 | ||
|
|
f69af82a49 | ||
|
|
854f542164 | ||
|
|
b9265fccec | ||
|
|
b3a272110a | ||
|
|
316e5324ad | ||
|
|
6843703484 | ||
|
|
115a9a5b3d | ||
|
|
a4838a41ac | ||
|
|
74b9d35c7b | ||
|
|
c973482b2b | ||
|
|
188624440b | ||
|
|
72ec61a043 | ||
|
|
0ac19ebdfb | ||
|
|
bc6ffcc02c | ||
|
|
a9246f7ce4 | ||
|
|
3f5697554a | ||
|
|
5e6c82b68d | ||
|
|
268f8655a1 | ||
|
|
1dfabb3bef | ||
|
|
6617cf6f19 | ||
|
|
81523b0346 | ||
|
|
927be9a7d9 | ||
|
|
ada3d6b3b5 | ||
|
|
30bbd26d0a | ||
|
|
8637c89a6b | ||
|
|
11e5f9c95a | ||
|
|
9bfb3fbea1 | ||
|
|
9c95e34df5 | ||
|
|
ceebda7431 | ||
|
|
75288af88c | ||
|
|
7c67d71f68 | ||
|
|
548dfb363a | ||
|
|
9fec2bd515 | ||
|
|
fc04aa2411 | ||
|
|
c3a5e3ef21 | ||
|
|
0e85431405 | ||
|
|
b3b6d20d96 | ||
|
|
272bbe275e | ||
|
|
496aec211e | ||
|
|
b9b72df9d4 | ||
|
|
fcb1846bf5 | ||
|
|
9f1b2c122a | ||
|
|
6ec38b48ef | ||
|
|
b93e723a83 | ||
|
|
1a47918bdb | ||
|
|
ff9d965726 | ||
|
|
77d2cebe39 | ||
|
|
5d380708e1 | ||
|
|
aa7b36dbd1 | ||
|
|
c9123c3640 | ||
|
|
67199a81f4 | ||
|
|
72ee4a53df | ||
|
|
0b963d1540 | ||
|
|
9cd2584de5 | ||
|
|
3f40c997e5 | ||
|
|
6b93ae9c39 | ||
|
|
f5b3c0556d | ||
|
|
5b3841a038 | ||
|
|
9d00a278e6 | ||
|
|
b470dd5f99 | ||
|
|
7b4a19b943 | ||
|
|
8eceed9aa3 | ||
|
|
4188d69356 | ||
|
|
3fc7c195c3 | ||
|
|
f823b67a4a | ||
|
|
064cab405a | ||
|
|
75ad302d21 | ||
|
|
18a4f17fbf | ||
|
|
6266cd3290 | ||
|
|
8a401ebd68 | ||
|
|
805e97946e | ||
|
|
e878bb47ed | ||
|
|
dae852d9f9 | ||
|
|
8a014a6c2d | ||
|
|
9676eeb1bf | ||
|
|
412f13e1c4 | ||
|
|
11a30806f6 | ||
|
|
b9257bbe93 | ||
|
|
78e81b02fd | ||
|
|
52c23dafd5 | ||
|
|
bc37a2788e | ||
|
|
051c379e4a | ||
|
|
844c853768 | ||
|
|
990d3235c5 | ||
|
|
fd76e9e62b | ||
|
|
a3ff1ae8ee | ||
|
|
17dff82d12 | ||
|
|
9af86c4136 | ||
|
|
aa8a52b845 | ||
|
|
9adc524a42 | ||
|
|
549646d113 | ||
|
|
7ba3c1f244 | ||
|
|
c532c24f79 | ||
|
|
c5ea5c80b1 | ||
|
|
1b1c636107 | ||
|
|
2277ba3630 | ||
|
|
5dcd15e2b9 | ||
|
|
a652deba71 | ||
|
|
1cd1e7d6ec | ||
|
|
16bd1a3bd2 | ||
|
|
b6ee26adc2 | ||
|
|
0d6f469a36 | ||
|
|
338b10695a | ||
|
|
239bd4781b | ||
|
|
97571e4be8 | ||
|
|
c57d14d0d7 | ||
|
|
a0849dd19f | ||
|
|
52aedfed31 | ||
|
|
fade9d7b7c | ||
|
|
a8ccbfa407 | ||
|
|
f9f064dd71 | ||
|
|
fac5661280 | ||
|
|
df85c8bee0 | ||
|
|
e0a442263e | ||
|
|
2c9ceb8645 | ||
|
|
b31c5f1f3d | ||
|
|
c14352e7c1 | ||
|
|
f0584ff0c5 | ||
|
|
4a0c176327 | ||
|
|
94a6f5e2f1 | ||
|
|
842cef2675 | ||
|
|
ca64286117 | ||
|
|
5dc935f650 | ||
|
|
ad49745b18 | ||
|
|
938afb7357 | ||
|
|
0edc1b4499 | ||
|
|
d0fc4ace07 | ||
|
|
70a7a7b352 | ||
|
|
b93d2fbd48 | ||
|
|
635b96a2ae | ||
|
|
72fc9cd79a | ||
|
|
268c49af3b | ||
|
|
025bedfb65 | ||
|
|
df97d17844 | ||
|
|
2bf1a51627 | ||
|
|
a4de5c5560 | ||
|
|
0716020ab4 | ||
|
|
7f5e393cfb | ||
|
|
f4c0d38ba4 | ||
|
|
411e4002f1 | ||
|
|
3fd20fad16 | ||
|
|
889d9bff5b | ||
|
|
68b93f6fa9 | ||
|
|
abc8468989 |
160
.appveyor.yml
Normal file
@@ -0,0 +1,160 @@
|
||||
version: '2.3.2.{build}'
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
image: Visual Studio 2015
|
||||
clone_depth: 1
|
||||
environment:
|
||||
global:
|
||||
# Appveyor doesn't have Qt 12 yet
|
||||
LatestLTSQtVersion: 5.9
|
||||
LatestQtVersion: 5.11
|
||||
matrix:
|
||||
# Latest version of Qt, dll, 64bit, MSVC 2015, qmake
|
||||
- QT5: C:\Qt\%LatestQtVersion%\msvc2015_64
|
||||
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
|
||||
targetPlatform: amd64
|
||||
use_mingw: "false"
|
||||
use_static: "false"
|
||||
use_cmake: "false"
|
||||
# 32 bit builds
|
||||
# MSVC 2015 builds
|
||||
# Dynamic Library builds
|
||||
# LTS version of Qt, dll, 32bit, MSVC 2015, qmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\msvc2015
|
||||
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
|
||||
targetPlatform: x86
|
||||
use_mingw: "false"
|
||||
use_static: "false"
|
||||
use_cmake: "false"
|
||||
# LTS version of Qt, dll, 32bit, MSVC 2015, cmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\msvc2015
|
||||
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
|
||||
targetPlatform: x86
|
||||
use_mingw: "false"
|
||||
use_static: "false"
|
||||
use_cmake: "true"
|
||||
# end Dynamic Library builds
|
||||
# Static Library builds
|
||||
# LTS version of Qt, static, 32bit, MSVC 2015, qmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\msvc2015
|
||||
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
|
||||
targetPlatform: x86
|
||||
use_mingw: "false"
|
||||
use_static: "true"
|
||||
use_cmake: "false"
|
||||
# LTS version of Qt, static, 32bit, MSVC 2015, cmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\msvc2015
|
||||
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
|
||||
targetPlatform: x86
|
||||
use_mingw: "false"
|
||||
use_static: "true"
|
||||
use_cmake: "true"
|
||||
# end Static Library builds
|
||||
# end MSVC 2015 builds
|
||||
# MinGW builds
|
||||
# Dynamic Library builds
|
||||
# LTS version of Qt, dll, 32bit, MinGW, qmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\mingw53_32
|
||||
COMPILER: C:\Qt\Tools\mingw530_32
|
||||
targetPlatform: x86
|
||||
use_mingw: "true"
|
||||
use_static: "false"
|
||||
use_cmake: "false"
|
||||
# LTS version of Qt, dll, 32bit, MinGW, cmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\mingw53_32
|
||||
COMPILER: C:\Qt\Tools\mingw530_32
|
||||
targetPlatform: x86
|
||||
use_mingw: "true"
|
||||
use_static: "false"
|
||||
use_cmake: "true"
|
||||
# end Dynamic Library builds
|
||||
# Static Library builds
|
||||
# LTS version of Qt, static, 32bit, MinGW, qmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\mingw53_32
|
||||
COMPILER: C:\Qt\Tools\mingw530_32
|
||||
targetPlatform: x86
|
||||
use_mingw: "true"
|
||||
use_static: "true"
|
||||
use_cmake: "false"
|
||||
# LTS version of Qt, static, 32bit, MinGW, cmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\mingw53_32
|
||||
COMPILER: C:\Qt\Tools\mingw530_32
|
||||
targetPlatform: x86
|
||||
use_mingw: "true"
|
||||
use_static: "true"
|
||||
use_cmake: "true"
|
||||
# end Static Library builds
|
||||
# end MinGW builds
|
||||
# end 32 bit builds
|
||||
# 64 bit builds
|
||||
# MSVC 2015 builds
|
||||
# Dynamic Library builds
|
||||
# LTS version of Qt, dll, 64bit, MSVC 2015, qmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\msvc2015_64
|
||||
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
|
||||
targetPlatform: amd64
|
||||
use_mingw: "false"
|
||||
use_static: "false"
|
||||
use_cmake: "false"
|
||||
# LTS version of Qt, dll, 64bit, MSVC 2015, cmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\msvc2015_64
|
||||
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
|
||||
targetPlatform: amd64
|
||||
use_mingw: "false"
|
||||
use_static: "false"
|
||||
use_cmake: "true"
|
||||
# end Dynamic Library builds
|
||||
# Static Library builds
|
||||
# LTS version of Qt, static, 64bit, MSVC 2015, qmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\msvc2015_64
|
||||
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
|
||||
targetPlatform: amd64
|
||||
use_mingw: "false"
|
||||
use_static: "true"
|
||||
use_cmake: "false"
|
||||
# LTS version of Qt, static, 64bit, MSVC 2015, cmake
|
||||
- QT5: C:\Qt\%LatestLTSQtVersion%\msvc2015_64
|
||||
COMPILER: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
|
||||
targetPlatform: amd64
|
||||
use_mingw: "false"
|
||||
use_static: "true"
|
||||
use_cmake: "true"
|
||||
# end Static Library builds
|
||||
# end MSVC 2015 builds
|
||||
# end 64 bit builds
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
before_build:
|
||||
- set PATH=%COMPILER%\bin;%QT5%\bin;%PATH%
|
||||
- set originalWD=%CD%
|
||||
- call "%QT5%\bin\qtenv2.bat"
|
||||
- cd %originalWD%
|
||||
- if %use_mingw%==false call "%COMPILER%\vcvarsall.bat" %targetPlatform%
|
||||
- if %use_static%==true (set USESTATIC=ON) else (set USESTATIC=OFF)
|
||||
- if %use_mingw%==true (set CMAKEGENERATOR="MinGW Makefiles") else (set CMAKEGENERATOR="NMake Makefiles")
|
||||
- if %use_mingw%==true (set MAKEENGINE=mingw32-make) else (set MAKEENGINE=nmake)
|
||||
- if %use_mingw%==true set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
|
||||
|
||||
build_script:
|
||||
- if %use_cmake%==true mkdir .\build
|
||||
- if %use_cmake%==true cd .\build
|
||||
- if %use_cmake%==true cmake --version
|
||||
- if %use_cmake%==true cmake -G %CMAKEGENERATOR% -DCMAKE_BUILD_TYPE=DEBUG -DBUILD_EXAMPLES=ON -DCMAKE_DEBUG_POSTFIX=d -DBUILD_STATIC=%USESTATIC% -DCMAKE_INSTALL_PREFIX="./installed" ../
|
||||
- if %use_cmake%==true cmake --build .
|
||||
- if %use_cmake%==true cmake --build . --target install
|
||||
- if %use_cmake%==true cmake -G %CMAKEGENERATOR% -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_EXAMPLES=ON -DBUILD_STATIC=%USESTATIC% -DCMAKE_INSTALL_PREFIX="./installed" ../
|
||||
- if %use_cmake%==true cmake --build .
|
||||
- if %use_cmake%==true cmake --build . --target install
|
||||
- if %use_cmake%==false if %use_static%==true qmake "CONFIG+=adsBuildStatic"
|
||||
- if %use_cmake%==false if %use_static%==false qmake
|
||||
- if %use_cmake%==false %MAKEENGINE% debug
|
||||
- if %use_cmake%==false %MAKEENGINE% install
|
||||
- if %use_cmake%==false %MAKEENGINE% release
|
||||
- if %use_cmake%==false %MAKEENGINE% install
|
||||
|
||||
after_build:
|
||||
- if %use_mingw%==true set PATH=C:\Program Files\Git\usr\bin;%PATH%
|
||||
14
.astylerc
@@ -1,14 +0,0 @@
|
||||
--style=allman
|
||||
|
||||
--indent=force-tab=4
|
||||
|
||||
--align-pointer=type
|
||||
--align-reference=type
|
||||
|
||||
--pad-oper
|
||||
--pad-header
|
||||
--unpad-paren
|
||||
|
||||
--remove-comment-prefix
|
||||
|
||||
--mode=c
|
||||
359
.cproject
Normal file
@@ -0,0 +1,359 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
|
||||
<folderInfo id="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584" name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.base.88699815" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.base">
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.PE" id="cdt.managedbuild.target.gnu.platform.mingw.base.519267520" name="Debug Platform" osList="win32" superClass="cdt.managedbuild.target.gnu.platform.mingw.base"/>
|
||||
<builder id="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1200539104" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.mingw.base.1438677059" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.base">
|
||||
<option id="gnu.both.asm.option.include.paths.403127333" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/QtAdvancedDockingSystem/demo}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/QtAdvancedDockingSystem/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${QTDIR}/include""/>
|
||||
<listOptionValue builtIn="false" value=""${QTDIR}/include/QtCore""/>
|
||||
<listOptionValue builtIn="false" value=""${QTDIR}/include/QtWidgets""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1249325593" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.933824900" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.1947822681" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base">
|
||||
<option id="gnu.cpp.compiler.option.include.paths.349616932" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/QtAdvancedDockingSystem/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/QtAdvancedDockingSystem/demo}""/>
|
||||
<listOptionValue builtIn="false" value=""${QTDIR}/include""/>
|
||||
<listOptionValue builtIn="false" value=""${QTDIR}/include/QtCore""/>
|
||||
<listOptionValue builtIn="false" value=""${QTDIR}/include/QtWidgets""/>
|
||||
</option>
|
||||
<option id="gnu.cpp.compiler.option.preprocessor.def.56223209" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1318830536" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.base.389117097" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.base">
|
||||
<option id="gnu.c.compiler.option.include.paths.1871729602" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/QtAdvancedDockingSystem/demo}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/QtAdvancedDockingSystem/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${QTDIR}/include""/>
|
||||
<listOptionValue builtIn="false" value=""${QTDIR}/include/QtCore""/>
|
||||
<listOptionValue builtIn="false" value=""${QTDIR}/include/QtWidgets""/>
|
||||
</option>
|
||||
<option id="gnu.c.compiler.option.preprocessor.def.symbols.806805509" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1568363924" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.base.1734874312" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base.985493173" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.266071128" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="QtAdvancedDockingSystem.null.1346550114" name="QtAdvancedDockingSystem"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
||||
<buildTargets>
|
||||
<target name="Build all" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Clean" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Debug Build" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j6</buildArguments>
|
||||
<buildTarget>debug</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="qmake" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>qmake</buildCommand>
|
||||
<buildArguments>-recursive ../ads.pro</buildArguments>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Release Build" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>release</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Build all" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Clean" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Debug Build" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j6</buildArguments>
|
||||
<buildTarget>debug</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="qmake" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>qmake</buildCommand>
|
||||
<buildArguments>-recursive ../../src/src.pro</buildArguments>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Release Build" path=" build/src" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>release</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Build all" path=" build/example" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Clean" path=" build/example" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Debug Build" path=" build/example" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j6</buildArguments>
|
||||
<buildTarget>debug</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="qmake" path=" build/example" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>qmake</buildCommand>
|
||||
<buildArguments>-recursive ../../example/example.pro</buildArguments>
|
||||
<buildTarget/>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Release Build" path=" build/example" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>release</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Build all" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Clean" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Debug Build" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j6</buildArguments>
|
||||
<buildTarget>debug</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="qmake" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>qmake</buildCommand>
|
||||
<buildArguments>-recursive ../../demo/demo.pro</buildArguments>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Release Build" path=" build/demo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>release</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Build all" path=" build/AdvancedDockingSystemDemo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Clean" path=" build/AdvancedDockingSystemDemo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Debug Build" path=" build/AdvancedDockingSystemDemo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j6</buildArguments>
|
||||
<buildTarget>debug</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="qmake" path=" build/AdvancedDockingSystemDemo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>qmake</buildCommand>
|
||||
<buildArguments>-recursive ../../AdvancedDockingSystemDemo/AdvancedDockingSystemDemo.pro</buildArguments>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Release Build" path=" build/AdvancedDockingSystemDemo" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>release</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Build all" path=" build/AdvancedDockingSystemDemo_v2" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Clean" path=" build/AdvancedDockingSystemDemo_v2" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Debug Build" path=" build/AdvancedDockingSystemDemo_v2" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j6</buildArguments>
|
||||
<buildTarget>debug</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="qmake" path=" build/AdvancedDockingSystemDemo_v2" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>qmake</buildCommand>
|
||||
<buildArguments>-recursive ../../AdvancedDockingSystemDemo_v2/AdvancedDockingSystemDemo_v2.pro</buildArguments>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Release Build" path=" build/AdvancedDockingSystemDemo_v2" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>release</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Build all" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Clean" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Debug Build" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j6</buildArguments>
|
||||
<buildTarget>debug</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="qmake" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>qmake</buildCommand>
|
||||
<buildArguments>-recursive ../../AdvancedDockingSystem/src.pro</buildArguments>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="Release Build" path=" build/AdvancedDockingSystem" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>release</buildTarget>
|
||||
<stopOnError>false</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</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>
|
||||
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
PyQtAds/_version.py export-subst
|
||||
22
.github/workflows/linux-builds.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: linux-builds
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, ubuntu-18.04, ubuntu-16.04]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: install qt
|
||||
run: |
|
||||
sudo apt-get update --fix-missing
|
||||
sudo apt-get install qt5-default
|
||||
- name: qmake
|
||||
run: qmake
|
||||
- name: make
|
||||
run: make -j4
|
||||
18
.gitignore
vendored
@@ -1 +1,19 @@
|
||||
*.pro.user
|
||||
/build
|
||||
*.o
|
||||
*.dylib
|
||||
*.app
|
||||
qrc_*
|
||||
moc_*
|
||||
ui_*
|
||||
Makefile
|
||||
|
||||
# IDEs
|
||||
.idea
|
||||
|
||||
# Python
|
||||
.eggs
|
||||
*.pyc
|
||||
*.pyd
|
||||
__pycache__
|
||||
PyQtAds/rc.py
|
||||
|
||||
27
.project
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>QtAdvancedDockingSystem</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
12
.settings/language.settings.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
<configuration id="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795" name="Default">
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorMinGW" ref="shared-provider"/>
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" keep-relative-paths="false" name="CDT GCC Build Output Parser" parameter="(g?cc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
</extension>
|
||||
</configuration>
|
||||
</project>
|
||||
171
.travis.yml
@@ -1,24 +1,155 @@
|
||||
language:
|
||||
- cpp
|
||||
language: cpp
|
||||
# gcc is clang on mac
|
||||
compiler: gcc
|
||||
|
||||
compiler:
|
||||
- g++
|
||||
|
||||
addons:
|
||||
apt:
|
||||
git:
|
||||
depth: 1
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- name: Ubuntu qmake Qt5.5.1
|
||||
os: linux
|
||||
dist: trusty
|
||||
group: stable
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-sdk-team
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt551-trusty'
|
||||
update: true
|
||||
packages:
|
||||
- qt5-qmake
|
||||
- qtbase5-dev
|
||||
- qtdeclarative5-dev
|
||||
- libqt5webkit5-dev
|
||||
- libsqlite3-dev
|
||||
- qt55base
|
||||
- qt55tools
|
||||
- gcc-6
|
||||
- g++-6
|
||||
- libc6-i386
|
||||
script:
|
||||
- PATH="/opt/qt55/bin:$PATH"
|
||||
- CXX="g++-6"
|
||||
- CC="gcc-6"
|
||||
- qt55-env.sh
|
||||
- qmake
|
||||
- make
|
||||
- make install
|
||||
- name: Ubuntu qmake dll
|
||||
os: linux
|
||||
dist: xenial
|
||||
group: stable
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt-5.12.0-xenial'
|
||||
update: true
|
||||
packages:
|
||||
- qt512base
|
||||
- qt512tools
|
||||
- gcc-6
|
||||
- g++-6
|
||||
- libc6-i386
|
||||
- libgl-dev
|
||||
- libgl1-mesa-dev
|
||||
- mesa-common-dev
|
||||
script:
|
||||
- PATH="/opt/qt512/bin:$PATH"
|
||||
- CXX="g++-6"
|
||||
- CC="gcc-6"
|
||||
- qt512-env.sh
|
||||
- qmake
|
||||
- make
|
||||
- make install
|
||||
- name: Ubuntu qmake static
|
||||
os: linux
|
||||
dist: xenial
|
||||
group: stable
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt-5.12.0-xenial'
|
||||
update: true
|
||||
packages:
|
||||
- qt512base
|
||||
- qt512tools
|
||||
- gcc-6
|
||||
- g++-6
|
||||
- libc6-i386
|
||||
- libgl-dev
|
||||
- libgl1-mesa-dev
|
||||
- mesa-common-dev
|
||||
script:
|
||||
- PATH="/opt/qt512/bin:$PATH"
|
||||
- CXX="g++-6"
|
||||
- CC="gcc-6"
|
||||
- qt512-env.sh
|
||||
- qmake "CONFIG+=adsBuildStatic"
|
||||
- make
|
||||
- make install
|
||||
- name: macOS CMake dll
|
||||
os: osx
|
||||
osx_image: xcode10.1
|
||||
addons:
|
||||
homebrew:
|
||||
packages:
|
||||
- qt
|
||||
update: true
|
||||
script:
|
||||
- PATH="/usr/local/opt/qt5/bin:$PATH"
|
||||
- mkdir -p build
|
||||
- cd build
|
||||
- cmake --version
|
||||
- cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_DEBUG_POSTFIX=_debug -DBUILD_EXAMPLES=ON -DBUILD_STATIC=OFF -DCMAKE_INSTALL_PREFIX="./installed" ../
|
||||
- cmake --build .
|
||||
- cmake --build . --target install
|
||||
- cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_EXAMPLES=ON -DBUILD_STATIC=OFF -DCMAKE_INSTALL_PREFIX="./installed" ../
|
||||
- cmake --build .
|
||||
- cmake --build . --target install
|
||||
- name: macOS CMake static
|
||||
os: osx
|
||||
osx_image: xcode10.1
|
||||
addons:
|
||||
homebrew:
|
||||
packages:
|
||||
- qt
|
||||
update: true
|
||||
script:
|
||||
- PATH="/usr/local/opt/qt5/bin:$PATH"
|
||||
- mkdir -p build
|
||||
- cd build
|
||||
- cmake --version
|
||||
- cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_DEBUG_POSTFIX=_debug -DBUILD_EXAMPLES=ON -DBUILD_STATIC=ON -DCMAKE_INSTALL_PREFIX="./installed" ../
|
||||
- cmake --build .
|
||||
- cmake --build . --target install
|
||||
- cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_EXAMPLES=ON -DBUILD_STATIC=ON -DCMAKE_INSTALL_PREFIX="./installed" ../
|
||||
- cmake --build .
|
||||
- cmake --build . --target install
|
||||
- name: macOS qmake dll
|
||||
os: osx
|
||||
osx_image: xcode10.1
|
||||
addons:
|
||||
homebrew:
|
||||
packages:
|
||||
- qt
|
||||
update: true
|
||||
script:
|
||||
- PATH="/usr/local/opt/qt5/bin:$PATH"
|
||||
- qmake
|
||||
- make
|
||||
- make install
|
||||
- name: macOS qmake static
|
||||
os: osx
|
||||
osx_image: xcode10.1
|
||||
addons:
|
||||
homebrew:
|
||||
packages:
|
||||
- qt
|
||||
update: true
|
||||
script:
|
||||
- PATH="/usr/local/opt/qt5/bin:$PATH"
|
||||
- qmake "CONFIG+=adsBuildStatic"
|
||||
- make
|
||||
- make install
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
script:
|
||||
- qmake -qt=qt5 -v
|
||||
- qmake -qt=qt5 -r build.pro
|
||||
- make
|
||||
|
||||
#- sudo apt-get install -qq qtbase5-dev qtdeclarative5-dev libqt5webkit5-dev libsqlite3-dev
|
||||
#- sudo apt-get install -qq qt5-default qttools5-dev-tools
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/src/API.cpp \
|
||||
$$PWD/src/ContainerWidget.cpp \
|
||||
$$PWD/src/SectionWidget.cpp \
|
||||
$$PWD/src/SectionContent.cpp \
|
||||
$$PWD/src/SectionTitleWidget.cpp \
|
||||
$$PWD/src/SectionContentWidget.cpp \
|
||||
$$PWD/src/DropOverlay.cpp \
|
||||
$$PWD/src/FloatingWidget.cpp \
|
||||
$$PWD/src/Internal.cpp \
|
||||
$$PWD/src/Serialization.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/include/ads/API.h \
|
||||
$$PWD/include/ads/ContainerWidget.h \
|
||||
$$PWD/include/ads/SectionWidget.h \
|
||||
$$PWD/include/ads/SectionContent.h \
|
||||
$$PWD/include/ads/SectionTitleWidget.h \
|
||||
$$PWD/include/ads/SectionContentWidget.h \
|
||||
$$PWD/include/ads/DropOverlay.h \
|
||||
$$PWD/include/ads/FloatingWidget.h \
|
||||
$$PWD/include/ads/Internal.h \
|
||||
$$PWD/include/ads/Serialization.h
|
||||
@@ -1,35 +0,0 @@
|
||||
TARGET = AdvancedDockingSystem
|
||||
TEMPLATE = lib
|
||||
VERSION = 1.0.0
|
||||
|
||||
CONFIG += adsBuildShared
|
||||
|
||||
QT += core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
greaterThan(QT_MAJOR_VERSION, 4): DEFINES += ADS_NAMESPACE_ENABLED
|
||||
|
||||
adsBuildShared {
|
||||
CONFIG += shared
|
||||
DEFINES += ADS_EXPORT
|
||||
}
|
||||
!adsBuildShared {
|
||||
CONFIG += staticlib
|
||||
}
|
||||
|
||||
INCLUDEPATH += $$PWD/include
|
||||
|
||||
windows {
|
||||
# MinGW
|
||||
*-g++* {
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
QMAKE_CXXFLAGS += -Wall -Wextra -pedantic
|
||||
}
|
||||
# MSVC
|
||||
*-msvc* {
|
||||
}
|
||||
}
|
||||
|
||||
RESOURCES += \
|
||||
res/ads.qrc
|
||||
|
||||
include(AdvancedDockingSystem.pri)
|
||||
@@ -1,74 +0,0 @@
|
||||
#ifndef ADS_API_H
|
||||
#define ADS_API_H
|
||||
|
||||
#include <QFlags>
|
||||
class QWidget;
|
||||
class QSplitter;
|
||||
|
||||
// DLL Export API
|
||||
#ifdef _WIN32
|
||||
#if defined(ADS_IMPORT)
|
||||
#define ADS_EXPORT_API
|
||||
#elif defined(ADS_EXPORT)
|
||||
#define ADS_EXPORT_API __declspec(dllexport)
|
||||
#else
|
||||
#define ADS_EXPORT_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define ADS_EXPORT_API
|
||||
#endif
|
||||
|
||||
// Use namespace
|
||||
// Disabled with Qt4, it makes problems with signals and slots.
|
||||
#ifdef ADS_NAMESPACE_ENABLED
|
||||
#define ADS_NAMESPACE_BEGIN namespace ads {
|
||||
#define ADS_NAMESPACE_END }
|
||||
#define ADS_NS ::ads
|
||||
#else
|
||||
#define ADS_NAMESPACE_BEGIN
|
||||
#define ADS_NAMESPACE_END
|
||||
#define ADS_NS
|
||||
#endif
|
||||
|
||||
// Always enable "serialization" namespace.
|
||||
// It is not required for signals and slots.
|
||||
#define ADS_NAMESPACE_SER_BEGIN namespace ads { namespace serialization {
|
||||
#define ADS_NAMESPACE_SER_END }}
|
||||
#define ADS_NS_SER ::ads::serialization
|
||||
|
||||
// Width of the native window frame border (based on OS).
|
||||
#define ADS_WINDOW_FRAME_BORDER_WIDTH 7
|
||||
|
||||
// Beautiful C++ stuff.
|
||||
#define ADS_Expects(cond)
|
||||
#define ADS_Ensures(cond)
|
||||
|
||||
// Indicates whether ADS should include animations.
|
||||
//#define ADS_ANIMATIONS_ENABLED 1
|
||||
//#define ADS_ANIMATION_DURATION 150
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class ContainerWidget;
|
||||
class SectionWidget;
|
||||
|
||||
enum DropArea
|
||||
{
|
||||
InvalidDropArea = 0,
|
||||
TopDropArea = 1,
|
||||
RightDropArea = 2,
|
||||
BottomDropArea = 4,
|
||||
LeftDropArea = 8,
|
||||
CenterDropArea = 16,
|
||||
|
||||
AllAreas = TopDropArea | RightDropArea | BottomDropArea | LeftDropArea | CenterDropArea
|
||||
};
|
||||
Q_DECLARE_FLAGS(DropAreas, DropArea)
|
||||
|
||||
void deleteEmptySplitter(ContainerWidget* container);
|
||||
ContainerWidget* findParentContainerWidget(QWidget* w);
|
||||
SectionWidget* findParentSectionWidget(QWidget* w);
|
||||
QSplitter* findParentSplitter(QWidget* w);
|
||||
QSplitter* findImmediateSplitter(QWidget* w);
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
#endif
|
||||
@@ -1,191 +0,0 @@
|
||||
#ifndef ADS_CONTAINERWIDGET_H
|
||||
#define ADS_CONTAINERWIDGET_H
|
||||
|
||||
#include <QList>
|
||||
#include <QHash>
|
||||
#include <QPointer>
|
||||
#include <QFrame>
|
||||
class QPoint;
|
||||
class QSplitter;
|
||||
class QMenu;
|
||||
class QGridLayout;
|
||||
|
||||
#include "ads/API.h"
|
||||
#include "ads/Internal.h"
|
||||
#include "ads/SectionContent.h"
|
||||
#include "ads/FloatingWidget.h"
|
||||
#include "ads/Serialization.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class SectionWidget;
|
||||
class DropOverlay;
|
||||
class InternalContentData;
|
||||
|
||||
|
||||
/*!
|
||||
* ContainerWidget is the main container to provide the docking
|
||||
* functionality. It manages multiple sections with all possible areas.
|
||||
*/
|
||||
class ADS_EXPORT_API ContainerWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class SectionContent;
|
||||
friend class SectionWidget;
|
||||
friend class FloatingWidget;
|
||||
friend class SectionTitleWidget;
|
||||
friend class SectionContentWidget;
|
||||
|
||||
public:
|
||||
explicit ContainerWidget(QWidget *parent = NULL);
|
||||
virtual ~ContainerWidget();
|
||||
|
||||
//
|
||||
// Public API
|
||||
//
|
||||
|
||||
/*!
|
||||
* Adds the section-content <em>sc</em> to this container-widget into the section-widget <em>sw</em>.
|
||||
* If <em>sw</em> is not NULL, the <em>area</em> is used to indicate how the content should be arranged.
|
||||
* Returns a pointer to the SectionWidget of the added SectionContent. Do not use it for anything else than adding more
|
||||
* SectionContent elements with this method.
|
||||
*/
|
||||
SectionWidget* addSectionContent(const SectionContent::RefPtr& sc, SectionWidget* sw = NULL, DropArea area = CenterDropArea);
|
||||
|
||||
/*!
|
||||
* Completely removes the <em>sc</em> from this ContainerWidget.
|
||||
* This container will no longer hold a reference to the content.
|
||||
* The content can be safely deleted.
|
||||
*/
|
||||
bool removeSectionContent(const SectionContent::RefPtr& sc);
|
||||
|
||||
/*!
|
||||
* Shows the specific SectionContent in UI.
|
||||
* Independed of the current state, whether it is used inside a section or is floating.
|
||||
*/
|
||||
bool showSectionContent(const SectionContent::RefPtr& sc);
|
||||
|
||||
/*!
|
||||
* Closes the specified SectionContent from UI.
|
||||
* Independed of the current state, whether it is used inside a section or is floating.
|
||||
*/
|
||||
bool hideSectionContent(const SectionContent::RefPtr& sc);
|
||||
|
||||
/*!
|
||||
* Selects the specific SectionContent as current, if it is part of a SectionWidget.
|
||||
* If SC is floating, it does nothing (or should we show it?)
|
||||
*/
|
||||
bool raiseSectionContent(const SectionContent::RefPtr& sc);
|
||||
|
||||
/*!
|
||||
* Indicates whether the SectionContent <em>sc</em> is visible.
|
||||
*/
|
||||
bool isSectionContentVisible(const SectionContent::RefPtr& sc);
|
||||
|
||||
/*!
|
||||
* Creates a QMenu based on available SectionContents.
|
||||
* The caller is responsible to delete the menu.
|
||||
*/
|
||||
QMenu* createContextMenu() const;
|
||||
|
||||
/*!
|
||||
* Serializes the current state of contents and returns it as a plain byte array.
|
||||
* \see restoreState(const QByteArray&)
|
||||
*/
|
||||
QByteArray saveState() const;
|
||||
|
||||
/*!
|
||||
* Deserilizes the state of contents from <em>data</em>, which was written with <em>saveState()</em>.
|
||||
* \see saveState()
|
||||
*/
|
||||
bool restoreState(const QByteArray& data);
|
||||
|
||||
//
|
||||
// Advanced Public API
|
||||
// You usually should not need access to this methods
|
||||
//
|
||||
|
||||
// Outer DropAreas
|
||||
QRect outerTopDropRect() const;
|
||||
QRect outerRightDropRect() const;
|
||||
QRect outerBottomDropRect() const;
|
||||
QRect outerLeftDropRect() const;
|
||||
|
||||
/*!
|
||||
* \brief contents
|
||||
* \return List of known SectionContent for this ContainerWidget.
|
||||
*/
|
||||
QList<SectionContent::RefPtr> contents() const;
|
||||
|
||||
QPointer<DropOverlay> dropOverlay() const;
|
||||
|
||||
private:
|
||||
//
|
||||
// Internal Stuff Begins Here
|
||||
//
|
||||
|
||||
SectionWidget* newSectionWidget();
|
||||
SectionWidget* dropContent(const InternalContentData& data, SectionWidget* targetSection, DropArea area, bool autoActive = true);
|
||||
void addSection(SectionWidget* section);
|
||||
SectionWidget* sectionAt(const QPoint& pos) const;
|
||||
SectionWidget* dropContentOuterHelper(QLayout* l, const InternalContentData& data, Qt::Orientation orientation, bool append);
|
||||
|
||||
// Serialization
|
||||
QByteArray saveHierarchy() const;
|
||||
void saveFloatingWidgets(QDataStream& out) const;
|
||||
void saveSectionWidgets(QDataStream& out, QWidget* widget) const;
|
||||
|
||||
bool saveSectionIndex(ADS_NS_SER::SectionIndexData &sid) const;
|
||||
|
||||
bool restoreHierarchy(const QByteArray& data);
|
||||
bool restoreFloatingWidgets(QDataStream& in, int version, QList<FloatingWidget*>& floatings);
|
||||
bool restoreSectionWidgets(QDataStream& in, int version, QSplitter* currentSplitter, QList<SectionWidget*>& sections, QList<SectionContent::RefPtr>& contentsToHide);
|
||||
|
||||
bool takeContent(const SectionContent::RefPtr& sc, InternalContentData& data);
|
||||
|
||||
private slots:
|
||||
void onActiveTabChanged();
|
||||
void onActionToggleSectionContentVisibility(bool visible);
|
||||
|
||||
signals:
|
||||
void orientationChanged();
|
||||
|
||||
/*!
|
||||
* Emits whenever the "isActiveTab" state of a SectionContent changes.
|
||||
* Whenever the users sets another tab as active, this signal gets invoked
|
||||
* for the old tab and the new active tab (the order is unspecified).
|
||||
*/
|
||||
void activeTabChanged(const SectionContent::RefPtr& sc, bool active);
|
||||
|
||||
/*!
|
||||
* Emits whenever the visibility of a SectionContent changes.
|
||||
* \see showSectionContent(), hideSectionContent()
|
||||
* \since 0.2
|
||||
*/
|
||||
void sectionContentVisibilityChanged(const SectionContent::RefPtr& sc, bool visible);
|
||||
|
||||
private:
|
||||
// Elements inside container.
|
||||
QList<SectionWidget*> _sections;
|
||||
QList<FloatingWidget*> _floatings;
|
||||
QHash<int, HiddenSectionItem> _hiddenSectionContents;
|
||||
|
||||
|
||||
// Helper lookup maps, restricted to this container.
|
||||
QHash<int, SectionContent::WeakPtr> _scLookupMapById;
|
||||
QHash<QString, SectionContent::WeakPtr> _scLookupMapByName;
|
||||
QHash<int, SectionWidget*> _swLookupMapById;
|
||||
|
||||
|
||||
// Layout stuff
|
||||
QGridLayout* _mainLayout;
|
||||
Qt::Orientation _orientation;
|
||||
QPointer<QSplitter> _splitter; // $mfreiholz: I'd like to remove this variable entirely,
|
||||
// because it changes during user interaction anyway.
|
||||
|
||||
// Drop overlay stuff.
|
||||
QPointer<DropOverlay> _dropOverlay;
|
||||
};
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
#endif
|
||||
@@ -1,86 +0,0 @@
|
||||
#ifndef DROP_OVERLAY_H
|
||||
#define DROP_OVERLAY_H
|
||||
|
||||
#include <QPointer>
|
||||
#include <QHash>
|
||||
#include <QRect>
|
||||
#include <QFrame>
|
||||
class QGridLayout;
|
||||
|
||||
#include "ads/API.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class DropOverlayCross;
|
||||
|
||||
/*!
|
||||
* DropOverlay paints a translucent rectangle over another widget. The geometry
|
||||
* of the rectangle is based on the mouse location.
|
||||
*/
|
||||
class ADS_EXPORT_API DropOverlay : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class DropOverlayCross;
|
||||
|
||||
public:
|
||||
DropOverlay(QWidget* parent);
|
||||
virtual ~DropOverlay();
|
||||
|
||||
void setAllowedAreas(DropAreas areas);
|
||||
DropAreas allowedAreas() const;
|
||||
|
||||
void setAreaWidgets(const QHash<DropArea, QWidget*>& widgets);
|
||||
|
||||
DropArea cursorLocation() const;
|
||||
|
||||
DropArea showDropOverlay(QWidget* target);
|
||||
void showDropOverlay(QWidget* target, const QRect& targetAreaRect);
|
||||
void hideDropOverlay();
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *e);
|
||||
virtual void showEvent(QShowEvent* e);
|
||||
virtual void hideEvent(QHideEvent* e);
|
||||
virtual void resizeEvent(QResizeEvent* e);
|
||||
virtual void moveEvent(QMoveEvent* e);
|
||||
|
||||
private:
|
||||
DropAreas _allowedAreas;
|
||||
DropOverlayCross* _cross;
|
||||
|
||||
bool _fullAreaDrop;
|
||||
QPointer<QWidget> _target;
|
||||
QRect _targetRect;
|
||||
DropArea _lastLocation;
|
||||
};
|
||||
|
||||
/*!
|
||||
* DropOverlayCross shows a cross with 5 different drop area possibilities.
|
||||
* I could have handled everything inside DropOverlay, but because of some
|
||||
* styling issues it's better to have a separate class for the cross.
|
||||
*/
|
||||
class DropOverlayCross : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class DropOverlay;
|
||||
|
||||
public:
|
||||
DropOverlayCross(DropOverlay* overlay);
|
||||
virtual ~DropOverlayCross();
|
||||
|
||||
void setAreaWidgets(const QHash<DropArea, QWidget*>& widgets);
|
||||
DropArea cursorLocation() const;
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent* e);
|
||||
|
||||
private:
|
||||
void reset();
|
||||
|
||||
private:
|
||||
DropOverlay* _overlay;
|
||||
QHash<DropArea, QWidget*> _widgets;
|
||||
QGridLayout* _grid;
|
||||
};
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
#endif
|
||||
@@ -1,46 +0,0 @@
|
||||
#ifndef FLOATINGWIDGET_H
|
||||
#define FLOATINGWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
class QBoxLayout;
|
||||
|
||||
#include "ads/API.h"
|
||||
#include "ads/SectionContent.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class ContainerWidget;
|
||||
class SectionTitleWidget;
|
||||
class SectionContentWidget;
|
||||
class InternalContentData;
|
||||
|
||||
// FloatingWidget holds and displays SectionContent as a floating window.
|
||||
// It can be resized, moved and dropped back into a SectionWidget.
|
||||
class FloatingWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class ContainerWidget;
|
||||
|
||||
public:
|
||||
FloatingWidget(ContainerWidget* container, SectionContent::RefPtr sc, SectionTitleWidget* titleWidget, SectionContentWidget* contentWidget, QWidget* parent = NULL);
|
||||
virtual ~FloatingWidget();
|
||||
|
||||
SectionContent::RefPtr content() const { return _content; }
|
||||
|
||||
public://private:
|
||||
bool takeContent(InternalContentData& data);
|
||||
|
||||
private slots:
|
||||
void onCloseButtonClicked();
|
||||
|
||||
private:
|
||||
ContainerWidget* _container;
|
||||
SectionContent::RefPtr _content;
|
||||
SectionTitleWidget* _titleWidget;
|
||||
SectionContentWidget* _contentWidget;
|
||||
|
||||
QBoxLayout* _titleLayout;
|
||||
};
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
#ifndef ADS_INTERNAL_HEADER
|
||||
#define ADS_INTERNAL_HEADER
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QWeakPointer>
|
||||
|
||||
#include "ads/API.h"
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
#else
|
||||
#include "ads/SectionContent.h"
|
||||
#endif
|
||||
|
||||
#define SCLookupMapById(X) X->_scLookupMapById
|
||||
#define SCLookupMapByName(X) X->_scLookupMapByName
|
||||
#define SWLookupMapById(X) X->_swLookupMapById
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class SectionContent;
|
||||
class SectionTitleWidget;
|
||||
class SectionContentWidget;
|
||||
|
||||
|
||||
class InternalContentData
|
||||
{
|
||||
public:
|
||||
typedef QSharedPointer<InternalContentData> RefPtr;
|
||||
typedef QWeakPointer<InternalContentData> WeakPtr;
|
||||
|
||||
InternalContentData();
|
||||
~InternalContentData();
|
||||
|
||||
QSharedPointer<SectionContent> content;
|
||||
SectionTitleWidget* titleWidget;
|
||||
SectionContentWidget* contentWidget;
|
||||
};
|
||||
|
||||
|
||||
class HiddenSectionItem
|
||||
{
|
||||
public:
|
||||
HiddenSectionItem() :
|
||||
preferredSectionId(-1),
|
||||
preferredSectionIndex(-1)
|
||||
{}
|
||||
|
||||
int preferredSectionId;
|
||||
int preferredSectionIndex;
|
||||
InternalContentData data;
|
||||
};
|
||||
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
#endif
|
||||
@@ -1,78 +0,0 @@
|
||||
#ifndef SECTIONCONTENT_H
|
||||
#define SECTIONCONTENT_H
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QWeakPointer>
|
||||
#include <QPointer>
|
||||
class QWidget;
|
||||
|
||||
#include "ads/API.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class ContainerWidget;
|
||||
|
||||
class ADS_EXPORT_API SectionContent
|
||||
{
|
||||
friend class ContainerWidget;
|
||||
|
||||
private:
|
||||
SectionContent();
|
||||
SectionContent(const SectionContent&);
|
||||
SectionContent& operator=(const SectionContent&);
|
||||
|
||||
public:
|
||||
typedef QSharedPointer<SectionContent> RefPtr;
|
||||
typedef QWeakPointer<SectionContent> WeakPtr;
|
||||
|
||||
enum Flag
|
||||
{
|
||||
None = 0,
|
||||
Closeable = 1,
|
||||
AllFlags = Closeable
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
||||
/*!
|
||||
* Creates new content, associates it to <em>container</em> and takes ownership of
|
||||
* <em>title</em>- and <em>content</em>- widgets.
|
||||
* \param uniqueName An unique identifier across the entire process.
|
||||
* \param container The parent ContainerWidget in which this content will be active.
|
||||
* \param title The widget to use as title.
|
||||
* \param content The widget to use as content.
|
||||
* \return May return a invalid ref-pointer in case of invalid parameters.
|
||||
*/
|
||||
static RefPtr newSectionContent(const QString& uniqueName, ContainerWidget* container, QWidget* title, QWidget* content);
|
||||
|
||||
virtual ~SectionContent();
|
||||
int uid() const;
|
||||
QString uniqueName() const;
|
||||
ContainerWidget* containerWidget() const;
|
||||
QWidget* titleWidget() const;
|
||||
QWidget* contentWidget() const;
|
||||
Flags flags() const;
|
||||
|
||||
QString visibleTitle() const;
|
||||
QString title() const;
|
||||
void setTitle(const QString& title);
|
||||
void setFlags(const Flags f);
|
||||
|
||||
private:
|
||||
const int _uid;
|
||||
QString _uniqueName;
|
||||
|
||||
QPointer<ContainerWidget> _containerWidget;
|
||||
QPointer<QWidget> _titleWidget;
|
||||
QPointer<QWidget> _contentWidget;
|
||||
|
||||
// Optional attributes
|
||||
QString _title;
|
||||
Flags _flags;
|
||||
|
||||
/* Note: This method could be a problem in static build environment
|
||||
* since it may begin with 0 for every module which uses ADS.
|
||||
*/
|
||||
static int GetNextUid();
|
||||
};
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
#endif
|
||||
@@ -1,28 +0,0 @@
|
||||
#ifndef SECTION_CONTENT_WIDGET_H
|
||||
#define SECTION_CONTENT_WIDGET_H
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
#include "ads/API.h"
|
||||
#include "ads/SectionContent.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class ContainerWidget;
|
||||
class SectionWidget;
|
||||
|
||||
class SectionContentWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class ContainerWidget;
|
||||
|
||||
public:
|
||||
SectionContentWidget(SectionContent::RefPtr c, QWidget* parent = 0);
|
||||
virtual ~SectionContentWidget();
|
||||
|
||||
private:
|
||||
SectionContent::RefPtr _content;
|
||||
};
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
#ifndef SECTION_TITLE_WIDGET_H
|
||||
#define SECTION_TITLE_WIDGET_H
|
||||
|
||||
#include <QPointer>
|
||||
#include <QPoint>
|
||||
#include <QFrame>
|
||||
|
||||
#include "ads/API.h"
|
||||
#include "ads/SectionContent.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class ContainerWidget;
|
||||
class SectionWidget;
|
||||
class FloatingWidget;
|
||||
|
||||
class SectionTitleWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool activeTab READ isActiveTab WRITE setActiveTab NOTIFY activeTabChanged)
|
||||
|
||||
friend class ContainerWidget;
|
||||
friend class SectionWidget;
|
||||
|
||||
SectionContent::RefPtr _content;
|
||||
|
||||
// Drag & Drop (Floating)
|
||||
QPointer<FloatingWidget> _fw;
|
||||
QPoint _dragStartPos;
|
||||
|
||||
// Drag & Drop (Title/Tabs)
|
||||
bool _tabMoving;
|
||||
|
||||
// Property values
|
||||
bool _activeTab;
|
||||
|
||||
public:
|
||||
SectionTitleWidget(SectionContent::RefPtr content, QWidget* parent);
|
||||
virtual ~SectionTitleWidget();
|
||||
|
||||
bool isActiveTab() const;
|
||||
void setActiveTab(bool active);
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent* ev);
|
||||
virtual void mouseReleaseEvent(QMouseEvent* ev);
|
||||
virtual void mouseMoveEvent(QMouseEvent* ev);
|
||||
|
||||
signals:
|
||||
void activeTabChanged();
|
||||
void clicked();
|
||||
};
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
#endif
|
||||
@@ -1,103 +0,0 @@
|
||||
#ifndef SECTION_WIDGET_H
|
||||
#define SECTION_WIDGET_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPointer>
|
||||
#include <QList>
|
||||
#include <QFrame>
|
||||
#include <QScrollArea>
|
||||
class QBoxLayout;
|
||||
class QStackedLayout;
|
||||
class QPushButton;
|
||||
class QMenu;
|
||||
|
||||
#include "ads/API.h"
|
||||
#include "ads/Internal.h"
|
||||
#include "ads/SectionContent.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class ContainerWidget;
|
||||
class SectionTitleWidget;
|
||||
class SectionContentWidget;
|
||||
|
||||
// SectionWidget manages multiple instances of SectionContent.
|
||||
// It displays a title TAB, which is clickable and will switch to
|
||||
// the contents associated to the title when clicked.
|
||||
class ADS_EXPORT_API SectionWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class ContainerWidget;
|
||||
|
||||
explicit SectionWidget(ContainerWidget* parent);
|
||||
|
||||
public:
|
||||
virtual ~SectionWidget();
|
||||
|
||||
int uid() const;
|
||||
ContainerWidget* containerWidget() const;
|
||||
|
||||
QRect titleAreaGeometry() const;
|
||||
QRect contentAreaGeometry() const;
|
||||
|
||||
const QList<SectionContent::RefPtr>& contents() const { return _contents; }
|
||||
void addContent(const SectionContent::RefPtr& c);
|
||||
void addContent(const InternalContentData& data, bool autoActivate);
|
||||
bool takeContent(int uid, InternalContentData& data);
|
||||
int indexOfContent(const SectionContent::RefPtr& c) const;
|
||||
int indexOfContentByUid(int uid) const;
|
||||
int indexOfContentByTitlePos(const QPoint& pos, QWidget* exclude = NULL) const;
|
||||
|
||||
int currentIndex() const;
|
||||
void moveContent(int from, int to);
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent*);
|
||||
|
||||
public slots:
|
||||
void setCurrentIndex(int index);
|
||||
|
||||
private slots:
|
||||
void onSectionTitleClicked();
|
||||
void onCloseButtonClicked();
|
||||
void onTabsMenuActionTriggered(bool);
|
||||
void updateTabsMenu();
|
||||
|
||||
|
||||
private:
|
||||
const int _uid;
|
||||
|
||||
QPointer<ContainerWidget> _container;
|
||||
QList<SectionContent::RefPtr> _contents;
|
||||
QList<SectionTitleWidget*> _sectionTitles;
|
||||
QList<SectionContentWidget*> _sectionContents;
|
||||
|
||||
QBoxLayout* _topLayout;
|
||||
QScrollArea* _tabsScrollArea;
|
||||
QWidget* _tabsContainerWidget;
|
||||
QBoxLayout* _tabsLayout;
|
||||
QPushButton* _tabsMenuButton;
|
||||
QPushButton* _closeButton;
|
||||
int _tabsLayoutInitCount; // used for calculations on _tabsLayout modification calls.
|
||||
|
||||
QStackedLayout *_contentsLayout;
|
||||
|
||||
QPoint _mousePressPoint;
|
||||
SectionContent::RefPtr _mousePressContent;
|
||||
SectionTitleWidget* _mousePressTitleWidget;
|
||||
|
||||
static int GetNextUid();
|
||||
};
|
||||
|
||||
/* Custom scrollable implementation for tabs */
|
||||
class SectionWidgetTabsScrollArea : public QScrollArea
|
||||
{
|
||||
public:
|
||||
SectionWidgetTabsScrollArea(SectionWidget* sectionWidget, QWidget* parent = NULL);
|
||||
virtual ~SectionWidgetTabsScrollArea();
|
||||
|
||||
protected:
|
||||
virtual void wheelEvent(QWheelEvent*);
|
||||
};
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
#endif
|
||||
@@ -1,165 +0,0 @@
|
||||
#ifndef ADS_SERIALIZATION_H
|
||||
#define ADS_SERIALIZATION_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QDataStream>
|
||||
#include <QBuffer>
|
||||
|
||||
#include "ads/API.h"
|
||||
|
||||
ADS_NAMESPACE_SER_BEGIN
|
||||
|
||||
enum EntryType
|
||||
{
|
||||
ET_Unknown = 0x00000000,
|
||||
ET_Hierarchy = 0x00000001,
|
||||
ET_SectionIndex = 0x00000002,
|
||||
|
||||
// Begin of custom entry types (e.g. CustomType + 42)
|
||||
ET_Custom = 0x0000ffff
|
||||
};
|
||||
|
||||
class ADS_EXPORT_API HeaderEntity
|
||||
{
|
||||
public:
|
||||
static qint32 MAGIC;
|
||||
static qint32 MAJOR_VERSION;
|
||||
static qint32 MINOR_VERSION;
|
||||
|
||||
HeaderEntity();
|
||||
qint32 magic;
|
||||
qint32 majorVersion;
|
||||
qint32 minorVersion;
|
||||
};
|
||||
QDataStream& operator<<(QDataStream& out, const HeaderEntity& data);
|
||||
QDataStream& operator>>(QDataStream& in, HeaderEntity& data);
|
||||
|
||||
|
||||
class ADS_EXPORT_API OffsetsHeaderEntity
|
||||
{
|
||||
public:
|
||||
OffsetsHeaderEntity();
|
||||
|
||||
qint64 entriesCount;
|
||||
QList<class OffsetsHeaderEntryEntity> entries;
|
||||
};
|
||||
QDataStream& operator<<(QDataStream& out, const OffsetsHeaderEntity& data);
|
||||
QDataStream& operator>>(QDataStream& in, OffsetsHeaderEntity& data);
|
||||
|
||||
|
||||
class ADS_EXPORT_API OffsetsHeaderEntryEntity
|
||||
{
|
||||
public:
|
||||
OffsetsHeaderEntryEntity();
|
||||
qint32 type;
|
||||
qint64 offset;
|
||||
qint64 contentSize;
|
||||
};
|
||||
QDataStream& operator<<(QDataStream& out, const OffsetsHeaderEntryEntity& data);
|
||||
QDataStream& operator>>(QDataStream& in, OffsetsHeaderEntryEntity& data);
|
||||
|
||||
|
||||
class ADS_EXPORT_API SectionEntity
|
||||
{
|
||||
public:
|
||||
SectionEntity();
|
||||
qint32 x;
|
||||
qint32 y;
|
||||
qint32 width;
|
||||
qint32 height;
|
||||
qint32 currentIndex;
|
||||
qint32 sectionContentsCount;
|
||||
QList<class SectionContentEntity> sectionContents;
|
||||
};
|
||||
QDataStream& operator<<(QDataStream& out, const SectionEntity& data);
|
||||
QDataStream& operator>>(QDataStream& in, SectionEntity& data);
|
||||
|
||||
|
||||
class ADS_EXPORT_API SectionContentEntity
|
||||
{
|
||||
public:
|
||||
SectionContentEntity();
|
||||
QString uniqueName;
|
||||
bool visible;
|
||||
qint32 preferredIndex;
|
||||
};
|
||||
QDataStream& operator<<(QDataStream& out, const SectionContentEntity& data);
|
||||
QDataStream& operator>>(QDataStream& in, SectionContentEntity& data);
|
||||
|
||||
|
||||
class ADS_EXPORT_API FloatingContentEntity
|
||||
{
|
||||
public:
|
||||
FloatingContentEntity();
|
||||
QString uniqueName;
|
||||
qint32 xpos;
|
||||
qint32 ypos;
|
||||
qint32 width;
|
||||
qint32 height;
|
||||
bool visible;
|
||||
};
|
||||
QDataStream& operator<<(QDataStream& out, const FloatingContentEntity& data);
|
||||
QDataStream& operator>>(QDataStream& in, FloatingContentEntity& data);
|
||||
|
||||
|
||||
// Type: OffsetHeaderEntry::Hierarchy
|
||||
class ADS_EXPORT_API HierarchyData
|
||||
{
|
||||
public:
|
||||
HierarchyData();
|
||||
QByteArray data;
|
||||
};
|
||||
QDataStream& operator<<(QDataStream& out, const HierarchyData& data);
|
||||
QDataStream& operator>>(QDataStream& in, HierarchyData& data);
|
||||
|
||||
|
||||
// Type: OffsetHeaderEntry::SectionIndex
|
||||
class ADS_EXPORT_API SectionIndexData
|
||||
{
|
||||
public:
|
||||
SectionIndexData();
|
||||
qint32 sectionsCount;
|
||||
QList<SectionEntity> sections;
|
||||
};
|
||||
QDataStream& operator<<(QDataStream& out, const SectionIndexData& data);
|
||||
QDataStream& operator>>(QDataStream& in, SectionIndexData& data);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The InMemoryWriter class writes into a QByteArray.
|
||||
*/
|
||||
class ADS_EXPORT_API InMemoryWriter
|
||||
{
|
||||
public:
|
||||
InMemoryWriter();
|
||||
bool write(qint32 entryType, const QByteArray& data);
|
||||
bool write(const SectionIndexData& data);
|
||||
QByteArray toByteArray() const;
|
||||
qint32 offsetsCount() const { return _offsetsHeader.entriesCount; }
|
||||
|
||||
private:
|
||||
QBuffer _contentBuffer;
|
||||
OffsetsHeaderEntity _offsetsHeader;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The InMemoryReader class
|
||||
*/
|
||||
class ADS_EXPORT_API InMemoryReader
|
||||
{
|
||||
public:
|
||||
InMemoryReader(const QByteArray& data);
|
||||
bool initReadHeader();
|
||||
bool read(qint32 entryType, QByteArray &data);
|
||||
bool read(SectionIndexData& sid);
|
||||
qint32 offsetsCount() const { return _offsetsHeader.entriesCount; }
|
||||
|
||||
private:
|
||||
QByteArray _data;
|
||||
OffsetsHeaderEntity _offsetsHeader;
|
||||
};
|
||||
|
||||
ADS_NAMESPACE_SER_END
|
||||
#endif
|
||||
@@ -1,7 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/ads">
|
||||
<file>stylesheets/default-windows.css</file>
|
||||
<file>stylesheets/vendor-partsolutions.css</file>
|
||||
<file>stylesheets/modern-windows.css</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Default style sheet on Windows Platforms
|
||||
* Note: Always use CSS-classes with and without "ads--" namespace to support Qt4 & Qt5
|
||||
*/
|
||||
|
||||
ads--ContainerWidget,
|
||||
ContainerWidget
|
||||
{
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--ContainerWidget QSplitter::handle,
|
||||
ContainerWidget QSplitter::handle
|
||||
{
|
||||
background: palette(dark);
|
||||
}
|
||||
|
||||
ads--SectionWidget,
|
||||
SectionWidget
|
||||
{
|
||||
background: palette(window);
|
||||
border: 1px solid palette(light);
|
||||
}
|
||||
|
||||
ads--SectionWidget #tabsMenuButton::menu-indicator,
|
||||
SectionWidget #tabsMenuButton::menu-indicator
|
||||
{
|
||||
image: none;
|
||||
}
|
||||
|
||||
ads--SectionTitleWidget,
|
||||
SectionTitleWidget
|
||||
{
|
||||
background: palette(window);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 0 1px 0 0;
|
||||
padding: 0 9px;
|
||||
}
|
||||
|
||||
ads--SectionTitleWidget[activeTab="true"],
|
||||
SectionTitleWidget[activeTab="true"]
|
||||
{
|
||||
/* background: palette(light);*/
|
||||
/* background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(240, 240, 240, 255));*/
|
||||
background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:0.5, stop:0 palette(window), stop:1 palette(light));
|
||||
}
|
||||
|
||||
ads--SectionContentWidget,
|
||||
SectionContentWidget
|
||||
{
|
||||
background: palette(light);
|
||||
border-color: palette(light);
|
||||
border-style: solid;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
|
||||
/* Special: QLabels inside SectionTitleWidget
|
||||
*/
|
||||
ads--SectionTitleWidget QLabel,
|
||||
SectionTitleWidget QLabel
|
||||
{
|
||||
color: palette(dark);
|
||||
}
|
||||
ads--SectionTitleWidget[activeTab="true"] QLabel,
|
||||
SectionTitleWidget[activeTab="true"] QLabel
|
||||
{
|
||||
color: palette(foreground);
|
||||
}
|
||||
|
||||
/* Special: QLabels inside SectionTitleWidget, which is floating
|
||||
*/
|
||||
ads--FloatingWidget ads--SectionTitleWidget QLabel,
|
||||
FloatingWidget SectionTitleWidget QLabel
|
||||
{
|
||||
color: palette(foreground);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
QSplitter::handle {
|
||||
background: palette(light);
|
||||
}
|
||||
|
||||
ads--ContainerWidget, ContainerWidget {
|
||||
background: palette(light);
|
||||
}
|
||||
|
||||
ads--SectionWidget, SectionWidget {
|
||||
background: palette(light);
|
||||
}
|
||||
|
||||
ads--SectionTitleWidget, SectionTitleWidget {
|
||||
background: #ffffff;
|
||||
}
|
||||
ads--SectionTitleWidget QLabel, SectionTitleWidget QLabel {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
ads--SectionTitleWidget[activeTab="true"], SectionTitleWidget[activeTab="true"] {
|
||||
background: #000000;
|
||||
border-right: 1px solid #000000;
|
||||
padding: 9px;
|
||||
}
|
||||
ads--SectionTitleWidget[activeTab="true"] QLabel, SectionTitleWidget[activeTab="true"] QLabel {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
ads--SectionContentWidget, SectionContentWidget {
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
|
||||
QAbstractItemView {
|
||||
border: 0;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Style sheet used by CADENAS PARTsolutions product line
|
||||
* Requires Qt4 compatibility
|
||||
*/
|
||||
|
||||
QSplitter::handle:vertical {
|
||||
image: url(:/img/splitter-horizontal.png);
|
||||
}
|
||||
|
||||
QSplitter::handle:horizontal {
|
||||
image: url(:/img/splitter-vertical.png);
|
||||
}
|
||||
|
||||
ads--ContainerWidget, ContainerWidget {
|
||||
background: #9ab6ca;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
ads--SectionWidget, SectionWidget {
|
||||
background: #7c9eb3;
|
||||
border-color: #ffffff;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
ads--SectionTitleWidget, SectionTitleWidget {
|
||||
background: #7c9eb3;
|
||||
border-right: 1px solid #E7F3F8;
|
||||
padding: 6px 6px;
|
||||
}
|
||||
|
||||
ads--SectionTitleWidget[activeTab="true"], SectionTitleWidget[activeTab="true"] {
|
||||
background: #E7F3F8;
|
||||
border: 1px solid #E7F3F8;
|
||||
}
|
||||
|
||||
ads--SectionWidget QPushButton#closeButton, SectionWidget QPushButton#closeButton,
|
||||
ads--FloatingWidget QPushButton#closeButton, FloatingWidget QPushButton#closeButton {
|
||||
background: #ff0000;
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
ads--SectionContentWidget, SectionContentWidget {
|
||||
background: #ffffff;
|
||||
border: 0px solid #E7F3F8;
|
||||
}
|
||||
|
||||
/* Special */
|
||||
|
||||
IconTitleWidget {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ads--SectionTitleWidget QLabel, SectionTitleWidget QLabel {
|
||||
color: #ffffff;
|
||||
background: #7c9eb3;
|
||||
}
|
||||
|
||||
ads--SectionTitleWidget[activeTab="true"] QLabel, SectionTitleWidget[activeTab="true"] QLabel {
|
||||
color: #000000;
|
||||
background: #E7F3F8;
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
#include "ads/API.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QSplitter>
|
||||
#include <QLayout>
|
||||
#include <QVariant>
|
||||
|
||||
#include "ads/ContainerWidget.h"
|
||||
#include "ads/SectionWidget.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
|
||||
static bool splitterContainsSectionWidget(QSplitter* splitter)
|
||||
{
|
||||
for (int i = 0; i < splitter->count(); ++i)
|
||||
{
|
||||
QWidget* w = splitter->widget(i);
|
||||
QSplitter* sp = qobject_cast<QSplitter*>(w);
|
||||
SectionWidget* sw = NULL;
|
||||
if (sp && splitterContainsSectionWidget(sp))
|
||||
return true;
|
||||
else if ((sw = qobject_cast<SectionWidget*>(w)) != NULL)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void deleteEmptySplitter(ContainerWidget* container)
|
||||
{
|
||||
bool doAgain = false;
|
||||
do
|
||||
{
|
||||
doAgain = false;
|
||||
QList<QSplitter*> splitters = container->findChildren<QSplitter*>();
|
||||
for (int i = 0; i < splitters.count(); ++i)
|
||||
{
|
||||
QSplitter* sp = splitters.at(i);
|
||||
if (!sp->property("ads-splitter").toBool())
|
||||
continue;
|
||||
if (sp->count() > 0 && splitterContainsSectionWidget(sp))
|
||||
continue;
|
||||
delete splitters[i];
|
||||
doAgain = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (doAgain);
|
||||
}
|
||||
|
||||
ContainerWidget* findParentContainerWidget(QWidget* w)
|
||||
{
|
||||
ContainerWidget* cw = 0;
|
||||
QWidget* next = w;
|
||||
do
|
||||
{
|
||||
if ((cw = dynamic_cast<ContainerWidget*>(next)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
next = next->parentWidget();
|
||||
}
|
||||
while (next);
|
||||
return cw;
|
||||
}
|
||||
|
||||
SectionWidget* findParentSectionWidget(class QWidget* w)
|
||||
{
|
||||
SectionWidget* cw = 0;
|
||||
QWidget* next = w;
|
||||
do
|
||||
{
|
||||
if ((cw = dynamic_cast<SectionWidget*>(next)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
next = next->parentWidget();
|
||||
}
|
||||
while (next);
|
||||
return cw;
|
||||
}
|
||||
|
||||
QSplitter* findParentSplitter(class QWidget* w)
|
||||
{
|
||||
QSplitter* cw = 0;
|
||||
QWidget* next = w;
|
||||
do
|
||||
{
|
||||
if ((cw = dynamic_cast<QSplitter*>(next)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
next = next->parentWidget();
|
||||
}
|
||||
while (next);
|
||||
return cw;
|
||||
}
|
||||
|
||||
QSplitter* findImmediateSplitter(class QWidget* w)
|
||||
{
|
||||
QSplitter* sp = NULL;
|
||||
QLayout* l = w->layout();
|
||||
if (!l || l->count() <= 0)
|
||||
return sp;
|
||||
for (int i = 0; i < l->count(); ++i)
|
||||
{
|
||||
QLayoutItem* li = l->itemAt(0);
|
||||
if (!li->widget())
|
||||
continue;
|
||||
if ((sp = dynamic_cast<QSplitter*>(li->widget())) != NULL)
|
||||
break;
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
@@ -1,441 +0,0 @@
|
||||
#include "ads/DropOverlay.h"
|
||||
|
||||
#include <QPointer>
|
||||
#include <QPaintEvent>
|
||||
#include <QResizeEvent>
|
||||
#include <QMoveEvent>
|
||||
#include <QPainter>
|
||||
#include <QGridLayout>
|
||||
#include <QCursor>
|
||||
#include <QIcon>
|
||||
#include <QLabel>
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
|
||||
// Helper /////////////////////////////////////////////////////////////
|
||||
|
||||
static QPixmap createDropIndicatorPixmap(const QPalette& pal, const QSizeF& size, DropArea dropArea)
|
||||
{
|
||||
const QColor borderColor = pal.color(QPalette::Active, QPalette::Highlight);
|
||||
const QColor backgroundColor = pal.color(QPalette::Active, QPalette::Base);
|
||||
const QColor areaBackgroundColor = pal.color(QPalette::Active, QPalette::Highlight).lighter(150);
|
||||
|
||||
QPixmap pm(size.width(), size.height());
|
||||
pm.fill(QColor(0, 0, 0, 0));
|
||||
|
||||
QPainter p(&pm);
|
||||
QPen pen = p.pen();
|
||||
QRectF baseRect(pm.rect());
|
||||
|
||||
// Fill
|
||||
p.fillRect(baseRect, backgroundColor);
|
||||
|
||||
// Drop area rect.
|
||||
if (true)
|
||||
{
|
||||
p.save();
|
||||
QRectF areaRect;
|
||||
QLineF areaLine;
|
||||
QLinearGradient gradient;
|
||||
switch (dropArea)
|
||||
{
|
||||
case TopDropArea:
|
||||
areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width(), baseRect.height() * .5f);
|
||||
areaLine = QLineF(areaRect.bottomLeft(), areaRect.bottomRight());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.bottomLeft());
|
||||
gradient.setColorAt(0.f, areaBackgroundColor);
|
||||
gradient.setColorAt(1.f, areaBackgroundColor.lighter(120));
|
||||
break;
|
||||
case RightDropArea:
|
||||
areaRect = QRectF(baseRect.width() * .5f, baseRect.y(), baseRect.width() * .5f, baseRect.height());
|
||||
areaLine = QLineF(areaRect.topLeft(), areaRect.bottomLeft());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.topRight());
|
||||
gradient.setColorAt(0.f, areaBackgroundColor.lighter(120));
|
||||
gradient.setColorAt(1.f, areaBackgroundColor);
|
||||
break;
|
||||
case BottomDropArea:
|
||||
areaRect = QRectF(baseRect.x(), baseRect.height() * .5f, baseRect.width(), baseRect.height() * .5f);
|
||||
areaLine = QLineF(areaRect.topLeft(), areaRect.topRight());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.bottomLeft());
|
||||
gradient.setColorAt(0.f, areaBackgroundColor.lighter(120));
|
||||
gradient.setColorAt(1.f, areaBackgroundColor);
|
||||
break;
|
||||
case LeftDropArea:
|
||||
areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width() * .5f, baseRect.height());
|
||||
areaLine = QLineF(areaRect.topRight(), areaRect.bottomRight());
|
||||
gradient.setStart(areaRect.topLeft());
|
||||
gradient.setFinalStop(areaRect.topRight());
|
||||
gradient.setColorAt(0.f, areaBackgroundColor);
|
||||
gradient.setColorAt(1.f, areaBackgroundColor.lighter(120));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (areaRect.isValid())
|
||||
{
|
||||
p.fillRect(areaRect, gradient);
|
||||
|
||||
pen = p.pen();
|
||||
pen.setColor(borderColor);
|
||||
pen.setStyle(Qt::DashLine);
|
||||
p.setPen(pen);
|
||||
p.drawLine(areaLine);
|
||||
}
|
||||
p.restore();
|
||||
}
|
||||
|
||||
// Border
|
||||
if (true)
|
||||
{
|
||||
p.save();
|
||||
pen = p.pen();
|
||||
pen.setColor(borderColor);
|
||||
pen.setWidth(1);
|
||||
|
||||
p.setPen(pen);
|
||||
p.drawRect(baseRect.adjusted(0, 0, -pen.width(), -pen.width()));
|
||||
p.restore();
|
||||
}
|
||||
return pm;
|
||||
}
|
||||
|
||||
static QWidget* createDropIndicatorWidget(DropArea dropArea)
|
||||
{
|
||||
QLabel* l = new QLabel();
|
||||
l->setObjectName("DropAreaLabel");
|
||||
|
||||
const qreal metric = static_cast<qreal>(l->fontMetrics().height()) * 2.f;
|
||||
const QSizeF size(metric, metric);
|
||||
|
||||
l->setPixmap(createDropIndicatorPixmap(l->palette(), size, dropArea));
|
||||
return l;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
DropOverlay::DropOverlay(QWidget* parent) :
|
||||
QFrame(parent),
|
||||
_allowedAreas(InvalidDropArea),
|
||||
_cross(new DropOverlayCross(this)),
|
||||
_fullAreaDrop(false),
|
||||
_lastLocation(InvalidDropArea)
|
||||
{
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
setWindowOpacity(0.2);
|
||||
setWindowTitle("DropOverlay");
|
||||
|
||||
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
l->setSpacing(0);
|
||||
setLayout(l);
|
||||
|
||||
// Cross with default drop area widgets.
|
||||
QHash<DropArea, QWidget*> areaWidgets;
|
||||
areaWidgets.insert(ADS_NS::TopDropArea, createDropIndicatorWidget(TopDropArea)); //createDropWidget(":/img/split-top.png"));
|
||||
areaWidgets.insert(ADS_NS::RightDropArea, createDropIndicatorWidget(RightDropArea));//createDropWidget(":/img/split-right.png"));
|
||||
areaWidgets.insert(ADS_NS::BottomDropArea, createDropIndicatorWidget(BottomDropArea));//createDropWidget(":/img/split-bottom.png"));
|
||||
areaWidgets.insert(ADS_NS::LeftDropArea, createDropIndicatorWidget(LeftDropArea));//createDropWidget(":/img/split-left.png"));
|
||||
areaWidgets.insert(ADS_NS::CenterDropArea, createDropIndicatorWidget(CenterDropArea));//createDropWidget(":/img/dock-center.png"));
|
||||
_cross->setAreaWidgets(areaWidgets);
|
||||
|
||||
_cross->setVisible(false);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
DropOverlay::~DropOverlay()
|
||||
{
|
||||
}
|
||||
|
||||
void DropOverlay::setAllowedAreas(DropAreas areas)
|
||||
{
|
||||
if (areas == _allowedAreas)
|
||||
return;
|
||||
_allowedAreas = areas;
|
||||
|
||||
_cross->reset();
|
||||
}
|
||||
|
||||
DropAreas DropOverlay::allowedAreas() const
|
||||
{
|
||||
return _allowedAreas;
|
||||
}
|
||||
|
||||
void DropOverlay::setAreaWidgets(const QHash<DropArea, QWidget*>& widgets)
|
||||
{
|
||||
_cross->setAreaWidgets(widgets);
|
||||
}
|
||||
|
||||
DropArea DropOverlay::cursorLocation() const
|
||||
{
|
||||
return _cross->cursorLocation();
|
||||
}
|
||||
|
||||
DropArea DropOverlay::showDropOverlay(QWidget* target)
|
||||
{
|
||||
if (_target == target)
|
||||
{
|
||||
// Hint: We could update geometry of overlay here.
|
||||
DropArea da = cursorLocation();
|
||||
if (da != _lastLocation)
|
||||
{
|
||||
repaint();
|
||||
_lastLocation = da;
|
||||
}
|
||||
return da;
|
||||
}
|
||||
|
||||
hideDropOverlay();
|
||||
_fullAreaDrop = false;
|
||||
_target = target;
|
||||
_targetRect = QRect();
|
||||
_lastLocation = InvalidDropArea;
|
||||
|
||||
// Move it over the target.
|
||||
resize(target->size());
|
||||
move(target->mapToGlobal(target->rect().topLeft()));
|
||||
|
||||
show();
|
||||
|
||||
return cursorLocation();
|
||||
}
|
||||
|
||||
void DropOverlay::showDropOverlay(QWidget* target, const QRect& targetAreaRect)
|
||||
{
|
||||
if (_target == target && _targetRect == targetAreaRect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hideDropOverlay();
|
||||
_fullAreaDrop = true;
|
||||
_target = target;
|
||||
_targetRect = targetAreaRect;
|
||||
_lastLocation = InvalidDropArea;
|
||||
|
||||
// Move it over the target's area.
|
||||
resize(targetAreaRect.size());
|
||||
move(target->mapToGlobal(QPoint(targetAreaRect.x(), targetAreaRect.y())));
|
||||
|
||||
show();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DropOverlay::hideDropOverlay()
|
||||
{
|
||||
hide();
|
||||
_fullAreaDrop = false;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
_target.clear();
|
||||
#else
|
||||
_target = 0;
|
||||
#endif
|
||||
_targetRect = QRect();
|
||||
_lastLocation = InvalidDropArea;
|
||||
}
|
||||
|
||||
void DropOverlay::paintEvent(QPaintEvent*)
|
||||
{
|
||||
QPainter p(this);
|
||||
const QColor areaColor = palette().color(QPalette::Active, QPalette::Highlight);//QColor(0, 100, 255)
|
||||
|
||||
// Always draw drop-rect over the entire rect()
|
||||
if (_fullAreaDrop)
|
||||
{
|
||||
QRect r = rect();
|
||||
p.fillRect(r, QBrush(areaColor, Qt::Dense4Pattern));
|
||||
p.setBrush(QBrush(areaColor));
|
||||
p.drawRect(r);
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw rect based on location
|
||||
QRect r = rect();
|
||||
const DropArea da = cursorLocation();
|
||||
switch (da)
|
||||
{
|
||||
case ADS_NS::TopDropArea:
|
||||
r.setHeight(r.height() / 2);
|
||||
break;
|
||||
case ADS_NS::RightDropArea:
|
||||
r.setX(r.width() / 2);
|
||||
break;
|
||||
case ADS_NS::BottomDropArea:
|
||||
r.setY(r.height() / 2);
|
||||
break;
|
||||
case ADS_NS::LeftDropArea:
|
||||
r.setWidth(r.width() / 2);
|
||||
break;
|
||||
case ADS_NS::CenterDropArea:
|
||||
r = rect();
|
||||
break;
|
||||
default:
|
||||
r = QRect();
|
||||
}
|
||||
if (!r.isNull())
|
||||
{
|
||||
p.fillRect(r, QBrush(areaColor, Qt::Dense4Pattern));
|
||||
p.setBrush(QBrush(areaColor));
|
||||
p.drawRect(r);
|
||||
}
|
||||
|
||||
// Draw rect over the entire size + border.
|
||||
// auto r = rect();
|
||||
// r.setWidth(r.width() - 1);
|
||||
// r.setHeight(r.height() - 1);
|
||||
|
||||
// p.fillRect(r, QBrush(QColor(0, 100, 255), Qt::Dense4Pattern));
|
||||
// p.setBrush(QBrush(QColor(0, 100, 255)));
|
||||
// p.drawRect(r);
|
||||
}
|
||||
|
||||
void DropOverlay::showEvent(QShowEvent*)
|
||||
{
|
||||
_cross->show();
|
||||
}
|
||||
|
||||
void DropOverlay::hideEvent(QHideEvent*)
|
||||
{
|
||||
_cross->hide();
|
||||
}
|
||||
|
||||
void DropOverlay::resizeEvent(QResizeEvent* e)
|
||||
{
|
||||
_cross->resize(e->size());
|
||||
}
|
||||
|
||||
void DropOverlay::moveEvent(QMoveEvent* e)
|
||||
{
|
||||
_cross->move(e->pos());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
static QPair<QPoint, int> gridPosForArea(const DropArea area)
|
||||
{
|
||||
switch (area)
|
||||
{
|
||||
case ADS_NS::TopDropArea:
|
||||
return qMakePair(QPoint(0, 1), (int) Qt::AlignHCenter | Qt::AlignBottom);
|
||||
case ADS_NS::RightDropArea:
|
||||
return qMakePair(QPoint(1, 2), (int) Qt::AlignLeft | Qt::AlignVCenter);
|
||||
case ADS_NS::BottomDropArea:
|
||||
return qMakePair(QPoint(2, 1), (int) Qt::AlignHCenter | Qt::AlignTop);
|
||||
case ADS_NS::LeftDropArea:
|
||||
return qMakePair(QPoint(1, 0), (int) Qt::AlignRight | Qt::AlignVCenter);
|
||||
case ADS_NS::CenterDropArea:
|
||||
return qMakePair(QPoint(1, 1), (int) Qt::AlignCenter);
|
||||
default:
|
||||
return QPair<QPoint, int>();
|
||||
}
|
||||
}
|
||||
|
||||
DropOverlayCross::DropOverlayCross(DropOverlay* overlay) :
|
||||
QWidget(overlay->parentWidget()),
|
||||
_overlay(overlay),
|
||||
_widgets()
|
||||
{
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
setWindowTitle("DropOverlayCross");
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
_grid = new QGridLayout();
|
||||
_grid->setContentsMargins(0, 0, 0, 0);
|
||||
_grid->setSpacing(6);
|
||||
|
||||
QBoxLayout* bl1 = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
bl1->setContentsMargins(0, 0, 0, 0);
|
||||
bl1->setSpacing(0);
|
||||
setLayout(bl1);
|
||||
|
||||
QBoxLayout* bl2 = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
bl2->setContentsMargins(0, 0, 0, 0);
|
||||
bl2->setSpacing(0);
|
||||
|
||||
bl1->addStretch(1);
|
||||
bl1->addLayout(bl2);
|
||||
bl2->addStretch(1);
|
||||
bl2->addLayout(_grid, 0);
|
||||
bl2->addStretch(1);
|
||||
bl1->addStretch(1);
|
||||
}
|
||||
|
||||
DropOverlayCross::~DropOverlayCross()
|
||||
{
|
||||
}
|
||||
|
||||
void DropOverlayCross::setAreaWidgets(const QHash<DropArea, QWidget*>& widgets)
|
||||
{
|
||||
// Delete old widgets.
|
||||
QMutableHashIterator<DropArea, QWidget*> i(_widgets);
|
||||
while (i.hasNext())
|
||||
{
|
||||
i.next();
|
||||
QWidget* widget = i.value();
|
||||
_grid->removeWidget(widget);
|
||||
delete widget;
|
||||
i.remove();
|
||||
}
|
||||
|
||||
// Insert new widgets into grid.
|
||||
_widgets = widgets;
|
||||
QHashIterator<DropArea, QWidget*> i2(_widgets);
|
||||
while (i2.hasNext())
|
||||
{
|
||||
i2.next();
|
||||
const DropArea area = i2.key();
|
||||
QWidget* widget = i2.value();
|
||||
const QPair<QPoint, int> opts = gridPosForArea(area);
|
||||
_grid->addWidget(widget, opts.first.x(), opts.first.y(), (Qt::Alignment) opts.second);
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
DropArea DropOverlayCross::cursorLocation() const
|
||||
{
|
||||
const QPoint pos = mapFromGlobal(QCursor::pos());
|
||||
QHashIterator<DropArea, QWidget*> i(_widgets);
|
||||
while (i.hasNext())
|
||||
{
|
||||
i.next();
|
||||
if (_overlay->allowedAreas().testFlag(i.key())
|
||||
&& i.value()
|
||||
&& i.value()->isVisible()
|
||||
&& i.value()->geometry().contains(pos))
|
||||
{
|
||||
return i.key();
|
||||
}
|
||||
}
|
||||
return InvalidDropArea;
|
||||
}
|
||||
|
||||
void DropOverlayCross::showEvent(QShowEvent*)
|
||||
{
|
||||
resize(_overlay->size());
|
||||
move(_overlay->pos());
|
||||
}
|
||||
|
||||
void DropOverlayCross::reset()
|
||||
{
|
||||
QList<DropArea> allAreas;
|
||||
allAreas << ADS_NS::TopDropArea << ADS_NS::RightDropArea << ADS_NS::BottomDropArea << ADS_NS::LeftDropArea << ADS_NS::CenterDropArea;
|
||||
const DropAreas allowedAreas = _overlay->allowedAreas();
|
||||
|
||||
// Update visibility of area widgets based on allowedAreas.
|
||||
for (int i = 0; i < allAreas.count(); ++i)
|
||||
{
|
||||
const QPair<QPoint, int> opts = gridPosForArea(allAreas.at(i));
|
||||
|
||||
QLayoutItem* item = _grid->itemAtPosition(opts.first.x(), opts.first.y());
|
||||
QWidget* w = NULL;
|
||||
if (item && (w = item->widget()) != NULL)
|
||||
{
|
||||
w->setVisible(allowedAreas.testFlag(allAreas.at(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
@@ -1,84 +0,0 @@
|
||||
#include "ads/FloatingWidget.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QSizePolicy>
|
||||
#include <QMouseEvent>
|
||||
#include <QStyle>
|
||||
|
||||
#include "ads/ContainerWidget.h"
|
||||
#include "ads/SectionTitleWidget.h"
|
||||
#include "ads/SectionContentWidget.h"
|
||||
#include "ads/Internal.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
|
||||
FloatingWidget::FloatingWidget(ContainerWidget* container, SectionContent::RefPtr sc, SectionTitleWidget* titleWidget, SectionContentWidget* contentWidget, QWidget* parent) :
|
||||
QWidget(parent, Qt::CustomizeWindowHint | Qt::Tool),
|
||||
_container(container),
|
||||
_content(sc),
|
||||
_titleWidget(titleWidget),
|
||||
_contentWidget(contentWidget)
|
||||
{
|
||||
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
l->setSpacing(0);
|
||||
setLayout(l);
|
||||
|
||||
// Title + Controls
|
||||
_titleLayout = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
_titleLayout->addWidget(titleWidget, 1);
|
||||
l->addLayout(_titleLayout, 0);
|
||||
titleWidget->setActiveTab(false);
|
||||
|
||||
if (sc->flags().testFlag(SectionContent::Closeable))
|
||||
{
|
||||
QPushButton* closeButton = new QPushButton();
|
||||
closeButton->setObjectName("closeButton");
|
||||
closeButton->setFlat(true);
|
||||
closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
|
||||
closeButton->setToolTip(tr("Close"));
|
||||
closeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
_titleLayout->addWidget(closeButton);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QObject::connect(closeButton, &QPushButton::clicked, this, &FloatingWidget::onCloseButtonClicked);
|
||||
#else
|
||||
QObject::connect(closeButton, SIGNAL(clicked(bool)), this, SLOT(onCloseButtonClicked()));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Content
|
||||
l->addWidget(contentWidget, 1);
|
||||
contentWidget->show();
|
||||
|
||||
// _container->_floatingWidgets.append(this);
|
||||
}
|
||||
|
||||
FloatingWidget::~FloatingWidget()
|
||||
{
|
||||
_container->_floatings.removeAll(this); // Note: I don't like this here, but we have to remove it from list...
|
||||
}
|
||||
|
||||
bool FloatingWidget::takeContent(InternalContentData& data)
|
||||
{
|
||||
data.content = _content;
|
||||
data.titleWidget = _titleWidget;
|
||||
data.contentWidget = _contentWidget;
|
||||
|
||||
_titleLayout->removeWidget(_titleWidget);
|
||||
_titleWidget->setParent(_container);
|
||||
_titleWidget = NULL;
|
||||
|
||||
layout()->removeWidget(_contentWidget);
|
||||
_contentWidget->setParent(_container);
|
||||
_contentWidget = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FloatingWidget::onCloseButtonClicked()
|
||||
{
|
||||
_container->hideSectionContent(_content);
|
||||
}
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "ads/Internal.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
|
||||
InternalContentData::InternalContentData() :
|
||||
titleWidget(NULL),
|
||||
contentWidget(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
InternalContentData::~InternalContentData()
|
||||
{
|
||||
}
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
@@ -1,115 +0,0 @@
|
||||
#include "ads/SectionContent.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
|
||||
#include "ads/Internal.h"
|
||||
#include "ads/ContainerWidget.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
|
||||
SectionContent::SectionContent() :
|
||||
_uid(GetNextUid()),
|
||||
_flags(AllFlags)
|
||||
{
|
||||
}
|
||||
|
||||
SectionContent::RefPtr SectionContent::newSectionContent(const QString& uniqueName, ContainerWidget* container, QWidget* title, QWidget* content)
|
||||
{
|
||||
if (uniqueName.isEmpty())
|
||||
{
|
||||
qFatal("Can not create SectionContent with empty uniqueName");
|
||||
return RefPtr();
|
||||
}
|
||||
else if (SCLookupMapByName(container).contains(uniqueName))
|
||||
{
|
||||
qFatal("Can not create SectionContent with already used uniqueName");
|
||||
return RefPtr();
|
||||
}
|
||||
else if (!container || !title || !content)
|
||||
{
|
||||
qFatal("Can not create SectionContent with NULL values");
|
||||
return RefPtr();
|
||||
}
|
||||
|
||||
QSharedPointer<SectionContent> sc(new SectionContent());
|
||||
sc->_uniqueName = uniqueName;
|
||||
sc->_containerWidget = container;
|
||||
sc->_titleWidget = title;
|
||||
sc->_contentWidget = content;
|
||||
|
||||
SCLookupMapById(container).insert(sc->uid(), sc);
|
||||
SCLookupMapByName(container).insert(sc->uniqueName(), sc);
|
||||
return sc;
|
||||
}
|
||||
|
||||
SectionContent::~SectionContent()
|
||||
{
|
||||
if (_containerWidget)
|
||||
{
|
||||
SCLookupMapById(_containerWidget).remove(_uid);
|
||||
SCLookupMapByName(_containerWidget).remove(_uniqueName);
|
||||
}
|
||||
delete _titleWidget;
|
||||
delete _contentWidget;
|
||||
}
|
||||
|
||||
int SectionContent::uid() const
|
||||
{
|
||||
return _uid;
|
||||
}
|
||||
|
||||
QString SectionContent::uniqueName() const
|
||||
{
|
||||
return _uniqueName;
|
||||
}
|
||||
|
||||
ContainerWidget* SectionContent::containerWidget() const
|
||||
{
|
||||
return _containerWidget;
|
||||
}
|
||||
|
||||
QWidget* SectionContent::titleWidget() const
|
||||
{
|
||||
return _titleWidget;
|
||||
}
|
||||
|
||||
QWidget* SectionContent::contentWidget() const
|
||||
{
|
||||
return _contentWidget;
|
||||
}
|
||||
|
||||
SectionContent::Flags SectionContent::flags() const
|
||||
{
|
||||
return _flags;
|
||||
}
|
||||
|
||||
QString SectionContent::visibleTitle() const
|
||||
{
|
||||
if (_title.isEmpty())
|
||||
return _uniqueName;
|
||||
return _title;
|
||||
}
|
||||
|
||||
QString SectionContent::title() const
|
||||
{
|
||||
return _title;
|
||||
}
|
||||
|
||||
void SectionContent::setTitle(const QString& title)
|
||||
{
|
||||
_title = title;
|
||||
}
|
||||
|
||||
void SectionContent::setFlags(const Flags f)
|
||||
{
|
||||
_flags = f;
|
||||
}
|
||||
|
||||
int SectionContent::GetNextUid()
|
||||
{
|
||||
static int NextUid = 0;
|
||||
return ++NextUid;
|
||||
}
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
@@ -1,23 +0,0 @@
|
||||
#include "ads/SectionContentWidget.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
|
||||
SectionContentWidget::SectionContentWidget(SectionContent::RefPtr c, QWidget* parent) :
|
||||
QFrame(parent),
|
||||
_content(c)
|
||||
{
|
||||
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
l->setSpacing(0);
|
||||
l->addWidget(_content->contentWidget());
|
||||
setLayout(l);
|
||||
}
|
||||
|
||||
SectionContentWidget::~SectionContentWidget()
|
||||
{
|
||||
layout()->removeWidget(_content->contentWidget());
|
||||
}
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
@@ -1,291 +0,0 @@
|
||||
#include "ads/SectionTitleWidget.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QApplication>
|
||||
#include <QBoxLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QMimeData>
|
||||
#include <QDrag>
|
||||
#include <QCursor>
|
||||
#include <QStyle>
|
||||
#include <QSplitter>
|
||||
|
||||
#ifdef ADS_ANIMATIONS_ENABLED
|
||||
#include <QPropertyAnimation>
|
||||
#include <QParallelAnimationGroup>
|
||||
#endif
|
||||
|
||||
#include "ads/Internal.h"
|
||||
#include "ads/DropOverlay.h"
|
||||
#include "ads/SectionContent.h"
|
||||
#include "ads/SectionWidget.h"
|
||||
#include "ads/FloatingWidget.h"
|
||||
#include "ads/ContainerWidget.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
|
||||
SectionTitleWidget::SectionTitleWidget(SectionContent::RefPtr content, QWidget* parent) :
|
||||
QFrame(parent),
|
||||
_content(content),
|
||||
_tabMoving(false),
|
||||
_activeTab(false)
|
||||
{
|
||||
QBoxLayout* l = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
l->setSpacing(0);
|
||||
l->addWidget(content->titleWidget());
|
||||
setLayout(l);
|
||||
}
|
||||
|
||||
SectionTitleWidget::~SectionTitleWidget()
|
||||
{
|
||||
layout()->removeWidget(_content->titleWidget());
|
||||
}
|
||||
|
||||
bool SectionTitleWidget::isActiveTab() const
|
||||
{
|
||||
return _activeTab;
|
||||
}
|
||||
|
||||
void SectionTitleWidget::setActiveTab(bool active)
|
||||
{
|
||||
if (active != _activeTab)
|
||||
{
|
||||
_activeTab = active;
|
||||
|
||||
style()->unpolish(this);
|
||||
style()->polish(this);
|
||||
update();
|
||||
|
||||
emit activeTabChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SectionTitleWidget::mousePressEvent(QMouseEvent* ev)
|
||||
{
|
||||
if (ev->button() == Qt::LeftButton)
|
||||
{
|
||||
ev->accept();
|
||||
_dragStartPos = ev->pos();
|
||||
return;
|
||||
}
|
||||
QFrame::mousePressEvent(ev);
|
||||
}
|
||||
|
||||
void SectionTitleWidget::mouseReleaseEvent(QMouseEvent* ev)
|
||||
{
|
||||
SectionWidget* section = NULL;
|
||||
ContainerWidget* cw = findParentContainerWidget(this);
|
||||
|
||||
// Drop contents of FloatingWidget into SectionWidget.
|
||||
if (_fw)
|
||||
{
|
||||
SectionWidget* sw = cw->sectionAt(cw->mapFromGlobal(ev->globalPos()));
|
||||
if (sw)
|
||||
{
|
||||
cw->_dropOverlay->setAllowedAreas(ADS_NS::AllAreas);
|
||||
DropArea loc = cw->_dropOverlay->showDropOverlay(sw);
|
||||
if (loc != InvalidDropArea)
|
||||
{
|
||||
#if !defined(ADS_ANIMATIONS_ENABLED)
|
||||
InternalContentData data;
|
||||
_fw->takeContent(data);
|
||||
_fw->deleteLater();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
_fw.clear();
|
||||
#else
|
||||
_fw = 0;
|
||||
#endif
|
||||
cw->dropContent(data, sw, loc, true);
|
||||
#else
|
||||
QPropertyAnimation* moveAnim = new QPropertyAnimation(_fw, "pos", this);
|
||||
moveAnim->setStartValue(_fw->pos());
|
||||
moveAnim->setEndValue(sw->mapToGlobal(sw->rect().topLeft()));
|
||||
moveAnim->setDuration(ADS_ANIMATION_DURATION);
|
||||
|
||||
QPropertyAnimation* resizeAnim = new QPropertyAnimation(_fw, "size", this);
|
||||
resizeAnim->setStartValue(_fw->size());
|
||||
resizeAnim->setEndValue(sw->size());
|
||||
resizeAnim->setDuration(ADS_ANIMATION_DURATION);
|
||||
|
||||
QParallelAnimationGroup* animGroup = new QParallelAnimationGroup(this);
|
||||
QObject::connect(animGroup, &QPropertyAnimation::finished, [this, data, sw, loc]()
|
||||
{
|
||||
InternalContentData data = _fw->takeContent();
|
||||
_fw->deleteLater();
|
||||
_fw.clear();
|
||||
cw->dropContent(data, sw, loc);
|
||||
});
|
||||
animGroup->addAnimation(moveAnim);
|
||||
animGroup->addAnimation(resizeAnim);
|
||||
animGroup->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// Mouse is over a outer-edge drop area
|
||||
else
|
||||
{
|
||||
DropArea dropArea = ADS_NS::InvalidDropArea;
|
||||
if (cw->outerTopDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
|
||||
dropArea = ADS_NS::TopDropArea;
|
||||
if (cw->outerRightDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
|
||||
dropArea = ADS_NS::RightDropArea;
|
||||
if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
|
||||
dropArea = ADS_NS::BottomDropArea;
|
||||
if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(ev->globalPos())))
|
||||
dropArea = ADS_NS::LeftDropArea;
|
||||
|
||||
if (dropArea != ADS_NS::InvalidDropArea)
|
||||
{
|
||||
#if !defined(ADS_ANIMATIONS_ENABLED)
|
||||
InternalContentData data;
|
||||
_fw->takeContent(data);
|
||||
_fw->deleteLater();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
_fw.clear();
|
||||
#else
|
||||
_fw = 0;
|
||||
#endif
|
||||
cw->dropContent(data, NULL, dropArea, true);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
// End of tab moving, change order now
|
||||
else if (_tabMoving
|
||||
&& (section = findParentSectionWidget(this)) != NULL)
|
||||
{
|
||||
// Find tab under mouse
|
||||
QPoint pos = ev->globalPos();
|
||||
pos = section->mapFromGlobal(pos);
|
||||
const int fromIndex = section->indexOfContent(_content);
|
||||
const int toIndex = section->indexOfContentByTitlePos(pos, this);
|
||||
section->moveContent(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
if (!_dragStartPos.isNull())
|
||||
emit clicked();
|
||||
|
||||
// Reset
|
||||
_dragStartPos = QPoint();
|
||||
_tabMoving = false;
|
||||
cw->_dropOverlay->hideDropOverlay();
|
||||
QFrame::mouseReleaseEvent(ev);
|
||||
}
|
||||
|
||||
void SectionTitleWidget::mouseMoveEvent(QMouseEvent* ev)
|
||||
{
|
||||
ContainerWidget* cw = findParentContainerWidget(this);
|
||||
SectionWidget* section = NULL;
|
||||
|
||||
// Move already existing FloatingWidget
|
||||
if (_fw && (ev->buttons() & Qt::LeftButton))
|
||||
{
|
||||
ev->accept();
|
||||
|
||||
const QPoint moveToPos = ev->globalPos() - (_dragStartPos + QPoint(ADS_WINDOW_FRAME_BORDER_WIDTH, ADS_WINDOW_FRAME_BORDER_WIDTH));
|
||||
_fw->move(moveToPos);
|
||||
|
||||
// Show drop indicator
|
||||
if (true)
|
||||
{
|
||||
// Mouse is over a SectionWidget
|
||||
section = cw->sectionAt(cw->mapFromGlobal(QCursor::pos()));
|
||||
if (section)
|
||||
{
|
||||
cw->_dropOverlay->setAllowedAreas(ADS_NS::AllAreas);
|
||||
cw->_dropOverlay->showDropOverlay(section);
|
||||
}
|
||||
// Mouse is at the edge of the ContainerWidget
|
||||
// Top, Right, Bottom, Left
|
||||
else if (cw->outerTopDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
|
||||
{
|
||||
cw->_dropOverlay->setAllowedAreas(ADS_NS::TopDropArea);
|
||||
cw->_dropOverlay->showDropOverlay(cw, cw->outerTopDropRect());
|
||||
}
|
||||
else if (cw->outerRightDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
|
||||
{
|
||||
cw->_dropOverlay->setAllowedAreas(ADS_NS::RightDropArea);
|
||||
cw->_dropOverlay->showDropOverlay(cw, cw->outerRightDropRect());
|
||||
}
|
||||
else if (cw->outerBottomDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
|
||||
{
|
||||
cw->_dropOverlay->setAllowedAreas(ADS_NS::BottomDropArea);
|
||||
cw->_dropOverlay->showDropOverlay(cw, cw->outerBottomDropRect());
|
||||
}
|
||||
else if (cw->outerLeftDropRect().contains(cw->mapFromGlobal(QCursor::pos())))
|
||||
{
|
||||
cw->_dropOverlay->setAllowedAreas(ADS_NS::LeftDropArea);
|
||||
cw->_dropOverlay->showDropOverlay(cw, cw->outerLeftDropRect());
|
||||
}
|
||||
else
|
||||
{
|
||||
cw->_dropOverlay->hideDropOverlay();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Begin to drag/float the SectionContent.
|
||||
else if (!_fw && !_dragStartPos.isNull() && (ev->buttons() & Qt::LeftButton)
|
||||
&& (section = findParentSectionWidget(this)) != NULL
|
||||
&& !section->titleAreaGeometry().contains(section->mapFromGlobal(ev->globalPos())))
|
||||
{
|
||||
ev->accept();
|
||||
|
||||
// Create floating widget.
|
||||
InternalContentData data;
|
||||
if (!section->takeContent(_content->uid(), data))
|
||||
{
|
||||
qWarning() << "THIS SHOULD NOT HAPPEN!!" << _content->uid() << _content->uniqueName();
|
||||
return;
|
||||
}
|
||||
|
||||
_fw = new FloatingWidget(cw, data.content, data.titleWidget, data.contentWidget, cw);
|
||||
_fw->resize(section->size());
|
||||
cw->_floatings.append(_fw); // Note: I don't like this...
|
||||
|
||||
const QPoint moveToPos = ev->globalPos() - (_dragStartPos + QPoint(ADS_WINDOW_FRAME_BORDER_WIDTH, ADS_WINDOW_FRAME_BORDER_WIDTH));
|
||||
_fw->move(moveToPos);
|
||||
_fw->show();
|
||||
|
||||
// Delete old section, if it is empty now.
|
||||
if (section->contents().isEmpty())
|
||||
{
|
||||
delete section;
|
||||
section = NULL;
|
||||
}
|
||||
deleteEmptySplitter(cw);
|
||||
return;
|
||||
}
|
||||
// Handle movement of this tab
|
||||
else if (_tabMoving
|
||||
&& (section = findParentSectionWidget(this)) != NULL)
|
||||
{
|
||||
ev->accept();
|
||||
|
||||
int left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
QPoint moveToPos = mapToParent(ev->pos()) - _dragStartPos;
|
||||
moveToPos.setY(0/* + top*/);
|
||||
move(moveToPos);
|
||||
|
||||
return;
|
||||
}
|
||||
// Begin to drag title inside the title area to switch its position inside the SectionWidget.
|
||||
else if (!_dragStartPos.isNull() && (ev->buttons() & Qt::LeftButton)
|
||||
&& (ev->pos() - _dragStartPos).manhattanLength() >= QApplication::startDragDistance() // Wait a few pixels before start moving
|
||||
&& (section = findParentSectionWidget(this)) != NULL
|
||||
&& section->titleAreaGeometry().contains(section->mapFromGlobal(ev->globalPos())))
|
||||
{
|
||||
ev->accept();
|
||||
|
||||
_tabMoving = true;
|
||||
raise(); // Raise current title-widget above other tabs
|
||||
|
||||
return;
|
||||
}
|
||||
QFrame::mouseMoveEvent(ev);
|
||||
}
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
@@ -1,458 +0,0 @@
|
||||
#include "ads/SectionWidget.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QBoxLayout>
|
||||
#include <QStackedLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QWheelEvent>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QMimeData>
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
#include <QSplitter>
|
||||
#include <QPushButton>
|
||||
#include <QScrollBar>
|
||||
#include <QMenu>
|
||||
|
||||
#if defined(ADS_ANIMATIONS_ENABLED)
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
#endif
|
||||
|
||||
#include "ads/Internal.h"
|
||||
#include "ads/DropOverlay.h"
|
||||
#include "ads/SectionContent.h"
|
||||
#include "ads/SectionTitleWidget.h"
|
||||
#include "ads/SectionContentWidget.h"
|
||||
#include "ads/FloatingWidget.h"
|
||||
#include "ads/ContainerWidget.h"
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
|
||||
SectionWidget::SectionWidget(ContainerWidget* parent) :
|
||||
QFrame(parent),
|
||||
_uid(GetNextUid()),
|
||||
_container(parent),
|
||||
_tabsLayout(NULL),
|
||||
_tabsLayoutInitCount(0),
|
||||
_contentsLayout(NULL),
|
||||
_mousePressTitleWidget(NULL)
|
||||
{
|
||||
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
l->setSpacing(0);
|
||||
setLayout(l);
|
||||
|
||||
/* top area with tabs and close button */
|
||||
|
||||
_topLayout = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
_topLayout->setContentsMargins(0, 0, 0, 0);
|
||||
_topLayout->setSpacing(0);
|
||||
l->addLayout(_topLayout);
|
||||
|
||||
_tabsScrollArea = new SectionWidgetTabsScrollArea(this);
|
||||
_topLayout->addWidget(_tabsScrollArea, 1);
|
||||
|
||||
_tabsContainerWidget = new QWidget();
|
||||
_tabsContainerWidget->setObjectName("tabsContainerWidget");
|
||||
_tabsScrollArea->setWidget(_tabsContainerWidget);
|
||||
|
||||
_tabsLayout = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
_tabsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
_tabsLayout->setSpacing(0);
|
||||
_tabsLayout->addStretch(1);
|
||||
_tabsContainerWidget->setLayout(_tabsLayout);
|
||||
|
||||
_tabsMenuButton = new QPushButton();
|
||||
_tabsMenuButton->setObjectName("tabsMenuButton");
|
||||
_tabsMenuButton->setFlat(true);
|
||||
_tabsMenuButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarUnshadeButton));
|
||||
_tabsMenuButton->setMaximumWidth(_tabsMenuButton->iconSize().width());
|
||||
_topLayout->addWidget(_tabsMenuButton, 0);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
//QObject::connect(_tabsMenuButton, &QPushButton::clicked, this, &SectionWidget::onTabsMenuButtonClicked);
|
||||
#else
|
||||
//QObject::connect(_tabsMenuButton, SIGNAL(clicked()), this, SLOT(onTabsMenuButtonClicked()));
|
||||
#endif
|
||||
|
||||
_closeButton = new QPushButton();
|
||||
_closeButton->setObjectName("closeButton");
|
||||
_closeButton->setFlat(true);
|
||||
_closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
|
||||
_closeButton->setToolTip(tr("Close"));
|
||||
_closeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
_topLayout->addWidget(_closeButton, 0);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QObject::connect(_closeButton, &QPushButton::clicked, this, &SectionWidget::onCloseButtonClicked);
|
||||
#else
|
||||
QObject::connect(_closeButton, SIGNAL(clicked(bool)), this, SLOT(onCloseButtonClicked()));
|
||||
#endif
|
||||
|
||||
_tabsLayoutInitCount = _tabsLayout->count();
|
||||
|
||||
/* central area with contents */
|
||||
|
||||
_contentsLayout = new QStackedLayout();
|
||||
_contentsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
_contentsLayout->setSpacing(0);
|
||||
l->addLayout(_contentsLayout, 1);
|
||||
|
||||
#if defined(ADS_ANIMATIONS_ENABLED)
|
||||
QGraphicsDropShadowEffect* shadow = new QGraphicsDropShadowEffect(this);
|
||||
shadow->setOffset(0, 0);
|
||||
shadow->setBlurRadius(8);
|
||||
setGraphicsEffect(shadow);
|
||||
#endif
|
||||
|
||||
SWLookupMapById(_container).insert(_uid, this);
|
||||
}
|
||||
|
||||
SectionWidget::~SectionWidget()
|
||||
{
|
||||
if (_container)
|
||||
{
|
||||
SWLookupMapById(_container).remove(_uid);
|
||||
_container->_sections.removeAll(this); // Note: I don't like this here, but we have to remove it from list...
|
||||
}
|
||||
|
||||
// Delete empty QSplitter.
|
||||
QSplitter* splitter = findParentSplitter(this);
|
||||
if (splitter && splitter->count() == 0)
|
||||
{
|
||||
splitter->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
int SectionWidget::uid() const
|
||||
{
|
||||
return _uid;
|
||||
}
|
||||
|
||||
ContainerWidget* SectionWidget::containerWidget() const
|
||||
{
|
||||
return _container;
|
||||
}
|
||||
|
||||
QRect SectionWidget::titleAreaGeometry() const
|
||||
{
|
||||
return _topLayout->geometry();
|
||||
}
|
||||
|
||||
QRect SectionWidget::contentAreaGeometry() const
|
||||
{
|
||||
return _contentsLayout->geometry();
|
||||
}
|
||||
|
||||
void SectionWidget::addContent(const SectionContent::RefPtr& c)
|
||||
{
|
||||
_contents.append(c);
|
||||
|
||||
SectionTitleWidget* title = new SectionTitleWidget(c, NULL);
|
||||
_sectionTitles.append(title);
|
||||
_tabsLayout->insertWidget(_tabsLayout->count() - _tabsLayoutInitCount, title);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QObject::connect(title, &SectionTitleWidget::clicked, this, &SectionWidget::onSectionTitleClicked);
|
||||
#else
|
||||
QObject::connect(title, SIGNAL(clicked()), this, SLOT(onSectionTitleClicked()));
|
||||
#endif
|
||||
|
||||
SectionContentWidget* content = new SectionContentWidget(c, NULL);
|
||||
_sectionContents.append(content);
|
||||
_contentsLayout->addWidget(content);
|
||||
|
||||
// Active first TAB.
|
||||
if (_contents.size() == 1)
|
||||
setCurrentIndex(0);
|
||||
// Switch to newest.
|
||||
// else
|
||||
// setCurrentIndex(_contentsLayout->count() - 1);
|
||||
|
||||
updateTabsMenu();
|
||||
}
|
||||
|
||||
void SectionWidget::addContent(const InternalContentData& data, bool autoActivate)
|
||||
{
|
||||
_contents.append(data.content);
|
||||
|
||||
// Add title-widget to tab-bar
|
||||
// #FIX: Make it visible, since it is possible that it was hidden previously.
|
||||
_sectionTitles.append(data.titleWidget);
|
||||
_tabsLayout->insertWidget(_tabsLayout->count() - _tabsLayoutInitCount, data.titleWidget);
|
||||
data.titleWidget->setVisible(true);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QObject::connect(data.titleWidget, &SectionTitleWidget::clicked, this, &SectionWidget::onSectionTitleClicked);
|
||||
#else
|
||||
QObject::connect(data.titleWidget, SIGNAL(clicked()), this, SLOT(onSectionTitleClicked()));
|
||||
#endif
|
||||
|
||||
// Add content-widget to stack.
|
||||
// Visibility is managed by QStackedWidget.
|
||||
_sectionContents.append(data.contentWidget);
|
||||
_contentsLayout->addWidget(data.contentWidget);
|
||||
|
||||
// Activate first TAB.
|
||||
if (_contents.size() == 1)
|
||||
setCurrentIndex(0);
|
||||
// Switch to just added TAB.
|
||||
else if (autoActivate)
|
||||
setCurrentIndex(_contents.count() - 1);
|
||||
// Mark it as inactive tab.
|
||||
else
|
||||
data.titleWidget->setActiveTab(false); // or: setCurrentIndex(currentIndex())
|
||||
|
||||
updateTabsMenu();
|
||||
}
|
||||
|
||||
bool SectionWidget::takeContent(int uid, InternalContentData& data)
|
||||
{
|
||||
// Find SectionContent.
|
||||
SectionContent::RefPtr sc;
|
||||
int index = -1;
|
||||
for (int i = 0; i < _contents.count(); i++)
|
||||
{
|
||||
if (_contents[i]->uid() != uid)
|
||||
continue;
|
||||
index = i;
|
||||
sc = _contents.takeAt(i);
|
||||
break;
|
||||
}
|
||||
if (!sc)
|
||||
return false;
|
||||
|
||||
// Title wrapper widget (TAB)
|
||||
SectionTitleWidget* title = _sectionTitles.takeAt(index);
|
||||
if (title)
|
||||
{
|
||||
_tabsLayout->removeWidget(title);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
title->setAttribute(Qt::WA_WState_Created, false); /* fix: floating rubberband #16 */
|
||||
#endif
|
||||
title->disconnect(this);
|
||||
title->setParent(_container);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
title->setAttribute(Qt::WA_WState_Created, true); /* fix: floating rubberband #16 */
|
||||
#endif
|
||||
}
|
||||
|
||||
// Content wrapper widget (CONTENT)
|
||||
SectionContentWidget* content = _sectionContents.takeAt(index);
|
||||
if (content)
|
||||
{
|
||||
_contentsLayout->removeWidget(content);
|
||||
content->disconnect(this);
|
||||
content->setParent(_container);
|
||||
}
|
||||
|
||||
// Select the previous tab as activeTab.
|
||||
if (_contents.size() > 0 && title->isActiveTab())
|
||||
{
|
||||
if (index > 0)
|
||||
setCurrentIndex(index - 1);
|
||||
else
|
||||
setCurrentIndex(0);
|
||||
}
|
||||
|
||||
updateTabsMenu();
|
||||
|
||||
data.content = sc;
|
||||
data.titleWidget = title;
|
||||
data.contentWidget = content;
|
||||
return !data.content.isNull();
|
||||
}
|
||||
|
||||
int SectionWidget::indexOfContent(const SectionContent::RefPtr& c) const
|
||||
{
|
||||
return _contents.indexOf(c);
|
||||
}
|
||||
|
||||
int SectionWidget::indexOfContentByUid(int uid) const
|
||||
{
|
||||
for (int i = 0; i < _contents.count(); ++i)
|
||||
{
|
||||
if (_contents[i]->uid() == uid)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SectionWidget::indexOfContentByTitlePos(const QPoint& p, QWidget* exclude) const
|
||||
{
|
||||
int index = -1;
|
||||
for (int i = 0; i < _sectionTitles.size(); ++i)
|
||||
{
|
||||
if (_sectionTitles[i]->geometry().contains(p) && (exclude == NULL || _sectionTitles[i] != exclude))
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
int SectionWidget::currentIndex() const
|
||||
{
|
||||
return _contentsLayout->currentIndex();
|
||||
}
|
||||
|
||||
void SectionWidget::moveContent(int from, int to)
|
||||
{
|
||||
if (from >= _contents.size() || from < 0 || to >= _contents.size() || to < 0 || from == to)
|
||||
{
|
||||
qDebug() << "Invalid index for tab movement" << from << to;
|
||||
_tabsLayout->update();
|
||||
return;
|
||||
}
|
||||
|
||||
_contents.move(from, to);
|
||||
_sectionTitles.move(from, to);
|
||||
_sectionContents.move(from, to);
|
||||
|
||||
QLayoutItem* liFrom = NULL;
|
||||
liFrom = _tabsLayout->takeAt(from);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
_tabsLayout->insertItem(to, liFrom);
|
||||
#else
|
||||
_tabsLayout->insertWidget(to, liFrom->widget());
|
||||
delete liFrom;
|
||||
liFrom = NULL;
|
||||
#endif
|
||||
|
||||
liFrom = _contentsLayout->takeAt(from);
|
||||
_contentsLayout->insertWidget(to, liFrom->widget());
|
||||
delete liFrom;
|
||||
|
||||
updateTabsMenu();
|
||||
}
|
||||
|
||||
void SectionWidget::showEvent(QShowEvent*)
|
||||
{
|
||||
_tabsScrollArea->ensureWidgetVisible(_sectionTitles.at(currentIndex()));
|
||||
}
|
||||
|
||||
void SectionWidget::setCurrentIndex(int index)
|
||||
{
|
||||
if (index < 0 || index > _contents.count() - 1)
|
||||
{
|
||||
qWarning() << Q_FUNC_INFO << "Invalid index" << index;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set active TAB
|
||||
for (int i = 0; i < _tabsLayout->count(); ++i)
|
||||
{
|
||||
QLayoutItem* item = _tabsLayout->itemAt(i);
|
||||
if (item->widget())
|
||||
{
|
||||
SectionTitleWidget* stw = dynamic_cast<SectionTitleWidget*>(item->widget());
|
||||
if (stw)
|
||||
{
|
||||
if (i == index)
|
||||
{
|
||||
stw->setActiveTab(true);
|
||||
_tabsScrollArea->ensureWidgetVisible(stw);
|
||||
if (stw->_content->flags().testFlag(SectionContent::Closeable))
|
||||
_closeButton->setEnabled(true);
|
||||
else
|
||||
_closeButton->setEnabled(false);
|
||||
}
|
||||
else
|
||||
stw->setActiveTab(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set active CONTENT
|
||||
_contentsLayout->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
void SectionWidget::onSectionTitleClicked()
|
||||
{
|
||||
SectionTitleWidget* stw = qobject_cast<SectionTitleWidget*>(sender());
|
||||
if (stw)
|
||||
{
|
||||
int index = _tabsLayout->indexOf(stw);
|
||||
setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
void SectionWidget::onCloseButtonClicked()
|
||||
{
|
||||
const int index = currentIndex();
|
||||
if (index < 0 || index > _contents.size() - 1)
|
||||
return;
|
||||
SectionContent::RefPtr sc = _contents.at(index);
|
||||
if (sc.isNull())
|
||||
return;
|
||||
_container->hideSectionContent(sc);
|
||||
}
|
||||
|
||||
void SectionWidget::onTabsMenuActionTriggered(bool)
|
||||
{
|
||||
QAction* a = qobject_cast<QAction*>(sender());
|
||||
if (a)
|
||||
{
|
||||
const int uid = a->data().toInt();
|
||||
const int index = indexOfContentByUid(uid);
|
||||
if (index >= 0)
|
||||
setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
void SectionWidget::updateTabsMenu()
|
||||
{
|
||||
QMenu* m = new QMenu();
|
||||
for (int i = 0; i < _contents.count(); ++i)
|
||||
{
|
||||
const SectionContent::RefPtr& sc = _contents.at(i);
|
||||
QAction* a = m->addAction(QIcon(), sc->visibleTitle());
|
||||
a->setData(sc->uid());
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QObject::connect(a, &QAction::triggered, this, &SectionWidget::onTabsMenuActionTriggered);
|
||||
#else
|
||||
QObject::connect(a, SIGNAL(triggered(bool)), this, SLOT(onTabsMenuActionTriggered(bool)));
|
||||
#endif
|
||||
}
|
||||
QMenu* old = _tabsMenuButton->menu();
|
||||
_tabsMenuButton->setMenu(m);
|
||||
delete old;
|
||||
}
|
||||
|
||||
int SectionWidget::GetNextUid()
|
||||
{
|
||||
static int NextUid = 0;
|
||||
return ++NextUid;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
SectionWidgetTabsScrollArea::SectionWidgetTabsScrollArea(SectionWidget*,
|
||||
QWidget* parent) :
|
||||
QScrollArea(parent)
|
||||
{
|
||||
/* Important: QSizePolicy::Ignored makes the QScrollArea behaves
|
||||
like a QLabel and automatically fits into the layout. */
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored);
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
setWidgetResizable(true);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
}
|
||||
|
||||
SectionWidgetTabsScrollArea::~SectionWidgetTabsScrollArea()
|
||||
{
|
||||
}
|
||||
|
||||
void SectionWidgetTabsScrollArea::wheelEvent(QWheelEvent* e)
|
||||
{
|
||||
e->accept();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
const int direction = e->angleDelta().y();
|
||||
#else
|
||||
const int direction = e->delta();
|
||||
#endif
|
||||
if (direction < 0)
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + 20);
|
||||
else
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - 20);
|
||||
}
|
||||
|
||||
ADS_NAMESPACE_END
|
||||
@@ -1,440 +0,0 @@
|
||||
#include "ads/Serialization.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
ADS_NAMESPACE_SER_BEGIN
|
||||
|
||||
/*
|
||||
\namespace ads::serialization
|
||||
|
||||
Serialization of ContainerWidget
|
||||
--------------------------------
|
||||
|
||||
# Data Format Header
|
||||
|
||||
quint32 Magic
|
||||
quint32 Major Version
|
||||
quint32 Minor Version
|
||||
|
||||
# Offsets of available contents
|
||||
|
||||
qint32 Number of offset headers
|
||||
LOOP
|
||||
qint32 Type (e.g. Hierachy, SectionIndex)
|
||||
qint64 Offset
|
||||
qint64 Length
|
||||
|
||||
# Type: Hierachy
|
||||
# Used to recreate the GUI geometry and state.
|
||||
|
||||
int Number of floating widgets
|
||||
LOOP Floating widgets
|
||||
QString Unique name of content
|
||||
QByteArray Geometry of floating widget
|
||||
bool Visibility
|
||||
|
||||
int Number of layout items (Valid values: 0, 1)
|
||||
IF 0
|
||||
int Number of hidden contents
|
||||
LOOP Contents
|
||||
QString Unique name of content
|
||||
ELSEIF 1
|
||||
... todo ...
|
||||
ENDIF
|
||||
|
||||
# Type: SectionIndex
|
||||
# Can be used for quick lookups on details for SectionWidgets.
|
||||
# It includes sizes and its contents.
|
||||
|
||||
qint32 Number of section-widgets
|
||||
LOOP
|
||||
qint32 Width
|
||||
qint32 Height
|
||||
qint32 Current active tab index
|
||||
qint32 Number of contents
|
||||
LOOP
|
||||
QString Unique name of content
|
||||
bool Visibility
|
||||
qint32 Preferred tab index
|
||||
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
qint32 HeaderEntity::MAGIC = 0x00001337;
|
||||
qint32 HeaderEntity::MAJOR_VERSION = 2;
|
||||
qint32 HeaderEntity::MINOR_VERSION = 0;
|
||||
|
||||
HeaderEntity::HeaderEntity() :
|
||||
magic(0), majorVersion(0), minorVersion(0)
|
||||
{
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& out, const HeaderEntity& data)
|
||||
{
|
||||
out << data.magic;
|
||||
out << data.majorVersion;
|
||||
out << data.minorVersion;
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& in, HeaderEntity& data)
|
||||
{
|
||||
in >> data.magic;
|
||||
in >> data.majorVersion;
|
||||
in >> data.minorVersion;
|
||||
return in;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
OffsetsHeaderEntity::OffsetsHeaderEntity() :
|
||||
entriesCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& out, const OffsetsHeaderEntity& data)
|
||||
{
|
||||
out << data.entriesCount;
|
||||
for (int i = 0; i < data.entriesCount; ++i)
|
||||
{
|
||||
out << data.entries.at(i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& in, OffsetsHeaderEntity& data)
|
||||
{
|
||||
in >> data.entriesCount;
|
||||
for (int i = 0; i < data.entriesCount; ++i)
|
||||
{
|
||||
OffsetsHeaderEntryEntity entry;
|
||||
in >> entry;
|
||||
data.entries.append(entry);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
OffsetsHeaderEntryEntity::OffsetsHeaderEntryEntity() :
|
||||
type(ET_Unknown), offset(0), contentSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& out, const OffsetsHeaderEntryEntity& data)
|
||||
{
|
||||
out << data.type;
|
||||
out << data.offset;
|
||||
out << data.contentSize;
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& in, OffsetsHeaderEntryEntity& data)
|
||||
{
|
||||
in >> data.type;
|
||||
in >> data.offset;
|
||||
in >> data.contentSize;
|
||||
return in;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SectionEntity::SectionEntity() :
|
||||
x(0), y(0), width(0), height(0), currentIndex(0), sectionContentsCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& out, const SectionEntity& data)
|
||||
{
|
||||
out << data.x;
|
||||
out << data.y;
|
||||
out << data.width;
|
||||
out << data.height;
|
||||
out << data.currentIndex;
|
||||
out << data.sectionContentsCount;
|
||||
for (int i = 0; i < data.sectionContentsCount; ++i)
|
||||
{
|
||||
out << data.sectionContents.at(i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& in, SectionEntity& data)
|
||||
{
|
||||
in >> data.x;
|
||||
in >> data.y;
|
||||
in >> data.width;
|
||||
in >> data.height;
|
||||
in >> data.currentIndex;
|
||||
in >> data.sectionContentsCount;
|
||||
for (int i = 0; i < data.sectionContentsCount; ++i)
|
||||
{
|
||||
SectionContentEntity sc;
|
||||
in >> sc;
|
||||
data.sectionContents.append(sc);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SectionContentEntity::SectionContentEntity() :
|
||||
visible(false), preferredIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& out, const SectionContentEntity& data)
|
||||
{
|
||||
out << data.uniqueName;
|
||||
out << data.visible;
|
||||
out << data.preferredIndex;
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& in, SectionContentEntity& data)
|
||||
{
|
||||
in >> data.uniqueName;
|
||||
in >> data.visible;
|
||||
in >> data.preferredIndex;
|
||||
return in;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FloatingContentEntity::FloatingContentEntity() :
|
||||
xpos(0), ypos(0), width(0), height(0), visible(false)
|
||||
{
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& out, const FloatingContentEntity& data)
|
||||
{
|
||||
out << data.uniqueName;
|
||||
out << data.xpos;
|
||||
out << data.ypos;
|
||||
out << data.width;
|
||||
out << data.height;
|
||||
out << data.visible;
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& in, FloatingContentEntity& data)
|
||||
{
|
||||
in >> data.uniqueName;
|
||||
in >> data.xpos;
|
||||
in >> data.ypos;
|
||||
in >> data.width;
|
||||
in >> data.height;
|
||||
in >> data.visible;
|
||||
return in;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HierarchyData::HierarchyData()
|
||||
{
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& out, const HierarchyData& data)
|
||||
{
|
||||
out << data.data;
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& in, HierarchyData& data)
|
||||
{
|
||||
in >> data.data;
|
||||
return in;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SectionIndexData::SectionIndexData() :
|
||||
sectionsCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& out, const SectionIndexData& data)
|
||||
{
|
||||
out << data.sectionsCount;
|
||||
for (int i = 0; i < data.sectionsCount; ++i)
|
||||
{
|
||||
out << data.sections.at(i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& in, SectionIndexData& data)
|
||||
{
|
||||
in >> data.sectionsCount;
|
||||
for (int i = 0; i < data.sectionsCount; ++i)
|
||||
{
|
||||
SectionEntity s;
|
||||
in >> s;
|
||||
data.sections.append(s);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
InMemoryWriter::InMemoryWriter()
|
||||
{
|
||||
_contentBuffer.open(QIODevice::ReadWrite);
|
||||
}
|
||||
|
||||
bool InMemoryWriter::write(qint32 entryType, const QByteArray& data)
|
||||
{
|
||||
OffsetsHeaderEntryEntity entry;
|
||||
entry.type = entryType;
|
||||
entry.offset = _contentBuffer.pos(); // Relative offset!
|
||||
entry.contentSize = data.size();
|
||||
|
||||
_contentBuffer.write(data);
|
||||
|
||||
_offsetsHeader.entries.append(entry);
|
||||
_offsetsHeader.entriesCount += 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InMemoryWriter::write(const SectionIndexData& data)
|
||||
{
|
||||
OffsetsHeaderEntryEntity entry;
|
||||
entry.type = ET_SectionIndex;
|
||||
entry.offset = _contentBuffer.pos(); // Relative offset!
|
||||
|
||||
QDataStream out(&_contentBuffer);
|
||||
out.setVersion(QDataStream::Qt_4_5);
|
||||
out << data;
|
||||
|
||||
entry.contentSize = _contentBuffer.size() - entry.offset;
|
||||
|
||||
_offsetsHeader.entries.append(entry);
|
||||
_offsetsHeader.entriesCount += 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QByteArray InMemoryWriter::toByteArray() const
|
||||
{
|
||||
QByteArray data;
|
||||
QDataStream out(&data, QIODevice::ReadWrite);
|
||||
out.setVersion(QDataStream::Qt_4_5);
|
||||
|
||||
// Basic format header.
|
||||
HeaderEntity header;
|
||||
header.magic = HeaderEntity::MAGIC;
|
||||
header.majorVersion = HeaderEntity::MAJOR_VERSION;
|
||||
header.minorVersion = HeaderEntity::MINOR_VERSION;
|
||||
out << header;
|
||||
|
||||
// Offsets-Header
|
||||
// - Save begin pos
|
||||
// - Write OffsetsHeader
|
||||
// - Convert relative- to absolute-offsets
|
||||
// - Seek back to begin-pos and write OffsetsHeader again.
|
||||
// Use a copy of OffsetsHeader to keep the _offsetsHeader relative.
|
||||
const qint64 posOffsetHeaders = out.device()->pos();
|
||||
OffsetsHeaderEntity offsetsHeader = _offsetsHeader;
|
||||
out << offsetsHeader;
|
||||
|
||||
// Now we know the size of the entire header.
|
||||
// We can update the relative- to absolute-offsets now.
|
||||
const qint64 allHeaderSize = out.device()->pos();
|
||||
for (int i = 0; i < offsetsHeader.entriesCount; ++i)
|
||||
{
|
||||
offsetsHeader.entries[i].offset += allHeaderSize; // Absolute offset!
|
||||
}
|
||||
|
||||
// Seek back and write again with absolute offsets.
|
||||
// TODO Thats not nice, but it works...
|
||||
out.device()->seek(posOffsetHeaders);
|
||||
out << offsetsHeader;
|
||||
|
||||
// Write contents.
|
||||
out.writeRawData(_contentBuffer.data().constData(), _contentBuffer.size());
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
InMemoryReader::InMemoryReader(const QByteArray& data) :
|
||||
_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
bool InMemoryReader::initReadHeader()
|
||||
{
|
||||
QDataStream in(_data);
|
||||
in.setVersion(QDataStream::Qt_4_5);
|
||||
|
||||
// Basic format header.
|
||||
HeaderEntity header;
|
||||
in >> header;
|
||||
if (header.magic != HeaderEntity::MAGIC)
|
||||
{
|
||||
qWarning() << QString("invalid format (magic=%1)").arg(header.magic);
|
||||
return false;
|
||||
}
|
||||
if (header.majorVersion != HeaderEntity::MAJOR_VERSION)
|
||||
{
|
||||
qWarning() << QString("format is too new (major=%1; minor=%2)")
|
||||
.arg(header.majorVersion).arg(header.minorVersion);
|
||||
return false;
|
||||
}
|
||||
|
||||
// OffsetsHeader.
|
||||
in >> _offsetsHeader;
|
||||
|
||||
return !in.atEnd();
|
||||
}
|
||||
|
||||
bool InMemoryReader::read(qint32 entryType, QByteArray& data)
|
||||
{
|
||||
// Find offset for "type".
|
||||
int index = -1;
|
||||
for (int i = 0; i < _offsetsHeader.entriesCount; ++i)
|
||||
{
|
||||
if (_offsetsHeader.entries.at(i).type == entryType)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index < 0)
|
||||
return false;
|
||||
else if (_offsetsHeader.entries.at(index).offset == 0)
|
||||
return false;
|
||||
|
||||
const OffsetsHeaderEntryEntity& entry = _offsetsHeader.entries.at(index);
|
||||
|
||||
QDataStream in(_data);
|
||||
in.setVersion(QDataStream::Qt_4_5);
|
||||
in.device()->seek(entry.offset);
|
||||
|
||||
char* buff = new char[entry.contentSize];
|
||||
in.readRawData(buff, entry.contentSize);
|
||||
data.append(buff, entry.contentSize);
|
||||
delete[] buff;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InMemoryReader::read(SectionIndexData& sid)
|
||||
{
|
||||
QByteArray sidData;
|
||||
if (!read(ET_SectionIndex, sidData) || sidData.isEmpty())
|
||||
return false;
|
||||
|
||||
QDataStream in(sidData);
|
||||
in.setVersion(QDataStream::Qt_4_5);
|
||||
in >> sid;
|
||||
|
||||
return in.atEnd();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ADS_NAMESPACE_SER_END
|
||||
@@ -1,55 +0,0 @@
|
||||
TARGET = AdvancedDockingSystemDemo
|
||||
|
||||
QT += core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
greaterThan(QT_MAJOR_VERSION, 4): DEFINES += ADS_NAMESPACE_ENABLED
|
||||
|
||||
windows {
|
||||
# MinGW
|
||||
*-g++* {
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
}
|
||||
# MSVC
|
||||
*-msvc* {
|
||||
}
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
src/main.cpp \
|
||||
src/mainwindow.cpp \
|
||||
src/icontitlewidget.cpp \
|
||||
src/dialogs/SectionContentListModel.cpp \
|
||||
src/dialogs/SectionContentListWidget.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/mainwindow.h \
|
||||
src/icontitlewidget.h \
|
||||
src/dialogs/SectionContentListModel.h \
|
||||
src/dialogs/SectionContentListWidget.h
|
||||
|
||||
FORMS += \
|
||||
src/mainwindow.ui \
|
||||
src/dialogs/SectionContentListWidget.ui
|
||||
|
||||
|
||||
# Dependency: AdvancedDockingSystem (staticlib)
|
||||
#win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../AdvancedDockingSystem/release/ -lAdvancedDockingSystem
|
||||
#else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../AdvancedDockingSystem/debug/ -lAdvancedDockingSystem
|
||||
#else:unix: LIBS += -L$$OUT_PWD/../AdvancedDockingSystem/ -lAdvancedDockingSystem
|
||||
|
||||
#INCLUDEPATH += $$PWD/../AdvancedDockingSystem/include
|
||||
#DEPENDPATH += $$PWD/../AdvancedDockingSystem/include
|
||||
|
||||
#win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../AdvancedDockingSystem/release/libAdvancedDockingSystem.a
|
||||
#else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../AdvancedDockingSystem/debug/libAdvancedDockingSystem.a
|
||||
#else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../AdvancedDockingSystem/release/AdvancedDockingSystem.lib
|
||||
#else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../AdvancedDockingSystem/debug/AdvancedDockingSystem.lib
|
||||
#else:unix: PRE_TARGETDEPS += $$OUT_PWD/../AdvancedDockingSystem/libAdvancedDockingSystem.a
|
||||
|
||||
# Dependency: AdvancedDockingSystem (shared)
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../AdvancedDockingSystem/release/ -lAdvancedDockingSystem1
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../AdvancedDockingSystem/debug/ -lAdvancedDockingSystem1
|
||||
else:unix: LIBS += -L$$OUT_PWD/../AdvancedDockingSystem/ -lAdvancedDockingSystem1
|
||||
|
||||
INCLUDEPATH += $$PWD/../AdvancedDockingSystem/include
|
||||
DEPENDPATH += $$PWD/../AdvancedDockingSystem/include
|
||||
@@ -1,96 +0,0 @@
|
||||
#include "SectionContentListModel.h"
|
||||
|
||||
SectionContentListModel::SectionContentListModel(QObject* parent) :
|
||||
QAbstractTableModel(parent)
|
||||
{
|
||||
_headers.insert(UidColumn, "UID");
|
||||
_headers.insert(UniqueNameColumn, "Unique Name");
|
||||
_headers.insert(TitleColumn, "Title");
|
||||
_headers.insert(VisibleColumn, "Visible");
|
||||
}
|
||||
|
||||
SectionContentListModel::~SectionContentListModel()
|
||||
{
|
||||
}
|
||||
|
||||
void SectionContentListModel::init(ADS_NS::ContainerWidget* cw)
|
||||
{
|
||||
#if QT_VERSION >= 0x050000
|
||||
beginResetModel();
|
||||
_cw = cw;
|
||||
_contents = _cw->contents();
|
||||
endResetModel();
|
||||
#else
|
||||
_cw = cw;
|
||||
_contents = _cw->contents();
|
||||
reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
int SectionContentListModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return _headers.count();
|
||||
}
|
||||
|
||||
QVariant SectionContentListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
return _headers.value(section);
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
int SectionContentListModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return _contents.count();
|
||||
}
|
||||
|
||||
QVariant SectionContentListModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() > rowCount(index) - 1)
|
||||
return QVariant();
|
||||
|
||||
const ADS_NS::SectionContent::RefPtr sc = _contents.at(index.row());
|
||||
if (sc.isNull())
|
||||
return QVariant();
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case UidColumn:
|
||||
return sc->uid();
|
||||
case UniqueNameColumn:
|
||||
return sc->uniqueName();
|
||||
case TitleColumn:
|
||||
return sc->title();
|
||||
case VisibleColumn:
|
||||
return _cw->isSectionContentVisible(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool SectionContentListModel::removeRows(int row, int count, const QModelIndex& parent)
|
||||
{
|
||||
if (row > rowCount(parent) - 1)
|
||||
return false;
|
||||
|
||||
const int first = row;
|
||||
const int last = row + count - 1;
|
||||
beginRemoveRows(parent, first, last);
|
||||
|
||||
for (int i = last; i >= first; --i)
|
||||
{
|
||||
const ADS_NS::SectionContent::RefPtr sc = _contents.at(i);
|
||||
_cw->removeSectionContent(sc);
|
||||
_contents.removeAt(i);
|
||||
}
|
||||
|
||||
endRemoveRows();
|
||||
return true;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#ifndef ADS_SECTIONCONTENTMODEL_H
|
||||
#define ADS_SECTIONCONTENTMODEL_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
#include "ads/API.h"
|
||||
#include "ads/ContainerWidget.h"
|
||||
#include "ads/SectionContent.h"
|
||||
ADS_NAMESPACE_BEGIN
|
||||
class ContainerWidget;
|
||||
ADS_NAMESPACE_END
|
||||
|
||||
class SectionContentListModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Column
|
||||
{
|
||||
UidColumn,
|
||||
UniqueNameColumn,
|
||||
TitleColumn,
|
||||
VisibleColumn
|
||||
};
|
||||
|
||||
SectionContentListModel(QObject* parent);
|
||||
virtual ~SectionContentListModel();
|
||||
void init(ADS_NS::ContainerWidget* cw);
|
||||
|
||||
virtual int columnCount(const QModelIndex &parent) const;
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
|
||||
virtual int rowCount(const QModelIndex &parent) const;
|
||||
virtual QVariant data(const QModelIndex &index, int role) const;
|
||||
|
||||
virtual bool removeRows(int row, int count, const QModelIndex &parent);
|
||||
|
||||
private:
|
||||
QHash<int, QString> _headers;
|
||||
|
||||
ADS_NS::ContainerWidget* _cw;
|
||||
QList<ADS_NS::SectionContent::RefPtr> _contents;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
#include "SectionContentListWidget.h"
|
||||
#include "SectionContentListModel.h"
|
||||
|
||||
|
||||
SectionContentListWidget::SectionContentListWidget(QWidget* parent) :
|
||||
QDialog(parent)
|
||||
{
|
||||
_ui.setupUi(this);
|
||||
connect(_ui.deleteButton, SIGNAL(clicked(bool)), this, SLOT(onDeleteButtonClicked()));
|
||||
}
|
||||
|
||||
void SectionContentListWidget::setValues(const SectionContentListWidget::Values& v)
|
||||
{
|
||||
_v = v;
|
||||
|
||||
// Reset
|
||||
QAbstractItemModel* m = _ui.tableView->model();
|
||||
if (m)
|
||||
{
|
||||
_ui.tableView->setModel(NULL);
|
||||
delete m;
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
// Fill.
|
||||
SectionContentListModel* sclm = new SectionContentListModel(this);
|
||||
sclm->init(_v.cw);
|
||||
_ui.tableView->setModel(sclm);
|
||||
}
|
||||
|
||||
void SectionContentListWidget::onDeleteButtonClicked()
|
||||
{
|
||||
const QModelIndex mi = _ui.tableView->currentIndex();
|
||||
if (!mi.isValid())
|
||||
return;
|
||||
|
||||
_ui.tableView->model()->removeRows(mi.row(), 1, mi.parent());
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef SECTIONCONTENTLISTWIDGET
|
||||
#define SECTIONCONTENTLISTWIDGET
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_SectionContentListWidget.h"
|
||||
|
||||
#include "ads/API.h"
|
||||
#include "ads/ContainerWidget.h"
|
||||
#include "ads/SectionContent.h"
|
||||
|
||||
class SectionContentListWidget : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
class Values
|
||||
{
|
||||
public:
|
||||
ADS_NS::ContainerWidget* cw;
|
||||
};
|
||||
|
||||
SectionContentListWidget(QWidget* parent);
|
||||
void setValues(const Values& v);
|
||||
|
||||
private slots:
|
||||
void onDeleteButtonClicked();
|
||||
|
||||
private:
|
||||
Ui::SectionContentListWidgetForm _ui;
|
||||
Values _v;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SectionContentListWidgetForm</class>
|
||||
<widget class="QWidget" name="SectionContentListWidgetForm">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>522</width>
|
||||
<height>258</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QTableView" name="tableView">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteButton">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,65 +0,0 @@
|
||||
#include "icontitlewidget.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QString>
|
||||
#include <QBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QStyle>
|
||||
|
||||
IconTitleWidget::IconTitleWidget(const QIcon& icon, const QString& title, QWidget *parent) :
|
||||
QFrame(parent)
|
||||
{
|
||||
QBoxLayout* l = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
setLayout(l);
|
||||
|
||||
_iconLabel = new QLabel();
|
||||
l->addWidget(_iconLabel);
|
||||
|
||||
_titleLabel = new QLabel();
|
||||
l->addWidget(_titleLabel, 1);
|
||||
|
||||
setIcon(icon);
|
||||
setTitle(title);
|
||||
}
|
||||
|
||||
void IconTitleWidget::setIcon(const QIcon& icon)
|
||||
{
|
||||
if (icon.isNull())
|
||||
{
|
||||
_iconLabel->setPixmap(QPixmap());
|
||||
_iconLabel->setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_iconLabel->setPixmap(icon.pixmap(16, 16));
|
||||
_iconLabel->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
void IconTitleWidget::setTitle(const QString& title)
|
||||
{
|
||||
if (title.isEmpty())
|
||||
{
|
||||
_titleLabel->setText(QString());
|
||||
_titleLabel->setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_titleLabel->setText(title);
|
||||
_titleLabel->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
void IconTitleWidget::polishUpdate()
|
||||
{
|
||||
QList<QWidget*> widgets;
|
||||
widgets.append(_iconLabel);
|
||||
widgets.append(_titleLabel);
|
||||
foreach (QWidget* w, widgets)
|
||||
{
|
||||
w->style()->unpolish(w);
|
||||
w->style()->polish(w);
|
||||
w->update();
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef ICONTITLEWIDGET_H
|
||||
#define ICONTITLEWIDGET_H
|
||||
|
||||
#include <QFrame>
|
||||
class QIcon;
|
||||
class QString;
|
||||
class QLabel;
|
||||
|
||||
class IconTitleWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit IconTitleWidget(const QIcon& icon, const QString& title, QWidget *parent = 0);
|
||||
|
||||
public slots:
|
||||
void setIcon(const QIcon& icon);
|
||||
void setTitle(const QString& title);
|
||||
void polishUpdate();
|
||||
|
||||
public:
|
||||
QLabel* _iconLabel;
|
||||
QLabel* _titleLabel;
|
||||
};
|
||||
|
||||
#endif // ICONTITLEWIDGET_H
|
||||
@@ -1,28 +0,0 @@
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <QApplication>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
static void initStyleSheet(QApplication& a)
|
||||
{
|
||||
//Q_INIT_RESOURCE(ads); // If static linked.
|
||||
QFile f(":ads/stylesheets/default-windows.css");
|
||||
if (f.open(QFile::ReadOnly))
|
||||
{
|
||||
const QByteArray ba = f.readAll();
|
||||
f.close();
|
||||
a.setStyleSheet(QString(ba));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setQuitOnLastWindowClosed(true);
|
||||
initStyleSheet(a);
|
||||
|
||||
MainWindow mw;
|
||||
mw.show();
|
||||
return a.exec();
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include <QTime>
|
||||
#include <QLabel>
|
||||
#include <QTextEdit>
|
||||
#include <QCalendarWidget>
|
||||
#include <QFrame>
|
||||
#include <QTreeView>
|
||||
#include <QFileSystemModel>
|
||||
#include <QBoxLayout>
|
||||
|
||||
#include "ads/SectionWidget.h"
|
||||
#include "ads/DropOverlay.h"
|
||||
|
||||
#include "dialogs/SectionContentListWidget.h"
|
||||
|
||||
#include "icontitlewidget.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CONTENT_COUNT = 0;
|
||||
|
||||
static ADS_NS::SectionContent::RefPtr createLongTextLabelSC(ADS_NS::ContainerWidget* container)
|
||||
{
|
||||
QWidget* w = new QWidget();
|
||||
QBoxLayout* bl = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
w->setLayout(bl);
|
||||
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText(QString("Lorem Ipsum ist ein einfacher Demo-Text für die Print- und Schriftindustrie. Lorem Ipsum ist in der Industrie bereits der Standard Demo-Text seit 1500, als ein unbekannter Schriftsteller eine Hand voll Wörter nahm und diese durcheinander warf um ein Musterbuch zu erstellen. Es hat nicht nur 5 Jahrhunderte überlebt, sondern auch in Spruch in die elektronische Schriftbearbeitung geschafft (bemerke, nahezu unverändert). Bekannt wurde es 1960, mit dem erscheinen von Letrase, welches Passagen von Lorem Ipsum enhielt, so wie Desktop Software wie Aldus PageMaker - ebenfalls mit Lorem Ipsum."));
|
||||
bl->addWidget(l);
|
||||
|
||||
const int index = ++CONTENT_COUNT;
|
||||
ADS_NS::SectionContent::RefPtr sc = ADS_NS::SectionContent::newSectionContent(QString("uname-%1").arg(index), container, new IconTitleWidget(QIcon(), QString("Label %1").arg(index)), w);
|
||||
sc->setTitle("Ein Label " + QString::number(index));
|
||||
return sc;
|
||||
}
|
||||
|
||||
static ADS_NS::SectionContent::RefPtr createCalendarSC(ADS_NS::ContainerWidget* container)
|
||||
{
|
||||
QCalendarWidget* w = new QCalendarWidget();
|
||||
|
||||
const int index = ++CONTENT_COUNT;
|
||||
return ADS_NS::SectionContent::newSectionContent(QString("uname-%1").arg(index), container, new IconTitleWidget(QIcon(), QString("Calendar %1").arg(index)), w);
|
||||
}
|
||||
|
||||
static ADS_NS::SectionContent::RefPtr createFileSystemTreeSC(ADS_NS::ContainerWidget* container)
|
||||
{
|
||||
QTreeView* w = new QTreeView();
|
||||
w->setFrameShape(QFrame::NoFrame);
|
||||
// QFileSystemModel* m = new QFileSystemModel(w);
|
||||
// m->setRootPath(QDir::currentPath());
|
||||
// w->setModel(m);
|
||||
|
||||
const int index = ++CONTENT_COUNT;
|
||||
return ADS_NS::SectionContent::newSectionContent(QString("uname-%1").arg(index), container, new IconTitleWidget(QIcon(), QString("Filesystem %1").arg(index)), w);
|
||||
}
|
||||
|
||||
static void storeDataHelper(const QString& fname, const QByteArray& ba)
|
||||
{
|
||||
QFile f(fname + QString(".dat"));
|
||||
if (f.open(QFile::WriteOnly))
|
||||
{
|
||||
f.write(ba);
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
|
||||
static QByteArray loadDataHelper(const QString& fname)
|
||||
{
|
||||
QFile f(fname + QString(".dat"));
|
||||
if (f.open(QFile::ReadOnly))
|
||||
{
|
||||
QByteArray ba = f.readAll();
|
||||
f.close();
|
||||
return ba;
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// Setup actions.
|
||||
QObject::connect(ui->actionContentList, SIGNAL(triggered()), this, SLOT(showSectionContentListDialog()));
|
||||
|
||||
// ADS - Create main container (ContainerWidget).
|
||||
_container = new ADS_NS::ContainerWidget();
|
||||
#if QT_VERSION >= 0x050000
|
||||
QObject::connect(_container, &ADS_NS::ContainerWidget::activeTabChanged, this, &MainWindow::onActiveTabChanged);
|
||||
QObject::connect(_container, &ADS_NS::ContainerWidget::sectionContentVisibilityChanged, this, &MainWindow::onSectionContentVisibilityChanged);
|
||||
#else
|
||||
QObject::connect(_container, SIGNAL(activeTabChanged(const SectionContent::RefPtr&, bool)), this, SLOT(onActiveTabChanged(const SectionContent::RefPtr&, bool)));
|
||||
QObject::connect(_container, SIGNAL(sectionContentVisibilityChanged(SectionContent::RefPtr,bool)), this, SLOT(onSectionContentVisibilityChanged(SectionContent::RefPtr,bool)));
|
||||
#endif
|
||||
setCentralWidget(_container);
|
||||
|
||||
// Optional: Use custom drop area widgets.
|
||||
if (false)
|
||||
{
|
||||
QHash<ADS_NS::DropArea, QWidget*> areaWidgets;
|
||||
areaWidgets.insert(ADS_NS::TopDropArea, new QPushButton("TOP"));
|
||||
areaWidgets.insert(ADS_NS::RightDropArea, new QPushButton("RIGHT"));
|
||||
areaWidgets.insert(ADS_NS::BottomDropArea, new QPushButton("BOTTOM"));
|
||||
areaWidgets.insert(ADS_NS::LeftDropArea, new QPushButton("LEFT"));
|
||||
areaWidgets.insert(ADS_NS::CenterDropArea, new QPushButton("CENTER"));
|
||||
_container->dropOverlay()->setAreaWidgets(areaWidgets);
|
||||
}
|
||||
|
||||
// ADS - Adding some contents.
|
||||
if (true)
|
||||
{
|
||||
// Test #1: Use high-level public API
|
||||
ADS_NS::ContainerWidget* cw = _container;
|
||||
ADS_NS::SectionWidget* sw = NULL;
|
||||
|
||||
sw = _container->addSectionContent(createLongTextLabelSC(cw), sw, ADS_NS::CenterDropArea);
|
||||
sw = _container->addSectionContent(createCalendarSC(cw), sw, ADS_NS::RightDropArea);
|
||||
sw = _container->addSectionContent(createFileSystemTreeSC(cw), sw, ADS_NS::CenterDropArea);
|
||||
|
||||
_container->addSectionContent(createCalendarSC(_container));
|
||||
_container->addSectionContent(createLongTextLabelSC(_container));
|
||||
_container->addSectionContent(createLongTextLabelSC(_container));
|
||||
_container->addSectionContent(createLongTextLabelSC(_container));
|
||||
|
||||
ADS_NS::SectionContent::RefPtr sc = createLongTextLabelSC(cw);
|
||||
sc->setFlags(ADS_NS::SectionContent::AllFlags ^ ADS_NS::SectionContent::Closeable);
|
||||
_container->addSectionContent(sc);
|
||||
}
|
||||
else if (false)
|
||||
{
|
||||
// Issue #2: If the first drop is not into CenterDropArea, the application crashes.
|
||||
ADS_NS::ContainerWidget* cw = _container;
|
||||
ADS_NS::SectionWidget* sw = NULL;
|
||||
|
||||
sw = _container->addSectionContent(createLongTextLabelSC(cw), sw, ADS_NS::LeftDropArea);
|
||||
sw = _container->addSectionContent(createCalendarSC(cw), sw, ADS_NS::LeftDropArea);
|
||||
sw = _container->addSectionContent(createLongTextLabelSC(cw), sw, ADS_NS::CenterDropArea);
|
||||
sw = _container->addSectionContent(createLongTextLabelSC(cw), sw, ADS_NS::CenterDropArea);
|
||||
sw = _container->addSectionContent(createLongTextLabelSC(cw), sw, ADS_NS::CenterDropArea);
|
||||
sw = _container->addSectionContent(createLongTextLabelSC(cw), sw, ADS_NS::RightDropArea);
|
||||
sw = _container->addSectionContent(createLongTextLabelSC(cw), sw, ADS_NS::BottomDropArea);
|
||||
}
|
||||
|
||||
// Default window geometry
|
||||
resize(800, 600);
|
||||
restoreGeometry(loadDataHelper("MainWindow"));
|
||||
|
||||
// ADS - Restore geometries and states of contents.
|
||||
_container->restoreState(loadDataHelper("ContainerWidget"));
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MainWindow::showSectionContentListDialog()
|
||||
{
|
||||
SectionContentListWidget::Values v;
|
||||
v.cw = _container;
|
||||
|
||||
SectionContentListWidget w(this);
|
||||
w.setValues(v);
|
||||
w.exec();
|
||||
}
|
||||
|
||||
void MainWindow::onActiveTabChanged(const ADS_NS::SectionContent::RefPtr& sc, bool active)
|
||||
{
|
||||
Q_UNUSED(active);
|
||||
IconTitleWidget* itw = dynamic_cast<IconTitleWidget*>(sc->titleWidget());
|
||||
if (itw)
|
||||
{
|
||||
itw->polishUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onSectionContentVisibilityChanged(const ADS_NS::SectionContent::RefPtr& sc, bool visible)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << sc->uniqueName() << visible;
|
||||
}
|
||||
|
||||
void MainWindow::onActionAddSectionContentTriggered()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void MainWindow::contextMenuEvent(QContextMenuEvent* e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
QMenu* m = _container->createContextMenu();
|
||||
m->exec(QCursor::pos());
|
||||
delete m;
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent* e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
storeDataHelper("MainWindow", saveGeometry());
|
||||
storeDataHelper("ContainerWidget", _container->saveState());
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "ads/API.h"
|
||||
#include "ads/ContainerWidget.h"
|
||||
#include "ads/SectionContent.h"
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
virtual ~MainWindow();
|
||||
|
||||
public slots:
|
||||
void showSectionContentListDialog();
|
||||
|
||||
private slots:
|
||||
#if QT_VERSION >= 0x050000
|
||||
void onActiveTabChanged(const ADS_NS::SectionContent::RefPtr& sc, bool active);
|
||||
void onSectionContentVisibilityChanged(const ADS_NS::SectionContent::RefPtr& sc, bool visible);
|
||||
#else
|
||||
void onActiveTabChanged(const SectionContent::RefPtr& sc, bool active);
|
||||
void onSectionContentVisibilityChanged(const SectionContent::RefPtr& sc, bool visible);
|
||||
#endif
|
||||
void onActionAddSectionContentTriggered();
|
||||
|
||||
protected:
|
||||
virtual void contextMenuEvent(QContextMenuEvent* e);
|
||||
virtual void closeEvent(QCloseEvent* e);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
ADS_NS::ContainerWidget* _container;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/src/TestCore.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/src/main.cpp \
|
||||
$$PWD/src/TestCore.cpp
|
||||
@@ -1,14 +0,0 @@
|
||||
TARGET = AdvancedDockingSystemUnitTests
|
||||
|
||||
QT += core gui testlib
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
greaterThan(QT_MAJOR_VERSION, 4): DEFINES += ADS_NAMESPACE_ENABLED
|
||||
DEFINES += ADS_IMPORT
|
||||
|
||||
INCLUDEPATH += $$PWD/src
|
||||
|
||||
INCLUDEPATH += $$PWD/../AdvancedDockingSystem/include
|
||||
DEPENDPATH += $$PWD/../AdvancedDockingSystem/include
|
||||
|
||||
include(AdvancedDockingSystemUnitTests.pri)
|
||||
include(../AdvancedDockingSystem/AdvancedDockingSystem.pri)
|
||||
@@ -1,68 +0,0 @@
|
||||
#include "TestCore.h"
|
||||
|
||||
#include "ads/API.h"
|
||||
#include "ads/Serialization.h"
|
||||
|
||||
void TestCore::serialization()
|
||||
{
|
||||
QList<QByteArray> datas;
|
||||
datas.append(QByteArray("Custom Data Here!!!"));
|
||||
datas.append(QByteArray("Even More..."));
|
||||
datas.append(QByteArray("lalalaalalalalalalal").toBase64());
|
||||
|
||||
// WRITE some data.
|
||||
ADS_NS_SER::InMemoryWriter writer;
|
||||
for (int i = 0; i < datas.count(); ++i)
|
||||
{
|
||||
QVERIFY(writer.write(ADS_NS_SER::ET_Custom + i, datas.at(i)));
|
||||
}
|
||||
|
||||
// Type: SectionIndexData
|
||||
ADS_NS_SER::SectionIndexData sid;
|
||||
for (int i = 0; i < 1; ++i)
|
||||
{
|
||||
ADS_NS_SER::SectionEntity se;
|
||||
se.x = i;
|
||||
se.y = i;
|
||||
se.width = 100 + i;
|
||||
se.height = 100 + i;
|
||||
se.currentIndex = i;
|
||||
|
||||
for (int j = 0; j < 1; ++j)
|
||||
{
|
||||
ADS_NS_SER::SectionContentEntity sce;
|
||||
sce.uniqueName = QString("uname-%1-%2").arg(i).arg(j);
|
||||
sce.preferredIndex = 8;
|
||||
sce.visible = true;
|
||||
se.sectionContents.append(sce);
|
||||
se.sectionContentsCount += 1;
|
||||
}
|
||||
|
||||
sid.sections.append(se);
|
||||
sid.sectionsCount += 1;
|
||||
}
|
||||
QVERIFY(writer.write(sid));
|
||||
|
||||
QVERIFY(writer.offsetsCount() == datas.count() + 1);
|
||||
const QByteArray writtenData = writer.toByteArray();
|
||||
QVERIFY(writtenData.size() > 0);
|
||||
|
||||
// READ and validate written data.
|
||||
ADS_NS_SER::InMemoryReader reader(writtenData);
|
||||
QVERIFY(reader.initReadHeader());
|
||||
QVERIFY(reader.offsetsCount() == datas.count() + 1);
|
||||
for (int i = 0; i < datas.count(); ++i)
|
||||
{
|
||||
QByteArray readData;
|
||||
QVERIFY(reader.read(ADS_NS_SER::ET_Custom + i, readData));
|
||||
QVERIFY(readData == datas.at(i));
|
||||
}
|
||||
|
||||
// Type: SectionIndexData
|
||||
ADS_NS_SER::SectionIndexData sidRead;
|
||||
QVERIFY(reader.read(sidRead));
|
||||
|
||||
// TODO compare sidRead with sid
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestCore)
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef TEST_CORE_H
|
||||
#define TEST_CORE_H
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
class TestCore : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void serialization();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1 +0,0 @@
|
||||
#include <QtTest/QtTest>
|
||||
129
CMakeLists.txt
Normal file
@@ -0,0 +1,129 @@
|
||||
cmake_minimum_required(VERSION 3.3)
|
||||
set(ads_VERSION "2.3.2")
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
project(QtAdvancedDockingSystem VERSION ${ads_VERSION})
|
||||
option(BUILD_STATIC "Build the static library" OFF)
|
||||
option(BUILD_EXAMPLES "Build the examples" ON)
|
||||
set(REQUIRED_QT_VERSION 5.5.0)
|
||||
find_package(Qt5Core ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt5Widgets ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
message(STATUS "Found Qt ${Qt5Core_VERSION}")
|
||||
set(ads_INCLUDE ${ads_INCLUDE} ${Qt5Core_INCLUDE_DIRS})
|
||||
set(ads_INCLUDE ${ads_INCLUDE} "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
set(ads_LIBS ${ads_LIBS} ${Qt5Core_LIBRARIES})
|
||||
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ${Qt5Core_COMPILE_DEFINITIONS})
|
||||
set(ads_LIBS ${ads_LIBS} ${Qt5Gui_LIBRARIES})
|
||||
set(ads_INCLUDE ${ads_INCLUDE} ${Qt5Gui_INCLUDE_DIRS})
|
||||
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ${Qt5Gui_COMPILE_DEFINITIONS})
|
||||
set(ads_LIBS ${ads_LIBS} ${Qt5Widgets_LIBRARIES})
|
||||
set(ads_INCLUDE ${ads_INCLUDE} ${Qt5Widgets_INCLUDE_DIRS})
|
||||
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ${Qt5Widgets_COMPILE_DEFINITIONS})
|
||||
if(BUILD_STATIC)
|
||||
set(CMAKE_STATIC_LIBRARY_SUFFIX "_static${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
endif()
|
||||
set(ads_SRCS
|
||||
src/ads_globals.cpp
|
||||
src/DockAreaTabBar.cpp
|
||||
src/DockAreaTitleBar.cpp
|
||||
src/DockAreaWidget.cpp
|
||||
src/DockContainerWidget.cpp
|
||||
src/DockManager.cpp
|
||||
src/DockOverlay.cpp
|
||||
src/DockSplitter.cpp
|
||||
src/DockWidget.cpp
|
||||
src/DockWidgetTab.cpp
|
||||
src/DockingStateReader.cpp
|
||||
src/ElidingLabel.cpp
|
||||
src/FloatingDockContainer.cpp
|
||||
src/FloatingDragPreview.cpp
|
||||
src/IconProvider.cpp
|
||||
src/DockComponentsFactory.cpp
|
||||
src/ads.qrc
|
||||
src/linux/FloatingWidgetTitleBar.cpp
|
||||
)
|
||||
set(ads_INSTALL_INCLUDE
|
||||
src/ads_globals.h
|
||||
src/DockAreaTabBar.h
|
||||
src/DockAreaTitleBar.h
|
||||
src/DockAreaWidget.h
|
||||
src/DockContainerWidget.h
|
||||
src/DockManager.h
|
||||
src/DockOverlay.h
|
||||
src/DockSplitter.h
|
||||
src/DockWidget.h
|
||||
src/DockWidgetTab.h
|
||||
src/DockingStateReader.h
|
||||
src/ElidingLabel.h
|
||||
src/FloatingDockContainer.h
|
||||
src/FloatingDragPreview.h
|
||||
src/IconProvider.h
|
||||
src/DockComponentsFactory.h
|
||||
src/linux/FloatingWidgetTitleBar.h
|
||||
)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
|
||||
set(ads_PlatformDir "x86")
|
||||
else()
|
||||
set(ads_PlatformDir "x64")
|
||||
endif()
|
||||
if(BUILD_STATIC)
|
||||
add_library(qtadvanceddocking STATIC ${ads_SRCS})
|
||||
target_compile_definitions(qtadvanceddocking PUBLIC ADS_STATIC)
|
||||
else()
|
||||
add_library(qtadvanceddocking SHARED ${ads_SRCS})
|
||||
set(ads_COMPILE_DEFINE ${ads_COMPILE_DEFINE} ADS_SHARED_EXPORT)
|
||||
endif()
|
||||
install(FILES ${ads_INSTALL_INCLUDE}
|
||||
DESTINATION include
|
||||
COMPONENT headers
|
||||
)
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/LICENSE"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/gnu-lgpl-v2.1.md"
|
||||
DESTINATION license
|
||||
COMPONENT license
|
||||
)
|
||||
install(TARGETS qtadvanceddocking
|
||||
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}>"
|
||||
$<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 "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"
|
||||
)
|
||||
if(BUILD_EXAMPLES)
|
||||
add_subdirectory(example)
|
||||
add_subdirectory(demo)
|
||||
endif()
|
||||
|
||||
504
LICENSE
Normal file
@@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random
|
||||
Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
2
MANIFEST.in
Normal file
@@ -0,0 +1,2 @@
|
||||
include versioneer.py
|
||||
include PyQtAds/_version.py
|
||||
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
|
||||
9
PyQtAds/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from .rc import *
|
||||
from ._version import get_versions
|
||||
__version__ = get_versions()['version']
|
||||
short_version = __version__
|
||||
version = __version__
|
||||
full_version = __version__
|
||||
git_revision = get_versions()['full-revisionid']
|
||||
release = not get_versions()['dirty']
|
||||
del get_versions
|
||||
520
PyQtAds/_version.py
Normal file
@@ -0,0 +1,520 @@
|
||||
|
||||
# This file helps to compute a version number in source trees obtained from
|
||||
# git-archive tarball (such as those provided by githubs download-from-tag
|
||||
# feature). Distribution tarballs (built by setup.py sdist) and build
|
||||
# directories (produced by setup.py build) will contain a much shorter file
|
||||
# that just contains the computed version number.
|
||||
|
||||
# This file is released into the public domain. Generated by
|
||||
# versioneer-0.18 (https://github.com/warner/python-versioneer)
|
||||
|
||||
"""Git implementation of _version.py."""
|
||||
|
||||
import errno
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def get_keywords():
|
||||
"""Get the keywords needed to look up the version information."""
|
||||
# these strings will be replaced by git during git-archive.
|
||||
# setup.py/versioneer.py will grep for the variable names, so they must
|
||||
# each be defined on a line of their own. _version.py will just call
|
||||
# get_keywords().
|
||||
git_refnames = "$Format:%d$"
|
||||
git_full = "$Format:%H$"
|
||||
git_date = "$Format:%ci$"
|
||||
keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
|
||||
return keywords
|
||||
|
||||
|
||||
class VersioneerConfig:
|
||||
"""Container for Versioneer configuration parameters."""
|
||||
|
||||
|
||||
def get_config():
|
||||
"""Create, populate and return the VersioneerConfig() object."""
|
||||
# these strings are filled in when 'setup.py versioneer' creates
|
||||
# _version.py
|
||||
cfg = VersioneerConfig()
|
||||
cfg.VCS = "git"
|
||||
cfg.style = "pep440"
|
||||
cfg.tag_prefix = ""
|
||||
cfg.parentdir_prefix = "None"
|
||||
cfg.versionfile_source = "PyQtAds/_version.py"
|
||||
cfg.verbose = False
|
||||
return cfg
|
||||
|
||||
|
||||
class NotThisMethod(Exception):
|
||||
"""Exception raised if a method is not valid for the current scenario."""
|
||||
|
||||
|
||||
LONG_VERSION_PY = {}
|
||||
HANDLERS = {}
|
||||
|
||||
|
||||
def register_vcs_handler(vcs, method): # decorator
|
||||
"""Create decorator to mark a method as the handler of a VCS."""
|
||||
def decorate(f):
|
||||
"""Store f in HANDLERS[vcs][method]."""
|
||||
if vcs not in HANDLERS:
|
||||
HANDLERS[vcs] = {}
|
||||
HANDLERS[vcs][method] = f
|
||||
return f
|
||||
return decorate
|
||||
|
||||
|
||||
def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
|
||||
env=None):
|
||||
"""Call the given command(s)."""
|
||||
assert isinstance(commands, list)
|
||||
p = None
|
||||
for c in commands:
|
||||
try:
|
||||
dispcmd = str([c] + args)
|
||||
# remember shell=False, so use git.cmd on windows, not just git
|
||||
p = subprocess.Popen([c] + args, cwd=cwd, env=env,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=(subprocess.PIPE if hide_stderr
|
||||
else None))
|
||||
break
|
||||
except EnvironmentError:
|
||||
e = sys.exc_info()[1]
|
||||
if e.errno == errno.ENOENT:
|
||||
continue
|
||||
if verbose:
|
||||
print("unable to run %s" % dispcmd)
|
||||
print(e)
|
||||
return None, None
|
||||
else:
|
||||
if verbose:
|
||||
print("unable to find command, tried %s" % (commands,))
|
||||
return None, None
|
||||
stdout = p.communicate()[0].strip()
|
||||
if sys.version_info[0] >= 3:
|
||||
stdout = stdout.decode()
|
||||
if p.returncode != 0:
|
||||
if verbose:
|
||||
print("unable to run %s (error)" % dispcmd)
|
||||
print("stdout was %s" % stdout)
|
||||
return None, p.returncode
|
||||
return stdout, p.returncode
|
||||
|
||||
|
||||
def versions_from_parentdir(parentdir_prefix, root, verbose):
|
||||
"""Try to determine the version from the parent directory name.
|
||||
|
||||
Source tarballs conventionally unpack into a directory that includes both
|
||||
the project name and a version string. We will also support searching up
|
||||
two directory levels for an appropriately named parent directory
|
||||
"""
|
||||
rootdirs = []
|
||||
|
||||
for i in range(3):
|
||||
dirname = os.path.basename(root)
|
||||
if dirname.startswith(parentdir_prefix):
|
||||
return {"version": dirname[len(parentdir_prefix):],
|
||||
"full-revisionid": None,
|
||||
"dirty": False, "error": None, "date": None}
|
||||
else:
|
||||
rootdirs.append(root)
|
||||
root = os.path.dirname(root) # up a level
|
||||
|
||||
if verbose:
|
||||
print("Tried directories %s but none started with prefix %s" %
|
||||
(str(rootdirs), parentdir_prefix))
|
||||
raise NotThisMethod("rootdir doesn't start with parentdir_prefix")
|
||||
|
||||
|
||||
@register_vcs_handler("git", "get_keywords")
|
||||
def git_get_keywords(versionfile_abs):
|
||||
"""Extract version information from the given file."""
|
||||
# the code embedded in _version.py can just fetch the value of these
|
||||
# keywords. When used from setup.py, we don't want to import _version.py,
|
||||
# so we do it with a regexp instead. This function is not used from
|
||||
# _version.py.
|
||||
keywords = {}
|
||||
try:
|
||||
f = open(versionfile_abs, "r")
|
||||
for line in f.readlines():
|
||||
if line.strip().startswith("git_refnames ="):
|
||||
mo = re.search(r'=\s*"(.*)"', line)
|
||||
if mo:
|
||||
keywords["refnames"] = mo.group(1)
|
||||
if line.strip().startswith("git_full ="):
|
||||
mo = re.search(r'=\s*"(.*)"', line)
|
||||
if mo:
|
||||
keywords["full"] = mo.group(1)
|
||||
if line.strip().startswith("git_date ="):
|
||||
mo = re.search(r'=\s*"(.*)"', line)
|
||||
if mo:
|
||||
keywords["date"] = mo.group(1)
|
||||
f.close()
|
||||
except EnvironmentError:
|
||||
pass
|
||||
return keywords
|
||||
|
||||
|
||||
@register_vcs_handler("git", "keywords")
|
||||
def git_versions_from_keywords(keywords, tag_prefix, verbose):
|
||||
"""Get version information from git keywords."""
|
||||
if not keywords:
|
||||
raise NotThisMethod("no keywords at all, weird")
|
||||
date = keywords.get("date")
|
||||
if date is not None:
|
||||
# git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
|
||||
# datestamp. However we prefer "%ci" (which expands to an "ISO-8601
|
||||
# -like" string, which we must then edit to make compliant), because
|
||||
# it's been around since git-1.5.3, and it's too difficult to
|
||||
# discover which version we're using, or to work around using an
|
||||
# older one.
|
||||
date = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
|
||||
refnames = keywords["refnames"].strip()
|
||||
if refnames.startswith("$Format"):
|
||||
if verbose:
|
||||
print("keywords are unexpanded, not using")
|
||||
raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
|
||||
refs = set([r.strip() for r in refnames.strip("()").split(",")])
|
||||
# starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
|
||||
# just "foo-1.0". If we see a "tag: " prefix, prefer those.
|
||||
TAG = "tag: "
|
||||
tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)])
|
||||
if not tags:
|
||||
# Either we're using git < 1.8.3, or there really are no tags. We use
|
||||
# a heuristic: assume all version tags have a digit. The old git %d
|
||||
# expansion behaves like git log --decorate=short and strips out the
|
||||
# refs/heads/ and refs/tags/ prefixes that would let us distinguish
|
||||
# between branches and tags. By ignoring refnames without digits, we
|
||||
# filter out many common branch names like "release" and
|
||||
# "stabilization", as well as "HEAD" and "master".
|
||||
tags = set([r for r in refs if re.search(r'\d', r)])
|
||||
if verbose:
|
||||
print("discarding '%s', no digits" % ",".join(refs - tags))
|
||||
if verbose:
|
||||
print("likely tags: %s" % ",".join(sorted(tags)))
|
||||
for ref in sorted(tags):
|
||||
# sorting will prefer e.g. "2.0" over "2.0rc1"
|
||||
if ref.startswith(tag_prefix):
|
||||
r = ref[len(tag_prefix):]
|
||||
if verbose:
|
||||
print("picking %s" % r)
|
||||
return {"version": r,
|
||||
"full-revisionid": keywords["full"].strip(),
|
||||
"dirty": False, "error": None,
|
||||
"date": date}
|
||||
# no suitable tags, so version is "0+unknown", but full hex is still there
|
||||
if verbose:
|
||||
print("no suitable tags, using unknown + full revision id")
|
||||
return {"version": "0+unknown",
|
||||
"full-revisionid": keywords["full"].strip(),
|
||||
"dirty": False, "error": "no suitable tags", "date": None}
|
||||
|
||||
|
||||
@register_vcs_handler("git", "pieces_from_vcs")
|
||||
def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
|
||||
"""Get version from 'git describe' in the root of the source tree.
|
||||
|
||||
This only gets called if the git-archive 'subst' keywords were *not*
|
||||
expanded, and _version.py hasn't already been rewritten with a short
|
||||
version string, meaning we're inside a checked out source tree.
|
||||
"""
|
||||
GITS = ["git"]
|
||||
if sys.platform == "win32":
|
||||
GITS = ["git.cmd", "git.exe"]
|
||||
|
||||
out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root,
|
||||
hide_stderr=True)
|
||||
if rc != 0:
|
||||
if verbose:
|
||||
print("Directory %s not under git control" % root)
|
||||
raise NotThisMethod("'git rev-parse --git-dir' returned error")
|
||||
|
||||
# if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
|
||||
# if there isn't one, this yields HEX[-dirty] (no NUM)
|
||||
describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty",
|
||||
"--always", "--long",
|
||||
"--match", "%s*" % tag_prefix],
|
||||
cwd=root)
|
||||
# --long was added in git-1.5.5
|
||||
if describe_out is None:
|
||||
raise NotThisMethod("'git describe' failed")
|
||||
describe_out = describe_out.strip()
|
||||
full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
|
||||
if full_out is None:
|
||||
raise NotThisMethod("'git rev-parse' failed")
|
||||
full_out = full_out.strip()
|
||||
|
||||
pieces = {}
|
||||
pieces["long"] = full_out
|
||||
pieces["short"] = full_out[:7] # maybe improved later
|
||||
pieces["error"] = None
|
||||
|
||||
# parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
|
||||
# TAG might have hyphens.
|
||||
git_describe = describe_out
|
||||
|
||||
# look for -dirty suffix
|
||||
dirty = git_describe.endswith("-dirty")
|
||||
pieces["dirty"] = dirty
|
||||
if dirty:
|
||||
git_describe = git_describe[:git_describe.rindex("-dirty")]
|
||||
|
||||
# now we have TAG-NUM-gHEX or HEX
|
||||
|
||||
if "-" in git_describe:
|
||||
# TAG-NUM-gHEX
|
||||
mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe)
|
||||
if not mo:
|
||||
# unparseable. Maybe git-describe is misbehaving?
|
||||
pieces["error"] = ("unable to parse git-describe output: '%s'"
|
||||
% describe_out)
|
||||
return pieces
|
||||
|
||||
# tag
|
||||
full_tag = mo.group(1)
|
||||
if not full_tag.startswith(tag_prefix):
|
||||
if verbose:
|
||||
fmt = "tag '%s' doesn't start with prefix '%s'"
|
||||
print(fmt % (full_tag, tag_prefix))
|
||||
pieces["error"] = ("tag '%s' doesn't start with prefix '%s'"
|
||||
% (full_tag, tag_prefix))
|
||||
return pieces
|
||||
pieces["closest-tag"] = full_tag[len(tag_prefix):]
|
||||
|
||||
# distance: number of commits since tag
|
||||
pieces["distance"] = int(mo.group(2))
|
||||
|
||||
# commit: short hex revision ID
|
||||
pieces["short"] = mo.group(3)
|
||||
|
||||
else:
|
||||
# HEX: no tags
|
||||
pieces["closest-tag"] = None
|
||||
count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"],
|
||||
cwd=root)
|
||||
pieces["distance"] = int(count_out) # total number of commits
|
||||
|
||||
# commit date: see ISO-8601 comment in git_versions_from_keywords()
|
||||
date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"],
|
||||
cwd=root)[0].strip()
|
||||
pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
|
||||
|
||||
return pieces
|
||||
|
||||
|
||||
def plus_or_dot(pieces):
|
||||
"""Return a + if we don't already have one, else return a ."""
|
||||
if "+" in pieces.get("closest-tag", ""):
|
||||
return "."
|
||||
return "+"
|
||||
|
||||
|
||||
def render_pep440(pieces):
|
||||
"""Build up version string, with post-release "local version identifier".
|
||||
|
||||
Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
|
||||
get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty
|
||||
|
||||
Exceptions:
|
||||
1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
|
||||
"""
|
||||
if pieces["closest-tag"]:
|
||||
rendered = pieces["closest-tag"]
|
||||
if pieces["distance"] or pieces["dirty"]:
|
||||
rendered += plus_or_dot(pieces)
|
||||
rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
|
||||
if pieces["dirty"]:
|
||||
rendered += ".dirty"
|
||||
else:
|
||||
# exception #1
|
||||
rendered = "0+untagged.%d.g%s" % (pieces["distance"],
|
||||
pieces["short"])
|
||||
if pieces["dirty"]:
|
||||
rendered += ".dirty"
|
||||
return rendered
|
||||
|
||||
|
||||
def render_pep440_pre(pieces):
|
||||
"""TAG[.post.devDISTANCE] -- No -dirty.
|
||||
|
||||
Exceptions:
|
||||
1: no tags. 0.post.devDISTANCE
|
||||
"""
|
||||
if pieces["closest-tag"]:
|
||||
rendered = pieces["closest-tag"]
|
||||
if pieces["distance"]:
|
||||
rendered += ".post.dev%d" % pieces["distance"]
|
||||
else:
|
||||
# exception #1
|
||||
rendered = "0.post.dev%d" % pieces["distance"]
|
||||
return rendered
|
||||
|
||||
|
||||
def render_pep440_post(pieces):
|
||||
"""TAG[.postDISTANCE[.dev0]+gHEX] .
|
||||
|
||||
The ".dev0" means dirty. Note that .dev0 sorts backwards
|
||||
(a dirty tree will appear "older" than the corresponding clean one),
|
||||
but you shouldn't be releasing software with -dirty anyways.
|
||||
|
||||
Exceptions:
|
||||
1: no tags. 0.postDISTANCE[.dev0]
|
||||
"""
|
||||
if pieces["closest-tag"]:
|
||||
rendered = pieces["closest-tag"]
|
||||
if pieces["distance"] or pieces["dirty"]:
|
||||
rendered += ".post%d" % pieces["distance"]
|
||||
if pieces["dirty"]:
|
||||
rendered += ".dev0"
|
||||
rendered += plus_or_dot(pieces)
|
||||
rendered += "g%s" % pieces["short"]
|
||||
else:
|
||||
# exception #1
|
||||
rendered = "0.post%d" % pieces["distance"]
|
||||
if pieces["dirty"]:
|
||||
rendered += ".dev0"
|
||||
rendered += "+g%s" % pieces["short"]
|
||||
return rendered
|
||||
|
||||
|
||||
def render_pep440_old(pieces):
|
||||
"""TAG[.postDISTANCE[.dev0]] .
|
||||
|
||||
The ".dev0" means dirty.
|
||||
|
||||
Exceptions:
|
||||
1: no tags. 0.postDISTANCE[.dev0]
|
||||
"""
|
||||
if pieces["closest-tag"]:
|
||||
rendered = pieces["closest-tag"]
|
||||
if pieces["distance"] or pieces["dirty"]:
|
||||
rendered += ".post%d" % pieces["distance"]
|
||||
if pieces["dirty"]:
|
||||
rendered += ".dev0"
|
||||
else:
|
||||
# exception #1
|
||||
rendered = "0.post%d" % pieces["distance"]
|
||||
if pieces["dirty"]:
|
||||
rendered += ".dev0"
|
||||
return rendered
|
||||
|
||||
|
||||
def render_git_describe(pieces):
|
||||
"""TAG[-DISTANCE-gHEX][-dirty].
|
||||
|
||||
Like 'git describe --tags --dirty --always'.
|
||||
|
||||
Exceptions:
|
||||
1: no tags. HEX[-dirty] (note: no 'g' prefix)
|
||||
"""
|
||||
if pieces["closest-tag"]:
|
||||
rendered = pieces["closest-tag"]
|
||||
if pieces["distance"]:
|
||||
rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
|
||||
else:
|
||||
# exception #1
|
||||
rendered = pieces["short"]
|
||||
if pieces["dirty"]:
|
||||
rendered += "-dirty"
|
||||
return rendered
|
||||
|
||||
|
||||
def render_git_describe_long(pieces):
|
||||
"""TAG-DISTANCE-gHEX[-dirty].
|
||||
|
||||
Like 'git describe --tags --dirty --always -long'.
|
||||
The distance/hash is unconditional.
|
||||
|
||||
Exceptions:
|
||||
1: no tags. HEX[-dirty] (note: no 'g' prefix)
|
||||
"""
|
||||
if pieces["closest-tag"]:
|
||||
rendered = pieces["closest-tag"]
|
||||
rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
|
||||
else:
|
||||
# exception #1
|
||||
rendered = pieces["short"]
|
||||
if pieces["dirty"]:
|
||||
rendered += "-dirty"
|
||||
return rendered
|
||||
|
||||
|
||||
def render(pieces, style):
|
||||
"""Render the given version pieces into the requested style."""
|
||||
if pieces["error"]:
|
||||
return {"version": "unknown",
|
||||
"full-revisionid": pieces.get("long"),
|
||||
"dirty": None,
|
||||
"error": pieces["error"],
|
||||
"date": None}
|
||||
|
||||
if not style or style == "default":
|
||||
style = "pep440" # the default
|
||||
|
||||
if style == "pep440":
|
||||
rendered = render_pep440(pieces)
|
||||
elif style == "pep440-pre":
|
||||
rendered = render_pep440_pre(pieces)
|
||||
elif style == "pep440-post":
|
||||
rendered = render_pep440_post(pieces)
|
||||
elif style == "pep440-old":
|
||||
rendered = render_pep440_old(pieces)
|
||||
elif style == "git-describe":
|
||||
rendered = render_git_describe(pieces)
|
||||
elif style == "git-describe-long":
|
||||
rendered = render_git_describe_long(pieces)
|
||||
else:
|
||||
raise ValueError("unknown style '%s'" % style)
|
||||
|
||||
return {"version": rendered, "full-revisionid": pieces["long"],
|
||||
"dirty": pieces["dirty"], "error": None,
|
||||
"date": pieces.get("date")}
|
||||
|
||||
|
||||
def get_versions():
|
||||
"""Get version information or return default if unable to do so."""
|
||||
# I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
|
||||
# __file__, we can work backwards from there to the root. Some
|
||||
# py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
|
||||
# case we can only use expanded keywords.
|
||||
|
||||
cfg = get_config()
|
||||
verbose = cfg.verbose
|
||||
|
||||
try:
|
||||
return git_versions_from_keywords(get_keywords(), cfg.tag_prefix,
|
||||
verbose)
|
||||
except NotThisMethod:
|
||||
pass
|
||||
|
||||
try:
|
||||
root = os.path.realpath(__file__)
|
||||
# versionfile_source is the relative path from the top of the source
|
||||
# tree (where the .git directory might live) to this file. Invert
|
||||
# this to find the root from __file__.
|
||||
for i in cfg.versionfile_source.split('/'):
|
||||
root = os.path.dirname(root)
|
||||
except NameError:
|
||||
return {"version": "0+unknown", "full-revisionid": None,
|
||||
"dirty": None,
|
||||
"error": "unable to find root of source tree",
|
||||
"date": None}
|
||||
|
||||
try:
|
||||
pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
|
||||
return render(pieces, cfg.style)
|
||||
except NotThisMethod:
|
||||
pass
|
||||
|
||||
try:
|
||||
if cfg.parentdir_prefix:
|
||||
return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
|
||||
except NotThisMethod:
|
||||
pass
|
||||
|
||||
return {"version": "0+unknown", "full-revisionid": None,
|
||||
"dirty": None,
|
||||
"error": "unable to compute version", "date": None}
|
||||
303
README.md
@@ -1,94 +1,275 @@
|
||||
# Advanced Docking System for Qt
|
||||
[](https://gitter.im/mfreiholz/Qt-Advanced-Docking-System?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
Manages content widgets more like Visual Studio or similar programs.
|
||||
I also try to get everything done with basic Qt functionality.
|
||||
Basic usage of QWidgets an QLayouts and using basic styles as much as possible.
|
||||
[](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)
|
||||
|
||||

|
||||

|
||||
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 environments (IDEs) such as Visual Studio.
|
||||
|
||||
[](https://www.youtube.com/watch?v=7pdNfafg3Qc)
|
||||
|
||||
Everything is implemented with standard Qt functionality without any
|
||||
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
|
||||
[Advanced Docking System for Qt](https://github.com/mfreiholz/Qt-Advanced-Docking-System)
|
||||
from Manuel Freiholz. I did an almost complete rewrite of his code to improve
|
||||
code quality, readibility and to fix all issues from the issue tracker
|
||||
of his docking system project.
|
||||
|
||||
## Features
|
||||
|
||||
### Overview
|
||||
|
||||
- [Advanced Docking System for Qt](#advanced-docking-system-for-qt)
|
||||
- [Features](#features)
|
||||
- [Overview](#overview)
|
||||
- [Docking everywhere - no central widget](#docking-everywhere---no-central-widget)
|
||||
- [Docking inside floating windows](#docking-inside-floating-windows)
|
||||
- [Grouped dragging](#grouped-dragging)
|
||||
- [Perspectives for fast switching of the complete main window layout](#perspectives-for-fast-switching-of-the-complete-main-window-layout)
|
||||
- [Opaque and non-opaque splitter resizing](#opaque-and-non-opaque-splitter-resizing)
|
||||
- [Opaque and non-opaque undocking](#opaque-and-non-opaque-undocking)
|
||||
- [Tab-menu for easy handling of many tabbed dock widgets](#tab-menu-for-easy-handling-of-many-tabbed-dock-widgets)
|
||||
- [Many different ways to detach dock widgets](#many-different-ways-to-detach-dock-widgets)
|
||||
- [Supports deletion of dynamically created dock widgets](#supports-deletion-of-dynamically-created-dock-widgets)
|
||||
- [Tested Compatible Environments](#tested-compatible-environments)
|
||||
- [Windows](#windows)
|
||||
- [macOS](#macos)
|
||||
- [Linux](#linux)
|
||||
- [Build](#build)
|
||||
- [Getting started / Example](#getting-started--example)
|
||||
- [Developers](#developers)
|
||||
- [License information](#license-information)
|
||||
- [Alternative Docking System Implementations](#alternative-docking-system-implementations)
|
||||
- [KDDockWidgets](#kddockwidgets)
|
||||
- [QtitanDocking](#qtitandocking)
|
||||
- [Donation](#donation)
|
||||
|
||||
### Docking everywhere - no central widget
|
||||
|
||||
There is no central widget like in the Qt docking system. You can dock on every
|
||||
border of the main window or you can dock into each dock area - so you are
|
||||
free to dock almost everywhere.
|
||||
|
||||
\
|
||||
\
|
||||

|
||||
|
||||
### Docking inside floating windows
|
||||
|
||||
There is no difference between the main window and a floating window. Docking
|
||||
into floating windows is supported.
|
||||
|
||||
\
|
||||
\
|
||||

|
||||
|
||||
### Grouped dragging
|
||||
|
||||
When dragging the titlebar of a dock, all the tabs that are tabbed with it are
|
||||
going to be dragged. So you can move complete groups of tabbed widgets into
|
||||
a floating widget or from one dock area to another one.
|
||||
|
||||
\
|
||||
\
|
||||

|
||||
|
||||
### Perspectives for fast switching of the complete main window layout
|
||||
|
||||
A perspective defines the set and layout of dock windows in the main
|
||||
window. You can save the current layout of the dockmanager into a named
|
||||
perspective to make your own custom perspective. Later you can simply
|
||||
select a perspective from the perspective list to quickly switch the complete
|
||||
main window layout.
|
||||
|
||||
\
|
||||
\
|
||||

|
||||
|
||||
### Opaque and non-opaque splitter resizing
|
||||
|
||||
The advanced docking system uses standard QSplitters as resize separators and thus supports opaque and non-opaque resizing functionality of QSplitter. In some rare cases, for very complex widgets or on slow machines resizing via separator on the fly may cause flicking and glaring of rendered content inside a widget. The global dock manager flag `OpaqueSplitterResize` configures the resizing behaviour of the splitters. If this flag is set, then widgets are resized dynamically (opaquely) while interactively moving the splitters.
|
||||
|
||||

|
||||
|
||||
If this flag is cleared, the widget resizing is deferred until the mouse button is released - this is some kind of lazy resizing separator.
|
||||
|
||||

|
||||
|
||||
### Opaque and non-opaque undocking
|
||||
|
||||
By default, opaque undocking is active. That means, as soon as you drag a dock widget or a dock area with a number of dock widgets it will be undocked and moved into a floating widget and then the floating widget will be dragged around. That means undocking will take place immediatelly. You can compare this with opaque splitter resizing. If the flag `OpaqueUndocking` is cleared, then non-opaque undocking is active. In this mode, undocking is more like a standard drag and drop operation. That means, the dragged dock widget or dock area is not undocked immediatelly. Instead, a drag preview widget is created and dragged around to indicate the future position of the dock widget or dock area. The actual dock operation is only executed when the mouse button is released. That makes it possible, to cancel an active drag operation with the escape key.
|
||||
|
||||
The drag preview widget can be configured by a number of global dock manager flags:
|
||||
- `DragPreviewIsDynamic`: if this flag is enabled, the preview will be adjusted dynamically to the drop area
|
||||
- `DragPreviewShowsContentPixmap`: the created drag preview window shows a static copy of the content of the dock widget / dock are that is dragged
|
||||
- `DragPreviewHasWindowFrame`: this flag configures if the drag preview is frameless like a QRubberBand or looks like a real window
|
||||
|
||||
The best way to test non-opaque undocking is to set the standard flags: `CDockManager::setConfigFlags(CDockManager::DefaultNonOpaqueConfig)`.
|
||||
|
||||
### Tab-menu for easy handling of many tabbed dock widgets
|
||||
|
||||
Tabs are a good way to quickly switch between dockwidgets in a dockarea. However, if the number of dockwidgets in a dockarea is too large, this may affect the usability of the tab bar. To keep track in this situation, you can use the tab menu. The menu allows you to quickly select the dockwidget you want to activate from a drop down menu.
|
||||
|
||||

|
||||
|
||||
### Many different ways to detach dock widgets
|
||||
|
||||
You can detach dock widgets and also dock areas in the following ways:
|
||||
|
||||
- by dragging the dock widget tab or the dock area title bar
|
||||
- by double clicking the tab or title bar
|
||||
- by using the detach menu entry from the tab and title bar drop down menu
|
||||
|
||||
### Supports deletion of dynamically created dock widgets
|
||||
|
||||
Normally clicking the close button of a dock widget will just hide the widget and the user can show it again using the toggleView() action of the dock widget. This is meant for user interfaces with a static amount of widgets. But the advanced docking system also supports dynamic dock widgets that will get deleted on close. If you set the dock widget flag `DockWidgetDeleteOnClose` for a certain dock widget, then it will be deleted as soon as you close this dock widget. This enables the implementation of user interfaces with dynamically created editors, like in word processing applications or source code development tools.
|
||||
|
||||
## Tested Compatible Environments
|
||||
- Windows 7 / 8 / 8.1 / 10
|
||||
- Ubuntu 15.10
|
||||
|
||||
### 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)
|
||||
[](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/actions?query=workflow%3Alinux-builds)
|
||||
|
||||
The application can be compiled for Linux and has been developed and tested with **Kubuntu 18.04** and **Kubuntu 19.10**.
|
||||
|
||||

|
||||
|
||||
and with **Ubuntu 19.10**
|
||||
|
||||

|
||||
|
||||
## Build
|
||||
Open the `build.pro` with QtCreator and start the build, that's it.
|
||||
|
||||
Open the `ads.pro` with QtCreator and start the build, that's it.
|
||||
You can run the demo project and test it yourself.
|
||||
|
||||
## Release & Development
|
||||
The `master` branch is not guaranteed to be stable or does not even build, since it is the main working branch.
|
||||
If you want a version that builds, you should always use a release/beta tag.
|
||||
|
||||
## Getting started / Example
|
||||
The following example shows the minimum code required to use ADS.
|
||||
|
||||
_MyWindow.h_
|
||||
The following example shows the minimum code required to use the advanced Qt docking system.
|
||||
|
||||
*MainWindow.h*
|
||||
|
||||
```cpp
|
||||
#include <QMainWindow>
|
||||
#include "ads/API.h"
|
||||
#include "ads/ContainerWidget.h"
|
||||
#include "ads/SectionContent.h"
|
||||
class MyWindow : public QMainWindow
|
||||
#include "DockManager.h"
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MyWindow(QWidget* parent);
|
||||
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
private:
|
||||
// The main container for dockings.
|
||||
ADS_NS::ContainerWidget* _container;
|
||||
|
||||
// You always want to keep a reference of your content,
|
||||
// in case you need to perform any action on it (show, hide, ...)
|
||||
ADS_NS::SectionContent::RefPtr _sc1;
|
||||
Ui::MainWindow *ui;
|
||||
|
||||
// The main container for docking
|
||||
ads::CDockManager* m_DockManager;
|
||||
};
|
||||
```
|
||||
|
||||
_MyWindow.cpp_
|
||||
*MainWindow.cpp*
|
||||
|
||||
```cpp
|
||||
#include "MyWindow.h"
|
||||
#include "MainWindow.h"
|
||||
#include "ui_MainWindow.h"
|
||||
|
||||
#include <QLabel>
|
||||
MyWindow::MyWindow(QWidget* parent) : QMainWindow(parent)
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
_container = new ADS_NS::ContainerWidget();
|
||||
setCentralWidget(_container);
|
||||
|
||||
_sc1 = ADS_NS::SectionContent::newSectionContent(QString("Unique-Internal-Name"), _container, new QLabel("Visible Title"), new QLabel("Content Widget"));
|
||||
_container->addSectionContent(_sc1, NULL, ADS_NS::CenterDropArea);
|
||||
ui->setupUi(this);
|
||||
|
||||
// Create the dock manager. Because the parent parameter is a QMainWindow
|
||||
// the dock manager registers itself as the central widget.
|
||||
m_DockManager = new ads::CDockManager(this);
|
||||
|
||||
// Create example content label - this can be any application specific
|
||||
// widget
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
|
||||
|
||||
// Create a dock widget with the title Label 1 and set the created label
|
||||
// as the dock widget content
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget("Label 1");
|
||||
DockWidget->setWidget(l);
|
||||
|
||||
// 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
|
||||
ui->menuView->addAction(DockWidget->toggleViewAction());
|
||||
|
||||
// Add the dock widget to the top dock widget area
|
||||
m_DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget);
|
||||
}
|
||||
|
||||
static void initStyleSheet(QApplication& a)
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
//Q_INIT_RESOURCE(ads); // If static linked.
|
||||
QFile f(":ads/stylesheets/default-windows.css");
|
||||
if (f.open(QFile::ReadOnly))
|
||||
{
|
||||
const QByteArray ba = f.readAll();
|
||||
f.close();
|
||||
a.setStyleSheet(QString(ba));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setQuitOnLastWindowClosed(true);
|
||||
initStyleSheet(a);
|
||||
|
||||
MainWindow mw;
|
||||
mw.show();
|
||||
return a.exec();
|
||||
delete ui;
|
||||
}
|
||||
```
|
||||
|
||||
## Developers
|
||||
[Manuel Freiholz](https://mfreiholz.de), Project Maintainer
|
||||
|
||||
- Uwe Kindler, Project Maintainer
|
||||
- Manuel Freiholz
|
||||
|
||||
## License information
|
||||

|
||||
|
||||
This projects uses the [WTFPL license](http://www.wtfpl.net/)
|
||||
(Do **W**hat **T**he **F**uck You Want To **P**ublic **L**icense)
|
||||
[](gnu-lgpl-v2.1.md)
|
||||
This project uses the [LGPLv2.1 license](gnu-lgpl-v2.1.md)
|
||||
|
||||
Using it? Let us know by creating a [new issue](https://github.com/mfreiholz/qt-docks/issues/new) (You don't have to, of course).
|
||||
|
||||
## Alternative Docking System Implementations
|
||||
|
||||
If this Qt Advanced Docking System does not fit to your needs you may consider some of the alternative docking system solutions for Qt.
|
||||
|
||||
### KDDockWidgets
|
||||
|
||||
This is an advanced docking framework for Qt from [KDAB](https://www.kdab.com/). The interesting thing is, that they separated GUI code from logic, so they can easily provide a QtQuick backend in the future.
|
||||
|
||||
- [Blog post about KDDockWidgets](https://www.kdab.com/kddockwidgets/)
|
||||
- [GitHub project](https://github.com/KDAB/KDDockWidgets)
|
||||
|
||||
|
||||
### QtitanDocking
|
||||
|
||||
This is a commercial component from [Developer Machines](https://www.devmachines.com/) for Qt Framework that allows to create a Microsoft like dockable user interface. They also offer a lot of other interesting and useful components for Qt.
|
||||
|
||||
- [Product page](https://www.devmachines.com/qtitandocking-overview.html)
|
||||
|
||||
## Donation
|
||||
|
||||
If this project help you reduce time to develop or if you just like it, you can give me a cup of coffee :coffee::wink:.
|
||||
|
||||
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=85R64TMMSY9T6">
|
||||
<img src="doc/donate.png" alt="Donate with PayPal" width="160"/>
|
||||
</a>
|
||||
|
||||
9
ads.pro
Normal file
@@ -0,0 +1,9 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS = \
|
||||
src \
|
||||
demo \
|
||||
example
|
||||
|
||||
demo.depends = src
|
||||
example.depends = src
|
||||
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")
|
||||
@@ -1,6 +0,0 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS = \
|
||||
AdvancedDockingSystem \
|
||||
AdvancedDockingSystemDemo \
|
||||
AdvancedDockingSystemUnitTests
|
||||
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_()
|
||||
54
demo/CMakeLists.txt
Normal file
@@ -0,0 +1,54 @@
|
||||
cmake_minimum_required(VERSION 3.3)
|
||||
set (CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
project(ads_demo VERSION "1.0")
|
||||
set(REQUIRED_QT_VERSION 5.5.0)
|
||||
find_package(Qt5Core ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt5Widgets ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
set(ads_demo_LIBS ${ads_demo_LIBS} ${Qt5Core_LIBRARIES})
|
||||
set(ads_demo_INCLUDE ${ads_demo_INCLUDE} ${Qt5Core_INCLUDE_DIRS})
|
||||
set(ads_demo_COMPILE_DEFINE ${ads_demo_COMPILE_DEFINE} ${Qt5Core_COMPILE_DEFINITIONS} )
|
||||
set(ads_demo_LIBS ${ads_demo_LIBS} ${Qt5Gui_LIBRARIES})
|
||||
set(ads_demo_INCLUDE ${ads_demo_INCLUDE} ${Qt5Gui_INCLUDE_DIRS})
|
||||
set(ads_demo_COMPILE_DEFINE ${ads_demo_COMPILE_DEFINE} ${Qt5Gui_COMPILE_DEFINITIONS})
|
||||
set(ads_demo_LIBS ${ads_demo_LIBS} ${Qt5Widgets_LIBRARIES})
|
||||
set(ads_demo_INCLUDE ${ads_demo_INCLUDE} ${Qt5Widgets_INCLUDE_DIRS})
|
||||
set(ads_demo_COMPILE_DEFINE ${ads_demo_COMPILE_DEFINE} ${Qt5Widgets_COMPILE_DEFINITIONS})
|
||||
if(WIN32)
|
||||
find_package(Qt5AxContainer ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
set(ads_demo_LIBS ${ads_demo_LIBS} ${Qt5AxContainer_LIBRARIES})
|
||||
set(ads_demo_INCLUDE ${ads_demo_INCLUDE} ${Qt5AxContainer_INCLUDE_DIRS})
|
||||
set(ads_demo_COMPILE_DEFINE ${ads_demo_COMPILE_DEFINE} ${Qt5AxContainer_COMPILE_DEFINITIONS})
|
||||
endif()
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(ads_demo_SRCS
|
||||
main.cpp
|
||||
MainWindow.cpp
|
||||
mainwindow.ui
|
||||
demo.qrc
|
||||
)
|
||||
add_executable(AdvancedDockingSystemDemo WIN32 ${ads_demo_SRCS})
|
||||
if(BUILD_STATIC)
|
||||
set(ads_demo_DEFINE ${ads_demo_DEFINE} ADS_STATIC)
|
||||
endif()
|
||||
add_dependencies(AdvancedDockingSystemDemo qtadvanceddocking)
|
||||
target_include_directories(AdvancedDockingSystemDemo PUBLIC
|
||||
$<BUILD_INTERFACE:${ads_demo_INCLUDE}>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
target_include_directories(AdvancedDockingSystemDemo PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src" ${ads_demo_INCLUDE})
|
||||
target_link_libraries(AdvancedDockingSystemDemo PRIVATE qtadvanceddocking ${ads_demo_LIBS})
|
||||
target_compile_definitions(AdvancedDockingSystemDemo PRIVATE ${ads_demo_DEFINE})
|
||||
set_target_properties(AdvancedDockingSystemDemo PROPERTIES
|
||||
VERSION "1.0"
|
||||
SOVERSION 1
|
||||
EXPORT_NAME "Qt Advanced Docking System Demo"
|
||||
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"
|
||||
)
|
||||
650
demo/MainWindow.cpp
Normal file
@@ -0,0 +1,650 @@
|
||||
|
||||
/*******************************************************************************
|
||||
** 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 MainWindow.cpp
|
||||
/// \author Uwe Kindler
|
||||
/// \date 13.02.2018
|
||||
/// \brief Implementation of CMainWindow demo class
|
||||
//============================================================================
|
||||
|
||||
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <MainWindow.h>
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QTime>
|
||||
#include <QLabel>
|
||||
#include <QTextEdit>
|
||||
#include <QCalendarWidget>
|
||||
#include <QFrame>
|
||||
#include <QTreeView>
|
||||
#include <QFileSystemModel>
|
||||
#include <QBoxLayout>
|
||||
#include <QSettings>
|
||||
#include <QDockWidget>
|
||||
#include <QDebug>
|
||||
#include <QResizeEvent>
|
||||
#include <QAction>
|
||||
#include <QWidgetAction>
|
||||
#include <QComboBox>
|
||||
#include <QInputDialog>
|
||||
#include <QRubberBand>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QTableWidget>
|
||||
#include <QScreen>
|
||||
#include <QStyle>
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
#include <QToolButton>
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QAxWidget>
|
||||
#endif
|
||||
|
||||
#include <QMap>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include "DockManager.h"
|
||||
#include "DockWidget.h"
|
||||
#include "DockAreaWidget.h"
|
||||
#include "DockAreaTitleBar.h"
|
||||
#include "DockAreaTabBar.h"
|
||||
#include "FloatingDockContainer.h"
|
||||
#include "DockComponentsFactory.h"
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createLongTextLabelDockWidget(QMenu* ViewMenu)
|
||||
{
|
||||
static int LabelCount = 0;
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText(QString("Label %1 %2 - 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.")
|
||||
.arg(LabelCount)
|
||||
.arg(QTime::currentTime().toString("hh:mm:ss:zzz")));
|
||||
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Label %1").arg(LabelCount++));
|
||||
DockWidget->setWidget(l);
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to create an SVG icon
|
||||
*/
|
||||
static QIcon svgIcon(const QString& File)
|
||||
{
|
||||
// This is a workaround, because in item views SVG icons are not
|
||||
// properly scaled an look blurry or pixelate
|
||||
QIcon SvgIcon(File);
|
||||
SvgIcon.addPixmap(SvgIcon.pixmap(92));
|
||||
return SvgIcon;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
class CCustomComponentsFactory : public ads::CDockComponentsFactory
|
||||
{
|
||||
public:
|
||||
using Super = ads::CDockComponentsFactory;
|
||||
ads::CDockAreaTitleBar* createDockAreaTitleBar(ads::CDockAreaWidget* DockArea) const override
|
||||
{
|
||||
auto TitleBar = new ads::CDockAreaTitleBar(DockArea);
|
||||
auto CustomButton = new QToolButton(DockArea);
|
||||
CustomButton->setToolTip(QObject::tr("Help"));
|
||||
CustomButton->setIcon(svgIcon(":/adsdemo/images/help_outline.svg"));
|
||||
CustomButton->setAutoRaise(true);
|
||||
int Index = TitleBar->indexOf(TitleBar->button(ads::TitleBarButtonTabsMenu));
|
||||
TitleBar->insertWidget(Index + 1, CustomButton);
|
||||
return TitleBar;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu)
|
||||
{
|
||||
static int CalendarCount = 0;
|
||||
QCalendarWidget* w = new QCalendarWidget();
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Calendar %1").arg(CalendarCount++));
|
||||
DockWidget->setWidget(w);
|
||||
DockWidget->setToggleViewActionMode(ads::CDockWidget::ActionModeShow);
|
||||
DockWidget->setIcon(svgIcon(":/adsdemo/images/date_range.svg"));
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createFileSystemTreeDockWidget(QMenu* ViewMenu)
|
||||
{
|
||||
static int FileSystemCount = 0;
|
||||
QTreeView* w = new QTreeView();
|
||||
w->setFrameShape(QFrame::NoFrame);
|
||||
QFileSystemModel* m = new QFileSystemModel(w);
|
||||
m->setRootPath(QDir::currentPath());
|
||||
w->setModel(m);
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1")
|
||||
.arg(FileSystemCount++));
|
||||
DockWidget->setWidget(w);
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createEditorWidget(QMenu* ViewMenu)
|
||||
{
|
||||
static int EditorCount = 0;
|
||||
QPlainTextEdit* w = new QPlainTextEdit();
|
||||
w->setPlaceholderText("This is an editor. If you close the editor, it will be "
|
||||
"deleted. Enter your text here.");
|
||||
w->setStyleSheet("border: none");
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Editor %1").arg(EditorCount++));
|
||||
DockWidget->setWidget(w);
|
||||
DockWidget->setIcon(svgIcon(":/adsdemo/images/edit.svg"));
|
||||
DockWidget->setFeature(ads::CDockWidget::CustomCloseHandling, true);
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
|
||||
QMenu* OptionsMenu = new QMenu(DockWidget);
|
||||
OptionsMenu->setTitle(QObject::tr("Options"));
|
||||
OptionsMenu->setToolTip(OptionsMenu->title());
|
||||
OptionsMenu->setIcon(svgIcon(":/adsdemo/images/custom-menu-button.svg"));
|
||||
auto MenuAction = OptionsMenu->menuAction();
|
||||
// The object name of the action will be set for the QToolButton that
|
||||
// is created in the dock area title bar. You can use this name for CSS
|
||||
// styling
|
||||
MenuAction->setObjectName("optionsMenu");
|
||||
DockWidget->setTitleBarActions({OptionsMenu->menuAction()});
|
||||
auto a = OptionsMenu->addAction(QObject::tr("Clear Editor"));
|
||||
w->connect(a, SIGNAL(triggered()), SLOT(clear()));
|
||||
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createTableWidget(QMenu* ViewMenu)
|
||||
{
|
||||
static int TableCount = 0;
|
||||
QTableWidget* w = new QTableWidget();
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Table %1").arg(TableCount++));
|
||||
static int colCount = 5;
|
||||
static int rowCount = 30;
|
||||
w->setColumnCount(colCount);
|
||||
w->setRowCount(rowCount);
|
||||
for (int col = 0; col < colCount; ++col)
|
||||
{
|
||||
w->setHorizontalHeaderItem(col, new QTableWidgetItem(QString("Col %1").arg(col+1)));
|
||||
for (int row = 0; row < rowCount; ++row)
|
||||
{
|
||||
w->setItem(row, col, new QTableWidgetItem(QString("T %1-%2").arg(row + 1).arg(col+1)));
|
||||
}
|
||||
}
|
||||
DockWidget->setWidget(w);
|
||||
DockWidget->setIcon(svgIcon(":/adsdemo/images/grid_on.svg"));
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
//============================================================================
|
||||
static ads::CDockWidget* createActiveXWidget(QMenu* ViewMenu, QWidget* parent = nullptr)
|
||||
{
|
||||
static int ActiveXCount = 0;
|
||||
QAxWidget* w = new QAxWidget("{6bf52a52-394a-11d3-b153-00c04f79faa6}", parent);
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Active X %1").arg(ActiveXCount++));
|
||||
DockWidget->setWidget(w);
|
||||
ViewMenu->addAction(DockWidget->toggleViewAction());
|
||||
return DockWidget;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//============================================================================
|
||||
/**
|
||||
* Private data class pimpl
|
||||
*/
|
||||
struct MainWindowPrivate
|
||||
{
|
||||
CMainWindow* _this;
|
||||
Ui::MainWindow ui;
|
||||
QAction* SavePerspectiveAction = nullptr;
|
||||
QWidgetAction* PerspectiveListAction = nullptr;
|
||||
QComboBox* PerspectiveComboBox = nullptr;
|
||||
ads::CDockManager* DockManager = nullptr;
|
||||
|
||||
MainWindowPrivate(CMainWindow* _public) : _this(_public) {}
|
||||
|
||||
/**
|
||||
* Creates the toolbar actions
|
||||
*/
|
||||
void createActions();
|
||||
|
||||
/**
|
||||
* Fill the dock manager with dock widgets
|
||||
*/
|
||||
void createContent();
|
||||
|
||||
/**
|
||||
* Saves the dock manager state and the main window geometry
|
||||
*/
|
||||
void saveState();
|
||||
|
||||
/**
|
||||
* Save the list of perspectives
|
||||
*/
|
||||
void savePerspectives();
|
||||
|
||||
/**
|
||||
* Restores the dock manager state
|
||||
*/
|
||||
void restoreState();
|
||||
|
||||
/**
|
||||
* Restore the perspective listo of the dock manager
|
||||
*/
|
||||
void restorePerspectives();
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
void MainWindowPrivate::createContent()
|
||||
{
|
||||
// Test container docking
|
||||
QMenu* ViewMenu = ui.menuView;
|
||||
auto DockWidget = createCalendarDockWidget(ViewMenu);
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
|
||||
auto SpecialDockArea = DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget);
|
||||
|
||||
// For this Special Dock Area we want to avoid dropping on the center of it (i.e. we don't want this widget to be ever tabbified):
|
||||
{
|
||||
SpecialDockArea->setAllowedAreas(ads::OuterDockAreas);
|
||||
//SpecialDockArea->setAllowedAreas({ads::LeftDockWidgetArea, ads::RightDockWidgetArea}); // just for testing
|
||||
}
|
||||
|
||||
DockManager->addDockWidget(ads::LeftDockWidgetArea, createLongTextLabelDockWidget(ViewMenu));
|
||||
auto FileSystemWidget = createFileSystemTreeDockWidget(ViewMenu);
|
||||
auto ToolBar = FileSystemWidget->createDefaultToolBar();
|
||||
ToolBar->addAction(ui.actionSaveState);
|
||||
ToolBar->addAction(ui.actionRestoreState);
|
||||
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
|
||||
appendFeaturStringToWindowTitle(FileSystemWidget);
|
||||
DockManager->addDockWidget(ads::BottomDockWidgetArea, FileSystemWidget);
|
||||
|
||||
FileSystemWidget = createFileSystemTreeDockWidget(ViewMenu);
|
||||
ToolBar = FileSystemWidget->createDefaultToolBar();
|
||||
ToolBar->addAction(ui.actionSaveState);
|
||||
ToolBar->addAction(ui.actionRestoreState);
|
||||
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
|
||||
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
|
||||
appendFeaturStringToWindowTitle(FileSystemWidget);
|
||||
|
||||
// Test custom factory - we inject a help button into the title bar
|
||||
ads::CDockComponentsFactory::setFactory(new CCustomComponentsFactory());
|
||||
auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget);
|
||||
ads::CDockComponentsFactory::resetDefaultFactory();
|
||||
|
||||
// We create a calendar widget and clear all flags to prevent the dock area
|
||||
// from closing
|
||||
DockWidget = createCalendarDockWidget(ViewMenu);
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
|
||||
DockWidget->setTabToolTip(QString("Tab ToolTip\nHodie est dies magna"));
|
||||
auto DockArea = DockManager->addDockWidget(ads::CenterDockWidgetArea, DockWidget, TopDockArea);
|
||||
|
||||
// Now we add a custom button to the dock area title bar that will create
|
||||
// new editor widgets when clicked
|
||||
auto CustomButton = new QToolButton(DockArea);
|
||||
CustomButton->setToolTip(QObject::tr("Create Editor"));
|
||||
CustomButton->setIcon(svgIcon(":/adsdemo/images/plus.svg"));
|
||||
CustomButton->setAutoRaise(true);
|
||||
auto TitleBar = DockArea->titleBar();
|
||||
int Index = TitleBar->indexOf(TitleBar->tabBar());
|
||||
TitleBar->insertWidget(Index + 1, CustomButton);
|
||||
QObject::connect(CustomButton, &QToolButton::clicked, [=]()
|
||||
{
|
||||
auto DockWidget = createEditorWidget(ui.menuView);
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
|
||||
DockManager->addDockWidgetTabToArea(DockWidget, DockArea);
|
||||
_this->connect(DockWidget, SIGNAL(closeRequested()), SLOT(onEditorCloseRequested()));
|
||||
});
|
||||
|
||||
// Test dock area docking
|
||||
auto RighDockArea = DockManager->addDockWidget(ads::RightDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), TopDockArea);
|
||||
DockManager->addDockWidget(ads::TopDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), RighDockArea);
|
||||
auto BottomDockArea = DockManager->addDockWidget(ads::BottomDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(ViewMenu), BottomDockArea);
|
||||
|
||||
auto Action = ui.menuView->addAction(QString("Set %1 floating").arg(DockWidget->windowTitle()));
|
||||
DockWidget->connect(Action, SIGNAL(triggered()), SLOT(setFloating()));
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (!DockManager->configFlags().testFlag(ads::CDockManager::OpaqueUndocking))
|
||||
{
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createActiveXWidget(ViewMenu), RighDockArea);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (auto DockWidget : DockManager->dockWidgetsMap())
|
||||
{
|
||||
_this->connect(DockWidget, SIGNAL(viewToggled(bool)), SLOT(onViewToggled(bool)));
|
||||
_this->connect(DockWidget, SIGNAL(visibilityChanged(bool)), SLOT(onViewVisibilityChanged(bool)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void MainWindowPrivate::createActions()
|
||||
{
|
||||
ui.toolBar->addAction(ui.actionSaveState);
|
||||
ui.toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
ui.actionSaveState->setIcon(svgIcon(":/adsdemo/images/save.svg"));
|
||||
ui.toolBar->addAction(ui.actionRestoreState);
|
||||
ui.actionRestoreState->setIcon(svgIcon(":/adsdemo/images/restore.svg"));
|
||||
|
||||
SavePerspectiveAction = new QAction("Create Perspective", _this);
|
||||
SavePerspectiveAction->setIcon(svgIcon(":/adsdemo/images/picture_in_picture.svg"));
|
||||
_this->connect(SavePerspectiveAction, SIGNAL(triggered()), SLOT(savePerspective()));
|
||||
PerspectiveListAction = new QWidgetAction(_this);
|
||||
PerspectiveComboBox = new QComboBox(_this);
|
||||
PerspectiveComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
PerspectiveComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
PerspectiveListAction->setDefaultWidget(PerspectiveComboBox);
|
||||
ui.toolBar->addSeparator();
|
||||
ui.toolBar->addAction(PerspectiveListAction);
|
||||
ui.toolBar->addAction(SavePerspectiveAction);
|
||||
|
||||
QAction* a = ui.toolBar->addAction("Create Editor");
|
||||
a->setToolTip("Creates floating dynamic dockable editor windows that are deleted on close");
|
||||
a->setIcon(svgIcon(":/adsdemo/images/note_add.svg"));
|
||||
_this->connect(a, SIGNAL(triggered()), SLOT(createEditor()));
|
||||
|
||||
a = ui.toolBar->addAction("Create Table");
|
||||
a->setToolTip("Creates floating dynamic dockable table with millions of entries");
|
||||
a->setIcon(svgIcon(":/adsdemo/images/grid_on.svg"));
|
||||
_this->connect(a, SIGNAL(triggered()), SLOT(createTable()));
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void MainWindowPrivate::saveState()
|
||||
{
|
||||
QSettings Settings("Settings.ini", QSettings::IniFormat);
|
||||
Settings.setValue("mainWindow/Geometry", _this->saveGeometry());
|
||||
Settings.setValue("mainWindow/State", _this->saveState());
|
||||
Settings.setValue("mainWindow/DockingState", DockManager->saveState());
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void MainWindowPrivate::restoreState()
|
||||
{
|
||||
QSettings Settings("Settings.ini", QSettings::IniFormat);
|
||||
_this->restoreGeometry(Settings.value("mainWindow/Geometry").toByteArray());
|
||||
_this->restoreState(Settings.value("mainWindow/State").toByteArray());
|
||||
DockManager->restoreState(Settings.value("mainWindow/DockingState").toByteArray());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void MainWindowPrivate::savePerspectives()
|
||||
{
|
||||
QSettings Settings("Settings.ini", QSettings::IniFormat);
|
||||
DockManager->savePerspectives(Settings);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void MainWindowPrivate::restorePerspectives()
|
||||
{
|
||||
QSettings Settings("Settings.ini", QSettings::IniFormat);
|
||||
DockManager->loadPerspectives(Settings);
|
||||
PerspectiveComboBox->clear();
|
||||
PerspectiveComboBox->addItems(DockManager->perspectiveNames());
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CMainWindow::CMainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
d(new MainWindowPrivate(this))
|
||||
{
|
||||
using namespace ads;
|
||||
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 want to use opaque undocking and
|
||||
// opaque splitter resizing
|
||||
// CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
|
||||
|
||||
// uncomment the following line if you want a fixed tab width that does
|
||||
// not change if the visibility of the close button changes
|
||||
//CDockManager::setConfigFlag(CDockManager::RetainTabSizeWhenCloseButtonHidden, true);
|
||||
|
||||
// uncomment the following line if you don't want close button on DockArea's title bar
|
||||
//CDockManager::setConfigFlag(CDockManager::DockAreaHasCloseButton, false);
|
||||
|
||||
// uncomment the following line if you don't want undock button on DockArea's title bar
|
||||
//CDockManager::setConfigFlag(CDockManager::DockAreaHasUndockButton, false);
|
||||
|
||||
// uncomment the following line if you don't want tabs menu button on DockArea's title bar
|
||||
//CDockManager::setConfigFlag(CDockManager::DockAreaHasTabsMenuButton, false);
|
||||
|
||||
// uncomment the following line if you don't want disabled buttons to appear on DockArea's title bar
|
||||
//CDockManager::setConfigFlag(CDockManager::DockAreaHideDisabledButtons, true);
|
||||
|
||||
// uncomment the following line if you want to show tabs menu button on DockArea's title bar only when there are more than one tab and at least of them has elided title
|
||||
//CDockManager::setConfigFlag(CDockManager::DockAreaDynamicTabsMenuButtonVisibility, true);
|
||||
|
||||
// uncomment the following line if you want floating container to always show application title instead of active dock widget's title
|
||||
//CDockManager::setConfigFlag(CDockManager::FloatingContainerHasWidgetTitle, false);
|
||||
|
||||
// uncomment the following line if you want floating container to show active dock widget's icon instead of always showing application icon
|
||||
//CDockManager::setConfigFlag(CDockManager::FloatingContainerHasWidgetIcon, 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
|
||||
// CDockManager::setConfigFlags({CDockManager::DockAreaHasCloseButton
|
||||
// | CDockManager::DockAreaCloseButtonClosesTab});
|
||||
connect(d->PerspectiveComboBox, SIGNAL(activated(const QString&)),
|
||||
d->DockManager, SLOT(openPerspective(const QString&)));
|
||||
|
||||
d->createContent();
|
||||
// Default window geometry - center on screen
|
||||
resize(1280, 720);
|
||||
setGeometry(QStyle::alignedRect(
|
||||
Qt::LeftToRight, Qt::AlignCenter, frameSize(),
|
||||
QGuiApplication::primaryScreen()->availableGeometry()
|
||||
));
|
||||
|
||||
//d->restoreState();
|
||||
d->restorePerspectives();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CMainWindow::~CMainWindow()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
d->saveState();
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::on_actionSaveState_triggered(bool)
|
||||
{
|
||||
qDebug() << "MainWindow::on_actionSaveState_triggered";
|
||||
d->saveState();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::on_actionRestoreState_triggered(bool)
|
||||
{
|
||||
qDebug() << "MainWindow::on_actionRestoreState_triggered";
|
||||
d->restoreState();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::savePerspective()
|
||||
{
|
||||
QString PerspectiveName = QInputDialog::getText(this, "Save Perspective", "Enter unique name:");
|
||||
if (PerspectiveName.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
d->DockManager->addPerspective(PerspectiveName);
|
||||
QSignalBlocker Blocker(d->PerspectiveComboBox);
|
||||
d->PerspectiveComboBox->clear();
|
||||
d->PerspectiveComboBox->addItems(d->DockManager->perspectiveNames());
|
||||
d->PerspectiveComboBox->setCurrentText(PerspectiveName);
|
||||
|
||||
d->savePerspectives();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::onViewToggled(bool Open)
|
||||
{
|
||||
auto DockWidget = qobject_cast<ads::CDockWidget*>(sender());
|
||||
if (!DockWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << DockWidget->objectName() << " viewToggled(" << Open << ")";
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::onViewVisibilityChanged(bool Visible)
|
||||
{
|
||||
auto DockWidget = qobject_cast<ads::CDockWidget*>(sender());
|
||||
if (!DockWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << DockWidget->objectName() << " visibilityChanged(" << Visible << ")";
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::createEditor()
|
||||
{
|
||||
auto DockWidget = createEditorWidget(d->ui.menuView);
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
|
||||
auto FloatingWidget = d->DockManager->addDockWidgetFloating(DockWidget);
|
||||
FloatingWidget->move(QPoint(20, 20));
|
||||
connect(DockWidget, SIGNAL(closeRequested()), SLOT(onEditorCloseRequested()));
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::onEditorCloseRequested()
|
||||
{
|
||||
auto DockWidget = qobject_cast<ads::CDockWidget*>(sender());
|
||||
int Result = QMessageBox::question(this, "Close Editor", QString("Editor %1 "
|
||||
"contains unsaved changes? Would you like to close it?")
|
||||
.arg(DockWidget->windowTitle()));
|
||||
if (QMessageBox::Yes == Result)
|
||||
{
|
||||
DockWidget->closeDockWidget();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CMainWindow::createTable()
|
||||
{
|
||||
auto DockWidget = createTableWidget(d->ui.menuView);
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetDeleteOnClose, true);
|
||||
auto FloatingWidget = d->DockManager->addDockWidgetFloating(DockWidget);
|
||||
FloatingWidget->move(QPoint(40, 40));
|
||||
}
|
||||
|
||||
68
demo/MainWindow.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_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 MainWindow.h
|
||||
/// \author Uwe Kindler
|
||||
/// \date 13.02.2018
|
||||
/// \brief Declaration of CMainWindow class
|
||||
//============================================================================
|
||||
|
||||
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <QMainWindow>
|
||||
|
||||
|
||||
|
||||
struct MainWindowPrivate;
|
||||
|
||||
|
||||
/**
|
||||
* Simple main window for demo
|
||||
*/
|
||||
class CMainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
MainWindowPrivate* d;///< private data - pimpl
|
||||
friend struct MainWindowPrivate;
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent* event) override;
|
||||
|
||||
public:
|
||||
explicit CMainWindow(QWidget *parent = 0);
|
||||
virtual ~CMainWindow();
|
||||
|
||||
private slots:
|
||||
void on_actionSaveState_triggered(bool);
|
||||
void on_actionRestoreState_triggered(bool);
|
||||
void savePerspective();
|
||||
void onViewToggled(bool Open);
|
||||
void onViewVisibilityChanged(bool Visible);
|
||||
void createEditor();
|
||||
void createTable();
|
||||
void onEditorCloseRequested();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
4
demo/app.css
Normal file
@@ -0,0 +1,4 @@
|
||||
ads--CTitleBarButton::menu-indicator
|
||||
{
|
||||
image: none;
|
||||
}
|
||||
51
demo/demo.pro
Normal file
@@ -0,0 +1,51 @@
|
||||
ADS_OUT_ROOT = $${OUT_PWD}/..
|
||||
|
||||
TARGET = AdvancedDockingSystemDemo
|
||||
DESTDIR = $${ADS_OUT_ROOT}/lib
|
||||
QT += core gui widgets
|
||||
|
||||
win32 {
|
||||
QT += axcontainer
|
||||
}
|
||||
|
||||
CONFIG += c++14
|
||||
CONFIG += debug_and_release
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
adsBuildStatic {
|
||||
DEFINES += ADS_STATIC
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
MainWindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
MainWindow.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
||||
RESOURCES += demo.qrc
|
||||
|
||||
|
||||
LIBS += -L$${ADS_OUT_ROOT}/lib
|
||||
|
||||
# Dependency: AdvancedDockingSystem (shared)
|
||||
CONFIG(debug, debug|release){
|
||||
win32 {
|
||||
LIBS += -lqtadvanceddockingd
|
||||
}
|
||||
else:mac {
|
||||
LIBS += -lqtadvanceddocking_debug
|
||||
}
|
||||
else {
|
||||
LIBS += -lqtadvanceddocking
|
||||
}
|
||||
}
|
||||
else{
|
||||
LIBS += -lqtadvanceddocking
|
||||
}
|
||||
|
||||
INCLUDEPATH += ../src
|
||||
DEPENDPATH += ../src
|
||||
17
demo/demo.qrc
Normal file
@@ -0,0 +1,17 @@
|
||||
<RCC>
|
||||
<qresource prefix="/adsdemo">
|
||||
<file>images/folder.svg</file>
|
||||
<file>images/folder_open.svg</file>
|
||||
<file>images/note_add.svg</file>
|
||||
<file>images/picture_in_picture.svg</file>
|
||||
<file>images/restore.svg</file>
|
||||
<file>images/save.svg</file>
|
||||
<file>images/date_range.svg</file>
|
||||
<file>images/edit.svg</file>
|
||||
<file>images/grid_on.svg</file>
|
||||
<file>images/custom-menu-button.svg</file>
|
||||
<file>app.css</file>
|
||||
<file>images/plus.svg</file>
|
||||
<file>images/help_outline.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
32
demo/images/custom-menu-button.svg
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="16px" height="16px" viewBox="0 0 16 16" id="svg2" version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="38 - menu bar lines option list hamburger web.svg">
|
||||
<defs id="defs4">
|
||||
<pattern y="0" x="0" height="6" width="6" patternUnits="userSpaceOnUse" id="EMFhbasepattern"/>
|
||||
<pattern y="0" x="0" height="6" width="6" patternUnits="userSpaceOnUse" id="EMFhbasepattern-4"/>
|
||||
<pattern y="0" x="0" height="6" width="6" patternUnits="userSpaceOnUse" id="EMFhbasepattern-3"/>
|
||||
<pattern y="0" x="0" height="6" width="6" patternUnits="userSpaceOnUse" id="EMFhbasepattern-8"/>
|
||||
</defs>
|
||||
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="22.627417" inkscape:cx="6.2316889" inkscape:cy="7.4271635" inkscape:document-units="px" inkscape:current-layer="g5228" showgrid="true" units="px" inkscape:window-width="1366" inkscape:window-height="705" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" inkscape:snap-bbox="true" inkscape:bbox-paths="true" inkscape:bbox-nodes="true" inkscape:snap-bbox-edge-midpoints="true" inkscape:snap-bbox-midpoints="true" inkscape:snap-global="true">
|
||||
<inkscape:grid type="xygrid" id="grid3336"/>
|
||||
</sodipodi:namedview>
|
||||
|
||||
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-1036.3622)">
|
||||
<g transform="translate(628,-140.49998)" id="g5228">
|
||||
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="M 4.484375 4 A 0.50005 0.50005 0 0 0 4.5351562 5 L 11.464844 5 A 0.50005 0.50005 0 1 0 11.464844 4 L 4.5351562 4 A 0.50005 0.50005 0 0 0 4.484375 4 z M 4.484375 7 A 0.50005 0.50005 0 0 0 4.5351562 8 L 11.464844 8 A 0.50005 0.50005 0 1 0 11.464844 7 L 4.5351562 7 A 0.50005 0.50005 0 0 0 4.484375 7 z M 4.484375 10 A 0.50005 0.50005 0 0 0 4.5351562 11 L 11.464844 11 A 0.50005 0.50005 0 1 0 11.464844 10 L 4.5351562 10 A 0.50005 0.50005 0 0 0 4.484375 10 z " transform="translate(-628,1176.8622)" id="path3340"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
|
||||
|
||||
|
||||
<metadata>
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<rdf:Description about="https://iconscout.com/legal#licenses" dc:title="Menu, Bar, Lines, Option, List, Hamburger, Web" dc:description="Menu, Bar, Lines, Option, List, Hamburger, Web" dc:publisher="Iconscout" dc:date="2016-12-14" dc:format="image/svg+xml" dc:language="en">
|
||||
<dc:creator>
|
||||
<rdf:Bag>
|
||||
<rdf:li>Jemis Mali</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:creator>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</metadata></svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
6
demo/images/date_range.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||
<desc>date_range icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||
<path d="M896,256v597.33c0,46.93 -38.4,85.34 -85.33,85.34h-597.34c-47.36,0 -85.33,-38.41 -85.33,-85.34l0.43,-597.33c0,-46.93 37.54,-85.33 84.9,-85.33h42.67v-85.34h85.33v85.34h341.34v-85.34h85.33v85.34h42.67c46.93,0 85.33,38.4 85.33,85.33zM810.67,384h-597.34v469.33h597.34zM384,554.67h-85.33v-85.34h85.33zM554.67,554.67h-85.34v-85.34h85.34zM725.33,554.67h-85.33v-85.34h85.33z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 783 B |
6
demo/images/edit.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||
<desc>create icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||
<path d="M599.89,264.11l160,160l-471.89,471.89h-160v-160zM805.55,378.45l-160,-160l78.08,-78.08c16.64,-16.64 43.52,-16.64 60.16,0l99.84,99.84c16.64,16.64 16.64,43.52 0,60.16z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 578 B |
6
demo/images/folder.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||
<desc>folder icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||
<path d="M512,256h341.33c46.93,0 85.34,38.4 85.34,85.33v426.67c0,46.93 -38.41,85.33 -85.34,85.33h-682.66c-46.93,0 -85.34,-38.4 -85.34,-85.33l0.43,-512c0,-46.93 37.98,-85.33 84.91,-85.33h256z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 595 B |
6
demo/images/folder_open.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||
<desc>folder_open icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||
<path d="M938.67,341.33v426.67c0,46.93 -38.41,85.33 -85.34,85.33h-682.66c-46.93,0 -85.34,-38.4 -85.34,-85.33l0.43,-512c0,-46.93 37.98,-85.33 84.91,-85.33h256l85.33,85.33h341.33c46.93,0 85.34,38.4 85.34,85.33zM853.33,341.33h-682.66v426.67h682.66z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 655 B |
6
demo/images/grid_on.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||
<desc>grid_on icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||
<path d="M938.67,170.67v682.66c0,46.93 -38.41,85.34 -85.34,85.34h-682.66c-46.93,0 -85.34,-38.41 -85.34,-85.34v-682.66c0,-46.93 38.41,-85.34 85.34,-85.34h682.66c46.93,0 85.34,38.41 85.34,85.34zM341.33,170.67h-170.66v170.66h170.66zM341.33,682.67h-170.66v170.66h170.66zM341.33,426.67h-170.66v170.66h170.66zM597.33,170.67h-170.66v170.66h170.66zM853.33,170.67h-170.66v170.66h170.66zM597.33,682.67h-170.66v170.66h170.66zM597.33,426.67h-170.66v170.66h170.66zM853.33,682.67h-170.66v170.66h170.66zM853.33,426.67h-170.66v170.66h170.66z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 931 B |
6
demo/images/help_outline.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||
<desc>help_outline icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||
<path d="M938.67,512c0,235.52 -191.15,426.67 -426.67,426.67c-235.52,0 -426.67,-191.15 -426.67,-426.67c0,-235.52 191.15,-426.67 426.67,-426.67c235.52,0 426.67,191.15 426.67,426.67zM853.33,512c0,-188.16 -153.17,-341.33 -341.33,-341.33c-188.16,0 -341.33,153.17 -341.33,341.33c0,188.16 153.17,341.33 341.33,341.33c188.16,0 341.33,-153.17 341.33,-341.33zM682.67,426.67c0,106.67 -128,117.33 -128,213.33h-85.34c0,-138.67 128,-128 128,-213.33c0,-46.93 -38.4,-85.34 -85.33,-85.34c-46.93,0 -85.33,38.41 -85.33,85.34h-85.34c0,-94.29 76.38,-170.67 170.67,-170.67c94.29,0 170.67,76.38 170.67,170.67zM469.33,682.67h85.34v85.33h-85.34z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
211
demo/images/material_icons_license.txt
Normal file
@@ -0,0 +1,211 @@
|
||||
The Google Material icons and modifications can be used free of charge for
|
||||
commerical and non-commerical projects according to the Apache License 2.0.
|
||||
|
||||
An attribution to https://material.io/icons/ and/or https://iconfu.com on
|
||||
your website or in your app's "about" screen would be wonderful.
|
||||
|
||||
Please do not re-sell the icons.
|
||||
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
6
demo/images/note_add.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||
<desc>note_add icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||
<path d="M853.33,341.33v512c0,46.93 -38.4,85.34 -85.33,85.34h-512.43c-46.93,0 -84.9,-38.41 -84.9,-85.34l0.42,-682.66c0,-46.93 37.98,-85.34 84.91,-85.34h341.33zM682.67,597.33h-128v-128h-85.34v128h-128v85.34h128v128h85.34v-128h128zM789.33,384l-234.66,-234.67v234.67z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 671 B |
6
demo/images/picture_in_picture.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||
<desc>picture_in_picture icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||
<path d="M981.33,213.33v597.34c0,46.93 -38.4,84.48 -85.33,84.48h-768c-46.93,0 -85.33,-37.55 -85.33,-84.48v-597.34c0,-46.93 38.4,-85.33 85.33,-85.33h768c46.93,0 85.33,38.4 85.33,85.33zM896,212.48h-768v598.61h768zM810.67,554.67h-341.34v-256h341.34z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 663 B |
123
demo/images/plus.svg
Normal file
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16px"
|
||||
height="16px"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="plus.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-4" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-3" />
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
height="6"
|
||||
width="6"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="EMFhbasepattern-8" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="-2.5629517"
|
||||
inkscape:cy="7.4271635"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g5228"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3336" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1036.3622)">
|
||||
<g
|
||||
transform="translate(628,-140.49998)"
|
||||
id="g5228">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -620.5,1189.8622 v -11"
|
||||
id="path822-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -615,1184.3622 h -11"
|
||||
id="path822-5-2"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<rdf:Description
|
||||
about="https://iconscout.com/legal#licenses"
|
||||
dc:title="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:description="Menu, Bar, Lines, Option, List, Hamburger, Web"
|
||||
dc:publisher="Iconscout"
|
||||
dc:date="2016-12-14"
|
||||
dc:format="image/svg+xml"
|
||||
dc:language="en">
|
||||
<dc:creator>
|
||||
<rdf:Bag>
|
||||
<rdf:li>Jemis Mali</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:creator>
|
||||
</rdf:Description>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
6
demo/images/restore.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||
<desc>restore icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||
<path d="M938.67,512c0,212.05 -171.95,384 -384,384c-106.24,0 -201.81,-43.09 -271.36,-112.64l60.58,-60.59c53.76,54.19 128.43,87.9 210.78,87.9c165.12,0 298.66,-133.55 298.66,-298.67c0,-165.12 -133.54,-298.67 -298.66,-298.67c-165.12,0 -298.67,133.55 -298.67,298.67h128l-172.37,171.95l-2.99,-5.98l-165.97,-165.97h128c0,-212.05 171.95,-384 384,-384c212.05,0 384,171.95 384,384zM576,341.33v181.34l149.33,88.74l-30.72,51.63l-182.61,-108.37v-213.34z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 847 B |
6
demo/images/save.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,1024,1024">
|
||||
<desc>save icon - Licensed under Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - Created with Iconfu.com - Derivative work of Material icons (Copyright Google Inc.)</desc>
|
||||
<g fill="#03b8e5" fill-rule="nonzero" style="mix-blend-mode: normal">
|
||||
<path d="M896,298.67v512c0,46.93 -38.4,85.33 -85.33,85.33h-597.34c-47.36,0 -85.33,-38.4 -85.33,-85.33v-597.34c0,-46.93 37.97,-85.33 85.33,-85.33h512zM640,213.33h-426.67v170.67h426.67zM640,682.67c0,-70.83 -57.17,-128 -128,-128c-70.83,0 -128,57.17 -128,128c0,70.83 57.17,128 128,128c70.83,0 128,-57.17 128,-128z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 712 B |
58
demo/main.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <MainWindow.h>
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
QByteArray localMsg = msg.toLocal8Bit();
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
fprintf(stdout, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
||||
break;
|
||||
case QtInfoMsg:
|
||||
fprintf(stdout, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
||||
abort();
|
||||
}
|
||||
|
||||
fflush(stderr);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if QT_VERSION >= 0x050600
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
std::shared_ptr<int> b;
|
||||
QApplication a(argc, argv);
|
||||
a.setQuitOnLastWindowClosed(true);
|
||||
|
||||
QFile StyleSheetFile(":/adsdemo/app.css");
|
||||
StyleSheetFile.open(QIODevice::ReadOnly);
|
||||
QTextStream StyleSheetStream(&StyleSheetFile);
|
||||
a.setStyleSheet(StyleSheetStream.readAll());
|
||||
StyleSheetFile.close();
|
||||
|
||||
qInstallMessageHandler(myMessageOutput);
|
||||
qDebug() << "Message handler test";
|
||||
|
||||
CMainWindow mw;
|
||||
mw.show();
|
||||
return a.exec();
|
||||
}
|
||||
@@ -1,79 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget"/>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<addaction name="actionExit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
<string>View</string>
|
||||
</property>
|
||||
<addaction name="actionContentList"/>
|
||||
<addaction name="actionDemo_2"/>
|
||||
<addaction name="actionDemo_3"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuAbout">
|
||||
<property name="title">
|
||||
<string>About</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuAbout"/>
|
||||
</widget>
|
||||
<action name="actionAddSectionContent">
|
||||
<property name="text">
|
||||
<string>Add SectionContent</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionContentList">
|
||||
<property name="text">
|
||||
<string>Contents...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDemo_2">
|
||||
<property name="text">
|
||||
<string>Demo 2</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDemo_3">
|
||||
<property name="text">
|
||||
<string>Demo 3</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExit">
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<property name="dockOptions">
|
||||
<set>QMainWindow::AllowTabbedDocks</set>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget"/>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<addaction name="actionExit"/>
|
||||
<addaction name="actionSaveState"/>
|
||||
<addaction name="actionRestoreState"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
<string>View</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuAbout">
|
||||
<property name="title">
|
||||
<string>About</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuAbout"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<action name="actionExit">
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveState">
|
||||
<property name="text">
|
||||
<string>Save State</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRestoreState">
|
||||
<property name="text">
|
||||
<string>Restore State</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
BIN
doc/TabMenu.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
doc/TabMenu_dark.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
123
doc/ads_icon.svg
Normal file
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
viewBox="0,0,1024,1024"
|
||||
id="svg1145"
|
||||
sodipodi:docname="ads_icon.svg"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
inkscape:export-filename="C:\CodingXP\cetoni_projects\QtAdvancedDockingSystem\doc\ads_icon_256.png"
|
||||
inkscape:export-xdpi="24"
|
||||
inkscape:export-ydpi="24">
|
||||
<metadata
|
||||
id="metadata1151">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs1149" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
id="namedview1147"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.32593202"
|
||||
inkscape:cx="256.13402"
|
||||
inkscape:cy="235.82602"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg1145" />
|
||||
<desc
|
||||
id="desc1129">window_size icon - Licensed under Iconfu Standard License v1.0 (https://www.iconfu.com/iconfu_standard_license) - Incors GmbH</desc>
|
||||
<path
|
||||
id="path1797-1"
|
||||
visibility="hidden"
|
||||
d="M 71.53142,291.89723 H 950.1828 l 0.6743,0.6742 v 586.08 l -0.6743,0.6743 H 71.53142 l -0.6743,-0.6743 v -586.08 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="visibility:hidden;mix-blend-mode:normal;fill:#ffffff;fill-rule:nonzero;stroke-width:0.99999988;fill-opacity:1" />
|
||||
<rect
|
||||
transform="rotate(-90)"
|
||||
y="412.13489"
|
||||
x="-911.34436"
|
||||
height="560.90375"
|
||||
width="327.70862"
|
||||
id="rect1739-8"
|
||||
style="opacity:1;fill:#ffd292;fill-opacity:1;stroke:none;stroke-width:37.79526901;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke" />
|
||||
<path
|
||||
id="path1799"
|
||||
d="M 988.40121,578.11175 V 651.2546 H 409.96541 V 578.11175 Z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="mix-blend-mode:normal;fill:#546e7a;fill-rule:nonzero;stroke-width:0.99999988" />
|
||||
<rect
|
||||
style="opacity:1;fill:#b3c3cb;fill-opacity:1;stroke:none;stroke-width:37.79526901;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
id="rect1739-6-1"
|
||||
width="655.41724"
|
||||
height="338.99207"
|
||||
x="-914.85529"
|
||||
y="38.243896"
|
||||
transform="rotate(-90)" />
|
||||
<path
|
||||
id="path1801-7"
|
||||
d="m 73.1429,73.14287 h 877.7142 c 40.2857,0 73.1429,32.86857 73.1429,73.14285 V 914.2857 c 0,20.12571 -16.4458,36.57142 -36.5715,36.57142 H 36.5714 C 16.4343,950.85712 0,934.42284 0,914.2857 V 146.28572 C 0,106.00001 32.8571,73.14287 73.1429,73.14287 Z m 0,219.42856 V 877.71427 H 950.8571 V 292.57143 Z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="mix-blend-mode:normal;fill:#546e7a;fill-rule:nonzero;stroke-width:0.99999988" />
|
||||
<path
|
||||
id="path1799-6"
|
||||
d="M 359.8801,276.79402 H 433.023 V 886.78767 H 359.8801 Z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="mix-blend-mode:normal;fill:#546e7a;fill-rule:nonzero;stroke-width:0.99999988" />
|
||||
<circle
|
||||
r="36.81749"
|
||||
cy="169.78555"
|
||||
cx="920.66248"
|
||||
id="path1917-42"
|
||||
style="opacity:1;fill:#ffa726;fill-opacity:1;stroke:none;stroke-width:63.79999924;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
|
||||
<circle
|
||||
r="36.81749"
|
||||
cy="169.78555"
|
||||
cx="817.22302"
|
||||
id="path1917-4-6"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:63.79999924;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
|
||||
<path
|
||||
id="path1799-8"
|
||||
d="m 615.67076,292.13464 v 73.14285 H 433.023 v -73.14285 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="mix-blend-mode:normal;fill:#95abb6;fill-rule:nonzero;stroke-width:0.99999994;fill-opacity:1" />
|
||||
<path
|
||||
id="path1799-8-1"
|
||||
d="m 798.31852,292.13464 v 73.14285 H 615.67076 v -73.14285 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="mix-blend-mode:normal;fill:#c7d4d9;fill-rule:nonzero;stroke-width:0.99999994;fill-opacity:1" />
|
||||
<path
|
||||
id="path1799-8-7"
|
||||
d="m 255.79066,292.57143 v 73.14285 H 73.1429 v -73.14285 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="mix-blend-mode:normal;fill:#dfe5e9;fill-opacity:1;fill-rule:nonzero;stroke-width:0.99999994" />
|
||||
<path
|
||||
id="path1799-8-7-6"
|
||||
d="m 616.34083,651.15739 v 73.14285 H 433.69307 v -73.14285 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="mix-blend-mode:normal;fill:#ffba56;fill-opacity:1;fill-rule:nonzero;stroke-width:0.99999994" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
BIN
doc/ads_icon_256.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
doc/ads_icon_512.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
109
doc/ads_qt_marketplace_description.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Advanced Docking System for Qt
|
||||
|
||||
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 environments (IDEs) such as Visual Studio.
|
||||
|
||||
[](https://www.youtube.com/watch?v=7pdNfafg3Qc)
|
||||
|
||||
Everything is implemented with standard Qt functionality without any
|
||||
platform specific code. Basic usage of QWidgets and QLayouts and using basic
|
||||
styles as much as possible.
|
||||
|
||||
## Features
|
||||
|
||||
### Overview
|
||||
|
||||
- [Advanced Docking System for Qt](#advanced-docking-system-for-qt)
|
||||
- [Features](#features)
|
||||
- [Overview](#overview)
|
||||
- [Docking everywhere - no central widget](#docking-everywhere---no-central-widget)
|
||||
- [Docking inside floating windows](#docking-inside-floating-windows)
|
||||
- [Grouped dragging](#grouped-dragging)
|
||||
- [Perspectives for fast switching of the complete main window layout](#perspectives-for-fast-switching-of-the-complete-main-window-layout)
|
||||
- [Opaque and non-opaque splitter resizing](#opaque-and-non-opaque-splitter-resizing)
|
||||
- [Opaque and non-opaque undocking](#opaque-and-non-opaque-undocking)
|
||||
- [Tab-menu for easy handling of many tabbed dock widgets](#tab-menu-for-easy-handling-of-many-tabbed-dock-widgets)
|
||||
- [Many different ways to detach dock widgets](#many-different-ways-to-detach-dock-widgets)
|
||||
- [Supports deletion of dynamically created dock widgets](#supports-deletion-of-dynamically-created-dock-widgets)
|
||||
|
||||
### Docking everywhere - no central widget
|
||||
|
||||
There is no central widget like in the Qt docking system. You can dock on every
|
||||
border of the main window or you can dock into each dock area - so you are
|
||||
free to dock almost everywhere.
|
||||
|
||||
\
|
||||
\
|
||||

|
||||
|
||||
### Docking inside floating windows
|
||||
|
||||
There is no difference between the main window and a floating window. Docking
|
||||
into floating windows is supported.
|
||||
|
||||
\
|
||||
\
|
||||

|
||||
|
||||
### Grouped dragging
|
||||
|
||||
When dragging the titlebar of a dock, all the tabs that are tabbed with it are
|
||||
going to be dragged. So you can move complete groups of tabbed widgets into
|
||||
a floating widget or from one dock area to another one.
|
||||
|
||||
\
|
||||
\
|
||||

|
||||
|
||||
### Perspectives for fast switching of the complete main window layout
|
||||
|
||||
A perspective defines the set and layout of dock windows in the main
|
||||
window. You can save the current layout of the dockmanager into a named
|
||||
perspective to make your own custom perspective. Later you can simply
|
||||
select a perspective from the perspective list to quickly switch the complete
|
||||
main window layout.
|
||||
|
||||
\
|
||||
\
|
||||

|
||||
|
||||
### Opaque and non-opaque splitter resizing
|
||||
|
||||
The advanced docking system uses standard QSplitters as resize separators and thus supports opaque and non-opaque resizing functionality of QSplitter. In some rare cases, for very complex widgets or on slow machines resizing via separator on the fly may cause flicking and glaring of rendered content inside a widget. The global dock manager flag `OpaqueSplitterResize` configures the resizing behaviour of the splitters. If this flag is set, then widgets are resized dynamically (opaquely) while interactively moving the splitters.
|
||||
|
||||

|
||||
|
||||
If this flag is cleared, the widget resizing is deferred until the mouse button is released - this is some kind of lazy resizing separator.
|
||||
|
||||

|
||||
|
||||
### Opaque and non-opaque undocking
|
||||
|
||||
By default, opaque undocking is active. That means, as soon as you drag a dock widget or a dock area with a number of dock widgets it will be undocked and moved into a floating widget and then the floating widget will be dragged around. That means undocking will take place immediatelly. You can compare this with opaque splitter resizing. If the flag `OpaqueUndocking` is cleared, then non-opaque undocking is active. In this mode, undocking is more like a standard drag and drop operation. That means, the dragged dock widget or dock area is not undocked immediatelly. Instead, a drag preview widget is created and dragged around to indicate the future position of the dock widget or dock area. The actual dock operation is only executed when the mouse button is released. That makes it possible, to cancel an active drag operation with the escape key.
|
||||
|
||||
The drag preview widget can be configured by a number of global dock manager flags:
|
||||
|
||||
- `DragPreviewIsDynamic`: if this flag is enabled, the preview will be adjusted dynamically to the drop area
|
||||
- `DragPreviewShowsContentPixmap`: the created drag preview window shows a static copy of the content of the dock widget / dock are that is dragged
|
||||
- `DragPreviewHasWindowFrame`: this flag configures if the drag preview is frameless like a QRubberBand or looks like a real window
|
||||
|
||||
The best way to test non-opaque undocking is to set the standard flags: `CDockManager::setConfigFlags(CDockManager::DefaultNonOpaqueConfig)`.
|
||||
|
||||
### Tab-menu for easy handling of many tabbed dock widgets
|
||||
|
||||
Tabs are a good way to quickly switch between dockwidgets in a dockarea. However, if the number of dockwidgets in a dockarea is too large, this may affect the usability of the tab bar. To keep track in this situation, you can use the tab menu. The menu allows you to quickly select the dockwidget you want to activate from a drop down menu.
|
||||
|
||||

|
||||
|
||||
### Many different ways to detach dock widgets
|
||||
|
||||
You can detach dock widgets and also dock areas in the following ways:
|
||||
|
||||
- by dragging the dock widget tab or the dock area title bar
|
||||
- by double clicking the tab or title bar
|
||||
- by using the detach menu entry from the tab and title bar drop down menu
|
||||
|
||||
### Supports deletion of dynamically created dock widgets
|
||||
|
||||
Normally clicking the close button of a dock widget will just hide the widget and the user can show it again using the toggleView() action of the dock widget. This is meant for user interfaces with a static amount of widgets. But the advanced docking system also supports dynamic dock widgets that will get deleted on close. If you set the dock widget flag `DockWidgetDeleteOnClose` for a certain dock widget, then it will be deleted as soon as you close this dock widget. This enables the implementation of user interfaces with dynamically created editors, like in word processing applications or source code development tools.
|
||||
30
doc/ads_qt_marketplace_manifest.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"$schema": "http://qt.io/schema/extension-schema-v1#",
|
||||
"title": "Qt Advanced Docking System",
|
||||
"extensionType": [
|
||||
"library"
|
||||
],
|
||||
"version": "3.0.0",
|
||||
"vendor": {
|
||||
"name": "githubuser0xFFFF",
|
||||
"url": "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System"
|
||||
},
|
||||
"contact": "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues",
|
||||
"icon": "https://raw.githubusercontent.com/githubuser0xFFFF/Qt-Advanced-Docking-System/master/doc/ads_icon_512.png",
|
||||
"licenses": [
|
||||
{ "licenseType": "LGPLv2.1",
|
||||
"licenseUrl": "https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" }
|
||||
],
|
||||
"created": "2017-03-30",
|
||||
"lastUpdate": "2020-01-16",
|
||||
"platforms": [
|
||||
"Windows 7-10", "Kubuntu 18.04", "Kubuntu 19.10", "Ubuntu 19.10"
|
||||
],
|
||||
"qtVersions": [
|
||||
"5.5.1 or newer"
|
||||
],
|
||||
"tags": [
|
||||
"Widgets", "Docking"],
|
||||
"bugUrl": "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues",
|
||||
"sourceRepoUrl": "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System"
|
||||
}
|
||||
BIN
doc/advanced-docking_video.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
doc/donate.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
doc/floating-widget-dragndrop.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
doc/floating-widget-dragndrop_dark.png
Normal file
|
After Width: | Height: | Size: 123 KiB |
BIN
doc/grouped-dragging.gif
Normal file
|
After Width: | Height: | Size: 523 KiB |
BIN
doc/grouped-dragging.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
doc/grouped-dragging_dark.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
doc/linux_kubuntu_1804.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
doc/linux_ubuntu_1910.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
doc/macos.png
Normal file
|
After Width: | Height: | Size: 571 KiB |