Compare commits
721 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a784f1222 | ||
|
|
4a390696d5 | ||
|
|
68aaccadab | ||
|
|
3940228b59 | ||
|
|
f8abe48c82 | ||
|
|
86db81e5b7 | ||
|
|
34676f016f | ||
|
|
4448891315 | ||
|
|
fc1f12b77c | ||
|
|
a50057f5d2 | ||
|
|
d7b32e475e | ||
|
|
8b695eec79 | ||
|
|
c85904c67e | ||
|
|
22a709a39e | ||
|
|
4f4a5de700 | ||
|
|
08ecbb2ca6 | ||
|
|
048b494874 | ||
|
|
1539d7233b | ||
|
|
214dbdf359 | ||
|
|
473ce60340 | ||
|
|
74ba8c6bd2 | ||
|
|
11a1023e79 | ||
|
|
3c5f07ac79 | ||
|
|
ec4a4d1c86 | ||
|
|
5ef330f479 | ||
|
|
bbdbadd630 | ||
|
|
80a1483617 | ||
|
|
8800c02403 | ||
|
|
dd9ec48979 | ||
|
|
262d703608 | ||
|
|
5629e1dfc2 | ||
|
|
7001aa58ce | ||
|
|
d87898b59e | ||
|
|
d1078adad2 | ||
|
|
e4f0fae7e5 | ||
|
|
4b06706d61 | ||
|
|
7e1331bd76 | ||
|
|
f735f25fb0 | ||
|
|
750c089ab0 | ||
|
|
3088f33837 | ||
|
|
1d598d2585 | ||
|
|
768c51f01c | ||
|
|
a2e2b32fc3 | ||
|
|
a6abf73669 | ||
|
|
a6e62ec74d | ||
|
|
93441a5754 | ||
|
|
fe57686715 | ||
|
|
330f5aebdf | ||
|
|
02c17e59dd | ||
|
|
be8af12a90 | ||
|
|
238193f56b | ||
|
|
54233085a4 | ||
|
|
2241b938c9 | ||
|
|
631d036c26 | ||
|
|
d70f795dea | ||
|
|
0be99d3e79 | ||
|
|
45aab49be7 | ||
|
|
2c66238791 | ||
|
|
bec1ddae67 | ||
|
|
913d3b263d | ||
|
|
614e20a183 | ||
|
|
f9f270980d | ||
|
|
763b878ca1 | ||
|
|
d3d040adee | ||
|
|
31f5cc10cf | ||
|
|
38c9a3d9c6 | ||
|
|
362f2d5750 | ||
|
|
463b6a1322 | ||
|
|
00a95ac468 | ||
|
|
966f30e356 | ||
|
|
f0217f53c2 | ||
|
|
ced1c4dcc8 | ||
|
|
e1578436d0 | ||
|
|
701df72db6 | ||
|
|
c4ebef1f1e | ||
|
|
6f0eb7a2f2 | ||
|
|
be6c3ca2df | ||
|
|
18b49686f1 | ||
|
|
02d4611501 | ||
|
|
2fe8117e80 | ||
|
|
457ea402d5 | ||
|
|
89623eb8b4 | ||
|
|
df02382387 | ||
|
|
7470d62b7c | ||
|
|
9eb9018f47 | ||
|
|
d7bcbe666c | ||
|
|
aaa5b4ba26 | ||
|
|
720dad1ed6 | ||
|
|
6417db6d91 | ||
|
|
ec681e99ca | ||
|
|
47ef203643 | ||
|
|
844aa2f36a | ||
|
|
e2e8f10948 | ||
|
|
1c49e2297a | ||
|
|
6f031e3c33 | ||
|
|
f74fd52d53 | ||
|
|
2d4cef670b | ||
|
|
dfaf455624 | ||
|
|
5d2e09de36 | ||
|
|
c86de50032 | ||
|
|
5ff720f432 | ||
|
|
6f7e47324c | ||
|
|
b68f81779c | ||
|
|
4c1b433269 | ||
|
|
7c63da18ed | ||
|
|
6f2e5ecc3b | ||
|
|
759cf33f08 | ||
|
|
77279d21ef | ||
|
|
46872fdfe8 | ||
|
|
79fe9c2875 | ||
|
|
f04ea37ac2 | ||
|
|
d2db92f1e7 | ||
|
|
206433e430 | ||
|
|
fb1f3fa931 | ||
|
|
3d106ae2f1 | ||
|
|
05f0a6463b | ||
|
|
7b5d5d0f31 | ||
|
|
20174989a6 | ||
|
|
80d48adc07 | ||
|
|
3454185df4 | ||
|
|
9de0868c74 | ||
|
|
66cb6c7dee | ||
|
|
1ce67b1c8f | ||
|
|
a9bb5b2f42 | ||
|
|
97ca7fd2a0 | ||
|
|
b85e291d40 | ||
|
|
b3e3752789 | ||
|
|
7cd6928b87 | ||
|
|
bb1b3c7b7b | ||
|
|
49c7cea3a5 | ||
|
|
64f5009297 | ||
|
|
0ab701bab6 | ||
|
|
1721415799 | ||
|
|
26269459db | ||
|
|
675da6b2e2 | ||
|
|
517bfca259 | ||
|
|
3e30685eb4 | ||
|
|
95cbba4618 | ||
|
|
d89c6b9c06 | ||
|
|
4bda994d5c | ||
|
|
2b4f6f33af | ||
|
|
62500a322f | ||
|
|
ae58a8b9df | ||
|
|
2a8732fdcd | ||
|
|
19931ec18e | ||
|
|
b981fc4b7d | ||
|
|
4b2f268921 | ||
|
|
7fb5a8d444 | ||
|
|
913cc16371 | ||
|
|
4e8a9ff8ed | ||
|
|
68034de1a7 | ||
|
|
f67d8615ca | ||
|
|
4483c921ea | ||
|
|
e8732ecfc0 | ||
|
|
71a538651a | ||
|
|
18c9963124 | ||
|
|
cd0f2f4e33 | ||
|
|
fc028ec0be | ||
|
|
2dbdb9f7eb | ||
|
|
50f6e76e81 | ||
|
|
c6af93adcb | ||
|
|
bd985781b9 | ||
|
|
70ecdaf54c | ||
|
|
a04287b9b3 | ||
|
|
be8d00f0c8 | ||
|
|
b08797c400 | ||
|
|
2836edd32d | ||
|
|
92f6886217 | ||
|
|
0c9518dc74 | ||
|
|
944ee7c7dc | ||
|
|
917dbf09f6 | ||
|
|
d732be4e17 | ||
|
|
18dbbb291a | ||
|
|
3bb7922f2c | ||
|
|
4aedba3b2b | ||
|
|
99c0e99b26 | ||
|
|
28ab554cb3 | ||
|
|
cd80a47c93 | ||
|
|
eb05b54b0e | ||
|
|
bbbce6f694 | ||
|
|
ba0d515330 | ||
|
|
69154c0384 | ||
|
|
66ac5e9d2f | ||
|
|
4924b951cc | ||
|
|
96f7def396 | ||
|
|
4556f1c949 | ||
|
|
a4cca3bcc2 | ||
|
|
6254c2089f | ||
|
|
89f50769b6 | ||
|
|
a24f5e31b9 | ||
|
|
b338f183e1 | ||
|
|
8ab8e0524b | ||
|
|
affb48f44d | ||
|
|
d5b2336b69 | ||
|
|
580e3a6a2c | ||
|
|
e3d5203f1a | ||
|
|
9e42b11272 | ||
|
|
ce93c3b739 | ||
|
|
6a8e00bfa2 | ||
|
|
0b5a99860f | ||
|
|
3f012a2ef1 | ||
|
|
a102e4ae1e | ||
|
|
03f5817488 | ||
|
|
0f2edfdb4e | ||
|
|
d289134b15 | ||
|
|
7475c7cc71 | ||
|
|
7958eeeded | ||
|
|
f29f773555 | ||
|
|
a113205881 | ||
|
|
7830ccb017 | ||
|
|
6a205a5406 | ||
|
|
d91a42930d | ||
|
|
6f3df707f4 | ||
|
|
f388b11d0d | ||
|
|
66d12fef82 | ||
|
|
83c744041e | ||
|
|
dcac39a35f | ||
|
|
c4d3ba71b2 | ||
|
|
74c74593e2 | ||
|
|
62591bc360 | ||
|
|
1fca162fb2 | ||
|
|
82967435ea | ||
|
|
7738354be1 | ||
|
|
0d2166770e | ||
|
|
9d7de9ea4d | ||
|
|
5aa3ba25cc | ||
|
|
b330f902fd | ||
|
|
aa76dfba02 | ||
|
|
b3c2d87a9b | ||
|
|
cc1347adf8 | ||
|
|
df0a80b320 | ||
|
|
26f7557834 | ||
|
|
e6c2f29532 | ||
|
|
37cc16fe17 | ||
|
|
c7ac88836a | ||
|
|
536e048f1c | ||
|
|
4671848428 | ||
|
|
4449785e2c | ||
|
|
39deb9ee83 | ||
|
|
2266f4a75c | ||
|
|
06b680f603 | ||
|
|
ec6be7d1a5 | ||
|
|
37040bfc9e | ||
|
|
1f4f7ec0e5 | ||
|
|
a31571ab2c | ||
|
|
714ef2adb8 | ||
|
|
e447bbf03b | ||
|
|
3846b638fb | ||
|
|
6ae8a203d9 | ||
|
|
1dbd491738 | ||
|
|
e8693edb33 | ||
|
|
5cbad00cb5 | ||
|
|
c6e4deb0ca | ||
|
|
693fb84a3e | ||
|
|
b0a7d5d4a0 | ||
|
|
818acc0ff1 | ||
|
|
819fec6061 | ||
|
|
4ea8c98243 | ||
|
|
95317a7336 | ||
|
|
9b6abfbbc3 | ||
|
|
4bee3023d2 | ||
|
|
45f12db8d3 | ||
|
|
9956b3fed3 | ||
|
|
374e837aa9 | ||
|
|
6ffd3e574f | ||
|
|
8a3706f6cb | ||
|
|
faa16ad910 | ||
|
|
eb69e25622 | ||
|
|
b006bb0c3c | ||
|
|
02ed50b336 | ||
|
|
f0023bc084 | ||
|
|
6502f7760d | ||
|
|
7606691ea3 | ||
|
|
257a1e9474 | ||
|
|
9f02ccbb48 | ||
|
|
a18199e9a2 | ||
|
|
cdd6f998c4 | ||
|
|
df21b6fc6f | ||
|
|
edf7dee78e | ||
|
|
f723e5ea59 | ||
|
|
748243f512 | ||
|
|
e7d37402d7 | ||
|
|
7c101ae3af | ||
|
|
cf9cdd8b3b | ||
|
|
b18783c17a | ||
|
|
201d06d878 | ||
|
|
742ef7d529 | ||
|
|
3d73fc10cd | ||
|
|
075c1b06f7 | ||
|
|
2706a3d379 | ||
|
|
e476dce1d4 | ||
|
|
2f25657cfa | ||
|
|
1167545199 | ||
|
|
fcd1fae77e | ||
|
|
06db10561c | ||
|
|
ead9e8945e | ||
|
|
15d4f77d5d | ||
|
|
c903a64726 | ||
|
|
8fa63a8773 | ||
|
|
8a0e6c90b9 | ||
|
|
e4fdf33cfc | ||
|
|
548e38fca0 | ||
|
|
c804c806e1 | ||
|
|
7c291691aa | ||
|
|
cec8cf25ef | ||
|
|
5a2812ecf3 | ||
|
|
0f09ba717f | ||
|
|
1026abbbf4 | ||
|
|
5b578c86e8 | ||
|
|
d7e4a782c1 | ||
|
|
d65dfeceb0 | ||
|
|
e9a7a3a5f5 | ||
|
|
8504252142 | ||
|
|
19730ab6a4 | ||
|
|
44ae75110b | ||
|
|
4ab2a93d59 | ||
|
|
f82ea82403 | ||
|
|
fff6c004e0 | ||
|
|
75c7744e59 | ||
|
|
1e8bdba2dd | ||
|
|
2587831855 | ||
|
|
f00a283722 | ||
|
|
e3b333aca8 | ||
|
|
c9602c2b0a | ||
|
|
c660c80a15 | ||
|
|
6f889d1c3b | ||
|
|
80577832d7 | ||
|
|
7a18ef77cd | ||
|
|
e29f7cb1d3 | ||
|
|
8970274810 | ||
|
|
d57fd8bfd3 | ||
|
|
8507866891 | ||
|
|
425d53fbe3 | ||
|
|
b0cb983830 | ||
|
|
02515d8956 | ||
|
|
447b4337dd | ||
|
|
633daf124e | ||
|
|
446560931b | ||
|
|
9fe11a7ad5 | ||
|
|
b099994ac5 | ||
|
|
a8d56ef4e6 | ||
|
|
1f8d212dee | ||
|
|
64ea87f4cc | ||
|
|
e6fef433d5 | ||
|
|
2f212031b3 | ||
|
|
586ab710f6 | ||
|
|
d263ae649e | ||
|
|
c81ca45e41 | ||
|
|
9ce50fa305 | ||
|
|
f0240deaeb | ||
|
|
017f06dcfb | ||
|
|
54f17cb546 | ||
|
|
f174ab6ebc | ||
|
|
263f936690 | ||
|
|
bd903a0353 | ||
|
|
5040d3a6b6 | ||
|
|
3684da776d | ||
|
|
bc17c8e5b3 | ||
|
|
778c647782 | ||
|
|
2a91f6279b | ||
|
|
4ef2ddbfec | ||
|
|
ff06f0cc73 | ||
|
|
a37ab34fae | ||
|
|
cb2ffe66af | ||
|
|
16b0770d72 | ||
|
|
3fe44ee735 | ||
|
|
40d1a72300 | ||
|
|
4d428d42f6 | ||
|
|
7e9896263b | ||
|
|
cf0665c9b6 | ||
|
|
93c011c69d | ||
|
|
f50c0b9d06 | ||
|
|
6fc79d942b | ||
|
|
d01228d9ff | ||
|
|
b58d766d54 | ||
|
|
79cbb96a38 | ||
|
|
aabaeacb81 | ||
|
|
3ab3e6d41b | ||
|
|
f2f4afd0bb | ||
|
|
0d62c43b9e | ||
|
|
1614d5702c | ||
|
|
610b9542e9 | ||
|
|
946f32a274 | ||
|
|
c7a6bc015e | ||
|
|
19fd1635e6 | ||
|
|
74b034a195 | ||
|
|
581139d099 | ||
|
|
e5492ea906 | ||
|
|
623133a0dc | ||
|
|
6baa8f2dbb | ||
|
|
d2739d7218 | ||
|
|
5702101935 | ||
|
|
35d45a7523 | ||
|
|
e37c1f0e8c | ||
|
|
ac0d35ef12 | ||
|
|
15e63381a9 | ||
|
|
aa49ddacd5 | ||
|
|
f68e876bcb | ||
|
|
6b82ded399 | ||
|
|
000e67a09e | ||
|
|
1b6aa4c3d1 | ||
|
|
8912a2c842 | ||
|
|
4de50db68c | ||
|
|
6b95e4aac9 | ||
|
|
c27658822e | ||
|
|
8ec980c1e8 | ||
|
|
a952c5829a | ||
|
|
20e1b55a8a | ||
|
|
a2605868db | ||
|
|
67be35b9f8 | ||
|
|
b15eb1e62f | ||
|
|
d2e3ec0448 | ||
|
|
828c403fe5 | ||
|
|
53d3bc86ea | ||
|
|
6ed8742cc1 | ||
|
|
7bd047f6e6 | ||
|
|
482757b1cc | ||
|
|
c143f832c6 | ||
|
|
67a173ef53 | ||
|
|
c2c37488a3 | ||
|
|
8c1840b9cf | ||
|
|
1088e37cd4 | ||
|
|
4d6c3dac3d | ||
|
|
adf29873ef | ||
|
|
772afe29ea | ||
|
|
9c78953800 | ||
|
|
ff67b9bcbc | ||
|
|
103de4f910 | ||
|
|
7c3f06f98f | ||
|
|
6ac77a7662 | ||
|
|
610b85d01a | ||
|
|
d4d222ebd3 | ||
|
|
5cbed1d34b | ||
|
|
ba4a2eef5c | ||
|
|
acdf03fc84 | ||
|
|
a6f19e07c4 | ||
|
|
f07301bb1e | ||
|
|
2116e3741b | ||
|
|
1f11c732ed | ||
|
|
e42bee27a4 | ||
|
|
b36dcf1325 | ||
|
|
421746c943 | ||
|
|
f544ac58e6 | ||
|
|
6047275cfa | ||
|
|
630d832f50 | ||
|
|
e0a34465d8 | ||
|
|
443a4049c3 | ||
|
|
54980e7585 | ||
|
|
14ff8bb26b | ||
|
|
615bb0ee3f | ||
|
|
986fd8c13b | ||
|
|
ec1cc27815 | ||
|
|
3874e2d886 | ||
|
|
1afcf21529 | ||
|
|
4c0f3bd7cb | ||
|
|
9aafa2a662 | ||
|
|
029ba1202e | ||
|
|
b5043b2b87 | ||
|
|
52ce80fd97 | ||
|
|
cd19c5eb38 | ||
|
|
0d101d779f | ||
|
|
1ff6f43eac | ||
|
|
98d892f643 | ||
|
|
cc80afff7d | ||
|
|
91ad74e3ad | ||
|
|
b128d25fbe | ||
|
|
8b23769ccc | ||
|
|
13f84ab518 | ||
|
|
feadc1ff9e | ||
|
|
f75c3a123e | ||
|
|
12dfe49d9b | ||
|
|
545618964d | ||
|
|
a6f3f21b70 | ||
|
|
e6135f49fb | ||
|
|
cd3a1c869e | ||
|
|
8bb21b12aa | ||
|
|
f500791ba3 | ||
|
|
4ebc4e9546 | ||
|
|
94ee2e55fd | ||
|
|
e3c370eb6b | ||
|
|
6fea5af585 | ||
|
|
e9e149d55e | ||
|
|
bb5d98164f | ||
|
|
8941f41d1c | ||
|
|
d45e17b603 | ||
|
|
c2b3e6b36e | ||
|
|
b8405c01f1 | ||
|
|
3d191da07e | ||
|
|
aeb61993a4 | ||
|
|
3679e1da3a | ||
|
|
52aefd23f0 | ||
|
|
76a2b84925 | ||
|
|
a89b2c7ed1 | ||
|
|
5dd4eb2d20 | ||
|
|
600661a570 | ||
|
|
92f6453d26 | ||
|
|
8bf3aa9b4d | ||
|
|
c52db1945b | ||
|
|
09a10cd791 | ||
|
|
07fd577894 | ||
|
|
ed900b8531 | ||
|
|
fa010357b3 | ||
|
|
da6ffc85ef | ||
|
|
b7c23087e1 | ||
|
|
656f482cad | ||
|
|
5e03003b94 | ||
|
|
48b5b27d42 | ||
|
|
fccb815d5a | ||
|
|
544d3b026a | ||
|
|
15ff882919 | ||
|
|
18d405bdfb | ||
|
|
4379e7c544 | ||
|
|
51e2be9b7b | ||
|
|
f2b21d04b3 | ||
|
|
a73f35af22 | ||
|
|
7b3ef03924 | ||
|
|
a4d03c1514 | ||
|
|
eccdee0081 | ||
|
|
48f3390d71 | ||
|
|
df6f1e6c8f | ||
|
|
3c95081aee | ||
|
|
329a980510 | ||
|
|
d8605e9ce3 | ||
|
|
7dcc6dc114 | ||
|
|
64db52fd17 | ||
|
|
c0957024ec | ||
|
|
649571a2eb | ||
|
|
60adb0d50b | ||
|
|
f751d7c24e | ||
|
|
5ec5ade62f | ||
|
|
788c497cbb | ||
|
|
f6c274b82f | ||
|
|
5a6b4a6fdd | ||
|
|
ef212b8c0f | ||
|
|
aa2f46fd00 | ||
|
|
a30808e6b7 | ||
|
|
f23c55dfec | ||
|
|
583d3188ca | ||
|
|
ae81f64d07 | ||
|
|
8dca2e346c | ||
|
|
b995986318 | ||
|
|
0579b6dcd3 | ||
|
|
4d147c7ff3 | ||
|
|
baf5f088dc | ||
|
|
2adaacb922 | ||
|
|
bc6870f4ee | ||
|
|
c6abaf22c1 | ||
|
|
e04e066177 | ||
|
|
6ad01f4994 | ||
|
|
f6ad75e214 | ||
|
|
a76864450e | ||
|
|
3fe9994322 | ||
|
|
3bcfcc40c0 | ||
|
|
92b54f949b | ||
|
|
a73746fe8b | ||
|
|
da1fddffe1 | ||
|
|
e3b0feb967 | ||
|
|
4e6811cfdc | ||
|
|
cc47e46e1f | ||
|
|
4246d99b93 | ||
|
|
ba38e3c1aa | ||
|
|
83aa64928d | ||
|
|
5fbff7211b | ||
|
|
eb67f19e3e | ||
|
|
2130a31dfd | ||
|
|
f3ce208ec1 | ||
|
|
146478eb5e | ||
|
|
05413d5a99 | ||
|
|
eac726fcb8 | ||
|
|
b25af85234 | ||
|
|
02167a0788 | ||
|
|
54cce9aa41 | ||
|
|
73cdc7136c | ||
|
|
1567a2b847 | ||
|
|
9fe795f8dd | ||
|
|
0d6cfd183d | ||
|
|
bba36d041b | ||
|
|
710716f658 | ||
|
|
b39798ac24 | ||
|
|
1f8fbb8518 | ||
|
|
51dc666181 | ||
|
|
2a6e716e07 | ||
|
|
01d68f30e4 | ||
|
|
1b73d01de8 | ||
|
|
a421cb0b01 | ||
|
|
2177336d65 | ||
|
|
059a8cc38f | ||
|
|
4c33cd6409 | ||
|
|
ea48d52447 | ||
|
|
85f4be750a | ||
|
|
0ba37a347b | ||
|
|
6ee1900331 | ||
|
|
44bf1ef322 | ||
|
|
863691c313 | ||
|
|
97d7cbf657 | ||
|
|
3089535de6 | ||
|
|
36818093c6 | ||
|
|
e5857df439 | ||
|
|
42d25dc1a5 | ||
|
|
3b5e78bfba | ||
|
|
639dce7c53 | ||
|
|
882f54647c | ||
|
|
38443048b8 | ||
|
|
621c3dbeca | ||
|
|
f1e4f7ecda | ||
|
|
249d1b6790 | ||
|
|
894e0fd03a | ||
|
|
ec1f009914 | ||
|
|
697417b906 | ||
|
|
dadf57c184 | ||
|
|
7caa83be19 | ||
|
|
e745d38b1e | ||
|
|
6d389315bf | ||
|
|
024d56505a | ||
|
|
daec97ad66 | ||
|
|
a98daead1d | ||
|
|
2c5cf77cf2 | ||
|
|
a6b9a82e9c | ||
|
|
02cf9d1cd2 | ||
|
|
cde814b216 | ||
|
|
5f435cd8c7 | ||
|
|
6ccd98ca01 | ||
|
|
799f2a81a7 | ||
|
|
eb9fa6f567 | ||
|
|
9ebd595202 | ||
|
|
b50d301f44 | ||
|
|
b01b8908ea | ||
|
|
78c2cdddc4 | ||
|
|
1eaac74fb0 | ||
|
|
ee759a5459 | ||
|
|
e9d19805d7 | ||
|
|
1f74ba43f0 | ||
|
|
bc1e686455 | ||
|
|
5cc0552c57 | ||
|
|
6c06bc6af8 | ||
|
|
2193c131a8 | ||
|
|
9a38626af5 | ||
|
|
f0c243f6d1 | ||
|
|
f0441f1a08 | ||
|
|
8a9d9f9fce | ||
|
|
db06c496cf | ||
|
|
2aa97e6565 | ||
|
|
68597cac22 | ||
|
|
afa543ec79 | ||
|
|
d1df6e910b | ||
|
|
74ae567ced | ||
|
|
8d657c5b18 | ||
|
|
802bdc102f | ||
|
|
218d18793d | ||
|
|
723c29e33b | ||
|
|
2e248c6658 | ||
|
|
7fbd66d54c | ||
|
|
4bede063ae | ||
|
|
cbc5fec119 | ||
|
|
81927b088b | ||
|
|
5556edd83b | ||
|
|
2834532b5f | ||
|
|
17638bc29f | ||
|
|
67b48cc417 | ||
|
|
451996016a | ||
|
|
52b9a9223d | ||
|
|
d5b80b0bbd | ||
|
|
ae14e49338 | ||
|
|
c23bce9829 | ||
|
|
40a549ca29 | ||
|
|
cac435a2a5 | ||
|
|
b81f50402a | ||
|
|
44587cb947 | ||
|
|
54314273a0 | ||
|
|
de068dc6ff | ||
|
|
64f537ad1e | ||
|
|
312c89f884 | ||
|
|
d9fd7eb3a5 | ||
|
|
af9206f350 | ||
|
|
7c99bb084e | ||
|
|
1a2757b00a | ||
|
|
1e7a2110b1 | ||
|
|
243146fe49 | ||
|
|
370d139dfc | ||
|
|
c4e7db34a4 | ||
|
|
a4f6b72157 | ||
|
|
de3ca6dba5 | ||
|
|
bdfcfdd0fe | ||
|
|
dbf357ce66 | ||
|
|
e950cf7fc3 | ||
|
|
8dfad1c910 | ||
|
|
107d4e973c | ||
|
|
e33766a4fa | ||
|
|
6a550c6c4a | ||
|
|
a0fc2a8ce7 | ||
|
|
ab257b3468 | ||
|
|
e6bdb28484 | ||
|
|
c52446f3b0 | ||
|
|
9cadfb26d9 | ||
|
|
7d5ea8f908 | ||
|
|
161b33370e | ||
|
|
8dd7a90b34 | ||
|
|
7ff865a36f | ||
|
|
d0b8ee606a | ||
|
|
c6c3b16fd2 | ||
|
|
64a6cbb2e4 | ||
|
|
e1cf532437 | ||
|
|
67f2127710 | ||
|
|
9111b424a1 | ||
|
|
772b51216f | ||
|
|
a79a2f5ecb | ||
|
|
585c0d64ed | ||
|
|
7ddb95a417 | ||
|
|
02648eb54e | ||
|
|
54a1050fbb | ||
|
|
f997b2d2f0 | ||
|
|
8f61e57b57 | ||
|
|
cfcff6f2d7 | ||
|
|
44d7cc0588 | ||
|
|
c91275d091 | ||
|
|
69c88919c0 | ||
|
|
e0e6f55868 | ||
|
|
7698584ee0 | ||
|
|
d034722ba9 | ||
|
|
e1e07c95ba | ||
|
|
b81c32b1c9 |
73
.clang-format
Normal file
73
.clang-format
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
BasedOnStyle: WebKit
|
||||
Language: Cpp
|
||||
Standard: Cpp11
|
||||
|
||||
IndentWidth: 4
|
||||
SpacesBeforeTrailingComments: 1
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
SortIncludes: false
|
||||
ContinuationIndentWidth: 4
|
||||
MaxEmptyLinesToKeep: 3
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: true
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
|
||||
ForEachMacros:
|
||||
- forever # avoids { wrapped to next line
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
|
||||
AccessModifierOffset: -4
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: false # requires clang-format 11
|
||||
AlignAfterOpenBracket: true
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackParameters: true
|
||||
ColumnLimit: 0
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerBinding: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
IndentCaseLabels: false
|
||||
NamespaceIndentation: None
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 60
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerBindsToType: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
SpaceAfterControlStatementKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: true
|
||||
SpacesInParentheses: false
|
||||
...
|
||||
|
||||
4
.codespellrc
Normal file
4
.codespellrc
Normal file
@@ -0,0 +1,4 @@
|
||||
[codespell]
|
||||
skip = ./build-*,.git
|
||||
interactive = 3
|
||||
ignore-words-list = overlay,overlayed
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -58,3 +58,9 @@ kddockwidgets_minimal_example
|
||||
/CMakeDoxygenDefaults.cmake
|
||||
/Testing
|
||||
/layout_tst*
|
||||
/x64
|
||||
/src/kddockwidgets_version.h
|
||||
*.vcxproj*
|
||||
*.sln
|
||||
*.dir
|
||||
.vscode
|
||||
|
||||
4
.krazy
4
.krazy
@@ -7,7 +7,7 @@ EXTRA kdabcopyright-reuse,kdabcontactus,fosslicense-reuse
|
||||
#EXTRA defines,null
|
||||
|
||||
#exclude checks now being done by clazy or clang-tools
|
||||
EXCLUDE strings,explicit,normalize,passbyvalue,operators,nullstrcompare,nullstrassign,doublequote_chars,qobject,sigsandslots,staticobjects,dpointer,inline
|
||||
EXCLUDE strings,explicit,normalize,passbyvalue,operators,nullstrcompare,nullstrassign,doublequote_chars,qobject,sigsandslots,staticobjects,dpointer,inline,postfixop
|
||||
#exclude more checks
|
||||
EXCLUDE style
|
||||
|
||||
@@ -16,6 +16,8 @@ SKIP Doxyfile.cmake
|
||||
|
||||
#skip CMake files
|
||||
SKIP /KDDockWidgetsConfig.cmake.in
|
||||
#skip more files
|
||||
SKIP CMakePresets.json
|
||||
#skip the borrowed code in the cmake subdir
|
||||
SKIP /cmake/Qt5Portability.cmake|/cmake/ECM/|/cmake/InstallLocation.cmake
|
||||
|
||||
|
||||
18
.reuse/dep5
Normal file
18
.reuse/dep5
Normal file
@@ -0,0 +1,18 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: KDDockWidgets
|
||||
Upstream-Contact: <info@kdab.com>
|
||||
Source: https://www.github.com/KDAB/KDDockWidgets
|
||||
|
||||
Files: *.qrc *.json *.xml *.html src/fwd_headers/*
|
||||
Copyright: 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
License: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#artwork
|
||||
Files: screencap.gif images/* src/img/* docs/api/*.png examples/dockwidgets/assets/*.png src/img/classic_indicators/*.png
|
||||
Copyright: 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
License: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#3rdparty
|
||||
Files: cmake/ECM/modules/*
|
||||
Copyright:
|
||||
License: BSD-3-Clause
|
||||
66
.travis.yml
Normal file
66
.travis.yml
Normal file
@@ -0,0 +1,66 @@
|
||||
env:
|
||||
global:
|
||||
- secure: "NlWO/NTPlOU6cowOMuPOvjAprXVwIjmpHHf9CoMR71E2c/eBFFKIHj10kXuyFwz2KihHAIExmo9OlGtGniNWobvIrVrabO3dsOSb6UGbPAQkzQiyQLKsDNQAZx3nMuWEKBtMsVRee6rd7/2uGTY4WB5Ot3VhrUYcN1FoRgQQ9gk="
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: bionic
|
||||
- os: osx
|
||||
osx_image: xcode11.5
|
||||
env:
|
||||
- QT_SELECT=qt5
|
||||
- CMAKE_PREFIX_PATH=/usr/local/opt/qt
|
||||
|
||||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_BUILD_TYPE=Release -DKDDockWidgets_TESTS=True -KDDockWidgets_EXAMPLES=True -DKDDockWidgets_DEVELOPER_MODE=True ..
|
||||
- make
|
||||
- make test
|
||||
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- allen.winter@kdab.com
|
||||
- sergio.martins@kdab.com
|
||||
on_success: never
|
||||
on_failure: always
|
||||
|
||||
dist: bionic
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
packages:
|
||||
- qt5-default
|
||||
- qtbase5-dev
|
||||
- qtbase5-dev-tools
|
||||
- qtbase5-private-dev
|
||||
- qttools5-dev
|
||||
- qttools5-dev-tools
|
||||
- qtdeclarative5-dev
|
||||
- qtdeclarative5-dev-tools
|
||||
- libqt5xmlpatterns5-dev
|
||||
- libqt5xmlpatterns5
|
||||
- qtxmlpatterns5-dev-tools
|
||||
- libqt5x11extras5-dev
|
||||
homebrew:
|
||||
update: true
|
||||
packages:
|
||||
- qt5
|
||||
coverity_scan:
|
||||
project:
|
||||
name: KDAB/KDDockWidgets
|
||||
notification_email: allen.winter@kdab.com
|
||||
build_command_prepend: cd build && cmake ..
|
||||
build_command: make
|
||||
branch_pattern: coverity_scan
|
||||
68
.vscode/launch.json
vendored
68
.vscode/launch.json
vendored
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) QtWidgets example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) QtQuick example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/kddockwidgets_example_quick",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(vs) kddockwidgets_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/kddockwidgets_example.exe",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"sourceFileMap" : {
|
||||
"C:\\Users\\qt\\work\\qt\\qtbase\\src" : "D:\\Qt\\5.14.2\\Src\\qtbase\\src"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "(vs) tst_docks",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/tst_docks.exe",
|
||||
"args": ["tst_moreTitleBarCornerCases", "-platform", "windows"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false
|
||||
}
|
||||
]
|
||||
}
|
||||
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools",
|
||||
"files.associations": {
|
||||
"qevent": "cpp"
|
||||
},
|
||||
"cmake.configureSettings": {
|
||||
"KDDockWidgets_DEVELOPER_MODE" : "ON",
|
||||
"KDDockWidgets_QTQUICK" : true
|
||||
}
|
||||
}
|
||||
257
CMakeLists.txt
257
CMakeLists.txt
@@ -19,9 +19,15 @@
|
||||
# Build static versions of the libraries
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_UNINSTALL=[true|false]
|
||||
# Setup the uninstall target.
|
||||
# You may want to disable the uninstall target when you are using KDDockWidgets
|
||||
# as a submodule directly and have a custom uninstall target of your own.
|
||||
# Default=true
|
||||
#
|
||||
# -DKDDockWidgets_TESTS=[true|false]
|
||||
# Build the test harness.
|
||||
# Currently does nothing unless you also set KDDockWidgets_DEVELOPER_MODE=True
|
||||
# Currently ignored unless you also set KDDockWidgets_DEVELOPER_MODE=True
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_EXAMPLES=[true|false]
|
||||
@@ -29,31 +35,45 @@
|
||||
# Default=true
|
||||
#
|
||||
# -DKDDockWidgets_DOCS=[true|false]
|
||||
# Build the API documentation.
|
||||
# Build the API documentation. Enables the 'docs' build target.
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_QTQUICK=[true|false]
|
||||
# Build for QtQuick instead of QtWidgets.
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_PYTHON_BINDINGS=[true|false]
|
||||
# Build/Generate python bindings. Always false for Debug builds
|
||||
# (If your shiboken or pyside is installed in a non-standard locations
|
||||
# try passing the SHIBOKEN_CUSTOM_PREFIX and PYSIDE2_CUSTOM_PREFIX variables.)
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_PYTHON_BINDINGS_INSTALL_PREFIX=[path]
|
||||
# Set an alternative install path for Python bindings
|
||||
# Default=CMAKE_INSTALL_PREFIX
|
||||
|
||||
# ## DO NOT USE IF YOU ARE AN END-USER. FOR THE DEVELOPERS ONLY!!
|
||||
## Special CMake Options for Developers
|
||||
#
|
||||
# -DKDDockWidgets_DEVELOPER_MODE=[true|false]
|
||||
# Configure the build for a developer setup.
|
||||
# Enables some features that are not geared towards end-users.
|
||||
# Forces the test harness to be built.
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_QTQUICK == IN DEVELOPMENT. DO NOT USE! ==
|
||||
# Build for QtQuick instead of QtWidgets
|
||||
# -DKDDockWidgets_WERROR=[true|false]
|
||||
# Compile with the -Werror gcc/clang option (always true for developer-mode)
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_PYTHON_BINDINGS=[true|false]
|
||||
# Build/Generate python bindings. Always false for Debug builds
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_PYTHON_BINDINGS_INSTALL_PREFIX=[path]
|
||||
# Set an alternative install path for Python bindings
|
||||
# Default=CMAKE_INSTALL_PREFIX
|
||||
#
|
||||
# -DKDDockWidgets_UNITY_BUILD=[true|false]
|
||||
# Build with CMake's UNITY_BUILD (requires CMake version 3.16 or higher)
|
||||
# -DKDDockWidgets_LINTER=[true|false]
|
||||
# Build the layout linter.
|
||||
# Ignored unless KDDockWidgets_DEVELOPER_MODE=True
|
||||
# Default=true
|
||||
#
|
||||
# -DKDDockWidgets_FUZZER=[true|false]
|
||||
# Build the fuzzer.
|
||||
# Ignored unless KDDockWidgets_DEVELOPER_MODE=True
|
||||
# Default=true
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
if(POLICY CMP0020)
|
||||
@@ -63,8 +83,26 @@ if(POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 NEW)
|
||||
endif()
|
||||
|
||||
# Just to fix warnings with --warn-uninitialized
|
||||
if(NOT DEFINED USE_DEFAULT_INSTALL_LOCATION)
|
||||
set(USE_DEFAULT_INSTALL_LOCATION FALSE)
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX "")
|
||||
endif()
|
||||
if(NOT DEFINED SHIBOKEN_CUSTOM_PREFIX) #look for shiboken in a custom location
|
||||
set(SHIBOKEN_CUSTOM_PREFIX "")
|
||||
endif()
|
||||
if(NOT DEFINED PYSIDE2_CUSTOM_PREFIX) #look for pyside in a custom location
|
||||
set(PYSIDE2_CUSTOM_PREFIX "")
|
||||
endif()
|
||||
if(NOT DEFINED PYSIDE6_CUSTOM_PREFIX) #look for pyside in a custom location
|
||||
set(PYSIDE6_CUSTOM_PREFIX "")
|
||||
endif()
|
||||
|
||||
# Allow using a non-KDAB install location
|
||||
set(KDAB_INSTALL True)
|
||||
if((NOT DEFINED ${USE_DEFAULT_INSTALL_LOCATION}) OR (NOT ${USE_DEFAULT_INSTALL_LOCATION}))
|
||||
if(NOT ${USE_DEFAULT_INSTALL_LOCATION})
|
||||
if(NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "")
|
||||
set(KDAB_INSTALL False)
|
||||
endif()
|
||||
@@ -81,60 +119,81 @@ else()
|
||||
endif()
|
||||
|
||||
set(${PROJECT_NAME}_VERSION_MAJOR 1)
|
||||
set(${PROJECT_NAME}_VERSION_MINOR 2)
|
||||
set(${PROJECT_NAME}_VERSION_PATCH 1)
|
||||
set(${PROJECT_NAME}_VERSION_MINOR 4)
|
||||
set(${PROJECT_NAME}_VERSION_PATCH 0)
|
||||
set(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_PATCH})
|
||||
set(${PROJECT_NAME}_SOVERSION "1.3")
|
||||
set(PROJECT_VERSION ${${PROJECT_NAME}_VERSION}) #PROJECT_VERSION is needed by some ECM modules
|
||||
set(${PROJECT_NAME}_SOVERSION "1.4")
|
||||
|
||||
include(FeatureSummary)
|
||||
|
||||
option(${PROJECT_NAME}_QT6 "Build against Qt 6" OFF)
|
||||
option(${PROJECT_NAME}_DEVELOPER_MODE "Developer Mode" OFF)
|
||||
option(${PROJECT_NAME}_PYTHON_BINDINGS "Build python bindings" OFF)
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0")
|
||||
option(${PROJECT_NAME}_UNITY_BUILD "Build with CMake's UNITY_BUILD" ON)
|
||||
endif()
|
||||
|
||||
|
||||
if(${PROJECT_NAME}_PYTHON_BINDINGS AND (CMAKE_BUILD_TYPE MATCHES "^[Dd]eb" OR ${PROJECT_NAME}_STATIC))
|
||||
message(FATAL_ERROR "** Python Bindings are disabled in debug or static builds.")
|
||||
endif()
|
||||
|
||||
option(${PROJECT_NAME}_UNINSTALL "Enable the uninstall target" ON)
|
||||
option(${PROJECT_NAME}_STATIC "Build statically" OFF)
|
||||
option(${PROJECT_NAME}_TESTS "Build the tests" OFF)
|
||||
option(${PROJECT_NAME}_EXAMPLES "Build the examples" ON)
|
||||
option(${PROJECT_NAME}_DOCS "Build the API documentation" OFF)
|
||||
option(${PROJECT_NAME}_WERROR "Use -Werror (will be true for developer-mode unconditionally)" OFF)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/ECM/modules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/KDAB/modules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Python")
|
||||
|
||||
#Always build the test harness in developer-mode
|
||||
if(${PROJECT_NAME}_DEVELOPER_MODE)
|
||||
set(${PROJECT_NAME}_TESTS ON)
|
||||
set(${PROJECT_NAME}_WERROR ON)
|
||||
include(ECMEnableSanitizers)
|
||||
endif()
|
||||
|
||||
#option(${PROJECT_NAME}_QTQUICK "Build for QtQuick instead of QtWidgets" OFF)
|
||||
option(${PROJECT_NAME}_QTQUICK "Build for QtQuick instead of QtWidgets" OFF)
|
||||
|
||||
if (${PROJECT_NAME}_QT6)
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(IS_CLANG_BUILD TRUE)
|
||||
else()
|
||||
set(IS_CLANG_BUILD FALSE)
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_QT6)
|
||||
find_package(Qt6Widgets REQUIRED)
|
||||
find_package(Qt6Test REQUIRED)
|
||||
set(QT_MAJOR_VERSION 6)
|
||||
set(KDDockWidgets_LIBRARY_QTID "-qt6")
|
||||
else()
|
||||
find_package(Qt5Widgets 5.9 REQUIRED)
|
||||
find_package(Qt5Test 5.9 REQUIRED)
|
||||
find_package(Qt5Widgets 5.12 REQUIRED)
|
||||
find_package(Qt5Test 5.12 REQUIRED)
|
||||
set(QT_MAJOR_VERSION 5)
|
||||
set(KDDockWidgets_LIBRARY_QTID "")
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_QTQUICK)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(ECM_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/ECM/modules/")
|
||||
set(PYTHON_MODULE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake/Python")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake" ${ECM_MODULE_DIR} ${PYTHON_MODULE_DIR})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
# Set a default build type if none was specified
|
||||
set(default_build_type "Release")
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.git" OR ${PROJECT_NAME}_DEVELOPER_MODE)
|
||||
set(default_build_type "Debug")
|
||||
endif()
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "Setting build type to ${default_build_type} as none was specified.")
|
||||
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
|
||||
# Set the possible values of build type for cmake-gui
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
# setup default install locations
|
||||
include(InstallLocation)
|
||||
include(QtInstallPaths) #to set QT_INSTALL_FOO variables
|
||||
include(KDQtInstallPaths) #to set QT_INSTALL_FOO variables
|
||||
|
||||
macro(set_compiler_flags targetName)
|
||||
if(${PROJECT_NAME}_DEVELOPER_MODE)
|
||||
@@ -150,20 +209,27 @@ macro(set_compiler_flags targetName)
|
||||
endif()
|
||||
|
||||
# Enable -Werror
|
||||
if(NOT MSVC AND ${PROJECT_NAME}_WERROR)
|
||||
target_compile_options(${targetName} PRIVATE -Werror -Wno-error=deprecated-declarations)
|
||||
if(${PROJECT_NAME}_WERROR AND (NOT MSVC OR IS_CLANG_BUILD)) # clang-cl accepts these too
|
||||
target_compile_options(${targetName} PRIVATE -Werror -Wundef -Wno-error=deprecated-declarations)
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
set(${PROJECT_NAME}_DEPS "widgets")
|
||||
|
||||
if(${PROJECT_NAME}_QTQUICK)
|
||||
find_package(Qt${QT_MAJOR_VERSION}Quick)
|
||||
find_package(Qt${QT_MAJOR_VERSION}QuickControls2)
|
||||
add_definitions(-DKDDOCKWIDGETS_QTQUICK)
|
||||
set(${PROJECT_NAME}_DEPS "${${PROJECT_NAME}_DEPS} quick quickcontrols2")
|
||||
else()
|
||||
add_definitions(-DKDDOCKWIDGETS_QTWIDGETS)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE AND NOT EMSCRIPTEN AND NOT ${PROJECT_NAME}_QT6)
|
||||
set(${PROJECT_NAME}_DEPS "${${PROJECT_NAME}_DEPS} x11extras")
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_STATIC)
|
||||
set(${PROJECT_NAME}_LIBRARY_MODE "STATIC")
|
||||
else()
|
||||
@@ -178,69 +244,82 @@ if(USE_DEFAULT_INSTALL_LOCATION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
if(${PROJECT_NAME}_PYTHON_BINDINGS)
|
||||
if(CMAKE_BUILD_TYPE MATCHES "^[Dd]eb" OR ${PROJECT_NAME}_STATIC)
|
||||
message(FATAL_ERROR "** Python Bindings are disabled in debug or static builds.")
|
||||
endif()
|
||||
add_subdirectory(python)
|
||||
endif()
|
||||
|
||||
# Generate .pri file for qmake users
|
||||
include(ECMGeneratePriFile)
|
||||
set(PROJECT_VERSION_STRING ${${PROJECT_NAME}_VERSION})
|
||||
ecm_generate_pri_file(BASE_NAME KDDockWidgets
|
||||
LIB_NAME kddockwidgets
|
||||
FILENAME_VAR pri_filename
|
||||
)
|
||||
install(FILES ${pri_filename} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
|
||||
if(CMAKE_VERSION VERSION_GREATER "3.11.99" AND NOT CMAKE_CONFIGURATION_TYPES) # Not working with VS generator or older cmake versions
|
||||
#TODO: ECM does not support Qt6 yet
|
||||
if(QT_MAJOR_VERSION EQUAL 5)
|
||||
include(ECMGeneratePriFile)
|
||||
set(PROJECT_VERSION_STRING ${${PROJECT_NAME}_VERSION})
|
||||
ecm_generate_pri_file(BASE_NAME KDDockWidgets
|
||||
LIB_NAME kddockwidgets
|
||||
DEPS ${${PROJECT_NAME}_DEPS}
|
||||
FILENAME_VAR pri_filename
|
||||
INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
install(FILES ${pri_filename} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Unable to generate the pri file for qmake users. Try updating CMake.")
|
||||
endif()
|
||||
|
||||
install(FILES LICENSE.txt README.md DESTINATION ${INSTALL_DOC_DIR})
|
||||
install(DIRECTORY LICENSES DESTINATION ${INSTALL_DOC_DIR})
|
||||
|
||||
add_subdirectory(src)
|
||||
if(${PROJECT_NAME}_PYTHON_BINDINGS)
|
||||
add_subdirectory(python)
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_EXAMPLES)
|
||||
if (${PROJECT_NAME}_QTQUICK)
|
||||
if(${PROJECT_NAME}_QTQUICK)
|
||||
add_subdirectory(examples/qtquick)
|
||||
else()
|
||||
add_subdirectory(examples/dockwidgets)
|
||||
add_subdirectory(examples/minimal)
|
||||
set_compiler_flags(kddockwidgets_example)
|
||||
set_compiler_flags(kddockwidgets_minimal_example)
|
||||
add_subdirectory(examples/dockwidgets)
|
||||
add_subdirectory(examples/minimal)
|
||||
add_subdirectory(examples/minimal-mdi)
|
||||
set_compiler_flags(kddockwidgets_example)
|
||||
set_compiler_flags(kddockwidgets_minimal_example)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_DEVELOPER_MODE)
|
||||
include(ECMEnableSanitizers)
|
||||
|
||||
if(${PROJECT_NAME}_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
|
||||
# Require Qt5.15.1 or higher to run the tests_launcher tests on Mac
|
||||
if (NOT APPLE OR Qt5Widgets_VERSION VERSION_GREATER 5.15.0)
|
||||
# tst_docks.exe is pretty big (160 tests), so split it in more runs so we can use threads.
|
||||
add_test(NAME tst_docks0 COMMAND tests_launcher 0 5)
|
||||
add_test(NAME tst_docks1 COMMAND tests_launcher 1 5)
|
||||
add_test(NAME tst_docks2 COMMAND tests_launcher 2 5)
|
||||
add_test(NAME tst_docks3 COMMAND tests_launcher 3 5)
|
||||
add_test(NAME tst_docks4 COMMAND tests_launcher 4 5)
|
||||
add_test(NAME tst_docks5 COMMAND tests_launcher 5 5)
|
||||
add_test(NAME tst_docks6 COMMAND tests_launcher 6 5)
|
||||
add_test(NAME tst_docks7 COMMAND tests_launcher 7 5)
|
||||
add_test(NAME tst_docks8 COMMAND tests_launcher 8 5)
|
||||
add_test(NAME tst_docks9 COMMAND tests_launcher 9 5)
|
||||
add_test(NAME tst_docks10 COMMAND tests_launcher 10 5)
|
||||
add_test(NAME tst_docks11 COMMAND tests_launcher 10 5)
|
||||
add_test(NAME tst_docks12 COMMAND tests_launcher 11 5)
|
||||
add_test(NAME tst_docks13 COMMAND tests_launcher 12 5)
|
||||
add_test(NAME tst_docks14 COMMAND tests_launcher 13 5)
|
||||
add_test(NAME tst_docks15 COMMAND tests_launcher 14 5)
|
||||
add_test(NAME tst_docks16 COMMAND tests_launcher 15 5)
|
||||
add_test(NAME tst_docks17 COMMAND tests_launcher 16 5)
|
||||
add_test(NAME tst_docks18 COMMAND tests_launcher 17 5)
|
||||
add_test(NAME tst_docks19 COMMAND tests_launcher 18 5)
|
||||
add_test(NAME tst_docks20 COMMAND tests_launcher 19 5)
|
||||
add_test(NAME tst_docks21 COMMAND tests_launcher 20 5) # one more for rounding leftovers
|
||||
if(NOT APPLE OR Qt5Widgets_VERSION VERSION_GREATER 5.15.0)
|
||||
# tst_docks.exe is pretty big (160 tests), so split it in more runs so we can use threads.
|
||||
add_test(NAME tst_docks0 COMMAND tests_launcher 0 5)
|
||||
add_test(NAME tst_docks1 COMMAND tests_launcher 1 5)
|
||||
add_test(NAME tst_docks2 COMMAND tests_launcher 2 5)
|
||||
add_test(NAME tst_docks3 COMMAND tests_launcher 3 5)
|
||||
add_test(NAME tst_docks4 COMMAND tests_launcher 4 5)
|
||||
add_test(NAME tst_docks5 COMMAND tests_launcher 5 5)
|
||||
add_test(NAME tst_docks6 COMMAND tests_launcher 6 5)
|
||||
add_test(NAME tst_docks7 COMMAND tests_launcher 7 5)
|
||||
add_test(NAME tst_docks8 COMMAND tests_launcher 8 5)
|
||||
add_test(NAME tst_docks9 COMMAND tests_launcher 9 5)
|
||||
add_test(NAME tst_docks10 COMMAND tests_launcher 10 5)
|
||||
add_test(NAME tst_docks11 COMMAND tests_launcher 10 5)
|
||||
add_test(NAME tst_docks12 COMMAND tests_launcher 11 5)
|
||||
add_test(NAME tst_docks13 COMMAND tests_launcher 12 5)
|
||||
add_test(NAME tst_docks14 COMMAND tests_launcher 13 5)
|
||||
add_test(NAME tst_docks15 COMMAND tests_launcher 14 5)
|
||||
add_test(NAME tst_docks16 COMMAND tests_launcher 15 5)
|
||||
add_test(NAME tst_docks17 COMMAND tests_launcher 16 5)
|
||||
add_test(NAME tst_docks18 COMMAND tests_launcher 17 5)
|
||||
add_test(NAME tst_docks19 COMMAND tests_launcher 18 5)
|
||||
add_test(NAME tst_docks20 COMMAND tests_launcher 19 5)
|
||||
add_test(NAME tst_docks21 COMMAND tests_launcher 20 5) # one more for rounding leftovers
|
||||
endif()
|
||||
if (NOT ${PROJECT_NAME}_QTQUICK)
|
||||
# tst_multisplitter depends on QWidget
|
||||
add_test(NAME tst_multisplitter COMMAND tst_multisplitter)
|
||||
if(NOT ${PROJECT_NAME}_QTQUICK)
|
||||
# tst_multisplitter depends on QWidget
|
||||
add_test(NAME tst_multisplitter COMMAND tst_multisplitter)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
@@ -248,8 +327,16 @@ endif()
|
||||
|
||||
if(${PROJECT_NAME}_DOCS)
|
||||
add_subdirectory(docs) # needs to go last, in case there are build source files
|
||||
#don't create the dummy docs target as it can conflict when used as a submodule
|
||||
#else()
|
||||
# add_custom_target(docs
|
||||
# COMMAND ${CMAKE_COMMAND} -E echo "Sorry, there is no docs target since KDDockWidgets_DOCS=OFF."
|
||||
# "Re-run cmake with the -DKDDockWidgets_DOCS=True option if you want to generate the documentation.")
|
||||
endif()
|
||||
|
||||
if (${PROJECT_NAME}_UNITY_BUILD)
|
||||
set_target_properties(kddockwidgets PROPERTIES UNITY_BUILD ON)
|
||||
if(${PROJECT_NAME}_UNINSTALL)
|
||||
# Add uninstall target
|
||||
include(ECMUninstallTarget)
|
||||
endif()
|
||||
|
||||
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||
|
||||
@@ -1,47 +1,88 @@
|
||||
{
|
||||
"version": 1,
|
||||
"version": 2,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "dev-qtwidgets",
|
||||
"displayName": "dev-qtwidgets",
|
||||
"name": "dev",
|
||||
"displayName": "dev",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-qtwidgets",
|
||||
"binaryDir": "${sourceDir}/build-dev",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'"
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "clazy-qtwidgets",
|
||||
"displayName": "clazy-qtwidgets",
|
||||
"name": "dev-gammaray",
|
||||
"displayName": "dev-gammaray",
|
||||
"description": "A Gammaray friendly build. (No ASAN)",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-clazy-qtwidgets",
|
||||
"binaryDir": "${sourceDir}/build-dev-gammaray",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_WERROR": "ON"
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "clazy",
|
||||
"displayName": "clazy",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-clazy",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_WERROR": "ON",
|
||||
"KDDockWidgets_EXAMPLES" : "OFF"
|
||||
},
|
||||
"environment": {
|
||||
"CXX": "clazy"
|
||||
"CXX": "clazy",
|
||||
"CCACHE_DISABLE" : "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "qtwidgets",
|
||||
"displayName": "qtwidgets",
|
||||
"name": "clazy-qtquick",
|
||||
"displayName": "clazy-qtquick",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-qtwidgets",
|
||||
"binaryDir": "${sourceDir}/build-clazy-qtquick",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_EXAMPLES" : "OFF",
|
||||
"KDDockWidgets_WERROR": "ON",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
},
|
||||
"environment": {
|
||||
"CXX": "clazy",
|
||||
"CCACHE_DISABLE" : "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "qtquick",
|
||||
"displayName": "qtquick",
|
||||
"name": "release",
|
||||
"displayName": "release",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-qtquick",
|
||||
"binaryDir": "${sourceDir}/build-release",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
"CMAKE_UNITY_BUILD" : "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "release-qtquick",
|
||||
"displayName": "release-qtquick",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-release-qtquick",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QTQUICK": "ON",
|
||||
"CMAKE_UNITY_BUILD" : "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -53,7 +94,9 @@
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_QTQUICK": "ON",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'"
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -63,17 +106,19 @@
|
||||
"binaryDir": "${sourceDir}/build-python",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_PYTHON_BINDINGS": "ON"
|
||||
"KDDockWidgets_PYTHON_BINDINGS": "ON",
|
||||
"CMAKE_UNITY_BUILD" : "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "static-qtwidgets",
|
||||
"displayName": "static-qtwidgets",
|
||||
"name": "static",
|
||||
"displayName": "static",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-static-qtwidgets",
|
||||
"binaryDir": "${sourceDir}/build-static",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_STATIC": "ON"
|
||||
"KDDockWidgets_STATIC": "ON",
|
||||
"CMAKE_UNITY_BUILD" : "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -84,49 +129,178 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_STATIC": "ON",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
"KDDockWidgets_QTQUICK": "ON",
|
||||
"CMAKE_UNITY_BUILD" : "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "qtwidgets6",
|
||||
"displayName": "qtwidgets6",
|
||||
"name": "release6",
|
||||
"displayName": "release6",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-qtwidgets6",
|
||||
"binaryDir": "${sourceDir}/build-release6",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QT6": "ON"
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_UNITY_BUILD" : "ON",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
},
|
||||
"environment": {
|
||||
"PATH": "$env{HOME}/Qt/6.0.0/gcc_64/bin:$penv{PATH}"
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-qtwidgets6",
|
||||
"displayName": "dev-qtwidgets6",
|
||||
"name": "dev6",
|
||||
"displayName": "dev6",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-qtwidgets6",
|
||||
"binaryDir": "${sourceDir}/build-dev6",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'"
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'",
|
||||
"KDDockWidgets_FUZZER" : "OFF",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
},
|
||||
"environment": {
|
||||
"PATH": "$env{HOME}/Qt/6.0.0/gcc_64/bin:$penv{PATH}"
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "qtquick6",
|
||||
"displayName": "qtquick6",
|
||||
"name": "release-qtquick6",
|
||||
"displayName": "release-qtquick6",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-qtquick6",
|
||||
"binaryDir": "${sourceDir}/build-release-qtquick6",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QTQUICK": "ON",
|
||||
"KDDockWidgets_QT6": "ON"
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_UNITY_BUILD" : "ON",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
},
|
||||
"environment": {
|
||||
"PATH": "$env{HOME}/Qt/6.0.0/gcc_64/bin:$penv{PATH}"
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-qtquick6",
|
||||
"displayName": "dev-qtquick6",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-qtquick6",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_QTQUICK": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
},
|
||||
"environment": {
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}",
|
||||
"QML2_IMPORT_PATH" : "$env{QT6_DIR}/imports:$env{QT6_DIR}/qml",
|
||||
"LD_LIBRARY_PATH" : "$env{QT6_DIR}/lib"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-clangcl",
|
||||
"displayName": "dev-clangcl",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-clangcl",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "ON"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang-cl",
|
||||
"CXX": "clang-cl"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-qtquick-clangcl",
|
||||
"displayName": "dev-qtquick-clangcl",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-qtquick-clangcl",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang-cl",
|
||||
"CXX": "clang-cl"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-clangcl6",
|
||||
"displayName": "dev-clangcl6",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-clangcl6",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"KDDockWidgets_FUZZER" : "ON",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang-cl",
|
||||
"CXX": "clang-cl",
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-qtquick-clangcl6",
|
||||
"displayName": "dev-qtquick-clangcl6",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-qtquick-clangcl6",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF",
|
||||
"KDDockWidgets_QTQUICK": "ON",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang-cl",
|
||||
"CXX": "clang-cl",
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}",
|
||||
"QML2_IMPORT_PATH" : "$env{QT6_DIR}/imports:$env{QT6_DIR}/qml",
|
||||
"LD_LIBRARY_PATH" : "$env{QT6_DIR}/lib"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "clazy",
|
||||
"configurePreset": "clazy",
|
||||
"environment": {
|
||||
"CLAZY_CHECKS" : "level2,detaching-member,heap-allocated-small-trivial-type,isempty-vs-count,qstring-varargs,qvariant-template-instantiation,raw-environment-function,reserve-candidates,signal-with-return-value,thread-with-slots,no-ctor-missing-parent-argument,no-missing-typeinfo",
|
||||
"CCACHE_DISABLE" : "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "clazy-qtquick",
|
||||
"configurePreset": "clazy-qtquick",
|
||||
"environment": {
|
||||
"CLAZY_CHECKS" : "level2,detaching-member,heap-allocated-small-trivial-type,isempty-vs-count,qstring-varargs,qvariant-template-instantiation,raw-environment-function,reserve-candidates,signal-with-return-value,thread-with-slots,no-ctor-missing-parent-argument,no-missing-typeinfo",
|
||||
"CCACHE_DISABLE" : "ON"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
7
CONTRIBUTORS.txt
Normal file
7
CONTRIBUTORS.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
People who have signed the CLA:
|
||||
|
||||
Christian Riggenbach <criggenbach@magahugu.ch>
|
||||
Jacob Young <amazingjacob@gmail.com>
|
||||
Matthew Waltz <matthewwaltzis@gmail.com>
|
||||
Roman Pudashkin <r.pudashkin@gmail.com>
|
||||
Elnur Ismailzada <eismailzada@gmail.com>
|
||||
63
Changelog
63
Changelog
@@ -1,12 +1,69 @@
|
||||
* v1.3.0 (unreleased)
|
||||
- [TODO] QtQuick support
|
||||
* v1.4.0 (16 July 2021)
|
||||
- No longer supports Qt versions less than 5.12
|
||||
- Experimental MDI support. By using MainWindowMDI you can now have "docked" dock widgets
|
||||
which are free to be arbitrarily positioned and even overlapped inside the main window.
|
||||
- TitleBar's height is now controlled by sizeHint() instead of hardcoded.
|
||||
If you haven't overridden TitleBar or just inheriting from TitleBarWidget then there's nothing to do,
|
||||
as TitleBarWidget already reimplements sizeHint. If you're inheriting directly from TitleBar then make
|
||||
sure to provide a sizeHint.
|
||||
- Added MainWindow::closeDockWidgets()
|
||||
- Fixed crash in MainWindow::layoutEqually()
|
||||
- QtQuick: Added more declarative API
|
||||
- FloatingWindow now honours the dockwidget's max-size, if there's a single
|
||||
dock widget docked. Tabbed cases are more difficult since QStackedLayout doesn't
|
||||
propagate size constraints.
|
||||
- Added MainWindowBase::frameCountChanged()
|
||||
- Introduced Config::setDropIndicatorsInhibited(), which allows you to disable support
|
||||
for drop indicators while dragging.
|
||||
- Fixed embedding the main window into a non-kddw main window (#204, #168)
|
||||
- Fixed crash with an MFC application
|
||||
- Allows to disable translucency via the KDDW_NO_TRANSLUCENCY env var, useful
|
||||
in case running on weird Window Managers.
|
||||
- Added Flag_ShowButtonsOnTabBarIfTitleBarHidden, which can be used when using Flag_HideTitleBarWhenTabsVisible.
|
||||
The close and float buttons will be shown directly in the tab-bar.
|
||||
- Fixes persistent central frame being invisible after closing all tabs (#220)
|
||||
- Added python bindings for the InitialOption struct (#198)
|
||||
- Generate and install camelcase forwarding headers (public, exported classes)
|
||||
- Build in Release mode by default (in non-developer situations)
|
||||
|
||||
* v1.3.1 (7 June 2021)
|
||||
- Improve restoring layout when RestoreOption_RelativeToMainWindow is used (#171)
|
||||
- Improved dragging windows across screens in mixed hdpi setups
|
||||
- Fixed Flag_NativeTitleBar not hiding the client title bars when restoring (#170)
|
||||
- Double clicking a native title bar of a Qt::Tool window will now redock the window (#173)
|
||||
- Size of FloatingWindow now accounts for the fact that it's using Flag_NativeTitleBar and
|
||||
resizes its content accordingly (#174)
|
||||
- Fixed popups on overlayed dock widgets not working
|
||||
- Don't restore maximized state when using RestoreOption_RelativeToMainWindow (#184)
|
||||
|
||||
* v1.3.0 (8 February 2021)
|
||||
- Experimental QtQuick support (#49)
|
||||
- Added static DockWidgetBase::byName() (#126)
|
||||
- The enum KDDockWidgets::AddingOption has been deprecated, use
|
||||
KDDockWidgets::InitialVisibilityOption instead
|
||||
- You can now pass a preferred initial size to MainWindow::addDockWidget() (#95)
|
||||
- Added DockWidgetBase::Option_DeleteOnClose
|
||||
- Added Config::Flag_CloseOnlyCurrentTab
|
||||
- PySide6 support
|
||||
- Layout restorer now restores maximzied/minimized state too (#81)
|
||||
- Fixed dock indicators sometimes not appearing on Windows (#103)
|
||||
- Fixed Flag_NativeTitleBar not working
|
||||
- Fixed drag offset when dragging too fast with mouse
|
||||
- Fixed bug where last tab index position wouldn't be remembered in case user
|
||||
had manually reordered tabs (#154)
|
||||
- Fixed crash when hosting a QQuickWidget (#150)
|
||||
- Fixed CMake Visual Studio generator not working
|
||||
- Sidebar overlays now maintain their size when toggled (#155)
|
||||
- Added DockWidget::setFloatingGeometry() (#144)
|
||||
|
||||
* v1.2.1 (unreleased)
|
||||
* v1.2.1 (6 February 2021)
|
||||
- Support for resizing dock widgets when they are in overlay/popup mode (autohide/sidebar feature)
|
||||
- Fixed title bar close button enabled state not being restored with Layout saver (#137)
|
||||
- Installs a version header (kddockwidgets_version.h) that defines a version string and other useful versioning macros (#138)
|
||||
- DockWidgetBase::eventFilter() is protected instead of private (regression vs v1.1) (#148)
|
||||
It's recommended that you rebuild your application when updating KDDW, as MSVC encodes private/protected in the name mangling.
|
||||
- Fixed WASM build on Windows (#163)
|
||||
- Fixed sidebar overlay not getting hidden when clicking on the main window docking area (#157)
|
||||
|
||||
* v1.2.0 (17 December 2020)
|
||||
- Wayland support
|
||||
|
||||
28
LICENSES/BSD-3-Clause.txt
Normal file
28
LICENSES/BSD-3-Clause.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
Copyright (c) <year> <owner>. All rights reserved.
|
||||
|
||||
This license applies to the CMake ECM modules only.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
18
README-QtQuick.md
Normal file
18
README-QtQuick.md
Normal file
@@ -0,0 +1,18 @@
|
||||
Supported Qt versions and toolchains
|
||||
=====================================
|
||||
|
||||
KDDockWidgets for QtQuick requires a C++17 capable compiler and either
|
||||
Qt >= 5.15.0 or Qt >= 6.2.
|
||||
|
||||
|
||||
TROUBLESHOOTING
|
||||
===============
|
||||
|
||||
- QtGraphicalEffects is not supported, as it's buggy when moving between different QWindows.
|
||||
See for example QTBUG-94943, KDDockWidgets issue #213. Also search the Qt bug tracker
|
||||
for "QQuickItem: Cannot use same item on different windows at the same time"
|
||||
|
||||
- Very rarely, in some Nvidia/X11 setups, floating/docking has noticeable lag (like 1 second)
|
||||
This could be solved by going to Nvidia's settings and making sure all monitors have
|
||||
the same refresh rate and disabling "Allow Flipping". It's not known why this solves it. Might also
|
||||
be a bug in Qt.
|
||||
74
README-bindings.md
Normal file
74
README-bindings.md
Normal file
@@ -0,0 +1,74 @@
|
||||
These are the instructions for building the Python bindings for KDDockWidgets.
|
||||
|
||||
Make sure you have PySide2, shiboken2 and shiboken2-generator installed.
|
||||
As this time, you cannot get shiboken2-generator because the wheels are not on PyPi.
|
||||
To use the wheels do this:
|
||||
|
||||
```
|
||||
% pip3 install \
|
||||
--index-url=http://download.qt.io/official_releases/QtForPython/ \
|
||||
--trusted-host download.qt.io \
|
||||
shiboken2 pyside2 shiboken2_generator
|
||||
```
|
||||
|
||||
For more info visit https://doc.qt.io/qtforpython/shiboken2/gettingstarted.html
|
||||
|
||||
afterwards run 'pip3 list | grep PySide2'
|
||||
Note the version *must* match the same Qt you intend to use when building KDDockWidgets.
|
||||
|
||||
Not supported:
|
||||
- Debug builds
|
||||
- static builds
|
||||
- python2 bindings
|
||||
- only some 32-bit platforms are supported. see https://wiki.qt.io/Qt_for_Python
|
||||
|
||||
Tell CMake to build the bindings by passing the `-DKDDockWidgets_PYTHON_BINDINGS=True' option,
|
||||
followed by the make command.
|
||||
|
||||
The bindings will be installed to the passed `-DCMAKE_INSTALL_PREFIX`, which
|
||||
might require setting the `PYTHONPATH` env variable to point to that path when
|
||||
running applications. Alternatively, configure the bindings install location
|
||||
by passing `-DKDDockWidgets_PYTHON_BINDINGS_INSTALL_PREFIX=/usr/lib/python3.8/site-packages`
|
||||
to CMake (adjust to the python path on your system).
|
||||
|
||||
To run the KDDW python example
|
||||
|
||||
```
|
||||
$ export PYTHONPATH=/kddw/install/path # Only if needed
|
||||
$ cd python/examples/
|
||||
$ rcc -g python -o rc_assets.py ../../examples/dockwidgets/resources_example.qrc
|
||||
$ python3 main.py
|
||||
```
|
||||
|
||||
Build Issues
|
||||
|
||||
* If you see errors like "Unable to locate Clang's built-in include directory"
|
||||
then first make sure you have llvm installed. If you still have problems try
|
||||
setting the environment variable `LLVM_INSTALL_DIR` to point to your llvm installation.
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
export LLVM_INSTALL_DIR=/usr/local/opt/llvm-11
|
||||
set "LLVM_INSTALL_DIR=C:\Program Files\LLVM" #Windows
|
||||
```
|
||||
|
||||
* When building the examples you may encounter errors loading shared libraries from shiboken2_generator.
|
||||
|
||||
Try:
|
||||
|
||||
```
|
||||
export LD_LIBRARY_PATH=/usr/local/lib/python/dist-packages/PySide2/Qt/lib #linux
|
||||
export DYLD_LIBRARY_PATH=/usr/local/lib/python/dist-packages/PySide2/Qt/lib #Mac
|
||||
#adjust to wherever your PySide is installed
|
||||
```
|
||||
|
||||
* On Windows the `libclang.dll` that ship with QtForPython is not compatible with MSVC2019.
|
||||
To fix this, copy the `libclang.dll` that comes with llvm into shiboken2, like so:
|
||||
|
||||
```
|
||||
cd C:\Python37\Lib\site-packages\shiboken2_generator
|
||||
copy libclang.dll libclang.dll.save
|
||||
copy "C:\Program Files\llvm\bin\libclang.dll" libclang.dll
|
||||
#Python3 installation in C:\Python37 and llvm in c:\Program Files\llvm. adjust as needed
|
||||
```
|
||||
96
README.md
96
README.md
@@ -1,3 +1,5 @@
|
||||
[](https://travis-ci.com/KDAB/KDDockWidgets)
|
||||
|
||||
KDDockWidgets
|
||||
=============
|
||||
`KDDockWidgets` is a Qt dock widget library written by KDAB, suitable for replacing
|
||||
@@ -29,7 +31,7 @@ however that this demo isn't fully featured, as it's running on Qt for WebAssemb
|
||||
|
||||
Features
|
||||
========
|
||||
- Provide advanced docking that QDockWidgets doesn't support
|
||||
- Provide advanced docking that QDockWidget doesn't support
|
||||
- Native window resize on Windows (allowing for Aero-snap even with custom title bar decorations)
|
||||
- Arrow drop indicators for great drop precision
|
||||
- Allow for totally different, user provided, drop indicator types
|
||||
@@ -46,13 +48,13 @@ Features
|
||||
- Customize title bars
|
||||
- Customize window frames
|
||||
- Custom widget separators
|
||||
- Crossplatform (macOS, Linux, Windows, WebAssembly, Wayland, X11/XCB, EGLFS are working)
|
||||
- Cross-platform (macOS, Linux, Windows, WebAssembly, Wayland, X11/XCB, EGLFS are working)
|
||||
See README-Wayland.md and README-WASM.md for platform specific information.
|
||||
- Layouting engine honouring min/max size constraints and some size policies
|
||||
- PySide2 bindings
|
||||
- Clean codebase
|
||||
- Not mixing GUI with state with logic with animations
|
||||
- Great test coverage, even the gui and DnD operations are tested. 200 tests currently.
|
||||
- Great test coverage, even the GUI and DnD operations are tested. 200 tests currently.
|
||||
- Fuzzer for doing random testing and finding bugs
|
||||
- Lazy separator resize
|
||||
- Reordering tabs with mouse
|
||||
@@ -69,16 +71,12 @@ Screen capture
|
||||

|
||||
|
||||
|
||||
Roadmap
|
||||
========
|
||||
- QtQuick support
|
||||
|
||||
Trying out the examples
|
||||
=======================
|
||||
A full demo lives in `examples/dockwidgets/`, it showcasts most of the features.
|
||||
A simpler example lives in `examples/minimal/`, which might be more indicated
|
||||
to learn the API, as it's less overwelming than the full demo.
|
||||
A full demo that showcases most of the features lives in [examples/dockwidgets](examples/dockwidgets).
|
||||
|
||||
A simpler example can be found in [examples/minimal](examples/minimal),
|
||||
which might be more indicated to learn the API, as it's less overwhelming than the full demo.
|
||||
|
||||
Open a terminal capable of building Qt5 applications.
|
||||
Make sure you have cmake, ninja, compiler, Qt, etc in PATH.
|
||||
@@ -93,72 +91,58 @@ $ cmake --build . --target install
|
||||
```
|
||||
|
||||
Now build and run the example:
|
||||
|
||||
```
|
||||
$ cd path/to/kddockwidgets/examples/dockwidgets/
|
||||
$ cmake -G Ninja -DCMAKE_PREFIX_PATH=/path/where/to/install
|
||||
$ cmake --build .
|
||||
$ ./kddockwidgets_example
|
||||
|
||||
```
|
||||
|
||||
The installation directory defaults to `c:\KDAB\KDDockWidgets-<version>` on Windows
|
||||
and `/usr/local/KDAB/KDDockWidgets-<version>` on non-Windows. You can change this
|
||||
location by passing the option `-DCMAKE_INSTALL_PREFIX=/install/path` to cmake.
|
||||
and `/usr/local/KDAB/KDDockWidgets-<version>` on non-Windows.
|
||||
|
||||
You can change the installation location by passing the option `-DCMAKE_INSTALL_PREFIX=/install/path` to cmake.
|
||||
|
||||
Using
|
||||
=====
|
||||
From your CMake project, add
|
||||
|
||||
```
|
||||
find_package(KDDockWidgets CONFIG)
|
||||
```
|
||||
|
||||
and link to the imported target `KDAB::kddockwidgets`.
|
||||
That's all you need to do (the imported target also brings in the include directories)
|
||||
|
||||
You may also need to modify the `CMAKE_MODULE_PATH` environment variable depending
|
||||
You may also need to modify the `CMAKE_PREFIX_PATH` environment variable depending
|
||||
on where you installed KDDockWidgets.
|
||||
|
||||
|
||||
Python Bindings
|
||||
================
|
||||
Make sure you have pyside2, shiboken2 and shiboken2-generator installed.
|
||||
As this time, you cannot get shiboken2-generator because the wheels are not on PyPi.
|
||||
To use the wheels do this:
|
||||
Please refer to [README-bindings.md](README-bindings.md).
|
||||
|
||||
```
|
||||
% pip3 install \
|
||||
--index-url=http://download.qt.io/official_releases/QtForPython/ \
|
||||
--trusted-host download.qt.io \
|
||||
shiboken2 pyside2 shiboken2_generator
|
||||
```
|
||||
Versioning
|
||||
==========
|
||||
|
||||
For more info visit https://doc.qt.io/qtforpython/shiboken2/gettingstarted.html
|
||||
New features go to master while the stable branch only accepts non-intrusive bug fixes.
|
||||
|
||||
Once QtForPython is installed you are ready to generate the PySide bindings
|
||||
for KDDockwWidgets.
|
||||
We'll try to remain source-compatible across versions. API will get a deprecation
|
||||
notice before being removed in the next version. Note that this source-compatibility
|
||||
effort is only for the public API. Private API (headers ending in _p.h) might change so you
|
||||
shouldn't depend on them. Private API is only exposed so more advanced users can
|
||||
override, for example `paintEvent()`, and not so they can change internal business logic.
|
||||
|
||||
Next pass `-DKDDockWidgets_PYTHON_BINDINGS=ON` to CMake, followed by the
|
||||
make command.
|
||||
|
||||
The bindings will be installed to the passed `-DCMAKE_INSTALL_PREFIX`, which
|
||||
might require setting the `PYTHONPATH` env variable to point to that path when
|
||||
running applications. Alternatively, configure the bindings install location
|
||||
by passing `-DKDDockWidgets_PYTHON_BINDINGS_INSTALL_PREFIX=/usr/lib/python3.8/site-packages`
|
||||
to CMake (adjust to the python path on your system).
|
||||
|
||||
To run the KDDW python example
|
||||
```
|
||||
$ export PYTHONPATH=/kddw/install/path # Only if needed
|
||||
$ cd python/examples/
|
||||
$ rcc -g python -o rc_assets.py ../../examples/dockwidgets/resources_example.qrc
|
||||
$ python3 main.py
|
||||
```
|
||||
We don't promise or test binary compatibility. It's advised that you recompile
|
||||
your application whenever updating KDDW.
|
||||
|
||||
|
||||
Supported Qt versions and toolchains
|
||||
=====================================
|
||||
KDDockWidgets requires Qt >= 5.9 (or >=5.12 if Python bindings are enabled).
|
||||
The QtQuick support will require Qt >= 5.15.
|
||||
Qt 6 is supported.
|
||||
KDDockWidgets requires Qt5 >= 5.12 or Qt6 >= 6.1.
|
||||
The QtQuick support requires Qt5 >= 5.15 or Qt6 >= 6.1.
|
||||
|
||||
|
||||
Regarding compilers, whatever toolchain is able to build Qt 5.9 should also be
|
||||
fine. Note however that MSVC 2013 isn't supported anymore due to compiler crashes.
|
||||
@@ -166,7 +150,7 @@ fine. Note however that MSVC 2013 isn't supported anymore due to compiler crashe
|
||||
|
||||
Licensing
|
||||
=========
|
||||
KDDockWidgets is (C) 2018-2021, Klarälvdalens Datakonsult AB, and is licensed according to
|
||||
KDDockWidgets is (C) 2019-2021, Klarälvdalens Datakonsult AB, and is licensed according to
|
||||
the terms of the [GPL 2.0](LICENSES/GPL-2.0-only.txt) or [GPL 3.0](LICENSES/GPL-3.0-only.txt).
|
||||
|
||||
Contact KDAB at <info@kdab.com> to inquire about commercial licensing.
|
||||
@@ -174,14 +158,26 @@ Contact KDAB at <info@kdab.com> to inquire about commercial licensing.
|
||||
|
||||
Get Involved
|
||||
============
|
||||
Please submit your issue reports to our GitHub space at
|
||||
https://github.com/KDAB/KDDockWidgets
|
||||
|
||||
|
||||
When reporting bugs please make it easy for the maintainer to reproduce it. Use `examples/minimal/` or
|
||||
`examples/dockwidgets/` for reproducing the problem. If you did modifications to the example in order to
|
||||
reproduce then please attach the *patch* and not a picture of your changes. You can get a patch by doing
|
||||
`git diff > repro.diff` at the repo root.
|
||||
|
||||
Also state which KDDW sha1, branch or version you're using, and which operating system.
|
||||
|
||||
|
||||
KDAB will happily accept external contributions; however, **all** contributions require a
|
||||
signed [Copyright Assignment Agreement](docs/KDDockWidgets-CopyrightAssignmentForm.docx).
|
||||
signed [Copyright Assignment Agreement](docs/KDDockWidgets-CopyrightAssignmentForm.pdf).
|
||||
|
||||
This is needed so we can continue to dual-license it.
|
||||
|
||||
Contact info@kdab.com for more information.
|
||||
|
||||
Please submit your contributions or issue reports from our GitHub space at
|
||||
https://github.com/KDAB/KDDockWidgets
|
||||
|
||||
Thanks to our [contributors](CONTRIBUTORS.txt).
|
||||
|
||||
About KDAB
|
||||
==========
|
||||
|
||||
80
appveyor.yml
Normal file
80
appveyor.yml
Normal file
@@ -0,0 +1,80 @@
|
||||
#---------------------------------#
|
||||
# general configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# version format
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
# branches to build
|
||||
branches:
|
||||
except:
|
||||
- gh-pages
|
||||
|
||||
# Do not build on tags (GitHub and BitBucket)
|
||||
skip_tags: false
|
||||
|
||||
#---------------------------------#
|
||||
# environment configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# Build worker image
|
||||
image:
|
||||
- Visual Studio 2019
|
||||
|
||||
# scripts that are called at very beginning, before repo cloning
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
#---------------------------------#
|
||||
# build configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# build platform, i.e. x86, x64, Any CPU. This setting is optional.
|
||||
platform:
|
||||
- x64
|
||||
|
||||
# build Configuration, i.e. Debug, Release, etc.
|
||||
configuration:
|
||||
- Release
|
||||
|
||||
install:
|
||||
- call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
|
||||
- set QTDIR=C:\Qt\5.15\msvc2019_64
|
||||
- set PATH=%QTDIR%\bin;%PATH%
|
||||
build_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=%CONFIGURATION% -DKDDockWidgets_TESTS=True -DKDDockWidgets_EXAMPLES=True -DKDDockWidgets_DEVELOPER_MODE=True ..
|
||||
- nmake
|
||||
|
||||
# to disable automatic builds
|
||||
#build: off
|
||||
|
||||
#---------------------------------#
|
||||
# tests configuration #
|
||||
#---------------------------------#
|
||||
|
||||
test_script:
|
||||
- nmake test
|
||||
|
||||
# to disable automatic tests
|
||||
#test: off
|
||||
|
||||
|
||||
#---------------------------------#
|
||||
# deployment configuration #
|
||||
#---------------------------------#
|
||||
|
||||
deploy: off
|
||||
|
||||
#---------------------------------#
|
||||
# notifications #
|
||||
#---------------------------------#
|
||||
notifications:
|
||||
# Email
|
||||
- provider: Email
|
||||
to:
|
||||
- allen.winter@kdab.com
|
||||
- sergio.martins@kdab.com
|
||||
on_build_success: false
|
||||
on_build_failure: true
|
||||
@@ -40,6 +40,7 @@
|
||||
# - thread
|
||||
# - leak
|
||||
# - undefined
|
||||
# - fuzzer-no-link
|
||||
# - fuzzer
|
||||
#
|
||||
# The sanitizers "address", "memory" and "thread" are mutually exclusive. You
|
||||
@@ -102,30 +103,47 @@ endmacro ()
|
||||
# MACRO check_compiler_support
|
||||
#------------------------------
|
||||
macro (enable_sanitizer_flags sanitize_option)
|
||||
if (${sanitize_option} MATCHES "address")
|
||||
check_compiler_version("4.8" "3.1")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(XSAN_LINKER_FLAGS "asan")
|
||||
elseif (${sanitize_option} MATCHES "thread")
|
||||
check_compiler_version("4.8" "3.1")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
|
||||
set(XSAN_LINKER_FLAGS "tsan")
|
||||
elseif (${sanitize_option} MATCHES "memory")
|
||||
check_compiler_version("99.99" "3.1")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=memory")
|
||||
elseif (${sanitize_option} MATCHES "leak")
|
||||
check_compiler_version("4.9" "3.4")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=leak")
|
||||
set(XSAN_LINKER_FLAGS "lsan")
|
||||
elseif (${sanitize_option} MATCHES "undefined")
|
||||
check_compiler_version("4.9" "3.1")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
elseif (${sanitize_option} MATCHES "fuzzer")
|
||||
check_compiler_version("99.99" "6.0")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=fuzzer")
|
||||
else ()
|
||||
message(FATAL_ERROR "Compiler sanitizer option \"${sanitize_option}\" not supported.")
|
||||
endif ()
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
if (${sanitize_option} MATCHES "address")
|
||||
set(msvc_asan_required_version "19.28")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${msvc_asan_required_version})
|
||||
message(WARNING "Address sanitizer requires at least MSVC ${msvc_asan_required_version}")
|
||||
else()
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=address")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Compiler sanitizer option \"${sanitize_option}\" not supported on MSVC yet")
|
||||
endif()
|
||||
else()
|
||||
if (${sanitize_option} MATCHES "address")
|
||||
check_compiler_version("4.8" "3.1")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(XSAN_LINKER_FLAGS "asan")
|
||||
elseif (${sanitize_option} MATCHES "thread")
|
||||
check_compiler_version("4.8" "3.1")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
|
||||
set(XSAN_LINKER_FLAGS "tsan")
|
||||
elseif (${sanitize_option} MATCHES "memory")
|
||||
check_compiler_version("99.99" "3.1")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=memory")
|
||||
elseif (${sanitize_option} MATCHES "leak")
|
||||
check_compiler_version("4.9" "3.4")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=leak")
|
||||
set(XSAN_LINKER_FLAGS "lsan")
|
||||
elseif (${sanitize_option} MATCHES "undefined")
|
||||
check_compiler_version("4.9" "3.1")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=undefined -fsanitize=float-divide-by-zero -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
elseif (${sanitize_option} MATCHES "fuzzer-no-link")
|
||||
check_compiler_version("99.99" "6.0")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=fuzzer-no-link")
|
||||
set(XSAN_LINKER_FLAGS "-fsanitize=fuzzer-no-link")
|
||||
elseif (${sanitize_option} MATCHES "fuzzer")
|
||||
check_compiler_version("99.99" "6.0")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=fuzzer")
|
||||
else ()
|
||||
message(FATAL_ERROR "Compiler sanitizer option \"${sanitize_option}\" not supported.")
|
||||
endif ()
|
||||
endif()
|
||||
endmacro ()
|
||||
|
||||
if (ECM_ENABLE_SANITIZERS)
|
||||
@@ -149,6 +167,11 @@ if (ECM_ENABLE_SANITIZERS)
|
||||
string(REPLACE "-Wl,--no-undefined" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}")
|
||||
endif ()
|
||||
endforeach()
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
foreach (CUR_SANITIZER ${ECM_ENABLE_SANITIZERS})
|
||||
enable_sanitizer_flags(${CUR_SANITIZER})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${XSAN_COMPILE_FLAGS}")
|
||||
endforeach()
|
||||
else()
|
||||
message(STATUS "Tried to enable sanitizers (-DECM_ENABLE_SANITIZERS=${ECM_ENABLE_SANITIZERS}), \
|
||||
but compiler (${CMAKE_CXX_COMPILER_ID}) does not have sanitizer support")
|
||||
|
||||
223
cmake/ECM/modules/ECMGenerateHeaders.cmake
Normal file
223
cmake/ECM/modules/ECMGenerateHeaders.cmake
Normal file
@@ -0,0 +1,223 @@
|
||||
# SPDX-FileCopyrightText: 2013 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
|
||||
# SPDX-FileCopyrightText: 2014 Alex Merry <alex.merry@kdemail.net>
|
||||
# SPDX-FileCopyrightText: 2015 Patrick Spendrin <patrick.spendrin@kdab.com>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
ECMGenerateHeaders
|
||||
------------------
|
||||
|
||||
Generate C/C++ CamelCase forwarding headers.
|
||||
|
||||
::
|
||||
|
||||
ecm_generate_headers(<camelcase_forwarding_headers_var>
|
||||
HEADER_NAMES <CamelCaseName> [<CamelCaseName> [...]]
|
||||
[ORIGINAL <CAMELCASE|LOWERCASE>]
|
||||
[HEADER_EXTENSION <header_extension>]
|
||||
[OUTPUT_DIR <output_dir>]
|
||||
[PREFIX <prefix>]
|
||||
[REQUIRED_HEADERS <variable>]
|
||||
[COMMON_HEADER <HeaderName>]
|
||||
[RELATIVE <relative_path>])
|
||||
|
||||
For each CamelCase header name passed to HEADER_NAMES, a file of that name
|
||||
will be generated that will include a version with ``.h`` or, if set,
|
||||
``.<header_extension>`` appended.
|
||||
For example, the generated header ``ClassA`` will include ``classa.h`` (or
|
||||
``ClassA.h``, see ORIGINAL).
|
||||
If a CamelCaseName consists of multiple comma-separated files, e.g.
|
||||
``ClassA,ClassB,ClassC``, then multiple camelcase header files will be
|
||||
generated which are redirects to the first header file.
|
||||
The file locations of these generated headers will be stored in
|
||||
<camelcase_forwarding_headers_var>.
|
||||
|
||||
ORIGINAL specifies how the name of the original header is written: lowercased
|
||||
or also camelcased. The default is LOWERCASE. Since 1.8.0.
|
||||
|
||||
HEADER_EXTENSION specifies what file name extension is used for the header
|
||||
files. The default is "h". Since 5.48.0.
|
||||
|
||||
PREFIX places the generated headers in subdirectories. This should be a
|
||||
CamelCase name like ``KParts``, which will cause the CamelCase forwarding
|
||||
headers to be placed in the ``KParts`` directory (e.g. ``KParts/Part``). It
|
||||
will also, for the convenience of code in the source distribution, generate
|
||||
forwarding headers based on the original names (e.g. ``kparts/part.h``). This
|
||||
allows includes like ``"#include <kparts/part.h>"`` to be used before
|
||||
installation, as long as the include_directories are set appropriately.
|
||||
|
||||
OUTPUT_DIR specifies where the files will be generated; this should be within
|
||||
the build directory. By default, ``${CMAKE_CURRENT_BINARY_DIR}`` will be used.
|
||||
This option can be used to avoid file conflicts.
|
||||
|
||||
REQUIRED_HEADERS specifies an output variable name where all the required
|
||||
headers will be appended so that they can be installed together with the
|
||||
generated ones. This is mostly intended as a convenience so that adding a new
|
||||
header to a project only requires specifying the CamelCase variant in the
|
||||
CMakeLists.txt file; the original variant will then be added to this
|
||||
variable.
|
||||
|
||||
COMMON_HEADER generates an additional convenience header which includes all
|
||||
other header files.
|
||||
|
||||
The RELATIVE argument indicates where the original headers can be found
|
||||
relative to CMAKE_CURRENT_SOURCE_DIR. It does not affect the generated
|
||||
CamelCase forwarding files, but ecm_generate_headers() uses it when checking
|
||||
that the original header exists, and to generate originally named forwarding
|
||||
headers when PREFIX is set.
|
||||
|
||||
To allow other parts of the source distribution (eg: tests) to use the
|
||||
generated headers before installation, it may be desirable to set the
|
||||
INCLUDE_DIRECTORIES property for the library target to output_dir. For
|
||||
example, if OUTPUT_DIR is CMAKE_CURRENT_BINARY_DIR (the default), you could do
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_include_directories(MyLib PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
|
||||
|
||||
Example usage (without PREFIX):
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
ecm_generate_headers(
|
||||
MyLib_FORWARDING_HEADERS
|
||||
HEADERS
|
||||
MLFoo
|
||||
MLBar
|
||||
# etc
|
||||
REQUIRED_HEADERS MyLib_HEADERS
|
||||
COMMON_HEADER MLGeneral
|
||||
)
|
||||
install(FILES ${MyLib_FORWARDING_HEADERS} ${MyLib_HEADERS}
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/include
|
||||
COMPONENT Devel)
|
||||
|
||||
Example usage (with PREFIX):
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
ecm_generate_headers(
|
||||
MyLib_FORWARDING_HEADERS
|
||||
HEADERS
|
||||
Foo
|
||||
# several classes are contained in bar.h, so generate
|
||||
# additional files
|
||||
Bar,BarList
|
||||
# etc
|
||||
PREFIX MyLib
|
||||
REQUIRED_HEADERS MyLib_HEADERS
|
||||
)
|
||||
install(FILES ${MyLib_FORWARDING_HEADERS}
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/MyLib
|
||||
COMPONENT Devel)
|
||||
install(FILES ${MyLib_HEADERS}
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/mylib
|
||||
COMPONENT Devel)
|
||||
|
||||
Since pre-1.0.0.
|
||||
#]=======================================================================]
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
function(ECM_GENERATE_HEADERS camelcase_forwarding_headers_var)
|
||||
set(options)
|
||||
set(oneValueArgs ORIGINAL HEADER_EXTENSION OUTPUT_DIR PREFIX REQUIRED_HEADERS COMMON_HEADER RELATIVE)
|
||||
set(multiValueArgs HEADER_NAMES)
|
||||
cmake_parse_arguments(EGH "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if (EGH_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "Unexpected arguments to ECM_GENERATE_HEADERS: ${EGH_UNPARSED_ARGUMENTS}")
|
||||
endif()
|
||||
|
||||
if(NOT EGH_HEADER_NAMES)
|
||||
message(FATAL_ERROR "Missing header_names argument to ECM_GENERATE_HEADERS")
|
||||
endif()
|
||||
|
||||
if(NOT EGH_ORIGINAL)
|
||||
# default
|
||||
set(EGH_ORIGINAL "LOWERCASE")
|
||||
endif()
|
||||
if(NOT EGH_ORIGINAL STREQUAL "LOWERCASE" AND NOT EGH_ORIGINAL STREQUAL "CAMELCASE")
|
||||
message(FATAL_ERROR "Unexpected value for original argument to ECM_GENERATE_HEADERS: ${EGH_ORIGINAL}")
|
||||
endif()
|
||||
|
||||
if(NOT EGH_HEADER_EXTENSION)
|
||||
set(EGH_HEADER_EXTENSION "h")
|
||||
endif()
|
||||
|
||||
if(NOT EGH_OUTPUT_DIR)
|
||||
set(EGH_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
# Make sure EGH_RELATIVE is /-terminated when it's not empty
|
||||
if (EGH_RELATIVE AND NOT "${EGH_RELATIVE}" MATCHES "^.*/$")
|
||||
set(EGH_RELATIVE "${EGH_RELATIVE}/")
|
||||
endif()
|
||||
|
||||
set(originalprefix)
|
||||
if (EGH_PREFIX)
|
||||
if (NOT "${EGH_PREFIX}" MATCHES "^.*/$")
|
||||
set(EGH_PREFIX "${EGH_PREFIX}/")
|
||||
endif()
|
||||
if (EGH_ORIGINAL STREQUAL "CAMELCASE")
|
||||
set(originalprefix "${EGH_PREFIX}")
|
||||
else()
|
||||
string(TOLOWER "${EGH_PREFIX}" originalprefix)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(_classnameentry ${EGH_HEADER_NAMES})
|
||||
string(REPLACE "," ";" _classnames ${_classnameentry})
|
||||
list(GET _classnames 0 _baseclass)
|
||||
|
||||
if (EGH_ORIGINAL STREQUAL "CAMELCASE")
|
||||
set(originalbasename "${_baseclass}")
|
||||
else()
|
||||
string(TOLOWER "${_baseclass}" originalbasename)
|
||||
endif()
|
||||
|
||||
set(_actualheader "${CMAKE_CURRENT_SOURCE_DIR}/${EGH_RELATIVE}${originalbasename}.${EGH_HEADER_EXTENSION}")
|
||||
if (NOT EXISTS ${_actualheader})
|
||||
message(FATAL_ERROR "Could not find \"${_actualheader}\"")
|
||||
endif()
|
||||
|
||||
foreach(_CLASSNAME ${_classnames})
|
||||
set(FANCY_HEADER_FILE "${EGH_OUTPUT_DIR}/${EGH_PREFIX}${_CLASSNAME}")
|
||||
if (NOT EXISTS ${FANCY_HEADER_FILE})
|
||||
file(WRITE ${FANCY_HEADER_FILE} "#include \"${originalprefix}${originalbasename}.${EGH_HEADER_EXTENSION}\"\n")
|
||||
endif()
|
||||
list(APPEND ${camelcase_forwarding_headers_var} "${FANCY_HEADER_FILE}")
|
||||
if (EGH_PREFIX)
|
||||
# Local forwarding header, for namespaced headers, e.g. kparts/part.h
|
||||
if(EGH_ORIGINAL STREQUAL "CAMELCASE")
|
||||
set(originalclassname "${_CLASSNAME}")
|
||||
else()
|
||||
string(TOLOWER "${_CLASSNAME}" originalclassname)
|
||||
endif()
|
||||
set(REGULAR_HEADER_NAME ${EGH_OUTPUT_DIR}/${originalprefix}${originalclassname}.${EGH_HEADER_EXTENSION})
|
||||
if (NOT EXISTS ${REGULAR_HEADER_NAME})
|
||||
file(WRITE ${REGULAR_HEADER_NAME} "#include \"${_actualheader}\"\n")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
list(APPEND _REQUIRED_HEADERS "${_actualheader}")
|
||||
endforeach()
|
||||
|
||||
if(EGH_COMMON_HEADER)
|
||||
#combine required headers into 1 big convenience header
|
||||
set(COMMON_HEADER ${EGH_OUTPUT_DIR}/${EGH_PREFIX}${EGH_COMMON_HEADER})
|
||||
file(WRITE ${COMMON_HEADER} "// convenience header\n")
|
||||
foreach(_header ${_REQUIRED_HEADERS})
|
||||
get_filename_component(_base ${_header} NAME)
|
||||
file(APPEND ${COMMON_HEADER} "#include \"${_base}\"\n")
|
||||
endforeach()
|
||||
list(APPEND ${camelcase_forwarding_headers_var} "${COMMON_HEADER}")
|
||||
endif()
|
||||
|
||||
set(${camelcase_forwarding_headers_var} ${${camelcase_forwarding_headers_var}} PARENT_SCOPE)
|
||||
if (EGH_REQUIRED_HEADERS)
|
||||
set(${EGH_REQUIRED_HEADERS} ${${EGH_REQUIRED_HEADERS}} ${_REQUIRED_HEADERS} PARENT_SCOPE)
|
||||
endif ()
|
||||
endfunction()
|
||||
@@ -1,81 +1,88 @@
|
||||
#.rst:
|
||||
# ECMGeneratePriFile
|
||||
# ------------------
|
||||
#
|
||||
# Generate a ``.pri`` file for the benefit of qmake-based projects.
|
||||
#
|
||||
# As well as the function below, this module creates the cache variable
|
||||
# ``ECM_MKSPECS_INSTALL_DIR`` and sets the default value to ``mkspecs/modules``.
|
||||
# This assumes Qt and the current project are both installed to the same
|
||||
# non-system prefix. Packagers who use ``-DCMAKE_INSTALL_PREFIX=/usr`` will
|
||||
# certainly want to set ``ECM_MKSPECS_INSTALL_DIR`` to something like
|
||||
# ``share/qt5/mkspecs/modules``.
|
||||
#
|
||||
# The main thing is that this should be the ``modules`` subdirectory of either
|
||||
# the default qmake ``mkspecs`` directory or of a directory that will be in the
|
||||
# ``$QMAKEPATH`` environment variable when qmake is run.
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# ecm_generate_pri_file(BASE_NAME <baseName>
|
||||
# LIB_NAME <libName>
|
||||
# [DEPS "<dep> [<dep> [...]]"]
|
||||
# [FILENAME_VAR <filename_variable>]
|
||||
# [INCLUDE_INSTALL_DIR <dir>]
|
||||
# [LIB_INSTALL_DIR <dir>])
|
||||
#
|
||||
# If your CMake project produces a Qt-based library, you may expect there to be
|
||||
# applications that wish to use it that use a qmake-based build system, rather
|
||||
# than a CMake-based one. Creating a ``.pri`` file will make use of your
|
||||
# library convenient for them, in much the same way that CMake config files make
|
||||
# things convenient for CMake-based applications.
|
||||
#
|
||||
# ecm_generate_pri_file() generates just such a file. It requires the
|
||||
# ``PROJECT_VERSION_STRING`` variable to be set. This is typically set by
|
||||
# :module:`ECMSetupVersion`, although the project() command in CMake 3.0.0 and
|
||||
# later can also set this.
|
||||
#
|
||||
# BASE_NAME specifies the name qmake project (.pro) files should use to refer to
|
||||
# the library (eg: KArchive). LIB_NAME is the name of the actual library to
|
||||
# link to (ie: the first argument to add_library()). DEPS is a space-separated
|
||||
# list of the base names of other libraries (for Qt libraries, use the same
|
||||
# names you use with the ``QT`` variable in a qmake project file, such as "core"
|
||||
# for QtCore). FILENAME_VAR specifies the name of a variable to store the path
|
||||
# to the generated file in.
|
||||
#
|
||||
# INCLUDE_INSTALL_DIR is the path (relative to ``CMAKE_INSTALL_PREFIX``) that
|
||||
# include files will be installed to. It defaults to
|
||||
# ``${INCLUDE_INSTALL_DIR}/<baseName>`` if the ``INCLUDE_INSTALL_DIR`` variable
|
||||
# is set. If that variable is not set, the ``CMAKE_INSTALL_INCLUDEDIR`` variable
|
||||
# is used instead, and if neither are set ``include`` is used. LIB_INSTALL_DIR
|
||||
# operates similarly for the installation location for libraries; it defaults to
|
||||
# ``${LIB_INSTALL_DIR}``, ``${CMAKE_INSTALL_LIBDIR}`` or ``lib``, in that order.
|
||||
#
|
||||
# Example usage:
|
||||
#
|
||||
# .. code-block:: cmake
|
||||
#
|
||||
# ecm_generate_pri_file(
|
||||
# BASE_NAME KArchive
|
||||
# LIB_NAME KF5KArchive
|
||||
# DEPS "core"
|
||||
# FILENAME_VAR pri_filename
|
||||
# )
|
||||
# install(FILES ${pri_filename} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
|
||||
#
|
||||
# A qmake-based project that wished to use this would then do::
|
||||
#
|
||||
# QT += KArchive
|
||||
#
|
||||
# in their ``.pro`` file.
|
||||
#
|
||||
# Since pre-1.0.0.
|
||||
|
||||
#=============================================================================
|
||||
# SPDX-FileCopyrightText: 2014 David Faure <faure@kde.org>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
ECMGeneratePriFile
|
||||
------------------
|
||||
|
||||
Generate a ``.pri`` file for the benefit of qmake-based projects.
|
||||
|
||||
As well as the function below, this module creates the cache variable
|
||||
``ECM_MKSPECS_INSTALL_DIR`` and sets the default value to ``mkspecs/modules``.
|
||||
This assumes Qt and the current project are both installed to the same
|
||||
non-system prefix. Packagers who use ``-DCMAKE_INSTALL_PREFIX=/usr`` will
|
||||
certainly want to set ``ECM_MKSPECS_INSTALL_DIR`` to something like
|
||||
``share/qt5/mkspecs/modules``.
|
||||
|
||||
The main thing is that this should be the ``modules`` subdirectory of either
|
||||
the default qmake ``mkspecs`` directory or of a directory that will be in the
|
||||
``$QMAKEPATH`` environment variable when qmake is run.
|
||||
|
||||
::
|
||||
|
||||
ecm_generate_pri_file(BASE_NAME <baseName>
|
||||
LIB_NAME <libName>
|
||||
[VERSION <version>] # since 5.83
|
||||
[DEPS "<dep> [<dep> [...]]"]
|
||||
[FILENAME_VAR <filename_variable>]
|
||||
[INCLUDE_INSTALL_DIR <dir>]
|
||||
[LIB_INSTALL_DIR <dir>])
|
||||
|
||||
If your CMake project produces a Qt-based library, you may expect there to be
|
||||
applications that wish to use it that use a qmake-based build system, rather
|
||||
than a CMake-based one. Creating a ``.pri`` file will make use of your
|
||||
library convenient for them, in much the same way that CMake config files make
|
||||
things convenient for CMake-based applications. ``ecm_generate_pri_file()``
|
||||
generates just such a file.
|
||||
|
||||
VERSION specifies the version of the library the ``.pri`` file describes. If
|
||||
not set, the value is taken from the context variable ``PROJECT_VERSION``.
|
||||
This variable is usually set by the ``project(... VERSION ...)`` command or,
|
||||
if CMake policy CMP0048 is not NEW, by :module:`ECMSetupVersion`.
|
||||
For backward-compatibility with older ECM versions the
|
||||
``PROJECT_VERSION_STRING`` variable as set by :module:`ECMSetupVersion`
|
||||
will be preferred over ``PROJECT_VERSION`` if set, unless the minimum
|
||||
required version of ECM is 5.83 and newer. Since 5.83.
|
||||
|
||||
BASE_NAME specifies the name qmake project (.pro) files should use to refer to
|
||||
the library (eg: KArchive). LIB_NAME is the name of the actual library to
|
||||
link to (ie: the first argument to add_library()). DEPS is a space-separated
|
||||
list of the base names of other libraries (for Qt libraries, use the same
|
||||
names you use with the ``QT`` variable in a qmake project file, such as "core"
|
||||
for QtCore). FILENAME_VAR specifies the name of a variable to store the path
|
||||
to the generated file in.
|
||||
|
||||
INCLUDE_INSTALL_DIR is the path (relative to ``CMAKE_INSTALL_PREFIX``) that
|
||||
include files will be installed to. It defaults to
|
||||
``${INCLUDE_INSTALL_DIR}/<baseName>`` if the ``INCLUDE_INSTALL_DIR`` variable
|
||||
is set. If that variable is not set, the ``CMAKE_INSTALL_INCLUDEDIR`` variable
|
||||
is used instead, and if neither are set ``include`` is used. LIB_INSTALL_DIR
|
||||
operates similarly for the installation location for libraries; it defaults to
|
||||
``${LIB_INSTALL_DIR}``, ``${CMAKE_INSTALL_LIBDIR}`` or ``lib``, in that order.
|
||||
|
||||
Example usage:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
ecm_generate_pri_file(
|
||||
BASE_NAME KArchive
|
||||
LIB_NAME KF5KArchive
|
||||
DEPS "core"
|
||||
FILENAME_VAR pri_filename
|
||||
VERSION 4.2.0
|
||||
)
|
||||
install(FILES ${pri_filename} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
|
||||
|
||||
A qmake-based project that wished to use this would then do::
|
||||
|
||||
QT += KArchive
|
||||
|
||||
in their ``.pro`` file.
|
||||
|
||||
Since pre-1.0.0.
|
||||
#]=======================================================================]
|
||||
|
||||
# Replicate the logic from KDEInstallDirs.cmake as we can't depend on it
|
||||
# Ask qmake if we're using the same prefix as Qt
|
||||
set(_askqmake OFF)
|
||||
@@ -89,15 +96,24 @@ endif()
|
||||
|
||||
if(KDE_INSTALL_USE_QT_SYS_PATHS OR _askqmake)
|
||||
include(ECMQueryQmake)
|
||||
query_qmake(qt_install_prefix_dir QT_INSTALL_PREFIX)
|
||||
query_qmake(qt_host_data_dir QT_HOST_DATA)
|
||||
set(ECM_MKSPECS_INSTALL_DIR ${qt_host_data_dir}/mkspecs/modules CACHE PATH "The directory where mkspecs will be installed to.")
|
||||
if(qt_install_prefix_dir STREQUAL "${CMAKE_INSTALL_PREFIX}")
|
||||
file(RELATIVE_PATH qt_host_data_dir ${qt_install_prefix_dir} ${qt_host_data_dir})
|
||||
endif()
|
||||
if(qt_host_data_dir STREQUAL "")
|
||||
set(mkspecs_install_dir mkspecs/modules)
|
||||
else()
|
||||
set(mkspecs_install_dir ${qt_host_data_dir}/mkspecs/modules)
|
||||
endif()
|
||||
set(ECM_MKSPECS_INSTALL_DIR ${mkspecs_install_dir} CACHE PATH "The directory where mkspecs will be installed to.")
|
||||
else()
|
||||
set(ECM_MKSPECS_INSTALL_DIR mkspecs/modules CACHE PATH "The directory where mkspecs will be installed to.")
|
||||
endif()
|
||||
|
||||
function(ECM_GENERATE_PRI_FILE)
|
||||
set(options )
|
||||
set(oneValueArgs BASE_NAME LIB_NAME DEPS FILENAME_VAR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
|
||||
set(oneValueArgs BASE_NAME LIB_NAME DEPS FILENAME_VAR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR VERSION)
|
||||
set(multiValueArgs )
|
||||
|
||||
cmake_parse_arguments(EGPF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
@@ -106,14 +122,28 @@ function(ECM_GENERATE_PRI_FILE)
|
||||
message(FATAL_ERROR "Unknown keywords given to ECM_GENERATE_PRI_FILE(): \"${EGPF_UNPARSED_ARGUMENTS}\"")
|
||||
endif()
|
||||
|
||||
if(ECM_GLOBAL_FIND_VERSION VERSION_LESS 5.83.0)
|
||||
set(_support_backward_compat_version_string_var TRUE)
|
||||
else()
|
||||
set(_support_backward_compat_version_string_var FALSE)
|
||||
endif()
|
||||
|
||||
if(NOT EGPF_BASE_NAME)
|
||||
message(FATAL_ERROR "Required argument BASE_NAME missing in ECM_GENERATE_PRI_FILE() call")
|
||||
endif()
|
||||
if(NOT EGPF_LIB_NAME)
|
||||
message(FATAL_ERROR "Required argument LIB_NAME missing in ECM_GENERATE_PRI_FILE() call")
|
||||
endif()
|
||||
if(NOT PROJECT_VERSION_STRING)
|
||||
message(FATAL_ERROR "Required variable PROJECT_VERSION_STRING not set before ECM_GENERATE_PRI_FILE() call. Did you call ecm_setup_version?")
|
||||
if(NOT EGPF_VERSION)
|
||||
if(_support_backward_compat_version_string_var)
|
||||
if(NOT PROJECT_VERSION_STRING AND NOT PROJECT_VERSION)
|
||||
message(FATAL_ERROR "Required variable PROJECT_VERSION_STRING or PROJECT_VERSION not set before ECM_GENERATE_PRI_FILE() call. Missing call of ecm_setup_version() or project(VERSION)?")
|
||||
endif()
|
||||
else()
|
||||
if(NOT PROJECT_VERSION)
|
||||
message(FATAL_ERROR "Required variable PROJECT_VERSION not set before ECM_GENERATE_PRI_FILE() call. Missing call of ecm_setup_version() or project(VERSION)?")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(NOT EGPF_INCLUDE_INSTALL_DIR)
|
||||
if(INCLUDE_INSTALL_DIR)
|
||||
@@ -134,9 +164,22 @@ function(ECM_GENERATE_PRI_FILE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" PROJECT_VERSION_MAJOR "${PROJECT_VERSION_STRING}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" PROJECT_VERSION_MINOR "${PROJECT_VERSION_STRING}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PROJECT_VERSION_PATCH "${PROJECT_VERSION_STRING}")
|
||||
if(EGPF_VERSION)
|
||||
set(PRI_VERSION "${EGPF_VERSION}")
|
||||
else()
|
||||
if(_support_backward_compat_version_string_var AND PROJECT_VERSION_STRING)
|
||||
set(PRI_VERSION "${PROJECT_VERSION_STRING}")
|
||||
if(NOT PROJECT_VERSION_STRING STREQUAL PROJECT_VERSION)
|
||||
message(DEPRECATION "ECM_GENERATE_PRI_FILE() will no longer support PROJECT_VERSION_STRING when the required minimum version of ECM is 5.83 or newer. Set VERSION parameter or use PROJECT_VERSION instead.")
|
||||
endif()
|
||||
else()
|
||||
set(PRI_VERSION "${PROJECT_VERSION}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" PRI_VERSION_MAJOR "${PRI_VERSION}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" PRI_VERSION_MINOR "${PRI_VERSION}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PRI_VERSION_PATCH "${PRI_VERSION}")
|
||||
|
||||
# Prepare the right number of "../.." to go from ECM_MKSPECS_INSTALL_DIR to the install prefix
|
||||
# This allows to make the generated pri files relocatable (no absolute paths)
|
||||
@@ -182,10 +225,10 @@ function(ECM_GENERATE_PRI_FILE)
|
||||
file(GENERATE
|
||||
OUTPUT ${PRI_FILENAME}
|
||||
CONTENT
|
||||
"QT.${PRI_TARGET_BASENAME}.VERSION = ${PROJECT_VERSION_STRING}
|
||||
QT.${PRI_TARGET_BASENAME}.MAJOR_VERSION = ${PROJECT_VERSION_MAJOR}
|
||||
QT.${PRI_TARGET_BASENAME}.MINOR_VERSION = ${PROJECT_VERSION_MINOR}
|
||||
QT.${PRI_TARGET_BASENAME}.PATCH_VERSION = ${PROJECT_VERSION_PATCH}
|
||||
"QT.${PRI_TARGET_BASENAME}.VERSION = ${PRI_VERSION}
|
||||
QT.${PRI_TARGET_BASENAME}.MAJOR_VERSION = ${PRI_VERSION_MAJOR}
|
||||
QT.${PRI_TARGET_BASENAME}.MINOR_VERSION = ${PRI_VERSION_MINOR}
|
||||
QT.${PRI_TARGET_BASENAME}.PATCH_VERSION = ${PRI_VERSION_PATCH}
|
||||
QT.${PRI_TARGET_BASENAME}.name = ${PRI_TARGET_LIBNAME}
|
||||
QT.${PRI_TARGET_BASENAME}.module = ${PRI_TARGET_LIBNAME}
|
||||
QT.${PRI_TARGET_BASENAME}.defines = ${PRI_TARGET_DEFINES}
|
||||
|
||||
212
cmake/ECM/modules/ECMSetupVersion.cmake
Normal file
212
cmake/ECM/modules/ECMSetupVersion.cmake
Normal file
@@ -0,0 +1,212 @@
|
||||
# SPDX-FileCopyrightText: 2014 Alex Merry <alex.merry@kde.org>
|
||||
# SPDX-FileCopyrightText: 2012 Alexander Neundorf <neundorf@kde.org>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
ECMSetupVersion
|
||||
---------------
|
||||
|
||||
Handle library version information.
|
||||
|
||||
::
|
||||
|
||||
ecm_setup_version(<version>
|
||||
VARIABLE_PREFIX <prefix>
|
||||
[SOVERSION <soversion>]
|
||||
[VERSION_HEADER <filename>]
|
||||
[PACKAGE_VERSION_FILE <filename> [COMPATIBILITY <compat>]] )
|
||||
|
||||
This parses a version string and sets up a standard set of version variables.
|
||||
It can optionally also create a C version header file and a CMake package
|
||||
version file to install along with the library.
|
||||
|
||||
If the ``<version>`` argument is of the form ``<major>.<minor>.<patch>``
|
||||
(or ``<major>.<minor>.<patch>.<tweak>``), The following CMake variables are
|
||||
set::
|
||||
|
||||
<prefix>_VERSION_MAJOR - <major>
|
||||
<prefix>_VERSION_MINOR - <minor>
|
||||
<prefix>_VERSION_PATCH - <patch>
|
||||
<prefix>_VERSION - <version>
|
||||
<prefix>_SOVERSION - <soversion>, or <major> if SOVERSION was not given
|
||||
|
||||
For backward-compatibility also this variable is set (only if the minimum required
|
||||
version of ECM is < 5.83)::
|
||||
|
||||
<prefix>_VERSION_STRING - <version> (use <prefix>_VERSION instead)
|
||||
|
||||
If CMake policy CMP0048 is not NEW, the following CMake variables will also
|
||||
be set::
|
||||
|
||||
PROJECT_VERSION_MAJOR - <major>
|
||||
PROJECT_VERSION_MINOR - <minor>
|
||||
PROJECT_VERSION_PATCH - <patch>
|
||||
PROJECT_VERSION - <version>
|
||||
|
||||
For backward-compatibility, if CMake policy CMP0048 is not NEW, also this variable is set
|
||||
(only if the minimum required version of ECM is < 5.83)::
|
||||
|
||||
PROJECT_VERSION_STRING - <version> (use PROJECT_VERSION instead)
|
||||
|
||||
If the VERSION_HEADER option is used, a simple C header is generated with the
|
||||
given filename. If filename is a relative path, it is interpreted as relative
|
||||
to CMAKE_CURRENT_BINARY_DIR. The generated header contains the following
|
||||
macros::
|
||||
|
||||
<prefix>_VERSION_MAJOR - <major> as an integer
|
||||
<prefix>_VERSION_MINOR - <minor> as an integer
|
||||
<prefix>_VERSION_PATCH - <patch> as an integer
|
||||
<prefix>_VERSION_STRING - <version> as a C string
|
||||
<prefix>_VERSION - the version as an integer
|
||||
|
||||
``<prefix>_VERSION`` has ``<patch>`` in the bottom 8 bits, ``<minor>`` in the
|
||||
next 8 bits and ``<major>`` in the remaining bits. Note that ``<patch>`` and
|
||||
``<minor>`` must be less than 256.
|
||||
|
||||
If the PACKAGE_VERSION_FILE option is used, a simple CMake package version
|
||||
file is created using the write_basic_package_version_file() macro provided by
|
||||
CMake. It should be installed in the same location as the Config.cmake file of
|
||||
the library so that it can be found by find_package(). If the filename is a
|
||||
relative path, it is interpreted as relative to CMAKE_CURRENT_BINARY_DIR. The
|
||||
optional COMPATIBILITY option is forwarded to
|
||||
write_basic_package_version_file(), and defaults to AnyNewerVersion.
|
||||
|
||||
If CMake policy CMP0048 is NEW, an alternative form of the command is
|
||||
available::
|
||||
|
||||
ecm_setup_version(PROJECT
|
||||
[VARIABLE_PREFIX <prefix>]
|
||||
[SOVERSION <soversion>]
|
||||
[VERSION_HEADER <filename>]
|
||||
[PACKAGE_VERSION_FILE <filename>] )
|
||||
|
||||
This will use the version information set by the project() command.
|
||||
VARIABLE_PREFIX defaults to the project name. Note that PROJECT must be the
|
||||
first argument. In all other respects, it behaves like the other form of the
|
||||
command.
|
||||
|
||||
Since pre-1.0.0.
|
||||
|
||||
COMPATIBILITY option available since 1.6.0.
|
||||
#]=======================================================================]
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
# save the location of the header template while CMAKE_CURRENT_LIST_DIR
|
||||
# has the value we want
|
||||
set(_ECM_SETUP_VERSION_HEADER_TEMPLATE "${CMAKE_CURRENT_LIST_DIR}/ECMVersionHeader.h.in")
|
||||
|
||||
function(ecm_setup_version _version)
|
||||
set(options )
|
||||
set(oneValueArgs VARIABLE_PREFIX SOVERSION VERSION_HEADER PACKAGE_VERSION_FILE COMPATIBILITY)
|
||||
set(multiValueArgs )
|
||||
|
||||
cmake_parse_arguments(ESV "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(ESV_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "Unknown keywords given to ECM_SETUP_VERSION(): \"${ESV_UNPARSED_ARGUMENTS}\"")
|
||||
endif()
|
||||
|
||||
set(project_manages_version FALSE)
|
||||
set(use_project_version FALSE)
|
||||
cmake_policy(GET CMP0048 project_version_policy)
|
||||
if(project_version_policy STREQUAL "NEW")
|
||||
set(project_manages_version TRUE)
|
||||
if(_version STREQUAL "PROJECT")
|
||||
set(use_project_version TRUE)
|
||||
endif()
|
||||
elseif(_version STREQUAL "PROJECT")
|
||||
message(FATAL_ERROR "ecm_setup_version given PROJECT argument, but CMP0048 is not NEW")
|
||||
endif()
|
||||
|
||||
set(should_set_prefixed_vars TRUE)
|
||||
if(NOT ESV_VARIABLE_PREFIX)
|
||||
if(use_project_version)
|
||||
set(ESV_VARIABLE_PREFIX "${PROJECT_NAME}")
|
||||
set(should_set_prefixed_vars FALSE)
|
||||
else()
|
||||
message(FATAL_ERROR "Required argument PREFIX missing in ECM_SETUP_VERSION() call")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(use_project_version)
|
||||
set(_version "${PROJECT_VERSION}")
|
||||
set(_major "${PROJECT_VERSION_MAJOR}")
|
||||
set(_minor "${PROJECT_VERSION_MINOR}")
|
||||
set(_patch "${PROJECT_VERSION_PATCH}")
|
||||
else()
|
||||
string(REGEX REPLACE "^0*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" _major "${_version}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.0*([0-9]+)\\.[0-9]+.*" "\\1" _minor "${_version}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.0*([0-9]+).*" "\\1" _patch "${_version}")
|
||||
endif()
|
||||
|
||||
if(NOT ESV_SOVERSION)
|
||||
set(ESV_SOVERSION ${_major})
|
||||
endif()
|
||||
|
||||
if(ECM_GLOBAL_FIND_VERSION VERSION_LESS 5.83.0)
|
||||
set(_set_backward_compat_version_string_vars TRUE)
|
||||
else()
|
||||
set(_set_backward_compat_version_string_vars FALSE)
|
||||
endif()
|
||||
|
||||
if(should_set_prefixed_vars)
|
||||
set(${ESV_VARIABLE_PREFIX}_VERSION "${_version}")
|
||||
set(${ESV_VARIABLE_PREFIX}_VERSION_MAJOR ${_major})
|
||||
set(${ESV_VARIABLE_PREFIX}_VERSION_MINOR ${_minor})
|
||||
set(${ESV_VARIABLE_PREFIX}_VERSION_PATCH ${_patch})
|
||||
endif()
|
||||
|
||||
set(${ESV_VARIABLE_PREFIX}_SOVERSION ${ESV_SOVERSION})
|
||||
|
||||
if(NOT project_manages_version)
|
||||
set(PROJECT_VERSION "${_version}")
|
||||
set(PROJECT_VERSION_MAJOR "${_major}")
|
||||
set(PROJECT_VERSION_MINOR "${_minor}")
|
||||
set(PROJECT_VERSION_PATCH "${_patch}")
|
||||
endif()
|
||||
|
||||
if(_set_backward_compat_version_string_vars)
|
||||
set(PROJECT_VERSION_STRING "${PROJECT_VERSION}")
|
||||
set(${ESV_VARIABLE_PREFIX}_VERSION_STRING "${${ESV_VARIABLE_PREFIX}_VERSION}")
|
||||
endif()
|
||||
|
||||
if(ESV_VERSION_HEADER)
|
||||
set(HEADER_PREFIX "${ESV_VARIABLE_PREFIX}")
|
||||
set(HEADER_VERSION "${_version}")
|
||||
set(HEADER_VERSION_MAJOR "${_major}")
|
||||
set(HEADER_VERSION_MINOR "${_minor}")
|
||||
set(HEADER_VERSION_PATCH "${_patch}")
|
||||
configure_file("${_ECM_SETUP_VERSION_HEADER_TEMPLATE}" "${ESV_VERSION_HEADER}")
|
||||
endif()
|
||||
|
||||
if(ESV_PACKAGE_VERSION_FILE)
|
||||
if(NOT ESV_COMPATIBILITY)
|
||||
set(ESV_COMPATIBILITY AnyNewerVersion)
|
||||
endif()
|
||||
write_basic_package_version_file("${ESV_PACKAGE_VERSION_FILE}" VERSION ${_version} COMPATIBILITY ${ESV_COMPATIBILITY})
|
||||
endif()
|
||||
|
||||
if(should_set_prefixed_vars)
|
||||
set(${ESV_VARIABLE_PREFIX}_VERSION_MAJOR "${${ESV_VARIABLE_PREFIX}_VERSION_MAJOR}" PARENT_SCOPE)
|
||||
set(${ESV_VARIABLE_PREFIX}_VERSION_MINOR "${${ESV_VARIABLE_PREFIX}_VERSION_MINOR}" PARENT_SCOPE)
|
||||
set(${ESV_VARIABLE_PREFIX}_VERSION_PATCH "${${ESV_VARIABLE_PREFIX}_VERSION_PATCH}" PARENT_SCOPE)
|
||||
set(${ESV_VARIABLE_PREFIX}_VERSION "${${ESV_VARIABLE_PREFIX}_VERSION}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
# always set the soversion
|
||||
set(${ESV_VARIABLE_PREFIX}_SOVERSION "${${ESV_VARIABLE_PREFIX}_SOVERSION}" PARENT_SCOPE)
|
||||
|
||||
if(NOT project_manages_version)
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION}" PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}" PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_MINOR "${PROJECT_VERSION_MINOR}" PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_PATCH "${PROJECT_VERSION_PATCH}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(_set_backward_compat_version_string_vars)
|
||||
set(PROJECT_VERSION_STRING "${PROJECT_VERSION_STRING}" PARENT_SCOPE)
|
||||
set(${ESV_VARIABLE_PREFIX}_VERSION_STRING "${${ESV_VARIABLE_PREFIX}_VERSION}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
50
cmake/ECM/modules/ECMUninstallTarget.cmake
Normal file
50
cmake/ECM/modules/ECMUninstallTarget.cmake
Normal file
@@ -0,0 +1,50 @@
|
||||
# SPDX-FileCopyrightText: 2015 Alex Merry <alex.merry@kde.org>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
ECMUninstallTarget
|
||||
------------------
|
||||
|
||||
Add an ``uninstall`` target.
|
||||
|
||||
By including this module, an ``uninstall`` target will be added to your CMake
|
||||
project. This will remove all files installed (or updated) by a previous
|
||||
invocation of the ``install`` target. It will not remove files created or
|
||||
modified by an ``install(SCRIPT)`` or ``install(CODE)`` command; you should
|
||||
create a custom uninstallation target for these and use ``add_dependency`` to
|
||||
make the ``uninstall`` target depend on it:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
include(ECMUninstallTarget)
|
||||
install(SCRIPT install-foo.cmake)
|
||||
add_custom_target(uninstall_foo COMMAND ${CMAKE_COMMAND} -P uninstall-foo.cmake)
|
||||
add_dependency(uninstall uninstall_foo)
|
||||
|
||||
The target will fail if the ``install`` target has not yet been run (so it is
|
||||
not possible to run CMake on the project and then immediately run the
|
||||
``uninstall`` target).
|
||||
|
||||
.. warning::
|
||||
|
||||
CMake deliberately does not provide an ``uninstall`` target by default on
|
||||
the basis that such a target has the potential to remove important files
|
||||
from a user's computer. Use with caution.
|
||||
|
||||
Since 1.7.0.
|
||||
#]=======================================================================]
|
||||
|
||||
if (NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ecm_uninstall.cmake.in"
|
||||
"${CMAKE_BINARY_DIR}/ecm_uninstall.cmake"
|
||||
IMMEDIATE
|
||||
@ONLY
|
||||
)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_BINARY_DIR}/ecm_uninstall.cmake"
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
)
|
||||
endif()
|
||||
17
cmake/ECM/modules/ECMVersionHeader.h.in
Normal file
17
cmake/ECM/modules/ECMVersionHeader.h.in
Normal file
@@ -0,0 +1,17 @@
|
||||
// This file was generated by ecm_setup_version(): DO NOT EDIT!
|
||||
|
||||
#ifndef @HEADER_PREFIX@_VERSION_H
|
||||
#define @HEADER_PREFIX@_VERSION_H
|
||||
|
||||
#define @HEADER_PREFIX@_VERSION_STRING "@HEADER_VERSION@"
|
||||
#define @HEADER_PREFIX@_VERSION_MAJOR @HEADER_VERSION_MAJOR@
|
||||
#define @HEADER_PREFIX@_VERSION_MINOR @HEADER_VERSION_MINOR@
|
||||
#define @HEADER_PREFIX@_VERSION_PATCH @HEADER_VERSION_PATCH@
|
||||
#define @HEADER_PREFIX@_VERSION @HEADER_PREFIX@_VERSION_CHECK(@HEADER_PREFIX@_VERSION_MAJOR, @HEADER_PREFIX@_VERSION_MINOR, @HEADER_PREFIX@_VERSION_PATCH)
|
||||
|
||||
/*
|
||||
for example: @HEADER_PREFIX@_VERSION >= @HEADER_PREFIX@_VERSION_CHECK(1, 2, 2))
|
||||
*/
|
||||
#define @HEADER_PREFIX@_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
|
||||
|
||||
#endif
|
||||
21
cmake/ECM/modules/ecm_uninstall.cmake.in
Normal file
21
cmake/ECM/modules/ecm_uninstall.cmake.in
Normal file
@@ -0,0 +1,21 @@
|
||||
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
endif()
|
||||
|
||||
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -12,10 +12,10 @@ if(NOT INSTALL_RUNTIME_DIR)
|
||||
set(INSTALL_RUNTIME_DIR ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
if(NOT INSTALL_LIBRARY_DIR)
|
||||
set(INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR})
|
||||
set(INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
if(NOT INSTALL_ARCHIVE_DIR)
|
||||
set(INSTALL_ARCHIVE_DIR ${CMAKE_INSTALL_LIBDIR})
|
||||
set(INSTALL_ARCHIVE_DIR ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
if(NOT INSTALL_INCLUDE_DIR)
|
||||
set(INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
@@ -28,7 +28,7 @@ if(NOT INSTALL_DOC_DIR)
|
||||
endif()
|
||||
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
if (APPLE)
|
||||
if(APPLE)
|
||||
set(CMAKE_MACOSX_RPATH ON)
|
||||
else()
|
||||
set(CMAKE_INSTALL_RPATH "$ORIGIN/../${INSTALL_LIBRARY_DIR}")
|
||||
|
||||
@@ -4,29 +4,6 @@
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
#
|
||||
# Create variables for all the various install paths for the Qt version in use
|
||||
@@ -63,7 +40,7 @@ foreach(QVAL ${VARS_LIST})
|
||||
else()
|
||||
list(GET QVAL_LIST 1 path)
|
||||
endif()
|
||||
if(NOT ${var}) #if set aleady on the command line for example
|
||||
if(NOT ${var}) #if set already on the command line for example
|
||||
set(${var} ${path} CACHE PATH "Qt install path for ${var}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -80,12 +80,12 @@ else()
|
||||
|
||||
message(STATUS "ShibokenGenerator base dir: ${SHIBOKEN_GENERATOR_BASEDIR}")
|
||||
message(STATUS "Shiboken base dir: ${SHIBOKEN_BASEDIR}")
|
||||
message(STATUS "Shiboken custom path: ${SHIBOKEN_CUSTOM_PATH}")
|
||||
message(STATUS "Shiboken custom path: ${SHIBOKEN_CUSTOM_PREFIX}")
|
||||
|
||||
if(SHIBOKEN_BASEDIR)
|
||||
find_path(SHIBOKEN_INCLUDE_DIR
|
||||
shiboken.h
|
||||
PATHS ${SHIBOKEN_CUSTOM_PATH} ${SHIBOKEN_GENERATOR_BASEDIR}/include
|
||||
PATHS ${SHIBOKEN_CUSTOM_PREFIX} ${SHIBOKEN_GENERATOR_BASEDIR}/include
|
||||
NO_DEFAULT_PATH)
|
||||
if(MSVC)
|
||||
SET(SHIBOKEN_LIBRARY_BASENAMES "shiboken2.abi3.lib")
|
||||
@@ -112,7 +112,7 @@ else()
|
||||
if (NOT SHIBOKEN_INCLUDE_DIR)
|
||||
return()
|
||||
endif()
|
||||
set(SHIBOKEN_SEARCH_PATHS ${SHIBOKEN_CUSTOM_PATH})
|
||||
set(SHIBOKEN_SEARCH_PATHS ${SHIBOKEN_CUSTOM_PREFIX})
|
||||
list(APPEND SHIBOKEN_SEARCH_PATHS ${SHIBOKEN_BASEDIR})
|
||||
list(APPEND SHIBOKEN_SEARCH_PATHS ${SHIBOKEN_GENERATOR_BASEDIR})
|
||||
find_file(SHIBOKEN_LIBRARY
|
||||
|
||||
@@ -58,12 +58,12 @@ string(REPLACE ";" "." SHIBOKEN_VERSION "${SHIBOKEN_VERSION}")
|
||||
|
||||
message(STATUS "ShibokenGenerator base dir: ${SHIBOKEN_GENERATOR_BASEDIR}")
|
||||
message(STATUS "Shiboken base dir: ${SHIBOKEN_BASEDIR}")
|
||||
message(STATUS "Shiboken custom path: ${SHIBOKEN_CUSTOM_PATH}")
|
||||
message(STATUS "Shiboken custom path: ${SHIBOKEN_CUSTOM_PREFIX}")
|
||||
|
||||
if(SHIBOKEN_BASEDIR)
|
||||
find_path(SHIBOKEN_INCLUDE_DIR
|
||||
shiboken.h
|
||||
PATHS ${SHIBOKEN_CUSTOM_PATH} ${SHIBOKEN_GENERATOR_BASEDIR}/include
|
||||
PATHS ${SHIBOKEN_CUSTOM_PREFIX} ${SHIBOKEN_GENERATOR_BASEDIR}/include
|
||||
NO_DEFAULT_PATH)
|
||||
if(MSVC)
|
||||
SET(SHIBOKEN_LIBRARY_BASENAMES "shiboken6.abi3.lib")
|
||||
@@ -90,7 +90,7 @@ if(SHIBOKEN_BASEDIR)
|
||||
if (NOT SHIBOKEN_INCLUDE_DIR)
|
||||
return()
|
||||
endif()
|
||||
set(SHIBOKEN_SEARCH_PATHS ${SHIBOKEN_CUSTOM_PATH})
|
||||
set(SHIBOKEN_SEARCH_PATHS ${SHIBOKEN_CUSTOM_PREFIX})
|
||||
list(APPEND SHIBOKEN_SEARCH_PATHS ${SHIBOKEN_BASEDIR})
|
||||
list(APPEND SHIBOKEN_SEARCH_PATHS ${SHIBOKEN_GENERATOR_BASEDIR})
|
||||
find_file(SHIBOKEN_LIBRARY
|
||||
|
||||
@@ -74,11 +74,11 @@ endmacro()
|
||||
# Args:
|
||||
# LIBRARY_NAME - The name of the output module
|
||||
# TYPESYSTEM_PATHS - A list of paths where shiboken should look for typesystem files
|
||||
# INCLUDE_PATHS - Include pahts necessary to parse your class. *This is not the same as build*
|
||||
# INCLUDE_PATHS - Include paths necessary to parse your class. *This is not the same as build*
|
||||
# OUTPUT_SOURCES - The files that will be generated by shiboken
|
||||
# TARGET_INCLUDE_DIRS - This will be passed to target_include_directories
|
||||
# TARGET_LINK_LIBRARIES - This will be passed to target_link_libraries
|
||||
# GLOBAL_INCLUDE - A header-file that contains alls classes that will be generated
|
||||
# GLOBAL_INCLUDE - A header-file that contains all classes that will be generated
|
||||
# TYPESYSTEM_XML - The target binding typesystem (that should be the full path)
|
||||
# DEPENDS - This var will be passed to add_custom_command(DEPENDS) so a new generation will be
|
||||
# trigger if one of these files changes
|
||||
@@ -137,7 +137,6 @@ macro(CREATE_PYTHON_BINDINGS
|
||||
|
||||
target_include_directories(${TARGET_NAME} PUBLIC
|
||||
${TARGET_INCLUDE_DIRS}
|
||||
${PYSIDE_EXTRA_INCLUDES}
|
||||
)
|
||||
|
||||
target_link_libraries(${TARGET_NAME}
|
||||
|
||||
@@ -74,11 +74,11 @@ endmacro()
|
||||
# Args:
|
||||
# LIBRARY_NAME - The name of the output module
|
||||
# TYPESYSTEM_PATHS - A list of paths where shiboken should look for typesystem files
|
||||
# INCLUDE_PATHS - Include pahts necessary to parse your class. *This is not the same as build*
|
||||
# INCLUDE_PATHS - Include paths necessary to parse your class. *This is not the same as build*
|
||||
# OUTPUT_SOURCES - The files that will be generated by shiboken
|
||||
# TARGET_INCLUDE_DIRS - This will be passed to target_include_directories
|
||||
# TARGET_LINK_LIBRARIES - This will be passed to target_link_libraries
|
||||
# GLOBAL_INCLUDE - A header-file that contains alls classes that will be generated
|
||||
# GLOBAL_INCLUDE - A header-file that contains all classes that will be generated
|
||||
# TYPESYSTEM_XML - The target binding typesystem (that should be the full path)
|
||||
# DEPENDS - This var will be passed to add_custom_command(DEPENDS) so a new generation will be
|
||||
# trigger if one of these files changes
|
||||
@@ -137,7 +137,6 @@ macro(CREATE_PYTHON_BINDINGS
|
||||
|
||||
target_include_directories(${TARGET_NAME} PUBLIC
|
||||
${TARGET_INCLUDE_DIRS}
|
||||
${PYSIDE_EXTRA_INCLUDES}
|
||||
)
|
||||
|
||||
target_link_libraries(${TARGET_NAME}
|
||||
|
||||
147
code.dev-qtquick.code-workspace
Normal file
147
code.dev-qtquick.code-workspace
Normal file
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"C_Cpp.default.compileCommands": "${workspaceFolder}/build-dev-qtquick/compile_commands.json",
|
||||
"C_Cpp.default.cStandard": "c17",
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"editor.formatOnType": true,
|
||||
"C_Cpp.autocompleteAddParentheses": true
|
||||
},
|
||||
"launch": {
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "gdb-kddockwidgets_customtitlebar_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_customtitlebar_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-kddockwidgets_example_mdi_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_mdi_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-kddockwidgets_example_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-tst_docks",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_customtitlebar_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_customtitlebar_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_example_mdi_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_mdi_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_example_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-tst_docks",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_customtitlebar_quick",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_customtitlebar_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_example_mdi_quick",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_mdi_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_example_quick",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-tst_docks",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
147
code.dev-qtwidgets.code-workspace
Normal file
147
code.dev-qtwidgets.code-workspace
Normal file
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"C_Cpp.default.compileCommands": "${workspaceFolder}/build-dev/compile_commands.json",
|
||||
"C_Cpp.default.cStandard": "c17",
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"editor.formatOnType": true,
|
||||
"C_Cpp.autocompleteAddParentheses": true
|
||||
},
|
||||
"launch": {
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "gdb-kddockwidgets_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-kddockwidgets_minimal_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-kddockwidgets_minimal_mdi_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-tst_docks",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_minimal_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_minimal_mdi_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-tst_docks",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_minimal_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_minimal_mdi_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-tst_docks",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
147
code.dev-qtwidgets6.code-workspace
Normal file
147
code.dev-qtwidgets6.code-workspace
Normal file
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"C_Cpp.default.compileCommands": "${workspaceFolder}/build-dev6/compile_commands.json",
|
||||
"C_Cpp.default.cStandard": "c17",
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"editor.formatOnType": true,
|
||||
"C_Cpp.autocompleteAddParentheses": true
|
||||
},
|
||||
"launch": {
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "gdb-kddockwidgets_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-kddockwidgets_minimal_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-kddockwidgets_minimal_mdi_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-tst_docks",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_minimal_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_minimal_mdi_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-tst_docks",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_minimal_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_minimal_mdi_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-tst_docks",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ Configuration options:
|
||||
* build_examples
|
||||
Build the examples. Default=True
|
||||
|
||||
* builde_python_bindings
|
||||
* build_python_bindings
|
||||
Build/Generate python bindings (always false for Debug or static builds). Default=False
|
||||
|
||||
* build_for_qt6
|
||||
Build against Qt6 rather than Qt5. Default=false (Qt5 will be used even if Qt6 is available)
|
||||
(Make sure the Qt6 bin directory is found in your execute PATH)
|
||||
|
||||
@@ -11,7 +11,7 @@ from conans import ConanFile, CMake, tools
|
||||
|
||||
class KDDockWidgetsConan(ConanFile):
|
||||
name = "kddockwidgets"
|
||||
version = "1.2.0"
|
||||
version = "1.4.0"
|
||||
default_user = "kdab"
|
||||
default_channel = "stable"
|
||||
license = ("https://raw.githubusercontent.com/KDAB/KDDockWidgets/master/LICENSES/GPL-2.0-only.txt",
|
||||
@@ -28,6 +28,7 @@ class KDDockWidgetsConan(ConanFile):
|
||||
"build_examples": [True, False],
|
||||
"build_tests": [True, False],
|
||||
"build_python_bindings": [True, False],
|
||||
"build_for_qt6": [True, False],
|
||||
}
|
||||
|
||||
default_options = {
|
||||
@@ -36,6 +37,7 @@ class KDDockWidgetsConan(ConanFile):
|
||||
"build_examples": True,
|
||||
"build_tests": False,
|
||||
"build_python_bindings": False,
|
||||
"build_for_qt6": False,
|
||||
}
|
||||
|
||||
def requirements(self):
|
||||
@@ -52,6 +54,7 @@ class KDDockWidgetsConan(ConanFile):
|
||||
self.cmake.definitions["KDDockWidgets_EXAMPLES"] = self.options.build_examples
|
||||
self.cmake.definitions["KDDockWidgets_TESTS"] = self.options.build_tests
|
||||
self.cmake.definitions["KDDockWidgets_PYTHON_BINDINGS"] = self.options.build_python_bindings
|
||||
self.cmake.definitions["KDDockWidgets_QT6"] = self.options.build_for_qt6
|
||||
self.cmake.configure()
|
||||
self.cmake.build()
|
||||
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is an helper script which simply reads CMakePresets.json and builds those
|
||||
* presets. It's just for quickly checking that every supported setup builds
|
||||
* without having to wait for CI (or in case you don't have access to KDAB CI)
|
||||
*
|
||||
* Usage:
|
||||
* $ dart build-all.dart <kddw-source-directory> [--unity] [--tests]
|
||||
*/
|
||||
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
|
||||
String s_sourceDirectory = "";
|
||||
bool s_testUnityVariations = false;
|
||||
bool s_runTests = true;
|
||||
|
||||
class Preset {
|
||||
final String name;
|
||||
final String buildDir;
|
||||
Preset.fromJson(var jsonData)
|
||||
: name = jsonData['name'],
|
||||
buildDir = jsonData['binaryDir'] {
|
||||
}
|
||||
|
||||
String buildDirectory() {
|
||||
return buildDir.replaceAll("\${sourceDir}", s_sourceDirectory);
|
||||
}
|
||||
|
||||
List<String> cmakeConfigArguments(bool isUnityBuild) {
|
||||
return [
|
||||
"-G",
|
||||
"Ninja",
|
||||
"-B",
|
||||
buildDirectory(),
|
||||
"-S",
|
||||
s_sourceDirectory,
|
||||
"--preset=" + name,
|
||||
'-DKDDockWidgets_UNITY_BUILD=${isUnityBuild ? "ON" : "OFF"}'
|
||||
];
|
||||
}
|
||||
|
||||
List<String> cmakeBuildArguments() {
|
||||
return ["--build", buildDirectory()];
|
||||
}
|
||||
|
||||
// Builds twice. One with unity build and one without.
|
||||
Future<bool> build() async {
|
||||
if (!await buildSingle(true)) return false;
|
||||
if (s_testUnityVariations) if (!await buildSingle(false)) return false;
|
||||
if (s_runTests && !await runTests()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<bool> buildSingle(bool isUnityBuild) async {
|
||||
if (!await runCMake(cmakeConfigArguments(isUnityBuild))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!await runCMake(cmakeBuildArguments())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<bool> runTests() async {
|
||||
print("Running: ctest");
|
||||
|
||||
final savedCwd = Directory.current;
|
||||
Directory.current = buildDirectory();
|
||||
ProcessResult result = await Process.run('ctest', ["-j8"]);
|
||||
Directory.current = savedCwd;
|
||||
|
||||
if (result.exitCode != 0) {
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the contents of the CMakePresets.json file
|
||||
String cmakePresetsJson(presetsFile) {
|
||||
var file = File(presetsFile);
|
||||
if (!file.existsSync()) {
|
||||
throw Exception('Not existent file');
|
||||
}
|
||||
return file.readAsStringSync();
|
||||
}
|
||||
|
||||
List<Preset> readPresets(var presetsFile) {
|
||||
var presets = List<Preset>();
|
||||
|
||||
final jsonData = jsonDecode(cmakePresetsJson(presetsFile));
|
||||
for (var presetData in jsonData['configurePresets']) {
|
||||
presets.add(Preset.fromJson(presetData));
|
||||
}
|
||||
return presets;
|
||||
}
|
||||
|
||||
Future<bool> runCMake(var cmd) async {
|
||||
print("Running: cmake " + cmd.join(' '));
|
||||
ProcessResult result = await Process.run('cmake', cmd);
|
||||
if (result.exitCode != 0) {
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<int> main(List<String> arguments) async {
|
||||
if (arguments.length == 0) {
|
||||
print("Usage: build-all.dart <src-directory> [--unity] [--tests]");
|
||||
return 1;
|
||||
}
|
||||
|
||||
s_sourceDirectory = arguments[0];
|
||||
s_testUnityVariations = arguments.contains("--unity");
|
||||
s_runTests = arguments.contains("--tests");
|
||||
final presetsFile = s_sourceDirectory + '/CMakePresets.json';
|
||||
|
||||
if (FileSystemEntity.typeSync(presetsFile) == FileSystemEntityType.notFound) {
|
||||
print('ERROR: CMakePresets.json file not found in the source directory');
|
||||
return 1;
|
||||
}
|
||||
|
||||
var presets = readPresets(presetsFile);
|
||||
for (var preset in presets) {
|
||||
if (preset.name == 'python')
|
||||
continue; // TODO: blacklisted as it's not building on my setup yet
|
||||
|
||||
if (!await preset.build()) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
print("Success!!");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,3 +1,21 @@
|
||||
kddockwidgets (1.4.0) release candidate; urgency=high
|
||||
|
||||
* 1.4.0 final
|
||||
|
||||
-- Allen Winter <allen.winter@kdab.com> Fri, 16 Jul 2021 10:30:00 -0500
|
||||
|
||||
kddockwidgets (1.3.1) release candidate; urgency=high
|
||||
|
||||
* 1.3.1 final
|
||||
|
||||
-- Allen Winter <allen.winter@kdab.com> Mon, 07 Jun 2021 16:00:00 -0500
|
||||
|
||||
kddockwidgets (1.3.0) release candidate; urgency=high
|
||||
|
||||
* 1.3.0 final
|
||||
|
||||
-- Allen Winter <allen.winter@kdab.com> Mon, 08 Feb 2021 15:00:00 -0500
|
||||
|
||||
kddockwidgets (1.2.0) release candidate; urgency=high
|
||||
|
||||
* 1.2.0 final
|
||||
10
distro/qt5-kddockwidgets.dsc
Normal file
10
distro/qt5-kddockwidgets.dsc
Normal file
@@ -0,0 +1,10 @@
|
||||
Format: 1.0
|
||||
Source: kddockwidgets
|
||||
Version: 1.4.0-1
|
||||
Binary: kddockwidgets
|
||||
Maintainer: Allen Winter <allen.winter@kdab.com>
|
||||
Architecture: any
|
||||
Build-Depends: debhelper (>=9), cdbs, cmake, qtbase5-dev, libqt5x11extras5-dev
|
||||
|
||||
Files:
|
||||
00000000000000000000000000000000 00000 qt5-kddockwidgets-1.4.0.tar.gz
|
||||
@@ -1,7 +1,7 @@
|
||||
Name: kddockwidgets
|
||||
Version: 1.2.0
|
||||
Name: qt5-kddockwidgets
|
||||
Version: 1.4.0
|
||||
Release: 1
|
||||
Summary: KDAB's Dock Widget Framework for Qt
|
||||
Summary: KDAB's Dock Widget Framework for Qt5
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
Source1: %{name}-%{version}.tar.gz.asc
|
||||
Source2: %{name}-rpmlintrc
|
||||
@@ -79,7 +79,18 @@ cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
%if 0%{?sle_version} >= 150200 && 0%{?is_opensuse}
|
||||
%{_libdir}/qt5/mkspecs/modules/*
|
||||
%endif
|
||||
%if 0%{?suse_version} > 1500
|
||||
%{_libdir}/qt5/mkspecs/modules/*
|
||||
%endif
|
||||
%if 0%{?fedora} > 28
|
||||
%{_libdir}/qt5/mkspecs/modules/*
|
||||
%endif
|
||||
%if %{defined rhel}
|
||||
%{_libdir}/qt5/mkspecs/modules/*
|
||||
%endif
|
||||
%dir %{_includedir}/kddockwidgets
|
||||
%{_includedir}/kddockwidgets/*
|
||||
%dir %{_libdir}/cmake/KDDockWidgets
|
||||
@@ -87,6 +98,12 @@ cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release
|
||||
%{_libdir}/libkddockwidgets.so
|
||||
|
||||
%changelog
|
||||
* Fri Jul 16 2021 Allen Winter <allen.winter@kdab.com> 1.4.0
|
||||
1.4.0 final
|
||||
* Mon Jun 07 2021 Allen Winter <allen.winter@kdab.com> 1.3.1
|
||||
1.3.1 final
|
||||
* Mon Feb 08 2021 Allen Winter <allen.winter@kdab.com> 1.3.0
|
||||
1.3.0 final
|
||||
* Thu Dec 17 2020 Allen Winter <allen.winter@kdab.com> 1.2.0
|
||||
1.2.0 final
|
||||
* Fri Dec 11 2020 Allen Winter <allen.winter@kdab.com> 1.1.1
|
||||
4
distro/qt6-debian.rules
Normal file
4
distro/qt6-debian.rules
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/make -f
|
||||
DEB_CMAKE_EXTRA_FLAGS = -DKDDockWidgets_QT6=True -DCMAKE_BUILD_TYPE=Release
|
||||
include /usr/share/cdbs/1/rules/debhelper.mk
|
||||
include /usr/share/cdbs/1/class/cmake.mk
|
||||
1
distro/qt6-kddockwidgets-rpmlintrc
Normal file
1
distro/qt6-kddockwidgets-rpmlintrc
Normal file
@@ -0,0 +1 @@
|
||||
addFilter("E: shlib-policy-name-error")
|
||||
10
distro/qt6-kddockwidgets.dsc
Normal file
10
distro/qt6-kddockwidgets.dsc
Normal file
@@ -0,0 +1,10 @@
|
||||
Format: 1.0
|
||||
Source: kddockwidgets
|
||||
Version: 1.4.0-1
|
||||
Binary: kddockwidgets
|
||||
Maintainer: Allen Winter <allen.winter@kdab.com>
|
||||
Architecture: any
|
||||
Build-Depends: debhelper (>=9), cdbs, cmake, qtbase6-dev, libqt6x11extras5-dev
|
||||
|
||||
Files:
|
||||
00000000000000000000000000000000 00000 qt6-kddockwidgets-1.4.0.tar.gz
|
||||
105
distro/qt6-kddockwidgets.spec
Normal file
105
distro/qt6-kddockwidgets.spec
Normal file
@@ -0,0 +1,105 @@
|
||||
Name: qt6-kddockwidgets
|
||||
Version: 1.4.0
|
||||
Release: 1
|
||||
Summary: KDAB's Dock Widget Framework for Qt6
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
Source1: %{name}-%{version}.tar.gz.asc
|
||||
Source2: %{name}-rpmlintrc
|
||||
URL: https://github.com/KDAB/KDDockWidgets
|
||||
Group: System/Libraries
|
||||
License: GPL-2.0-only OR GPL-3.0-only
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
Vendor: Klaralvdalens Datakonsult AB (KDAB)
|
||||
Packager: Klaralvdalens Datakonsult AB (KDAB) <info@kdab.com>
|
||||
|
||||
BuildRequires: cmake
|
||||
%if %{defined suse_version}
|
||||
BuildRequires: libqt6-qtbase-devel libqt6-qtx11extras-devel
|
||||
%endif
|
||||
|
||||
%if %{defined fedora}
|
||||
BuildRequires: gcc-c++ qt6-qtbase-devel desktop-file-utils
|
||||
%endif
|
||||
|
||||
%if %{defined rhel}
|
||||
BuildRequires: gcc-c++ qt6-qtbase-devel qt6-qtx11extras-devel desktop-file-utils
|
||||
%endif
|
||||
|
||||
%description
|
||||
KDDockWidgets is a Qt dock widget library written by KDAB, suitable for replacing
|
||||
QDockWidget and implementing advanced functionalities missing in Qt, including:
|
||||
- Nesting dock widgets in a floating window and docking that group back to main window
|
||||
- Docking to any main window, not only to the parent main window
|
||||
- Docking to center of main window, or simply removing the concept of "central widget"
|
||||
- Main window supporting detachable tabs in center widget
|
||||
- Detaching arbitrary tabs from a tab bar into a dock area
|
||||
- Exposing inner helper widgets so the user can customize them or provide his own
|
||||
- Customize tab widgets
|
||||
- Customize title bars
|
||||
- Customize window frames
|
||||
- Custom widget separators
|
||||
...and much more
|
||||
|
||||
Authors:
|
||||
--------
|
||||
Klaralvdalens Datakonsult AB (KDAB) <info@kdab.com>
|
||||
|
||||
%define debug_package %{nil}
|
||||
%global __debug_install_post %{nil}
|
||||
|
||||
%package devel
|
||||
Summary: Development files for %{name}
|
||||
Group: Development/Libraries/C and C++
|
||||
Requires: %{name} = %{version}
|
||||
|
||||
%description devel
|
||||
This package contains header files and associated tools and libraries to
|
||||
develop programs using kddockwidgets.
|
||||
|
||||
%prep
|
||||
%autosetup
|
||||
|
||||
%build
|
||||
cmake . -DCMAKE_INSTALL_PREFIX=/usr -DKDDockWidgets_QT6=True -DCMAKE_BUILD_TYPE=Release
|
||||
%__make %{?_smp_mflags}
|
||||
|
||||
%post -p /sbin/ldconfig
|
||||
%postun -p /sbin/ldconfig
|
||||
|
||||
%install
|
||||
%make_install
|
||||
|
||||
%clean
|
||||
%__rm -rf "%{buildroot}"
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%{_prefix}/share/doc/KDDockWidgets
|
||||
%{_libdir}/libkddockwidgets-qt6.so.*
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{_includedir}/kddockwidgets
|
||||
%{_includedir}/kddockwidgets/*
|
||||
%dir %{_libdir}/cmake/KDDockWidgets
|
||||
%{_libdir}/cmake/KDDockWidgets/*
|
||||
%{_libdir}/libkddockwidgets-qt6.so
|
||||
#%{_prefix}/mkspecs/modules/* ECMGeneratePriFile isn't ported to Qt6 yet
|
||||
|
||||
%changelog
|
||||
* Fri Jul 16 2021 Allen Winter <allen.winter@kdab.com> 1.4.0
|
||||
1.4.0 final
|
||||
* Mon Jun 07 2021 Allen Winter <allen.winter@kdab.com> 1.3.1
|
||||
1.3.1 final
|
||||
* Mon Feb 08 2021 Allen Winter <allen.winter@kdab.com> 1.3.0
|
||||
1.3.0 final
|
||||
* Thu Dec 17 2020 Allen Winter <allen.winter@kdab.com> 1.2.0
|
||||
1.2.0 final
|
||||
* Fri Dec 11 2020 Allen Winter <allen.winter@kdab.com> 1.1.1
|
||||
1.1.1 final
|
||||
* Mon Oct 26 2020 Allen Winter <allen.winter@kdab.com> 1.1.0
|
||||
1.1.0 final
|
||||
* Wed Sep 02 2020 Allen Winter <allen.winter@kdab.com> 1.0.0
|
||||
1.0.0 final
|
||||
* Thu Aug 06 2020 Allen Winter <allen.winter@kdab.com> 0.99.9
|
||||
1.0.0 release candidate
|
||||
Binary file not shown.
BIN
docs/KDDockWidgets-CopyrightAssignmentForm.pdf
Normal file
BIN
docs/KDDockWidgets-CopyrightAssignmentForm.pdf
Normal file
Binary file not shown.
@@ -13,6 +13,7 @@ find_file(QDOC_QTCORE_TAG qtcore.tags
|
||||
HINTS ${QT_INSTALL_DOCS}/qtcore
|
||||
HINTS ${QT_INSTALL_DATA}/doc/qtcore
|
||||
)
|
||||
set(QDOC_TAG_DIR "<QDOC_TAG_DIR_not_found>")
|
||||
if(QDOC_QTCORE_TAG)
|
||||
get_filename_component(QDOC_TAG_DIR ${QDOC_QTCORE_TAG} DIRECTORY)
|
||||
get_filename_component(QDOC_TAG_DIR ${QDOC_TAG_DIR} DIRECTORY)
|
||||
@@ -32,9 +33,18 @@ add_custom_command(
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
||||
#handle a bug in doxygen where image files referred to in markdown are not copied the output
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/../../screencap.gif ${DOXYGEN_OUTPUT_DIR}/html
|
||||
#copy some files by-hand that are referred to by the markdown README
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/README-bindings.md ${DOXYGEN_OUTPUT_DIR}/html
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOXYGEN_OUTPUT_DIR}/html/LICENSES
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/LICENSES/GPL-2.0-only.txt ${DOXYGEN_OUTPUT_DIR}/html/LICENSES
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/LICENSES/GPL-3.0-only.txt ${DOXYGEN_OUTPUT_DIR}/html/LICENSES
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOXYGEN_OUTPUT_DIR}/html/docs
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/docs/KDDockWidgets-CopyrightAssignmentForm.pdf ${DOXYGEN_OUTPUT_DIR}/html/docs
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples ${DOXYGEN_OUTPUT_DIR}/html/examples
|
||||
DEPENDS ${_dox_deps} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
add_custom_target(kddockwidgets-api.qch ALL DEPENDS ${DOXYGEN_OUTPUT_DIR}/qch/kddockwidgets-api.qch)
|
||||
add_custom_target(docs DEPENDS kddockwidgets-api.qch)
|
||||
|
||||
install(FILES ${DOXYGEN_OUTPUT_DIR}/qch/kddockwidgets-api.qch DESTINATION ${INSTALL_DOC_DIR})
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = "KDDockWidgets API Documentation"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = @KDDockWidgets_VERSION@
|
||||
PROJECT_NUMBER = @KDDockWidgets_VERSION_MAJOR@.@KDDockWidgets_VERSION_MINOR@
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
@@ -261,7 +261,7 @@ TAB_SIZE = 8
|
||||
# commands \{ and \} for these it is advised to use the version @{ and @} or use
|
||||
# a double escape (\\{ and \\})
|
||||
|
||||
ALIASES =
|
||||
ALIASES = "reimp=Reimplemented for internal purposes.\n"
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<hr>
|
||||
<div style="float: left;">
|
||||
<img src="kdab-logo-16x16.png">
|
||||
<font style="font-weight: bold;">Klarälvdalens Datakonsult AB (KDAB)</font>
|
||||
<font style="font-weight: bold;">© 2019-2021 Klarälvdalens Datakonsult AB (KDAB)</font>
|
||||
<br>
|
||||
"The Qt, C++ and OpenGL Experts"<br>
|
||||
<a href="https://www.kdab.com/">https://www.kdab.com/</a>
|
||||
@@ -12,7 +12,8 @@
|
||||
<font style="font-weight: bold;">KDDockWidgets</font>
|
||||
<br>
|
||||
Advanced Dock Widget Framework for Qt<br>
|
||||
<a href="https://www.kdab.com/development-resources/qt-tools/kddockwidgets/">https://www.kdab.com/development-resources/qt-tools/kddockwidgets/</a>
|
||||
<a href="https://www.kdab.com/development-resources/qt-tools/kddockwidgets/">https://www.kdab.com/development-resources/qt-tools/kddockwidgets/</a><br>
|
||||
$generatedby doxygen $doxygenversion<br>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
#include "MyFrameworkWidgetFactory.h"
|
||||
|
||||
#include <kddockwidgets/FrameworkWidgetFactory.h>
|
||||
|
||||
#include <kddockwidgets/private/TabWidget_p.h>
|
||||
#include <kddockwidgets/private/widgets/FrameWidget_p.h>
|
||||
#include <kddockwidgets/private/widgets/TabBarWidget_p.h>
|
||||
#include <kddockwidgets/private/widgets/TabWidgetWidget_p.h>
|
||||
#include <kddockwidgets/private/widgets/TitleBarWidget_p.h>
|
||||
#include <kddockwidgets/private/multisplitter/Separator_qwidget.h>
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "MyMainWindow.h"
|
||||
#include "MyWidget.h"
|
||||
|
||||
#include <kddockwidgets/Config.h>
|
||||
#include <kddockwidgets/LayoutSaver.h>
|
||||
|
||||
#include <QMenu>
|
||||
@@ -20,9 +21,7 @@
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
#include <QTextEdit>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
#include <QRandomGenerator>
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
@@ -33,12 +32,7 @@
|
||||
|
||||
static MyWidget *newMyWidget()
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
const int randomNumber = qrand() % 100 + 1;
|
||||
#else
|
||||
const int randomNumber = QRandomGenerator::global()->bounded(0, 100) + 1;
|
||||
#endif
|
||||
|
||||
if (randomNumber < 50) {
|
||||
if (randomNumber < 33) {
|
||||
return new MyWidget1();
|
||||
@@ -52,24 +46,23 @@ static MyWidget *newMyWidget()
|
||||
|
||||
MyMainWindow::MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
|
||||
bool dockWidget0IsNonClosable, bool nonDockableDockWidget9, bool restoreIsRelative,
|
||||
bool maxSizeForDockWidget8,
|
||||
bool maxSizeForDockWidget8, bool dockwidget5DoesntCloseBeforeRestore,
|
||||
const QString &affinityName, QWidget *parent)
|
||||
: MainWindow(uniqueName, options, parent)
|
||||
, m_dockWidget0IsNonClosable(dockWidget0IsNonClosable)
|
||||
, m_dockWidget9IsNonDockable(nonDockableDockWidget9)
|
||||
, m_restoreIsRelative(restoreIsRelative)
|
||||
, m_maxSizeForDockWidget8(maxSizeForDockWidget8)
|
||||
, m_dockwidget5DoesntCloseBeforeRestore(dockwidget5DoesntCloseBeforeRestore)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
qsrand(time(nullptr));
|
||||
#endif
|
||||
|
||||
// qApp->installEventFilter(this);
|
||||
auto menubar = menuBar();
|
||||
auto fileMenu = new QMenu(QStringLiteral("File"));
|
||||
m_toggleMenu = new QMenu(QStringLiteral("Toggle"));
|
||||
auto miscMenu = new QMenu(QStringLiteral("Misc"));
|
||||
|
||||
menubar->addMenu(fileMenu);
|
||||
menubar->addMenu(m_toggleMenu);
|
||||
menubar->addMenu(miscMenu);
|
||||
|
||||
QAction *newAction = fileMenu->addAction(QStringLiteral("New DockWidget"));
|
||||
|
||||
@@ -113,6 +106,13 @@ MyMainWindow::MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowO
|
||||
auto quitAction = fileMenu->addAction(QStringLiteral("Quit"));
|
||||
connect(quitAction, &QAction::triggered, qApp, &QApplication::quit);
|
||||
|
||||
QAction *toggleDropIndicatorSupport = miscMenu->addAction(QStringLiteral("Toggle Drop Indicator Support"));
|
||||
toggleDropIndicatorSupport->setCheckable(true);
|
||||
toggleDropIndicatorSupport->setChecked(true);
|
||||
connect(toggleDropIndicatorSupport, &QAction::toggled, this, [](bool checked) {
|
||||
KDDockWidgets::Config::self().setDropIndicatorsInhibited(!checked);
|
||||
});
|
||||
|
||||
setAffinities({ affinityName });
|
||||
createDockWidgets();
|
||||
}
|
||||
@@ -133,7 +133,6 @@ void MyMainWindow::createDockWidgets()
|
||||
for (int i = 0; i < numDockWidgets; i++)
|
||||
m_dockwidgets << newDockWidget();
|
||||
|
||||
|
||||
// MainWindow::addDockWidget() attaches a dock widget to the main window:
|
||||
addDockWidget(m_dockwidgets.at(0), KDDockWidgets::Location_OnTop);
|
||||
|
||||
@@ -164,13 +163,18 @@ KDDockWidgets::DockWidgetBase *MyMainWindow::newDockWidget()
|
||||
|
||||
// Passing options is optional, we just want to illustrate Option_NotClosable here
|
||||
KDDockWidgets::DockWidget::Options options = KDDockWidgets::DockWidget::Option_None;
|
||||
KDDockWidgets::DockWidget::LayoutSaverOptions layoutSaverOptions = KDDockWidgets::DockWidget::LayoutSaverOption::None;
|
||||
|
||||
if (count == 0 && m_dockWidget0IsNonClosable)
|
||||
options |= KDDockWidgets::DockWidget::Option_NotClosable;
|
||||
|
||||
if (count == 9 && m_dockWidget9IsNonDockable)
|
||||
options |= KDDockWidgets::DockWidget::Option_NotDockable;
|
||||
|
||||
auto dock = new KDDockWidgets::DockWidget(QStringLiteral("DockWidget #%1").arg(count), options);
|
||||
if (count == 5 && m_dockwidget5DoesntCloseBeforeRestore)
|
||||
layoutSaverOptions |= KDDockWidgets::DockWidget::LayoutSaverOption::Skip;
|
||||
|
||||
auto dock = new KDDockWidgets::DockWidget(QStringLiteral("DockWidget #%1").arg(count), options, layoutSaverOptions);
|
||||
dock->setAffinities(affinities()); // optional, just to show the feature. Pass -mi to the example to see incompatible dock widgets
|
||||
|
||||
if (count == 1)
|
||||
@@ -192,6 +196,7 @@ KDDockWidgets::DockWidgetBase *MyMainWindow::newDockWidget()
|
||||
|
||||
dock->resize(600, 600);
|
||||
m_toggleMenu->addAction(dock->toggleAction());
|
||||
dock->toggleAction()->setShortcut(QStringLiteral("ctrl+%1").arg(count));
|
||||
|
||||
count++;
|
||||
return dock;
|
||||
|
||||
@@ -20,7 +20,7 @@ class MyMainWindow : public KDDockWidgets::MainWindow
|
||||
public:
|
||||
explicit MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
|
||||
bool dockWidget0IsNonClosable, bool nonDockableDockWidget9, bool restoreIsRelative,
|
||||
bool maxSizeForDockWidget8,
|
||||
bool maxSizeForDockWidget8, bool dockwidget5DoesntCloseBeforeRestore,
|
||||
const QString &affinityName = {}, // Usually not needed. Just here to show the feature.
|
||||
QWidget *parent = nullptr);
|
||||
~MyMainWindow() override;
|
||||
@@ -33,5 +33,6 @@ private:
|
||||
const bool m_dockWidget9IsNonDockable;
|
||||
const bool m_restoreIsRelative;
|
||||
const bool m_maxSizeForDockWidget8;
|
||||
const bool m_dockwidget5DoesntCloseBeforeRestore;
|
||||
KDDockWidgets::DockWidget::List m_dockwidgets;
|
||||
};
|
||||
|
||||
@@ -111,6 +111,18 @@ int main(int argc, char **argv)
|
||||
QCommandLineOption autoHideSupport("w", QCoreApplication::translate("main", "Enables auto-hide/minimization to side-bar support"));
|
||||
parser.addOption(autoHideSupport);
|
||||
|
||||
QCommandLineOption closeOnlyCurrentTab("close-only-current-tab",
|
||||
QCoreApplication::translate("main", "The title bar's close button will only close the current tab instead of all. Illustrates using Config::Flag_CloseOnlyCurrentTab"));
|
||||
parser.addOption(closeOnlyCurrentTab);
|
||||
|
||||
QCommandLineOption dontCloseBeforeRestore("dont-close-widget-before-restore", //krazy:exclude=spelling
|
||||
QCoreApplication::translate("main", "DockWidget #5 won't be closed before a restore. Illustrates LayoutSaverOption::DontCloseBeforeRestore"));
|
||||
parser.addOption(dontCloseBeforeRestore);
|
||||
|
||||
QCommandLineOption showButtonsInTabBarIfTitleBarHidden("show-buttons-in-tabbar-if-titlebar-hidden",
|
||||
QCoreApplication::translate("main", "If we're not using title bars we'll still show the close and float button in the tab bar"));
|
||||
parser.addOption(showButtonsInTabBarIfTitleBarHidden);
|
||||
|
||||
#if defined(DOCKS_DEVELOPER_MODE)
|
||||
parser.addOption(centralFrame);
|
||||
|
||||
@@ -177,6 +189,12 @@ int main(int argc, char **argv)
|
||||
if (parser.isSet(autoHideSupport))
|
||||
flags |= Config::Flag_AutoHideSupport;
|
||||
|
||||
if (parser.isSet(closeOnlyCurrentTab))
|
||||
flags |= Config::Flag_CloseOnlyCurrentTab;
|
||||
|
||||
if (parser.isSet(showButtonsInTabBarIfTitleBarHidden))
|
||||
flags |= Config::Flag_ShowButtonsOnTabBarIfTitleBarHidden;
|
||||
|
||||
if (parser.isSet(noTitleBars))
|
||||
flags |= KDDockWidgets::Config::Flag_HideTitleBarWhenTabsVisible;
|
||||
|
||||
@@ -227,6 +245,7 @@ int main(int argc, char **argv)
|
||||
const bool restoreIsRelative = parser.isSet(relativeRestore);
|
||||
const bool nonDockableDockWidget9 = parser.isSet(nonDockable);
|
||||
const bool maxSizeForDockWidget8 = parser.isSet(maxSizeOption);
|
||||
const bool dontCloseDockWidget5BeforeRestore = parser.isSet(dontCloseBeforeRestore);
|
||||
const bool usesMainWindowsWithAffinity = parser.isSet(multipleMainWindows);
|
||||
|
||||
#ifdef KDDOCKWIDGETS_SUPPORTS_NESTED_MAINWINDOWS
|
||||
@@ -236,7 +255,8 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
MyMainWindow mainWindow(QStringLiteral("MyMainWindow"), options, nonClosableDockWidget0,
|
||||
nonDockableDockWidget9, restoreIsRelative, maxSizeForDockWidget8);
|
||||
nonDockableDockWidget9, restoreIsRelative, maxSizeForDockWidget8,
|
||||
dontCloseDockWidget5BeforeRestore);
|
||||
mainWindow.setWindowTitle("Main Window 1");
|
||||
mainWindow.resize(1200, 1200);
|
||||
mainWindow.show();
|
||||
@@ -254,7 +274,8 @@ int main(int argc, char **argv)
|
||||
|
||||
auto mainWindow2 = new MyMainWindow(QStringLiteral("MyMainWindow-2"), options,
|
||||
nonClosableDockWidget0, nonDockableDockWidget9,
|
||||
restoreIsRelative, maxSizeForDockWidget8, affinity);
|
||||
restoreIsRelative, maxSizeForDockWidget8,
|
||||
dontCloseDockWidget5BeforeRestore, affinity);
|
||||
if (affinity.isEmpty())
|
||||
mainWindow2->setWindowTitle("Main Window 2");
|
||||
else
|
||||
@@ -267,7 +288,8 @@ int main(int argc, char **argv)
|
||||
|
||||
const QString affinity = QStringLiteral("Inner-DockWidgets-2");
|
||||
auto dockableMainWindow = new MyMainWindow(QStringLiteral("MyMainWindow-2"), options,
|
||||
false, false, restoreIsRelative, false, affinity);
|
||||
false, false, restoreIsRelative, false,
|
||||
false, affinity);
|
||||
|
||||
dockableMainWindow->setAffinities({ affinity });
|
||||
|
||||
|
||||
37
examples/minimal-mdi/CMakeLists.txt
Normal file
37
examples/minimal-mdi/CMakeLists.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# This file is part of KDDockWidgets.
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
# Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
#
|
||||
# Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(kddockwidgets_minimal_mdi_example)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||
|
||||
if(NOT TARGET kddockwidgets)
|
||||
# This will look for Qt, do find_package yourself manually before
|
||||
# if you want to look for a specific Qt version for instance.
|
||||
find_package(KDDockWidgets REQUIRED)
|
||||
endif()
|
||||
|
||||
set(RESOURCES_EXAMPLE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../dockwidgets/resources_example.qrc)
|
||||
|
||||
add_executable(kddockwidgets_minimal_mdi_example
|
||||
main.cpp
|
||||
../dockwidgets/MyWidget.cpp
|
||||
${RESOURCES_EXAMPLE_SRC}
|
||||
)
|
||||
|
||||
target_link_libraries(kddockwidgets_minimal_mdi_example
|
||||
PRIVATE
|
||||
KDAB::kddockwidgets
|
||||
)
|
||||
|
||||
116
examples/minimal-mdi/MyWidget.cpp
Normal file
116
examples/minimal-mdi/MyWidget.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#include "MyWidget.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QLineEdit>
|
||||
|
||||
static QHash<QString, QImage> s_images; /// clazy:exclude=non-pod-global-static
|
||||
|
||||
MyWidget::MyWidget(const QString &backgroundFile, const QString &logoFile, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
if (!backgroundFile.isEmpty()) {
|
||||
auto it = s_images.find(backgroundFile);
|
||||
if (it == s_images.end())
|
||||
it = s_images.insert(backgroundFile, QImage(backgroundFile));
|
||||
m_background = it.value();
|
||||
}
|
||||
|
||||
if (!logoFile.isEmpty()) {
|
||||
auto it = s_images.find(logoFile);
|
||||
if (it == s_images.end())
|
||||
it = s_images.insert(logoFile, QImage(logoFile));
|
||||
m_logo = it.value();
|
||||
}
|
||||
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
#if 0
|
||||
// Uncomment to show focus propagation working
|
||||
new QLineEdit(this);
|
||||
auto l2 = new QLineEdit(this);
|
||||
l2->move(0, 100);
|
||||
setFocusProxy(l2);
|
||||
#endif
|
||||
}
|
||||
|
||||
MyWidget::~MyWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void MyWidget::drawLogo(QPainter &p)
|
||||
{
|
||||
if (m_logo.isNull())
|
||||
return;
|
||||
|
||||
const qreal ratio = m_logo.height() / (m_logo.width() * 1.0);
|
||||
|
||||
const int maxWidth = int(0.80 * size().width());
|
||||
const int maxHeight = int(0.80 * size().height());
|
||||
|
||||
const int proposedHeight = int(maxWidth * ratio);
|
||||
|
||||
const int width = proposedHeight <= maxHeight ? maxWidth
|
||||
: int(maxHeight / ratio);
|
||||
|
||||
const int height = int(width * ratio);
|
||||
QRect targetLogoRect(0,0, width, height);
|
||||
targetLogoRect.moveCenter(rect().center() + QPoint(0, -int(size().height() * 0.00)));
|
||||
p.drawImage(targetLogoRect, m_logo, m_logo.rect());
|
||||
}
|
||||
|
||||
MyWidget1::MyWidget1(MyWidget::QWidget *parent)
|
||||
: MyWidget(QStringLiteral(":/assets/triangles.png"), QStringLiteral(":/assets/KDAB_bubble_white.png"), parent)
|
||||
{
|
||||
}
|
||||
|
||||
void MyWidget1::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
p.fillRect(rect(), QColor(0xCC, 0xCC, 0xCC));
|
||||
p.drawImage(m_background.rect(), m_background, m_background.rect());
|
||||
|
||||
drawLogo(p);
|
||||
}
|
||||
|
||||
MyWidget2::MyWidget2(MyWidget::QWidget *parent)
|
||||
: MyWidget(QString(), QStringLiteral(":/assets/KDAB_bubble_blue.png"), parent)
|
||||
{
|
||||
}
|
||||
|
||||
void MyWidget2::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
p.fillRect(rect(), Qt::white);
|
||||
drawLogo(p);
|
||||
}
|
||||
|
||||
MyWidget3::MyWidget3(MyWidget::QWidget *parent)
|
||||
: MyWidget(QStringLiteral(":/assets/base.png"), QStringLiteral(":/assets/KDAB_bubble_fulcolor.png"), parent)
|
||||
, m_triangle(QImage(QStringLiteral(":/assets/tri.png")))
|
||||
{
|
||||
}
|
||||
|
||||
void MyWidget3::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
p.fillRect(rect(), QColor(0xD5, 0xD5, 0xD5));
|
||||
|
||||
p.drawImage(m_background.rect(), m_background, m_background.rect());
|
||||
|
||||
const QRect targetRect = QRect({ width() - m_triangle.width(), height() - m_triangle.height() }, m_triangle.size());
|
||||
|
||||
p.drawImage(targetRect, m_triangle, m_triangle.rect());
|
||||
drawLogo(p);
|
||||
}
|
||||
65
examples/minimal-mdi/MyWidget.h
Normal file
65
examples/minimal-mdi/MyWidget.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#ifndef EXAMPLEDOCKABLEWIDGET_H
|
||||
#define EXAMPLEDOCKABLEWIDGET_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QPainter;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MyWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyWidget() = default;
|
||||
explicit MyWidget(const QString &backgroundFile, const QString &logoFile, QWidget *parent = nullptr);
|
||||
~MyWidget();
|
||||
protected:
|
||||
void drawLogo(QPainter &);
|
||||
QImage m_background;
|
||||
QImage m_logo;
|
||||
};
|
||||
|
||||
class MyWidget1 : public MyWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MyWidget1(QWidget *parent = nullptr);
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
};
|
||||
|
||||
class MyWidget2 : public MyWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MyWidget2(QWidget *parent = nullptr);
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
};
|
||||
|
||||
class MyWidget3 : public MyWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MyWidget3(QWidget *parent = nullptr);
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
QImage m_triangle;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
62
examples/minimal-mdi/main.cpp
Normal file
62
examples/minimal-mdi/main.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#include "MyWidget.h"
|
||||
|
||||
#include <kddockwidgets/DockWidget.h>
|
||||
#include <kddockwidgets/MainWindowMDI.h>
|
||||
|
||||
#include <QStyleFactory>
|
||||
#include <QApplication>
|
||||
|
||||
// clazy:excludeall=qstring-allocations
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
|
||||
app.setOrganizationName(QStringLiteral("KDAB"));
|
||||
app.setApplicationName(QStringLiteral("Test app"));
|
||||
|
||||
// Fusion looks better in general, but feel free to change
|
||||
qApp->setStyle(QStyleFactory::create(QStringLiteral("Fusion")));
|
||||
|
||||
// # 1. Create our main window
|
||||
|
||||
KDDockWidgets::MainWindowMDI mainWindow(QStringLiteral("MyMainWindow"));
|
||||
mainWindow.setWindowTitle("Main Window");
|
||||
mainWindow.resize(1200, 1200);
|
||||
mainWindow.show();
|
||||
|
||||
// # 2. Create a dock widget, it needs a unique name
|
||||
auto dock1 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock1"));
|
||||
auto widget1 = new MyWidget1();
|
||||
dock1->setWidget(widget1);
|
||||
|
||||
auto dock2 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock2"));
|
||||
auto widget2 = new MyWidget2();
|
||||
dock2->setWidget(widget2);
|
||||
|
||||
auto dock3 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock3"));
|
||||
auto widget3 = new MyWidget3();
|
||||
dock3->setWidget(widget3);
|
||||
|
||||
// # 3. Dock them
|
||||
mainWindow.addDockWidget(dock1, QPoint(10, 10));
|
||||
mainWindow.addDockWidget(dock2, QPoint(50, 50));
|
||||
mainWindow.addDockWidget(dock3, QPoint(90, 90));
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
add_subdirectory(customtitlebar)
|
||||
add_subdirectory(dockwidgets)
|
||||
add_subdirectory(mdi)
|
||||
|
||||
set_compiler_flags(kddockwidgets_example_quick)
|
||||
set_compiler_flags(kddockwidgets_example_mdi_quick)
|
||||
set_compiler_flags(kddockwidgets_customtitlebar_quick)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <QQuickView>
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
class CustomFrameworkWidgetFactory : public KDDockWidgets::DefaultWidgetFactory
|
||||
{
|
||||
@@ -45,15 +46,11 @@ int main(int argc, char *argv[])
|
||||
config.setFlags(flags);
|
||||
config.setFrameworkWidgetFactory(new CustomFrameworkWidgetFactory());
|
||||
|
||||
QQuickView view;
|
||||
view.setObjectName("MainWindow QQuickView");
|
||||
KDDockWidgets::Config::self().setQmlEngine(view.engine());
|
||||
view.resize(1000, 800);
|
||||
view.show();
|
||||
view.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
QQmlApplicationEngine appEngine;
|
||||
KDDockWidgets::Config::self().setQmlEngine(&appEngine);
|
||||
appEngine.load((QUrl("qrc:/main.qml")));
|
||||
|
||||
auto dw1 = new KDDockWidgets::DockWidgetQuick("Dock #1");
|
||||
view.setSource(QUrl("qrc:/main.qml"));
|
||||
|
||||
dw1->setWidget(QStringLiteral("qrc:/Guest1.qml"));
|
||||
dw1->resize(QSize(800, 800));
|
||||
|
||||
@@ -10,14 +10,18 @@
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.12
|
||||
import com.kdab.dockwidgets 1.0 as KDDW
|
||||
|
||||
KDDW.MainWindow {
|
||||
id: root
|
||||
ApplicationWindow {
|
||||
visible: true
|
||||
width: 1000
|
||||
height: 800
|
||||
|
||||
KDDW.MainWindowLayout {
|
||||
id: dockWidgetArea
|
||||
anchors.fill: parent
|
||||
|
||||
Component.onCompleted: {
|
||||
root.init("MyWindowName-1");
|
||||
uniqueName: "MyMainLayout"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,38 +10,10 @@
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.12
|
||||
import com.kdab.dockwidgets 1.0 as KDDW
|
||||
|
||||
Guest {
|
||||
anchors.fill: parent
|
||||
background: "qrc:/assets/triangles.png"
|
||||
logo: "qrc:/assets/KDAB_bubble_white.png"
|
||||
|
||||
KDDW.DockWidget {
|
||||
id: another
|
||||
uniqueName: "another1"
|
||||
source: ":/Another.qml"
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "Toggle Another"
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
margins: 5
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
|
||||
if (another.dockWidget.visible) {
|
||||
another.dockWidget.close();
|
||||
} else {
|
||||
another.dockWidget.show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <kddockwidgets/private/DockRegistry_p.h>
|
||||
#include <kddockwidgets/FrameworkWidgetFactory.h>
|
||||
|
||||
#include <QQuickView>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QGuiApplication>
|
||||
#include <QCommandLineParser>
|
||||
|
||||
@@ -23,6 +23,10 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
|
||||
#endif
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
QGuiApplication app(argc, argv);
|
||||
QCommandLineParser parser;
|
||||
@@ -69,20 +73,22 @@ int main(int argc, char *argv[])
|
||||
internalFlags |= KDDockWidgets::Config::InternalFlag_NoAeroSnap;
|
||||
# endif
|
||||
|
||||
// These are debug-only/development flags, which you can ignore.
|
||||
KDDockWidgets::Config::self().setInternalFlags(internalFlags);
|
||||
#endif
|
||||
|
||||
// Set any required flags. The defaults are usually fine.
|
||||
KDDockWidgets::Config::self().setFlags(flags);
|
||||
|
||||
QQuickView view;
|
||||
view.setObjectName("MainWindow QQuickView");
|
||||
KDDockWidgets::Config::self().setQmlEngine(view.engine());
|
||||
view.resize(1000, 800);
|
||||
view.show();
|
||||
view.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
// Create your engine which loads main.qml. A simple QQuickView would work too.
|
||||
QQmlApplicationEngine appEngine;
|
||||
KDDockWidgets::Config::self().setQmlEngine(&appEngine);
|
||||
appEngine.load((QUrl("qrc:/main.qml")));
|
||||
|
||||
// Below we illustrate usage of our C++ API. Alternative you can use declarative API.
|
||||
// See main.qml for examples of dockwidgets created directly in QML
|
||||
|
||||
auto dw1 = new KDDockWidgets::DockWidgetQuick("Dock #1");
|
||||
view.setSource(QUrl("qrc:/main.qml"));
|
||||
|
||||
dw1->setWidget(QStringLiteral("qrc:/Guest1.qml"));
|
||||
dw1->resize(QSize(800, 800));
|
||||
|
||||
@@ -10,14 +10,130 @@
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.12
|
||||
import com.kdab.dockwidgets 1.0 as KDDW
|
||||
|
||||
KDDW.MainWindow {
|
||||
id: root
|
||||
ApplicationWindow {
|
||||
visible: true
|
||||
width: 1000
|
||||
height: 800
|
||||
|
||||
menuBar: MenuBar {
|
||||
Menu {
|
||||
title: qsTr("&File")
|
||||
|
||||
Component.onCompleted: {
|
||||
root.init("MyWindowName-1");
|
||||
Action {
|
||||
text: qsTr("Save layout")
|
||||
onTriggered: {
|
||||
layoutSaver.saveToFile("mySavedLayout.json");
|
||||
}
|
||||
}
|
||||
|
||||
Action {
|
||||
text: qsTr("Restore layout")
|
||||
onTriggered: {
|
||||
layoutSaver.restoreFromFile("mySavedLayout.json");
|
||||
}
|
||||
}
|
||||
|
||||
Action {
|
||||
text: qsTr("Toggle widget #4")
|
||||
onTriggered: {
|
||||
toggleDockWidget(dock4);
|
||||
}
|
||||
}
|
||||
|
||||
Action {
|
||||
text: qsTr("Toggle widget #5")
|
||||
onTriggered: {
|
||||
toggleDockWidget(dock5);
|
||||
}
|
||||
}
|
||||
|
||||
Action {
|
||||
text: qsTr("Toggle widget #6")
|
||||
onTriggered: {
|
||||
toggleDockWidget(dock6);
|
||||
}
|
||||
}
|
||||
|
||||
Action {
|
||||
text: qsTr("Close All")
|
||||
onTriggered: {
|
||||
_kddwDockRegistry.clear();
|
||||
}
|
||||
}
|
||||
|
||||
MenuSeparator { }
|
||||
Action { text: qsTr("&Quit")
|
||||
onTriggered: {
|
||||
Qt.quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KDDW.MainWindowLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
// Each main layout needs a unique id
|
||||
uniqueName: "MainLayout-1"
|
||||
|
||||
Repeater {
|
||||
model: 3
|
||||
KDDW.DockWidget {
|
||||
uniqueName: "fromRepeater-" + index
|
||||
source: ":/Another.qml"
|
||||
}
|
||||
}
|
||||
|
||||
KDDW.DockWidget {
|
||||
id: dock4
|
||||
uniqueName: "dock4" // Each dock widget needs a unique id
|
||||
source: ":/Another.qml"
|
||||
}
|
||||
|
||||
KDDW.DockWidget {
|
||||
id: dock5
|
||||
uniqueName: "dock5"
|
||||
Rectangle {
|
||||
id: guest
|
||||
color: "pink"
|
||||
}
|
||||
}
|
||||
|
||||
KDDW.DockWidget {
|
||||
id: dock6
|
||||
uniqueName: "dock6"
|
||||
Rectangle {
|
||||
color: "black"
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// Add dock4 to the Bottom location
|
||||
addDockWidget(dock4, KDDW.KDDockWidgets.Location_OnBottom);
|
||||
|
||||
// Add dock5 to the left of dock4
|
||||
addDockWidget(dock5, KDDW.KDDockWidgets.Location_OnRight, dock4);
|
||||
|
||||
// Adds dock6 but specifies a preferred initial size and it starts hidden
|
||||
// When toggled it will be shown on the desired dock location.
|
||||
// See MainWindowInstantiator_p.h for the API
|
||||
addDockWidget(dock6, KDDW.KDDockWidgets.Location_OnLeft, null,
|
||||
Qt.size(500, 100), KDDW.KDDockWidgets.StartHidden);
|
||||
}
|
||||
}
|
||||
|
||||
KDDW.LayoutSaver {
|
||||
id: layoutSaver
|
||||
}
|
||||
|
||||
function toggleDockWidget(dw) {
|
||||
if (dw.dockWidget.isOpen()) {
|
||||
dw.dockWidget.close();
|
||||
} else {
|
||||
dw.dockWidget.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
18
examples/qtquick/mdi/Another.qml
Normal file
18
examples/qtquick/mdi/Another.qml
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
color: "green"
|
||||
anchors.fill: parent
|
||||
}
|
||||
37
examples/qtquick/mdi/CMakeLists.txt
Normal file
37
examples/qtquick/mdi/CMakeLists.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# This file is part of KDDockWidgets.
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
# Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
#
|
||||
# Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(kddockwidgets_example_mdi_quick)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||
|
||||
if(NOT TARGET kddockwidgets)
|
||||
# This will look for Qt, do find_package yourself manually before
|
||||
# if you want to look for a specific Qt version for instance.
|
||||
find_package(KDDockWidgets REQUIRED)
|
||||
endif()
|
||||
|
||||
set(RESOURCES_EXAMPLE_SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources_qtquick_mdi_example.qrc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../dockwidgets/resources_example.qrc)
|
||||
|
||||
add_executable(kddockwidgets_example_mdi_quick
|
||||
main.cpp
|
||||
${RESOURCES_EXAMPLE_SRC}
|
||||
)
|
||||
|
||||
target_link_libraries(kddockwidgets_example_mdi_quick
|
||||
PRIVATE
|
||||
KDAB::kddockwidgets
|
||||
)
|
||||
37
examples/qtquick/mdi/Guest.qml
Normal file
37
examples/qtquick/mdi/Guest.qml
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
|
||||
Rectangle {
|
||||
color: "white"
|
||||
anchors.fill: parent
|
||||
|
||||
property alias background: background.source
|
||||
property alias logo: logo.source
|
||||
|
||||
|
||||
Image {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
|
||||
Image {
|
||||
id: logo
|
||||
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
examples/qtquick/mdi/Guest1.qml
Normal file
44
examples/qtquick/mdi/Guest1.qml
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.12
|
||||
import com.kdab.dockwidgets 1.0 as KDDW
|
||||
|
||||
Guest {
|
||||
anchors.fill: parent
|
||||
background: "qrc:/assets/triangles.png"
|
||||
logo: "qrc:/assets/KDAB_bubble_white.png"
|
||||
|
||||
KDDW.DockWidget {
|
||||
id: another
|
||||
uniqueName: "another1"
|
||||
source: ":/Another.qml"
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "Toggle Another"
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
margins: 5
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
|
||||
if (another.dockWidget.visible) {
|
||||
another.dockWidget.close();
|
||||
} else {
|
||||
another.dockWidget.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
examples/qtquick/mdi/Guest2.qml
Normal file
17
examples/qtquick/mdi/Guest2.qml
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
|
||||
Guest {
|
||||
anchors.fill: parent
|
||||
logo: "qrc:/assets/KDAB_bubble_blue.png"
|
||||
}
|
||||
18
examples/qtquick/mdi/Guest3.qml
Normal file
18
examples/qtquick/mdi/Guest3.qml
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
|
||||
Guest {
|
||||
anchors.fill: parent
|
||||
background: "qrc:/assets/base.png"
|
||||
logo: "qrc:/assets/KDAB_bubble_fulcolor.png"
|
||||
}
|
||||
59
examples/qtquick/mdi/main.cpp
Normal file
59
examples/qtquick/mdi/main.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
|
||||
#include <kddockwidgets/Config.h>
|
||||
#include <kddockwidgets/DockWidgetQuick.h>
|
||||
#include <kddockwidgets/private/DockRegistry_p.h>
|
||||
#include <kddockwidgets/FrameworkWidgetFactory.h>
|
||||
#include <kddockwidgets/MainWindowMDI.h>
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QGuiApplication>
|
||||
#include <QCommandLineParser>
|
||||
|
||||
// Foro my own debugging, until we have better API
|
||||
#include "../../src/private/MDILayoutWidget_p.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
|
||||
#endif
|
||||
QGuiApplication app(argc, argv);
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("KDDockWidgets example application");
|
||||
parser.addHelpOption();
|
||||
|
||||
QQmlApplicationEngine appEngine;
|
||||
KDDockWidgets::Config::self().setQmlEngine(&appEngine);
|
||||
appEngine.load((QUrl("qrc:/main.qml")));
|
||||
|
||||
auto dw1 = new KDDockWidgets::DockWidgetQuick("Dock #1");
|
||||
dw1->setWidget(QStringLiteral("qrc:/Guest1.qml"));
|
||||
dw1->resize(QSize(400, 400));
|
||||
|
||||
auto dw2 = new KDDockWidgets::DockWidgetQuick("Dock #2");
|
||||
dw2->setWidget(QStringLiteral("qrc:/Guest2.qml"));
|
||||
dw2->resize(QSize(400, 400));
|
||||
|
||||
auto dw3 = new KDDockWidgets::DockWidgetQuick("Dock #3");
|
||||
dw3->setWidget(QStringLiteral("qrc:/Guest3.qml"));
|
||||
|
||||
auto mainWindow = static_cast<KDDockWidgets::MainWindowMDI*>(KDDockWidgets::DockRegistry::self()->mainwindows().constFirst());
|
||||
|
||||
mainWindow->addDockWidget(dw1, QPoint(10, 10));
|
||||
mainWindow->addDockWidget(dw2, QPoint(50, 50));
|
||||
mainWindow->addDockWidget(dw3, QPoint(90, 90));
|
||||
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
26
examples/qtquick/mdi/main.qml
Normal file
26
examples/qtquick/mdi/main.qml
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.12
|
||||
import com.kdab.dockwidgets 1.0 as KDDW
|
||||
|
||||
ApplicationWindow {
|
||||
visible: true
|
||||
width: 1000
|
||||
height: 1200
|
||||
|
||||
KDDW.MainWindowLayout {
|
||||
anchors.fill: parent
|
||||
uniqueName: "MyMainLayout"
|
||||
options: KDDW.KDDockWidgets.MainWindowOption_MDI
|
||||
}
|
||||
}
|
||||
10
examples/qtquick/mdi/resources_qtquick_mdi_example.qrc
Normal file
10
examples/qtquick/mdi/resources_qtquick_mdi_example.qrc
Normal file
@@ -0,0 +1,10 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
<file>Guest1.qml</file>
|
||||
<file>Guest2.qml</file>
|
||||
<file>Guest3.qml</file>
|
||||
<file>Guest.qml</file>
|
||||
<file>Another.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,10 +0,0 @@
|
||||
Format: 1.0
|
||||
Source: kddockwidgets
|
||||
Version: 1.2.0-1
|
||||
Binary: kddockwidgets
|
||||
Maintainer: Allen Winter <allen.winter@kdab.com>
|
||||
Architecture: any
|
||||
Build-Depends: debhelper (>=9), cdbs, cmake, qt5-default, qtbase5-dev, libqt5x11extras5-dev
|
||||
|
||||
Files:
|
||||
00000000000000000000000000000000 00000 kddockwidgets-1.2.0.tar.gz
|
||||
@@ -12,16 +12,16 @@
|
||||
set(PYTHON_VERSION "3.7" CACHE STRING "Use specific python version to build the project.")
|
||||
find_package(Python3 ${PYTHON_VERSION} REQUIRED COMPONENTS Interpreter Development)
|
||||
|
||||
if (${PROJECT_NAME}_QT6)
|
||||
find_package(Shiboken6 REQUIRED)
|
||||
find_package(PySide6 ${Qt5Widgets_VERSION} EXACT REQUIRED)
|
||||
include(PySide6ModuleBuild)
|
||||
set(PYSIDE_MAJOR_VERSION "6")
|
||||
if(${PROJECT_NAME}_QT6)
|
||||
find_package(Shiboken6 REQUIRED)
|
||||
find_package(PySide6 ${Qt6Widgets_VERSION} EXACT REQUIRED)
|
||||
include(PySide6ModuleBuild)
|
||||
set(PYSIDE_MAJOR_VERSION "6")
|
||||
else()
|
||||
find_package(Shiboken2 REQUIRED)
|
||||
find_package(PySide2 ${Qt5Widgets_VERSION} EXACT REQUIRED)
|
||||
include(PySide2ModuleBuild)
|
||||
set(PYSIDE_MAJOR_VERSION "2")
|
||||
find_package(Shiboken2 REQUIRED)
|
||||
find_package(PySide2 ${Qt5Widgets_VERSION} EXACT REQUIRED)
|
||||
include(PySide2ModuleBuild)
|
||||
set(PYSIDE_MAJOR_VERSION "2")
|
||||
endif()
|
||||
|
||||
add_subdirectory(PyKDDockWidgets)
|
||||
|
||||
@@ -16,10 +16,14 @@ set(PyKDDockWidgets_SRC
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_dockwidgetbase_wrapper.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_dockwidget_wrapper.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_dockwidget_wrapper.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_initialoption_wrapper.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_initialoption_wrapper.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_mainwindowbase_wrapper.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_mainwindowbase_wrapper.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_mainwindow_wrapper.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_mainwindow_wrapper.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_layoutsaver_wrapper.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_layoutsaver_wrapper.h
|
||||
# global module wrapper
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_module_wrapper.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgets/kddockwidgets_python.h
|
||||
@@ -56,6 +60,7 @@ set(PyKDDockWidgets_DEPENDS
|
||||
${CMAKE_SOURCE_DIR}/src/DockWidget.h
|
||||
${CMAKE_SOURCE_DIR}/src/MainWindowBase.h
|
||||
${CMAKE_SOURCE_DIR}/src/MainWindow.h
|
||||
${CMAKE_SOURCE_DIR}/src/LayoutSaver.h
|
||||
)
|
||||
|
||||
create_python_bindings(
|
||||
@@ -75,4 +80,4 @@ create_python_bindings(
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.cmake ${CMAKE_CURRENT_BINARY_DIR}/__init__.py @ONLY)
|
||||
|
||||
# install
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py DESTINATION ${${PROJECT_NAME}_PYTHON_BINDINGS_INSTALL_PREFIX}/PyKDDockWidgets)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/__init__.py DESTINATION ${${PROJECT_NAME}_PYTHON_BINDINGS_INSTALL_PREFIX}/PyKDDockWidgets)
|
||||
|
||||
@@ -25,3 +25,4 @@
|
||||
#include <kddockwidgets/MainWindow.h>
|
||||
#include <kddockwidgets/DockWidgetBase.h>
|
||||
#include <kddockwidgets/DockWidget.h>
|
||||
#include <kddockwidgets/LayoutSaver.h>
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
otherwise shiboken will ignore the function and will fail to create a wrapper -->
|
||||
<primitive-type name="DropAreaWithCentralFrame"/>
|
||||
<primitive-type name="SideBar"/>
|
||||
<primitive-type name="InitialOption"/>
|
||||
|
||||
<!-- Some plublic enum and flags -->
|
||||
<enum-type name="Location"/>
|
||||
@@ -28,6 +27,9 @@
|
||||
<enum-type name="DropIndicatorType"/>
|
||||
<enum-type name="SideBarLocation"/>
|
||||
<enum-type name="TitleBarButtonType"/>
|
||||
<enum-type name="SuggestedGeometryHint" flags="SuggestedGeometryHints" />
|
||||
<enum-type name="CursorPosition" flags="CursorPositions" />
|
||||
<enum-type name="AddingOption" />
|
||||
|
||||
<!-- our classes
|
||||
For class we can use two types:
|
||||
@@ -35,6 +37,7 @@
|
||||
value-type: class that can be passed as value for functions
|
||||
Here we only use 'object-type' since all our classes are derived from QWidget
|
||||
-->
|
||||
<value-type name="InitialOption"/>
|
||||
<object-type name="MainWindowBase" />
|
||||
<object-type name="MainWindow" />
|
||||
<object-type name="DockWidgetBase" >
|
||||
@@ -42,8 +45,10 @@
|
||||
inside of the object-type -->
|
||||
<enum-type name="Option" flags="Options" />
|
||||
<enum-type name="IconPlace" flags="IconPlaces" />
|
||||
<enum-type name="LayoutSaverOption" flags="LayoutSaverOptions" />
|
||||
</object-type>
|
||||
|
||||
<object-type name="DockWidget" />
|
||||
<object-type name="LayoutSaver" />
|
||||
</namespace-type>
|
||||
</typesystem>
|
||||
|
||||
@@ -106,7 +106,8 @@ class MyMainWindow(KDDockWidgets.MainWindow):
|
||||
self.m_dockwidgets.append(self.newDockWidget())
|
||||
|
||||
# MainWindow::addDockWidget() attaches a dock widget to the main window:
|
||||
self.addDockWidget(self.m_dockwidgets[0], KDDockWidgets.Location_OnTop)
|
||||
initialOpts = KDDockWidgets.InitialOption(KDDockWidgets.InitialVisibilityOption.StartHidden, QtCore.QSize(500, 500))
|
||||
self.addDockWidget(self.m_dockwidgets[0], KDDockWidgets.Location_OnBottom, None, initialOpts)
|
||||
|
||||
# Here, for finer granularity we specify right of dockwidgets[0]:
|
||||
self.addDockWidget(self.m_dockwidgets[1], KDDockWidgets.Location_OnRight, self.m_dockwidgets[0])
|
||||
|
||||
@@ -33,9 +33,15 @@ set(DOCKSLIBS_SRCS
|
||||
DockWidgetBase.h
|
||||
MainWindowBase.cpp
|
||||
MainWindowBase.h
|
||||
MainWindowMDI.cpp
|
||||
MainWindowMDI.h
|
||||
LayoutSaver.cpp
|
||||
LayoutSaver.h
|
||||
LayoutSaver_p.h
|
||||
private/LayoutSaver_p.h
|
||||
private/LayoutWidget.cpp
|
||||
private/LayoutWidget_p.h
|
||||
private/MDILayoutWidget.cpp
|
||||
private/MDILayoutWidget_p.h
|
||||
private/MultiSplitter.cpp
|
||||
private/MultiSplitter_p.h
|
||||
private/Position.cpp
|
||||
@@ -77,6 +83,8 @@ set(DOCKSLIBS_SRCS
|
||||
|
||||
private/multisplitter/Item.cpp
|
||||
private/multisplitter/Item_p.h
|
||||
private/multisplitter/ItemFreeContainer.cpp
|
||||
private/multisplitter/ItemFreeContainer_p.h
|
||||
private/multisplitter/Logging.cpp
|
||||
private/multisplitter/Logging_p.h
|
||||
private/multisplitter/MultiSplitterConfig.cpp
|
||||
@@ -97,18 +105,24 @@ set(DOCKS_INSTALLABLE_INCLUDES
|
||||
FocusScope.h
|
||||
QWidgetAdapter.h
|
||||
LayoutSaver.h
|
||||
LayoutSaver_p.h
|
||||
MainWindowMDI.h
|
||||
MainWindowBase.h
|
||||
)
|
||||
|
||||
set(DOCKS_INSTALLABLE_PRIVATE_INCLUDES
|
||||
private/DragController_p.h
|
||||
private/Draggable_p.h
|
||||
private/DropArea_p.h
|
||||
private/DropIndicatorOverlayInterface_p.h
|
||||
private/FloatingWindow_p.h
|
||||
private/Frame_p.h
|
||||
private/LayoutSaver_p.h
|
||||
private/MultiSplitter_p.h
|
||||
private/LayoutWidget_p.h
|
||||
private/SideBar_p.h
|
||||
private/TitleBar_p.h
|
||||
private/WindowBeingDragged_p.h
|
||||
private/WidgetResizeHandler_p.h
|
||||
private/DockRegistry_p.h
|
||||
private/TabWidget_p.h
|
||||
)
|
||||
@@ -141,14 +155,18 @@ if(${PROJECT_NAME}_QTQUICK)
|
||||
private/quick/TitleBarQuick_p.h
|
||||
private/quick/QmlTypes.cpp
|
||||
private/quick/QmlTypes.h
|
||||
private/quick/Helpers.cpp
|
||||
private/quick/Helpers_p.h
|
||||
private/quick/FrameQuick.cpp
|
||||
private/quick/FrameQuick_p.h
|
||||
private/quick/LayoutSaverInstantiator.cpp
|
||||
private/quick/LayoutSaverInstantiator_p.h
|
||||
private/quick/RubberBandQuick.cpp
|
||||
private/quick/RubberBandQuick.h
|
||||
private/quick/MainWindowQuick.cpp
|
||||
private/quick/MainWindowQuick_p.h
|
||||
private/quick/MainWindowWrapper.cpp
|
||||
private/quick/MainWindowWrapper_p.h
|
||||
private/quick/MainWindowInstantiator.cpp
|
||||
private/quick/MainWindowInstantiator_p.h
|
||||
private/multisplitter/Widget_quick.cpp
|
||||
private/multisplitter/Widget_quick.h
|
||||
private/multisplitter/Separator_quick.cpp
|
||||
@@ -156,6 +174,9 @@ if(${PROJECT_NAME}_QTQUICK)
|
||||
private/multisplitter/Rubberband_quick.cpp
|
||||
private/multisplitter/Rubberband_quick.h
|
||||
kddockwidgets_qtquick.qrc)
|
||||
|
||||
set(DOCKS_INSTALLABLE_INCLUDES ${DOCKS_INSTALLABLE_INCLUDES} DockWidgetQuick.h)
|
||||
|
||||
else()
|
||||
set(DOCKSLIBS_SRCS ${DOCKSLIBS_SRCS}
|
||||
private/DebugWindow.cpp
|
||||
@@ -187,26 +208,37 @@ else()
|
||||
private/indicators/SegmentedIndicators.cpp
|
||||
private/indicators/SegmentedIndicators_p.h
|
||||
# private/indicators/AnimatedIndicators.cpp
|
||||
)
|
||||
)
|
||||
|
||||
set(DOCKS_INSTALLABLE_INCLUDES
|
||||
${DOCKS_INSTALLABLE_INCLUDES}
|
||||
MainWindow.h
|
||||
MainWindowBase.h
|
||||
DockWidget.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(IS_CLANG_BUILD TRUE)
|
||||
else()
|
||||
set(IS_CLANG_BUILD FALSE)
|
||||
endif()
|
||||
#Generate C/C++ CamelCase forwarding headers (only public includes)
|
||||
include(ECMGenerateHeaders)
|
||||
ecm_generate_headers(camelcase_HEADERS
|
||||
ORIGINAL
|
||||
CAMELCASE
|
||||
HEADER_NAMES
|
||||
Config
|
||||
DockWidget
|
||||
DockWidgetBase
|
||||
FocusScope
|
||||
FrameworkWidgetFactory,DefaultWidgetFactory
|
||||
LayoutSaver
|
||||
MainWindow
|
||||
MainWindowBase
|
||||
MainWindowMDI
|
||||
)
|
||||
|
||||
set(RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/kddockwidgets_resources.qrc)
|
||||
|
||||
add_library(kddockwidgets ${KDDockWidgets_LIBRARY_MODE} ${DOCKSLIBS_SRCS} ${DOCKS_INSTALLABLE_INCLUDES} ${RESOURCES} ${RESOURCES_QUICK})
|
||||
add_library(kddockwidgets ${KDDockWidgets_LIBRARY_MODE} ${DOCKSLIBS_SRCS} ${DOCKS_INSTALLABLE_INCLUDES} ${RESOURCES})
|
||||
add_library(KDAB::kddockwidgets ALIAS kddockwidgets)
|
||||
set_target_properties(kddockwidgets PROPERTIES OUTPUT_NAME "kddockwidgets${KDDockWidgets_LIBRARY_QTID}")
|
||||
set_compiler_flags(kddockwidgets)
|
||||
|
||||
target_include_directories(kddockwidgets
|
||||
@@ -215,8 +247,6 @@ target_include_directories(kddockwidgets
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/fwd_headers>
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/private
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/private/multisplitter/
|
||||
)
|
||||
|
||||
target_compile_definitions(kddockwidgets
|
||||
@@ -232,11 +262,18 @@ else()
|
||||
target_compile_definitions(kddockwidgets PRIVATE BUILDING_DOCKS_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(KDDockWidgets_QTQUICK)
|
||||
target_compile_definitions(kddockwidgets PUBLIC KDDOCKWIDGETS_QTQUICK)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR IS_CLANG_BUILD)
|
||||
target_compile_options(kddockwidgets PRIVATE -Wshadow -fvisibility=hidden)
|
||||
target_compile_options(kddockwidgets PRIVATE -Wshadow)
|
||||
if(NOT MSVC)
|
||||
target_compile_options(kddockwidgets PRIVATE -fvisibility=hidden)
|
||||
endif()
|
||||
|
||||
# Disable -Wconversion for Qt6. The qsizetype to int conversions are harmless
|
||||
if (NOT ${PROJECT_NAME}_QT6)
|
||||
if(NOT ${PROJECT_NAME}_QT6)
|
||||
target_compile_options(kddockwidgets PRIVATE -Wconversion)
|
||||
endif()
|
||||
|
||||
@@ -251,11 +288,11 @@ else()
|
||||
target_link_libraries(kddockwidgets PUBLIC Qt${QT_MAJOR_VERSION}::Widgets)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(kddockwidgets PRIVATE Qt${QT_MAJOR_VERSION}::GuiPrivate dwmapi)
|
||||
if(WIN32)
|
||||
target_link_libraries(kddockwidgets PRIVATE Qt${QT_MAJOR_VERSION}::GuiPrivate dwmapi)
|
||||
elseif(NOT APPLE AND NOT EMSCRIPTEN AND NOT ${PROJECT_NAME}_QT6)
|
||||
find_package(Qt${QT_MAJOR_VERSION}X11Extras)
|
||||
target_link_libraries(kddockwidgets PUBLIC Qt${QT_MAJOR_VERSION}::X11Extras)
|
||||
find_package(Qt${QT_MAJOR_VERSION}X11Extras)
|
||||
target_link_libraries(kddockwidgets PUBLIC Qt${QT_MAJOR_VERSION}::X11Extras)
|
||||
endif()
|
||||
|
||||
set_target_properties(kddockwidgets PROPERTIES
|
||||
@@ -265,13 +302,19 @@ set_target_properties(kddockwidgets PROPERTIES
|
||||
|
||||
#version libraries on Windows
|
||||
if(WIN32)
|
||||
set(postfix ${${PROJECT_NAME}_VERSION_MAJOR})
|
||||
set(CMAKE_RELEASE_POSTFIX ${postfix})
|
||||
set_target_properties(kddockwidgets PROPERTIES RELEASE_POSTFIX ${CMAKE_RELEASE_POSTFIX})
|
||||
#append 'd' to debug libraries
|
||||
string(CONCAT postfix ${postfix} "d")
|
||||
set(CMAKE_DEBUG_POSTFIX ${postfix})
|
||||
set_target_properties(kddockwidgets PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
set(postfix ${${PROJECT_NAME}_VERSION_MAJOR})
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} UPPER_BUILD_TYPE)
|
||||
if(${UPPER_BUILD_TYPE} MATCHES "^DEBUG")
|
||||
string(CONCAT postfix ${postfix} "d")
|
||||
set_target_properties(kddockwidgets PROPERTIES DEBUG_POSTFIX ${postfix})
|
||||
else()
|
||||
set_target_properties(kddockwidgets PROPERTIES ${UPPER_BUILD_TYPE}_POSTFIX ${postfix})
|
||||
endif()
|
||||
elseif(CMAKE_CONFIGURATION_TYPES)
|
||||
# Visual Studio generator
|
||||
set_target_properties(kddockwidgets PROPERTIES DEBUG_POSTFIX d)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(TARGETS kddockwidgets
|
||||
@@ -283,24 +326,36 @@ install(TARGETS kddockwidgets
|
||||
if(MSVC AND NOT ${PROJECT_NAME}_STATIC)
|
||||
install(FILES "$<TARGET_PDB_FILE_DIR:kddockwidgets>/$<TARGET_PDB_FILE_NAME:kddockwidgets>" DESTINATION ${INSTALL_LIBRARY_DIR} CONFIGURATIONS Debug RelWithDebInfo)
|
||||
endif()
|
||||
|
||||
install(FILES ${camelcase_HEADERS} DESTINATION include/kddockwidgets)
|
||||
install(FILES ${DOCKS_INSTALLABLE_INCLUDES} DESTINATION include/kddockwidgets)
|
||||
install(FILES ${DOCKS_INSTALLABLE_PRIVATE_INCLUDES} DESTINATION include/kddockwidgets/private)
|
||||
install(FILES private/multisplitter/Item_p.h DESTINATION include/kddockwidgets/private/multisplitter)
|
||||
install(FILES private/multisplitter/Widget.h DESTINATION include/kddockwidgets/private/multisplitter)
|
||||
install(FILES private/multisplitter/Widget_qwidget.h DESTINATION include/kddockwidgets/private/multisplitter)
|
||||
install(FILES private/multisplitter/Separator_p.h DESTINATION include/kddockwidgets/private/multisplitter)
|
||||
install(FILES private/multisplitter/Separator_qwidget.h DESTINATION include/kddockwidgets/private/multisplitter)
|
||||
install(FILES ${DOCKS_INSTALLABLE_PRIVATE_WIDGET_INCLUDES} DESTINATION include/kddockwidgets/private/widgets)
|
||||
|
||||
install(FILES private/indicators/ClassicIndicators_p.h DESTINATION include/kddockwidgets/private/indicators)
|
||||
install(FILES private/indicators/SegmentedIndicators_p.h DESTINATION include/kddockwidgets/private/indicators)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
KDDockWidgetsConfigVersion.cmake
|
||||
VERSION ${${PROJECT_NAME}_VERSION}
|
||||
if(KDDockWidgets_QTQUICK)
|
||||
install(FILES private/multisplitter/Separator_quick.h DESTINATION include/kddockwidgets/private/multisplitter)
|
||||
install(FILES private/multisplitter/Widget_quick.h DESTINATION include/kddockwidgets/private/multisplitter)
|
||||
else()
|
||||
install(FILES ${DOCKS_INSTALLABLE_PRIVATE_WIDGET_INCLUDES} DESTINATION include/kddockwidgets/private/widgets)
|
||||
install(FILES private/multisplitter/Separator_qwidget.h DESTINATION include/kddockwidgets/private/multisplitter)
|
||||
install(FILES private/multisplitter/Widget_qwidget.h DESTINATION include/kddockwidgets/private/multisplitter)
|
||||
endif()
|
||||
|
||||
# Generate library version files
|
||||
include(ECMSetupVersion)
|
||||
ecm_setup_version(
|
||||
${${PROJECT_NAME}_VERSION}
|
||||
VARIABLE_PREFIX KDDOCKWIDGETS
|
||||
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kddockwidgets_version.h"
|
||||
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KDDockWidgetsConfigVersion.cmake"
|
||||
SOVERSION ${${PROJECT_NAME}_SOVERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kddockwidgets_version.h" DESTINATION include/kddockwidgets)
|
||||
|
||||
install(EXPORT kddockwidgetsTargets
|
||||
FILE KDDockWidgetsTargets.cmake
|
||||
@@ -319,7 +374,7 @@ if(${PROJECT_NAME}_DEVELOPER_MODE)
|
||||
|
||||
option(KDDockWidgets_LINTER "Build the layout linter" ON)
|
||||
|
||||
if (NOT ${PROJECT_NAME}_QTQUICK AND KDDockWidgets_LINTER) # TODO: We can support it
|
||||
if(NOT ${PROJECT_NAME}_QTQUICK AND KDDockWidgets_LINTER) # TODO: We can support it
|
||||
add_executable(kddockwidgets_linter layoutlinter_main.cpp)
|
||||
target_link_libraries(kddockwidgets_linter kddockwidgets Qt${QT_MAJOR_VERSION}::Widgets)
|
||||
endif()
|
||||
|
||||
@@ -17,22 +17,23 @@
|
||||
*/
|
||||
|
||||
#include "Config.h"
|
||||
#include "multisplitter/MultiSplitterConfig.h"
|
||||
#include "multisplitter/Widget.h"
|
||||
#include "DockRegistry_p.h"
|
||||
#include "private/multisplitter/MultiSplitterConfig.h"
|
||||
#include "private/multisplitter/Widget.h"
|
||||
#include "private/DockRegistry_p.h"
|
||||
#include "private/Utils_p.h"
|
||||
#include "private/DragController_p.h"
|
||||
#include "FrameworkWidgetFactory.h"
|
||||
#include "Utils_p.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QOperatingSystemVersion>
|
||||
|
||||
#ifdef KDDOCKWIDGETS_QTQUICK
|
||||
# include <QQmlEngine>
|
||||
# include <QQmlContext>
|
||||
#include "private/quick/Helpers_p.h"
|
||||
#include <QQmlEngine>
|
||||
#include <QQmlContext>
|
||||
#endif
|
||||
|
||||
namespace KDDockWidgets
|
||||
{
|
||||
namespace KDDockWidgets {
|
||||
|
||||
class Config::Private
|
||||
{
|
||||
@@ -56,7 +57,13 @@ public:
|
||||
FrameworkWidgetFactory *m_frameworkWidgetFactory = nullptr;
|
||||
Flags m_flags = Flag_Default;
|
||||
InternalFlags m_internalFlags = InternalFlag_None;
|
||||
CustomizableWidgets m_disabledPaintEvents = CustomizableWidget_None;
|
||||
qreal m_draggedWindowOpacity = Q_QNAN;
|
||||
int m_mdiPopupThreshold = 250;
|
||||
bool m_dropIndicatorsInhibited = false;
|
||||
#ifdef KDDOCKWIDGETS_QTQUICK
|
||||
QtQuickHelpers m_qquickHelpers;
|
||||
#endif
|
||||
};
|
||||
|
||||
Config::Config()
|
||||
@@ -72,7 +79,7 @@ Config::Config()
|
||||
Layouting::Config::self().setSeparatorFactoryFunc(separatorCreator);
|
||||
}
|
||||
|
||||
Config& Config::self()
|
||||
Config &Config::self()
|
||||
{
|
||||
static Config config;
|
||||
return config;
|
||||
@@ -91,7 +98,7 @@ Config::Flags Config::flags() const
|
||||
void Config::setFlags(Flags f)
|
||||
{
|
||||
auto dr = DockRegistry::self();
|
||||
if (!dr->isEmpty(/*excludeBeingDeleted=*/ true)) {
|
||||
if (!dr->isEmpty(/*excludeBeingDeleted=*/true)) {
|
||||
qWarning() << Q_FUNC_INFO << "Only use this function at startup before creating any DockWidget or MainWindow"
|
||||
<< "; These are already created: " << dr->mainWindowsNames()
|
||||
<< dr->dockWidgetNames() << dr->floatingWindows();
|
||||
@@ -145,7 +152,7 @@ int Config::separatorThickness() const
|
||||
|
||||
void Config::setSeparatorThickness(int value)
|
||||
{
|
||||
if (!DockRegistry::self()->isEmpty(/*excludeBeingDeleted=*/ true)) {
|
||||
if (!DockRegistry::self()->isEmpty(/*excludeBeingDeleted=*/true)) {
|
||||
qWarning() << Q_FUNC_INFO << "Only use this function at startup before creating any DockWidget or MainWindow";
|
||||
return;
|
||||
}
|
||||
@@ -175,7 +182,7 @@ TabbingAllowedFunc Config::tabbingAllowedFunc() const
|
||||
|
||||
void Config::setAbsoluteWidgetMinSize(QSize size)
|
||||
{
|
||||
if (!DockRegistry::self()->isEmpty(/*excludeBeingDeleted=*/ false)) {
|
||||
if (!DockRegistry::self()->isEmpty(/*excludeBeingDeleted=*/false)) {
|
||||
qWarning() << Q_FUNC_INFO << "Only use this function at startup before creating any DockWidget or MainWindow";
|
||||
return;
|
||||
}
|
||||
@@ -190,7 +197,7 @@ QSize Config::absoluteWidgetMinSize() const
|
||||
|
||||
void Config::setAbsoluteWidgetMaxSize(QSize size)
|
||||
{
|
||||
if (!DockRegistry::self()->isEmpty(/*excludeBeingDeleted=*/ false)) {
|
||||
if (!DockRegistry::self()->isEmpty(/*excludeBeingDeleted=*/false)) {
|
||||
qWarning() << Q_FUNC_INFO << "Only use this function at startup before creating any DockWidget or MainWindow";
|
||||
return;
|
||||
}
|
||||
@@ -226,14 +233,21 @@ void Config::setQmlEngine(QQmlEngine *qmlEngine)
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_qmlEngine = qmlEngine;
|
||||
|
||||
auto dr = DockRegistry::self(); // make sure our QML types are registered
|
||||
QQmlContext *context = qmlEngine->rootContext();
|
||||
context->setContextProperty(QStringLiteral("_kddwHelpers"), &d->m_qquickHelpers);
|
||||
context->setContextProperty(QStringLiteral("_kddwDockRegistry"), dr);
|
||||
context->setContextProperty(QStringLiteral("_kddwDragController"), DragController::instance());
|
||||
context->setContextProperty(QStringLiteral("_kddw_widgetFactory"), d->m_frameworkWidgetFactory);
|
||||
|
||||
d->m_qmlEngine = qmlEngine;
|
||||
}
|
||||
|
||||
QQmlEngine *Config::qmlEngine() const
|
||||
{
|
||||
if (!d->m_qmlEngine)
|
||||
qWarning() << "Please call KDDockWidgets::Config::self()->setQmlEngine(engine)";
|
||||
|
||||
return d->m_qmlEngine;
|
||||
}
|
||||
#endif
|
||||
@@ -290,6 +304,44 @@ void Config::Private::fixFlags()
|
||||
m_internalFlags |= InternalFlag_DontUseParentForFloatingWindows;
|
||||
m_internalFlags |= InternalFlag_DontUseQtToolWindowsForFloatingWindows;
|
||||
}
|
||||
|
||||
if (m_flags & Flag_ShowButtonsOnTabBarIfTitleBarHidden) {
|
||||
// Flag_ShowButtonsOnTabBarIfTitleBarHidden doesn't make sense if used alone
|
||||
m_flags |= Flag_HideTitleBarWhenTabsVisible;
|
||||
}
|
||||
}
|
||||
|
||||
void Config::setDisabledPaintEvents(CustomizableWidgets widgets)
|
||||
{
|
||||
d->m_disabledPaintEvents = widgets;
|
||||
}
|
||||
|
||||
Config::CustomizableWidgets Config::disabledPaintEvents() const
|
||||
{
|
||||
return d->m_disabledPaintEvents;
|
||||
}
|
||||
|
||||
void Config::setMDIPopupThreshold(int threshold)
|
||||
{
|
||||
d->m_mdiPopupThreshold = threshold;
|
||||
}
|
||||
|
||||
int Config::mdiPopupThreshold() const
|
||||
{
|
||||
return d->m_mdiPopupThreshold;
|
||||
}
|
||||
|
||||
void Config::setDropIndicatorsInhibited(bool inhibit) const
|
||||
{
|
||||
if (d->m_dropIndicatorsInhibited != inhibit) {
|
||||
d->m_dropIndicatorsInhibited = inhibit;
|
||||
Q_EMIT DockRegistry::self()->dropIndicatorsInhibitedChanged(inhibit);
|
||||
}
|
||||
}
|
||||
|
||||
bool Config::dropIndicatorsInhibited() const
|
||||
{
|
||||
return d->m_dropIndicatorsInhibited;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
75
src/Config.h
75
src/Config.h
@@ -21,28 +21,29 @@
|
||||
|
||||
#include "docks_export.h"
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QQmlEngine;
|
||||
class QSize;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace KDDockWidgets
|
||||
{
|
||||
namespace KDDockWidgets {
|
||||
|
||||
class DockWidgetBase;
|
||||
class MainWindowBase;
|
||||
class FrameworkWidgetFactory;
|
||||
|
||||
typedef KDDockWidgets::DockWidgetBase* (*DockWidgetFactoryFunc)(const QString &name);
|
||||
typedef KDDockWidgets::MainWindowBase* (*MainWindowFactoryFunc)(const QString &name);
|
||||
typedef KDDockWidgets::DockWidgetBase *(*DockWidgetFactoryFunc)(const QString &name);
|
||||
typedef KDDockWidgets::MainWindowBase *(*MainWindowFactoryFunc)(const QString &name);
|
||||
|
||||
/// @brief Function to allow the user more granularity to disallow dock widgets to tab together
|
||||
/// @param source The dock widgets being dragged
|
||||
/// @param target The dock widgets within an existing docked tab group
|
||||
/// @return true if the docking is allowed.
|
||||
/// @sa setTabbingAllowedFunc
|
||||
typedef bool (*TabbingAllowedFunc)(const QVector<DockWidgetBase*> &source,
|
||||
const QVector<DockWidgetBase*> &target);
|
||||
typedef bool (*TabbingAllowedFunc)(const QVector<DockWidgetBase *> &source,
|
||||
const QVector<DockWidgetBase *> &target);
|
||||
|
||||
/**
|
||||
* @brief Singleton to allow to choose certain behaviours of the framework.
|
||||
@@ -53,7 +54,6 @@ typedef bool (*TabbingAllowedFunc)(const QVector<DockWidgetBase*> &source,
|
||||
class DOCKS_EXPORT Config
|
||||
{
|
||||
public:
|
||||
|
||||
///@brief returns the singleton Config instance
|
||||
static Config &self();
|
||||
|
||||
@@ -61,9 +61,10 @@ public:
|
||||
~Config();
|
||||
|
||||
///@brief Flag enum to tune certain behaviours, the defaults are Flag_Default
|
||||
enum Flag {
|
||||
enum Flag
|
||||
{
|
||||
Flag_None = 0, ///< No option set
|
||||
Flag_NativeTitleBar = 1, ///< Enables the Native OS title bar on OSes that support it (Windows 10, macOS), ignored otherwise. This is mutually exclusive with Flag_AeroSnap
|
||||
Flag_NativeTitleBar = 1, ///< Enables the Native OS title bar on OSes that support it (Windows 10, macOS), ignored otherwise.
|
||||
Flag_AeroSnapWithClientDecos = 2, ///< Deprecated. This is now default and cannot be turned off. Moving a window on Windows 10 uses native moving, as that works well across screens with different HDPI settings. There's no reason to use manual client/Qt window moving.
|
||||
Flag_AlwaysTitleBarWhenFloating = 4, ///< Floating windows will have a title bar even if Flag_HideTitleBarWhenTabsVisible is specified. Unneeded if Flag_HideTitleBarWhenTabsVisible isn't specified, as that's the default already.
|
||||
Flag_HideTitleBarWhenTabsVisible = 8, ///< Hides the title bar if there's tabs visible. The empty space in the tab bar becomes draggable.
|
||||
@@ -75,24 +76,44 @@ public:
|
||||
Flag_TitleBarIsFocusable = 512, ///< You can click the title bar and it will focus the last focused widget in the focus scope. If no previously focused widget then it focuses the user's dock widget guest, which should accept focus or use a focus proxy.
|
||||
Flag_LazyResize = 1024, ///< The dock widgets are resized in a lazy manner. The actual resize only happens when you release the mouse button.
|
||||
Flag_DontUseUtilityFloatingWindows = 0x1000,
|
||||
Flag_TitleBarHasMinimizeButton = 0x2000 | Flag_DontUseUtilityFloatingWindows, ///< The title bar will have a minimize button when floating. This implies Flag_DontUseUtilityFloatingWindows too, otherwise they wouldn't appear in the task bar.
|
||||
Flag_TitleBarHasMinimizeButton = 0x2000 | Flag_DontUseUtilityFloatingWindows, ///< The title bar will have a minimize button when floating. This implies Flag_DontUseUtilityFloatingWindows too, otherwise they wouldn't appear in the task bar.
|
||||
Flag_TitleBarNoFloatButton = 0x4000, ///< The TitleBar won't show the float button
|
||||
Flag_AutoHideSupport = 0x8000 | Flag_TitleBarNoFloatButton, ///< Supports minimizing dock widgets to the side-bar.
|
||||
///< By default it also turns off the float button, but you can remove Flag_TitleBarNoFloatButton to have both.
|
||||
///< By default it also turns off the float button, but you can remove Flag_TitleBarNoFloatButton to have both.
|
||||
Flag_KeepAboveIfNotUtilityWindow = 0x10000, ///< Only meaningful if Flag_DontUseUtilityFloatingWindows is set. If floating windows are normal windows, you might still want them to keep above and not minimize when you focus the main window.
|
||||
Flag_CloseOnlyCurrentTab = 0x20000, ///< The TitleBar's close button will only close the current tab, instead of all of them
|
||||
Flag_ShowButtonsOnTabBarIfTitleBarHidden = 0x40000, ///< When using Flag_HideTitleBarWhenTabsVisible the close/float buttons disappear with the title bar. With Flag_ShowButtonsOnTabBarIfHidden they'll be shown in the tab bar.
|
||||
Flag_Default = Flag_AeroSnapWithClientDecos ///< The defaults
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
||||
///@brief List of customizable widgets
|
||||
enum CustomizableWidget
|
||||
{
|
||||
CustomizableWidget_None = 0, ///< None
|
||||
CustomizableWidget_TitleBar, ///< The title bar
|
||||
CustomizableWidget_DockWidget, ///< The dock widget
|
||||
CustomizableWidget_Frame, ///< The container for a group of 1 or more dockwidgets which are tabbed together
|
||||
CustomizableWidget_TabBar, ///< The tab bar, child of Frame, which contains 1 or more dock widgets
|
||||
CustomizableWidget_TabWidget, ///< The tab widget which relates to the tab bar
|
||||
CustomizableWidget_FloatingWindow, ///< A top-level window. The container for 1 or more Frame nested side by side
|
||||
CustomizableWidget_Separator ///< The draggable separator between dock widgets in a layout
|
||||
};
|
||||
Q_DECLARE_FLAGS(CustomizableWidgets, CustomizableWidget)
|
||||
|
||||
///@internal
|
||||
///Internal flags for addtional tunning.
|
||||
///Internal flags for additional tuning.
|
||||
///@warning Not for public consumption, support will be limited.
|
||||
enum InternalFlag {
|
||||
enum InternalFlag
|
||||
{
|
||||
InternalFlag_None = 0, ///< The default
|
||||
InternalFlag_NoAeroSnap = 1, ///< Only for development. Disables Aero-snap.
|
||||
InternalFlag_DontUseParentForFloatingWindows = 2, ///< FloatingWindows won't have a parent top-level.
|
||||
InternalFlag_DontUseParentForFloatingWindows = 2, ///< FloatingWindows won't have a parent top-level.
|
||||
InternalFlag_DontUseQtToolWindowsForFloatingWindows = 4, ///< FloatingWindows will use Qt::Window instead of Qt::Tool.
|
||||
InternalFlag_DontShowWhenUnfloatingHiddenWindow = 8 ///< DockWidget::setFloating(false) won't do anything if the window is hidden.
|
||||
InternalFlag_DontShowWhenUnfloatingHiddenWindow = 8, ///< DockWidget::setFloating(false) won't do anything if the window is hidden.
|
||||
InternalFlag_UseTransparentFloatingWindow = 16, ///< For QtQuick only. Allows to have round-corners. It's flaky when used with native Windows drop-shadow.
|
||||
InternalFlag_DisableTranslucency = 32 ///< KDDW tries to detect if your Window Manager doesn't support transparent windows, but the detection might fail
|
||||
/// with more exotic setups. This flag can be used to override.
|
||||
};
|
||||
Q_DECLARE_FLAGS(InternalFlags, InternalFlag)
|
||||
|
||||
@@ -167,6 +188,15 @@ public:
|
||||
///By default it's 1.0, fully opaque
|
||||
qreal draggedWindowOpacity() const;
|
||||
|
||||
/// @brief Allows to disable support for drop indicators while dragging
|
||||
/// By default drop indicators will be shown when dragging dock widgets.
|
||||
/// This functionality can be toggled whenever you need it (it's not a startup-only setting).
|
||||
void setDropIndicatorsInhibited(bool inhibit) const;
|
||||
|
||||
/// @brief Returns whether drop indicators are inhibited.
|
||||
/// by default this is false unless you call setDropIndicatorsInhibited(true)
|
||||
bool dropIndicatorsInhibited() const;
|
||||
|
||||
/**
|
||||
* @brief Allows the user to intercept a docking attempt to center (tabbed) and disallow it.
|
||||
*
|
||||
@@ -206,6 +236,13 @@ public:
|
||||
void setAbsoluteWidgetMaxSize(QSize size);
|
||||
QSize absoluteWidgetMaxSize() const;
|
||||
|
||||
///@brief Disables our internal widget's paint events
|
||||
/// By default, KDDockWidget's internal widgets reimplement paintEvent(). Disabling them
|
||||
/// (which makes the base-class, QWidget::paintEvent() be called instead) can be useful if you want to style
|
||||
// via CSS stylesheets.
|
||||
void setDisabledPaintEvents(CustomizableWidgets);
|
||||
Config::CustomizableWidgets disabledPaintEvents() const;
|
||||
|
||||
///@internal
|
||||
///@brief returns the internal flags.
|
||||
///@warning Not for public consumption, support will be limited.
|
||||
@@ -216,10 +253,16 @@ public:
|
||||
///@warning Not for public consumption, support will be limited.
|
||||
void setInternalFlags(InternalFlags flags);
|
||||
|
||||
/// @brief Sets the MDI popup threshold. When the layout is MDI and you drag a dock widget
|
||||
/// X pixels behond the window's edge, it will float the dock widget.
|
||||
/// by default this value is 250px. Use -1 to disable
|
||||
void setMDIPopupThreshold(int);
|
||||
int mdiPopupThreshold() const;
|
||||
|
||||
#ifdef KDDOCKWIDGETS_QTQUICK
|
||||
///@brief Sets the QQmlEngine to use. Applicable only when using QtQuick.
|
||||
void setQmlEngine(QQmlEngine *);
|
||||
QQmlEngine* qmlEngine() const;
|
||||
QQmlEngine *qmlEngine() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
@@ -49,7 +49,8 @@ public:
|
||||
* when visible, or stays without a parent when hidden. This allows to support docking
|
||||
* to different main windows.
|
||||
*/
|
||||
explicit DockWidget(const QString &uniqueName, Options options = DockWidgetBase::Options());
|
||||
explicit DockWidget(const QString &uniqueName, Options options = KDDockWidgets::DockWidgetBase::Options(),
|
||||
LayoutSaverOptions layoutSaverOptions = KDDockWidgets::DockWidgetBase::LayoutSaverOptions());
|
||||
|
||||
///@brief destructor
|
||||
~DockWidget() override;
|
||||
|
||||
@@ -10,18 +10,21 @@
|
||||
*/
|
||||
|
||||
#include "DockWidgetBase.h"
|
||||
#include "Frame_p.h"
|
||||
#include "FloatingWindow_p.h"
|
||||
#include "Logging_p.h"
|
||||
#include "Utils_p.h"
|
||||
#include "DockRegistry_p.h"
|
||||
#include "DropArea_p.h"
|
||||
#include "Config.h"
|
||||
#include "TitleBar_p.h"
|
||||
#include "FrameworkWidgetFactory.h"
|
||||
#include "private/DockWidgetBase_p.h"
|
||||
#include "private/DockRegistry_p.h"
|
||||
#include "private/FloatingWindow_p.h"
|
||||
#include "private/Frame_p.h"
|
||||
#include "private/LayoutSaver_p.h"
|
||||
#include "private/Logging_p.h"
|
||||
#include "private/MDILayoutWidget_p.h"
|
||||
#include "private/SideBar_p.h"
|
||||
#include "private/TitleBar_p.h"
|
||||
#include "private/Utils_p.h"
|
||||
#include "private/WindowBeingDragged_p.h"
|
||||
#include "private/Position_p.h"
|
||||
#include "WindowBeingDragged_p.h"
|
||||
#include "SideBar_p.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "FrameworkWidgetFactory.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QCloseEvent>
|
||||
@@ -37,107 +40,10 @@
|
||||
|
||||
using namespace KDDockWidgets;
|
||||
|
||||
class DockWidgetBase::Private
|
||||
{
|
||||
public:
|
||||
Private(const QString &dockName, DockWidgetBase::Options options_, DockWidgetBase *qq)
|
||||
: name(dockName)
|
||||
, title(dockName)
|
||||
, q(qq)
|
||||
, options(options_)
|
||||
, toggleAction(new QAction(q))
|
||||
, floatAction(new QAction(q))
|
||||
{
|
||||
q->connect(toggleAction, &QAction::toggled, q, [this] (bool enabled) {
|
||||
if (!m_updatingToggleAction) { // guard against recursiveness
|
||||
toggleAction->blockSignals(true); // and don't emit spurious toggle. Like when a dock widget is inserted into a tab widget it might get hide events, ignore those. The Dock Widget is open.
|
||||
toggle(enabled);
|
||||
toggleAction->blockSignals(false);
|
||||
}
|
||||
});
|
||||
|
||||
q->connect(floatAction, &QAction::toggled, q, [this] (bool checked) {
|
||||
if (!m_updatingFloatAction) { // guard against recursiveness
|
||||
q->setFloating(checked);
|
||||
}
|
||||
|
||||
Q_EMIT q->isFloatingChanged(checked);
|
||||
});
|
||||
|
||||
toggleAction->setCheckable(true);
|
||||
floatAction->setCheckable(true);
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
FloatingWindow *floatingWindow() const
|
||||
{
|
||||
return qobject_cast<FloatingWindow*>(q->window());
|
||||
}
|
||||
|
||||
MainWindowBase *mainWindow() const
|
||||
{
|
||||
if (q->isWindow())
|
||||
return nullptr;
|
||||
|
||||
// Note: Don't simply use window(), as the MainWindow might be embedded into something else
|
||||
QWidgetOrQuick *p = q->parentWidget();
|
||||
while (p) {
|
||||
if (auto window = qobject_cast<MainWindowBase*>(p))
|
||||
return window;
|
||||
|
||||
if (p->isWindow())
|
||||
return nullptr;
|
||||
|
||||
p = p->parentWidget();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QPoint defaultCenterPosForFloating();
|
||||
|
||||
void updateTitle();
|
||||
void toggle(bool enabled);
|
||||
void updateToggleAction();
|
||||
void updateFloatAction();
|
||||
void onDockWidgetShown();
|
||||
void onDockWidgetHidden();
|
||||
void show();
|
||||
void close();
|
||||
bool restoreToPreviousPosition();
|
||||
void maybeRestoreToPreviousPosition();
|
||||
int currentTabIndex() const;
|
||||
|
||||
/**
|
||||
* Before floating a dock widget we save its position. So it can be restored when calling
|
||||
* DockWidget::setFloating(false)
|
||||
*/
|
||||
void saveTabIndex();
|
||||
|
||||
const QString name;
|
||||
QStringList affinities;
|
||||
QString title;
|
||||
QIcon titleBarIcon;
|
||||
QIcon tabBarIcon;
|
||||
QWidgetOrQuick *widget = nullptr;
|
||||
DockWidgetBase *const q;
|
||||
DockWidgetBase::Options options;
|
||||
QAction *const toggleAction;
|
||||
QAction *const floatAction;
|
||||
LastPositions m_lastPositions;
|
||||
bool m_updatingToggleAction = false;
|
||||
bool m_updatingFloatAction = false;
|
||||
bool m_isForceClosing = false;
|
||||
QSize m_lastOverlayedSize = QSize(0, 0);
|
||||
};
|
||||
|
||||
DockWidgetBase::DockWidgetBase(const QString &name, Options options)
|
||||
DockWidgetBase::DockWidgetBase(const QString &name, Options options,
|
||||
LayoutSaverOptions layoutSaverOptions)
|
||||
: QWidgetAdapter(nullptr, Qt::Tool)
|
||||
, d(new Private(name, options, this))
|
||||
, d(new Private(name, options, layoutSaverOptions, this))
|
||||
{
|
||||
d->init();
|
||||
DockRegistry::self()->registerDockWidget(this);
|
||||
@@ -146,7 +52,6 @@ DockWidgetBase::DockWidgetBase(const QString &name, Options options)
|
||||
qWarning() << Q_FUNC_INFO << "Name can't be null";
|
||||
|
||||
setAttribute(Qt::WA_PendingMoveEvent, false);
|
||||
qApp->installEventFilter(this);
|
||||
}
|
||||
|
||||
DockWidgetBase::~DockWidgetBase()
|
||||
@@ -173,13 +78,12 @@ void DockWidgetBase::addDockWidgetAsTab(DockWidgetBase *other, InitialOption opt
|
||||
return;
|
||||
}
|
||||
|
||||
if ((other->options() & DockWidgetBase::Option_NotDockable) ||
|
||||
(options() & DockWidgetBase::Option_NotDockable)) {
|
||||
if ((other->options() & DockWidgetBase::Option_NotDockable) || (options() & DockWidgetBase::Option_NotDockable)) {
|
||||
qWarning() << Q_FUNC_INFO << "Refusing to dock non-dockable widget" << other;
|
||||
return;
|
||||
}
|
||||
|
||||
Frame *frame = this->frame();
|
||||
Frame *frame = d->frame();
|
||||
|
||||
if (frame) {
|
||||
if (frame->containsDockWidget(other)) {
|
||||
@@ -189,8 +93,8 @@ void DockWidgetBase::addDockWidgetAsTab(DockWidgetBase *other, InitialOption opt
|
||||
} else {
|
||||
if (isWindow()) {
|
||||
// Doesn't have a frame yet
|
||||
morphIntoFloatingWindow();
|
||||
frame = this->frame();
|
||||
d->morphIntoFloatingWindow();
|
||||
frame = d->frame();
|
||||
} else {
|
||||
// Doesn't happen
|
||||
qWarning() << Q_FUNC_INFO << "null frame";
|
||||
@@ -207,7 +111,7 @@ void DockWidgetBase::addDockWidgetToContainingWindow(DockWidgetBase *other,
|
||||
DockWidgetBase *relativeTo,
|
||||
InitialOption initialOption)
|
||||
{
|
||||
if (auto mainWindow = qobject_cast<MainWindowBase*>(window())) {
|
||||
if (auto mainWindow = qobject_cast<MainWindowBase *>(window())) {
|
||||
// It's inside a main window. Simply use the main window API.
|
||||
mainWindow->addDockWidget(other, location, relativeTo, initialOption);
|
||||
return;
|
||||
@@ -219,17 +123,16 @@ void DockWidgetBase::addDockWidgetToContainingWindow(DockWidgetBase *other,
|
||||
return;
|
||||
}
|
||||
|
||||
if ((other->options() & DockWidgetBase::Option_NotDockable) ||
|
||||
(options() & DockWidgetBase::Option_NotDockable)) {
|
||||
if ((other->options() & DockWidgetBase::Option_NotDockable) || (options() & DockWidgetBase::Option_NotDockable)) {
|
||||
qWarning() << Q_FUNC_INFO << "Refusing to dock non-dockable widget" << other;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWindow())
|
||||
morphIntoFloatingWindow();
|
||||
d->morphIntoFloatingWindow();
|
||||
|
||||
if (auto fw = floatingWindow()) {
|
||||
fw->dropArea()->addDockWidget(other, location, relativeTo, initialOption);
|
||||
fw->addDockWidget(other, location, relativeTo, initialOption);
|
||||
} else {
|
||||
qWarning() << Q_FUNC_INFO << "Couldn't find floating nested window";
|
||||
}
|
||||
@@ -237,7 +140,6 @@ void DockWidgetBase::addDockWidgetToContainingWindow(DockWidgetBase *other,
|
||||
|
||||
void DockWidgetBase::setWidget(QWidgetOrQuick *w)
|
||||
{
|
||||
Q_ASSERT(w);
|
||||
if (w == d->widget)
|
||||
return;
|
||||
|
||||
@@ -251,7 +153,6 @@ void DockWidgetBase::setWidget(QWidgetOrQuick *w)
|
||||
setSizePolicy(w->sizePolicy());
|
||||
|
||||
Q_EMIT widgetChanged(w);
|
||||
setWindowTitle(uniqueName());
|
||||
}
|
||||
|
||||
QWidgetOrQuick *DockWidgetBase::widget() const
|
||||
@@ -284,7 +185,7 @@ bool DockWidgetBase::setFloating(bool floats)
|
||||
if (floats) {
|
||||
d->saveTabIndex();
|
||||
if (isTabbed()) {
|
||||
auto frame = this->frame();
|
||||
auto frame = d->frame();
|
||||
if (!frame) {
|
||||
qWarning() << "DockWidget::setFloating: Tabbed but no frame exists"
|
||||
<< this;
|
||||
@@ -294,17 +195,17 @@ bool DockWidgetBase::setFloating(bool floats)
|
||||
|
||||
frame->detachTab(this);
|
||||
} else {
|
||||
frame()->titleBar()->makeWindow();
|
||||
d->frame()->titleBar()->makeWindow();
|
||||
}
|
||||
|
||||
auto lastGeo = lastPositions().lastFloatingGeometry();
|
||||
auto lastGeo = d->lastPositions().lastFloatingGeometry();
|
||||
if (lastGeo.isValid()) {
|
||||
if (auto fw = floatingWindow())
|
||||
fw->setSuggestedGeometry(lastGeo, /*preserveCenter=*/true);
|
||||
fw->setSuggestedGeometry(lastGeo, SuggestedGeometryHint_PreserveCenter);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
saveLastFloatingGeometry();
|
||||
d->saveLastFloatingGeometry();
|
||||
return d->restoreToPreviousPosition();
|
||||
}
|
||||
}
|
||||
@@ -338,11 +239,25 @@ void DockWidgetBase::setTitle(const QString &title)
|
||||
}
|
||||
}
|
||||
|
||||
QRect DockWidgetBase::frameGeometry() const
|
||||
{
|
||||
if (Frame *f = d->frame())
|
||||
return f->QWidgetAdapter::geometry();
|
||||
|
||||
// Means the dock widget isn't visible. Just fallback to its own geometry
|
||||
return QWidgetAdapter::geometry();
|
||||
}
|
||||
|
||||
DockWidgetBase::Options DockWidgetBase::options() const
|
||||
{
|
||||
return d->options;
|
||||
}
|
||||
|
||||
DockWidgetBase::LayoutSaverOptions DockWidgetBase::layoutSaverOptions() const
|
||||
{
|
||||
return d->layoutSaverOptions;
|
||||
}
|
||||
|
||||
void DockWidgetBase::setOptions(Options options)
|
||||
{
|
||||
if ((d->options & Option_NotDockable) != (options & Option_NotDockable)) {
|
||||
@@ -354,13 +269,13 @@ void DockWidgetBase::setOptions(Options options)
|
||||
d->options = options;
|
||||
Q_EMIT optionsChanged(options);
|
||||
if (auto tb = titleBar())
|
||||
tb->updateCloseButton();
|
||||
tb->updateButtons();
|
||||
}
|
||||
}
|
||||
|
||||
bool DockWidgetBase::isTabbed() const
|
||||
{
|
||||
if (Frame *frame = this->frame()) {
|
||||
if (Frame *frame = d->frame()) {
|
||||
return frame->alwaysShowsTabs() || frame->dockWidgetCount() > 1;
|
||||
} else {
|
||||
if (!isFloating())
|
||||
@@ -371,8 +286,8 @@ bool DockWidgetBase::isTabbed() const
|
||||
|
||||
bool DockWidgetBase::isCurrentTab() const
|
||||
{
|
||||
if (Frame *frame = this->frame()) {
|
||||
return frame->currentIndex() == frame->indexOfDockWidget(const_cast<DockWidgetBase*>(this));
|
||||
if (Frame *frame = d->frame()) {
|
||||
return frame->currentIndex() == frame->indexOfDockWidget(const_cast<DockWidgetBase *>(this));
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
@@ -380,10 +295,18 @@ bool DockWidgetBase::isCurrentTab() const
|
||||
|
||||
void DockWidgetBase::setAsCurrentTab()
|
||||
{
|
||||
if (Frame *frame = this->frame())
|
||||
if (Frame *frame = d->frame())
|
||||
frame->setCurrentDockWidget(this);
|
||||
}
|
||||
|
||||
int DockWidgetBase::tabIndex() const
|
||||
{
|
||||
if (Frame *frame = d->frame())
|
||||
return frame->indexOfDockWidget(this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DockWidgetBase::setIcon(const QIcon &icon, IconPlaces places)
|
||||
{
|
||||
if (places & IconPlace::TitleBar)
|
||||
@@ -414,13 +337,12 @@ QIcon DockWidgetBase::icon(IconPlace place) const
|
||||
|
||||
void DockWidgetBase::forceClose()
|
||||
{
|
||||
QScopedValueRollback<bool> rollback(d->m_isForceClosing, true);
|
||||
d->close();
|
||||
d->forceClose();
|
||||
}
|
||||
|
||||
TitleBar *DockWidgetBase::titleBar() const
|
||||
{
|
||||
if (Frame *f = frame())
|
||||
if (Frame *f = d->frame())
|
||||
return f->actualTitleBar();
|
||||
|
||||
return nullptr;
|
||||
@@ -441,7 +363,7 @@ void DockWidgetBase::show()
|
||||
if (isWindow() && (d->m_lastPositions.wasFloating() || !d->m_lastPositions.isValid())) {
|
||||
// Create the FloatingWindow already, instead of waiting for the show event.
|
||||
// This reduces flickering on some platforms
|
||||
morphIntoFloatingWindow();
|
||||
d->morphIntoFloatingWindow();
|
||||
} else {
|
||||
QWidgetOrQuick::show();
|
||||
}
|
||||
@@ -457,12 +379,15 @@ void DockWidgetBase::raise()
|
||||
if (auto fw = floatingWindow()) {
|
||||
fw->raise();
|
||||
fw->activateWindow();
|
||||
} else if (Frame *frame = d->frame()) {
|
||||
if (frame->isMDI())
|
||||
frame->raise();
|
||||
}
|
||||
}
|
||||
|
||||
bool DockWidgetBase::isMainWindow() const
|
||||
{
|
||||
return qobject_cast<MainWindowBase*>(widget());
|
||||
return qobject_cast<MainWindowBase *>(widget());
|
||||
}
|
||||
|
||||
bool DockWidgetBase::isInMainWindow() const
|
||||
@@ -470,14 +395,14 @@ bool DockWidgetBase::isInMainWindow() const
|
||||
return d->mainWindow() != nullptr;
|
||||
}
|
||||
|
||||
MainWindowBase* DockWidgetBase::mainWindow() const
|
||||
MainWindowBase *DockWidgetBase::mainWindow() const
|
||||
{
|
||||
return d->mainWindow();
|
||||
}
|
||||
|
||||
bool DockWidgetBase::isFocused() const
|
||||
{
|
||||
auto f = this->frame();
|
||||
auto f = d->frame();
|
||||
return f && f->isFocused() && isCurrentTab();
|
||||
}
|
||||
|
||||
@@ -523,6 +448,11 @@ SideBarLocation DockWidgetBase::sideBarLocation() const
|
||||
return DockRegistry::self()->sideBarLocationForDockWidget(this);
|
||||
}
|
||||
|
||||
bool DockWidgetBase::isInSideBar() const
|
||||
{
|
||||
return sideBarLocation() != SideBarLocation::None;
|
||||
}
|
||||
|
||||
bool DockWidgetBase::hasPreviousDockedLocation() const
|
||||
{
|
||||
return d->m_lastPositions.isValid();
|
||||
@@ -538,27 +468,43 @@ DockWidgetBase *DockWidgetBase::byName(const QString &uniqueName)
|
||||
return DockRegistry::self()->dockByName(uniqueName);
|
||||
}
|
||||
|
||||
FloatingWindow *DockWidgetBase::morphIntoFloatingWindow()
|
||||
bool DockWidgetBase::skipsRestore() const
|
||||
{
|
||||
return d->layoutSaverOptions & LayoutSaverOption::Skip;
|
||||
}
|
||||
|
||||
void DockWidgetBase::setFloatingGeometry(QRect geometry)
|
||||
{
|
||||
if (isOpen() && isFloating()) {
|
||||
window()->setGeometry(geometry);
|
||||
} else {
|
||||
d->m_lastPositions.setLastFloatingGeometry(geometry);
|
||||
}
|
||||
}
|
||||
|
||||
FloatingWindow *DockWidgetBase::Private::morphIntoFloatingWindow()
|
||||
{
|
||||
if (auto fw = floatingWindow())
|
||||
return fw; // Nothing to do
|
||||
|
||||
if (isWindow()) {
|
||||
QRect geo = d->m_lastPositions.lastFloatingGeometry();
|
||||
if (q->isWindow()) {
|
||||
QRect geo = m_lastPositions.lastFloatingGeometry();
|
||||
if (geo.isNull()) {
|
||||
geo = geometry();
|
||||
geo = q->geometry();
|
||||
|
||||
if (!testAttribute(Qt::WA_PendingMoveEvent)) { // If user already moved it, we don't interfere
|
||||
const QPoint center = d->defaultCenterPosForFloating();
|
||||
if (!q->testAttribute(Qt::WA_PendingMoveEvent)) { // If user already moved it, we don't
|
||||
// interfere
|
||||
const QPoint center = defaultCenterPosForFloating();
|
||||
if (!center.isNull())
|
||||
geo.moveCenter(center);
|
||||
}
|
||||
}
|
||||
|
||||
auto frame = Config::self().frameworkWidgetFactory()->createFrame();
|
||||
frame->addWidget(this);
|
||||
auto floatingWindow = Config::self().frameworkWidgetFactory()->createFloatingWindow(frame);
|
||||
floatingWindow->setSuggestedGeometry(geo);
|
||||
frame->addWidget(q);
|
||||
geo.setSize(geo.size().boundedTo(frame->maxSizeHint()));
|
||||
auto floatingWindow =
|
||||
Config::self().frameworkWidgetFactory()->createFloatingWindow(frame, nullptr, geo);
|
||||
floatingWindow->show();
|
||||
|
||||
return floatingWindow;
|
||||
@@ -567,60 +513,23 @@ FloatingWindow *DockWidgetBase::morphIntoFloatingWindow()
|
||||
}
|
||||
}
|
||||
|
||||
void DockWidgetBase::maybeMorphIntoFloatingWindow()
|
||||
void DockWidgetBase::Private::maybeMorphIntoFloatingWindow()
|
||||
{
|
||||
if (isWindow() && isVisible())
|
||||
if (q->isWindow() && q->isVisible())
|
||||
morphIntoFloatingWindow();
|
||||
}
|
||||
|
||||
Frame *DockWidgetBase::frame() const
|
||||
MDILayoutWidget *DockWidgetBase::Private::mdiLayout() const
|
||||
{
|
||||
QWidgetOrQuick *p = parentWidget();
|
||||
while (p) {
|
||||
if (auto frame = qobject_cast<Frame *>(p))
|
||||
return frame;
|
||||
p = p->parentWidget();
|
||||
}
|
||||
if (auto mw = mainWindow())
|
||||
return mw->mdiLayoutWidget();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FloatingWindow *DockWidgetBase::floatingWindow() const
|
||||
DockWidgetBase::Private *DockWidgetBase::dptr() const
|
||||
{
|
||||
return d->floatingWindow();
|
||||
}
|
||||
|
||||
void DockWidgetBase::addPlaceholderItem(Layouting::Item *item)
|
||||
{
|
||||
Q_ASSERT(item);
|
||||
d->m_lastPositions.addPosition(item);
|
||||
}
|
||||
|
||||
LastPositions& DockWidgetBase::lastPositions() const
|
||||
{
|
||||
return d->m_lastPositions;
|
||||
}
|
||||
|
||||
void DockWidgetBase::saveLastFloatingGeometry()
|
||||
{
|
||||
if (isFloating() && isVisible()) {
|
||||
// It's getting docked, save last floating position
|
||||
lastPositions().setLastFloatingGeometry(window()->geometry());
|
||||
}
|
||||
}
|
||||
|
||||
void DockWidgetBase::updateFloatAction()
|
||||
{
|
||||
d->updateFloatAction();
|
||||
}
|
||||
|
||||
bool DockWidgetBase::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
const bool isWindowActivate = event->type() == QEvent::WindowActivate;
|
||||
const bool isWindowDeactivate = event->type() == QEvent::WindowDeactivate;
|
||||
if ((isWindowActivate || isWindowDeactivate) && watched == window())
|
||||
Q_EMIT windowActiveAboutToChange(isWindowActivate);
|
||||
|
||||
return QWidgetAdapter::eventFilter(watched, event);
|
||||
return d;
|
||||
}
|
||||
|
||||
QPoint DockWidgetBase::Private::defaultCenterPosForFloating()
|
||||
@@ -634,21 +543,36 @@ QPoint DockWidgetBase::Private::defaultCenterPosForFloating()
|
||||
return mw->geometry().center();
|
||||
}
|
||||
|
||||
bool DockWidgetBase::Private::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
const bool isWindowActivate = event->type() == QEvent::WindowActivate;
|
||||
const bool isWindowDeactivate = event->type() == QEvent::WindowDeactivate;
|
||||
if ((isWindowActivate || isWindowDeactivate) && watched == q->window())
|
||||
Q_EMIT q->windowActiveAboutToChange(isWindowActivate);
|
||||
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void DockWidgetBase::Private::updateTitle()
|
||||
{
|
||||
if (q->isFloating())
|
||||
q->window()->setWindowTitle(title);
|
||||
|
||||
|
||||
toggleAction->setText(title);
|
||||
}
|
||||
|
||||
void DockWidgetBase::Private::toggle(bool enabled)
|
||||
{
|
||||
if (enabled) {
|
||||
show();
|
||||
if (SideBar *sb = sideBar()) {
|
||||
// The widget is in the sidebar, let's toggle its overlayed state
|
||||
sb->toggleOverlay(q);
|
||||
} else {
|
||||
q->close();
|
||||
// The most common case. The dock widget is not in the sidebar. just close or open it.
|
||||
if (enabled) {
|
||||
show();
|
||||
} else {
|
||||
q->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,9 +580,9 @@ void DockWidgetBase::Private::updateToggleAction()
|
||||
{
|
||||
QScopedValueRollback<bool> recursionGuard(m_updatingToggleAction, true); // Guard against recursiveness
|
||||
m_updatingToggleAction = true;
|
||||
if ((q->isVisible() || q->frame()) && !toggleAction->isChecked()) {
|
||||
if ((q->isVisible() || frame()) && !toggleAction->isChecked()) {
|
||||
toggleAction->setChecked(true);
|
||||
} else if ((!q->isVisible() && !q->frame()) && toggleAction->isChecked()) {
|
||||
} else if ((!q->isVisible() && !frame()) && toggleAction->isChecked()) {
|
||||
toggleAction->setChecked(false);
|
||||
}
|
||||
}
|
||||
@@ -692,22 +616,41 @@ void DockWidgetBase::Private::onDockWidgetHidden()
|
||||
|
||||
void DockWidgetBase::Private::close()
|
||||
{
|
||||
if (!m_isForceClosing && q->isFloating() && q->isVisible()) { // only user-closing is interesting to save the geometry
|
||||
// We check for isVisible so we don't save geometry if you call close() on an already closed dock widget
|
||||
if (!m_processingToggleAction && !q->isOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If it's overlayed and we're closing, we need to close the overlay
|
||||
if (SideBar *sb = DockRegistry::self()->sideBarForDockWidget(q)) {
|
||||
auto mainWindow = sb->mainWindow();
|
||||
if (mainWindow->overlayedDockWidget() == q) {
|
||||
mainWindow->clearSideBarOverlay(/* deleteFrame=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_isForceClosing && q->isFloating()
|
||||
&& q->isVisible()) { // only user-closing is interesting to save the geometry
|
||||
// We check for isVisible so we don't save geometry if you call close() on an already closed
|
||||
// dock widget
|
||||
m_lastPositions.setLastFloatingGeometry(q->window()->geometry());
|
||||
}
|
||||
|
||||
saveTabIndex();
|
||||
|
||||
// Do some cleaning. Widget is hidden, but we must hide the tab containing it.
|
||||
if (Frame *frame = q->frame()) {
|
||||
frame->removeWidget(q);
|
||||
if (Frame *frame = this->frame()) {
|
||||
q->setParent(nullptr);
|
||||
frame->removeWidget(q);
|
||||
|
||||
if (SideBar *sb = DockRegistry::self()->sideBarForDockWidget(q)) {
|
||||
sb->removeDockWidget(q);
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_isMovingToSideBar && (options & DockWidgetBase::Option_DeleteOnClose)) {
|
||||
Q_EMIT q->aboutToDeleteOnClose();
|
||||
q->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
bool DockWidgetBase::Private::restoreToPreviousPosition()
|
||||
@@ -717,7 +660,7 @@ bool DockWidgetBase::Private::restoreToPreviousPosition()
|
||||
|
||||
Layouting::Item *item = m_lastPositions.lastItem();
|
||||
|
||||
MultiSplitter *layout = DockRegistry::self()->layoutForItem(item);
|
||||
LayoutWidget *layout = DockRegistry::self()->layoutForItem(item);
|
||||
Q_ASSERT(layout);
|
||||
layout->restorePlaceholder(q, item, m_lastPositions.lastTabIndex());
|
||||
return true;
|
||||
@@ -737,7 +680,7 @@ void DockWidgetBase::Private::maybeRestoreToPreviousPosition()
|
||||
if (m_lastPositions.wasFloating())
|
||||
return; // Nothing to do, it was floating before, now it'll just get visible
|
||||
|
||||
Frame *frame = q->frame();
|
||||
Frame *frame = this->frame();
|
||||
|
||||
if (frame && frame->QWidgetAdapter::parentWidget() == DockRegistry::self()->layoutForItem(layoutItem)) {
|
||||
// There's a frame already. Means the DockWidget was hidden instead of closed.
|
||||
@@ -758,7 +701,7 @@ void DockWidgetBase::Private::maybeRestoreToPreviousPosition()
|
||||
|
||||
int DockWidgetBase::Private::currentTabIndex() const
|
||||
{
|
||||
Frame *frame = q->frame();
|
||||
Frame *frame = this->frame();
|
||||
return frame ? frame->indexOfDockWidget(q) : 0;
|
||||
}
|
||||
|
||||
@@ -783,6 +726,8 @@ void DockWidgetBase::onParentChanged()
|
||||
#endif
|
||||
d->updateToggleAction();
|
||||
d->updateFloatAction();
|
||||
|
||||
Q_EMIT actualTitleBarChanged();
|
||||
}
|
||||
|
||||
void DockWidgetBase::onShown(bool spontaneous)
|
||||
@@ -790,7 +735,7 @@ void DockWidgetBase::onShown(bool spontaneous)
|
||||
d->onDockWidgetShown();
|
||||
Q_EMIT shown();
|
||||
|
||||
if (Frame *f = frame()) {
|
||||
if (Frame *f = d->frame()) {
|
||||
if (!spontaneous) {
|
||||
f->onDockWidgetShown(this);
|
||||
}
|
||||
@@ -799,7 +744,7 @@ void DockWidgetBase::onShown(bool spontaneous)
|
||||
d->maybeRestoreToPreviousPosition();
|
||||
|
||||
// Transform into a FloatingWindow if this will be a regular floating dock widget.
|
||||
QTimer::singleShot(0, this, &DockWidgetBase::maybeMorphIntoFloatingWindow);
|
||||
QTimer::singleShot(0, d, &DockWidgetBase::Private::maybeMorphIntoFloatingWindow);
|
||||
}
|
||||
|
||||
void DockWidgetBase::onHidden(bool spontaneous)
|
||||
@@ -807,7 +752,7 @@ void DockWidgetBase::onHidden(bool spontaneous)
|
||||
d->onDockWidgetHidden();
|
||||
Q_EMIT hidden();
|
||||
|
||||
if (Frame *f = frame()) {
|
||||
if (Frame *f = d->frame()) {
|
||||
if (!spontaneous) {
|
||||
f->onDockWidgetHidden(this);
|
||||
}
|
||||
@@ -817,7 +762,7 @@ void DockWidgetBase::onHidden(bool spontaneous)
|
||||
bool DockWidgetBase::onResize(QSize newSize)
|
||||
{
|
||||
if (isOverlayed()) {
|
||||
if (auto frame = this->frame()) {
|
||||
if (auto frame = d->frame()) {
|
||||
d->m_lastOverlayedSize = frame->QWidgetAdapter::size();
|
||||
} else {
|
||||
qWarning() << Q_FUNC_INFO << "Overlayed dock widget without frame shouldn't happen";
|
||||
@@ -831,7 +776,7 @@ void DockWidgetBase::onCloseEvent(QCloseEvent *e)
|
||||
{
|
||||
e->accept(); // By default we accept, means DockWidget closes
|
||||
if (d->widget)
|
||||
qApp->sendEvent(d->widget, e); // Give a chancefor the widget to ignore
|
||||
qApp->sendEvent(d->widget, e); // Give a chance for the widget to ignore
|
||||
|
||||
if (e->isAccepted())
|
||||
d->close();
|
||||
@@ -839,14 +784,8 @@ void DockWidgetBase::onCloseEvent(QCloseEvent *e)
|
||||
|
||||
DockWidgetBase *DockWidgetBase::deserialize(const LayoutSaver::DockWidget::Ptr &saved)
|
||||
{
|
||||
DockWidgetBase *dw = DockRegistry::self()->dockByName(saved->uniqueName);
|
||||
if (!dw) {
|
||||
if (auto factoryFunc = Config::self().dockWidgetFactoryFunc()) {
|
||||
// DockWidget doesn't exist, ask to create it
|
||||
dw = factoryFunc(saved->uniqueName);
|
||||
}
|
||||
}
|
||||
|
||||
auto dr = DockRegistry::self();
|
||||
DockWidgetBase *dw = dr->dockByName(saved->uniqueName, DockRegistry::DockByNameFlag::CreateIfNotFound);
|
||||
if (dw) {
|
||||
if (QWidgetOrQuick *w = dw->widget())
|
||||
w->setVisible(true);
|
||||
@@ -857,18 +796,132 @@ DockWidgetBase *DockWidgetBase::deserialize(const LayoutSaver::DockWidget::Ptr &
|
||||
<< "; to" << saved->affinities;
|
||||
dw->d->affinities = saved->affinities;
|
||||
}
|
||||
|
||||
} else {
|
||||
qWarning() << Q_FUNC_INFO << "Couldn't find dock widget" << saved->uniqueName;
|
||||
}
|
||||
|
||||
return dw;
|
||||
}
|
||||
|
||||
LayoutSaver::DockWidget::Ptr DockWidgetBase::serialize() const
|
||||
void DockWidgetBase::setUserType(int userType)
|
||||
{
|
||||
auto ptr = LayoutSaver::DockWidget::dockWidgetForName(uniqueName());
|
||||
ptr->affinities = affinities();
|
||||
d->m_userType = userType;
|
||||
}
|
||||
|
||||
int DockWidgetBase::userType() const
|
||||
{
|
||||
return d->m_userType;
|
||||
}
|
||||
|
||||
void DockWidgetBase::setMDIPosition(QPoint pos)
|
||||
{
|
||||
if (MDILayoutWidget *layout = d->mdiLayout())
|
||||
layout->moveDockWidget(this, pos);
|
||||
}
|
||||
|
||||
void DockWidgetBase::setMDISize(QSize size)
|
||||
{
|
||||
if (MDILayoutWidget *layout = d->mdiLayout())
|
||||
layout->resizeDockWidget(this, size);
|
||||
}
|
||||
|
||||
void DockWidgetBase::setMDIZ(int z)
|
||||
{
|
||||
#ifdef KDDOCKWIDGETS_QTQUICK
|
||||
if (Frame *frame = d->frame()) {
|
||||
if (!frame->isMDI())
|
||||
return;
|
||||
frame->setZ(z);
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(z);
|
||||
qWarning() << Q_FUNC_INFO << "Not implemented for QtQuick";
|
||||
#endif
|
||||
}
|
||||
|
||||
LayoutSaver::DockWidget::Ptr DockWidgetBase::Private::serialize() const
|
||||
{
|
||||
auto ptr = LayoutSaver::DockWidget::dockWidgetForName(q->uniqueName());
|
||||
ptr->affinities = q->affinities();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void DockWidgetBase::Private::forceClose()
|
||||
{
|
||||
QScopedValueRollback<bool> rollback(m_isForceClosing, true);
|
||||
close();
|
||||
}
|
||||
|
||||
DockWidgetBase::Private::Private(const QString &dockName, DockWidgetBase::Options options_,
|
||||
LayoutSaverOptions layoutSaverOptions_, DockWidgetBase *qq)
|
||||
|
||||
: name(dockName)
|
||||
, title(dockName)
|
||||
, q(qq)
|
||||
, options(options_)
|
||||
, layoutSaverOptions(layoutSaverOptions_)
|
||||
, toggleAction(new QAction(q))
|
||||
, floatAction(new QAction(q))
|
||||
{
|
||||
q->connect(toggleAction, &QAction::toggled, q, [this](bool enabled) {
|
||||
if (!m_updatingToggleAction) { // guard against recursiveness
|
||||
toggleAction->blockSignals(true); // and don't emit spurious toggle. Like when a dock
|
||||
// widget is inserted into a tab widget it might get
|
||||
// hide events, ignore those. The Dock Widget is open.
|
||||
m_processingToggleAction = true;
|
||||
toggle(enabled);
|
||||
toggleAction->blockSignals(false);
|
||||
m_processingToggleAction = false;
|
||||
}
|
||||
});
|
||||
|
||||
q->connect(floatAction, &QAction::toggled, q, [this](bool checked) {
|
||||
if (!m_updatingFloatAction) { // guard against recursiveness
|
||||
q->setFloating(checked);
|
||||
}
|
||||
|
||||
Q_EMIT q->isFloatingChanged(checked);
|
||||
|
||||
// When floating, we remove from the sidebar
|
||||
if (checked && q->isOpen()) {
|
||||
if (SideBar *sb = DockRegistry::self()->sideBarForDockWidget(q)) {
|
||||
sb->mainWindow()->clearSideBarOverlay(/* deleteFrame=*/false);
|
||||
sb->removeDockWidget(q);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
toggleAction->setCheckable(true);
|
||||
floatAction->setCheckable(true);
|
||||
|
||||
qApp->installEventFilter(this);
|
||||
}
|
||||
|
||||
void DockWidgetBase::Private::addPlaceholderItem(Layouting::Item *item)
|
||||
{
|
||||
Q_ASSERT(item);
|
||||
m_lastPositions.addPosition(item);
|
||||
}
|
||||
|
||||
LastPositions &DockWidgetBase::Private::lastPositions()
|
||||
{
|
||||
return m_lastPositions;
|
||||
}
|
||||
|
||||
Frame *DockWidgetBase::Private::frame() const
|
||||
{
|
||||
QWidgetOrQuick *p = q->parentWidget();
|
||||
while (p) {
|
||||
if (auto frame = qobject_cast<Frame *>(p))
|
||||
return frame;
|
||||
p = p->parentWidget();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DockWidgetBase::Private::saveLastFloatingGeometry()
|
||||
{
|
||||
if (q->isFloating() && q->isVisible()) {
|
||||
// It's getting docked, save last floating position
|
||||
lastPositions().setLastFloatingGeometry(q->window()->geometry());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,25 +22,17 @@
|
||||
#include "docks_export.h"
|
||||
#include "KDDockWidgets.h"
|
||||
#include "QWidgetAdapter.h"
|
||||
#include "LayoutSaver_p.h"
|
||||
#include "LayoutSaver.h"
|
||||
|
||||
#include <QVector>
|
||||
#include <memory>
|
||||
|
||||
// clazy:excludeall=ctor-missing-parent-argument
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class TestDocks;
|
||||
|
||||
namespace Layouting {
|
||||
class Item;
|
||||
}
|
||||
|
||||
namespace KDDockWidgets {
|
||||
|
||||
struct LastPositions;
|
||||
class Frame;
|
||||
class FloatingWindow;
|
||||
class DragController;
|
||||
@@ -51,6 +43,8 @@ class TitleBar;
|
||||
class MainWindowBase;
|
||||
class StateDragging;
|
||||
class FrameQuick;
|
||||
class DockWidgetQuick;
|
||||
class LayoutWidget;
|
||||
|
||||
/**
|
||||
* @brief The DockWidget base-class. DockWidget and DockWidgetBase are only
|
||||
@@ -68,18 +62,35 @@ class DOCKS_EXPORT DockWidgetBase : public QWidget
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool isFocused READ isFocused NOTIFY isFocusedChanged)
|
||||
Q_PROPERTY(bool isFloating READ isFloating WRITE setFloating NOTIFY isFloatingChanged)
|
||||
Q_PROPERTY(QString uniqueName READ uniqueName CONSTANT)
|
||||
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
|
||||
Q_PROPERTY(QObject *widget READ widget NOTIFY widgetChanged)
|
||||
Q_PROPERTY(KDDockWidgets::DockWidgetBase::Options options READ options WRITE setOptions NOTIFY
|
||||
optionsChanged)
|
||||
public:
|
||||
typedef QVector<DockWidgetBase *> List;
|
||||
|
||||
///@brief DockWidget options to pass at construction time
|
||||
enum Option {
|
||||
enum Option
|
||||
{
|
||||
Option_None = 0, ///< No option, the default
|
||||
Option_NotClosable = 1, ///< The DockWidget can't be closed on the [x], only programatically
|
||||
Option_NotDockable = 2 ///< The DockWidget can't be docked, it's always floating
|
||||
Option_NotClosable = 1, ///< The DockWidget can't be closed on the [x], only programmatically
|
||||
Option_NotDockable = 2, ///< The DockWidget can't be docked, it's always floating
|
||||
Option_DeleteOnClose = 4 ///< Deletes the DockWidget when closed
|
||||
};
|
||||
Q_DECLARE_FLAGS(Options, Option)
|
||||
Q_ENUM(Options);
|
||||
|
||||
enum class IconPlace {
|
||||
/// @brief Options which will affect LayoutSaver save/restore
|
||||
enum class LayoutSaverOption
|
||||
{
|
||||
None = 0, ///< Just use the defaults
|
||||
Skip = 1, ///< The dock widget won't participate in save/restore. Currently only available for floating windows.
|
||||
};
|
||||
Q_DECLARE_FLAGS(LayoutSaverOptions, LayoutSaverOption)
|
||||
|
||||
enum class IconPlace
|
||||
{
|
||||
TitleBar = 1,
|
||||
TabBar = 2,
|
||||
ToggleAction = 4,
|
||||
@@ -91,12 +102,15 @@ public:
|
||||
/**
|
||||
* @brief constructs a new DockWidget
|
||||
* @param uniqueName the name of the dockwidget, should be unique. Use title for user visible text.
|
||||
* @param options optional options controlling behaviour
|
||||
* @param options the options controlling certain behaviours
|
||||
* @param layoutSaverOptions the options to control save/restore
|
||||
*
|
||||
* There's no parent argument. The DockWidget is either parented to FloatingWindow or MainWindow
|
||||
* when visible, or stays without a parent when hidden.
|
||||
*/
|
||||
explicit DockWidgetBase(const QString &uniqueName, Options options = DockWidgetBase::Options());
|
||||
explicit DockWidgetBase(const QString &uniqueName,
|
||||
Options options = KDDockWidgets::DockWidgetBase::Options(),
|
||||
LayoutSaverOptions layoutSaverOptions = KDDockWidgets::DockWidgetBase::LayoutSaverOptions());
|
||||
|
||||
///@brief destructor
|
||||
~DockWidgetBase() override;
|
||||
@@ -109,7 +123,8 @@ public:
|
||||
* shown.
|
||||
* @sa MainWindow::addDockWidget(), DockWidget::addDockWidgetToContainingWindow()
|
||||
*/
|
||||
void addDockWidgetAsTab(DockWidgetBase *other, InitialOption initialOption = {});
|
||||
Q_INVOKABLE void addDockWidgetAsTab(KDDockWidgets::DockWidgetBase *other,
|
||||
KDDockWidgets::InitialOption initialOption = {});
|
||||
|
||||
/**
|
||||
* @brief docks @p other widget into the window that contains this one.
|
||||
@@ -123,9 +138,11 @@ public:
|
||||
* @param initialOption Allows to specify some extra options that are used while docking.
|
||||
* @sa MainWindow::addDockWidget(), DockWidget::addDockWidgetAsTab()
|
||||
*/
|
||||
void addDockWidgetToContainingWindow(DockWidgetBase *other, KDDockWidgets::Location location,
|
||||
DockWidgetBase *relativeTo = nullptr,
|
||||
InitialOption initialOption = {});
|
||||
Q_INVOKABLE void
|
||||
addDockWidgetToContainingWindow(KDDockWidgets::DockWidgetBase *other,
|
||||
KDDockWidgets::Location location,
|
||||
KDDockWidgets::DockWidgetBase *relativeTo = nullptr,
|
||||
KDDockWidgets::InitialOption initialOption = {});
|
||||
|
||||
/**
|
||||
* @brief sets the widget which this dock widget hosts.
|
||||
@@ -164,13 +181,13 @@ public:
|
||||
* @brief Returns the QAction that allows to hide/show the dock widget
|
||||
* Useful to put in menus.
|
||||
*/
|
||||
QAction *toggleAction() const;
|
||||
Q_INVOKABLE QAction *toggleAction() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the QAction that allows to dock/undock the dock widget
|
||||
* Useful to put in menus.
|
||||
*/
|
||||
QAction *floatAction() const;
|
||||
Q_INVOKABLE QAction *floatAction() const;
|
||||
|
||||
/**
|
||||
* @brief the dock widget's unique name.
|
||||
@@ -192,12 +209,28 @@ public:
|
||||
*/
|
||||
void setTitle(const QString &title);
|
||||
|
||||
/**
|
||||
* @brief Returns the size of the dock widget's parent frame.
|
||||
*
|
||||
* This will always be bigger than the DockWidget's size, as there's margins and a title bar.
|
||||
* Also, a frame can contain more than 1 dock widget (tabbed), meaning the geometry will account
|
||||
* for the tab bar and title bar.
|
||||
*
|
||||
* The position of the rect is in layout coordinates. 0,0 is the top-left of the layout
|
||||
* holding the widgets.
|
||||
*/
|
||||
QRect frameGeometry() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the dock widget's options which control behaviour.
|
||||
* @sa setOptions(), optionsChanged()
|
||||
*/
|
||||
Options options() const;
|
||||
|
||||
/// @brief returns the per-dockwidget options which will affect LayoutSaver
|
||||
/// These are the options which were passed to the constructor
|
||||
KDDockWidgets::DockWidgetBase::LayoutSaverOptions layoutSaverOptions() const;
|
||||
|
||||
/**
|
||||
* @brief Setter for the options.
|
||||
* Only Option_NotClosable is allowed to change after construction. For the other options use
|
||||
@@ -210,7 +243,7 @@ public:
|
||||
/**
|
||||
* @brief returns if this dock widget is tabbed into another
|
||||
*
|
||||
* Technically a docked DockWidget always lives in a tab widget, but from the user's prespective
|
||||
* Technically a docked DockWidget always lives in a tab widget, but from the user's perspective
|
||||
* it's not tabbed when there's only 1 dock widget, as there are no tabs displayed. Unless
|
||||
* the frame is using Option_AlwaysShowsTabs, in which case this method will return true regardless
|
||||
* if being the single one.
|
||||
@@ -228,7 +261,13 @@ public:
|
||||
/**
|
||||
* @brief Makes this dock widget current in its tab group.
|
||||
*/
|
||||
void setAsCurrentTab();
|
||||
Q_INVOKABLE void setAsCurrentTab();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns which tab index this dock widget occupies in the tab widget it's contained in
|
||||
*/
|
||||
int tabIndex() const;
|
||||
|
||||
/**
|
||||
* @brief Sets an icon to show on title bars and tab bars.
|
||||
@@ -267,7 +306,7 @@ public:
|
||||
* @brief Returns whether this dock widget is open.
|
||||
* Equivalent to calling toggleAction().isChecked() or isVisible()
|
||||
*/
|
||||
bool isOpen() const;
|
||||
Q_INVOKABLE bool isOpen() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the affinity names. Dock widgets can only dock into dock widgets of the same affinity.
|
||||
@@ -322,7 +361,7 @@ public:
|
||||
bool isMainWindow() const;
|
||||
|
||||
/**
|
||||
* @brief Returns whether this dock widget is docked into a main window.
|
||||
* @brief Returns whether this dock widget is docked into a main window (as opposed to floating)
|
||||
*
|
||||
* Note that isFloating() returning false might either mean the dock widget is docked into a
|
||||
* main window or into a floating window (groupped/nested with other dock widgets. Use this function
|
||||
@@ -331,6 +370,7 @@ public:
|
||||
bool isInMainWindow() const;
|
||||
|
||||
/// @brief Returns the main window this dock widget is in. nullptr if it's not inside a main window
|
||||
/// Also returns nullptr if it's minimized to a sidebar
|
||||
MainWindowBase *mainWindow() const;
|
||||
|
||||
///@brief Returns whether This or any child of this dock widget is focused
|
||||
@@ -348,17 +388,24 @@ public:
|
||||
* The dockwidget will initially be visible and overlayed on top of the current layout (this is
|
||||
* the auto-hide feature).
|
||||
*/
|
||||
void moveToSideBar();
|
||||
Q_INVOKABLE void moveToSideBar();
|
||||
|
||||
/// @brief Returns whether this dock widget is overlayed on top of the main window, instead of
|
||||
/// docked into the layout. This is only relevant when using the auto-hide and side-bar feature.
|
||||
/// @brief Returns whether this dock widget is overlayed from the side-bar.
|
||||
///
|
||||
/// This is only relevant when using the auto-hide and side-bar feature.
|
||||
/// Not to be confused with "floating", which means top-level window.
|
||||
bool isOverlayed() const;
|
||||
|
||||
///@brief Returns whether this dock widget is in a side bar, and which.
|
||||
/// SideBarLocation::None is returned if it's not in a sidebar.
|
||||
/// This is only relevant when using the auto-hide and side-bar feature.
|
||||
/// @sa isInSideBar
|
||||
SideBarLocation sideBarLocation() const;
|
||||
|
||||
/// @brief Returns where this dockwidget is in a sidebar
|
||||
/// Similar to sideBarLocation(), but returns a bool
|
||||
bool isInSideBar() const;
|
||||
|
||||
/// @brief Returns whether this floating dock widget knows its previous docked location
|
||||
/// Result only makes sense if it's floating.
|
||||
///
|
||||
@@ -373,7 +420,35 @@ public:
|
||||
/// @brief Returns a dock widget by its name
|
||||
/// This is the same name you passed to DockWidget CTOR.
|
||||
/// nullptr is returned if the dock widget isn't found.
|
||||
static DockWidgetBase* byName(const QString &uniqueName);
|
||||
static DockWidgetBase *byName(const QString &uniqueName);
|
||||
|
||||
/// @brief Returns whether this widget has the LayoutSaverOption::Skip flag
|
||||
bool skipsRestore() const;
|
||||
|
||||
/// @brief If this dock widget is floating, then sets its geometry to @p geo.
|
||||
///
|
||||
/// If this dock widget is hidden then it stores the geometry so it can be used the next
|
||||
/// time it becomes floating.
|
||||
///
|
||||
/// This is just convenience, equivalent to calling window()->setGeometry(rect), with the
|
||||
/// added bonus of remembering the requested geometry in case it's still hidden.
|
||||
void setFloatingGeometry(QRect geo);
|
||||
|
||||
///@brief Allows the user to set a type on this dock widget
|
||||
///The type is opaque and will not be interpreted by KDDockWidgets.
|
||||
///This type is passed to FrameWorkWidgetFactory::createTitleBar(), which the user can override
|
||||
///and return different TitleBar subclasses, depending on the type.
|
||||
void setUserType(int userType);
|
||||
int userType() const;
|
||||
|
||||
/// @brief Sets this dock widgets position to pos within the MDI layout
|
||||
/// This only applies if the main window is in MDI mode, which it is not by default
|
||||
void setMDIPosition(QPoint pos);
|
||||
/// @brief like setMDIPosition(), but for the size.
|
||||
void setMDISize(QSize size);
|
||||
/// @brief like setMDIPosition(), but for the Z
|
||||
/// only implemented for QtQuick
|
||||
void setMDIZ(int z);
|
||||
|
||||
Q_SIGNALS:
|
||||
#ifdef KDDOCKWIDGETS_QTWIDGETS
|
||||
@@ -424,6 +499,12 @@ Q_SIGNALS:
|
||||
/// have it's 'activeWindow' property updated yet at this point.
|
||||
void windowActiveAboutToChange(bool activated);
|
||||
|
||||
///@brief Emitted when the title bar that serves this dock widget changes
|
||||
void actualTitleBarChanged();
|
||||
|
||||
/// @brief Emitted when this dock widget is about to be deleted due to Option_DeleteOnClose
|
||||
void aboutToDeleteOnClose();
|
||||
|
||||
protected:
|
||||
void onParentChanged();
|
||||
void onShown(bool spontaneous);
|
||||
@@ -434,21 +515,6 @@ protected:
|
||||
bool onResize(QSize newSize) override;
|
||||
#endif
|
||||
|
||||
#if defined(DOCKS_DEVELOPER_MODE)
|
||||
public Q_SLOTS:
|
||||
#else
|
||||
private Q_SLOTS:
|
||||
#endif
|
||||
/**
|
||||
* @brief Creates a FloatingWindow and adds itself into it
|
||||
* @return the created FloatingWindow
|
||||
*/
|
||||
KDDockWidgets::FloatingWindow *morphIntoFloatingWindow();
|
||||
|
||||
/// @brief calls morphIntoFloatingWindow() if the dock widget is visible and is a top-level
|
||||
/// This is called delayed whenever we show a floating dock widget, so we get a FloatingWindow
|
||||
void maybeMorphIntoFloatingWindow();
|
||||
|
||||
#if defined(DOCKS_DEVELOPER_MODE)
|
||||
public:
|
||||
#else
|
||||
@@ -456,6 +522,8 @@ private:
|
||||
#endif
|
||||
Q_DISABLE_COPY(DockWidgetBase)
|
||||
friend class MultiSplitter;
|
||||
friend class LayoutWidget;
|
||||
friend class MDILayoutWidget;
|
||||
friend class Frame;
|
||||
friend class DropArea;
|
||||
friend class ::TestDocks;
|
||||
@@ -467,125 +535,22 @@ private:
|
||||
friend class KDDockWidgets::LayoutSaver;
|
||||
friend class KDDockWidgets::MainWindowBase;
|
||||
friend class KDDockWidgets::FrameQuick;
|
||||
friend class KDDockWidgets::DockWidgetQuick;
|
||||
|
||||
/**
|
||||
* @brief Constructs a dock widget from its serialized form.
|
||||
* @internal
|
||||
*/
|
||||
static DockWidgetBase *deserialize(const LayoutSaver::DockWidget::Ptr &);
|
||||
static DockWidgetBase *deserialize(const std::shared_ptr<LayoutSaver::DockWidget> &);
|
||||
|
||||
/**
|
||||
* @brief Serializes this dock widget into an intermediate form
|
||||
*/
|
||||
LayoutSaver::DockWidget::Ptr serialize() const;
|
||||
|
||||
/**
|
||||
* @brief the Frame which contains this dock widgets.
|
||||
*
|
||||
* A frame wraps a docked DockWidget, giving it a TabWidget so it can accept other dock widgets.
|
||||
* Frame is also the actual class that goes into a MultiSplitter.
|
||||
*
|
||||
* It's nullptr immediately after creation.
|
||||
*/
|
||||
Frame *frame() const;
|
||||
|
||||
/**
|
||||
* @brief returns the FloatingWindow this dock widget is in. If nullptr then it's in a MainWindow.
|
||||
*
|
||||
* Note: Being in a FloatingWindow doesn't necessarily mean @ref isFloating() returns true, as
|
||||
* the dock widget might be in a floating window with other dock widgets side by side.
|
||||
*/
|
||||
FloatingWindow *floatingWindow() const;
|
||||
|
||||
///@brief adds the current layout item containing this dock widget
|
||||
void addPlaceholderItem(Layouting::Item*);
|
||||
|
||||
///@brief returns the last position, just for tests. TODO Make tests just use the d-pointer.
|
||||
LastPositions &lastPositions() const;
|
||||
|
||||
///@brief If this dock widget is floating, then it saves its geometry
|
||||
void saveLastFloatingGeometry();
|
||||
|
||||
///@brief Updates the floatAction state
|
||||
void updateFloatAction();
|
||||
|
||||
///@reimp
|
||||
bool eventFilter(QObject *, QEvent *) override;
|
||||
|
||||
class Private;
|
||||
Private *const d;
|
||||
|
||||
Private *dptr() const;
|
||||
};
|
||||
|
||||
}
|
||||
Q_DECLARE_METATYPE(KDDockWidgets::Location)
|
||||
|
||||
#if defined(QT_WIDGETS_LIB)
|
||||
# include <QAction>
|
||||
#else
|
||||
// A QAction for QtQuick. Just so it compiles, for now
|
||||
class QAction : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QObject::QObject;
|
||||
|
||||
bool isChecked() const {
|
||||
return m_isChecked ;
|
||||
}
|
||||
|
||||
void setCheckable(bool is) {
|
||||
m_isCheckable = is;
|
||||
}
|
||||
|
||||
void setText(const QString &text) {
|
||||
m_text = text;
|
||||
}
|
||||
|
||||
void setToolTip(const QString &text) {
|
||||
m_toolTip = text;
|
||||
}
|
||||
|
||||
QString toolTip() const {
|
||||
returm m_toolTip;
|
||||
}
|
||||
|
||||
bool enabled() const {
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void setEnabled(bool enabled) {
|
||||
m_enabled = enabled;
|
||||
}
|
||||
|
||||
bool checked() const {
|
||||
return m_checked;
|
||||
}
|
||||
|
||||
void setChecked(bool checked) {
|
||||
m_checked = checked;
|
||||
}
|
||||
|
||||
bool isEnabled() const {
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void toggle() {
|
||||
m_enabled = !m_enabled;
|
||||
Q_EMIT toggled(m_enabled);
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
bool toggled(bool);
|
||||
private:
|
||||
QString m_text;
|
||||
QString m_toolTip;
|
||||
|
||||
bool m_isChecked = false;
|
||||
bool m_isCheckable = false;
|
||||
bool m_enabled = false;
|
||||
bool m_checked = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
*/
|
||||
|
||||
#include "DockWidgetQuick.h"
|
||||
#include "FrameworkWidgetFactory.h"
|
||||
|
||||
#include "private/TitleBar_p.h"
|
||||
#include "private/DockWidgetBase_p.h"
|
||||
#include "private/quick/FrameQuick_p.h"
|
||||
|
||||
#include <Config.h>
|
||||
#include <QQuickItem>
|
||||
@@ -27,9 +32,11 @@ using namespace KDDockWidgets;
|
||||
class DockWidgetQuick::Private
|
||||
{
|
||||
public:
|
||||
Private(DockWidgetQuick *dw)
|
||||
Private(DockWidgetQuick *dw, QQmlEngine *qmlengine)
|
||||
: q(dw)
|
||||
, m_visualItem(q->createItem(Config::self().qmlEngine(), QStringLiteral("qrc:/kddockwidgets/private/quick/qml/DockWidget.qml")))
|
||||
, m_visualItem(q->createItem(qmlengine,
|
||||
Config::self().frameworkWidgetFactory()->dockwidgetFilename().toString()))
|
||||
, m_qmlEngine(qmlengine)
|
||||
{
|
||||
Q_ASSERT(m_visualItem);
|
||||
m_visualItem->setParent(q);
|
||||
@@ -38,11 +45,13 @@ public:
|
||||
|
||||
DockWidgetBase *const q;
|
||||
QQuickItem *const m_visualItem;
|
||||
QQmlEngine *const m_qmlEngine;
|
||||
};
|
||||
|
||||
DockWidgetQuick::DockWidgetQuick(const QString &name, Options options)
|
||||
: DockWidgetBase(name, options)
|
||||
, d(new Private(this))
|
||||
DockWidgetQuick::DockWidgetQuick(const QString &name, Options options,
|
||||
LayoutSaverOptions layoutSaverOptions, QQmlEngine *engine)
|
||||
: DockWidgetBase(name, options, layoutSaverOptions)
|
||||
, d(new Private(this, engine ? engine : Config::self().qmlEngine()))
|
||||
{
|
||||
// To mimic what QtWidgets does when creating a new QWidget.
|
||||
setVisible(false);
|
||||
@@ -55,15 +64,11 @@ DockWidgetQuick::~DockWidgetQuick()
|
||||
|
||||
void DockWidgetQuick::setWidget(const QString &qmlFilename)
|
||||
{
|
||||
QQuickItem *guest = createItem(Config::self().qmlEngine(), qmlFilename);
|
||||
QQuickItem *guest = createItem(d->m_qmlEngine, qmlFilename);
|
||||
if (!guest)
|
||||
return;
|
||||
|
||||
auto adapter = new QWidgetAdapter(this);
|
||||
guest->setParentItem(adapter);
|
||||
guest->setParent(adapter);
|
||||
|
||||
setWidget(adapter);
|
||||
setWidget(guest);
|
||||
}
|
||||
|
||||
void DockWidgetQuick::setWidget(QWidgetAdapter *widget)
|
||||
@@ -73,16 +78,33 @@ void DockWidgetQuick::setWidget(QWidgetAdapter *widget)
|
||||
DockWidgetBase::setWidget(widget);
|
||||
}
|
||||
|
||||
void DockWidgetQuick::setWidget(QQuickItem *guest)
|
||||
{
|
||||
auto adapter = new QWidgetAdapter(this);
|
||||
adapter->setIsWrapper();
|
||||
|
||||
// In case the user app needs to use them:
|
||||
adapter->setProperty("originalParent", QVariant::fromValue(guest->parent()));
|
||||
adapter->setProperty("originalParentItem", QVariant::fromValue(guest->parentItem()));
|
||||
|
||||
guest->setParentItem(adapter);
|
||||
guest->setParent(adapter);
|
||||
QWidgetAdapter::makeItemFillParent(guest);
|
||||
|
||||
setWidget(adapter);
|
||||
}
|
||||
|
||||
bool DockWidgetQuick::event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::ParentChange) {
|
||||
onParentChanged();
|
||||
Q_EMIT actualTitleBarChanged();
|
||||
} else if (e->type() == QEvent::Show) {
|
||||
onShown(e->spontaneous());
|
||||
} else if (e->type() == QEvent::Hide) {
|
||||
onHidden(e->spontaneous());
|
||||
} else if (e->type() == QEvent::Close) {
|
||||
onCloseEvent(static_cast<QCloseEvent*>(e));
|
||||
onCloseEvent(static_cast<QCloseEvent *>(e));
|
||||
}
|
||||
|
||||
return DockWidgetBase::event(e);
|
||||
@@ -107,3 +129,36 @@ QSize DockWidgetQuick::maximumSize() const
|
||||
|
||||
return DockWidgetBase::maximumSize();
|
||||
}
|
||||
|
||||
TitleBar *DockWidgetQuick::actualTitleBar() const
|
||||
{
|
||||
if (Frame *frame = DockWidgetBase::d->frame())
|
||||
return frame->actualTitleBar();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QObject *DockWidgetQuick::actualTitleBarObj() const
|
||||
{
|
||||
return actualTitleBar();
|
||||
}
|
||||
|
||||
QQuickItem *DockWidgetQuick::frameVisualItem() const
|
||||
{
|
||||
if (auto frame = qobject_cast<FrameQuick *>(DockWidgetBase::d->frame()))
|
||||
return frame->visualItem();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DockWidgetQuick::onGeometryUpdated()
|
||||
{
|
||||
if (auto frame = qobject_cast<FrameQuick *>(DockWidgetBase::d->frame())) {
|
||||
frame->updateConstriants();
|
||||
frame->updateGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
Frame *DockWidgetQuick::frame() const
|
||||
{
|
||||
return qobject_cast<FrameQuick *>(DockWidgetBase::d->frame());
|
||||
}
|
||||
|
||||
@@ -23,10 +23,14 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QCloseEvent;
|
||||
class QQmlEngine;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace KDDockWidgets {
|
||||
|
||||
class Frame;
|
||||
class TitleBar;
|
||||
|
||||
/**
|
||||
* @brief Represents a dock widget.
|
||||
*
|
||||
@@ -35,17 +39,22 @@ namespace KDDockWidgets {
|
||||
class DOCKS_EXPORT DockWidgetQuick : public DockWidgetBase
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QObject *actualTitleBar READ actualTitleBarObj NOTIFY actualTitleBarChanged)
|
||||
public:
|
||||
/**
|
||||
* @brief constructs a new DockWidget
|
||||
* @param name the name of the dockwidget, should be unique. Use title for user visible text.
|
||||
* @param uniqueName the name of the dockwidget, should be unique. Use title for user visible text.
|
||||
* @param options optional options controlling behaviour
|
||||
* @param parent optional QWidget parent, for ownership purposes
|
||||
* @param layoutSaverOptions options regarding LayoutSaver behaviour
|
||||
* @param engine the QML engine this dock widget will be created on. If not specified then
|
||||
* Config::self().qmlEngine() will be used
|
||||
*
|
||||
* There's no parent argument. The DockWidget is either parented to FloatingWindow or MainWindow
|
||||
* when visible, or stays without a parent when hidden.
|
||||
*/
|
||||
explicit DockWidgetQuick(const QString &uniqueName, Options options = {});
|
||||
explicit DockWidgetQuick(const QString &uniqueName, Options options = {},
|
||||
LayoutSaverOptions layoutSaverOptions = LayoutSaverOptions(),
|
||||
QQmlEngine *engine = nullptr);
|
||||
|
||||
///@brief destructor
|
||||
~DockWidgetQuick() override;
|
||||
@@ -57,12 +66,38 @@ public:
|
||||
/// @reimp
|
||||
void setWidget(QWidgetAdapter *widget) override;
|
||||
|
||||
/// @reimp
|
||||
Q_INVOKABLE void setWidget(QQuickItem *widget);
|
||||
|
||||
/// @reimp
|
||||
QSize minimumSize() const override;
|
||||
|
||||
/// @reimp
|
||||
QSize maximumSize() const override;
|
||||
|
||||
/// @brief Returns the title bar
|
||||
TitleBar *actualTitleBar() const;
|
||||
|
||||
/// @brief Returns the title bar
|
||||
/// Qt6 requires us to include TitleBar_p.h, so instead the Q_PROPERTY uses
|
||||
/// QObject so we don't include private headers in public headers
|
||||
QObject *actualTitleBarObj() const;
|
||||
|
||||
/// @brief Returns the visual item which represents Frame in the screen
|
||||
/// Equivalent to Frame::visualItem().
|
||||
QQuickItem *frameVisualItem() const;
|
||||
|
||||
///@internal
|
||||
Q_INVOKABLE KDDockWidgets::Frame *frame() const;
|
||||
|
||||
/// @brief Called by QtQuick when min-size changes
|
||||
Q_INVOKABLE void onGeometryUpdated();
|
||||
|
||||
Q_SIGNALS:
|
||||
/// @brief The geometry of the frame container this dock widget is in changed
|
||||
/// For example, when dragging a dockwidget
|
||||
void frameGeometryChanged(QRect);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e) override;
|
||||
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
*/
|
||||
|
||||
#include "FocusScope.h"
|
||||
#include "TitleBar_p.h"
|
||||
#include "Frame_p.h"
|
||||
#include "DockWidgetBase.h"
|
||||
#include "DockRegistry_p.h"
|
||||
|
||||
#include "private/TitleBar_p.h"
|
||||
#include "private/Frame_p.h"
|
||||
#include "private/DockRegistry_p.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QGuiApplication>
|
||||
@@ -43,12 +44,27 @@ public:
|
||||
m_inCtor = false;
|
||||
}
|
||||
|
||||
/// @brief Returns whether the last focused widget is the tab widget itself
|
||||
bool lastFocusedIsTabWidget() const
|
||||
{
|
||||
if (!m_lastFocusedInScope)
|
||||
return false;
|
||||
|
||||
if (auto metaObj = m_lastFocusedInScope->metaObject()) {
|
||||
const auto className = QLatin1String(metaObj->className());
|
||||
|
||||
return className == QLatin1String("KDDockWidgets::TabBarWidget")
|
||||
|| className == QLatin1String("KDDockWidgets::TabBarQuick");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
~Private() override;
|
||||
|
||||
void setIsFocused(bool);
|
||||
void onFocusObjectChanged(QObject *);
|
||||
bool isInFocusScope(WidgetType *) const;
|
||||
void emitDockWidgetFocusChanged();
|
||||
|
||||
FocusScope *const q;
|
||||
QWidgetAdapter *const m_thisWidget;
|
||||
@@ -83,10 +99,13 @@ WidgetType *FocusScope::focusedWidget() const
|
||||
|
||||
void FocusScope::focus(Qt::FocusReason reason)
|
||||
{
|
||||
if (d->m_lastFocusedInScope) {
|
||||
if (d->m_lastFocusedInScope && !d->lastFocusedIsTabWidget()) {
|
||||
// When we focus the FocusScope, we give focus to the last focused widget, but let's
|
||||
// do better than focusing a tab widget. The tab widget itself being focused isn't
|
||||
// very useful.
|
||||
d->m_lastFocusedInScope->setFocus(reason);
|
||||
} else {
|
||||
if (auto frame = qobject_cast<Frame*>(d->m_thisWidget)) {
|
||||
if (auto frame = qobject_cast<Frame *>(d->m_thisWidget)) {
|
||||
if (DockWidgetBase *dw = frame->currentDockWidget()) {
|
||||
if (auto guest = dw->widget()) {
|
||||
if (guest->focusPolicy() != Qt::NoFocus)
|
||||
@@ -105,9 +124,6 @@ void FocusScope::Private::setIsFocused(bool is)
|
||||
if (is != m_isFocused) {
|
||||
m_isFocused = is;
|
||||
|
||||
if (is)
|
||||
emitDockWidgetFocusChanged();
|
||||
|
||||
if (!m_inCtor) // Hack so we don't call pure-virtual
|
||||
/* Q_EMIT */ q->isFocusedChangedCallback();
|
||||
}
|
||||
@@ -115,14 +131,14 @@ void FocusScope::Private::setIsFocused(bool is)
|
||||
|
||||
void FocusScope::Private::onFocusObjectChanged(QObject *obj)
|
||||
{
|
||||
auto widget = qobject_cast<WidgetType*>(obj);
|
||||
auto widget = qobject_cast<WidgetType *>(obj);
|
||||
if (!widget) {
|
||||
setIsFocused(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is = isInFocusScope(widget);
|
||||
if (is && m_lastFocusedInScope != widget && !qobject_cast<TitleBar*>(obj)) {
|
||||
if (is && m_lastFocusedInScope != widget && !qobject_cast<TitleBar *>(obj)) {
|
||||
m_lastFocusedInScope = widget;
|
||||
setIsFocused(is);
|
||||
/* Q_EMIT */ q->focusedWidgetChangedCallback();
|
||||
@@ -143,33 +159,3 @@ bool FocusScope::Private::isInFocusScope(WidgetType *widget) const
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FocusScope::Private::emitDockWidgetFocusChanged()
|
||||
{
|
||||
auto p = qobject_cast<WidgetType*>(qApp->focusObject());
|
||||
if (!p) return;
|
||||
|
||||
// Find the nearest DockWidget and send the focusChangedSignal
|
||||
while (p) {
|
||||
if (auto frame = qobject_cast<Frame*>(p)) {
|
||||
// Special case: The focused widget is inside the frame but not inside the dockwidget.
|
||||
// For example, it's a line edit in the QTabBar. We still need to send the signal for
|
||||
// the current dw in the tab group
|
||||
if (auto dw = frame->currentDockWidget()) {
|
||||
DockRegistry::self()->setFocusedDockWidget(dw);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == m_thisWidget)
|
||||
break;
|
||||
|
||||
if (auto dw = qobject_cast<DockWidgetBase*>(p)) {
|
||||
DockRegistry::self()->setFocusedDockWidget(dw);
|
||||
break;
|
||||
}
|
||||
|
||||
p = KDDockWidgets::Private::parentWidget(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
#include "docks_export.h"
|
||||
#include "QWidgetAdapter.h"
|
||||
|
||||
namespace KDDockWidgets
|
||||
{
|
||||
namespace KDDockWidgets {
|
||||
///@brief Allows to implement a similar functionality to QtQuick's FocusScope item, in QtWidgets
|
||||
class DOCKS_EXPORT FocusScope
|
||||
{
|
||||
@@ -41,14 +40,14 @@ public:
|
||||
///@brief Returns the widget that's focused in this scope
|
||||
///The widget itself might not have focus as in QWidget::hasFocus(), but will get actual focus
|
||||
///as soon as this scope is focused.
|
||||
WidgetType* focusedWidget() const;
|
||||
WidgetType *focusedWidget() const;
|
||||
|
||||
///@brief Sets focus on this scope.
|
||||
///
|
||||
/// This will call QWidget::focus() on the last QWidget that was focused in this scope.
|
||||
void focus(Qt::FocusReason = Qt::OtherFocusReason);
|
||||
|
||||
/*Q_SIGNALS:*/
|
||||
/*Q_SIGNALS:*/
|
||||
protected:
|
||||
///@brief reimplement in the 1st QObject derived class
|
||||
virtual void isFocusedChangedCallback() = 0;
|
||||
|
||||
@@ -10,37 +10,38 @@
|
||||
*/
|
||||
|
||||
#include "FrameworkWidgetFactory.h"
|
||||
#include "Frame_p.h"
|
||||
#include "TitleBar_p.h"
|
||||
#include "multisplitter/Separator_p.h"
|
||||
#include "FloatingWindow_p.h"
|
||||
#include "Config.h"
|
||||
#include "indicators/ClassicIndicators_p.h"
|
||||
#include "indicators/NullIndicators_p.h"
|
||||
#include "Utils_p.h"
|
||||
#include "TabWidget_p.h"
|
||||
|
||||
#include "private/Frame_p.h"
|
||||
#include "private/TitleBar_p.h"
|
||||
#include "private/multisplitter/Separator_p.h"
|
||||
#include "private/FloatingWindow_p.h"
|
||||
#include "private/indicators/ClassicIndicators_p.h"
|
||||
#include "private/indicators/NullIndicators_p.h"
|
||||
#include "private/Utils_p.h"
|
||||
#include "private/TabWidget_p.h"
|
||||
|
||||
#ifdef KDDOCKWIDGETS_QTWIDGETS
|
||||
# include "widgets/FrameWidget_p.h"
|
||||
# include "widgets/TitleBarWidget_p.h"
|
||||
# include "widgets/TabBarWidget_p.h"
|
||||
# include "widgets/SideBarWidget_p.h"
|
||||
# include "widgets/TabWidgetWidget_p.h"
|
||||
# include "multisplitter/Separator_qwidget.h"
|
||||
# include "widgets/FloatingWindowWidget_p.h"
|
||||
# include "indicators/SegmentedIndicators_p.h"
|
||||
#include "private/widgets/FrameWidget_p.h"
|
||||
#include "private/widgets/TitleBarWidget_p.h"
|
||||
#include "private/widgets/TabBarWidget_p.h"
|
||||
#include "private/widgets/SideBarWidget_p.h"
|
||||
#include "private/widgets/TabWidgetWidget_p.h"
|
||||
#include "private/multisplitter/Separator_qwidget.h"
|
||||
#include "private/widgets/FloatingWindowWidget_p.h"
|
||||
#include "private/indicators/SegmentedIndicators_p.h"
|
||||
|
||||
# include <QRubberBand>
|
||||
# include <QToolButton>
|
||||
#include <QRubberBand>
|
||||
#include <QToolButton>
|
||||
#else
|
||||
# include "DockWidgetQuick.h"
|
||||
# include "quick/FrameQuick_p.h"
|
||||
# include "quick/TitleBarQuick_p.h"
|
||||
# include "quick/TabWidgetQuick_p.h"
|
||||
# include "quick/TabBarQuick_p.h"
|
||||
# include "quick/FloatingWindowQuick_p.h"
|
||||
# include "quick/RubberBandQuick.h"
|
||||
# include "multisplitter/Separator_quick.h"
|
||||
#include "DockWidgetQuick.h"
|
||||
#include "private/quick/FrameQuick_p.h"
|
||||
#include "private/quick/TitleBarQuick_p.h"
|
||||
#include "private/quick/TabWidgetQuick_p.h"
|
||||
#include "private/quick/TabBarQuick_p.h"
|
||||
#include "private/quick/FloatingWindowQuick_p.h"
|
||||
#include "private/quick/RubberBandQuick.h"
|
||||
#include "private/multisplitter/Separator_quick.h"
|
||||
#endif
|
||||
|
||||
// clazy:excludeall=ctor-missing-parent-argument
|
||||
@@ -86,12 +87,12 @@ Layouting::Separator *DefaultWidgetFactory::createSeparator(Layouting::Widget *p
|
||||
|
||||
FloatingWindow *DefaultWidgetFactory::createFloatingWindow(MainWindowBase *parent) const
|
||||
{
|
||||
return new FloatingWindowWidget(parent);
|
||||
return new FloatingWindowWidget(QRect(), parent);
|
||||
}
|
||||
|
||||
FloatingWindow *DefaultWidgetFactory::createFloatingWindow(Frame *frame, MainWindowBase *parent) const
|
||||
FloatingWindow *DefaultWidgetFactory::createFloatingWindow(Frame *frame, MainWindowBase *parent, QRect suggestedGeometry) const
|
||||
{
|
||||
return new FloatingWindowWidget(frame, parent);
|
||||
return new FloatingWindowWidget(frame, suggestedGeometry, parent);
|
||||
}
|
||||
|
||||
DropIndicatorOverlayInterface *DefaultWidgetFactory::createDropIndicatorOverlay(DropArea *dropArea) const
|
||||
@@ -123,7 +124,7 @@ SideBar *DefaultWidgetFactory::createSideBar(SideBarLocation loc, MainWindowBase
|
||||
return new SideBarWidget(loc, parent);
|
||||
}
|
||||
|
||||
QAbstractButton* DefaultWidgetFactory::createTitleBarButton(QWidget *parent, TitleBarButtonType type) const
|
||||
QAbstractButton *DefaultWidgetFactory::createTitleBarButton(QWidget *parent, TitleBarButtonType type) const
|
||||
{
|
||||
if (!parent) {
|
||||
qWarning() << Q_FUNC_INFO << "Parent not provided";
|
||||
@@ -163,9 +164,9 @@ FloatingWindow *DefaultWidgetFactory::createFloatingWindow(MainWindowBase *paren
|
||||
return new FloatingWindowQuick(parent);
|
||||
}
|
||||
|
||||
FloatingWindow *DefaultWidgetFactory::createFloatingWindow(Frame *frame, MainWindowBase *parent) const
|
||||
FloatingWindow *DefaultWidgetFactory::createFloatingWindow(Frame *frame, MainWindowBase *parent, QRect suggestedGeometry) const
|
||||
{
|
||||
return new FloatingWindowQuick(frame, parent);
|
||||
return new FloatingWindowQuick(frame, suggestedGeometry, parent);
|
||||
}
|
||||
|
||||
DropIndicatorOverlayInterface *DefaultWidgetFactory::createDropIndicatorOverlay(DropArea *dropArea) const
|
||||
@@ -217,6 +218,21 @@ QUrl DefaultWidgetFactory::titleBarFilename() const
|
||||
return QUrl(QStringLiteral("qrc:/kddockwidgets/private/quick/qml/TitleBar.qml"));
|
||||
}
|
||||
|
||||
QUrl DefaultWidgetFactory::dockwidgetFilename() const
|
||||
{
|
||||
return QUrl(QStringLiteral("qrc:/kddockwidgets/private/quick/qml/DockWidget.qml"));
|
||||
}
|
||||
|
||||
QUrl DefaultWidgetFactory::frameFilename() const
|
||||
{
|
||||
return QUrl(QStringLiteral("qrc:/kddockwidgets/private/quick/qml/Frame.qml"));
|
||||
}
|
||||
|
||||
QUrl DefaultWidgetFactory::floatingWindowFilename() const
|
||||
{
|
||||
return QUrl(QStringLiteral("qrc:/kddockwidgets/private/quick/qml/FloatingWindow.qml"));
|
||||
}
|
||||
|
||||
#endif // QtQuick
|
||||
|
||||
// iconForButtonType impl is the same for QtQuick and QtWidgets
|
||||
@@ -252,25 +268,15 @@ QIcon DefaultWidgetFactory::iconForButtonType(TitleBarButtonType type, qreal dpr
|
||||
return {};
|
||||
|
||||
QIcon icon(QStringLiteral(":/img/%1.png").arg(iconName));
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 2)
|
||||
const bool isFractional = int(dpr) != dpr;
|
||||
if (isFractional) {
|
||||
// We don't support 1.5x yet.
|
||||
// Problem with Linux is that rendering is off due to a rounding bug only fixed in 5.15.2
|
||||
// Will enable for fractional later.
|
||||
// QTBUG-86170
|
||||
// Mostly affects Linux. Unless you're using Qt::HighDpiScaleFactorRoundingPolicy::PassThrough, in which case it will
|
||||
// affect other OSes too.
|
||||
if (!scalingFactorIsSupported(dpr))
|
||||
return icon;
|
||||
}
|
||||
#else
|
||||
|
||||
// Not using Qt's sugar syntax, which doesn't support 1.5x anyway when we need it.
|
||||
// Simply add the high-res files and Qt will pick them when needed
|
||||
|
||||
icon.addFile(QStringLiteral(":/img/%1-1.5x.png").arg(iconName));
|
||||
Q_UNUSED(dpr);
|
||||
#endif
|
||||
if (scalingFactorIsSupported(1.5))
|
||||
icon.addFile(QStringLiteral(":/img/%1-1.5x.png").arg(iconName));
|
||||
|
||||
icon.addFile(QStringLiteral(":/img/%1-2x.png").arg(iconName));
|
||||
|
||||
return icon;
|
||||
|
||||
@@ -66,9 +66,6 @@ class TabWidgetQuick;
|
||||
*/
|
||||
class DOCKS_EXPORT FrameworkWidgetFactory : public QObject
|
||||
{
|
||||
#ifdef KDDOCKWIDGETS_QTQUICK
|
||||
Q_PROPERTY(QUrl titleBarFilename READ titleBarFilename CONSTANT)
|
||||
#endif
|
||||
Q_OBJECT
|
||||
public:
|
||||
FrameworkWidgetFactory() = default;
|
||||
@@ -83,35 +80,35 @@ public:
|
||||
/// DockWidgets.
|
||||
///@param parent just forward to Frame's constructor
|
||||
///@param options just forward to Frame's constructor
|
||||
virtual Frame* createFrame(QWidgetOrQuick *parent = nullptr, FrameOptions options = FrameOption_None) const = 0;
|
||||
virtual Frame *createFrame(QWidgetOrQuick *parent = nullptr, FrameOptions options = FrameOption_None) const = 0;
|
||||
|
||||
///@brief Called internally by the framework to create a TitleBar
|
||||
/// Override to provide your own TitleBar sub-class. If overridden then
|
||||
/// you also need to override the overload below.
|
||||
///@param frame Just forward to TitleBar's constructor.
|
||||
virtual TitleBar* createTitleBar(Frame *frame) const = 0;
|
||||
virtual TitleBar *createTitleBar(Frame *frame) const = 0;
|
||||
|
||||
///@brief Called internally by the framework to create a TitleBar
|
||||
/// Override to provide your own TitleBar sub-class. If overridden then
|
||||
/// you also need to override the overload above.
|
||||
///@param floatingWindow Just forward to TitleBar's constructor.
|
||||
virtual TitleBar* createTitleBar(FloatingWindow *floatingWindow) const = 0;
|
||||
virtual TitleBar *createTitleBar(FloatingWindow *floatingWindow) const = 0;
|
||||
|
||||
///@brief Called internally by the framework to create a TabWidget
|
||||
/// Override to provide your own TabWidget sub-class.
|
||||
///@param parent Just forward to TabWidget's constructor.
|
||||
virtual TabWidget* createTabWidget(Frame *parent) const = 0;
|
||||
virtual TabWidget *createTabWidget(Frame *parent) const = 0;
|
||||
|
||||
///@brief Called internally by the framework to create a TabBar
|
||||
/// Override to provide your own TabBar sub-class.
|
||||
///@param parent Just forward to TabBar's's constructor.
|
||||
virtual TabBar* createTabBar(TabWidget *parent = nullptr) const = 0;
|
||||
virtual TabBar *createTabBar(TabWidget *parent = nullptr) const = 0;
|
||||
|
||||
///@brief Called internally by the framework to create a Separator
|
||||
/// Override to provide your own Separator sub-class. The Separator allows
|
||||
/// the user to resize nested dock widgets.
|
||||
///@param parent Just forward to Separator's constructor.
|
||||
virtual Layouting::Separator* createSeparator(Layouting::Widget *parent = nullptr) const = 0;
|
||||
virtual Layouting::Separator *createSeparator(Layouting::Widget *parent = nullptr) const = 0;
|
||||
|
||||
///@brief Called internally by the framework to create a FloatingWindow
|
||||
/// Override to provide your own FloatingWindow sub-class. If overridden then
|
||||
@@ -124,7 +121,7 @@ public:
|
||||
/// you also need to override the overloads above.
|
||||
///@param frame Just forward to FloatingWindow's constructor.
|
||||
///@param parent Just forward to FloatingWindow's constructor.
|
||||
virtual FloatingWindow *createFloatingWindow(Frame *frame, MainWindowBase *parent = nullptr) const = 0;
|
||||
virtual FloatingWindow *createFloatingWindow(Frame *frame, MainWindowBase *parent = nullptr, QRect suggestedGeometry = {}) const = 0;
|
||||
|
||||
///@brief Called internally by the framework to create a DropIndicatorOverlayInterface
|
||||
/// Override to provide your own DropIndicatorOverlayInterface sub-class.
|
||||
@@ -143,14 +140,18 @@ public:
|
||||
#ifdef KDDOCKWIDGETS_QTWIDGETS
|
||||
///@brief Called internally by the framework to create a title bar button
|
||||
///@p parent the button's parent
|
||||
virtual QAbstractButton* createTitleBarButton(QWidget *parent, TitleBarButtonType) const = 0;
|
||||
virtual QAbstractButton *createTitleBarButton(QWidget *parent, TitleBarButtonType) const = 0;
|
||||
#else
|
||||
virtual QUrl titleBarFilename() const = 0;
|
||||
virtual QUrl dockwidgetFilename() const = 0;
|
||||
virtual QUrl frameFilename() const = 0;
|
||||
virtual QUrl floatingWindowFilename() const = 0;
|
||||
#endif
|
||||
|
||||
/// @brief Returns the icon to be used with the specified @p type
|
||||
/// @param dpr the device pixel ratio of the button
|
||||
virtual QIcon iconForButtonType(TitleBarButtonType type, qreal dpr) const = 0;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(FrameworkWidgetFactory)
|
||||
};
|
||||
@@ -170,20 +171,24 @@ public:
|
||||
TabBar *createTabBar(TabWidget *parent) const override;
|
||||
Layouting::Separator *createSeparator(Layouting::Widget *parent = nullptr) const override;
|
||||
FloatingWindow *createFloatingWindow(MainWindowBase *parent = nullptr) const override;
|
||||
FloatingWindow *createFloatingWindow(Frame *frame, MainWindowBase *parent = nullptr) const override;
|
||||
DropIndicatorOverlayInterface *createDropIndicatorOverlay(DropArea*) const override;
|
||||
FloatingWindow *createFloatingWindow(Frame *frame, MainWindowBase *parent = nullptr, QRect suggestedGeometry = {}) const override;
|
||||
DropIndicatorOverlayInterface *createDropIndicatorOverlay(DropArea *) const override;
|
||||
QWidgetOrQuick *createRubberBand(QWidgetOrQuick *parent) const override;
|
||||
SideBar *createSideBar(SideBarLocation loc, MainWindowBase *parent) const override;
|
||||
|
||||
#ifdef KDDOCKWIDGETS_QTWIDGETS
|
||||
QAbstractButton* createTitleBarButton(QWidget *parent, TitleBarButtonType) const override;
|
||||
QAbstractButton *createTitleBarButton(QWidget *parent, TitleBarButtonType) const override;
|
||||
#else
|
||||
QUrl titleBarFilename() const override;
|
||||
Q_INVOKABLE QUrl titleBarFilename() const override;
|
||||
QUrl dockwidgetFilename() const override;
|
||||
QUrl frameFilename() const override;
|
||||
QUrl floatingWindowFilename() const override;
|
||||
#endif
|
||||
|
||||
QIcon iconForButtonType(TitleBarButtonType type, qreal dpr) const override;
|
||||
|
||||
static DropIndicatorType s_dropIndicatorType;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(DefaultWidgetFactory)
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#ifndef KD_KDDOCKWIDGETS_H
|
||||
#define KD_KDDOCKWIDGETS_H
|
||||
|
||||
#include "docks_export.h"
|
||||
#include "Qt5Qt6Compat_p.h"
|
||||
|
||||
#include <QObject>
|
||||
@@ -26,7 +27,7 @@
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Only on Windows, where this is popular. On linux the Qt::Tool windows need reparenting. Untested on macOS.
|
||||
# define KDDOCKWIDGETS_SUPPORTS_NESTED_MAINWINDOWS
|
||||
#define KDDOCKWIDGETS_SUPPORTS_NESTED_MAINWINDOWS
|
||||
#endif
|
||||
|
||||
namespace Layouting {
|
||||
@@ -34,104 +35,124 @@ class Item;
|
||||
class ItemBoxContainer;
|
||||
}
|
||||
|
||||
namespace KDDockWidgets
|
||||
namespace KDDockWidgets {
|
||||
DOCKS_EXPORT
|
||||
Q_NAMESPACE
|
||||
class MultiSplitter;
|
||||
class DropArea;
|
||||
|
||||
enum Location
|
||||
{
|
||||
class MultiSplitter;
|
||||
class DropArea;
|
||||
Location_None,
|
||||
Location_OnLeft, ///> Left docking location
|
||||
Location_OnTop, ///> Top docking location
|
||||
Location_OnRight, ///> Right docking location
|
||||
Location_OnBottom ///> Bottom docking location
|
||||
};
|
||||
Q_ENUM_NS(Location)
|
||||
|
||||
enum Location {
|
||||
Location_None,
|
||||
Location_OnLeft, ///> Left docking location
|
||||
Location_OnTop, ///> Top docking location
|
||||
Location_OnRight, ///> Right docking location
|
||||
Location_OnBottom ///> Bottom docking location
|
||||
};
|
||||
enum MainWindowOption
|
||||
{
|
||||
MainWindowOption_None = 0, ///> No option set
|
||||
MainWindowOption_HasCentralFrame = 1, ///> Makes the MainWindow always have a central frame, for tabbing documents
|
||||
MainWindowOption_MDI = 2 ///> EXPERIMENTAL!!1 The layout will be MDI. DockWidgets can have arbitrary positions, not restricted by any layout
|
||||
};
|
||||
Q_DECLARE_FLAGS(MainWindowOptions, MainWindowOption)
|
||||
Q_ENUM_NS(MainWindowOptions)
|
||||
|
||||
enum MainWindowOption {
|
||||
MainWindowOption_None = 0, ///> No option set
|
||||
MainWindowOption_HasCentralFrame = 1 ///> Makes the MainWindow always have a central frame, for tabbing documents
|
||||
};
|
||||
Q_DECLARE_FLAGS(MainWindowOptions, MainWindowOption)
|
||||
///@internal
|
||||
///@brief Describes some sizing strategies for the layouting engine.
|
||||
///This is internal. The public API for dealing with sizing is InitialOption.
|
||||
///@sa InitialOption
|
||||
enum class DefaultSizeMode
|
||||
{
|
||||
ItemSize, ///< Simply uses the Item::size() of the item being added. Actual used size might be smaller if our window isn't big enough.
|
||||
Fair, ///< Gives an equal relative size as the items that are already in the layout
|
||||
FairButFloor, ///< Equal to fair, but if the item we're adding is smaller than the fair suggestion, then that small size is used.
|
||||
NoDefaultSizeMode, ///< Don't do any sizing
|
||||
};
|
||||
Q_ENUM_NS(DefaultSizeMode)
|
||||
|
||||
///@internal
|
||||
///@brief Describes some sizing strategies for the layouting engine.
|
||||
///This is internal. The public API for dealing with sizing is InitialOption.
|
||||
///@sa InitialOption
|
||||
enum class DefaultSizeMode {
|
||||
ItemSize, ///< Simply uses the Item::size() of the item being added. Actual used size might be smaller if our window isn't big enough.
|
||||
Fair, ///< Gives an equal relative size as the items that are already in the layout
|
||||
FairButFloor, ///< Equal to fair, but if the item we're adding is smaller than the fair suggestion, then that small size is used.
|
||||
None, ///< Don't do any sizing
|
||||
};
|
||||
///@brief Only here for source-compat with v1.2. Do not use.
|
||||
///Use InitialVisibilityOption instead.
|
||||
enum AddingOption
|
||||
{
|
||||
AddingOption_None = 0,
|
||||
AddingOption_StartHidden
|
||||
};
|
||||
Q_ENUM_NS(AddingOption)
|
||||
|
||||
///@brief Only here for source-compat with v1.2. Do not use.
|
||||
///Use InitialVisibilityOption instead.
|
||||
enum AddingOption {
|
||||
AddingOption_None = 0,
|
||||
AddingOption_StartHidden
|
||||
};
|
||||
enum class InitialVisibilityOption
|
||||
{
|
||||
StartVisible = 0, ///< The dock widget is made visible when docked
|
||||
StartHidden ///< Don't show the dock widget when adding it
|
||||
};
|
||||
Q_ENUM_NS(InitialVisibilityOption)
|
||||
|
||||
enum class InitialVisibilityOption {
|
||||
StartVisible = 0, ///< The dock widget is made visible when docked
|
||||
StartHidden ///< Don't show the dock widget when adding it
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Struct describing the preferred dock widget size and visibility when adding it to a layout
|
||||
*
|
||||
* You can pass this to MainWindowBase::addDockWidget() to give an hint of your preferred size
|
||||
* and visibility.
|
||||
*
|
||||
* See bellow the documentation for InitialOption::visibility and InitialOption::preferredSize.
|
||||
* See below the documentation for InitialOption::visibility and InitialOption::preferredSize.
|
||||
*
|
||||
* @sa MainWindowBase::addDockWidget()
|
||||
*/
|
||||
struct InitialOption
|
||||
struct InitialOption
|
||||
{
|
||||
// Implicit ctors for convenience:
|
||||
|
||||
InitialOption() = default;
|
||||
|
||||
InitialOption(InitialVisibilityOption v)
|
||||
: visibility(v)
|
||||
{
|
||||
// Implicit ctors for convenience:
|
||||
}
|
||||
|
||||
InitialOption() = default;
|
||||
InitialOption(QSize size)
|
||||
: preferredSize(size)
|
||||
{
|
||||
}
|
||||
|
||||
InitialOption(InitialVisibilityOption v)
|
||||
: visibility(v) {}
|
||||
InitialOption(InitialVisibilityOption v, QSize size)
|
||||
: visibility(v)
|
||||
, preferredSize(size)
|
||||
{
|
||||
}
|
||||
|
||||
InitialOption(QSize size)
|
||||
: preferredSize(size) {}
|
||||
QT_DEPRECATED_X("AddingOption is deprecated and will be removed in v1.5. Use InitialVisibilityOption instead.")
|
||||
InitialOption(AddingOption opt)
|
||||
: visibility(opt == AddingOption_StartHidden ? InitialVisibilityOption::StartHidden
|
||||
: InitialVisibilityOption::StartVisible)
|
||||
{
|
||||
}
|
||||
|
||||
InitialOption(InitialVisibilityOption v, QSize size)
|
||||
: visibility(v)
|
||||
, preferredSize(size)
|
||||
{}
|
||||
bool startsHidden() const
|
||||
{
|
||||
return visibility == InitialVisibilityOption::StartHidden;
|
||||
}
|
||||
|
||||
QT_DEPRECATED_X("AddingOption is deprecated and will be removed in v1.5. Use InitialVisibilityOption instead.")
|
||||
InitialOption(AddingOption opt)
|
||||
: visibility(opt == AddingOption_StartHidden ? InitialVisibilityOption::StartHidden
|
||||
: InitialVisibilityOption::StartVisible)
|
||||
{
|
||||
}
|
||||
int preferredLength(Qt::Orientation o) const
|
||||
{
|
||||
return o == Qt::Horizontal ? preferredSize.width()
|
||||
: preferredSize.height();
|
||||
}
|
||||
|
||||
bool startsHidden() const {
|
||||
return visibility == InitialVisibilityOption::StartHidden;
|
||||
}
|
||||
bool hasPreferredLength(Qt::Orientation o) const
|
||||
{
|
||||
return preferredLength(o) > 0;
|
||||
}
|
||||
|
||||
int preferredLength(Qt::Orientation o) const {
|
||||
return o == Qt::Horizontal ? preferredSize.width()
|
||||
: preferredSize.height();
|
||||
}
|
||||
|
||||
bool hasPreferredLength(Qt::Orientation o) const {
|
||||
return preferredLength(o) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Allows a dock widget to be docked as hidden.
|
||||
*
|
||||
* Next time you call DockWidget::show() it will be shown at that place. This avoids
|
||||
* flickering, as no show()/hide() workarounds are needed.
|
||||
*/
|
||||
const InitialVisibilityOption visibility = InitialVisibilityOption::StartVisible;
|
||||
InitialVisibilityOption visibility = InitialVisibilityOption::StartVisible;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Allows to control the size a dock widget should get when docked.
|
||||
*
|
||||
* If an invalid or empty size is passed then KDDW's default heuristics are applied.
|
||||
@@ -140,86 +161,126 @@ namespace KDDockWidgets
|
||||
* dock widget to the left then only the preferred width will be taken into account, as the
|
||||
* height will simply fill the whole layout.
|
||||
*/
|
||||
const QSize preferredSize;
|
||||
QSize preferredSize;
|
||||
|
||||
private:
|
||||
friend class Layouting::Item;
|
||||
friend class Layouting::ItemBoxContainer;
|
||||
friend class KDDockWidgets::MultiSplitter;
|
||||
friend class KDDockWidgets::DropArea;
|
||||
private:
|
||||
friend class Layouting::Item;
|
||||
friend class Layouting::ItemBoxContainer;
|
||||
friend class KDDockWidgets::MultiSplitter;
|
||||
friend class KDDockWidgets::DropArea;
|
||||
|
||||
InitialOption(DefaultSizeMode mode)
|
||||
: sizeMode(mode) {}
|
||||
|
||||
const DefaultSizeMode sizeMode = DefaultSizeMode::Fair;
|
||||
};
|
||||
|
||||
///@internal
|
||||
enum FrameOption {
|
||||
FrameOption_None = 0,
|
||||
FrameOption_AlwaysShowsTabs = 1,
|
||||
FrameOption_IsCentralFrame = 2,
|
||||
FrameOption_IsOverlayed = 4
|
||||
};
|
||||
Q_DECLARE_FLAGS(FrameOptions, FrameOption)
|
||||
|
||||
enum RestoreOption {
|
||||
RestoreOption_None = 0,
|
||||
RestoreOption_RelativeToMainWindow = 1, ///< Skips restoring the main window geometry and the restored dock widgets will use relative sizing.
|
||||
///< Loading layouts won't change the main window geometry and just use whatever the user has at the moment.
|
||||
};
|
||||
Q_DECLARE_FLAGS(RestoreOptions, RestoreOption)
|
||||
|
||||
enum class DropIndicatorType {
|
||||
Classic, ///< The default
|
||||
Segmented, ///< Segmented indicators
|
||||
None ///< Don't show any drop indicators while dragging
|
||||
};
|
||||
|
||||
///@internal
|
||||
inline QString locationStr(Location loc)
|
||||
InitialOption(DefaultSizeMode mode)
|
||||
: sizeMode(mode)
|
||||
{
|
||||
switch (loc) {
|
||||
case KDDockWidgets::Location_None:
|
||||
return QStringLiteral("none");
|
||||
case KDDockWidgets::Location_OnLeft:
|
||||
return QStringLiteral("left");
|
||||
case KDDockWidgets::Location_OnTop:
|
||||
return QStringLiteral("top");
|
||||
case KDDockWidgets::Location_OnRight:
|
||||
return QStringLiteral("right");
|
||||
case KDDockWidgets::Location_OnBottom:
|
||||
return QStringLiteral("bottom");
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
/// @brief Each main window supports 4 sidebars
|
||||
enum class SideBarLocation {
|
||||
None,
|
||||
North,
|
||||
East,
|
||||
West,
|
||||
South
|
||||
};
|
||||
DefaultSizeMode sizeMode = DefaultSizeMode::Fair;
|
||||
};
|
||||
|
||||
///@brief describes a type of button you can have in the title bar
|
||||
enum class TitleBarButtonType {
|
||||
Close,
|
||||
Float,
|
||||
Minimize,
|
||||
Maximize,
|
||||
Normal, // Restore from maximized state
|
||||
AutoHide,
|
||||
UnautoHide
|
||||
};
|
||||
enum RestoreOption
|
||||
{
|
||||
RestoreOption_None = 0,
|
||||
RestoreOption_RelativeToMainWindow = 1, ///< Skips restoring the main window geometry and the restored dock widgets will use relative sizing.
|
||||
///< Loading layouts won't change the main window geometry and just use whatever the user has at the moment.
|
||||
};
|
||||
Q_DECLARE_FLAGS(RestoreOptions, RestoreOption)
|
||||
Q_ENUM_NS(RestoreOptions)
|
||||
|
||||
///@internal
|
||||
inline Qt5Qt6Compat::qhashtype qHash(SideBarLocation loc, Qt5Qt6Compat::qhashtype seed)
|
||||
{
|
||||
return ::qHash(static_cast<uint>(loc), seed);
|
||||
enum class DropIndicatorType
|
||||
{
|
||||
Classic, ///< The default
|
||||
Segmented, ///< Segmented indicators
|
||||
None ///< Don't show any drop indicators while dragging
|
||||
};
|
||||
Q_ENUM_NS(DropIndicatorType)
|
||||
|
||||
///@internal
|
||||
enum SuggestedGeometryHint
|
||||
{
|
||||
SuggestedGeometryHint_None,
|
||||
SuggestedGeometryHint_PreserveCenter = 1,
|
||||
SuggestedGeometryHint_GeometryIsFromDocked = 2
|
||||
};
|
||||
Q_DECLARE_FLAGS(SuggestedGeometryHints, SuggestedGeometryHint)
|
||||
Q_ENUM_NS(SuggestedGeometryHint)
|
||||
|
||||
/// @brief Each main window supports 4 sidebars
|
||||
enum class SideBarLocation
|
||||
{
|
||||
None,
|
||||
North,
|
||||
East,
|
||||
West,
|
||||
South
|
||||
};
|
||||
|
||||
///@brief describes a type of button you can have in the title bar
|
||||
enum class TitleBarButtonType
|
||||
{
|
||||
Close,
|
||||
Float,
|
||||
Minimize,
|
||||
Maximize,
|
||||
Normal, // Restore from maximized state
|
||||
AutoHide,
|
||||
UnautoHide
|
||||
};
|
||||
Q_ENUM_NS(TitleBarButtonType)
|
||||
|
||||
///@internal
|
||||
inline Qt5Qt6Compat::qhashtype qHash(SideBarLocation loc, Qt5Qt6Compat::qhashtype seed)
|
||||
{
|
||||
return ::qHash(static_cast<uint>(loc), seed);
|
||||
}
|
||||
|
||||
///@internal
|
||||
enum CursorPosition
|
||||
{
|
||||
CursorPosition_Undefined = 0,
|
||||
CursorPosition_Left = 1,
|
||||
CursorPosition_Right = 2,
|
||||
CursorPosition_Top = 4,
|
||||
CursorPosition_Bottom = 8,
|
||||
CursorPosition_TopLeft = CursorPosition_Top | CursorPosition_Left,
|
||||
CursorPosition_TopRight = CursorPosition_Top | CursorPosition_Right,
|
||||
CursorPosition_BottomRight = CursorPosition_Bottom | CursorPosition_Right,
|
||||
CursorPosition_BottomLeft = CursorPosition_Bottom | CursorPosition_Left,
|
||||
CursorPosition_Horizontal = CursorPosition_Right | CursorPosition_Left,
|
||||
CursorPosition_Vertical = CursorPosition_Top | CursorPosition_Bottom,
|
||||
CursorPosition_All = CursorPosition_Left | CursorPosition_Right | CursorPosition_Top | CursorPosition_Bottom
|
||||
};
|
||||
Q_DECLARE_FLAGS(CursorPositions, CursorPosition)
|
||||
Q_ENUM_NS(CursorPosition)
|
||||
|
||||
///@internal
|
||||
enum FrameOption
|
||||
{
|
||||
FrameOption_None = 0,
|
||||
FrameOption_AlwaysShowsTabs = 1,
|
||||
FrameOption_IsCentralFrame = 2,
|
||||
FrameOption_IsOverlayed = 4
|
||||
};
|
||||
Q_DECLARE_FLAGS(FrameOptions, FrameOption)
|
||||
Q_ENUM_NS(FrameOptions)
|
||||
|
||||
///@internal
|
||||
inline QString locationStr(Location loc)
|
||||
{
|
||||
switch (loc) {
|
||||
case KDDockWidgets::Location_None:
|
||||
return QStringLiteral("none");
|
||||
case KDDockWidgets::Location_OnLeft:
|
||||
return QStringLiteral("left");
|
||||
case KDDockWidgets::Location_OnTop:
|
||||
return QStringLiteral("top");
|
||||
case KDDockWidgets::Location_OnRight:
|
||||
return QStringLiteral("right");
|
||||
case KDDockWidgets::Location_OnBottom:
|
||||
return QStringLiteral("bottom");
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@@ -16,7 +16,7 @@ if (@KDDockWidgets_QTQUICK@)
|
||||
find_dependency(Qt5Quick REQUIRED)
|
||||
endif()
|
||||
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
if (NOT WIN32 AND NOT APPLE AND NOT EMSCRIPTEN)
|
||||
find_dependency(Qt5X11Extras REQUIRED)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -17,74 +17,65 @@
|
||||
*/
|
||||
|
||||
#include "LayoutSaver.h"
|
||||
#include "LayoutSaver_p.h"
|
||||
#include "Config.h"
|
||||
#include "DockRegistry_p.h"
|
||||
#include "DockWidgetBase.h"
|
||||
#include "DropArea_p.h"
|
||||
#include "Logging_p.h"
|
||||
#include "Frame_p.h"
|
||||
#include "Position_p.h"
|
||||
#include "FrameworkWidgetFactory.h"
|
||||
#include "MainWindowBase.h"
|
||||
#include "FloatingWindow_p.h"
|
||||
#include "DockWidgetBase.h"
|
||||
#include "FrameworkWidgetFactory.h"
|
||||
|
||||
#include "private/LayoutSaver_p.h"
|
||||
#include "private/DockRegistry_p.h"
|
||||
#include "private/DockWidgetBase_p.h"
|
||||
#include "private/FloatingWindow_p.h"
|
||||
#include "private/Frame_p.h"
|
||||
#include "private/LayoutWidget_p.h"
|
||||
#include "private/Logging_p.h"
|
||||
#include "private/Position_p.h"
|
||||
|
||||
#include <qmath.h>
|
||||
#include <QDebug>
|
||||
#include <QSettings>
|
||||
#include <QFile>
|
||||
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* Some implementation details:
|
||||
*
|
||||
* Restoring is done in two phases. From the JSON, we construct an intermediate representation,
|
||||
* which doesn't have any GUI types. Finally we then construct the GUI from the intermediate
|
||||
* representation.
|
||||
*
|
||||
* JSON <-> Intermediate rep (bunch non-gui structs) <-> GUI classes
|
||||
*
|
||||
* This is in contrast to many other dock widget frameworks which just do:
|
||||
* serialized <-> GUI
|
||||
*
|
||||
* The advantage of having the intermediate structs is that we can do validations on them and if
|
||||
* we find some corruption we don't even start messing with the GUI.
|
||||
*
|
||||
* See the LayoutSaver::* structs in LayoutSaver_p.h, those are the intermediate structs.
|
||||
* They have methods to convert to/from JSON.
|
||||
* All other gui classes have methods to convert to/from these structs. For example
|
||||
* FloatingWindow::serialize()/deserialize()
|
||||
*/
|
||||
using namespace KDDockWidgets;
|
||||
|
||||
QHash<QString, LayoutSaver::DockWidget::Ptr> LayoutSaver::DockWidget::s_dockWidgets;
|
||||
LayoutSaver::Layout* LayoutSaver::Layout::s_currentLayoutBeingRestored = nullptr;
|
||||
LayoutSaver::Layout *LayoutSaver::Layout::s_currentLayoutBeingRestored = nullptr;
|
||||
|
||||
class KDDockWidgets::LayoutSaver::Private
|
||||
|
||||
inline InternalRestoreOptions internalRestoreOptions(RestoreOptions options)
|
||||
{
|
||||
public:
|
||||
|
||||
struct RAIIIsRestoring
|
||||
{
|
||||
RAIIIsRestoring()
|
||||
{
|
||||
LayoutSaver::Private::s_restoreInProgress = true;
|
||||
}
|
||||
|
||||
~RAIIIsRestoring()
|
||||
{
|
||||
LayoutSaver::Private::s_restoreInProgress = false;
|
||||
}
|
||||
Q_DISABLE_COPY(RAIIIsRestoring)
|
||||
};
|
||||
|
||||
Private(RestoreOptions options)
|
||||
: m_dockRegistry(DockRegistry::self())
|
||||
, m_restoreOptions(options)
|
||||
{
|
||||
if (options == RestoreOption_None) {
|
||||
return InternalRestoreOption::None;
|
||||
} else if (options == RestoreOption_RelativeToMainWindow) {
|
||||
return InternalRestoreOptions(InternalRestoreOption::SkipMainWindowGeometry)
|
||||
| InternalRestoreOption::RelativeFloatingWindowGeometry;
|
||||
} else {
|
||||
qWarning() << Q_FUNC_INFO << "Unknown options" << options;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool matchesAffinity(const QStringList &affinities) const {
|
||||
return m_affinityNames.isEmpty() || affinities.isEmpty() || DockRegistry::self()->affinitiesMatch(m_affinityNames, affinities);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void deserializeWindowGeometry(const T &saved, QWidgetOrQuick *topLevel);
|
||||
void deleteEmptyFrames();
|
||||
void clearRestoredProperty();
|
||||
|
||||
std::unique_ptr<QSettings> settings() const;
|
||||
DockRegistry *const m_dockRegistry;
|
||||
const RestoreOptions m_restoreOptions;
|
||||
QStringList m_affinityNames;
|
||||
|
||||
static bool s_restoreInProgress;
|
||||
};
|
||||
}
|
||||
|
||||
bool LayoutSaver::Private::s_restoreInProgress = false;
|
||||
|
||||
|
||||
static QVariantList stringListToVariant(const QStringList &strs)
|
||||
{
|
||||
QVariantList variantList;
|
||||
@@ -162,7 +153,7 @@ QByteArray LayoutSaver::serializeLayout() const
|
||||
layout.mainWindows.push_back(mainWindow->serialize());
|
||||
}
|
||||
|
||||
const QVector<KDDockWidgets::FloatingWindow*> floatingWindows = d->m_dockRegistry->floatingWindows();
|
||||
const QVector<KDDockWidgets::FloatingWindow *> floatingWindows = d->m_dockRegistry->floatingWindows();
|
||||
layout.floatingWindows.reserve(floatingWindows.size());
|
||||
for (KDDockWidgets::FloatingWindow *floatingWindow : floatingWindows) {
|
||||
if (d->matchesAffinity(floatingWindow->affinities()))
|
||||
@@ -174,7 +165,7 @@ QByteArray LayoutSaver::serializeLayout() const
|
||||
layout.closedDockWidgets.reserve(closedDockWidgets.size());
|
||||
for (DockWidgetBase *dockWidget : closedDockWidgets) {
|
||||
if (d->matchesAffinity(dockWidget->affinities()))
|
||||
layout.closedDockWidgets.push_back(dockWidget->serialize());
|
||||
layout.closedDockWidgets.push_back(dockWidget->d->serialize());
|
||||
}
|
||||
|
||||
// Save the placeholder info. We do it last, as we also restore it last, since we need all items to be created
|
||||
@@ -184,8 +175,8 @@ QByteArray LayoutSaver::serializeLayout() const
|
||||
layout.allDockWidgets.reserve(dockWidgets.size());
|
||||
for (DockWidgetBase *dockWidget : dockWidgets) {
|
||||
if (d->matchesAffinity(dockWidget->affinities())) {
|
||||
auto dw = dockWidget->serialize();
|
||||
dw->lastPosition = dockWidget->lastPositions().serialize();
|
||||
auto dw = dockWidget->d->serialize();
|
||||
dw->lastPosition = dockWidget->d->lastPositions().serialize();
|
||||
layout.allDockWidgets.push_back(dw);
|
||||
}
|
||||
}
|
||||
@@ -199,9 +190,8 @@ bool LayoutSaver::restoreLayout(const QByteArray &data)
|
||||
if (data.isEmpty())
|
||||
return true;
|
||||
|
||||
Private::RAIIIsRestoring isRestoring;
|
||||
|
||||
struct FrameCleanup {
|
||||
struct FrameCleanup
|
||||
{
|
||||
FrameCleanup(LayoutSaver *saver)
|
||||
: m_saver(saver)
|
||||
{
|
||||
@@ -226,19 +216,23 @@ bool LayoutSaver::restoreLayout(const QByteArray &data)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d->m_restoreOptions & RestoreOption_RelativeToMainWindow)
|
||||
layout.scaleSizes();
|
||||
layout.scaleSizes(d->m_restoreOptions);
|
||||
|
||||
d->floatWidgetsWhichSkipRestore(layout.mainWindowNames());
|
||||
|
||||
Private::RAIIIsRestoring isRestoring;
|
||||
|
||||
// Hide all dockwidgets and unparent them from any layout before starting restore
|
||||
// We only close the stuff that the loaded JSON knows about. Unknown widgets might be newer.
|
||||
d->m_dockRegistry->clear(d->m_dockRegistry->dockWidgets(layout.dockWidgetNames()),
|
||||
|
||||
d->m_dockRegistry->clear(d->m_dockRegistry->dockWidgets(layout.dockWidgetsToClose()),
|
||||
d->m_dockRegistry->mainWindows(layout.mainWindowNames()),
|
||||
d->m_affinityNames);
|
||||
|
||||
// 1. Restore main windows
|
||||
for (const LayoutSaver::MainWindow &mw : qAsConst(layout.mainWindows)) {
|
||||
MainWindowBase *mainWindow = d->m_dockRegistry->mainWindowByName(mw.uniqueName);
|
||||
if (!mainWindow ) {
|
||||
if (!mainWindow) {
|
||||
if (auto mwFunc = Config::self().mainWindowFactoryFunc()) {
|
||||
mainWindow = mwFunc(mw.uniqueName);
|
||||
} else {
|
||||
@@ -250,22 +244,29 @@ bool LayoutSaver::restoreLayout(const QByteArray &data)
|
||||
if (!d->matchesAffinity(mainWindow->affinities()))
|
||||
continue;
|
||||
|
||||
if (!(d->m_restoreOptions & RestoreOption_RelativeToMainWindow))
|
||||
if (!(d->m_restoreOptions & InternalRestoreOption::SkipMainWindowGeometry)) {
|
||||
d->deserializeWindowGeometry(mw, mainWindow->window()); // window(), as the MainWindow can be embedded
|
||||
if (mw.windowState != Qt::WindowNoState) {
|
||||
if (auto w = mainWindow->windowHandle()) {
|
||||
w->setWindowState(mw.windowState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mainWindow->deserialize(mw))
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. Restore FloatingWindows
|
||||
for (const LayoutSaver::FloatingWindow &fw : qAsConst(layout.floatingWindows)) {
|
||||
if (!d->matchesAffinity(fw.affinities))
|
||||
for (LayoutSaver::FloatingWindow &fw : layout.floatingWindows) {
|
||||
if (!d->matchesAffinity(fw.affinities) || fw.skipsRestore())
|
||||
continue;
|
||||
|
||||
MainWindowBase *parent = fw.parentIndex == -1 ? nullptr
|
||||
: DockRegistry::self()->mainwindows().at(fw.parentIndex);
|
||||
|
||||
auto floatingWindow = Config::self().frameworkWidgetFactory()->createFloatingWindow(parent);
|
||||
fw.floatingWindowInstance = floatingWindow;
|
||||
d->deserializeWindowGeometry(fw, floatingWindow);
|
||||
if (!floatingWindow->deserialize(fw)) {
|
||||
qWarning() << Q_FUNC_INFO << "Failed to deserialize floating window";
|
||||
@@ -285,8 +286,9 @@ bool LayoutSaver::restoreLayout(const QByteArray &data)
|
||||
if (!d->matchesAffinity(dw->affinities))
|
||||
continue;
|
||||
|
||||
if (DockWidgetBase *dockWidget = d->m_dockRegistry->dockByName(dw->uniqueName)) {
|
||||
dockWidget->lastPositions().deserialize(dw->lastPosition);
|
||||
if (DockWidgetBase *dockWidget =
|
||||
d->m_dockRegistry->dockByName(dw->uniqueName, DockRegistry::DockByNameFlag::ConsultRemapping)) {
|
||||
dockWidget->d->lastPositions().deserialize(dw->lastPosition);
|
||||
} else {
|
||||
qWarning() << Q_FUNC_INFO << "Couldn't find dock widget" << dw->uniqueName;
|
||||
}
|
||||
@@ -304,6 +306,11 @@ void LayoutSaver::setAffinityNames(const QStringList &affinityNames)
|
||||
}
|
||||
}
|
||||
|
||||
LayoutSaver::Private *LayoutSaver::dptr() const
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
DockWidgetBase::List LayoutSaver::restoredDockWidgets() const
|
||||
{
|
||||
const DockWidgetBase::List &allDockWidgets = DockRegistry::self()->dockwidgets();
|
||||
@@ -325,13 +332,50 @@ void LayoutSaver::Private::clearRestoredProperty()
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
void LayoutSaver::Private::deserializeWindowGeometry(const T &saved, QWidgetOrQuick *topLevel)
|
||||
{
|
||||
topLevel->setGeometry(saved.geometry);
|
||||
// Not simply calling QWidget::setGeometry() here.
|
||||
// For QtQuick we need to modify the QWindow's geometry.
|
||||
|
||||
if (topLevel->isWindow()) {
|
||||
topLevel->setGeometry(saved.geometry);
|
||||
} else {
|
||||
KDDockWidgets::Private::setTopLevelGeometry(saved.geometry, topLevel);
|
||||
}
|
||||
|
||||
topLevel->setVisible(saved.isVisible);
|
||||
}
|
||||
|
||||
LayoutSaver::Private::Private(RestoreOptions options)
|
||||
: m_dockRegistry(DockRegistry::self())
|
||||
, m_restoreOptions(internalRestoreOptions(options))
|
||||
{
|
||||
}
|
||||
|
||||
bool LayoutSaver::Private::matchesAffinity(const QStringList &affinities) const
|
||||
{
|
||||
return m_affinityNames.isEmpty() || affinities.isEmpty()
|
||||
|| DockRegistry::self()->affinitiesMatch(m_affinityNames, affinities);
|
||||
}
|
||||
|
||||
void LayoutSaver::Private::floatWidgetsWhichSkipRestore(const QStringList &mainWindowNames)
|
||||
{
|
||||
// Widgets with the DockWidget::LayoutSaverOption::Skip flag skip restore completely.
|
||||
// If they were visible before they need to remain visible now.
|
||||
// If they were previously docked we need to float them, as the main window they were on will
|
||||
// be loading a new layout.
|
||||
|
||||
for (MainWindowBase *mw : DockRegistry::self()->mainWindows(mainWindowNames)) {
|
||||
const KDDockWidgets::DockWidgetBase::List docks = mw->layoutWidget()->dockWidgets();
|
||||
for (auto dw : docks) {
|
||||
if (dw->skipsRestore()) {
|
||||
dw->setFloating(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutSaver::Private::deleteEmptyFrames()
|
||||
{
|
||||
// After a restore it can happen that some DockWidgets didn't exist, so weren't restored.
|
||||
@@ -393,7 +437,7 @@ bool LayoutSaver::Layout::fromJson(const QByteArray &jsonData)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(jsonData, &error);
|
||||
if (error.error == QJsonParseError::NoError) {
|
||||
if (error.error == QJsonParseError::NoError) {
|
||||
fromVariantMap(doc.toVariant().toMap());
|
||||
return true;
|
||||
}
|
||||
@@ -439,25 +483,44 @@ void LayoutSaver::Layout::fromVariantMap(const QVariantMap &map)
|
||||
screenInfo = fromVariantList<LayoutSaver::ScreenInfo>(map.value(QStringLiteral("screenInfo")).toList());
|
||||
}
|
||||
|
||||
void LayoutSaver::Layout::scaleSizes()
|
||||
void LayoutSaver::Layout::scaleSizes(InternalRestoreOptions options)
|
||||
{
|
||||
if (mainWindows.isEmpty())
|
||||
return;
|
||||
|
||||
const bool skipsMainWindowGeometry = options & InternalRestoreOption::SkipMainWindowGeometry;
|
||||
if (!skipsMainWindowGeometry) {
|
||||
// No scaling to do. All windows will be restored with the exact size specified in the
|
||||
// saved JSON layouts.
|
||||
return;
|
||||
}
|
||||
|
||||
// We won't restore MainWindow's geometry, we use whatever the user has now, meaning
|
||||
// we need to scale all dock widgets inside the layout, as the layout might not have
|
||||
// the same size as specified in the saved JSON layout
|
||||
for (auto &mw : mainWindows)
|
||||
mw.scaleSizes();
|
||||
|
||||
for (auto &fw : floatingWindows) {
|
||||
LayoutSaver::MainWindow mw = mainWindowForIndex(fw.parentIndex);
|
||||
if (mw.scalingInfo.isValid())
|
||||
fw.scaleSizes(mw.scalingInfo);
|
||||
|
||||
// MainWindow has a different size than the one in JSON, so we also restore FloatingWindows
|
||||
// relatively to the user set new MainWindow size
|
||||
const bool useRelativeSizesForFloatingWidgets =
|
||||
options & InternalRestoreOption::RelativeFloatingWindowGeometry;
|
||||
|
||||
if (useRelativeSizesForFloatingWidgets) {
|
||||
for (auto &fw : floatingWindows) {
|
||||
LayoutSaver::MainWindow mw = mainWindowForIndex(fw.parentIndex);
|
||||
if (mw.scalingInfo.isValid())
|
||||
fw.scaleSizes(mw.scalingInfo);
|
||||
}
|
||||
}
|
||||
|
||||
const ScalingInfo firstScalingInfo = mainWindows.constFirst().scalingInfo;
|
||||
if (firstScalingInfo.isValid()) {
|
||||
for (auto &dw : allDockWidgets) {
|
||||
// TODO: Determine the best main window. This only interesting for closed dock widget geometry
|
||||
// which was previously floating. But they still have some other main window as parent.
|
||||
// TODO: Determine the best main window. This only interesting for closed dock
|
||||
// widget geometry which was previously floating. But they still have some other
|
||||
// main window as parent.
|
||||
dw->scaleSizes(firstScalingInfo);
|
||||
}
|
||||
}
|
||||
@@ -471,6 +534,14 @@ LayoutSaver::MainWindow LayoutSaver::Layout::mainWindowForIndex(int index) const
|
||||
return mainWindows.at(index);
|
||||
}
|
||||
|
||||
LayoutSaver::FloatingWindow LayoutSaver::Layout::floatingWindowForIndex(int index) const
|
||||
{
|
||||
if (index < 0 || index >= floatingWindows.size())
|
||||
return {};
|
||||
|
||||
return floatingWindows.at(index);
|
||||
}
|
||||
|
||||
QStringList LayoutSaver::Layout::mainWindowNames() const
|
||||
{
|
||||
QStringList names;
|
||||
@@ -493,6 +564,35 @@ QStringList LayoutSaver::Layout::dockWidgetNames() const
|
||||
return names;
|
||||
}
|
||||
|
||||
QStringList LayoutSaver::Layout::dockWidgetsToClose() const
|
||||
{
|
||||
// Before restoring a layout we close all dock widgets, unless they're a floating window with the DontCloseBeforeRestore flag
|
||||
|
||||
QStringList names;
|
||||
names.reserve(allDockWidgets.size());
|
||||
auto registry = DockRegistry::self();
|
||||
for (const auto &dw : allDockWidgets) {
|
||||
if (DockWidgetBase *dockWidget = registry->dockByName(dw->uniqueName)) {
|
||||
|
||||
bool doClose = true;
|
||||
|
||||
if (dockWidget->skipsRestore()) {
|
||||
if (auto fw = dockWidget->floatingWindow()) {
|
||||
if (fw->allDockWidgetsHave(DockWidgetBase::LayoutSaverOption::Skip)) {
|
||||
// All dock widgets in this floating window skips float, so we can honour it for all.
|
||||
doClose = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doClose)
|
||||
names << dw->uniqueName;
|
||||
}
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
bool LayoutSaver::Frame::isValid() const
|
||||
{
|
||||
if (isNull)
|
||||
@@ -528,9 +628,24 @@ bool LayoutSaver::Frame::isValid() const
|
||||
return true;
|
||||
}
|
||||
|
||||
void LayoutSaver::Frame::scaleSizes(const ScalingInfo &scalingInfo)
|
||||
bool LayoutSaver::Frame::hasSingleDockWidget() const
|
||||
{
|
||||
scalingInfo.applyFactorsTo(geometry);
|
||||
return dockWidgets.size() == 1;
|
||||
}
|
||||
|
||||
bool LayoutSaver::Frame::skipsRestore() const
|
||||
{
|
||||
return std::all_of(dockWidgets.cbegin(), dockWidgets.cend(), [](LayoutSaver::DockWidget::Ptr dw) {
|
||||
return dw->skipsRestore();
|
||||
});
|
||||
}
|
||||
|
||||
LayoutSaver::DockWidget::Ptr LayoutSaver::Frame::singleDockWidget() const
|
||||
{
|
||||
if (!hasSingleDockWidget())
|
||||
return {};
|
||||
|
||||
return dockWidgets.first();
|
||||
}
|
||||
|
||||
QVariantMap LayoutSaver::Frame::toVariantMap() const
|
||||
@@ -560,7 +675,7 @@ void LayoutSaver::Frame::fromVariantMap(const QVariantMap &map)
|
||||
isNull = map.value(QStringLiteral("isNull")).toBool();
|
||||
objectName = map.value(QStringLiteral("objectName")).toString();
|
||||
geometry = Layouting::mapToRect(map.value(QStringLiteral("geometry")).toMap());
|
||||
options = map.value(QStringLiteral("options")).toUInt();
|
||||
options = static_cast<QFlags<FrameOption>::Int>(map.value(QStringLiteral("options")).toUInt());
|
||||
currentTabIndex = map.value(QStringLiteral("currentTabIndex")).toInt();
|
||||
|
||||
const QVariantList dockWidgetsV = map.value(QStringLiteral("dockWidgets")).toList();
|
||||
@@ -583,6 +698,14 @@ void LayoutSaver::DockWidget::scaleSizes(const ScalingInfo &scalingInfo)
|
||||
lastPosition.scaleSizes(scalingInfo);
|
||||
}
|
||||
|
||||
bool LayoutSaver::DockWidget::skipsRestore() const
|
||||
{
|
||||
if (DockWidgetBase *dw = DockRegistry::self()->dockByName(uniqueName))
|
||||
return dw->skipsRestore();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariantMap LayoutSaver::DockWidget::toVariantMap() const
|
||||
{
|
||||
QVariantMap map;
|
||||
@@ -621,10 +744,24 @@ bool LayoutSaver::FloatingWindow::isValid() const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LayoutSaver::FloatingWindow::hasSingleDockWidget() const
|
||||
{
|
||||
return multiSplitterLayout.hasSingleDockWidget();
|
||||
}
|
||||
|
||||
LayoutSaver::DockWidget::Ptr LayoutSaver::FloatingWindow::singleDockWidget() const
|
||||
{
|
||||
return multiSplitterLayout.singleDockWidget();
|
||||
}
|
||||
|
||||
bool LayoutSaver::FloatingWindow::skipsRestore() const
|
||||
{
|
||||
return multiSplitterLayout.skipsRestore();
|
||||
}
|
||||
|
||||
void LayoutSaver::FloatingWindow::scaleSizes(const ScalingInfo &scalingInfo)
|
||||
{
|
||||
scalingInfo.applyFactorsTo(/*by-ref*/geometry);
|
||||
multiSplitterLayout.scaleSizes(scalingInfo);
|
||||
scalingInfo.applyFactorsTo(/*by-ref*/ geometry);
|
||||
}
|
||||
|
||||
QVariantMap LayoutSaver::FloatingWindow::toVariantMap() const
|
||||
@@ -682,9 +819,6 @@ void LayoutSaver::MainWindow::scaleSizes()
|
||||
}
|
||||
|
||||
scalingInfo = ScalingInfo(uniqueName, geometry);
|
||||
|
||||
if (scalingInfo.isValid())
|
||||
multiSplitterLayout.scaleSizes(scalingInfo);
|
||||
}
|
||||
|
||||
QVariantMap LayoutSaver::MainWindow::toVariantMap() const
|
||||
@@ -698,6 +832,7 @@ QVariantMap LayoutSaver::MainWindow::toVariantMap() const
|
||||
map.insert(QStringLiteral("screenSize"), Layouting::sizeToMap(screenSize));
|
||||
map.insert(QStringLiteral("isVisible"), isVisible);
|
||||
map.insert(QStringLiteral("affinities"), stringListToVariant(affinities));
|
||||
map.insert(QStringLiteral("windowState"), windowState);
|
||||
|
||||
for (SideBarLocation loc : { SideBarLocation::North, SideBarLocation::East, SideBarLocation::West, SideBarLocation::South }) {
|
||||
const QStringList dockWidgets = dockWidgetsPerSideBar.value(loc);
|
||||
@@ -718,6 +853,7 @@ void LayoutSaver::MainWindow::fromVariantMap(const QVariantMap &map)
|
||||
screenSize = Layouting::mapToSize(map.value(QStringLiteral("screenSize")).toMap());
|
||||
isVisible = map.value(QStringLiteral("isVisible")).toBool();
|
||||
affinities = variantToStringList(map.value(QStringLiteral("affinities")).toList());
|
||||
windowState = Qt::WindowState(map.value(QStringLiteral("windowState"), Qt::WindowNoState).toInt());
|
||||
|
||||
// Compatibility hack. Old json format had a single "affinityName" instead of an "affinities" list:
|
||||
const QString affinityName = map.value(QStringLiteral("affinityName")).toString();
|
||||
@@ -747,11 +883,24 @@ bool LayoutSaver::MultiSplitter::isValid() const
|
||||
return true;
|
||||
}
|
||||
|
||||
void LayoutSaver::MultiSplitter::scaleSizes(const ScalingInfo &)
|
||||
bool LayoutSaver::MultiSplitter::hasSingleDockWidget() const
|
||||
{
|
||||
// scalingInfo.applyFactorsTo(/*by-ref*/size);
|
||||
//for (LayoutSaver::Item &item : items) TODO
|
||||
// item.scaleSizes(scalingInfo);
|
||||
return frames.size() == 1 && frames.cbegin()->hasSingleDockWidget();
|
||||
}
|
||||
|
||||
LayoutSaver::DockWidget::Ptr LayoutSaver::MultiSplitter::singleDockWidget() const
|
||||
{
|
||||
if (!hasSingleDockWidget())
|
||||
return {};
|
||||
|
||||
return frames.cbegin()->singleDockWidget();
|
||||
}
|
||||
|
||||
bool LayoutSaver::MultiSplitter::skipsRestore() const
|
||||
{
|
||||
return std::all_of(frames.cbegin(), frames.cend(), [](const LayoutSaver::Frame &frame) {
|
||||
return frame.skipsRestore();
|
||||
});
|
||||
}
|
||||
|
||||
QVariantMap LayoutSaver::MultiSplitter::toVariantMap() const
|
||||
@@ -781,7 +930,7 @@ void LayoutSaver::MultiSplitter::fromVariantMap(const QVariantMap &map)
|
||||
|
||||
void LayoutSaver::Position::scaleSizes(const ScalingInfo &scalingInfo)
|
||||
{
|
||||
scalingInfo.applyFactorsTo(/*by-ref*/lastFloatingGeometry);
|
||||
scalingInfo.applyFactorsTo(/*by-ref*/ lastFloatingGeometry);
|
||||
}
|
||||
|
||||
QVariantMap LayoutSaver::Position::toVariantMap() const
|
||||
@@ -883,8 +1032,7 @@ void LayoutSaver::ScalingInfo::translatePos(QPoint &pt) const
|
||||
|
||||
void LayoutSaver::ScalingInfo::applyFactorsTo(QPoint &pt) const
|
||||
{
|
||||
pt.setX(qCeil(pt.x() * widthFactor));
|
||||
pt.setY(qCeil(pt.y() * heightFactor));
|
||||
translatePos(pt);
|
||||
}
|
||||
|
||||
void LayoutSaver::ScalingInfo::applyFactorsTo(QSize &sz) const
|
||||
@@ -901,9 +1049,19 @@ void LayoutSaver::ScalingInfo::applyFactorsTo(QRect &rect) const
|
||||
QPoint pos = rect.topLeft();
|
||||
QSize size = rect.size();
|
||||
|
||||
applyFactorsTo(/*by-ref*/size);
|
||||
applyFactorsTo(/*by-ref*/pos);
|
||||
applyFactorsTo(/*by-ref*/ size);
|
||||
applyFactorsTo(/*by-ref*/ pos);
|
||||
|
||||
rect.moveTopLeft(pos);
|
||||
rect.setSize(size);
|
||||
}
|
||||
|
||||
LayoutSaver::Private::RAIIIsRestoring::RAIIIsRestoring()
|
||||
{
|
||||
LayoutSaver::Private::s_restoreInProgress = true;
|
||||
}
|
||||
|
||||
LayoutSaver::Private::RAIIIsRestoring::~RAIIIsRestoring()
|
||||
{
|
||||
LayoutSaver::Private::s_restoreInProgress = false;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,24 @@ namespace KDDockWidgets {
|
||||
|
||||
class DockWidgetBase;
|
||||
|
||||
|
||||
/**
|
||||
* @brief LayoutSaver allows to save or restore layouts.
|
||||
*
|
||||
* You can save a layout to a file or to a byte array.
|
||||
* JSON is used as the serialized format.
|
||||
*
|
||||
* Example:
|
||||
* LayoutSaver saver;
|
||||
*
|
||||
* // Save to a file:
|
||||
* saver.saveToFile(filename);
|
||||
*
|
||||
* The counterpart of saveToFile() is restoreFromFile().
|
||||
*
|
||||
* You can also save to a QByteArray instead, with serializeLayout().
|
||||
* The counterpart of serializeLayout() is restoreLayout();
|
||||
*/
|
||||
class DOCKS_EXPORT LayoutSaver
|
||||
{
|
||||
public:
|
||||
@@ -86,7 +104,6 @@ public:
|
||||
*/
|
||||
QVector<DockWidgetBase *> restoredDockWidgets() const;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sets the list of affinity names for which restore and save will be applied on.
|
||||
* Allows to save/restore only a subset of the windows.
|
||||
@@ -95,6 +112,10 @@ public:
|
||||
*/
|
||||
void setAffinityNames(const QStringList &affinityNames);
|
||||
|
||||
/// @internal Returns the private-impl. Not intended for public use.
|
||||
class Private;
|
||||
Private *dptr() const;
|
||||
|
||||
struct Layout;
|
||||
struct MainWindow;
|
||||
struct FloatingWindow;
|
||||
@@ -105,11 +126,11 @@ public:
|
||||
struct Placeholder;
|
||||
struct ScalingInfo;
|
||||
struct ScreenInfo;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(LayoutSaver)
|
||||
friend class ::TestDocks;
|
||||
|
||||
class Private;
|
||||
Private *const d;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,61 +18,73 @@
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "Config.h"
|
||||
#include "DropArea_p.h"
|
||||
#include "Frame_p.h"
|
||||
#include "Logging_p.h"
|
||||
#include "SideBar_p.h"
|
||||
#include "DropAreaWithCentralFrame_p.h"
|
||||
#include "FrameworkWidgetFactory.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include "private/DockRegistry_p.h"
|
||||
#include "private/DropAreaWithCentralFrame_p.h"
|
||||
#include "private/DropArea_p.h"
|
||||
#include "private/Frame_p.h"
|
||||
#include "private/Logging_p.h"
|
||||
#include "private/SideBar_p.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QScreen>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWindow>
|
||||
|
||||
// clazy:excludeall=ctor-missing-parent-argument,missing-qobject-macro
|
||||
|
||||
using namespace KDDockWidgets;
|
||||
|
||||
class MainWindow::Private
|
||||
{
|
||||
public:
|
||||
|
||||
explicit Private(MainWindowOptions, MainWindowBase *mainWindow)
|
||||
: m_supportsAutoHide(Config::self().flags() & Config::Flag_AutoHideSupport)
|
||||
{
|
||||
if (m_supportsAutoHide) {
|
||||
for (auto location : { SideBarLocation::North, SideBarLocation::East,
|
||||
SideBarLocation::West, SideBarLocation::South}) {
|
||||
m_sideBars.insert(location, Config::self().frameworkWidgetFactory()->createSideBar(location, mainWindow) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool m_supportsAutoHide;
|
||||
QHash<SideBarLocation, SideBar*> m_sideBars;
|
||||
};
|
||||
|
||||
namespace KDDockWidgets {
|
||||
class MyCentralWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
explicit MyCentralWidget(QWidget *parent = nullptr) : QWidget(parent)
|
||||
explicit MyCentralWidget(QWidget *parent = nullptr)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setObjectName(QStringLiteral("MyCentralWidget"));
|
||||
}
|
||||
|
||||
~MyCentralWidget() override;
|
||||
|
||||
void paintEvent(QPaintEvent *) override
|
||||
{
|
||||
QPainter p(this);
|
||||
QPen pen(QColor(184, 184, 184, 184));
|
||||
p.setPen(pen);
|
||||
p.drawLine(0, 0, width(), 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
MyCentralWidget::~MyCentralWidget() {}
|
||||
class MainWindow::Private
|
||||
{
|
||||
public:
|
||||
explicit Private(MainWindowOptions, MainWindow *mainWindow)
|
||||
: q(mainWindow)
|
||||
, m_supportsAutoHide(Config::self().flags() & Config::Flag_AutoHideSupport)
|
||||
, m_centralWidget(new MyCentralWidget(mainWindow))
|
||||
, m_layout(new QHBoxLayout(m_centralWidget)) // 1 level of indirection so we can add some margins
|
||||
{
|
||||
if (m_supportsAutoHide) {
|
||||
for (auto location : { SideBarLocation::North, SideBarLocation::East,
|
||||
SideBarLocation::West, SideBarLocation::South }) {
|
||||
m_sideBars.insert(location, Config::self().frameworkWidgetFactory()->createSideBar(location, mainWindow));
|
||||
}
|
||||
}
|
||||
|
||||
m_layout->setSpacing(0);
|
||||
updateMargins();
|
||||
}
|
||||
|
||||
void updateMargins()
|
||||
{
|
||||
m_layout->setContentsMargins(q->centerWidgetMargins());
|
||||
}
|
||||
|
||||
MainWindow *const q;
|
||||
const bool m_supportsAutoHide;
|
||||
QHash<SideBarLocation, SideBar *> m_sideBars;
|
||||
MyCentralWidget *const m_centralWidget;
|
||||
QHBoxLayout *const m_layout;
|
||||
};
|
||||
|
||||
MyCentralWidget::~MyCentralWidget()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MainWindow::MainWindow(const QString &name, MainWindowOptions options,
|
||||
@@ -80,26 +92,28 @@ MainWindow::MainWindow(const QString &name, MainWindowOptions options,
|
||||
: MainWindowBase(name, options, parent, flags)
|
||||
, d(new Private(options, this))
|
||||
{
|
||||
auto centralWidget = new MyCentralWidget(this);
|
||||
auto layout = new QHBoxLayout(centralWidget); // 1 level of indirection so we can add some margins
|
||||
layout->setSpacing(0);
|
||||
layout->setContentsMargins(centerWidgetMargins());
|
||||
|
||||
if (d->m_supportsAutoHide) {
|
||||
layout->addWidget(sideBar(SideBarLocation::West));
|
||||
d->m_layout->addWidget(sideBar(SideBarLocation::West));
|
||||
auto innerVLayout = new QVBoxLayout();
|
||||
innerVLayout->setSpacing(0);
|
||||
innerVLayout->setContentsMargins(0, 0, 0, 0);
|
||||
innerVLayout->addWidget(sideBar(SideBarLocation::North));
|
||||
innerVLayout->addWidget(dropArea());
|
||||
innerVLayout->addWidget(layoutWidget());
|
||||
innerVLayout->addWidget(sideBar(SideBarLocation::South));
|
||||
layout->addLayout(innerVLayout);
|
||||
layout->addWidget(sideBar(SideBarLocation::East));
|
||||
d->m_layout->addLayout(innerVLayout);
|
||||
d->m_layout->addWidget(sideBar(SideBarLocation::East));
|
||||
} else {
|
||||
layout->addWidget(dropArea());
|
||||
d->m_layout->addWidget(layoutWidget());
|
||||
}
|
||||
|
||||
setCentralWidget(centralWidget);
|
||||
setCentralWidget(d->m_centralWidget);
|
||||
|
||||
create();
|
||||
connect(windowHandle(), &QWindow::screenChanged, DockRegistry::self(),
|
||||
[this] {
|
||||
d->updateMargins(); // logical dpi might have changed
|
||||
Q_EMIT DockRegistry::self()->windowChangedScreen(windowHandle());
|
||||
});
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@@ -125,7 +139,8 @@ void MainWindow::resizeEvent(QResizeEvent *ev)
|
||||
|
||||
QMargins MainWindow::centerWidgetMargins() const
|
||||
{
|
||||
return { 1, 5, 1, 1};
|
||||
const QMargins margins = { 1, 5, 1, 1 };
|
||||
return margins * logicalDpiFactor(this);
|
||||
}
|
||||
|
||||
QRect MainWindow::centralAreaGeometry() const
|
||||
|
||||
@@ -33,7 +33,7 @@ class DOCKS_EXPORT MainWindow : public MainWindowBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef QVector<MainWindow*> List;
|
||||
typedef QVector<MainWindow *> List;
|
||||
|
||||
///@brief Constructor. Use it as you would use QMainWindow.
|
||||
///@param uniqueName Mandatory name that should be unique between all MainWindow instances.
|
||||
@@ -54,6 +54,7 @@ protected:
|
||||
void resizeEvent(QResizeEvent *) override;
|
||||
QMargins centerWidgetMargins() const override;
|
||||
QRect centralAreaGeometry() const override;
|
||||
|
||||
private:
|
||||
using QMainWindow::setCentralWidget;
|
||||
void setCentralWidget(QWidget *); // overridden just to make it private
|
||||
|
||||
@@ -18,25 +18,36 @@
|
||||
*/
|
||||
|
||||
#include "MainWindowBase.h"
|
||||
#include "DockRegistry_p.h"
|
||||
#include "DropArea_p.h"
|
||||
#include "Frame_p.h"
|
||||
#include "Utils_p.h"
|
||||
#include "SideBar_p.h"
|
||||
#include "Logging_p.h"
|
||||
#include "WidgetResizeHandler_p.h"
|
||||
#include "private/DockRegistry_p.h"
|
||||
#include "private/MDILayoutWidget_p.h"
|
||||
#include "private/DropArea_p.h"
|
||||
#include "private/Frame_p.h"
|
||||
#include "private/Utils_p.h"
|
||||
#include "private/SideBar_p.h"
|
||||
#include "private/Logging_p.h"
|
||||
#include "private/WidgetResizeHandler_p.h"
|
||||
#include "FrameworkWidgetFactory.h"
|
||||
#include "DropAreaWithCentralFrame_p.h"
|
||||
#include "private/DropAreaWithCentralFrame_p.h"
|
||||
#include "private/LayoutSaver_p.h"
|
||||
#include "private/DockWidgetBase_p.h"
|
||||
|
||||
using namespace KDDockWidgets;
|
||||
|
||||
static LayoutWidget *createLayoutWidget(MainWindowBase *mainWindow, MainWindowOptions options)
|
||||
{
|
||||
if (options & MainWindowOption_MDI)
|
||||
return new MDILayoutWidget(mainWindow);
|
||||
|
||||
return new DropAreaWithCentralFrame(mainWindow, options);
|
||||
}
|
||||
|
||||
class MainWindowBase::Private
|
||||
{
|
||||
public:
|
||||
explicit Private(MainWindowBase *mainWindow, MainWindowOptions options)
|
||||
: m_options(options)
|
||||
, q(mainWindow)
|
||||
, m_dropArea(new DropAreaWithCentralFrame(mainWindow, options))
|
||||
, m_layoutWidget(createLayoutWidget(mainWindow, options))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -45,11 +56,11 @@ public:
|
||||
return m_options & MainWindowOption_HasCentralFrame;
|
||||
}
|
||||
|
||||
WidgetResizeHandler::CursorPositions allowedResizeSides(SideBarLocation loc) const;
|
||||
CursorPositions allowedResizeSides(SideBarLocation loc) const;
|
||||
|
||||
QRect rectForOverlay(Frame *, SideBarLocation) const;
|
||||
SideBarLocation preferredSideBar(DockWidgetBase *) const;
|
||||
void updateOverlayGeometry(bool reusePreviousSize = false);
|
||||
void updateOverlayGeometry(QSize suggestedSize);
|
||||
void clearSideBars();
|
||||
|
||||
QString name;
|
||||
@@ -57,7 +68,7 @@ public:
|
||||
const MainWindowOptions m_options;
|
||||
MainWindowBase *const q;
|
||||
QPointer<DockWidgetBase> m_overlayedDockWidget;
|
||||
DropAreaWithCentralFrame *const m_dropArea;
|
||||
LayoutWidget *const m_layoutWidget;
|
||||
};
|
||||
|
||||
MainWindowBase::MainWindowBase(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
|
||||
@@ -66,6 +77,9 @@ MainWindowBase::MainWindowBase(const QString &uniqueName, KDDockWidgets::MainWin
|
||||
, d(new Private(this, options))
|
||||
{
|
||||
setUniqueName(uniqueName);
|
||||
|
||||
connect(d->m_layoutWidget, &LayoutWidget::visibleWidgetCountChanged, this,
|
||||
&MainWindowBase::frameCountChanged);
|
||||
}
|
||||
|
||||
MainWindowBase::~MainWindowBase()
|
||||
@@ -90,6 +104,11 @@ void MainWindowBase::addDockWidgetAsTab(DockWidgetBase *widget)
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMDI()) {
|
||||
// Not applicable to MDI
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->supportsCentralFrame()) {
|
||||
dropArea()->m_centralFrame->addWidget(widget);
|
||||
} else {
|
||||
@@ -105,6 +124,11 @@ void MainWindowBase::addDockWidget(DockWidgetBase *dw, Location location,
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMDI()) {
|
||||
// Not applicable to MDI
|
||||
return;
|
||||
}
|
||||
|
||||
dropArea()->addDockWidget(dw, location, relativeTo, option);
|
||||
}
|
||||
|
||||
@@ -120,7 +144,7 @@ MainWindowOptions MainWindowBase::options() const
|
||||
|
||||
DropAreaWithCentralFrame *MainWindowBase::dropArea() const
|
||||
{
|
||||
return d->m_dropArea;
|
||||
return qobject_cast<DropAreaWithCentralFrame *>(d->m_layoutWidget);
|
||||
}
|
||||
|
||||
MultiSplitter *MainWindowBase::multiSplitter() const
|
||||
@@ -128,6 +152,16 @@ MultiSplitter *MainWindowBase::multiSplitter() const
|
||||
return dropArea();
|
||||
}
|
||||
|
||||
LayoutWidget *MainWindowBase::layoutWidget() const
|
||||
{
|
||||
return d->m_layoutWidget;
|
||||
}
|
||||
|
||||
MDILayoutWidget *MainWindowBase::mdiLayoutWidget() const
|
||||
{
|
||||
return qobject_cast<MDILayoutWidget *>(layoutWidget());
|
||||
}
|
||||
|
||||
void MainWindowBase::setAffinities(const QStringList &affinityNames)
|
||||
{
|
||||
QStringList affinities = affinityNames;
|
||||
@@ -161,25 +195,25 @@ void MainWindowBase::layoutParentContainerEqually(DockWidgetBase *dockWidget)
|
||||
dropArea()->layoutParentContainerEqually(dockWidget);
|
||||
}
|
||||
|
||||
WidgetResizeHandler::CursorPositions MainWindowBase::Private::allowedResizeSides(SideBarLocation loc) const
|
||||
CursorPositions MainWindowBase::Private::allowedResizeSides(SideBarLocation loc) const
|
||||
{
|
||||
// When a sidebar is on top, you can only resize its bottom.
|
||||
// and so forth...
|
||||
|
||||
switch (loc) {
|
||||
case SideBarLocation::North:
|
||||
return WidgetResizeHandler::CursorPosition_Bottom;
|
||||
return CursorPosition_Bottom;
|
||||
case SideBarLocation::East:
|
||||
return WidgetResizeHandler::CursorPosition_Left;
|
||||
return CursorPosition_Left;
|
||||
case SideBarLocation::West:
|
||||
return WidgetResizeHandler::CursorPosition_Right;
|
||||
return CursorPosition_Right;
|
||||
case SideBarLocation::South:
|
||||
return WidgetResizeHandler::CursorPosition_Top;
|
||||
return CursorPosition_Top;
|
||||
case SideBarLocation::None:
|
||||
return WidgetResizeHandler::CursorPosition_Undefined;
|
||||
return CursorPosition_Undefined;
|
||||
}
|
||||
|
||||
return WidgetResizeHandler::CursorPosition_Undefined;
|
||||
return CursorPosition_Undefined;
|
||||
}
|
||||
|
||||
QRect MainWindowBase::Private::rectForOverlay(Frame *frame, SideBarLocation location) const
|
||||
@@ -286,7 +320,7 @@ SideBarLocation MainWindowBase::Private::preferredSideBar(DockWidgetBase *dw) co
|
||||
{
|
||||
// TODO: Algorithm can still be made smarter
|
||||
|
||||
Layouting::Item *item = q->multiSplitter()->itemForFrame(dw->frame());
|
||||
Layouting::Item *item = q->layoutWidget()->itemForFrame(dw->d->frame());
|
||||
if (!item) {
|
||||
qWarning() << Q_FUNC_INFO << "No item for dock widget";
|
||||
return SideBarLocation::None;
|
||||
@@ -348,7 +382,7 @@ SideBarLocation MainWindowBase::Private::preferredSideBar(DockWidgetBase *dw) co
|
||||
: SideBarLocation::West;
|
||||
}
|
||||
|
||||
void MainWindowBase::Private::updateOverlayGeometry(bool reusePreviousSize)
|
||||
void MainWindowBase::Private::updateOverlayGeometry(QSize suggestedSize)
|
||||
{
|
||||
if (!m_overlayedDockWidget)
|
||||
return;
|
||||
@@ -359,46 +393,45 @@ void MainWindowBase::Private::updateOverlayGeometry(bool reusePreviousSize)
|
||||
return;
|
||||
}
|
||||
|
||||
const QRect defaultGeometry = rectForOverlay(m_overlayedDockWidget->frame(), sb->location());
|
||||
const QRect defaultGeometry = rectForOverlay(m_overlayedDockWidget->d->frame(), sb->location());
|
||||
QRect newGeometry = defaultGeometry;
|
||||
|
||||
Frame *frame = m_overlayedDockWidget->frame();
|
||||
Frame *frame = m_overlayedDockWidget->d->frame();
|
||||
|
||||
if (reusePreviousSize) {
|
||||
// Let's try to honour the previous overlay size
|
||||
if (suggestedSize.isValid() && !suggestedSize.isEmpty()) {
|
||||
// Let's try to honour the suggested overlay size
|
||||
switch (sb->location()) {
|
||||
case SideBarLocation::North: {
|
||||
const int maxHeight = q->height() - frame->pos().y() - 10; // gap
|
||||
newGeometry.setHeight(qMin(frame->height(), maxHeight));
|
||||
newGeometry.setHeight(qMin(suggestedSize.height(), maxHeight));
|
||||
break;
|
||||
}
|
||||
case SideBarLocation::South: {
|
||||
const int maxHeight = sb->pos().y() - m_dropArea->pos().y() - 10; // gap
|
||||
const int maxHeight = sb->pos().y() - m_layoutWidget->pos().y() - 10; // gap
|
||||
const int bottom = newGeometry.bottom();
|
||||
newGeometry.setHeight(qMin(frame->height(), maxHeight));
|
||||
newGeometry.setHeight(qMin(suggestedSize.height(), maxHeight));
|
||||
newGeometry.moveBottom(bottom);
|
||||
break;
|
||||
}
|
||||
case SideBarLocation::East: {
|
||||
const int maxWidth = sb->pos().x() - m_dropArea->pos().x() - 10; // gap
|
||||
const int maxWidth = sb->pos().x() - m_layoutWidget->pos().x() - 10; // gap
|
||||
const int right = newGeometry.right();
|
||||
newGeometry.setWidth(qMin(frame->width(), maxWidth));
|
||||
newGeometry.setWidth(qMin(suggestedSize.width(), maxWidth));
|
||||
newGeometry.moveRight(right);
|
||||
break;
|
||||
}
|
||||
case SideBarLocation::West: {
|
||||
const int maxWidth = q->width() - frame->pos().x() - 10; // gap
|
||||
newGeometry.setWidth(qMin(frame->height(), maxWidth));
|
||||
newGeometry.setWidth(qMin(suggestedSize.width(), maxWidth));
|
||||
break;
|
||||
}
|
||||
case SideBarLocation::None:
|
||||
qWarning() << Q_FUNC_INFO << "Unexpected sidebar value";
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_overlayedDockWidget->frame()->QWidgetAdapter::setGeometry(newGeometry);
|
||||
m_overlayedDockWidget->d->frame()->QWidgetAdapter::setGeometry(newGeometry);
|
||||
}
|
||||
|
||||
void MainWindowBase::Private::clearSideBars()
|
||||
@@ -418,6 +451,7 @@ void MainWindowBase::moveToSideBar(DockWidgetBase *dw)
|
||||
void MainWindowBase::moveToSideBar(DockWidgetBase *dw, SideBarLocation location)
|
||||
{
|
||||
if (SideBar *sb = sideBar(location)) {
|
||||
QScopedValueRollback<bool> rollback(dw->d->m_isMovingToSideBar, true);
|
||||
dw->forceClose();
|
||||
sb->addDockWidget(dw);
|
||||
} else {
|
||||
@@ -465,12 +499,9 @@ void MainWindowBase::overlayOnSideBar(DockWidgetBase *dw)
|
||||
auto frame = Config::self().frameworkWidgetFactory()->createFrame(this, FrameOption_IsOverlayed);
|
||||
d->m_overlayedDockWidget = dw;
|
||||
frame->addWidget(dw);
|
||||
d->updateOverlayGeometry(/*reusePreviousSize=*/ false);
|
||||
|
||||
// Uncomment once I'm happy with the resizing
|
||||
auto resizeHandler = new WidgetResizeHandler(true, frame);
|
||||
resizeHandler->setAllowedResizeSides(d->allowedResizeSides(sb->location()));
|
||||
d->updateOverlayGeometry(dw->d->lastPositions().lastOverlayedGeometry(sb->location()).size());
|
||||
|
||||
frame->setAllowedResizeSides(d->allowedResizeSides(sb->location()));
|
||||
frame->QWidgetAdapter::show();
|
||||
|
||||
Q_EMIT dw->isOverlayedChanged(true);
|
||||
@@ -485,16 +516,34 @@ void MainWindowBase::toggleOverlayOnSideBar(DockWidgetBase *dw)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindowBase::clearSideBarOverlay()
|
||||
void MainWindowBase::clearSideBarOverlay(bool deleteFrame)
|
||||
{
|
||||
if (!d->m_overlayedDockWidget)
|
||||
return;
|
||||
|
||||
Frame *frame = d->m_overlayedDockWidget->frame();
|
||||
d->m_overlayedDockWidget->setParent(nullptr);
|
||||
Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
|
||||
d->m_overlayedDockWidget = nullptr;
|
||||
delete frame;
|
||||
Frame *frame = d->m_overlayedDockWidget->d->frame();
|
||||
if (!frame) { // prophylactic check
|
||||
d->m_overlayedDockWidget = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
const SideBarLocation loc = d->m_overlayedDockWidget->sideBarLocation();
|
||||
d->m_overlayedDockWidget->d->lastPositions().setLastOverlayedGeometry(
|
||||
loc, frame->QWidgetAdapter::geometry());
|
||||
|
||||
frame->unoverlay();
|
||||
|
||||
if (deleteFrame) {
|
||||
d->m_overlayedDockWidget->setParent(nullptr);
|
||||
Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
|
||||
d->m_overlayedDockWidget = nullptr;
|
||||
delete frame;
|
||||
} else {
|
||||
// No cleanup, just unset. When we drag the overlay it becomes a normal floating window
|
||||
// meaning we reuse Frame. Don't delete it.
|
||||
Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
|
||||
d->m_overlayedDockWidget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
SideBar *MainWindowBase::sideBarForDockWidget(const DockWidgetBase *dw) const
|
||||
@@ -536,6 +585,41 @@ bool MainWindowBase::anySideBarIsVisible() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWindowBase::isMDI() const
|
||||
{
|
||||
return d->m_options & MainWindowOption_MDI;
|
||||
}
|
||||
|
||||
bool MainWindowBase::closeDockWidgets(bool force)
|
||||
{
|
||||
bool allClosed = true;
|
||||
|
||||
const auto dockWidgets = d->m_layoutWidget->dockWidgets();
|
||||
for (DockWidgetBase *dw : dockWidgets) {
|
||||
Frame *frame = dw->d->frame();
|
||||
|
||||
if (force) {
|
||||
dw->forceClose();
|
||||
} else {
|
||||
const bool closed = dw->close();
|
||||
allClosed = allClosed && closed;
|
||||
}
|
||||
|
||||
if (frame->beingDeletedLater()) {
|
||||
// The dock widget was closed and this frame is empty, delete immediately instead of
|
||||
// waiting. I'm not a big fan of deleting stuff later, as state becomes inconsistent
|
||||
|
||||
// Empty frames are historically deleted later since they are triggered by mouse click
|
||||
// on the title bar, and the title bar is inside the frame.
|
||||
// When doing it programmatically we can delete immediately.
|
||||
|
||||
delete frame;
|
||||
}
|
||||
}
|
||||
|
||||
return allClosed;
|
||||
}
|
||||
|
||||
void MainWindowBase::setUniqueName(const QString &uniqueName)
|
||||
{
|
||||
if (uniqueName.isEmpty())
|
||||
@@ -553,7 +637,7 @@ void MainWindowBase::setUniqueName(const QString &uniqueName)
|
||||
void MainWindowBase::onResized(QResizeEvent *)
|
||||
{
|
||||
if (d->m_overlayedDockWidget)
|
||||
d->updateOverlayGeometry(/*reusePreviousSize=*/ true);
|
||||
d->updateOverlayGeometry(d->m_overlayedDockWidget->d->frame()->QWidgetAdapter::size());
|
||||
}
|
||||
|
||||
bool MainWindowBase::deserialize(const LayoutSaver::MainWindow &mw)
|
||||
@@ -571,7 +655,7 @@ bool MainWindowBase::deserialize(const LayoutSaver::MainWindow &mw)
|
||||
d->affinities = mw.affinities;
|
||||
}
|
||||
|
||||
const bool success = dropArea()->deserialize(mw.multiSplitterLayout);
|
||||
const bool success = layoutWidget()->deserialize(mw.multiSplitterLayout);
|
||||
|
||||
// Restore the SideBars
|
||||
d->clearSideBars();
|
||||
@@ -583,7 +667,7 @@ bool MainWindowBase::deserialize(const LayoutSaver::MainWindow &mw)
|
||||
const QStringList dockWidgets = mw.dockWidgetsPerSideBar.value(loc);
|
||||
for (const QString &uniqueName : dockWidgets) {
|
||||
|
||||
DockWidgetBase *dw = DockRegistry::self()->dockByName(uniqueName);
|
||||
DockWidgetBase *dw = DockRegistry::self()->dockByName(uniqueName, DockRegistry::DockByNameFlag::CreateIfNotFound);
|
||||
if (!dw) {
|
||||
qWarning() << Q_FUNC_INFO << "Could not find dock widget" << uniqueName
|
||||
<< ". Won't restore it to sidebar";
|
||||
@@ -594,7 +678,7 @@ bool MainWindowBase::deserialize(const LayoutSaver::MainWindow &mw)
|
||||
}
|
||||
}
|
||||
|
||||
// Commented-out for now, we dont' want to restore the popup/overlay. popups are perishable
|
||||
// Commented-out for now, we don't want to restore the popup/overlay. popups are perishable
|
||||
//if (!mw.overlayedDockWidget.isEmpty())
|
||||
// overlayOnSideBar(DockRegistry::self()->dockByName(mw.overlayedDockWidget));
|
||||
|
||||
@@ -606,13 +690,15 @@ LayoutSaver::MainWindow MainWindowBase::serialize() const
|
||||
LayoutSaver::MainWindow m;
|
||||
|
||||
m.options = options();
|
||||
m.geometry = window()->geometry(); // window() as the MainWindow can be embedded
|
||||
m.geometry = windowGeometry();
|
||||
m.isVisible = isVisible();
|
||||
m.uniqueName = uniqueName();
|
||||
m.screenIndex = screenNumberForWidget(this);
|
||||
m.screenSize = screenSizeForWidget(this);
|
||||
m.multiSplitterLayout = dropArea()->serialize();
|
||||
m.multiSplitterLayout = layoutWidget()->serialize();
|
||||
m.affinities = d->affinities;
|
||||
m.windowState = windowHandle() ? windowHandle()->windowState()
|
||||
: Qt::WindowNoState;
|
||||
|
||||
for (SideBarLocation loc : { SideBarLocation::North, SideBarLocation::East, SideBarLocation::West, SideBarLocation::South }) {
|
||||
if (SideBar *sb = sideBar(loc)) {
|
||||
@@ -624,3 +710,11 @@ LayoutSaver::MainWindow MainWindowBase::serialize() const
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
QRect MainWindowBase::windowGeometry() const
|
||||
{
|
||||
if (QWindow *window = windowHandle())
|
||||
return window->geometry();
|
||||
|
||||
return window()->geometry();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user