mirror of
https://invent.kde.org/multimedia/kdenlive
synced 2025-12-07 00:39:58 +01:00
Compare commits
746 Commits
audioAlign
...
v0.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f0072e81e | ||
|
|
1209aa73f6 | ||
|
|
022bd7997c | ||
|
|
fdd7c8009e | ||
|
|
9cbc0bee24 | ||
|
|
83ec01298c | ||
|
|
eae5b982e1 | ||
|
|
1dd98a7192 | ||
|
|
00779bb588 | ||
|
|
bfbfd81fd8 | ||
|
|
193e2ef6b8 | ||
|
|
c59d91bd42 | ||
|
|
2d0ecef61f | ||
|
|
537e37a167 | ||
|
|
336e36b6e9 | ||
|
|
c3508f3e9c | ||
|
|
5a5914957e | ||
|
|
3c9669bae8 | ||
|
|
dbcf08fcce | ||
|
|
23c57780f7 | ||
|
|
513ed94084 | ||
|
|
3f52582763 | ||
|
|
8ca0eed20d | ||
|
|
b35e1a3dba | ||
|
|
01c741d54f | ||
|
|
1b81912437 | ||
|
|
c50a0a2041 | ||
|
|
73e88501a8 | ||
|
|
fee0b75196 | ||
|
|
2d345d27d2 | ||
|
|
33fe961d18 | ||
|
|
4d45d7ad45 | ||
|
|
34353faca5 | ||
|
|
8592b9b6ae | ||
|
|
0ff236168b | ||
|
|
a387d600f8 | ||
|
|
7173aa98d8 | ||
|
|
bcf08c498f | ||
|
|
eac1b3327b | ||
|
|
b67d828f7e | ||
|
|
fd20099d8c | ||
|
|
1a606184fc | ||
|
|
7772670696 | ||
|
|
2d112ee988 | ||
|
|
2a124c65bd | ||
|
|
7779799363 | ||
|
|
60080ee350 | ||
|
|
d0f65b8150 | ||
|
|
e29a82b194 | ||
|
|
e6e33563c2 | ||
|
|
678e5dcf4e | ||
|
|
eec276a118 | ||
|
|
afe7756540 | ||
|
|
6674bfdc17 | ||
|
|
289fc73853 | ||
|
|
eb06619a0a | ||
|
|
a75037c6a1 | ||
|
|
793e8d2bbb | ||
|
|
76ea18353d | ||
|
|
e7dc0a1b1e | ||
|
|
a4fa666c8a | ||
|
|
e29c652911 | ||
|
|
6d7549d66e | ||
|
|
45e05743ec | ||
|
|
99f57e63b9 | ||
|
|
2914c46076 | ||
|
|
9a6ceaf6e8 | ||
|
|
adb49a05e6 | ||
|
|
ca2c886d9c | ||
|
|
b5f15b5511 | ||
|
|
f79ea4599e | ||
|
|
cf1c2d258e | ||
|
|
513a2ac48f | ||
|
|
61338f46e0 | ||
|
|
86573f5af7 | ||
|
|
f7e5022a6c | ||
|
|
571306d08f | ||
|
|
0a09501e0c | ||
|
|
7f33dc7172 | ||
|
|
a7bf8b62a6 | ||
|
|
9f99f99144 | ||
|
|
5fd529c9d1 | ||
|
|
98af63466c | ||
|
|
26b741520f | ||
|
|
966f5b5631 | ||
|
|
f7e377c7d1 | ||
|
|
a26ff7a60e | ||
|
|
3b9ad419df | ||
|
|
f3b1d93fb4 | ||
|
|
810073d69e | ||
|
|
b9dbc28d11 | ||
|
|
603b5a8542 | ||
|
|
a34e364e31 | ||
|
|
05f20eda70 | ||
|
|
23f7586ada | ||
|
|
d969e21a43 | ||
|
|
b8c84bfc3a | ||
|
|
37e4286e80 | ||
|
|
1981be1b0a | ||
|
|
5f071d35e3 | ||
|
|
5f4485e01b | ||
|
|
2eb09035ea | ||
|
|
5c2ad19df0 | ||
|
|
a76b021066 | ||
|
|
3e33dd74fd | ||
|
|
cb1c225356 | ||
|
|
242b34a2e1 | ||
|
|
2c77d2db7e | ||
|
|
e7e8e21ba3 | ||
|
|
b1d191ee26 | ||
|
|
8b8f66a146 | ||
|
|
638515b2f6 | ||
|
|
63eb21e781 | ||
|
|
d243276781 | ||
|
|
6f2a8ed39e | ||
|
|
ca829270a3 | ||
|
|
a67e13aa59 | ||
|
|
28218f3054 | ||
|
|
68f5ff3168 | ||
|
|
7e99d96c22 | ||
|
|
5f3bb4eeb8 | ||
|
|
31001d60c9 | ||
|
|
18796c1016 | ||
|
|
65be8a5a31 | ||
|
|
5e2cb0f4e6 | ||
|
|
f22f080db6 | ||
|
|
0415de1eed | ||
|
|
c89f6b3879 | ||
|
|
5bb198126e | ||
|
|
38628dd8a1 | ||
|
|
2747a209dc | ||
|
|
519dce4464 | ||
|
|
8ed5bce13f | ||
|
|
629b0cb6de | ||
|
|
45b0b4dc6c | ||
|
|
0478cf276a | ||
|
|
f3bca8009f | ||
|
|
08614d7be6 | ||
|
|
74d4a56cea | ||
|
|
b4cd8e5882 | ||
|
|
96d873bb2b | ||
|
|
8ca44cc603 | ||
|
|
4dd620b9c3 | ||
|
|
910e49c805 | ||
|
|
0097caf273 | ||
|
|
f2e2aa0b76 | ||
|
|
f663bdd328 | ||
|
|
ab3b5e2ca7 | ||
|
|
2af433083b | ||
|
|
bf992aef55 | ||
|
|
b378528894 | ||
|
|
dca8b03ba3 | ||
|
|
142e3e41d6 | ||
|
|
a01e37d60c | ||
|
|
5eaf1c602a | ||
|
|
f7573287d1 | ||
|
|
5948ee0151 | ||
|
|
b4633f1d6b | ||
|
|
fe5586ec6d | ||
|
|
31012828bb | ||
|
|
7c9855c7b5 | ||
|
|
952681475b | ||
|
|
10d1c827c1 | ||
|
|
066d37fc43 | ||
|
|
1efbcfc92a | ||
|
|
2e654bcec3 | ||
|
|
06a8be51bc | ||
|
|
ce50b7deb5 | ||
|
|
ffd37b37a2 | ||
|
|
32813818d1 | ||
|
|
81e7614799 | ||
|
|
256767b764 | ||
|
|
e467a6a777 | ||
|
|
b67fb9481a | ||
|
|
c6b1beff20 | ||
|
|
8c96562a49 | ||
|
|
c030d42f97 | ||
|
|
6e93ff5fe7 | ||
|
|
029d2db59a | ||
|
|
95c1b91921 | ||
|
|
ed31bc0d0d | ||
|
|
fc8ccb61a4 | ||
|
|
a121e94dd9 | ||
|
|
6c8b8a6e03 | ||
|
|
f43ef86a0f | ||
|
|
2abbfe2ef0 | ||
|
|
0438a0682c | ||
|
|
12cd43cfd4 | ||
|
|
8afe094faa | ||
|
|
c3cc3abc21 | ||
|
|
e5752ab314 | ||
|
|
a84ecc52ea | ||
|
|
1ddbf38fad | ||
|
|
88fab6e0fd | ||
|
|
8c55aa37ab | ||
|
|
2dd1db6676 | ||
|
|
bc55890a55 | ||
|
|
ed37f7bad2 | ||
|
|
39465e1126 | ||
|
|
cabd83dcf4 | ||
|
|
79634a597c | ||
|
|
d06b38d7e6 | ||
|
|
f50634a4de | ||
|
|
a44e4ced83 | ||
|
|
0088750869 | ||
|
|
bc95cc02c1 | ||
|
|
aa58692458 | ||
|
|
77b5c4becd | ||
|
|
bea3e057f8 | ||
|
|
3701617d75 | ||
|
|
b3ee29e687 | ||
|
|
9256029a01 | ||
|
|
cfedab39f0 | ||
|
|
43dcc8bcec | ||
|
|
2e19960808 | ||
|
|
456efd6445 | ||
|
|
fe9248af58 | ||
|
|
28406cbc78 | ||
|
|
fde4c3affb | ||
|
|
382b731ef8 | ||
|
|
bc24dd0547 | ||
|
|
3c9c2762bc | ||
|
|
798becb879 | ||
|
|
00118ecfed | ||
|
|
3e0341727e | ||
|
|
195ea6b6ef | ||
|
|
3ac7926509 | ||
|
|
e687ac0352 | ||
|
|
a0d3941b85 | ||
|
|
0ec4289e12 | ||
|
|
61c33cd043 | ||
|
|
62fc36de3a | ||
|
|
599909d0e4 | ||
|
|
1cb68ab635 | ||
|
|
5937575100 | ||
|
|
e5e694dff0 | ||
|
|
d850307c9a | ||
|
|
4f4107b7ed | ||
|
|
7bd1fe25a4 | ||
|
|
4945e4f986 | ||
|
|
24ca8fbc26 | ||
|
|
23dc375673 | ||
|
|
d91a9ffb62 | ||
|
|
fc6d807720 | ||
|
|
9c55a7673d | ||
|
|
fe156af311 | ||
|
|
91ea03539f | ||
|
|
42c6e91470 | ||
|
|
5592ccc13c | ||
|
|
d2c65ec06a | ||
|
|
affa16ba1e | ||
|
|
c589269fd6 | ||
|
|
26d8168764 | ||
|
|
ed5a2c50b2 | ||
|
|
e06a4ef2cf | ||
|
|
c3fa0f6b32 | ||
|
|
f02f17aa9e | ||
|
|
e070d4a42a | ||
|
|
ebc919bf53 | ||
|
|
b929781756 | ||
|
|
a8592dd7fb | ||
|
|
ad2a5a339a | ||
|
|
ee41343805 | ||
|
|
5794e725b2 | ||
|
|
51610e2e7c | ||
|
|
0ae06f0ace | ||
|
|
d1019376c0 | ||
|
|
d20fa38526 | ||
|
|
157428a666 | ||
|
|
c1d3481eb5 | ||
|
|
25b8bcc770 | ||
|
|
c5e042e1e8 | ||
|
|
ef8fbd60d3 | ||
|
|
f15361123a | ||
|
|
3f32160f5f | ||
|
|
43d88a8f5f | ||
|
|
543c6a2389 | ||
|
|
1a07028e9a | ||
|
|
261291108f | ||
|
|
5881fda044 | ||
|
|
e2ba5297bf | ||
|
|
b94d740d40 | ||
|
|
1f5c19bcf7 | ||
|
|
0a470cfe6d | ||
|
|
ff0585a36b | ||
|
|
662a801650 | ||
|
|
d9369573d1 | ||
|
|
fdb0c519cc | ||
|
|
5ed1c89abc | ||
|
|
263f5cbe3f | ||
|
|
d1b3811243 | ||
|
|
68a4690524 | ||
|
|
e384cfce0d | ||
|
|
8a308c87de | ||
|
|
baf425ed61 | ||
|
|
de24fac8fc | ||
|
|
f8cedebe26 | ||
|
|
2fde4655d7 | ||
|
|
9d5d4f3acc | ||
|
|
8391434d0c | ||
|
|
eb74feb585 | ||
|
|
4c1498b707 | ||
|
|
5851418c91 | ||
|
|
16e193e8de | ||
|
|
c8ebcc09c2 | ||
|
|
56cc4b662e | ||
|
|
d93121f700 | ||
|
|
f12da75ef2 | ||
|
|
bb6a9922f1 | ||
|
|
dab2779376 | ||
|
|
1a0e490dbd | ||
|
|
e9069aace0 | ||
|
|
dc7a5edefe | ||
|
|
863679d878 | ||
|
|
d213b296a2 | ||
|
|
6e8e2fba5f | ||
|
|
1a57025e45 | ||
|
|
68c7f874ec | ||
|
|
7c8c0a4bed | ||
|
|
07ddbd1d2a | ||
|
|
bdfcbfc3ec | ||
|
|
004b2c5e87 | ||
|
|
1b9506db4e | ||
|
|
b473496bdd | ||
|
|
cc750a21b5 | ||
|
|
1bf89e5af6 | ||
|
|
c63438808a | ||
|
|
0174daf0a8 | ||
|
|
270875c57c | ||
|
|
0afc8ed1eb | ||
|
|
4c0b2ea867 | ||
|
|
5749e8f081 | ||
|
|
5658766d95 | ||
|
|
34c086bb4b | ||
|
|
bddf7dbd05 | ||
|
|
464c319bc0 | ||
|
|
f410faaa27 | ||
|
|
e5b9c51bd2 | ||
|
|
e8de13f8f6 | ||
|
|
fd4a0aa096 | ||
|
|
836ab97535 | ||
|
|
8fb1c990f3 | ||
|
|
f2f647f622 | ||
|
|
cd6d679212 | ||
|
|
103b8bfb99 | ||
|
|
55ab81618b | ||
|
|
7e5766e97e | ||
|
|
10ac0b917d | ||
|
|
3981204e9b | ||
|
|
c1ff82962b | ||
|
|
ddbca1db73 | ||
|
|
396bfec9ff | ||
|
|
512e333f83 | ||
|
|
a5ed66fd26 | ||
|
|
dce39b99d8 | ||
|
|
585c3da082 | ||
|
|
40d2600fa0 | ||
|
|
b6e074e4f5 | ||
|
|
8c8a7a52d1 | ||
|
|
61a66ae9f5 | ||
|
|
7ec6e64b72 | ||
|
|
2a899d6e85 | ||
|
|
5a828a077d | ||
|
|
166bcc9f67 | ||
|
|
a6fe00242d | ||
|
|
60765fc245 | ||
|
|
6fa9db6c7f | ||
|
|
e599fe2b22 | ||
|
|
a53b963b9f | ||
|
|
bd2c5c0474 | ||
|
|
5eaf1ee0d7 | ||
|
|
186ed086b5 | ||
|
|
0c33635f73 | ||
|
|
bc070a1830 | ||
|
|
3b36275789 | ||
|
|
651cfe4bc2 | ||
|
|
3c6382a662 | ||
|
|
27bd91107e | ||
|
|
9fa09dca16 | ||
|
|
ef18c87989 | ||
|
|
bf16decf8d | ||
|
|
2b4a438e09 | ||
|
|
60eb4b8254 | ||
|
|
778b2a473f | ||
|
|
520bbaa477 | ||
|
|
8ddbcd4eb8 | ||
|
|
51ad98351c | ||
|
|
27ac7e68c9 | ||
|
|
9170b84176 | ||
|
|
a3b7e870f1 | ||
|
|
ffc8664898 | ||
|
|
858868ea8d | ||
|
|
f4ac7ea289 | ||
|
|
a049711c22 | ||
|
|
d089be1c20 | ||
|
|
c4b468f0c7 | ||
|
|
3c98191107 | ||
|
|
1aa6ae8f35 | ||
|
|
2947837eee | ||
|
|
31328d7f8f | ||
|
|
6c4cbe3a60 | ||
|
|
3b176bab2a | ||
|
|
6828103776 | ||
|
|
0bcde02453 | ||
|
|
6555f094d1 | ||
|
|
5437749139 | ||
|
|
71202eb52f | ||
|
|
1d9ce4dd05 | ||
|
|
9411aa0de2 | ||
|
|
0a64c6204c | ||
|
|
38b7b398fd | ||
|
|
51513e687f | ||
|
|
6c819d9cd5 | ||
|
|
c2c5d4c68b | ||
|
|
619221c49a | ||
|
|
12ba9acf6b | ||
|
|
8e035c9777 | ||
|
|
563a57ad47 | ||
|
|
2f1e393bc3 | ||
|
|
f2b847f5ac | ||
|
|
b6a63f517f | ||
|
|
e007747d5b | ||
|
|
c5c8891f34 | ||
|
|
ba471399b5 | ||
|
|
76c9abb930 | ||
|
|
71689ab468 | ||
|
|
3935c390ba | ||
|
|
326d2ef672 | ||
|
|
21e141ba07 | ||
|
|
b5cb5c59a3 | ||
|
|
9ad93a6f43 | ||
|
|
bb87617d97 | ||
|
|
b8684fb225 | ||
|
|
bf5a5feff2 | ||
|
|
c7b4c141f7 | ||
|
|
f694ca2820 | ||
|
|
427196239e | ||
|
|
3d5881108a | ||
|
|
50e2d39f24 | ||
|
|
09194484c4 | ||
|
|
d385077e0e | ||
|
|
dd1faa59e0 | ||
|
|
cdf2b2a097 | ||
|
|
485eee3bef | ||
|
|
ad7afcc42e | ||
|
|
5c6ce89e92 | ||
|
|
d7937111a5 | ||
|
|
71e41ad0c1 | ||
|
|
7d497f6999 | ||
|
|
89a6e8726e | ||
|
|
515478642c | ||
|
|
a48203f136 | ||
|
|
1b39be5477 | ||
|
|
9c82a7f081 | ||
|
|
433955ea29 | ||
|
|
c6137d8358 | ||
|
|
e5bed1802f | ||
|
|
d4acad82cb | ||
|
|
f24c4ea58a | ||
|
|
82e4ad925b | ||
|
|
b12c9a4e21 | ||
|
|
17a4a5bf6c | ||
|
|
c2ff328765 | ||
|
|
4be24f6d31 | ||
|
|
1e7e59628f | ||
|
|
4191df91ef | ||
|
|
0ecaca9918 | ||
|
|
664bf2e8e8 | ||
|
|
97c37bedc4 | ||
|
|
e5d7ec0b18 | ||
|
|
fca738b2b2 | ||
|
|
f7439c739a | ||
|
|
366a54600e | ||
|
|
d8f5d6bf15 | ||
|
|
05a837d483 | ||
|
|
e2ba470c88 | ||
|
|
a3b6a34d67 | ||
|
|
57fe61218c | ||
|
|
bf56db7ee6 | ||
|
|
8afac50420 | ||
|
|
4329ed5f48 | ||
|
|
12bd13b246 | ||
|
|
f4590f9086 | ||
|
|
207154c1ba | ||
|
|
b870613e80 | ||
|
|
4f8fead2a3 | ||
|
|
6a00e6e1ce | ||
|
|
b302d3e65c | ||
|
|
e8adc4246a | ||
|
|
6c21c88fa3 | ||
|
|
7bf12a82af | ||
|
|
c71d02442c | ||
|
|
d3820e8361 | ||
|
|
c8f1395bba | ||
|
|
655081ef78 | ||
|
|
91bbd7aab8 | ||
|
|
56bef60dc0 | ||
|
|
d55b20cc27 | ||
|
|
44b2c212ff | ||
|
|
67c082885c | ||
|
|
29f015a3e6 | ||
|
|
cdbf39fd1d | ||
|
|
8b4c224d49 | ||
|
|
46dade029f | ||
|
|
9e9937aade | ||
|
|
d59f690d74 | ||
|
|
f9482a02e7 | ||
|
|
2347c76b93 | ||
|
|
ab6c26341d | ||
|
|
4732b64d8d | ||
|
|
3ac8f6754b | ||
|
|
e8cb078eb6 | ||
|
|
f9c0df27ed | ||
|
|
472606c9ae | ||
|
|
07b893f8cf | ||
|
|
8be90ee688 | ||
|
|
f19daa7ce1 | ||
|
|
f90fd0bd3c | ||
|
|
d92f43b968 | ||
|
|
b949fe03a0 | ||
|
|
f8e4c2f5e8 | ||
|
|
861d83ee58 | ||
|
|
449d9625a3 | ||
|
|
c678909645 | ||
|
|
30b14d0653 | ||
|
|
ac8d1e668e | ||
|
|
4b7a253243 | ||
|
|
1fa3df342e | ||
|
|
96cae9f64d | ||
|
|
29d609c8d2 | ||
|
|
ffeb5522f4 | ||
|
|
c5e5c4b888 | ||
|
|
66a3c7d1c9 | ||
|
|
525c7c608d | ||
|
|
cbf0c0c6e3 | ||
|
|
1f9ce41f0d | ||
|
|
4274029010 | ||
|
|
ac37d09b99 | ||
|
|
f9e6dac2ea | ||
|
|
621d20cc89 | ||
|
|
fb76bccc7c | ||
|
|
5dffd33ca3 | ||
|
|
64f9e4fc12 | ||
|
|
9c230a8e36 | ||
|
|
04ddba2662 | ||
|
|
7209bf667d | ||
|
|
c9447c88a3 | ||
|
|
0eec75fae8 | ||
|
|
a4416e854b | ||
|
|
945a1ba0c4 | ||
|
|
bb0f02c5c8 | ||
|
|
12a5d89680 | ||
|
|
7536d25117 | ||
|
|
0be5ff6006 | ||
|
|
b5066d2402 | ||
|
|
fbff3bdb9a | ||
|
|
b9ae7e9c8a | ||
|
|
51156d5897 | ||
|
|
d5bbdb443a | ||
|
|
3ca6159194 | ||
|
|
32bc8d871b | ||
|
|
0a5febf38a | ||
|
|
e59f00af34 | ||
|
|
cceb7560ae | ||
|
|
8de645e2f5 | ||
|
|
4e14c0a4c2 | ||
|
|
d67b780d92 | ||
|
|
9ac6245269 | ||
|
|
f60438fc4d | ||
|
|
f555964fc8 | ||
|
|
34f172135b | ||
|
|
233ac0217e | ||
|
|
f5eccec357 | ||
|
|
72a8dbe899 | ||
|
|
f92a11caf3 | ||
|
|
10c313e92d | ||
|
|
73fce75ed0 | ||
|
|
5528e44e00 | ||
|
|
9d55f9b8a1 | ||
|
|
dbf5dcad6e | ||
|
|
01854db1bc | ||
|
|
5fed24ada4 | ||
|
|
2fb1616889 | ||
|
|
0ae1ad35ac | ||
|
|
bc8bc0fa42 | ||
|
|
c107bbef0b | ||
|
|
0dbab0b6c9 | ||
|
|
8991f78225 | ||
|
|
c466aa345f | ||
|
|
8f300bfe02 | ||
|
|
be563b527d | ||
|
|
89b6a84207 | ||
|
|
f41770656c | ||
|
|
e286ff4854 | ||
|
|
da7f563b41 | ||
|
|
cd8f3c6658 | ||
|
|
ec4afadc6e | ||
|
|
85bd7bd9f3 | ||
|
|
250bfbb98b | ||
|
|
de5b5ab370 | ||
|
|
e0c9bf5175 | ||
|
|
0b80c8c148 | ||
|
|
8216494ab1 | ||
|
|
e528979cfc | ||
|
|
fa881607bd | ||
|
|
a14d57eda6 | ||
|
|
2c13ddcbf2 | ||
|
|
fc0ae01091 | ||
|
|
7f1da50876 | ||
|
|
3034cfd4ff | ||
|
|
6cb2872bd7 | ||
|
|
18e6edb680 | ||
|
|
2c520f24bb | ||
|
|
ffa934dd5e | ||
|
|
12bd991064 | ||
|
|
d3d0a7fd4c | ||
|
|
609d7d18f5 | ||
|
|
9716fdce57 | ||
|
|
28a68c6147 | ||
|
|
d9599175b2 | ||
|
|
614bbd2b09 | ||
|
|
a193349fcc | ||
|
|
e13ffc528f | ||
|
|
8a6cd38060 | ||
|
|
2ef1b6061d | ||
|
|
6012446181 | ||
|
|
cf55d5f66b | ||
|
|
62ef2d16f4 | ||
|
|
c89dd4dcf5 | ||
|
|
3c18296300 | ||
|
|
425e14da6b | ||
|
|
9f8da3a0dd | ||
|
|
56329b8673 | ||
|
|
b0a0a7a26e | ||
|
|
53f9c1b981 | ||
|
|
9cac64de24 | ||
|
|
b27b4c450e | ||
|
|
6d1acdab58 | ||
|
|
7874b76830 | ||
|
|
4d988e59ca | ||
|
|
50451496ba | ||
|
|
9b72f1df9f | ||
|
|
d4b6dc2efb | ||
|
|
10246b5d17 | ||
|
|
efc1004af4 | ||
|
|
5706601be8 | ||
|
|
b3ef3d6bba | ||
|
|
20dce6e949 | ||
|
|
50fb1bfe81 | ||
|
|
9ea290da75 | ||
|
|
ffaffc8d31 | ||
|
|
10ad1edcda | ||
|
|
2f0e4e365b | ||
|
|
b49e04f016 | ||
|
|
77d8cca359 | ||
|
|
4db534e109 | ||
|
|
5257097d15 | ||
|
|
25bfb2d2fc | ||
|
|
c4aeddbf6a | ||
|
|
eb19dab9a3 | ||
|
|
1d7da2457c | ||
|
|
27e955932a | ||
|
|
926e3664f2 | ||
|
|
cf7eb45af0 | ||
|
|
3dc213ac16 | ||
|
|
c1f18506b2 | ||
|
|
1d1760bd3f | ||
|
|
3b400d92b6 | ||
|
|
3cddf00ac1 | ||
|
|
4c11561fe3 | ||
|
|
81ffc86247 | ||
|
|
3c0a0d3f90 | ||
|
|
7faa38b672 | ||
|
|
0021e7d518 | ||
|
|
6b24f25d50 | ||
|
|
6b9c3cb660 | ||
|
|
09efe0bca0 | ||
|
|
fc88c34243 | ||
|
|
37b8773983 | ||
|
|
05a2c84dd4 | ||
|
|
4fa2235ac5 | ||
|
|
b105b9579c | ||
|
|
8e0df3266e | ||
|
|
a010eb0e39 | ||
|
|
0898dcc150 | ||
|
|
c5b60ba999 | ||
|
|
b4a0ec0fff | ||
|
|
cde2d7e3db | ||
|
|
65d0c1f96a | ||
|
|
bf10172346 | ||
|
|
b01ec0dcad | ||
|
|
0736b9f353 | ||
|
|
f56fce7c96 | ||
|
|
6fbcf1b7dd | ||
|
|
4c60e68058 | ||
|
|
ef4d9224f3 | ||
|
|
ac5519967c | ||
|
|
b1f3c36559 | ||
|
|
97571645de | ||
|
|
0b1c83021a | ||
|
|
ebab86f196 | ||
|
|
6e131c3c7d | ||
|
|
c148205d49 | ||
|
|
051ddbf0d5 | ||
|
|
419d8e22c7 | ||
|
|
eac193bc64 | ||
|
|
83f1134622 | ||
|
|
00e301465f | ||
|
|
f4b670e99a | ||
|
|
909a7ae4e0 | ||
|
|
ac03c83ac5 | ||
|
|
e313e070ad | ||
|
|
2dedab4412 | ||
|
|
6ea03211dc | ||
|
|
4ee0a36997 | ||
|
|
d49eeed017 | ||
|
|
1e1c236c5c | ||
|
|
9e12078c1f | ||
|
|
5f70ef320b | ||
|
|
09f834675e | ||
|
|
2cd321d36c | ||
|
|
810ca9453f | ||
|
|
768329495e | ||
|
|
4ace3b2c23 | ||
|
|
c98594949f | ||
|
|
dfb8c7af14 | ||
|
|
be9c9dec39 | ||
|
|
caa4bf9683 | ||
|
|
483a25e176 | ||
|
|
6513af9aa5 | ||
|
|
cb1211e53d | ||
|
|
8a9ca9115d | ||
|
|
13075a95b3 | ||
|
|
c9616cc486 | ||
|
|
f41ee253ad | ||
|
|
54271b47a8 | ||
|
|
2a2afe7d06 | ||
|
|
37c0a27c07 | ||
|
|
e482c50f76 | ||
|
|
19c95e56d8 | ||
|
|
92abe16daa | ||
|
|
d1dc39f406 | ||
|
|
960999fb8d | ||
|
|
d11a222d4a | ||
|
|
00de2590f9 | ||
|
|
c3deed6356 |
@@ -1,11 +1,14 @@
|
||||
project(kdenlive)
|
||||
project(Kdenlive)
|
||||
|
||||
# An odd patch version number means development version, while an even one means
|
||||
# stable release. An additional number can be used for bugfix-only releases.
|
||||
set(KDENLIVE_VERSION 0.8.3)
|
||||
set(KDENLIVE_VERSION 0.9.7)
|
||||
|
||||
# Minimum versions of main dependencies.
|
||||
set(LIBMLT_MIN_VERSION 0.7.6)
|
||||
set(MLT_MIN_MAJOR_VERSION 0)
|
||||
set(MLT_MIN_MINOR_VERSION 8)
|
||||
set(MLT_MIN_PATCH_VERSION 8)
|
||||
set(MLT_MIN_VERSION ${MLT_MIN_MAJOR_VERSION}.${MLT_MIN_MINOR_VERSION}.${MLT_MIN_PATCH_VERSION})
|
||||
set(QT_MIN_VERSION 4.5.0)
|
||||
set(KDE_MIN_VERSION 4.3.0)
|
||||
|
||||
@@ -15,33 +18,31 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
|
||||
option(RELEASE_BUILD "Remove Git revision from program version (use for stable releases)" OFF)
|
||||
|
||||
# Get current version.
|
||||
set(VERSION "\"${KDENLIVE_VERSION}\"")
|
||||
if(NOT RELEASE_BUILD)
|
||||
if(EXISTS ${PROJECT_SOURCE_DIR}/.git)
|
||||
# Probably a Git workspace: determine the revision.
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
set(KDENLIVE_VERSION_STRING "${KDENLIVE_VERSION}")
|
||||
if(NOT RELEASE_BUILD AND EXISTS ${CMAKE_SOURCE_DIR}/.git)
|
||||
# Probably a Git workspace; determine the revision.
|
||||
find_package(Git QUIET)
|
||||
if(GIT_FOUND)
|
||||
exec_program(${GIT_EXECUTABLE}
|
||||
${CMAKE_SOURCE_DIR}
|
||||
ARGS "describe --tags"
|
||||
OUTPUT_VARIABLE KDENLIVE_GIT_REVISION
|
||||
RETURN_VALUE TAG_RESULT
|
||||
)
|
||||
# git describe --tags failed; maybe the repository was checked with depth=1.
|
||||
if(NOT ${TAG_RESULT} EQUAL 0)
|
||||
exec_program(${GIT_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
ARGS "describe --tags"
|
||||
${CMAKE_SOURCE_DIR}
|
||||
ARGS "describe --always"
|
||||
OUTPUT_VARIABLE KDENLIVE_GIT_REVISION
|
||||
RETURN_VALUE TAG_RESULT
|
||||
)
|
||||
# git describe --tags failed, for example it fails if repo was checked with depth=1
|
||||
if(NOT ${TAG_RESULT} EQUAL 0)
|
||||
exec_program(${GIT_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
ARGS "describe --always"
|
||||
OUTPUT_VARIABLE KDENLIVE_GIT_REVISION
|
||||
)
|
||||
endif(NOT ${TAG_RESULT} EQUAL 0)
|
||||
message("Current Kdenlive Git revision is ${KDENLIVE_GIT_REVISION}")
|
||||
set(VERSION "\"${KDENLIVE_VERSION} (rev. ${KDENLIVE_GIT_REVISION})\"")
|
||||
else(GIT_FOUND)
|
||||
message("Could not determine the Git revision")
|
||||
endif(GIT_FOUND)
|
||||
endif(EXISTS ${PROJECT_SOURCE_DIR}/.git)
|
||||
endif(NOT RELEASE_BUILD)
|
||||
endif()
|
||||
message(STATUS "Kdenlive Git revision: ${KDENLIVE_GIT_REVISION}")
|
||||
set(KDENLIVE_VERSION_STRING "${KDENLIVE_VERSION} (rev. ${KDENLIVE_GIT_REVISION})")
|
||||
else()
|
||||
message(STATUS "Kdenlive Git revision could not be determined")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(CheckIncludeFiles)
|
||||
check_include_files(malloc.h HAVE_MALLOC_H)
|
||||
@@ -63,17 +64,15 @@ macro_log_feature(KDE4_FOUND
|
||||
find_package(Qt4 ${QT_MIN_VERSION} REQUIRED)
|
||||
|
||||
# Search MLT package.
|
||||
find_package(LIBMLT ${LIBMLT_MIN_VERSION} REQUIRED)
|
||||
if(LIBMLT_VERSION VERSION_LESS ${LIBMLT_MIN_VERSION})
|
||||
set(LIBMLT_FOUND FALSE)
|
||||
endif(LIBMLT_VERSION VERSION_LESS ${LIBMLT_MIN_VERSION})
|
||||
macro_log_feature(LIBMLT_FOUND
|
||||
find_package(MLT ${MLT_MIN_VERSION} REQUIRED)
|
||||
macro_log_feature(MLT_FOUND
|
||||
"MLT"
|
||||
"Multimedia framework and video playout server for TV broadcasting"
|
||||
"http://mltframework.org"
|
||||
TRUE
|
||||
${LIBMLT_MIN_VERSION}
|
||||
${MLT_MIN_VERSION}
|
||||
)
|
||||
set(MLT_PREFIX ${MLT_ROOT_DIR})
|
||||
|
||||
add_subdirectory(data)
|
||||
macro_optional_add_subdirectory(doc)
|
||||
|
||||
2
COPYING
2
COPYING
@@ -2,7 +2,7 @@
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
109
ChangeLog
109
ChangeLog
@@ -1,16 +1,103 @@
|
||||
Current git
|
||||
* Fix archiving feature not saving playlist clips and slowmotion clips inside them
|
||||
* Fix Crash recovery feature triggering error messages about wrong path
|
||||
* Fix rendering jobs sometimes not starting
|
||||
* Fix crash on proxy creation (concurrency issue)
|
||||
* Fix zone playing
|
||||
* Fix click on monitor sometimes not triggering play
|
||||
0.9.7
|
||||
* Add support for a custom suffix for FFmpeg binaries (mostly for packagers)
|
||||
|
||||
0.9.6
|
||||
* Fix keyframes when cutting a clip / undoing a clip cut
|
||||
* Warn before overwriting .mlt stabilized file
|
||||
* Fix monitor confusion (clip monitor sometimes playing timeline,...)
|
||||
* Fix the Mono to Stereo effect UI
|
||||
* Fix proxy of playlist having wrong aspect ratio in some locales
|
||||
* Fix transition widget not correctly updated when resizing a transition
|
||||
* Fix DVD chapters broken when using an intro movie
|
||||
* Fix error message (No matching profile) poping up in render widget when everything was ok
|
||||
* Fix clip keyframes not showing on project load
|
||||
* Fix bug when moving guide (was not moving to the correct place)
|
||||
* Fix project corruption (wrong character) caused by some clip's metadata
|
||||
* Fix possible crash on track deletion
|
||||
* Fix timeline corruption when using spacer tool or overwrite edit mode
|
||||
* Fix possible crash when editing speed effect
|
||||
* Fix transition losing all its properties when moved
|
||||
* Fix crash when pressing del when editing animation in title widget
|
||||
* Fix crash when doing quick clip resize
|
||||
* Fix corruption when groups where overlapping
|
||||
* Fix corruption when adding a title clip where a transition already existed
|
||||
* Fix timeline preview corruption with some transitions
|
||||
|
||||
0.9.4
|
||||
* Fix color parameter in some effects not working correctly (#2644)
|
||||
* Fix V4l licensing issue (#2632)
|
||||
* Fix keyframes lost / broken when pasting an effect
|
||||
|
||||
0.9.2
|
||||
* Fix firewire capture (preview not showing)
|
||||
* Fix freeze when reloading previously missing clip
|
||||
* Fade effects lost when moving / resizing clip
|
||||
* Undoing change in clip crop start breaking clip
|
||||
* Make disabling of track effects possible
|
||||
* Fix slideshow clips not working
|
||||
* Fix crash on composite transition
|
||||
* Fix crash when opening stop motion widget
|
||||
* Fix rendering of projects created in another locale
|
||||
|
||||
0.9
|
||||
* Fix monitor effect scene sometimes forcing monitor minimum size
|
||||
* Improve detection of locale issues (default to POSIX when there is a locale conflict on the system)
|
||||
* Improve timeline operation for small clips (disable resizing, only allow move)
|
||||
* Add background color parameter to "Rotate" and "Pan and Zoom" effects
|
||||
* Allow to scroll using the mouse wheel in monitor editing scene
|
||||
* Zoom to mouse when using CTRL + mouse wheel in monitor editing scene
|
||||
* Add support for new slope mode in "Color Selection" effect to allow smooth alpha transition
|
||||
* Introduce grouping of effects; groups can also be saved
|
||||
* Allow dragging an effect to another clip/track
|
||||
* Allow record monitor to go fullscreen
|
||||
* Image sequences can now start at an arbitrary frame (http://kdenlive.org/mantis/view.php?id=2508)
|
||||
* Add automatic clip alignment based on audio (experimental, has to be manually enabled)s
|
||||
* Allow archiving for offline use (only archive proxies)
|
||||
* Offline editing: Allow working on project with only proxies available (http://kdenlive.org/mantis/view.php?id=2509)
|
||||
* Allow rendering to another framerate
|
||||
* Check for missing locale and ask to install instead of opening corrupted project
|
||||
* Allow to open project files manually extracted from archived project
|
||||
* Support dropping a folder in the project tree (http://kdenlive.org/mantis/view.php?id=1288)
|
||||
* Add "select all clips in track" and "select all clips in timeline" features (http://kdenlive.org/mantis/view.php?id=1950)
|
||||
* Put audio effects in subcategories to avoid uberlong menus (http://kdenlive.org/mantis/view.php?id=2436)
|
||||
* Support for project metadata (can be embedded in rendered file)
|
||||
* Add Online Resource Widget allowing easy search and download of online services (freesound, openclipart, archive.org)
|
||||
* Introduce generic job framework for project tree jobs
|
||||
* Fix color change not working in title widget
|
||||
* Fix crash when moving a folder and a clip in project tree
|
||||
* Fix profile warning with clips that have 1088 pixels height
|
||||
* Introduce MLT clip analysis to get auto normalize data in sox gain effect
|
||||
* Connect recording to audio scopes
|
||||
* Add audio only recording (works while playing)
|
||||
* Add extract zone function: part of clip is copied to new file without re-encoding
|
||||
* Introduce generic job framework to process clips
|
||||
* Improve the Choose color widget: Use less space and make it easier to pick the average color value from an area
|
||||
* Add GUI for effect Dynamic Text: Allows to display timecode/framecount and other data
|
||||
* Rework effect stack: All effects are shown at once and are collapsible
|
||||
* Add two different video stabilizers
|
||||
* Add IIR Blur GUI
|
||||
* Add date column to project tree
|
||||
|
||||
* Fix clip move sometimes giving error when it should work
|
||||
* Fix custom effects not considering capital letters in name (http://kdenlive.org/mantis/view.php?id=2580)
|
||||
* Fix script rendering when script name contains whitespace
|
||||
* Ensure clip in project tree is visible after rename (scroll if necessary) (http://kdenlive.org/mantis/view.php?id=2563)
|
||||
* Fix monitor scene never resetting scrollbars
|
||||
* Fix issues with transitions when inserting track (http://kdenlive.org/mantis/view.php?id=2477)
|
||||
* Fix some GUI elements not responding to color theme change
|
||||
* Do not hide render profile list when there is only one item to avoid confusion (http://kdenlive.org/mantis/view.php?id=2543)
|
||||
* Fix consecutive error messages overwriting each other (http://www.kdenlive.org/mantis/view.php?id=2519)
|
||||
* Fix crash when editing properties of several missing clips
|
||||
* Fix vectorscope for 24b RGB images (http://kdenlive.org/mantis/view.php?id=2478)
|
||||
* Fix archiving sometimes not saving playlist clips and subclips (http://kdenlive.org/mantis/view.php?id=2475)
|
||||
* Fix archiving feature not saving playlist clips and slowmotion clips inside them (http://kdenlive.org/mantis/view.php?id=2475)
|
||||
* Fix crash recovery feature issues with long or non UTF-8 filenames (http://kdenlive.org/mantis/view.php?id=2441, http://kdenlive.org/mantis/view.php?id=2450)
|
||||
* Fix rendering jobs sometimes not starting
|
||||
* Fix crash on proxy creation (concurrency issue) (http://kdenlive.org/mantis/view.php?id=2471)
|
||||
* Fix zone playing (http://kdenlive.org/mantis/view.php?id=2468)
|
||||
* Fix click on monitor sometimes not triggering play
|
||||
* Fix crash when moving a folder and a clip in project tree (http://kdenlive.org/mantis/view.php?id=2458)
|
||||
* Fix color change not working in title widget (http://kdenlive.org/mantis/view.php?id=2459)
|
||||
* Fix slideshow clips created with invalid frame duration
|
||||
* Fix profile warning with clips that have 1088 pixels height
|
||||
* Fix unnecessary proxy reload on document load
|
||||
* Fix detection of broken render scripts
|
||||
|
||||
0.8.2.1
|
||||
* Fix title text oultine transparency not working
|
||||
|
||||
4
README
4
README
@@ -1,4 +1,4 @@
|
||||
Kdenlive 0.8.2
|
||||
Kdenlive 0.9.6
|
||||
by Jean-Baptiste Mardelle <jb@kdenlive.org> and the Kdenlive team
|
||||
|
||||
Kdenlive is a video editing application based on KDE Platform 4.
|
||||
@@ -12,7 +12,7 @@ the following web page:
|
||||
|
||||
http://www.mltframework.org
|
||||
|
||||
The recommended MLT version is 0.7.6. It may work with other
|
||||
It is recommended to use the latest MLT version. It may work with older
|
||||
versions, but this is not guaranteed, or (at this stage of development) likely.
|
||||
|
||||
We welcome all bug reports, feedback, and offers for help!
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#
|
||||
# Find the MLT includes and libraries.
|
||||
#
|
||||
|
||||
include(FindPkgConfig)
|
||||
pkg_check_modules(MLT mlt++)
|
||||
add_definitions(-DMLT_PREFIX=\\\"\"${MLT_PREFIX}\"\\\")
|
||||
|
||||
find_path(LIBMLT_INCLUDE_DIR
|
||||
NAMES framework/mlt.h
|
||||
PATHS
|
||||
${MLT_INCLUDEDIR}/mlt
|
||||
${MLT_PREFIX}/include/mlt
|
||||
/usr/local/include/mlt
|
||||
/usr/include/mlt
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
find_library(LIBMLT_LIBRARY
|
||||
NAMES mlt
|
||||
PATHS
|
||||
${MLT_LIBDIR}
|
||||
${MLT_PREFIX}/lib
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
find_path(LIBMLTPLUS_INCLUDE_DIR
|
||||
NAMES mlt++/Mlt.h
|
||||
PATHS
|
||||
${MLT_INCLUDEDIR}
|
||||
${MLT_PREFIX}/include
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
find_library(LIBMLTPLUS_LIBRARY
|
||||
NAMES mlt++
|
||||
PATHS
|
||||
${MLT_LIBDIR}
|
||||
${MLT_PREFIX}/lib
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
if(LIBMLT_LIBRARY AND LIBMLT_INCLUDE_DIR)
|
||||
set(LIBMLT_FOUND 1)
|
||||
set(LIBMLT_LIBRARIES ${LIBMLT_LIBRARY})
|
||||
else(LIBMLT_LIBRARY AND LIBMLT_INCLUDE_DIR)
|
||||
set(LIBMLT_FOUND 0)
|
||||
endif(LIBMLT_LIBRARY AND LIBMLT_INCLUDE_DIR)
|
||||
|
||||
if(LIBMLT_FOUND AND LIBMLTPLUS_LIBRARY AND LIBMLTPLUS_INCLUDE_DIR)
|
||||
set(LIBMLT_FOUND 1)
|
||||
set(LIBMLTPLUS_LIBRARIES ${LIBMLTPLUS_LIBRARY})
|
||||
else(LIBMLT_FOUND AND LIBMLTPLUS_LIBRARY AND LIBMLTPLUS_INCLUDE_DIR)
|
||||
set(LIBMLT_FOUND 0)
|
||||
endif(LIBMLT_FOUND AND LIBMLTPLUS_LIBRARY AND LIBMLTPLUS_INCLUDE_DIR)
|
||||
|
||||
if(LIBMLT_FOUND)
|
||||
set(LIBMLT_VERSION ${MLT_VERSION})
|
||||
if(NOT LIBMLT_FIND_QUIETLY)
|
||||
message(STATUS "Found MLT++: ${LIBMLTPLUS_LIBRARY}")
|
||||
endif(NOT LIBMLT_FIND_QUIETLY)
|
||||
else(LIBMLT_FOUND)
|
||||
if(LIBMLT_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find MLT++")
|
||||
endif(LIBMLT_FIND_REQUIRED)
|
||||
endif(LIBMLT_FOUND)
|
||||
27
cmake/modules/FindLibV4L2.cmake
Normal file
27
cmake/modules/FindLibV4L2.cmake
Normal file
@@ -0,0 +1,27 @@
|
||||
# cmake macro to find LibV4L2
|
||||
#
|
||||
# Copyright (c) 2009, Jaroslav Reznik <jreznik@redhat.com>
|
||||
#
|
||||
# Once done this will define:
|
||||
#
|
||||
# LIBV4L2_FOUND - System has LibV4L2
|
||||
# LIBV4L2_INCLUDE_DIR - The LibV4L2 include directory
|
||||
# LIBV4L2_LIBRARY - The libraries needed to use LibV4L2
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
IF (LIBV4L2_INCLUDE_DIR AND LIBV4L2_LIBRARY)
|
||||
# Already in cache, be silent
|
||||
SET (LIBV4L2_FIND_QUIETLY TRUE)
|
||||
ENDIF (LIBV4L2_INCLUDE_DIR AND LIBV4L2_LIBRARY)
|
||||
|
||||
FIND_PATH (LIBV4L2_INCLUDE_DIR libv4l2.h)
|
||||
|
||||
FIND_LIBRARY (LIBV4L2_LIBRARY v4l2)
|
||||
|
||||
INCLUDE (FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS (LibV4L2 DEFAULT_MSG LIBV4L2_INCLUDE_DIR LIBV4L2_LIBRARY)
|
||||
|
||||
MARK_AS_ADVANCED(LIBV4L2_INCLUDE_DIR LIBV4L2_LIBRARY)
|
||||
|
||||
59
cmake/modules/FindMLT.cmake
Normal file
59
cmake/modules/FindMLT.cmake
Normal file
@@ -0,0 +1,59 @@
|
||||
# - Find the MLT includes and libraries
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_MLT QUIET mlt++)
|
||||
|
||||
find_path(MLT_INCLUDE_DIR
|
||||
NAMES framework/mlt.h
|
||||
HINTS
|
||||
${PC_MLT_INCLUDEDIR}
|
||||
${PC_MLT_PREFIX}/include
|
||||
PATHS
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
PATH_SUFFIXES mlt
|
||||
)
|
||||
|
||||
find_library(MLT_LIBRARIES
|
||||
NAMES mlt
|
||||
HINTS
|
||||
${PC_MLT_LIBDIR}
|
||||
${PC_MLT_PREFIX}/lib
|
||||
PATHS
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
)
|
||||
|
||||
find_path(MLTPP_INCLUDE_DIR
|
||||
NAMES mlt++/Mlt.h
|
||||
HINTS
|
||||
${PC_MLT_INCLUDEDIR}
|
||||
${PC_MLT_PREFIX}/include
|
||||
PATHS
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
find_library(MLTPP_LIBRARIES
|
||||
NAMES mlt++
|
||||
HINTS
|
||||
${PC_MLT_LIBDIR}
|
||||
${PC_MLT_PREFIX}/lib
|
||||
PATHS
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
)
|
||||
|
||||
get_filename_component(MLT_ROOT_DIR ${MLTPP_INCLUDE_DIR} PATH)
|
||||
|
||||
if(PC_MLT_VERSION)
|
||||
set(MLT_VERSION_STRING ${PC_MLT_VERSION})
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(MLT
|
||||
REQUIRED_VARS MLT_LIBRARIES MLTPP_LIBRARIES MLT_INCLUDE_DIR MLTPP_INCLUDE_DIR
|
||||
VERSION_VAR MLT_VERSION_STRING
|
||||
)
|
||||
|
||||
mark_as_advanced(MLT_INCLUDE_DIR MLT_LIBRARIES MLTPP_INCLUDE_DIR MLTPP_LIBRARIES)
|
||||
@@ -1,7 +1,14 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#cmakedefine VERSION @VERSION@
|
||||
#define KDENLIVE_VERSION "@KDENLIVE_VERSION_STRING@"
|
||||
|
||||
#define MLT_PREFIX "@MLT_PREFIX@"
|
||||
#define MLT_MIN_MAJOR_VERSION @MLT_MIN_MAJOR_VERSION@
|
||||
#define MLT_MIN_MINOR_VERSION @MLT_MIN_MINOR_VERSION@
|
||||
#define MLT_MIN_PATCH_VERSION @MLT_MIN_PATCH_VERSION@
|
||||
|
||||
#define FFMPEG_SUFFIX "@FFMPEG_SUFFIX@"
|
||||
|
||||
#cmakedefine HAVE_MALLOC_H 1
|
||||
#cmakedefine HAVE_PTHREAD_H 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
install(FILES banner.png timeline_nothumbs.png timeline_athumbs.png timeline_vthumbs.png timeline_avthumbs.png metadata.properties blacklisted_effects.txt blacklisted_transitions.txt encodingprofiles.rc DESTINATION ${DATA_INSTALL_DIR}/kdenlive )
|
||||
install(FILES banner.png timeline_nothumbs.png timeline_athumbs.png timeline_vthumbs.png timeline_avthumbs.png metadata.properties blacklisted_effects.txt blacklisted_transitions.txt encodingprofiles.rc meta_ffmpeg.png meta_libav.png meta_magiclantern.png DESTINATION ${DATA_INSTALL_DIR}/kdenlive )
|
||||
install( FILES kdenliveeffectscategory.rc DESTINATION ${CONFIG_INSTALL_DIR} )
|
||||
install (FILES kdenlive.xpm DESTINATION share/pixmaps)
|
||||
install (FILES kdenlive.menu DESTINATION share/menu RENAME kdenlive)
|
||||
|
||||
@@ -25,6 +25,7 @@ frei0r.cluster
|
||||
frei0r.c0rners
|
||||
frei0r.coloradj_RGB
|
||||
frei0r.colordistance
|
||||
frei0r.colortap
|
||||
frei0r.contrast0r
|
||||
frei0r.curves
|
||||
frei0r.defish0r
|
||||
@@ -39,6 +40,7 @@ frei0r.facebl0r
|
||||
frei0r.flippo
|
||||
frei0r.glow
|
||||
frei0r.IIRblur
|
||||
frei0r.keyspillm0pup
|
||||
frei0r.hqdn3d
|
||||
frei0r.hueshift0r
|
||||
frei0r.lenscorrection
|
||||
@@ -74,6 +76,8 @@ frei0r.vignette
|
||||
|
||||
|
||||
#MLT effects with XML UI
|
||||
channelcopy
|
||||
crop
|
||||
dust
|
||||
grain
|
||||
lines
|
||||
@@ -81,9 +85,8 @@ oldfilm
|
||||
tcolor
|
||||
rotoscoping
|
||||
wave
|
||||
volume
|
||||
vignette
|
||||
|
||||
volume
|
||||
|
||||
#Effects not usable with a simple GUI
|
||||
sox
|
||||
@@ -93,7 +96,7 @@ luma
|
||||
data_show
|
||||
gtkrescale
|
||||
watermark
|
||||
#region
|
||||
region
|
||||
resize
|
||||
resample
|
||||
mono
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# redundant transitions
|
||||
frei0r.composition
|
||||
|
||||
# unusable transitions
|
||||
# unusable transitions (parameters required, not implemented in Kdenlive)
|
||||
frei0r.alphainjection
|
||||
frei0r.blend
|
||||
frei0r.xfade0r
|
||||
|
||||
|
||||
4
data/camcorderfilters.rc
Normal file
4
data/camcorderfilters.rc
Normal file
@@ -0,0 +1,4 @@
|
||||
[Model]
|
||||
NEX-VG20E=full_luma 1
|
||||
NEX-5=full_luma 1
|
||||
|
||||
@@ -5,6 +5,10 @@ Normal MPEG=vcodec=mpeg2video qscale=10 acodec=mp2 ac=2 ab=128k ar=48000 threads
|
||||
[proxy]
|
||||
Normal MPEG=-f mpegts -acodec libmp3lame -ac 2 -ab 128k -ar 48000 -vcodec mpeg2video -g 5 -deinterlace -s 480x270 -vb 400k;ts
|
||||
|
||||
[screengrab]
|
||||
X246 mute=-vcodec libx264 -preset fast -threads 0;mkv
|
||||
X246 with audio=-f alsa -i pulse -acodec libvorbis -ab 256k -vcodec libx264 -preset fast -threads 0;mkv
|
||||
|
||||
[video4linux]
|
||||
Normal MPEG=f=mpeg acodec=mp2 ab=128k ar=48000 vcodec=mpeg2video minrate=0 vb=4000k;mpg
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
|
||||
<data name="effects" version="0">
|
||||
<group list="brightness,gamma,frei0r.balanc0r,frei0r.brightness,frei0r.levels,frei0r.three_point_balance,frei0r.curves,frei0r.coloradj_RGB,frei0r.sopsat,frei0r.bezier_curves">
|
||||
<group list="brightness,gamma,frei0r.colgate,frei0r.balanc0r,frei0r.brightness,frei0r.levels,frei0r.three_point_balance,frei0r.curves,frei0r.coloradj_RGB,frei0r.sopsat,frei0r.bezier_curves">
|
||||
<text>Colour correction</text>
|
||||
</group>
|
||||
<group list="invert,sepia,tcolor,greyscale,frei0r.B,frei0r.G,frei0r.R,frei0r.contrast0r,frei0r.saturat0r,frei0r.tint0r,frei0r.primaries,frei0r.rgbparade,chroma_hold,frei0r.hueshift0r">
|
||||
@@ -31,7 +31,7 @@
|
||||
<group list="wave,mirror,frei0r.distort0r,frei0r.lenscorrection,frei0r.c0rners,frei0r.defish0r,frei0r.pixeliz0r">
|
||||
<text>Distort</text>
|
||||
</group>
|
||||
<group list="chroma,frei0r.alpha0ps,frei0r.alphagrad,frei0r.alphaspot,frei0r.transparency,frei0r.select0r,frei0r.mask0mate,rotoscoping">
|
||||
<group list="chroma,frei0r.alpha0ps,frei0r.alphagrad,frei0r.alphaspot,frei0r.transparency,frei0r.select0r,frei0r.mask0mate,rotoscoping,frei0r.keyspillm0pup">
|
||||
<text>Alpha manipulation</text>
|
||||
</group>
|
||||
<group list="frei0r.d90stairsteppingfix,frei0r.hqdn3d,frei0r.sharpness">
|
||||
|
||||
BIN
data/meta_ffmpeg.png
Normal file
BIN
data/meta_ffmpeg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 855 B |
BIN
data/meta_libav.png
Normal file
BIN
data/meta_libav.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 442 B |
BIN
data/meta_magiclantern.png
Normal file
BIN
data/meta_magiclantern.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
@@ -3,7 +3,7 @@
|
||||
<!ENTITY % addindex "IGNORE">
|
||||
<!ENTITY % English "INCLUDE">
|
||||
]>
|
||||
<book lang="&language;">
|
||||
<book id="kdenlive" lang="&language;">
|
||||
<bookinfo>
|
||||
<title>The Kdenlive Quick Start Guide</title>
|
||||
<authorgroup>
|
||||
|
||||
@@ -48,8 +48,10 @@ frei0r_bezier_curves.xml
|
||||
frei0r_brightness.xml
|
||||
frei0r_cartoon.xml
|
||||
frei0r_cluster.xml
|
||||
frei0r_colgate.xml
|
||||
frei0r_coloradj_rgb.xml
|
||||
frei0r_colordistance.xml
|
||||
frei0r_colortap.xml
|
||||
frei0r_contrast0r.xml
|
||||
frei0r_c0rners.xml
|
||||
frei0r_curves.xml
|
||||
@@ -65,12 +67,14 @@ frei0r_glow.xml
|
||||
frei0r_hqdn3d.xml
|
||||
frei0r_hueshift0r.xml
|
||||
frei0r_iirblur.xml
|
||||
frei0r_keyspillm0pup.xml
|
||||
frei0r_lenscorrection.xml
|
||||
frei0r_letterb0xed.xml
|
||||
frei0r_levels.xml
|
||||
frei0r_lightgraffiti.xml
|
||||
frei0r_luminance.xml
|
||||
frei0r_mask0mate.xml
|
||||
frei0r_medians.xml
|
||||
frei0r_nervous.xml
|
||||
frei0r_nosync0r.xml
|
||||
frei0r_pixeliz0r.xml
|
||||
@@ -90,6 +94,7 @@ frei0r_tehroxx0r.xml
|
||||
frei0r_three_point_balance.xml
|
||||
frei0r_threelay0r.xml
|
||||
frei0r_threshold0r.xml
|
||||
frei0r_timeout.xml
|
||||
frei0r_tint0r.xml
|
||||
frei0r_twolay0r.xml
|
||||
frei0r_vectorscope.xml
|
||||
|
||||
@@ -6,10 +6,33 @@
|
||||
<parameter type="geometry" name="geometry" default="50%,50%:50%x50%" fixed="1" opacity="false">
|
||||
<name>Geometry</name>
|
||||
</parameter>
|
||||
<parameter type="constant" name="motion_est.macroblock_width" max="100" min="1" default="16" suffix="pixels">
|
||||
<name>Macroblock width</name>
|
||||
</parameter>
|
||||
<parameter type="constant" name="motion_est.macroblock_height" max="100" min="1" default="16" suffix="pixels">
|
||||
<name>Macroblock height</name>
|
||||
</parameter>
|
||||
<parameter type="constant" name="motion_est.limit_x" max="500" min="1" default="64" suffix="pixels">
|
||||
<name>Maximum x distance</name>
|
||||
</parameter>
|
||||
<parameter type="constant" name="motion_est.limit_y" max="500" min="1" default="64" suffix="pixels">
|
||||
<name>Maximum y distance</name>
|
||||
</parameter>
|
||||
<parameter type="bool" name="motion_est.denoise" default="0">
|
||||
<name>Denoise</name>
|
||||
</parameter>
|
||||
<parameter type="bool" name="debug" default="0">
|
||||
<name>Debug</name>
|
||||
</parameter>
|
||||
<parameter type="bool" name="obscure" default="1">
|
||||
<name>Obscure</name>
|
||||
</parameter>
|
||||
<parameter type="filterjob" filtertag="autotrack_rectangle" filterparams="_serialize=1 motion_vector_list=0 %params in=%position" consumer="null" consumerparams="all=1 terminate_on_pause=1">
|
||||
<jobparam name="storedata" />
|
||||
<jobparam name="projecttreefilter" />
|
||||
<jobparam name="key">motion_vector_list</jobparam>
|
||||
<jobparam name="finalfilter">autotrack_rectangle</jobparam>
|
||||
<jobparam name="displaydataname">Motion vectors</jobparam>
|
||||
<name>Analyse</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<effect tag="channelcopy" id="channelcopy" type="audio">
|
||||
<effect tag="channelcopy" id="stereocopy" type="audio">
|
||||
<name>Mono to stereo</name>
|
||||
<description>Copy one channel to another</description>
|
||||
<author>Dan Dennedy</author>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<name>Blue Screen</name>
|
||||
<description>Make selected color transparent</description>
|
||||
<author>Charles Yates</author>
|
||||
<parameter type="color" name="key" default="0x0000FF">
|
||||
<parameter type="color" name="key" default="0x0000ffff">
|
||||
<name>Color key</name>
|
||||
</parameter>
|
||||
<parameter type="constant" name="variance" max="100" min="0" factor="100" default="15">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<name>Chroma Hold</name>
|
||||
<description>Make image greyscale except for chosen color</description>
|
||||
<author>Charles Yates</author>
|
||||
<parameter type="color" name="key" default="0x000000">
|
||||
<parameter type="color" name="key" default="0x000000ff">
|
||||
<name>Color key</name>
|
||||
</parameter>
|
||||
<parameter type="constant" name="variance" max="100" min="0" factor="100" default="15" >
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<effect tag="crop" id="crop">
|
||||
<name>Crop</name>
|
||||
<name>Edge Crop</name>
|
||||
<description>Trim the edges of a clip</description>
|
||||
<author>Dan Dennedy</author>
|
||||
<parameter type="constant" name="top" max="%maxHeight" min="0" default="0" suffix="pixels">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<name>Dust</name>
|
||||
<description>Add dust and specks to the video, as in old movies</description>
|
||||
<author>Marco Gittler</author>
|
||||
<parameter type="double" name="maxdiameter" max="100" min="0" default="2">
|
||||
<parameter type="double" name="maxdiameter" max="100" min="0" default="2" suffix="%">
|
||||
<name>Maximal Diameter</name>
|
||||
</parameter>
|
||||
<parameter type="double" name="maxcount" max="400" min="0" default="10">
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
</parameter>
|
||||
<parameter type="keywords" name="argument" default="#timecode#">
|
||||
<name>Text</name>
|
||||
<keywords>#timecode#;#frame#;#filedate#;#meta.media.0.stream.frame_rate#;#meta.media.0.codec.name#;#meta.media.0.codec.bit_rate#;#meta.media.width#;#meta.media.height#;#meta.attr.comment.markup#</keywords>
|
||||
<keywordsdisplay>timecode;frame;file date;source frame rate;source codec;source bit rate;source width;source height;source comment</keywordsdisplay>
|
||||
<keywords>#timecode#;#frame#;#filedate#;#localfiledate#;#meta.media.0.stream.frame_rate#;#meta.media.0.codec.name#;#meta.media.0.codec.bit_rate#;#meta.media.width#;#meta.media.height#;#meta.attr.comment.markup#</keywords>
|
||||
<keywordsdisplay>timecode;frame;file date;local file date;source frame rate;source codec;source bit rate;source width;source height;source comment</keywordsdisplay>
|
||||
</parameter>
|
||||
</effect>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<name>Fade to Black</name>
|
||||
<description>Fade video to black</description>
|
||||
<author>Charles Yates</author>
|
||||
<parameter type="position" name="in" max="0" min="0" default="75">
|
||||
<parameter type="position" name="in" max="0" min="0" default="-75">
|
||||
<name>Duration</name>
|
||||
</parameter>
|
||||
<parameter type="fixed" name="out" max="99999" min="0" default="0">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<effect tag="volume" id="fadeout" type="audio" unique="1">
|
||||
<name>Fade out</name>
|
||||
<description>Fade in audio track</description>
|
||||
<description>Fade out audio track</description>
|
||||
<author></author>
|
||||
<parameter type="position" name="in" max="0" min="0" default="75">
|
||||
<parameter type="position" name="in" max="0" min="0" default="-75">
|
||||
<name>Duration</name>
|
||||
</parameter>
|
||||
<parameter type="fixed" name="out" max="90000" min="0" default="0">
|
||||
|
||||
@@ -1,33 +1,66 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<effect LC_NUMERIC="C" tag="frei0r.alpha0ps" id="frei0r.alpha0ps">
|
||||
<name>Alpha operations</name>
|
||||
<description>Display and manipulation of the alpha channel</description>
|
||||
<author>Marko Cebokli</author>
|
||||
<group>
|
||||
<effect LC_NUMERIC="C" tag="frei0r.alpha0ps" id="frei0r.alpha0ps">
|
||||
<name>Alpha operations</name>
|
||||
<description>Display and manipulation of the alpha channel</description>
|
||||
<author>Marko Cebokli</author>
|
||||
|
||||
<parameter type="list" name="Display" default="0.0" paramlist="0.0;0.21;0.36;0.50;0.64;0.79;1.0">
|
||||
<paramlistdisplay>Image,Alpha as gray,Gray + red,Selection on black,Selection on gray,Selection on white,Selection on checkers</paramlistdisplay>
|
||||
<name>Display</name>
|
||||
</parameter>
|
||||
<parameter type="list" name="Display" default="0.0" paramlist="0.0;0.21;0.36;0.50;0.64;0.79;1.0">
|
||||
<paramlistdisplay>Image,Alpha as gray,Gray + red,Selection on black,Selection on gray,Selection on white,Selection on checkers</paramlistdisplay>
|
||||
<name>Display</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="bool" name="Display input alpha" default="0">
|
||||
<name>Display input alpha</name>
|
||||
</parameter>
|
||||
<parameter type="bool" name="Display input alpha" default="0">
|
||||
<name>Display input alpha</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.21;0.36;0.50;0.64;0.79;1.0">
|
||||
<paramlistdisplay>NO OP,Shave,Shrink hard,Shrink soft,Grow hard,Grow soft,Threshold</paramlistdisplay>
|
||||
<name>Operation</name>
|
||||
</parameter>
|
||||
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.21;0.36;0.50;0.64;0.79;1.0">
|
||||
<paramlistdisplay>NO OP,Shave,Shrink hard,Shrink soft,Grow hard,Grow soft,Threshold</paramlistdisplay>
|
||||
<name>Operation</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="simplekeyframe" name="Threshold" default="500" min="0" max="1000" factor="1000">
|
||||
<name>Threshold</name>
|
||||
</parameter>
|
||||
<parameter type="simplekeyframe" name="Threshold" default="500" min="0" max="1000" factor="1000">
|
||||
<name>Threshold</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="simplekeyframe" name="Shrink/grow amount" default="500" min="0" max="1000" factor="1000" intimeline="1">
|
||||
<name>Shrink/grow amount</name>
|
||||
</parameter>
|
||||
<parameter type="simplekeyframe" name="Shrink/grow amount" default="500" min="0" max="1000" factor="1000" intimeline="1">
|
||||
<name>Shrink/grow amount</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="bool" name="Invert" default="0">
|
||||
<name>Invert</name>
|
||||
</parameter>
|
||||
<parameter type="bool" name="Invert" default="0">
|
||||
<name>Invert</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
|
||||
</effect>
|
||||
<effect LC_NUMERIC="C" tag="frei0r.alpha0ps" id="frei0r.alpha0ps" version="0.3">
|
||||
<name>Alpha operations</name>
|
||||
<description>Display and manipulation of the alpha channel</description>
|
||||
<author>Marko Cebokli</author>
|
||||
|
||||
<parameter type="list" name="Display" default="0.0" paramlist="0.0;0.21;0.36;0.50;0.64;0.79;1.0">
|
||||
<paramlistdisplay>Image,Alpha as gray,Gray + red,Selection on black,Selection on gray,Selection on white,Selection on checkers</paramlistdisplay>
|
||||
<name>Display</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="bool" name="Display input alpha" default="0">
|
||||
<name>Display input alpha</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.2;0.3;0.4;0.6;0.7;0.8;1.0">
|
||||
<paramlistdisplay>NO OP,Shave,Shrink hard,Shrink soft,Grow hard,Grow soft,Threshold,Blur</paramlistdisplay>
|
||||
<name>Operation</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="simplekeyframe" name="Threshold" default="500" min="0" max="1000" factor="1000">
|
||||
<name>Threshold</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="simplekeyframe" name="Shrink/Grow/Blur amount" default="500" min="0" max="1000" factor="1000" intimeline="1">
|
||||
<name>Shrink/Grow/Blur amount</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="bool" name="Invert" default="0">
|
||||
<name>Invert</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
</group>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<name>White Balance</name>
|
||||
<description>Adjust the white balance / color temperature</description>
|
||||
<author>Dan Dennedy</author>
|
||||
<parameter type="color" name="Neutral Color" default="0xFFFFFF">
|
||||
<parameter type="color" name="Neutral Color" default="0xffffffff">
|
||||
<name>Neutral Color</name>
|
||||
</parameter>
|
||||
<parameter type="simplekeyframe" name="Green Tint" default="1200" min="0" max="2500" factor="1000">
|
||||
@@ -15,7 +15,7 @@
|
||||
<name>White Balance</name>
|
||||
<description>Adjust the white balance / color temperature</description>
|
||||
<author>Dan Dennedy</author>
|
||||
<parameter type="color" name="Neutral Color" default="0xFFFFFF">
|
||||
<parameter type="color" name="Neutral Color" default="0xffffffff">
|
||||
<name>Neutral Color</name>
|
||||
</parameter>
|
||||
<parameter type="simplekeyframe" name="Green Tint" default="1333" min="0" max="10000" factor="10000">
|
||||
|
||||
14
effects/frei0r_colgate.xml
Normal file
14
effects/frei0r_colgate.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<effect tag="frei0r.colgate" id="frei0r.colgate">
|
||||
<name>White Balance (LMS space)</name>
|
||||
<description>Do simple color correction, in a physically meaningful
|
||||
way</description>
|
||||
<author>Steiner H. Gunderson</author>
|
||||
<parameter type="color" name="Neutral Color" default="0x7f7f7fff">
|
||||
<name>Neutral Color</name>
|
||||
</parameter>
|
||||
<parameter type="simplekeyframe" name="Color Temperature"
|
||||
default="6500" min="1000" max="15000" factor="15000">
|
||||
<name>Color Temperature</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
@@ -3,7 +3,7 @@
|
||||
<name>Color Distance</name>
|
||||
<description>Calculates the distance between the selected color and the current pixel and uses that value as new pixel value</description>
|
||||
<author>Richard Spindler</author>
|
||||
<parameter type="color" name="Color" default="0x000000">
|
||||
<parameter type="color" name="Color" default="0x000000ff">
|
||||
<name>Source Color</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
|
||||
9
effects/frei0r_colortap.xml
Normal file
9
effects/frei0r_colortap.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<effect tag="frei0r.colortap" id="frei0r.colortap">
|
||||
<name>Color Effect</name>
|
||||
<description>Applies a pre-made color effect to image</description>
|
||||
<author>Janne Liljeblad</author>
|
||||
<parameter type="list" name="table" default="xpro" paramlist="xpro;sepia;heat;red_green;old_photo;xray;esses;yellow_blue">
|
||||
<name>Type</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
61
effects/frei0r_keyspillm0pup.xml
Normal file
61
effects/frei0r_keyspillm0pup.xml
Normal file
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<effect LC_NUMERIC="C" tag="frei0r.keyspillm0pup" id="frei0r.keyspillm0pup">
|
||||
<name>Key Spill Mop Up</name>
|
||||
<description>Reduces the visibility of key color spill in chroma keying</description>
|
||||
<author>Marko Cebokli</author>
|
||||
|
||||
<parameter type="color" name="Key color" default="0x1010D0ff">
|
||||
<name>Key color</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="color" name="Target color" default="0xC87F65ff">
|
||||
<name>Target color</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="list" name="Mask type" default="0" paramlist="0;1;2;3">
|
||||
<paramlistdisplay>Color distance, Transparency, Edge inwards, Edge outwards</paramlistdisplay>
|
||||
<name>Mask type</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="constant" name="Tolerance" default="240" min="0" max="1000" factor="1000">
|
||||
<name>Tolerance</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="constant" name="Slope" default="400" min="0" max="1000" factor="1000">
|
||||
<name>Slope</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="constant" name="Hue gate" default="250" min="0" max="1000" factor="1000">
|
||||
<name>Hue gate</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="constant" name="Saturation threshold" default="150" min="0" max="1000" factor="1000">
|
||||
<name>Saturation threshold</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="list" name="Operation 1" default="1" paramlist="0;1;2;3;4">
|
||||
<paramlistdisplay>None, De-Key, Target, Desaturate, Luma adjust</paramlistdisplay>
|
||||
<name>Operation 1</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="constant" name="Amount 1" default="500" min="0" max="1000" factor="1000">
|
||||
<name>Amount 1</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="list" name="Operation 2" default="0" paramlist="0;1;2;3;4">
|
||||
<paramlistdisplay>None, De-Key, Target, Desaturate, Luma adjust</paramlistdisplay>
|
||||
<name>Operation 2</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="constant" name="Amount 2" default="0" min="0" max="1000" factor="1000">
|
||||
<name>Amount 2</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="bool" name="Show mask" default="0">
|
||||
<name>Show mask</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="bool" name="Mask to Alpha" default="0">
|
||||
<name>Mask to Alpha</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
17
effects/frei0r_medians.xml
Normal file
17
effects/frei0r_medians.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<effect LC_NUMERIC="C" tag="frei0r.medians" id="frei0r.medians">
|
||||
<name>Medians</name>
|
||||
<description>Implements several median-type filters</description>
|
||||
<author>Marko Cebokli</author>
|
||||
|
||||
<parameter type="list" name="Type" default="Square3x3" paramlist="Cross5;Square3x3;Bilevel;Diamond3x3;Square5x5;Temp3;Temp5;ArceBI;ML3D;ML3dEX;VarSize">
|
||||
<paramlistdisplay>Cross5,Square3x3,Bilevel,Diamond3x3,Square5x5,Temp3,Temp5,ArceBI,ML3D,ML3dEX,VarSize</paramlistdisplay>
|
||||
<name>Type</name>
|
||||
</parameter>
|
||||
|
||||
<parameter type="constant" name="Size" default="5" min="0" max="50" factor="50">
|
||||
<name>Size</name>
|
||||
</parameter>
|
||||
|
||||
|
||||
</effect>
|
||||
@@ -1,6 +1,6 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<effect tag="frei0r.scale0tilt" id="frei0r.scale0tilt">
|
||||
<name>Scale and Tilt</name>
|
||||
<name>Crop, Scale and Position</name>
|
||||
<description>Scales, Tilts and Crops an Image</description>
|
||||
<author>Richard Spindler</author>
|
||||
<parameter type="constant" name="Clip left" max="%width-1" min="0" default="0" factor="%width">
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<description>Color based alpha selection</description>
|
||||
<author>Marko Cebokli</author>
|
||||
|
||||
<parameter type="color" name="Color to select" default="0x00FF00">
|
||||
<parameter type="color" name="Color to select" default="0x00ff00ff">
|
||||
<name>Color to select</name>
|
||||
</parameter>
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<description>Color based alpha selection</description>
|
||||
<author>Marko Cebokli</author>
|
||||
|
||||
<parameter type="color" name="Color to select" default="0x00FF00">
|
||||
<parameter type="color" name="Color to select" default="0x00ff00ff">
|
||||
<name>Color to select</name>
|
||||
</parameter>
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<name>3 point balance</name>
|
||||
<description>Balances colors along with 3 points</description>
|
||||
<author>Maksim Golovkin</author>
|
||||
<parameter type="color" name="Black color" default="0x000000">
|
||||
<parameter type="color" name="Black color" default="0x000000ff">
|
||||
<name>Black color</name>
|
||||
</parameter>
|
||||
<parameter type="color" name="Gray color" default="0x808080">
|
||||
<parameter type="color" name="Gray color" default="0x808080ff">
|
||||
<name>Gray color</name>
|
||||
</parameter>
|
||||
<parameter type="color" name="White color" default="0xFFFFFF">
|
||||
<parameter type="color" name="White color" default="0xffffffff">
|
||||
<name>White color</name>
|
||||
</parameter>
|
||||
<parameter type="bool" name="Split preview" default="0">
|
||||
|
||||
16
effects/frei0r_timeout.xml
Normal file
16
effects/frei0r_timeout.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<group>
|
||||
<effect tag="frei0r.timeout" id="frei0r.timeout">
|
||||
<name>Timeout indicator</name>
|
||||
<author>Simon A. Eugster (Granjow)</author>
|
||||
<parameter type="color" name="color" default="0x6893C8ff">
|
||||
<name>Indicator color</name>
|
||||
</parameter>
|
||||
<parameter type="simplekeyframe" name="time" default="0" min="0" max="1000" factor="1000">
|
||||
<name>Time</name>
|
||||
</parameter>
|
||||
<parameter type="simplekeyframe" name="transparency" default="0" min="0" max="1000" factor="1000">
|
||||
<name>Transparency</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
</group>
|
||||
@@ -3,10 +3,10 @@
|
||||
<name>Tint</name>
|
||||
<description>Maps source image luminance between two colors specified</description>
|
||||
<author>Maksim Golovkin</author>
|
||||
<parameter type="color" name="Map black to" default="0x000000">
|
||||
<parameter type="color" name="Map black to" default="0x000000ff">
|
||||
<name>Map black to</name>
|
||||
</parameter>
|
||||
<parameter type="color" name="Map white to" default="0x80FF80">
|
||||
<parameter type="color" name="Map white to" default="0x80FF80ff">
|
||||
<name>Map white to</name>
|
||||
</parameter>
|
||||
<parameter type="simplekeyframe" name="Tint amount" default="250" min="0" max="1000" factor="1000">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<name>Grain</name>
|
||||
<description>Grain over the image</description>
|
||||
<author>Marco Gittler</author>
|
||||
<parameter type="double" name="noise" max="200" min="0" default="40">
|
||||
<parameter type="double" name="noise" max="200" min="0" default="40" suffix="%">
|
||||
<name>Noise</name>
|
||||
</parameter>
|
||||
<parameter type="double" name="contrast" max="400" min="0" default="160">
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parameter type="double" name="delta" max="400" min="0" default="14">
|
||||
<name>Y-Delta</name>
|
||||
</parameter>
|
||||
<parameter type="double" name="every" max="100" min="0" default="20">
|
||||
<parameter type="double" name="every" max="100" min="0" default="20" suffix="%">
|
||||
<name>% of picture have a delta</name>
|
||||
</parameter>
|
||||
<parameter type="double" name="brightnessdelta_up" max="100" min="0" default="20">
|
||||
@@ -15,7 +15,7 @@
|
||||
<parameter type="double" name="brightnessdelta_down" max="100" min="0" default="30">
|
||||
<name>Brightness down</name>
|
||||
</parameter>
|
||||
<parameter type="double" name="brightnessdelta_every" max="100" min="0" default="70">
|
||||
<parameter type="double" name="brightnessdelta_every" max="100" min="0" default="70" suffix="%">
|
||||
<name>Brightness every</name>
|
||||
</parameter>
|
||||
<parameter type="double" name="unevendevelop_up" max="100" min="0" default="60">
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parameter type="bool" name="transition.distort" default="0">
|
||||
<name>Distort</name>
|
||||
</parameter>
|
||||
<parameter type="color" name="background" default="colour:0x00000000" paramprefix="colour:">
|
||||
<parameter type="color" name="background" default="colour:0x00000000" alpha="1" paramprefix="colour:">
|
||||
<name>Background Color</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
|
||||
@@ -6,5 +6,8 @@
|
||||
<parameter type="url" name="resource" default="">
|
||||
<name>Url</name>
|
||||
</parameter>
|
||||
<parameter type="geometry" name="composite.geometry" default="0%,0%:100%x100%" fixed="1" opacity="false">
|
||||
<name>Pan and Zoom</name>
|
||||
</parameter>
|
||||
<parameter type="fixed" name="filter_only" min="1" max="1" default="1" />
|
||||
</effect>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<parameter type="geometry" name="transition.geometry" default="0%,0%:100%x100%" fixed="1" opacity="false">
|
||||
<name>Pan and Zoom</name>
|
||||
</parameter>
|
||||
<parameter type="color" name="background" default="colour:0x00000000" paramprefix="colour:">
|
||||
<parameter type="color" name="background" default="colour:0x00000000" alpha="1" paramprefix="colour:">
|
||||
<name>Background Color</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<parameter type="simplekeyframe" name="transition.oy" max="32000" min="-32000" default="0">
|
||||
<name>Offset Y</name>
|
||||
</parameter>
|
||||
<parameter type="color" name="background" default="colour:0x00000000" paramprefix="colour:">
|
||||
<parameter type="color" name="background" default="colour:0x00000000" alpha="1" paramprefix="colour:">
|
||||
<name>Background Color</name>
|
||||
</parameter>
|
||||
<parameter type="fixed" name="transition.keyed" max="1" min="1" default="1" />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<name>Scratchlines</name>
|
||||
<description>Scratchlines over the picture</description>
|
||||
<author>Marco Gittler</author>
|
||||
<parameter type="double" name="width" max="100" min="0" default="2">
|
||||
<parameter type="double" name="line_width" max="100" min="0" default="2">
|
||||
<name>Width of line</name>
|
||||
</parameter>
|
||||
<parameter type="double" name="num" max="100" min="0" default="5">
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
<parameter type="double" name="gain" max="50" min="-50" default="5.00" decimals="2">
|
||||
<name>Gain</name>
|
||||
</parameter>
|
||||
<parameter type="filterjob" filtertag="sox:analysis" filterparams="" consumer="null" consumerparams="video_off=1 all=1 terminate_on_pause=1" wantedproperties="gain" finalfilter="sox_gain">
|
||||
<parameter type="filterjob" filtertag="sox:analysis" filterparams="" consumer="null" consumerparams="video_off=1 all=1 terminate_on_pause=1">
|
||||
<jobparam name="key">gain</jobparam>
|
||||
<jobparam name="finalfilter">sox_gain</jobparam>
|
||||
<name>Normalize</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
|
||||
@@ -54,7 +54,9 @@
|
||||
</group>
|
||||
|
||||
<group name="MPEG-4" renderer="avformat" extension="mp4" type="av">
|
||||
<profile name="MPEG-4" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000,18000,25000" defaultbitrate="12000" audiobitrates="64,128,192,256,384" defaultaudiobitrate="128"
|
||||
<profile name="MPEG-4/AAC" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000,18000,25000" defaultbitrate="12000" audiobitrates="64,128,192,256,384" defaultaudiobitrate="128"
|
||||
args="f=mp4 acodec=aac ab=%audiobitrate+'k' ar=44100 vcodec=mpeg4 minrate=0 vb=%bitrate+'k' aspect=%dar mbd=2 trellis=1 mv4=1 pass=%passes" />
|
||||
<profile name="MPEG-4/MP3" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000,18000,25000" defaultbitrate="12000" audiobitrates="64,128,192,256,384" defaultaudiobitrate="128"
|
||||
args="f=mp4 acodec=libmp3lame ab=%audiobitrate+'k' ar=44100 vcodec=mpeg4 minrate=0 vb=%bitrate+'k' aspect=%dar mbd=2 trellis=1 mv4=1 pass=%passes" />
|
||||
</group>
|
||||
|
||||
@@ -90,7 +92,7 @@
|
||||
</group>
|
||||
|
||||
<group name="WebM" renderer="avformat" extension="webm" type="av">
|
||||
<profile name="WebM" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000" defaultbitrate="8000"
|
||||
<profile name="WebM" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000,18000,25000" defaultbitrate="8000"
|
||||
audiobitrates="64,128,192,256,384" defaultaudiobitrate="128" args="acodec=vorbis ab=%audiobitrate+'k' ar=44100 aq=50 vcodec=libvpx minrate=0 vb=%bitrate+'k' aspect=%dar maxrate=%bitrate*2+'k' g=120 qmax=42 qmin=10" />
|
||||
</group>
|
||||
|
||||
@@ -124,13 +126,14 @@
|
||||
|
||||
<group name="Lossless/HQ" renderer="avformat" type="av">
|
||||
<groupname id="lossless">Lossless / HQ</groupname>
|
||||
<profile name="FFV1 lossless (video) + FLAC (sound)" extension="avi" args="f=avi acodec=flac ar=48000 ab=1024k ac=2 vcodec=ffv1 qscale=1 aspect=%dar" />
|
||||
<profile name="FFV1 lossless (video) + FLAC (sound)" extension="mkv" args="f=matroska acodec=flac ar=48000 ac=2 vcodec=ffv1 aspect=%dar" />
|
||||
<profile name="FFV1 lossless (video) + PCM (sound)" extension="mkv" args="f=matroska acodec=pcm_s16le ac=2 vcodec=ffv1 aspect=%dar" />
|
||||
<profile name="HuffYUV lossless (video) + PCM (sound)" extension="avi" args="f=avi acodec=pcm_s16le ac=2 vcodec=huffyuv aspect=%dar" />
|
||||
<profile name="MPEG-2 I-frame only (video) + MP2 (sound)" extension="mpg" args="f=mpeg acodec=mp2 ab=384k ar=48000 ac=2 vcodec=mpeg2video qscale=1 qmin=1 aspect=%dar intra=1" />
|
||||
<profile name="MPEG-4 I-frame only (video) + MP3 (sound)" extension="mp4" args="f=mp4 acodec=libmp3lame ab=384k ar=48000 ac=2 vcodec=mpeg4 qscale=1 qmin=1 aspect=%dar intra=1" />
|
||||
<profile name="H.264 I-frame only (video) + AAC (sound)" extension="mp4" args="f=mp4 acodec=aac ab=384k ar=48000 ac=2 pix_fmt=yuv420p vcodec=libx264 cqp=1 subq=1 qmax=1 qmin=1 qcomp=0.6 qdiff=0 coder=ac trellis=1 aspect=%dar intra=1" />
|
||||
<profile name="H.264 lossless slow (video) + AAC (sound)" extension="mp4" args="f=mp4 acodec=aac ab=384k ar=48000 ac=2 pix_fmt=yuv420p vcodec=libx264 cqp=0 me_method=esa subq=8 qmin=10 qcomp=0.6 qdiff=4 qmax=51 coder=ac partitions=+parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 refs=16 flags2=+dct8x8+mixed_refs trellis=1 aspect=%dar" />
|
||||
<profile name="H.264 lossless fast (video) + AAC (sound)" extension="mp4" args="f=mp4 acodec=aac ab=384k ar=48000 ac=2 pix_fmt=yuv420p vcodec=libx264 cqp=0 me_method=dia subq=1 qmin=10 qcomp=0.6 qdiff=4 qmax=51 partitions=-parti4x4-parti8x8-partp4x4-partp8x8-partb8x8 trellis=1 aspect=%dar" />
|
||||
<profile name="H.264 lossless slow (video) + PCM (sound)" extension="mkv" args="f=matroska acodec=pcm_s16le ac=2 pix_fmt=yuv420p vcodec=libx264 qp=0 preset=veryslow aspect=%dar" />
|
||||
<profile name="H.264 lossless fast (video) + PCM (sound)" extension="mkv" args="f=matroska acodec=pcm_s16le ac=2 pix_fmt=yuv420p vcodec=libx264 qp=0 preset=ultrafast aspect=%dar" />
|
||||
</group>
|
||||
|
||||
<group name="Apple" renderer="avformat" type="av">
|
||||
|
||||
0
lumas/burst.pgm
Executable file → Normal file
0
lumas/burst.pgm
Executable file → Normal file
0
lumas/checkerboard_small.pgm
Executable file → Normal file
0
lumas/checkerboard_small.pgm
Executable file → Normal file
0
lumas/horizontal_blinds.pgm
Executable file → Normal file
0
lumas/horizontal_blinds.pgm
Executable file → Normal file
0
lumas/symmetric_clock.pgm
Executable file → Normal file
0
lumas/symmetric_clock.pgm
Executable file → Normal file
459
mindmap.svg
459
mindmap.svg
@@ -1079,6 +1079,90 @@
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<marker
|
||||
markerWidth="3.9808"
|
||||
markerHeight="3.9318"
|
||||
orient="auto"
|
||||
id="marker4304">
|
||||
<path
|
||||
style="color:#000000;fill:#d8d8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:transform-center-x="-0.56748783"
|
||||
d="m 2.5578878,2.1402036e-5 -3.9808,1.965899997964 0,-3.9318 z"
|
||||
id="path4302"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:transform-center-y="2.1402036e-05" />
|
||||
</marker>
|
||||
<marker
|
||||
markerWidth="3.9808"
|
||||
markerHeight="3.9318"
|
||||
orient="auto"
|
||||
id="marker4309">
|
||||
<path
|
||||
style="color:#000000;fill:#d8d8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:transform-center-x="0.56748783"
|
||||
d="m -2.5578878,2.1402036e-5 3.9808,1.965899997964 0,-3.9318 z"
|
||||
id="path4307"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:transform-center-y="2.1402036e-05" />
|
||||
</marker>
|
||||
<marker
|
||||
markerWidth="3.9807999"
|
||||
markerHeight="3.9317999"
|
||||
orient="auto"
|
||||
id="marker4309-9">
|
||||
<path
|
||||
style="color:#000000;fill:#d8d8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:transform-center-x="0.56748783"
|
||||
d="m -2.5578878,2.1402036e-5 3.9808,1.965899997964 0,-3.9318 z"
|
||||
id="path4307-5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:transform-center-y="2.1402036e-05" />
|
||||
</marker>
|
||||
<marker
|
||||
markerWidth="3.9807999"
|
||||
markerHeight="3.9317999"
|
||||
orient="auto"
|
||||
id="marker4304-5">
|
||||
<path
|
||||
style="color:#000000;fill:#d8d8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:transform-center-x="-0.56748783"
|
||||
d="m 2.5578878,2.1402036e-5 -3.9808,1.965899997964 0,-3.9318 z"
|
||||
id="path4302-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:transform-center-y="2.1402036e-05" />
|
||||
</marker>
|
||||
<marker
|
||||
markerWidth="3.9807999"
|
||||
markerHeight="3.9317999"
|
||||
orient="auto"
|
||||
id="marker4309-0">
|
||||
<path
|
||||
style="color:#000000;fill:#d8d8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:transform-center-x="0.56748783"
|
||||
d="m -2.5578878,2.1402036e-5 3.9808,1.965899997964 0,-3.9318 z"
|
||||
id="path4307-0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:transform-center-y="2.1402036e-05" />
|
||||
</marker>
|
||||
<marker
|
||||
markerWidth="3.9807999"
|
||||
markerHeight="3.9317999"
|
||||
orient="auto"
|
||||
id="marker4304-1">
|
||||
<path
|
||||
style="color:#000000;fill:#d8d8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:transform-center-x="-0.56748783"
|
||||
d="m 2.5578878,2.1402036e-5 -3.9808,1.965899997964 0,-3.9318 z"
|
||||
id="path4302-1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:transform-center-y="2.1402036e-05" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
@@ -1087,11 +1171,11 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.061871843"
|
||||
inkscape:cx="7521.0349"
|
||||
inkscape:cy="3852.2176"
|
||||
inkscape:zoom="0.11313708"
|
||||
inkscape:cx="10267.259"
|
||||
inkscape:cy="6273.3081"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:current-layer="layer3"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="709"
|
||||
@@ -2031,18 +2115,18 @@
|
||||
y="2910.9241">Color correction tools</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-1431.6742"
|
||||
y="2717.301"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-1434.5314"
|
||||
y="2751.5867"
|
||||
id="text13442"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan13444"
|
||||
x="-1431.6742"
|
||||
y="2717.301">Allow to select an area in the displays (e.g. the 10 % darkest pixels in Levels)</tspan><tspan
|
||||
x="-1434.5314"
|
||||
y="2751.5867">Allow to select an area in the displays (e.g. the 10 % darkest pixels in Levels)</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="-1431.6742"
|
||||
y="2747.301"
|
||||
x="-1434.5314"
|
||||
y="2811.5867"
|
||||
id="tspan13446">and highlight these pixels in the project monitor</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
@@ -2132,6 +2216,17 @@
|
||||
x="-3539.5745"
|
||||
id="tspan533"
|
||||
sodipodi:role="line">Monitors</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3497"
|
||||
y="-1007.4729"
|
||||
x="5283.937"
|
||||
style="font-size:144px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.2017544;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
|
||||
xml:space="preserve"><tspan
|
||||
y="-1007.4729"
|
||||
x="5283.937"
|
||||
id="tspan3500"
|
||||
sodipodi:role="line">Titler</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
@@ -2140,33 +2235,33 @@
|
||||
transform="translate(5590.4771,2020.1246)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-1694.4684"
|
||||
y="2400.0696"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-1863.0398"
|
||||
y="2357.2124"
|
||||
id="text11110"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan11112"
|
||||
x="-1694.4684"
|
||||
y="2400.0696">Vectorscope (YCbCr)</tspan><tspan
|
||||
x="-1863.0398"
|
||||
y="2357.2124">Vectorscope (YCbCr)</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="-1694.4684"
|
||||
y="2430.0696"
|
||||
x="-1863.0398"
|
||||
y="2417.2124"
|
||||
id="tspan3270">with zoom slider</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-1342.1429"
|
||||
y="2490.2192"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-1405.0001"
|
||||
y="2510.2192"
|
||||
id="text13262"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan13264"
|
||||
x="-1342.1429"
|
||||
y="2490.2192">Levels with linear and logarithmic scale</tspan></text>
|
||||
x="-1405.0001"
|
||||
y="2510.2192">Levels with linear and logarithmic scale</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="3651.0798"
|
||||
y="-283.18719"
|
||||
id="text13262-4"
|
||||
@@ -2177,44 +2272,44 @@
|
||||
y="-283.18719">As much room for monitors as possible, less priority for timelines</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-1996.0614"
|
||||
y="2490.8193"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-2150.3472"
|
||||
y="2482.2478"
|
||||
id="text13415"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan13417"
|
||||
x="-1996.0614"
|
||||
y="2490.8193">RGB parade</tspan></text>
|
||||
x="-2150.3472"
|
||||
y="2482.2478">RGB parade</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="4599.0342"
|
||||
y="2153.9888"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="4610.4629"
|
||||
y="2182.5603"
|
||||
id="text13262-4-1"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan13264-5-6"
|
||||
x="4599.0342"
|
||||
y="2153.9888">Specify target size</tspan><tspan
|
||||
x="4610.4629"
|
||||
y="2182.5603">Specify target size</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="4599.0342"
|
||||
y="2183.9888"
|
||||
x="4610.4629"
|
||||
y="2242.5603"
|
||||
id="tspan13573">(Note: DVDShrink was somehow able to do that)</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="629.29169"
|
||||
y="2668.8303"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="575.00598"
|
||||
y="2705.9731"
|
||||
id="text13575"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan13577"
|
||||
x="629.29169"
|
||||
y="2668.8303">Curves</tspan></text>
|
||||
x="575.00598"
|
||||
y="2705.9731">Curves</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="3114.6748"
|
||||
y="3758.7349"
|
||||
id="text3198"
|
||||
@@ -2229,33 +2324,33 @@
|
||||
id="tspan3252">http://kdenlive.org/forum/automatic-captions-youtube-demo</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-2290.8105"
|
||||
y="2404.5063"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-2633.6677"
|
||||
y="2415.9348"
|
||||
id="text13415-9"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan13417-2"
|
||||
x="-2290.8105"
|
||||
y="2404.5063">Color bars (for TV)</tspan></text>
|
||||
x="-2633.6677"
|
||||
y="2415.9348">Color bars (for TV)</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-471.45425"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-580.55072"
|
||||
y="4009.6975"
|
||||
id="text3198-8"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="-471.45425"
|
||||
x="-580.55072"
|
||||
y="4009.6975"
|
||||
id="tspan3252-4">Levels display (dB)</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="-471.45425"
|
||||
y="4039.6975"
|
||||
x="-580.55072"
|
||||
y="4069.6975"
|
||||
id="tspan3334">(with checkboxes for each track)</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="288.88086"
|
||||
y="-1409.5881"
|
||||
id="text13262-4-8"
|
||||
@@ -2266,55 +2361,55 @@
|
||||
y="-1409.5881">Celtx</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="2565.7876"
|
||||
y="3765.6318"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="2688.6448"
|
||||
y="3271.3462"
|
||||
id="text3386"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3388"
|
||||
x="2565.7876"
|
||||
y="3765.6318">Blender</tspan></text>
|
||||
x="2688.6448"
|
||||
y="3271.3462">Blender</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="2741.554"
|
||||
y="3785.835"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="3101.554"
|
||||
y="3357.2634"
|
||||
id="text3399"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3401"
|
||||
x="2741.554"
|
||||
y="3785.835">OpenFX</tspan></text>
|
||||
x="3101.554"
|
||||
y="3357.2634">OpenFX</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="303.56454"
|
||||
y="4082.9124"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="323.76761"
|
||||
y="4111.1968"
|
||||
id="text3198-8-0"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="303.56454"
|
||||
y="4082.9124"
|
||||
x="323.76761"
|
||||
y="4111.1968"
|
||||
id="tspan3334-6">Audacity project support</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="2407.8591"
|
||||
y="-1767.9474"
|
||||
y="-1820.8046"
|
||||
id="text13262-4-3"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan13264-5-4"
|
||||
x="2407.8591"
|
||||
y="-1767.9474">Effects (like moving things around) directly on the project monitor</tspan><tspan
|
||||
y="-1820.8046">Effects (like moving things around) directly on the project monitor</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="2407.8591"
|
||||
y="-1737.9474"
|
||||
y="-1760.8046"
|
||||
id="tspan3297">instead of red rectangle (see Composite effect)</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="1100.912"
|
||||
y="2722.6309"
|
||||
id="text3227"
|
||||
@@ -2325,7 +2420,7 @@
|
||||
y="2722.6309">GEGL</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="1306.9829"
|
||||
y="2646.8691"
|
||||
id="text3231"
|
||||
@@ -2336,7 +2431,7 @@
|
||||
y="2646.8691">GIMP</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="1399.9169"
|
||||
y="2721.6206"
|
||||
id="text3235"
|
||||
@@ -2347,29 +2442,29 @@
|
||||
y="2721.6206">ShowFoto</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="3007.51"
|
||||
y="-1522.7045"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="2108.9385"
|
||||
y="-1508.4187"
|
||||
id="text13262-4-3-7"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="3007.51"
|
||||
y="-1522.7045"
|
||||
x="2108.9385"
|
||||
y="-1508.4187"
|
||||
id="tspan3297-5">Set zoom level</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-2251.8438"
|
||||
y="2730.7996"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-2303.2722"
|
||||
y="2762.228"
|
||||
id="text13415-9-7"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan13417-2-7"
|
||||
x="-2251.8438"
|
||||
y="2730.7996">Color safety (TV) display</tspan></text>
|
||||
x="-2303.2722"
|
||||
y="2762.228">Color safety (TV) display</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-4944.0391"
|
||||
y="-812.96991"
|
||||
id="text13262-4-8-5"
|
||||
@@ -2380,7 +2475,7 @@
|
||||
y="-812.96991">Unit Tests</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-2432.7744"
|
||||
y="-886.15479"
|
||||
id="text13262-4-8-5-5"
|
||||
@@ -2391,7 +2486,7 @@
|
||||
y="-886.15479">Don't crash when an effect crashes</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-1491.0187"
|
||||
y="28.033258"
|
||||
id="text13262-4-8-5-5-9"
|
||||
@@ -2406,15 +2501,15 @@
|
||||
id="tspan3880">(Proxy Clips)</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="737.45343"
|
||||
y="3027.1831"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="354.59628"
|
||||
y="3058.6116"
|
||||
id="text3227-4"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3229-3"
|
||||
x="737.45343"
|
||||
y="3027.1831">ASC CDL Effect, import/export</tspan></text>
|
||||
x="354.59628"
|
||||
y="3058.6116">ASC CDL Effect, import/export</tspan></text>
|
||||
<path
|
||||
style="fill:#2dab00;fill-opacity:1;stroke:none"
|
||||
d="m -5938.9449,4645.1291 c -1.7518,1.2513 9.1348,13.4484 15.5163,12.0126 8.9817,-2.0209 20.5214,-31.5331 18.7696,-33.2849 -1.0011,-1.2514 -16.5818,22.3354 -20.021,23.7749 -2.5715,1.0762 -14.2649,-2.5026 -14.2649,-2.5026 z"
|
||||
@@ -2441,7 +2536,7 @@
|
||||
y="0"
|
||||
xlink:href="#path3261"
|
||||
id="use4237"
|
||||
transform="translate(6600.2311,-2021.7106)"
|
||||
transform="translate(6705.9454,-1955.9963)"
|
||||
width="14148.571"
|
||||
height="6765.7144" />
|
||||
<use
|
||||
@@ -2461,7 +2556,7 @@
|
||||
y="0"
|
||||
xlink:href="#path3261-2"
|
||||
id="use4263"
|
||||
transform="translate(4888.0185,-2191.5654)"
|
||||
transform="translate(5113.7328,-2197.2797)"
|
||||
width="14148.571"
|
||||
height="6765.7144" />
|
||||
<use
|
||||
@@ -2469,7 +2564,7 @@
|
||||
y="0"
|
||||
xlink:href="#path3261"
|
||||
id="use4265"
|
||||
transform="translate(4747.153,-2199.0073)"
|
||||
transform="translate(4867.153,-2204.7216)"
|
||||
width="14148.571"
|
||||
height="6765.7144" />
|
||||
<use
|
||||
@@ -2482,7 +2577,7 @@
|
||||
x="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="4651.2607"
|
||||
y="-163.50342"
|
||||
id="text13262-4-6"
|
||||
@@ -2496,7 +2591,7 @@
|
||||
id="text3288"
|
||||
y="-71.055161"
|
||||
x="2257.0693"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="-71.055161"
|
||||
x="2257.0693"
|
||||
@@ -2504,7 +2599,7 @@
|
||||
sodipodi:role="line">Make customizable</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="1620.6732"
|
||||
y="1.675822"
|
||||
id="text3292"
|
||||
@@ -2524,20 +2619,20 @@
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3848"
|
||||
y="-1475.5615"
|
||||
x="2193.2241"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
y="-1439.8472"
|
||||
x="2508.9385"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan3850"
|
||||
y="-1475.5615"
|
||||
x="2193.2241"
|
||||
y="-1439.8472"
|
||||
x="2508.9385"
|
||||
sodipodi:role="line">Display both monitors (clip/project) to compare results</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3856"
|
||||
y="-1203.4962"
|
||||
x="4411.6221"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan3858"
|
||||
y="-1203.4962"
|
||||
@@ -2546,20 +2641,20 @@
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3860"
|
||||
y="4036.4453"
|
||||
x="982.38702"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
y="4064.7295"
|
||||
x="1079.3617"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan3862"
|
||||
y="4036.4453"
|
||||
x="982.38702"
|
||||
y="4064.7295"
|
||||
x="1079.3617"
|
||||
sodipodi:role="line">Set audio track to general sound level</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3864"
|
||||
y="4177.1982"
|
||||
x="1280.7074"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan3866"
|
||||
y="4177.1982"
|
||||
@@ -2570,7 +2665,7 @@
|
||||
id="text3874"
|
||||
y="159.74539"
|
||||
x="5255.332"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="159.74539"
|
||||
x="5255.332"
|
||||
@@ -2582,7 +2677,7 @@
|
||||
id="tspan3878">(similar to adding a .kdenlive file as clip to the timeline)</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="6559.6177"
|
||||
y="268.31683"
|
||||
id="text3882"
|
||||
@@ -2593,7 +2688,7 @@
|
||||
y="268.31683">EDL (Edit Decision List)</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="-3640.9109"
|
||||
y="2943.2024"
|
||||
id="text506"
|
||||
@@ -2611,7 +2706,7 @@
|
||||
id="text3486"
|
||||
y="-176.01756"
|
||||
x="-1375.8613"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan3490"
|
||||
y="-176.01756"
|
||||
@@ -2628,43 +2723,139 @@
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3489"
|
||||
y="4072.3269"
|
||||
x="-1186.6422"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
y="4068.2864"
|
||||
x="-1849.3022"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan3493"
|
||||
y="4072.3269"
|
||||
x="-1186.6422"
|
||||
y="4068.2864"
|
||||
x="-1849.3022"
|
||||
sodipodi:role="line">Automatic synchronisation</tspan><tspan
|
||||
y="4102.3271"
|
||||
x="-1186.6422"
|
||||
y="4128.2866"
|
||||
x="-1849.3022"
|
||||
sodipodi:role="line"
|
||||
id="tspan3497">for additional audio (portable recorders etc.)</tspan><tspan
|
||||
y="4132.3267"
|
||||
x="-1186.6422"
|
||||
y="4188.2866"
|
||||
x="-1849.3022"
|
||||
sodipodi:role="line"
|
||||
id="tspan3499">http://jeff.ecchi.ca/blog/2011/07/25/automated-multicamera-clip-syncing/</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text518"
|
||||
y="3808.0583"
|
||||
x="1992.021"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
y="3493.7727"
|
||||
x="1340.5924"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="3808.0583"
|
||||
x="1992.021"
|
||||
y="3493.7727"
|
||||
x="1340.5924"
|
||||
id="tspan3488"
|
||||
sodipodi:role="line">Unified keyframing for all effects</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="1648.5691"
|
||||
y="3707.043"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="1579.9977"
|
||||
y="3375.6145"
|
||||
id="text3490"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3492"
|
||||
x="1648.5691"
|
||||
y="3707.043">Smooth Keyframe interpolation (see Blender)</tspan></text>
|
||||
x="1579.9977"
|
||||
y="3375.6145">Smooth Keyframe interpolation (see Blender)</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="5587.4399"
|
||||
y="-894.38953"
|
||||
id="text3502"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="5587.4399"
|
||||
y="-894.38953"
|
||||
id="tspan3504">Spell checking</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3509"
|
||||
y="-1018.6752"
|
||||
x="5864.583"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan3511"
|
||||
y="-1018.6752"
|
||||
x="5864.583"
|
||||
sodipodi:role="line">Change multiple items</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="5720.2974"
|
||||
y="-1165.818"
|
||||
id="text3513"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="5720.2974"
|
||||
y="-1165.818"
|
||||
id="tspan3515">Variables (replaced by timecode etc.)</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3517"
|
||||
y="-1230.4678"
|
||||
x="5380.8862"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan3519"
|
||||
y="-1230.4678"
|
||||
x="5380.8862"
|
||||
sodipodi:role="line">Use SVGs?</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="5035.4141"
|
||||
y="-1173.8992"
|
||||
id="text3521"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="5035.4141"
|
||||
y="-1173.8992"
|
||||
id="tspan3523">Guidelines</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
|
||||
x="5469.4575"
|
||||
y="-1379.0392"
|
||||
id="text3525"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="5469.4575"
|
||||
y="-1379.0392"
|
||||
id="tspan3527">Automatically use all files (live update) in a directory</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#d8d8d8;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker4309);marker-end:url(#marker4304);stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 11198.572,729.99998 122.857,-64.28571"
|
||||
id="path4312"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-5590.4771,-2020.1246)" />
|
||||
<path
|
||||
style="fill:none;stroke:#d8d8d8;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -5958.8801,4691.5687 97.1428,0"
|
||||
id="path3529"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="color:#000000;fill:#d8d8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:transform-center-x="-0.56748783"
|
||||
d="m -5857.9701,4691.4519 -3.9808,1.9659 0,-3.9318 z"
|
||||
id="path3531"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:transform-center-y="2.1402036e-05" />
|
||||
<path
|
||||
style="fill:none;stroke:#d8d8d8;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-start:url(#marker4309);marker-end:url(#marker4304);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m -355.7631,6731.4639 96.12233,0"
|
||||
id="path5071"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-5590.4771,-2020.1246)" />
|
||||
<path
|
||||
style="fill:none;stroke:#d8d8d8;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#marker4309);marker-end:url(#marker4304)"
|
||||
d="m 5608.0954,-1290.1246 122.857,-64.2857"
|
||||
id="path4312-1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 457 KiB After Width: | Height: | Size: 468 KiB |
@@ -25,12 +25,14 @@
|
||||
#include <KIntSpinBox>
|
||||
#include <KDebug>
|
||||
#include <KMessageBox>
|
||||
#include <KApplication>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDomDocument>
|
||||
#include <QInputDialog>
|
||||
#include <QProcess>
|
||||
|
||||
QStringList SamplePlugin::generators(const QStringList producers) const
|
||||
QStringList SamplePlugin::generators(const QStringList &producers) const
|
||||
{
|
||||
QStringList result;
|
||||
if (producers.contains("pango")) result << i18n("Countdown");
|
||||
@@ -39,7 +41,7 @@ QStringList SamplePlugin::generators(const QStringList producers) const
|
||||
}
|
||||
|
||||
|
||||
KUrl SamplePlugin::generatedClip(const QString &generator, const KUrl &projectFolder, const QStringList &/*lumaNames*/, const QStringList &/*lumaFiles*/, const double fps, const int /*width*/, const int height)
|
||||
KUrl SamplePlugin::generatedClip(const QString &renderer, const QString &generator, const KUrl &projectFolder, const QStringList &/*lumaNames*/, const QStringList &/*lumaFiles*/, const double fps, const int /*width*/, const int height)
|
||||
{
|
||||
QString prePath;
|
||||
if (generator == i18n("Noise")) {
|
||||
@@ -51,15 +53,15 @@ KUrl SamplePlugin::generatedClip(const QString &generator, const KUrl &projectFo
|
||||
ct++;
|
||||
counter = QString::number(ct).rightJustified(5, '0', false);
|
||||
}
|
||||
QDialog d;
|
||||
QPointer<QDialog> d = new QDialog;
|
||||
Ui::CountDown_UI view;
|
||||
view.setupUi(&d);
|
||||
view.setupUi(d);
|
||||
if (generator == i18n("Noise")) {
|
||||
d.setWindowTitle(tr("Create Noise Clip"));
|
||||
d->setWindowTitle(i18n("Create Noise Clip"));
|
||||
view.font_label->setHidden(true);
|
||||
view.font->setHidden(true);
|
||||
} else {
|
||||
d.setWindowTitle(tr("Create Countdown Clip"));
|
||||
d->setWindowTitle(i18n("Create Countdown Clip"));
|
||||
view.font->setValue(height);
|
||||
}
|
||||
|
||||
@@ -68,50 +70,56 @@ KUrl SamplePlugin::generatedClip(const QString &generator, const KUrl &projectFo
|
||||
|
||||
QString clipFile = prePath + counter + ".mlt";
|
||||
view.path->setUrl(KUrl(clipFile));
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
QDomDocument doc;
|
||||
QDomElement mlt = doc.createElement("mlt");
|
||||
QDomElement playlist = doc.createElement("playlist");
|
||||
KUrl result;
|
||||
|
||||
if (d->exec() == QDialog::Accepted) {
|
||||
QProcess generatorProcess;
|
||||
|
||||
// Disable VDPAU so that rendering will work even if there is a Kdenlive instance using VDPAU
|
||||
#if QT_VERSION >= 0x040600
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
env.insert("MLT_NO_VDPAU", "1");
|
||||
generatorProcess.setProcessEnvironment(env);
|
||||
#else
|
||||
QStringList env = QProcess::systemEnvironment();
|
||||
env << "MLT_NO_VDPAU=1";
|
||||
generatorProcess.setEnvironment(env);
|
||||
#endif
|
||||
QStringList args;
|
||||
if (generator == i18n("Noise")) {
|
||||
QDomElement prod = doc.createElement("producer");
|
||||
prod.setAttribute("mlt_service", "noise");
|
||||
prod.setAttribute("in", "0");
|
||||
prod.setAttribute("out", QString::number((int) fps * view.duration->value()));
|
||||
playlist.appendChild(prod);
|
||||
} else {
|
||||
args << "noise:" << "in=0" << QString("out=" + QString::number((int) fps * view.duration->value()));
|
||||
}
|
||||
else {
|
||||
// Countdown producer
|
||||
for (int i = 0; i < view.duration->value(); i++) {
|
||||
// Create the producers
|
||||
QDomElement prod = doc.createElement("producer");
|
||||
prod.setAttribute("mlt_service", "pango");
|
||||
prod.setAttribute("in", "0");
|
||||
prod.setAttribute("out", QString::number((int) fps));
|
||||
prod.setAttribute("text", QString::number(view.duration->value() - i));
|
||||
//FIXME: the font and pad values are approximate, the pango producer seems unable
|
||||
// to produce a predictable frame size.
|
||||
prod.setAttribute("font", QString::number(view.font->value()) + "px");
|
||||
//prod.setAttribute("pad", 50);
|
||||
playlist.appendChild(prod);
|
||||
args << "pango:" << "in=0" << QString("out=" + QString::number((int) fps * view.duration->value()));
|
||||
args << QString("text=" + QString::number(view.duration->value() - i));
|
||||
args << QString("font=" + QString::number(view.font->value()) + "px");
|
||||
}
|
||||
}
|
||||
mlt.appendChild(playlist);
|
||||
doc.appendChild(mlt);
|
||||
QFile file(view.path->url().path());
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
kWarning() << "////// ERROR writing to file: " << view.path->url().path();
|
||||
KMessageBox::error(0, i18n("Cannot write to file %1", view.path->url().path()));
|
||||
return KUrl();
|
||||
|
||||
args << "-consumer"<<QString("xml:%1").arg(view.path->url().path());
|
||||
generatorProcess.start(renderer, args);
|
||||
if (generatorProcess.waitForFinished()) {
|
||||
if (generatorProcess.exitStatus() == QProcess::CrashExit) {
|
||||
kDebug() << "/// Generator failed: ";
|
||||
QString error = generatorProcess.readAllStandardError();
|
||||
KMessageBox::sorry(kapp->activeWindow(), i18n("Failed to generate clip:\n%1", error, i18n("Generator Failed")));
|
||||
}
|
||||
else {
|
||||
result = view.path->url();
|
||||
}
|
||||
} else {
|
||||
kDebug() << "/// Generator failed: ";
|
||||
QString error = generatorProcess.readAllStandardError();
|
||||
KMessageBox::sorry(kapp->activeWindow(), i18n("Failed to generate clip:\n%1", error, i18n("Generator Failed")));
|
||||
}
|
||||
QTextStream out(&file);
|
||||
out << doc.toString();
|
||||
if (file.error() != QFile::NoError) {
|
||||
KMessageBox::error(0, i18n("Cannot write to file %1", view.path->url().path()));
|
||||
file.close();
|
||||
return KUrl();
|
||||
}
|
||||
file.close();
|
||||
return view.path->url();
|
||||
}
|
||||
return KUrl();
|
||||
delete d;
|
||||
return result;
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN2(kdenlive_sampleplugin, SamplePlugin)
|
||||
|
||||
#include "sampleplugin.moc"
|
||||
|
||||
@@ -34,8 +34,8 @@ class SamplePlugin : public QObject, public ClipGenerator
|
||||
Q_INTERFACES(ClipGenerator)
|
||||
|
||||
public:
|
||||
QStringList generators(const QStringList producers = QStringList()) const;
|
||||
KUrl generatedClip(const QString &generator, const KUrl &projectFolder, const QStringList &lumaNames, const QStringList &lumaFiles, const double fps, const int width, const int height);
|
||||
QStringList generators(const QStringList &producers = QStringList()) const;
|
||||
KUrl generatedClip(const QString &renderer, const QString &generator, const KUrl &projectFolder, const QStringList &lumaNames, const QStringList &lumaFiles, const double fps, const int width, const int height);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -69,7 +69,12 @@ int main(int argc, char **argv)
|
||||
QString profile = args.takeFirst();
|
||||
QString rendermodule = args.takeFirst();
|
||||
QString player = args.takeFirst();
|
||||
QString src = args.takeFirst();
|
||||
QByteArray srcString = args.takeFirst().toUtf8();
|
||||
QUrl srcurl = QUrl::fromEncoded(srcString);
|
||||
QString src = srcurl.path();
|
||||
// The QUrl path() strips the consumer: protocol, so re-add it if necessary
|
||||
if (srcString.startsWith("consumer:"))
|
||||
src.prepend("consumer:");
|
||||
QUrl desturl = QUrl::fromEncoded(args.takeFirst().toUtf8());
|
||||
QString dest = desturl.path();
|
||||
bool dualpass = false;
|
||||
@@ -80,7 +85,7 @@ int main(int argc, char **argv)
|
||||
if (vprepos >= 0) {
|
||||
vpre=args.at(vprepos);
|
||||
}
|
||||
QStringList vprelist = vpre.replace("vpre=", "").split(",");
|
||||
QStringList vprelist = vpre.replace("vpre=", "").split(',');
|
||||
if (vprelist.size() > 0) {
|
||||
args.replaceInStrings(QRegExp("^vpre=.*"), QString("vpre=").append(vprelist.at(0)));
|
||||
}
|
||||
@@ -96,6 +101,14 @@ int main(int argc, char **argv)
|
||||
doerase = erase;
|
||||
}
|
||||
|
||||
// Decode metadata
|
||||
for (int i = 0; i < args.count(); ++i) {
|
||||
if (args.at(i).startsWith("meta.attr")) {
|
||||
QString data = args.at(i);
|
||||
args.replace(i, data.section('=', 0, 0) + "=\"" + QUrl::fromPercentEncoding(data.section('=', 1).toUtf8()) + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "//STARTING RENDERING: " << erase << "," << usekuiserver << "," << render << "," << profile << "," << rendermodule << "," << player << "," << src << "," << dest << "," << preargs << "," << args << "," << in << "," << out ;
|
||||
RenderJob *job = new RenderJob(doerase, usekuiserver, pid, render, profile, rendermodule, player, src, dest, preargs, args, in, out);
|
||||
if (!locale.isEmpty()) job->setLocale(locale);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
class SleepThread : QThread
|
||||
{
|
||||
public:
|
||||
virtual void run() {};
|
||||
virtual void run() {}
|
||||
static void msleep(unsigned long msecs) {
|
||||
QThread::msleep(msecs);
|
||||
}
|
||||
@@ -118,7 +118,7 @@ RenderJob::RenderJob(bool erase, bool usekuiserver, int pid, const QString& rend
|
||||
|
||||
RenderJob::~RenderJob()
|
||||
{
|
||||
if (m_renderProcess) delete m_renderProcess;
|
||||
delete m_renderProcess;
|
||||
if (m_enablelog) {
|
||||
m_logfile.close();
|
||||
}
|
||||
@@ -302,8 +302,8 @@ void RenderJob::initKdenliveDbusInterface()
|
||||
m_dbusargs.append((int) 0);
|
||||
if (!m_args.contains("pass=2"))
|
||||
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingProgress", m_dbusargs);
|
||||
connect(m_kdenliveinterface, SIGNAL(abortRenderJob(const QString&)),
|
||||
this, SLOT(slotAbort(const QString&)));
|
||||
connect(m_kdenliveinterface, SIGNAL(abortRenderJob(QString)),
|
||||
this, SLOT(slotAbort(QString)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,17 +11,19 @@ endif(APPLE)
|
||||
macro_optional_find_package(Nepomuk)
|
||||
macro_optional_find_package(QJSON)
|
||||
|
||||
option(WITH_V4L "Build capture support with Video4Linux" ON)
|
||||
option(WITH_JogShuttle "Build Jog/Shuttle support" ON)
|
||||
|
||||
if(WITH_V4L)
|
||||
# This can be changed to support FreeBSD as soon as we move to a newer V4L2
|
||||
# header.
|
||||
check_include_files(linux/ioctl.h HAVE_LINUX_IOCTL_H)
|
||||
if(HAVE_LINUX_IOCTL_H)
|
||||
set(BUILD_V4L TRUE)
|
||||
endif(HAVE_LINUX_IOCTL_H)
|
||||
endif(WITH_V4L)
|
||||
set(FFMPEG_SUFFIX "" CACHE STRING "FFmpeg custom suffix")
|
||||
|
||||
macro_optional_find_package(LibV4L2)
|
||||
macro_log_feature(LIBV4L2_FOUND
|
||||
"libv4l"
|
||||
"Collection of video4linux support libraries"
|
||||
"http://freecode.com/projects/libv4l"
|
||||
FALSE
|
||||
""
|
||||
"Required for better webcam support"
|
||||
)
|
||||
|
||||
if(WITH_JogShuttle)
|
||||
check_include_files(linux/input.h HAVE_LINUX_INPUT_H)
|
||||
@@ -63,6 +65,9 @@ macro_log_feature(Nepomuk_FOUND
|
||||
"http://nepomuk.semanticdesktop.org"
|
||||
)
|
||||
|
||||
find_package(NepomukCore QUIET)
|
||||
set_package_properties(NepomukCore PROPERTIES DESCRIPTION "The Nepomuk Core libraries" URL "http://www.kde.org" TYPE RECOMMENDED PURPOSE "Support for the Nepomuk semantic desktop system")
|
||||
|
||||
macro_log_feature(QJSON_FOUND
|
||||
"QJson"
|
||||
"Qt-based library that maps JSON data to QVariant objects"
|
||||
@@ -72,7 +77,6 @@ macro_log_feature(QJSON_FOUND
|
||||
"Required to build the rotoscoping filter and for Freesound.org queries"
|
||||
)
|
||||
|
||||
|
||||
add_subdirectory(beziercurve)
|
||||
add_subdirectory(colorcorrection)
|
||||
add_subdirectory(commands)
|
||||
@@ -92,9 +96,9 @@ if(QJSON_FOUND)
|
||||
add_subdirectory(rotoscoping)
|
||||
endif(QJSON_FOUND)
|
||||
|
||||
if(BUILD_V4L)
|
||||
if(LIBV4L2_FOUND)
|
||||
add_subdirectory(v4l)
|
||||
endif(BUILD_V4L)
|
||||
endif()
|
||||
|
||||
list(APPEND kdenlive_SRCS
|
||||
main.cpp
|
||||
@@ -134,7 +138,6 @@ list(APPEND kdenlive_SRCS
|
||||
effectslistview.cpp
|
||||
effectslistwidget.cpp
|
||||
effectstackedit.cpp
|
||||
effectstackview.cpp
|
||||
encodingprofilesdialog.cpp
|
||||
folderprojectitem.cpp
|
||||
gentime.cpp
|
||||
@@ -198,7 +201,6 @@ kde4_add_ui_files(kdenlive_UIS
|
||||
widgets/clipproperties_ui.ui
|
||||
widgets/cliptranscode_ui.ui
|
||||
widgets/collapsiblewidget_ui.ui
|
||||
widgets/collapsiblegroup_ui.ui
|
||||
widgets/clipstabilize_ui.ui
|
||||
widgets/colorclip_ui.ui
|
||||
widgets/colorplaneexport_ui.ui
|
||||
@@ -248,7 +250,7 @@ kde4_add_ui_files(kdenlive_UIS
|
||||
widgets/trackheader_ui.ui
|
||||
widgets/tracksconfigdialog_ui.ui
|
||||
widgets/transitionsettings_ui.ui
|
||||
widgets/unicodedialog_ui.ui
|
||||
widgets/unicodewidget_ui.ui
|
||||
widgets/urlval_ui.ui
|
||||
widgets/vectorscope_ui.ui
|
||||
widgets/waveform_ui.ui
|
||||
@@ -261,6 +263,8 @@ kde4_add_ui_files(kdenlive_UIS
|
||||
widgets/keywordval_ui.ui
|
||||
widgets/fontval_ui.ui
|
||||
widgets/cutjobdialog_ui.ui
|
||||
widgets/scenecutdialog_ui.ui
|
||||
widgets/importkeyframesdialog_ui.ui
|
||||
)
|
||||
|
||||
if(OPENGL_FOUND)
|
||||
@@ -298,8 +302,8 @@ add_definitions(${KDE4_DEFINITIONS})
|
||||
include_directories(
|
||||
${CMAKE_BINARY_DIR}
|
||||
${KDE4_INCLUDES} # Adds Qt include directories too.
|
||||
${LIBMLT_INCLUDE_DIR}
|
||||
${LIBMLTPLUS_INCLUDE_DIR}
|
||||
${MLT_INCLUDE_DIR}
|
||||
${MLTPP_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
# Adds Qt definitions and include directories, and sets QT_LIBRARIES according
|
||||
@@ -320,8 +324,8 @@ target_link_libraries(kdenlive
|
||||
${KDE4_KROSSUI_LIBS}
|
||||
${KDE4_SOLID_LIBS}
|
||||
${QT_LIBRARIES}
|
||||
${LIBMLT_LIBRARY}
|
||||
${LIBMLTPLUS_LIBRARY}
|
||||
${MLT_LIBRARIES}
|
||||
${MLTPP_LIBRARIES}
|
||||
${CMAKE_DL_LIBS}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
@@ -340,11 +344,17 @@ if(SDL_FOUND)
|
||||
target_link_libraries(kdenlive ${SDL_LIBRARY})
|
||||
endif(SDL_FOUND)
|
||||
|
||||
if(Nepomuk_FOUND)
|
||||
add_definitions(-DUSE_NEPOMUK)
|
||||
include_directories(${NEPOMUK_INCLUDES})
|
||||
target_link_libraries(kdenlive ${NEPOMUK_LIBRARIES})
|
||||
endif(Nepomuk_FOUND)
|
||||
if(NepomukCore_FOUND)
|
||||
add_definitions(-DUSE_NEPOMUKCORE)
|
||||
include_directories(${NEPOMUK_CORE_INCLUDE_DIR})
|
||||
target_link_libraries(kdenlive ${NEPOMUK_CORE_LIBRARY})
|
||||
else(NepomukWidgets_FOUND)
|
||||
if(Nepomuk_FOUND)
|
||||
add_definitions(-DUSE_NEPOMUK)
|
||||
include_directories(${NEPOMUK_INCLUDES})
|
||||
target_link_libraries(kdenlive ${NEPOMUK_LIBRARIES})
|
||||
endif(Nepomuk_FOUND)
|
||||
endif()
|
||||
|
||||
if(QJSON_FOUND)
|
||||
add_definitions(-DUSE_QJSON)
|
||||
@@ -352,9 +362,11 @@ if(QJSON_FOUND)
|
||||
target_link_libraries(kdenlive ${QJSON_LIBRARIES})
|
||||
endif(QJSON_FOUND)
|
||||
|
||||
if(BUILD_V4L)
|
||||
if(LIBV4L2_FOUND)
|
||||
include_directories(${LIBV4L2_INCLUDE_DIR})
|
||||
target_link_libraries(kdenlive ${LIBV4L2_LIBRARY})
|
||||
add_definitions(-DUSE_V4L)
|
||||
endif(BUILD_V4L)
|
||||
endif()
|
||||
|
||||
if(BUILD_JogShuttle)
|
||||
add_definitions(-DUSE_JOGSHUTTLE)
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
*
|
||||
* @param parent parent QWidget
|
||||
*/
|
||||
KoSliderCombo(QWidget *parent = 0);
|
||||
explicit KoSliderCombo(QWidget *parent = 0);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
|
||||
@@ -29,16 +29,20 @@
|
||||
#include <QPainter>
|
||||
#include <QToolTip>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QParallelAnimationGroup>
|
||||
|
||||
AbstractClipItem::AbstractClipItem(const ItemInfo &info, const QRectF& rect, double fps) :
|
||||
QObject(),
|
||||
QGraphicsRectItem(rect),
|
||||
m_info(info),
|
||||
m_editedKeyframe(-1),
|
||||
m_selectedKeyframe(0),
|
||||
m_keyframeFactor(1),
|
||||
m_keyframeOffset(0),
|
||||
m_fps(fps)
|
||||
QObject()
|
||||
, QGraphicsRectItem(rect)
|
||||
, m_info(info)
|
||||
, m_editedKeyframe(-1)
|
||||
, m_selectedKeyframe(0)
|
||||
, m_keyframeFactor(1)
|
||||
, m_keyframeOffset(0)
|
||||
, m_keyframeDefault(0)
|
||||
, m_visibleParam(0)
|
||||
, m_fps(fps)
|
||||
, m_isMainSelectedClip(false)
|
||||
{
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||
#if QT_VERSION >= 0x040600
|
||||
@@ -56,14 +60,16 @@ void AbstractClipItem::closeAnimation()
|
||||
#if QT_VERSION >= 0x040600
|
||||
if (!isEnabled()) return;
|
||||
setEnabled(false);
|
||||
setFlag(QGraphicsItem::ItemIsSelectable, false);
|
||||
if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
|
||||
// animation disabled
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
QPropertyAnimation *closeAnimation = new QPropertyAnimation(this, "rect");
|
||||
connect(closeAnimation, SIGNAL(finished()), this, SLOT(deleteLater()));
|
||||
QPropertyAnimation *closeAnimation2 = new QPropertyAnimation(this, "opacity");
|
||||
closeAnimation->setDuration(200);
|
||||
closeAnimation2->setDuration(200);
|
||||
QRectF r = rect();
|
||||
QRectF r2 = r;
|
||||
r2.setLeft(r.left() + r.width() / 2);
|
||||
@@ -73,7 +79,13 @@ void AbstractClipItem::closeAnimation()
|
||||
closeAnimation->setStartValue(r);
|
||||
closeAnimation->setEndValue(r2);
|
||||
closeAnimation->setEasingCurve(QEasingCurve::InQuad);
|
||||
closeAnimation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
closeAnimation2->setStartValue(1.0);
|
||||
closeAnimation2->setEndValue(0.0);
|
||||
QParallelAnimationGroup *group = new QParallelAnimationGroup;
|
||||
connect(group, SIGNAL(finished()), this, SLOT(deleteLater()));
|
||||
group->addAnimation(closeAnimation);
|
||||
group->addAnimation(closeAnimation2);
|
||||
group->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -110,7 +122,7 @@ GenTime AbstractClipItem::cropDuration() const
|
||||
return m_info.cropDuration;
|
||||
}
|
||||
|
||||
void AbstractClipItem::setCropStart(GenTime pos)
|
||||
void AbstractClipItem::setCropStart(const GenTime &pos)
|
||||
{
|
||||
m_info.cropStart = pos;
|
||||
}
|
||||
@@ -126,7 +138,7 @@ void AbstractClipItem::updateRectGeometry()
|
||||
setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
|
||||
}
|
||||
|
||||
void AbstractClipItem::resizeStart(int posx, bool hasSizeLimit)
|
||||
void AbstractClipItem::resizeStart(int posx, bool hasSizeLimit, bool /*emitChange*/)
|
||||
{
|
||||
GenTime durationDiff = GenTime(posx, m_fps) - m_info.startPos;
|
||||
if (durationDiff == GenTime()) return;
|
||||
@@ -189,7 +201,7 @@ void AbstractClipItem::resizeStart(int posx, bool hasSizeLimit)
|
||||
}*/
|
||||
}
|
||||
|
||||
void AbstractClipItem::resizeEnd(int posx)
|
||||
void AbstractClipItem::resizeEnd(int posx, bool /*emitChange*/)
|
||||
{
|
||||
GenTime durationDiff = GenTime(posx, m_fps) - endPos();
|
||||
if (durationDiff == GenTime()) return;
|
||||
@@ -249,7 +261,7 @@ GenTime AbstractClipItem::maxDuration() const
|
||||
return m_maxDuration;
|
||||
}
|
||||
|
||||
void AbstractClipItem::drawKeyFrames(QPainter *painter, bool limitedKeyFrames)
|
||||
void AbstractClipItem::drawKeyFrames(QPainter *painter, const QTransform &transformation, bool limitedKeyFrames)
|
||||
{
|
||||
if (m_keyframes.count() < 1)
|
||||
return;
|
||||
@@ -267,13 +279,13 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, bool limitedKeyFrames)
|
||||
x2 = br.right();
|
||||
if (limitedKeyFrames) {
|
||||
QMap<int, int>::const_iterator end = m_keyframes.constEnd();
|
||||
end--;
|
||||
--end;
|
||||
x2 = x1 + maxw * (end.key() - start);
|
||||
x1 += maxw * (m_keyframes.constBegin().key() - start);
|
||||
}
|
||||
y1 = br.bottom() - (m_keyframeDefault - m_keyframeOffset) * maxh;
|
||||
QLineF l(x1, y1, x2, y1);
|
||||
QLineF l2 = painter->worldTransform().map(l);
|
||||
QLineF l2 = transformation.map(l);
|
||||
painter->setPen(QColor(168, 168, 168, 180));
|
||||
painter->drawLine(l2);
|
||||
painter->setPen(QColor(108, 108, 108, 180));
|
||||
@@ -294,7 +306,7 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, bool limitedKeyFrames)
|
||||
// make sure line begins with clip beginning
|
||||
if (!limitedKeyFrames && i.key() != start) {
|
||||
QLineF l(br.x(), y1, x1, y1);
|
||||
l2 = painter->worldTransform().map(l);
|
||||
l2 = transformation.map(l);
|
||||
painter->drawLine(l2);
|
||||
}
|
||||
while (i != m_keyframes.constEnd()) {
|
||||
@@ -314,7 +326,7 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, bool limitedKeyFrames)
|
||||
y2 = br.bottom() - (i.value() - m_keyframeOffset) * maxh;
|
||||
}
|
||||
QLineF l(x1, y1, x2, y2);
|
||||
l2 = painter->worldTransform().map(l);
|
||||
l2 = transformation.map(l);
|
||||
painter->drawLine(l2);
|
||||
if (active) {
|
||||
const QRectF frame(l2.x1() - 3, l2.y1() - 3, 6, 6);
|
||||
@@ -327,7 +339,7 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, bool limitedKeyFrames)
|
||||
// make sure line ends at clip end
|
||||
if (!limitedKeyFrames && x1 != br.right()) {
|
||||
QLineF l(x1, y1, br.right(), y1);
|
||||
painter->drawLine(painter->worldTransform().map(l));
|
||||
painter->drawLine(transformation.map(l));
|
||||
}
|
||||
|
||||
if (active && m_keyframes.count() > 1) {
|
||||
@@ -351,7 +363,7 @@ int AbstractClipItem::mouseOverKeyFrames(QPointF pos, double maxOffset)
|
||||
x1 = br.x() + maxw * (i.key() - cropStart().frames(m_fps));
|
||||
y1 = br.bottom() - (i.value() - m_keyframeOffset) * maxh;
|
||||
if (qAbs(pos.x() - x1) < maxOffset && qAbs(pos.y() - y1) < 10) {
|
||||
setToolTip('[' + QString::number((GenTime(i.key(), m_fps) - cropStart()).seconds(), 'f', 2) + i18n("seconds") + ", " + QString::number(i.value(), 'f', 1) + "]");
|
||||
setToolTip('[' + QString::number((GenTime(i.key(), m_fps) - cropStart()).seconds(), 'f', 2) + i18n("seconds") + ", " + QString::number(i.value(), 'f', 1) + ']');
|
||||
return i.key();
|
||||
} else if (x1 > pos.x()) {
|
||||
break;
|
||||
@@ -437,6 +449,21 @@ int AbstractClipItem::keyFrameNumber() const
|
||||
return m_keyframes.count();
|
||||
}
|
||||
|
||||
int AbstractClipItem::checkForSingleKeyframe()
|
||||
{
|
||||
// Check if we have only one keyframe
|
||||
if (!m_keyframes.isEmpty() && m_keyframes.count() == 1) {
|
||||
int min = (int) cropStart().frames(m_fps);
|
||||
int max = (int)(cropStart() + cropDuration()).frames(m_fps) - 1;
|
||||
if (m_keyframes.contains(min)) {
|
||||
// Add keyframe at end of clip to allow inserting a new keframe in between
|
||||
m_keyframes[max] = m_keyframes.value(min);
|
||||
return m_keyframes.value(min);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int AbstractClipItem::addKeyFrame(const GenTime &pos, const double value)
|
||||
{
|
||||
QRectF br = sceneBoundingRect();
|
||||
@@ -508,4 +535,17 @@ int AbstractClipItem::itemOffset()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AbstractClipItem::setMainSelectedClip(bool selected)
|
||||
{
|
||||
if (selected == m_isMainSelectedClip) return;
|
||||
m_isMainSelectedClip = selected;
|
||||
update();
|
||||
}
|
||||
|
||||
bool AbstractClipItem::isMainSelectedClip()
|
||||
{
|
||||
return m_isMainSelectedClip;
|
||||
}
|
||||
|
||||
|
||||
#include "abstractclipitem.moc"
|
||||
|
||||
@@ -38,6 +38,7 @@ class AbstractClipItem : public QObject, public QGraphicsRectItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QRectF rect READ rect WRITE setRect)
|
||||
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
|
||||
|
||||
public:
|
||||
AbstractClipItem(const ItemInfo &info, const QRectF& rect, double fps);
|
||||
@@ -48,6 +49,7 @@ public:
|
||||
* @param pos new Position
|
||||
* @param value new Value */
|
||||
void updateKeyFramePos(const GenTime &pos, const double value);
|
||||
int checkForSingleKeyframe();
|
||||
int addKeyFrame(const GenTime &pos, const double value);
|
||||
bool hasKeyFrames() const;
|
||||
int editedKeyFramePos() const;
|
||||
@@ -65,7 +67,7 @@ public:
|
||||
bool isItemLocked() const;
|
||||
void closeAnimation();
|
||||
|
||||
virtual OPERATIONTYPE operationMode(QPointF pos) = 0;
|
||||
virtual OPERATIONTYPE operationMode(const QPointF &pos) = 0;
|
||||
virtual GenTime startPos() const ;
|
||||
virtual void setTrack(int track);
|
||||
virtual GenTime endPos() const ;
|
||||
@@ -82,19 +84,23 @@ public:
|
||||
/** @brief Resizes the clip from the start.
|
||||
* @param posx Absolute position of new in point
|
||||
* @param hasSizeLimit (optional) Whether the clip has a maximum size */
|
||||
virtual void resizeStart(int posx, bool hasSizeLimit = true);
|
||||
virtual void resizeStart(int posx, bool hasSizeLimit = true, bool emitChange = true);
|
||||
|
||||
/** @brief Resizes the clip from the end.
|
||||
* @param posx Absolute position of new out point */
|
||||
virtual void resizeEnd(int posx);
|
||||
virtual void resizeEnd(int posx, bool emitChange = true);
|
||||
virtual double fps() const;
|
||||
virtual void updateFps(double fps);
|
||||
virtual GenTime maxDuration() const;
|
||||
virtual void setCropStart(GenTime pos);
|
||||
virtual void setCropStart(const GenTime &pos);
|
||||
|
||||
/** @brief Set this clip as the main selected clip (or not). */
|
||||
void setMainSelectedClip(bool selected);
|
||||
/** @brief Is this clip selected as the main clip. */
|
||||
bool isMainSelectedClip();
|
||||
|
||||
protected:
|
||||
ItemInfo m_info;
|
||||
// int m_track;
|
||||
/** The position of the current keyframe when it has moved */
|
||||
int m_editedKeyframe;
|
||||
/** The position of the current keyframe before it was moved */
|
||||
@@ -113,15 +119,17 @@ protected:
|
||||
/** The (keyframe) parameter that is visible and editable in timeline (on the clip) */
|
||||
int m_visibleParam;
|
||||
double m_fps;
|
||||
/** @brief True if this is the last clip the user selected */
|
||||
bool m_isMainSelectedClip;
|
||||
/** @brief Draw the keyframes of a clip
|
||||
* @param painter The painter device for the clip
|
||||
* @param limitedKeyFrames The keyframes can be of type "keyframe" or "simplekeyframe". In the
|
||||
* "simplekeyframe" type, the effect always starts on clip start and ends on clip end. With the
|
||||
* "keyframe" type, the effect starts on the first keyframe and ends on the last keyframe
|
||||
*/
|
||||
void drawKeyFrames(QPainter *painter, bool limitedKeyFrames);
|
||||
void drawKeyFrames(QPainter *painter, const QTransform &transformation, bool limitedKeyFrames);
|
||||
int mouseOverKeyFrames(QPointF pos, double maxOffset);
|
||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent * event);
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent * event);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -32,9 +32,10 @@
|
||||
#include <QMimeData>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
|
||||
|
||||
AbstractGroupItem::AbstractGroupItem(double /* fps */) :
|
||||
QObject(),
|
||||
QGraphicsItemGroup()
|
||||
QObject(),
|
||||
QGraphicsItemGroup()
|
||||
{
|
||||
setZValue(1);
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||
@@ -52,7 +53,20 @@ int AbstractGroupItem::type() const
|
||||
|
||||
int AbstractGroupItem::track() const
|
||||
{
|
||||
return (int)(scenePos().y() / KdenliveSettings::trackheight());
|
||||
//return (int)(scenePos().y() / KdenliveSettings::trackheight());
|
||||
int topTrack = -1;
|
||||
QList<QGraphicsItem *> children = childItems();
|
||||
for (int i = 0; i < children.count(); ++i) {
|
||||
if (children.at(i)->type() == GROUPWIDGET) {
|
||||
children.append(children.at(i)->childItems());
|
||||
continue;
|
||||
}
|
||||
AbstractClipItem *item = static_cast <AbstractClipItem *>(children.at(i));
|
||||
if (item && (topTrack == -1 || topTrack > item->track())) {
|
||||
topTrack = item->track();
|
||||
}
|
||||
}
|
||||
return topTrack;
|
||||
}
|
||||
|
||||
void AbstractGroupItem::setItemLocked(bool locked)
|
||||
@@ -78,21 +92,26 @@ CustomTrackScene* AbstractGroupItem::projectScene()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QPainterPath AbstractGroupItem::clipGroupShape(QPointF offset) const
|
||||
QPainterPath AbstractGroupItem::clipGroupSpacerShape(const QPointF &offset) const
|
||||
{
|
||||
return spacerGroupShape(AVWIDGET, offset);
|
||||
}
|
||||
|
||||
QPainterPath AbstractGroupItem::clipGroupShape(const QPointF &offset) const
|
||||
{
|
||||
return groupShape(AVWIDGET, offset);
|
||||
}
|
||||
|
||||
QPainterPath AbstractGroupItem::transitionGroupShape(QPointF offset) const
|
||||
QPainterPath AbstractGroupItem::transitionGroupShape(const QPointF &offset) const
|
||||
{
|
||||
return groupShape(TRANSITIONWIDGET, offset);
|
||||
}
|
||||
|
||||
QPainterPath AbstractGroupItem::groupShape(GRAPHICSRECTITEM type, QPointF offset) const
|
||||
QPainterPath AbstractGroupItem::groupShape(GRAPHICSRECTITEM type, const QPointF &offset) const
|
||||
{
|
||||
QPainterPath path;
|
||||
QList<QGraphicsItem *> children = childItems();
|
||||
for (int i = 0; i < children.count(); i++) {
|
||||
for (int i = 0; i < children.count(); ++i) {
|
||||
if (children.at(i)->type() == (int)type) {
|
||||
QRectF r(children.at(i)->sceneBoundingRect());
|
||||
r.translate(offset);
|
||||
@@ -111,10 +130,40 @@ QPainterPath AbstractGroupItem::groupShape(GRAPHICSRECTITEM type, QPointF offset
|
||||
return path;
|
||||
}
|
||||
|
||||
QPainterPath AbstractGroupItem::spacerGroupShape(GRAPHICSRECTITEM type, const QPointF &offset) const
|
||||
{
|
||||
QPainterPath path;
|
||||
QList<QGraphicsItem *> children = childItems();
|
||||
for (int i = 0; i < children.count(); ++i) {
|
||||
if (children.at(i)->type() == (int)type) {
|
||||
QRectF r(children.at(i)->sceneBoundingRect());
|
||||
r.translate(offset);
|
||||
r.setRight(scene()->width());
|
||||
path.addRect(r);
|
||||
} else if (children.at(i)->type() == GROUPWIDGET) {
|
||||
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
|
||||
for (int j = 0; j < subchildren.count(); j++) {
|
||||
if (subchildren.at(j)->type() == (int)type) {
|
||||
QRectF r(subchildren.at(j)->sceneBoundingRect());
|
||||
r.translate(offset);
|
||||
r.setRight(scene()->width());
|
||||
path.addRect(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
void AbstractGroupItem::addItem(QGraphicsItem * item)
|
||||
{
|
||||
addToGroup(item);
|
||||
//fixItemRect();
|
||||
item->setFlag(QGraphicsItem::ItemIsMovable, false);
|
||||
}
|
||||
|
||||
void AbstractGroupItem::removeItem(QGraphicsItem * item)
|
||||
{
|
||||
removeFromGroup(item);
|
||||
}
|
||||
|
||||
void AbstractGroupItem::fixItemRect()
|
||||
@@ -136,18 +185,16 @@ void AbstractGroupItem::fixItemRect()
|
||||
// virtual
|
||||
void AbstractGroupItem::paint(QPainter *p, const QStyleOptionGraphicsItem *option, QWidget *)
|
||||
{
|
||||
const double scale = option->matrix.m11();
|
||||
QColor bgcolor(100, 100, 200, 100);
|
||||
QRectF bound = option->exposedRect.adjusted(0, 0, 1, 1);
|
||||
p->setClipRect(bound);
|
||||
p->fillRect(option->exposedRect, bgcolor);
|
||||
p->setBrush(bgcolor);
|
||||
QPen pen = p->pen();
|
||||
pen.setColor(QColor(200, 90, 90));
|
||||
pen.setStyle(Qt::DashLine);
|
||||
pen.setWidthF(0.0);
|
||||
//pen.setCosmetic(true);
|
||||
p->setPen(pen);
|
||||
p->drawRect(boundingRect().adjusted(0, 0, - 1 / scale, 0));
|
||||
p->drawRoundedRect(boundingRect().adjusted(0, 0, -1, 0), 3, 3);
|
||||
}
|
||||
|
||||
//virtual
|
||||
@@ -165,25 +212,25 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant
|
||||
int xpos = projectScene()->getSnapPointForPos((int)(start.x() + newPos.x() - pos().x()), KdenliveSettings::snaptopoints());
|
||||
|
||||
xpos = qMax(xpos, 0);
|
||||
//kDebug()<<"GRP XPOS:"<<xpos<<", START:"<<start.x()<<",NEW:"<<newPos.x()<<"; SCENE:"<<scenePos().x()<<",POS:"<<pos().x();
|
||||
//kDebug()<<"GRP XPOS:"<<xpos<<", START:"<<start.x()<<",NEW:"<<newPos.x()<<"; SCENE:"<<scenePos().x()<<",POS:"<<pos().x();
|
||||
newPos.setX((int)(pos().x() + xpos - (int) start.x()));
|
||||
|
||||
//int startTrack = (start.y() + trackHeight / 2) / trackHeight;
|
||||
|
||||
int realTrack = (start.y() + newPos.y() - pos().y()) / trackHeight;
|
||||
int proposedTrack = newPos.y() / trackHeight;
|
||||
|
||||
int correctedTrack = qMin(realTrack, projectScene()->tracksCount() - (int)(boundingRect().height() + 5) / trackHeight);
|
||||
correctedTrack = qMax(correctedTrack, 0);
|
||||
|
||||
proposedTrack += (correctedTrack - realTrack);
|
||||
|
||||
QStringList lockedTracks = property("locked_tracks").toStringList();
|
||||
int proposedTrack = (property("y_absolute").toInt() + newPos.y()) / trackHeight;
|
||||
// Check if top item is a clip or a transition
|
||||
int offset = 0;
|
||||
int topTrack = -1;
|
||||
QList<int> groupTracks;
|
||||
QList<QGraphicsItem *> children = childItems();
|
||||
for (int i = 0; i < children.count(); i++) {
|
||||
int currentTrack = (int)(children.at(i)->scenePos().y() / trackHeight);
|
||||
for (int i = 0; i < children.count(); ++i) {
|
||||
int currentTrack = 0;
|
||||
if (children.at(i)->type() == AVWIDGET || children.at(i)->type() == TRANSITIONWIDGET) {
|
||||
currentTrack = static_cast <AbstractClipItem*> (children.at(i))->track();
|
||||
if (!groupTracks.contains(currentTrack)) groupTracks.append(currentTrack);
|
||||
}
|
||||
else if (children.at(i)->type() == GROUPWIDGET) {
|
||||
currentTrack = static_cast <AbstractGroupItem*> (children.at(i))->track();
|
||||
}
|
||||
else continue;
|
||||
if (children.at(i)->type() == AVWIDGET) {
|
||||
if (topTrack == -1 || currentTrack <= topTrack) {
|
||||
offset = 0;
|
||||
@@ -198,9 +245,10 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant
|
||||
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
|
||||
bool clipGroup = false;
|
||||
for (int j = 0; j < subchildren.count(); j++) {
|
||||
if (subchildren.at(j)->type() == AVWIDGET) {
|
||||
if (subchildren.at(j)->type() == AVWIDGET || subchildren.at(j)->type() == TRANSITIONWIDGET) {
|
||||
int subTrack = static_cast <AbstractClipItem*> (subchildren.at(j))->track();
|
||||
if (!groupTracks.contains(subTrack)) groupTracks.append(subTrack);
|
||||
clipGroup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (clipGroup) {
|
||||
@@ -216,6 +264,24 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check no clip in the group goes outside of existing tracks
|
||||
int maximumTrack = projectScene()->tracksCount() - 1;
|
||||
int groupHeight = 0;
|
||||
for (int i = 0; i < groupTracks.count(); ++i) {
|
||||
int offset = groupTracks.at(i) - topTrack;
|
||||
if (offset > groupHeight) groupHeight = offset;
|
||||
}
|
||||
maximumTrack -= groupHeight;
|
||||
proposedTrack = qMin(proposedTrack, maximumTrack);
|
||||
proposedTrack = qMax(proposedTrack, 0);
|
||||
int groupOffset = proposedTrack - topTrack;
|
||||
if (!lockedTracks.isEmpty()) {
|
||||
for (int i = 0; i < groupTracks.count(); ++i) {
|
||||
if (lockedTracks.contains(QString::number(groupTracks.at(i) + groupOffset))) {
|
||||
return pos();
|
||||
}
|
||||
}
|
||||
}
|
||||
newPos.setY((int)((proposedTrack) * trackHeight) + offset);
|
||||
//if (newPos == start) return start;
|
||||
|
||||
@@ -230,7 +296,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant
|
||||
shape = clipGroupShape(newPos - pos());
|
||||
collidingItems = scene()->items(shape, Qt::IntersectsItemShape);
|
||||
collidingItems.removeAll(this);
|
||||
for (int i = 0; i < children.count(); i++) {
|
||||
for (int i = 0; i < children.count(); ++i) {
|
||||
if (children.at(i)->type() == GROUPWIDGET) {
|
||||
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
|
||||
for (int j = 0; j < subchildren.count(); j++) {
|
||||
@@ -243,7 +309,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant
|
||||
if (!collidingItems.isEmpty()) {
|
||||
bool forwardMove = xpos > start.x();
|
||||
int offset = 0;
|
||||
for (int i = 0; i < collidingItems.count(); i++) {
|
||||
for (int i = 0; i < collidingItems.count(); ++i) {
|
||||
QGraphicsItem *collision = collidingItems.at(i);
|
||||
if (collision->type() == AVWIDGET) {
|
||||
// Collision
|
||||
@@ -276,7 +342,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant
|
||||
// If there is still a collision after our position adjust, restore original pos
|
||||
collidingItems = scene()->items(clipGroupShape(newPos - pos()), Qt::IntersectsItemShape);
|
||||
collidingItems.removeAll(this);
|
||||
for (int i = 0; i < children.count(); i++) {
|
||||
for (int i = 0; i < children.count(); ++i) {
|
||||
if (children.at(i)->type() == GROUPWIDGET) {
|
||||
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
|
||||
for (int j = 0; j < subchildren.count(); j++) {
|
||||
@@ -285,7 +351,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant
|
||||
}
|
||||
collidingItems.removeAll(children.at(i));
|
||||
}
|
||||
for (int i = 0; i < collidingItems.count(); i++)
|
||||
for (int i = 0; i < collidingItems.count(); ++i)
|
||||
if (collidingItems.at(i)->type() == AVWIDGET) return pos();
|
||||
}
|
||||
}
|
||||
@@ -294,7 +360,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant
|
||||
shape = transitionGroupShape(newPos - pos());
|
||||
collidingItems = scene()->items(shape, Qt::IntersectsItemShape);
|
||||
collidingItems.removeAll(this);
|
||||
for (int i = 0; i < children.count(); i++) {
|
||||
for (int i = 0; i < children.count(); ++i) {
|
||||
if (children.at(i)->type() == GROUPWIDGET) {
|
||||
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
|
||||
for (int j = 0; j < subchildren.count(); j++) {
|
||||
@@ -308,7 +374,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant
|
||||
else {
|
||||
bool forwardMove = xpos > start.x();
|
||||
int offset = 0;
|
||||
for (int i = 0; i < collidingItems.count(); i++) {
|
||||
for (int i = 0; i < collidingItems.count(); ++i) {
|
||||
QGraphicsItem *collision = collidingItems.at(i);
|
||||
if (collision->type() == TRANSITIONWIDGET) {
|
||||
// Collision
|
||||
@@ -340,10 +406,10 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant
|
||||
}
|
||||
// If there is still a collision after our position adjust, restore original pos
|
||||
collidingItems = scene()->items(transitionGroupShape(newPos - pos()), Qt::IntersectsItemShape);
|
||||
for (int i = 0; i < children.count(); i++) {
|
||||
for (int i = 0; i < children.count(); ++i) {
|
||||
collidingItems.removeAll(children.at(i));
|
||||
}
|
||||
for (int i = 0; i < collidingItems.count(); i++)
|
||||
for (int i = 0; i < collidingItems.count(); ++i)
|
||||
if (collidingItems.at(i)->type() == TRANSITIONWIDGET) return pos();
|
||||
}
|
||||
}
|
||||
@@ -361,7 +427,16 @@ void AbstractGroupItem::dropEvent(QGraphicsSceneDragDropEvent * event)
|
||||
QDomElement e = doc.documentElement();
|
||||
e.setAttribute("kdenlive_ix", 0);
|
||||
CustomTrackView *view = (CustomTrackView *) scene()->views()[0];
|
||||
if (view) view->slotAddGroupEffect(e, this);
|
||||
QPointF dropPos = event->scenePos();
|
||||
QList<QGraphicsItem *> selection = scene()->items(dropPos);
|
||||
AbstractClipItem *dropChild = NULL;
|
||||
for (int i = 0; i < selection.count(); ++i) {
|
||||
if (selection.at(i)->type() == AVWIDGET) {
|
||||
dropChild = (AbstractClipItem *) selection.at(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (view) view->slotAddGroupEffect(e, this, dropChild);
|
||||
}
|
||||
|
||||
//virtual
|
||||
@@ -381,7 +456,17 @@ void AbstractGroupItem::mousePressEvent(QGraphicsSceneMouseEvent * event)
|
||||
if (event->modifiers() & Qt::ShiftModifier) {
|
||||
// User want to do a rectangle selection, so ignore the event to pass it to the view
|
||||
event->ignore();
|
||||
} else QGraphicsItem::mousePressEvent(event);
|
||||
} else {
|
||||
QList <QGraphicsItem *>list = scene()->items(event->scenePos());
|
||||
// only allow group move if we click over an item in the group
|
||||
foreach(const QGraphicsItem *item, list) {
|
||||
if (item->type() == TRANSITIONWIDGET || item->type() == AVWIDGET) {
|
||||
QGraphicsItem::mousePressEvent(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractGroupItem::resizeStart(int diff)
|
||||
@@ -469,3 +554,5 @@ GenTime AbstractGroupItem::duration()
|
||||
}
|
||||
return end - start;
|
||||
}
|
||||
|
||||
#include "abstractgroupitem.moc"
|
||||
|
||||
@@ -38,9 +38,11 @@ public:
|
||||
virtual int type() const;
|
||||
CustomTrackScene* projectScene();
|
||||
void addItem(QGraphicsItem * item);
|
||||
void removeItem(QGraphicsItem * item);
|
||||
int track() const;
|
||||
QPainterPath clipGroupShape(QPointF offset) const;
|
||||
QPainterPath transitionGroupShape(QPointF offset) const;
|
||||
QPainterPath clipGroupShape(const QPointF &offset) const;
|
||||
QPainterPath clipGroupSpacerShape(const QPointF &offset) const;
|
||||
QPainterPath transitionGroupShape(const QPointF &offset) const;
|
||||
void setItemLocked(bool locked);
|
||||
bool isItemLocked() const;
|
||||
// ItemInfo info() const;
|
||||
@@ -69,7 +71,8 @@ protected:
|
||||
|
||||
private:
|
||||
void fixItemRect();
|
||||
QPainterPath groupShape(GRAPHICSRECTITEM type, QPointF offset) const;
|
||||
QPainterPath groupShape(GRAPHICSRECTITEM type, const QPointF &offset) const;
|
||||
QPainterPath spacerGroupShape(GRAPHICSRECTITEM type, const QPointF &offset) const;
|
||||
/** Stores the original info of the items beeing resized. */
|
||||
QList <ItemInfo> m_resizeInfos;
|
||||
};
|
||||
|
||||
@@ -41,8 +41,7 @@ AbstractMonitor::AbstractMonitor(Kdenlive::MONITORID id, MonitorManager *manager
|
||||
|
||||
AbstractMonitor::~AbstractMonitor()
|
||||
{
|
||||
if (videoSurface)
|
||||
delete videoSurface;
|
||||
delete videoSurface;
|
||||
}
|
||||
|
||||
void AbstractMonitor::createVideoSurface()
|
||||
@@ -59,9 +58,9 @@ bool AbstractMonitor::isActive() const
|
||||
return m_monitorManager->isActive(m_id);
|
||||
}
|
||||
|
||||
bool AbstractMonitor::slotActivateMonitor()
|
||||
bool AbstractMonitor::slotActivateMonitor(bool forceRefresh)
|
||||
{
|
||||
return m_monitorManager->activateMonitor(m_id);
|
||||
return m_monitorManager->activateMonitor(m_id, forceRefresh);
|
||||
}
|
||||
|
||||
VideoContainer::VideoContainer(AbstractMonitor* monitor, QWidget *parent) :
|
||||
@@ -169,7 +168,7 @@ VideoSurface::VideoSurface(QWidget* parent) :
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
setAttribute(Qt::WA_NoSystemBackground);
|
||||
setUpdatesEnabled(false);
|
||||
//setUpdatesEnabled(false);
|
||||
}
|
||||
|
||||
void VideoSurface::paintEvent(QPaintEvent *event)
|
||||
@@ -180,3 +179,5 @@ void VideoSurface::paintEvent(QPaintEvent *event)
|
||||
emit refreshMonitor();
|
||||
}
|
||||
|
||||
|
||||
#include "abstractmonitor.moc"
|
||||
|
||||
@@ -26,9 +26,7 @@
|
||||
#include <QVector>
|
||||
#include <QWidget>
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
#include <QFrame>
|
||||
#include <QTimer>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -43,10 +41,16 @@ Q_OBJECT public:
|
||||
* @param name A unique identifier for this renderer
|
||||
* @param winid The parent widget identifier (required for SDL display). Set to 0 for OpenGL rendering
|
||||
* @param profile The MLT profile used for the renderer (default one will be used if empty). */
|
||||
AbstractRender(Kdenlive::MONITORID name, QWidget *parent = 0):QObject(parent), sendFrameForAnalysis(false), m_name(name) {};
|
||||
explicit AbstractRender(Kdenlive::MONITORID name, QWidget *parent = 0)
|
||||
: QObject(parent),
|
||||
sendFrameForAnalysis(false),
|
||||
analyseAudio(false),
|
||||
m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief Destroy the MLT Renderer. */
|
||||
virtual ~AbstractRender() {};
|
||||
virtual ~AbstractRender() {}
|
||||
|
||||
/** @brief This property is used to decide if the renderer should convert it's frames to QImage for use in other Kdenlive widgets. */
|
||||
bool sendFrameForAnalysis;
|
||||
@@ -54,7 +58,7 @@ Q_OBJECT public:
|
||||
/** @brief This property is used to decide if the renderer should send audio data for monitoring. */
|
||||
bool analyseAudio;
|
||||
|
||||
const QString &name() const {return m_name;};
|
||||
const QString &name() const {return m_name;}
|
||||
|
||||
/** @brief Someone needs us to send again a frame. */
|
||||
virtual void sendFrameUpdate() = 0;
|
||||
@@ -64,10 +68,10 @@ private:
|
||||
|
||||
signals:
|
||||
/** @brief The renderer refreshed the current frame. */
|
||||
void frameUpdated(QImage);
|
||||
void frameUpdated(const QImage &);
|
||||
|
||||
/** @brief This signal contains the audio of the current frame. */
|
||||
void audioSamplesSignal(QVector<int16_t>,int,int,int);
|
||||
void audioSamplesSignal(const QVector<int16_t>&,int,int,int);
|
||||
};
|
||||
|
||||
|
||||
@@ -91,7 +95,7 @@ class AbstractMonitor : public QWidget
|
||||
Q_OBJECT
|
||||
public:
|
||||
AbstractMonitor(Kdenlive::MONITORID id, MonitorManager *manager, QWidget *parent = 0);
|
||||
Kdenlive::MONITORID id() {return m_id;};
|
||||
Kdenlive::MONITORID id() {return m_id;}
|
||||
virtual ~AbstractMonitor();
|
||||
virtual AbstractRender *abstractRender() = 0;
|
||||
bool isActive() const;
|
||||
@@ -105,7 +109,7 @@ public slots:
|
||||
virtual void start() = 0;
|
||||
virtual void slotPlay() = 0;
|
||||
virtual void slotMouseSeek(int eventDelta, bool fast) = 0;
|
||||
bool slotActivateMonitor();
|
||||
bool slotActivateMonitor(bool forceRefresh = false);
|
||||
virtual void slotSwitchFullScreen() = 0;
|
||||
|
||||
protected:
|
||||
@@ -117,7 +121,7 @@ class VideoContainer : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VideoContainer(AbstractMonitor *monitor, QWidget *parent = 0);
|
||||
explicit VideoContainer(AbstractMonitor *monitor, QWidget *parent = 0);
|
||||
void switchFullScreen();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -41,22 +41,24 @@
|
||||
#include "projectsettings.h"
|
||||
|
||||
|
||||
ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList <DocClipBase*> list, QStringList luma_list, QWidget * parent) :
|
||||
QDialog(parent),
|
||||
m_requestedSize(0),
|
||||
m_copyJob(NULL),
|
||||
m_name(projectName.section('.', 0, -2)),
|
||||
m_doc(doc),
|
||||
m_abortArchive(false),
|
||||
m_extractMode(false),
|
||||
m_extractArchive(NULL),
|
||||
m_missingClips(0)
|
||||
ArchiveWidget::ArchiveWidget(const QString &projectName, const QDomDocument &doc, const QList <DocClipBase*> &list, const QStringList &luma_list, QWidget * parent) :
|
||||
QDialog(parent)
|
||||
, m_requestedSize(0)
|
||||
, m_copyJob(NULL)
|
||||
, m_name(projectName.section('.', 0, -2))
|
||||
, m_doc(doc)
|
||||
, m_temp(NULL)
|
||||
, m_abortArchive(false)
|
||||
, m_extractMode(false)
|
||||
, m_progressTimer(NULL)
|
||||
, m_extractArchive(NULL)
|
||||
, m_missingClips(0)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setupUi(this);
|
||||
setWindowTitle(i18n("Archive Project"));
|
||||
archive_url->setUrl(KUrl(QDir::homePath()));
|
||||
connect(archive_url, SIGNAL(textChanged (const QString &)), this, SLOT(slotCheckSpace()));
|
||||
connect(archive_url, SIGNAL(textChanged(QString)), this, SLOT(slotCheckSpace()));
|
||||
connect(this, SIGNAL(archivingFinished(bool)), this, SLOT(slotArchivingFinished(bool)));
|
||||
connect(this, SIGNAL(archiveProgress(int)), this, SLOT(slotArchivingProgress(int)));
|
||||
connect(proxy_only, SIGNAL(stateChanged(int)), this, SLOT(slotProxyOnly(int)));
|
||||
@@ -115,7 +117,7 @@ ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList <DocCl
|
||||
QMap <QString, QString>playlistUrls;
|
||||
QMap <QString, QString>proxyUrls;
|
||||
|
||||
for (int i = 0; i < list.count(); i++) {
|
||||
for (int i = 0; i < list.count(); ++i) {
|
||||
DocClipBase *clip = list.at(i);
|
||||
CLIPTYPE t = clip->clipType();
|
||||
QString id = clip->getId();
|
||||
@@ -182,7 +184,7 @@ ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList <DocCl
|
||||
|
||||
// Hide unused categories, add item count
|
||||
int total = 0;
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); i++) {
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *parentItem = files_list->topLevelItem(i);
|
||||
int items = parentItem->childCount();
|
||||
if (items == 0) {
|
||||
@@ -197,7 +199,7 @@ ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList <DocCl
|
||||
}
|
||||
}
|
||||
else total += items;
|
||||
parentItem->setText(0, files_list->topLevelItem(i)->text(0) + " " + i18np("(%1 item)", "(%1 items)", items));
|
||||
parentItem->setText(0, files_list->topLevelItem(i)->text(0) + ' ' + i18np("(%1 item)", "(%1 items)", items));
|
||||
}
|
||||
}
|
||||
if (m_name.isEmpty()) m_name = i18n("Untitled");
|
||||
@@ -219,8 +221,12 @@ ArchiveWidget::ArchiveWidget(const KUrl &url, QWidget * parent):
|
||||
//setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
setupUi(this);
|
||||
m_progressTimer = new QTimer;
|
||||
m_progressTimer->setInterval(800);
|
||||
m_progressTimer->setSingleShot(false);
|
||||
connect(m_progressTimer, SIGNAL(timeout()), this, SLOT(slotExtractProgress()));
|
||||
connect(this, SIGNAL(extractingFinished()), this, SLOT(slotExtractingFinished()));
|
||||
connect(this, SIGNAL(showMessage(const QString &, const QString &)), this, SLOT(slotDisplayMessage(const QString &, const QString &)));
|
||||
connect(this, SIGNAL(showMessage(QString,QString)), this, SLOT(slotDisplayMessage(QString,QString)));
|
||||
|
||||
compressed_archive->setHidden(true);
|
||||
proxy_only->setHidden(true);
|
||||
@@ -239,7 +245,8 @@ ArchiveWidget::ArchiveWidget(const KUrl &url, QWidget * parent):
|
||||
|
||||
ArchiveWidget::~ArchiveWidget()
|
||||
{
|
||||
if (m_extractArchive) delete m_extractArchive;
|
||||
delete m_extractArchive;
|
||||
delete m_progressTimer;
|
||||
}
|
||||
|
||||
void ArchiveWidget::slotDisplayMessage(const QString &icon, const QString &text)
|
||||
@@ -274,7 +281,7 @@ void ArchiveWidget::openArchiveForExtraction()
|
||||
// Check that it is a kdenlive project archive
|
||||
bool isProjectArchive = false;
|
||||
QStringList files = m_extractArchive->directory()->entries();
|
||||
for (int i = 0; i < files.count(); i++) {
|
||||
for (int i = 0; i < files.count(); ++i) {
|
||||
if (files.at(i).endsWith(".kdenlive")) {
|
||||
m_projectName = files.at(i);
|
||||
isProjectArchive = true;
|
||||
@@ -285,6 +292,7 @@ void ArchiveWidget::openArchiveForExtraction()
|
||||
if (!isProjectArchive) {
|
||||
emit showMessage("dialog-close", i18n("File %1\n is not an archived Kdenlive project", m_extractUrl.path()));
|
||||
groupBox->setEnabled(false);
|
||||
buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
|
||||
@@ -317,7 +325,7 @@ bool ArchiveWidget::closeAccepted()
|
||||
}
|
||||
|
||||
|
||||
void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items)
|
||||
void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, const QStringList& items)
|
||||
{
|
||||
QStringList filesList;
|
||||
QString fileName;
|
||||
@@ -335,14 +343,13 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items
|
||||
if (slideUrl.fileName().startsWith(".all.")) {
|
||||
// mimetype slideshow (for example *.png)
|
||||
QStringList filters;
|
||||
QString extension;
|
||||
// TODO: improve jpeg image detection with extension like jpeg, requires change in MLT image producers
|
||||
filters << "*." + slideUrl.fileName().section('.', -1);
|
||||
dir.setNameFilters(filters);
|
||||
QFileInfoList resultList = dir.entryInfoList(QDir::Files);
|
||||
QStringList slideImages;
|
||||
qint64 totalSize = 0;
|
||||
for (int i = 0; i < resultList.count(); i++) {
|
||||
for (int i = 0; i < resultList.count(); ++i) {
|
||||
totalSize += resultList.at(i).size();
|
||||
slideImages << resultList.at(i).absoluteFilePath();
|
||||
}
|
||||
@@ -356,7 +363,7 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items
|
||||
QString filter = slideUrl.fileName();
|
||||
QString ext = filter.section('.', -1);
|
||||
filter = filter.section('%', 0, -2);
|
||||
QString regexp = "^" + filter + "\\d+\\." + ext + "$";
|
||||
QString regexp = '^' + filter + "\\d+\\." + ext + '$';
|
||||
QRegExp rx(regexp);
|
||||
QStringList slideImages;
|
||||
QString directory = dir.absolutePath();
|
||||
@@ -376,10 +383,10 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items
|
||||
else if (filesList.contains(fileName)) {
|
||||
// we have 2 files with same name
|
||||
int ix = 0;
|
||||
QString newFileName = fileName.section('.', 0, -2) + "_" + QString::number(ix) + "." + fileName.section('.', -1);
|
||||
QString newFileName = fileName.section('.', 0, -2) + '_' + QString::number(ix) + '.' + fileName.section('.', -1);
|
||||
while (filesList.contains(newFileName)) {
|
||||
ix ++;
|
||||
newFileName = fileName.section('.', 0, -2) + "_" + QString::number(ix) + "." + fileName.section('.', -1);
|
||||
newFileName = fileName.section('.', 0, -2) + '_' + QString::number(ix) + '.' + fileName.section('.', -1);
|
||||
}
|
||||
fileName = newFileName;
|
||||
item->setData(0, Qt::UserRole, fileName);
|
||||
@@ -399,7 +406,7 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items
|
||||
}
|
||||
}
|
||||
|
||||
void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QMap <QString, QString> items)
|
||||
void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, const QMap <QString, QString>& items)
|
||||
{
|
||||
QStringList filesList;
|
||||
QString fileName;
|
||||
@@ -421,14 +428,13 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QMap <QString, QS
|
||||
if (slideUrl.fileName().startsWith(".all.")) {
|
||||
// mimetype slideshow (for example *.png)
|
||||
QStringList filters;
|
||||
QString extension;
|
||||
// TODO: improve jpeg image detection with extension like jpeg, requires change in MLT image producers
|
||||
filters << "*." + slideUrl.fileName().section('.', -1);
|
||||
dir.setNameFilters(filters);
|
||||
QFileInfoList resultList = dir.entryInfoList(QDir::Files);
|
||||
QStringList slideImages;
|
||||
qint64 totalSize = 0;
|
||||
for (int i = 0; i < resultList.count(); i++) {
|
||||
for (int i = 0; i < resultList.count(); ++i) {
|
||||
totalSize += resultList.at(i).size();
|
||||
slideImages << resultList.at(i).absoluteFilePath();
|
||||
}
|
||||
@@ -442,7 +448,7 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QMap <QString, QS
|
||||
QString filter = slideUrl.fileName();
|
||||
QString ext = filter.section('.', -1);
|
||||
filter = filter.section('%', 0, -2);
|
||||
QString regexp = "^" + filter + "\\d+\\." + ext + "$";
|
||||
QString regexp = '^' + filter + "\\d+\\." + ext + '$';
|
||||
QRegExp rx(regexp);
|
||||
QStringList slideImages;
|
||||
qint64 totalSize = 0;
|
||||
@@ -462,7 +468,7 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QMap <QString, QS
|
||||
else if (filesList.contains(fileName)) {
|
||||
// we have 2 files with same name
|
||||
int ix = 0;
|
||||
QString newFileName = fileName.section('.', 0, -2) + "_" + QString::number(ix) + "." + fileName.section('.', -1);
|
||||
QString newFileName = fileName.section('.', 0, -2) + '_' + QString::number(ix) + '.' + fileName.section('.', -1);
|
||||
while (filesList.contains(newFileName)) {
|
||||
ix ++;
|
||||
newFileName = fileName.section('.', 0, -2) + "_" + QString::number(ix) + "." + fileName.section('.', -1);
|
||||
@@ -529,10 +535,10 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass)
|
||||
QString destPath;
|
||||
QTreeWidgetItem *parentItem;
|
||||
bool isSlideshow = false;
|
||||
int items = 0;
|
||||
|
||||
// We parse all files going into one folder, then start the copy job
|
||||
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); i++) {
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); ++i) {
|
||||
parentItem = files_list->topLevelItem(i);
|
||||
if (parentItem->isDisabled()) {
|
||||
parentItem->setExpanded(false);
|
||||
@@ -548,15 +554,16 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass)
|
||||
else isSlideshow = false;
|
||||
files_list->setCurrentItem(parentItem);
|
||||
parentItem->setExpanded(true);
|
||||
destPath = parentItem->data(0, Qt::UserRole).toString() + "/";
|
||||
destPath = parentItem->data(0, Qt::UserRole).toString() + '/';
|
||||
destUrl = KUrl(archive_url->url().path(KUrl::AddTrailingSlash) + destPath);
|
||||
QTreeWidgetItem *item;
|
||||
for (int j = 0; j < parentItem->childCount(); j++) {
|
||||
item = parentItem->child(j);
|
||||
if (item->isDisabled()) continue;
|
||||
// Special case: slideshows
|
||||
items++;
|
||||
if (isSlideshow) {
|
||||
destPath += item->data(0, Qt::UserRole).toString() + "/";
|
||||
destPath += item->data(0, Qt::UserRole).toString() + '/';
|
||||
destUrl = KUrl(archive_url->url().path(KUrl::AddTrailingSlash) + destPath);
|
||||
QStringList srcFiles = item->data(0, Qt::UserRole + 1).toStringList();
|
||||
for (int k = 0; k < srcFiles.count(); k++) {
|
||||
@@ -586,6 +593,12 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass)
|
||||
}
|
||||
}
|
||||
|
||||
if (items == 0) {
|
||||
// No clips to archive
|
||||
slotArchivingFinished(NULL, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (destPath.isEmpty()) {
|
||||
if (m_duplicateFiles.isEmpty()) return false;
|
||||
QMapIterator<KUrl, KUrl> i(m_duplicateFiles);
|
||||
@@ -595,15 +608,15 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass)
|
||||
KUrl startJobDst = i.value();
|
||||
m_duplicateFiles.remove(startJobSrc);
|
||||
KIO::CopyJob *job = KIO::copyAs(startJobSrc, startJobDst, KIO::HideProgressInfo);
|
||||
connect(job, SIGNAL(result(KJob *)), this, SLOT(slotArchivingFinished(KJob *)));
|
||||
connect(job, SIGNAL(processedSize(KJob *, qulonglong)), this, SLOT(slotArchivingProgress(KJob *, qulonglong)));
|
||||
connect(job, SIGNAL(result(KJob*)), this, SLOT(slotArchivingFinished(KJob*)));
|
||||
connect(job, SIGNAL(processedSize(KJob*,qulonglong)), this, SLOT(slotArchivingProgress(KJob*,qulonglong)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isArchive) {
|
||||
m_foldersList.append(destPath);
|
||||
for (int i = 0; i < files.count(); i++) {
|
||||
for (int i = 0; i < files.count(); ++i) {
|
||||
m_filesList.insert(files.at(i).path(), destPath + files.at(i).fileName());
|
||||
}
|
||||
slotArchivingFinished();
|
||||
@@ -614,8 +627,8 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass)
|
||||
else {
|
||||
KIO::NetAccess::mkdir(destUrl, this);
|
||||
m_copyJob = KIO::copy (files, destUrl, KIO::HideProgressInfo);
|
||||
connect(m_copyJob, SIGNAL(result(KJob *)), this, SLOT(slotArchivingFinished(KJob *)));
|
||||
connect(m_copyJob, SIGNAL(processedSize(KJob *, qulonglong)), this, SLOT(slotArchivingProgress(KJob *, qulonglong)));
|
||||
connect(m_copyJob, SIGNAL(result(KJob*)), this, SLOT(slotArchivingFinished(KJob*)));
|
||||
connect(m_copyJob, SIGNAL(processedSize(KJob*,qulonglong)), this, SLOT(slotArchivingProgress(KJob*,qulonglong)));
|
||||
}
|
||||
if (firstPass) {
|
||||
progressBar->setValue(0);
|
||||
@@ -624,10 +637,10 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArchiveWidget::slotArchivingFinished(KJob *job)
|
||||
void ArchiveWidget::slotArchivingFinished(KJob *job, bool finished)
|
||||
{
|
||||
if (job == NULL || job->error() == 0) {
|
||||
if (slotStartArchiving(false)) {
|
||||
if (!finished && slotStartArchiving(false)) {
|
||||
// We still have files to archive
|
||||
return;
|
||||
}
|
||||
@@ -651,7 +664,7 @@ void ArchiveWidget::slotArchivingFinished(KJob *job)
|
||||
archive_url->setEnabled(true);
|
||||
proxy_only->setEnabled(true);
|
||||
compressed_archive->setEnabled(true);
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); i++) {
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); ++i) {
|
||||
files_list->topLevelItem(i)->setDisabled(false);
|
||||
for (int j = 0; j < files_list->topLevelItem(i)->childCount(); j++)
|
||||
files_list->topLevelItem(i)->child(j)->setDisabled(false);
|
||||
@@ -671,7 +684,7 @@ bool ArchiveWidget::processProjectFile()
|
||||
QTreeWidgetItem *item;
|
||||
bool isArchive = compressed_archive->isChecked();
|
||||
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); i++) {
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *parentItem = files_list->topLevelItem(i);
|
||||
if (parentItem->childCount() > 0) {
|
||||
destUrl = KUrl(archive_url->url().path(KUrl::AddTrailingSlash) + parentItem->data(0, Qt::UserRole).toString());
|
||||
@@ -681,7 +694,7 @@ bool ArchiveWidget::processProjectFile()
|
||||
KUrl src(item->text(0));
|
||||
KUrl dest = destUrl;
|
||||
if (isSlideshow) {
|
||||
dest = KUrl(destUrl.path(KUrl::AddTrailingSlash) + item->data(0, Qt::UserRole).toString() + "/" + src.fileName());
|
||||
dest = KUrl(destUrl.path(KUrl::AddTrailingSlash) + item->data(0, Qt::UserRole).toString() + '/' + src.fileName());
|
||||
}
|
||||
else if (item->data(0, Qt::UserRole).isNull()) {
|
||||
dest.addPath(src.fileName());
|
||||
@@ -695,7 +708,7 @@ bool ArchiveWidget::processProjectFile()
|
||||
}
|
||||
|
||||
QDomElement mlt = m_doc.documentElement();
|
||||
QString root = mlt.attribute("root") + "/";
|
||||
QString root = mlt.attribute("root") + '/';
|
||||
|
||||
// Adjust global settings
|
||||
QString basePath;
|
||||
@@ -707,7 +720,7 @@ bool ArchiveWidget::processProjectFile()
|
||||
|
||||
// process kdenlive producers
|
||||
QDomNodeList prods = mlt.elementsByTagName("kdenlive_producer");
|
||||
for (int i = 0; i < prods.count(); i++) {
|
||||
for (int i = 0; i < prods.count(); ++i) {
|
||||
QDomElement e = prods.item(i).toElement();
|
||||
if (e.isNull()) continue;
|
||||
if (e.hasAttribute("resource")) {
|
||||
@@ -724,7 +737,7 @@ bool ArchiveWidget::processProjectFile()
|
||||
|
||||
// process mlt producers
|
||||
prods = mlt.elementsByTagName("producer");
|
||||
for (int i = 0; i < prods.count(); i++) {
|
||||
for (int i = 0; i < prods.count(); ++i) {
|
||||
QDomElement e = prods.item(i).toElement();
|
||||
if (e.isNull()) continue;
|
||||
QString src = EffectsList::property(e, "resource");
|
||||
@@ -739,7 +752,7 @@ bool ArchiveWidget::processProjectFile()
|
||||
// process mlt transitions (for luma files)
|
||||
prods = mlt.elementsByTagName("transition");
|
||||
QString attribute;
|
||||
for (int i = 0; i < prods.count(); i++) {
|
||||
for (int i = 0; i < prods.count(); ++i) {
|
||||
QDomElement e = prods.item(i).toElement();
|
||||
if (e.isNull()) continue;
|
||||
attribute = "resource";
|
||||
@@ -761,8 +774,8 @@ bool ArchiveWidget::processProjectFile()
|
||||
QString endString("\"");
|
||||
endString.append(basePath);
|
||||
playList.replace(startString, endString);
|
||||
startString = ">" + archive_url->url().path(KUrl::RemoveTrailingSlash);
|
||||
endString = ">" + basePath;
|
||||
startString = '>' + archive_url->url().path(KUrl::RemoveTrailingSlash);
|
||||
endString = '>' + basePath;
|
||||
playList.replace(startString, endString);
|
||||
}
|
||||
|
||||
@@ -817,9 +830,13 @@ void ArchiveWidget::createArchive()
|
||||
}
|
||||
|
||||
// Add project file
|
||||
archive.addLocalFile(m_temp->fileName(), m_name + ".kdenlive");
|
||||
bool result = archive.close();
|
||||
delete m_temp;
|
||||
bool result = false;
|
||||
if (m_temp) {
|
||||
archive.addLocalFile(m_temp->fileName(), m_name + ".kdenlive");
|
||||
result = archive.close();
|
||||
delete m_temp;
|
||||
m_temp = 0;
|
||||
}
|
||||
emit archivingFinished(result);
|
||||
}
|
||||
|
||||
@@ -837,7 +854,7 @@ void ArchiveWidget::slotArchivingFinished(bool result)
|
||||
archive_url->setEnabled(true);
|
||||
proxy_only->setEnabled(true);
|
||||
compressed_archive->setEnabled(true);
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); i++) {
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); ++i) {
|
||||
files_list->topLevelItem(i)->setDisabled(false);
|
||||
for (int j = 0; j < files_list->topLevelItem(i)->childCount(); j++)
|
||||
files_list->topLevelItem(i)->child(j)->setDisabled(false);
|
||||
@@ -860,10 +877,6 @@ void ArchiveWidget::slotStartExtracting()
|
||||
KIO::NetAccess::mkdir(archive_url->url().path(KUrl::RemoveTrailingSlash), this);
|
||||
slotDisplayMessage("system-run", i18n("Extracting..."));
|
||||
buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Abort"));
|
||||
m_progressTimer = new QTimer;
|
||||
m_progressTimer->setInterval(800);
|
||||
m_progressTimer->setSingleShot(false);
|
||||
connect(m_progressTimer, SIGNAL(timeout()), this, SLOT(slotExtractProgress()));
|
||||
m_archiveThread = QtConcurrent::run(this, &ArchiveWidget::doExtracting);
|
||||
m_progressTimer->start();
|
||||
}
|
||||
@@ -890,7 +903,7 @@ void ArchiveWidget::doExtracting()
|
||||
emit extractingFinished();
|
||||
}
|
||||
|
||||
QString ArchiveWidget::extractedProjectFile()
|
||||
QString ArchiveWidget::extractedProjectFile() const
|
||||
{
|
||||
return archive_url->url().path(KUrl::AddTrailingSlash) + m_projectName;
|
||||
}
|
||||
@@ -898,7 +911,6 @@ QString ArchiveWidget::extractedProjectFile()
|
||||
void ArchiveWidget::slotExtractingFinished()
|
||||
{
|
||||
m_progressTimer->stop();
|
||||
delete m_progressTimer;
|
||||
// Process project file
|
||||
QFile file(extractedProjectFile());
|
||||
bool error = false;
|
||||
@@ -906,7 +918,7 @@ void ArchiveWidget::slotExtractingFinished()
|
||||
error = true;
|
||||
}
|
||||
else {
|
||||
QString playList = file.readAll();
|
||||
QString playList = QString::fromUtf8(file.readAll());
|
||||
file.close();
|
||||
if (playList.isEmpty()) {
|
||||
error = true;
|
||||
@@ -942,7 +954,7 @@ void ArchiveWidget::slotProxyOnly(int onlyProxy)
|
||||
QTreeWidgetItem *parentItem = NULL;
|
||||
|
||||
// Build list of existing proxy ids
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); i++) {
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); ++i) {
|
||||
parentItem = files_list->topLevelItem(i);
|
||||
if (parentItem->data(0, Qt::UserRole).toString() == "proxy") break;
|
||||
}
|
||||
@@ -953,7 +965,7 @@ void ArchiveWidget::slotProxyOnly(int onlyProxy)
|
||||
}
|
||||
|
||||
// Parse all items to disable original clips for existing proxies
|
||||
for (int i = 0; i < proxyIdList.count(); i++) {
|
||||
for (int i = 0; i < proxyIdList.count(); ++i) {
|
||||
QString id = proxyIdList.at(i);
|
||||
if (id.isEmpty()) continue;
|
||||
for (int j = 0; j < files_list->topLevelItemCount(); j++) {
|
||||
@@ -972,7 +984,7 @@ void ArchiveWidget::slotProxyOnly(int onlyProxy)
|
||||
}
|
||||
else {
|
||||
// Archive all clips
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); i++) {
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *parentItem = files_list->topLevelItem(i);
|
||||
int items = parentItem->childCount();
|
||||
for (int j = 0; j < items; j++) {
|
||||
@@ -983,7 +995,7 @@ void ArchiveWidget::slotProxyOnly(int onlyProxy)
|
||||
|
||||
// Calculate requested size
|
||||
int total = 0;
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); i++) {
|
||||
for (int i = 0; i < files_list->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *parentItem = files_list->topLevelItem(i);
|
||||
int items = parentItem->childCount();
|
||||
int itemsCount = 0;
|
||||
@@ -997,9 +1009,11 @@ void ArchiveWidget::slotProxyOnly(int onlyProxy)
|
||||
itemsCount ++;
|
||||
}
|
||||
}
|
||||
parentItem->setText(0, parentItem->text(0).section("(", 0, 0) + i18np("(%1 item)", "(%1 items)", itemsCount));
|
||||
parentItem->setText(0, parentItem->text(0).section('(', 0, 0) + i18np("(%1 item)", "(%1 items)", itemsCount));
|
||||
}
|
||||
project_files->setText(i18np("%1 file to archive, requires %2", "%1 files to archive, requires %2", total, KIO::convertSize(m_requestedSize)));
|
||||
slotCheckSpace();
|
||||
}
|
||||
|
||||
|
||||
#include "archivewidget.moc"
|
||||
|
||||
@@ -53,17 +53,17 @@ class ArchiveWidget : public QDialog, public Ui::ArchiveWidget_UI
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ArchiveWidget(QString projectName, QDomDocument doc, QList <DocClipBase*> list, QStringList luma_list, QWidget * parent = 0);
|
||||
ArchiveWidget(const QString &projectName, const QDomDocument &doc, const QList <DocClipBase*> &list, const QStringList &luma_list, QWidget * parent = 0);
|
||||
// Constructor for extracting widget
|
||||
ArchiveWidget(const KUrl &url, QWidget * parent = 0);
|
||||
explicit ArchiveWidget(const KUrl &url, QWidget * parent = 0);
|
||||
~ArchiveWidget();
|
||||
|
||||
QString extractedProjectFile();
|
||||
QString extractedProjectFile() const;
|
||||
|
||||
private slots:
|
||||
void slotCheckSpace();
|
||||
bool slotStartArchiving(bool firstPass = true);
|
||||
void slotArchivingFinished(KJob *job = NULL);
|
||||
void slotArchivingFinished(KJob *job = NULL, bool finished = false);
|
||||
void slotArchivingProgress(KJob *, qulonglong);
|
||||
virtual void done ( int r );
|
||||
bool closeAccepted();
|
||||
@@ -107,9 +107,9 @@ private:
|
||||
#endif
|
||||
|
||||
/** @brief Generate tree widget subitems from a string list of urls. */
|
||||
void generateItems(QTreeWidgetItem *parentItem, QStringList items);
|
||||
void generateItems(QTreeWidgetItem *parentItem, const QStringList &items);
|
||||
/** @brief Generate tree widget subitems from a map of clip ids / urls. */
|
||||
void generateItems(QTreeWidgetItem *parentItem, QMap <QString, QString> items);
|
||||
void generateItems(QTreeWidgetItem *parentItem, const QMap<QString, QString> &items);
|
||||
/** @brief Replace urls in project file. */
|
||||
bool processProjectFile();
|
||||
|
||||
|
||||
@@ -24,14 +24,17 @@
|
||||
|
||||
|
||||
BezierSplineEditor::BezierSplineEditor(QWidget* parent) :
|
||||
QWidget(parent),
|
||||
m_mode(ModeNormal),
|
||||
m_zoomLevel(0),
|
||||
m_gridLines(3),
|
||||
m_showAllHandles(true),
|
||||
m_pixmapCache(NULL),
|
||||
m_pixmapIsDirty(true),
|
||||
m_currentPointIndex(-1)
|
||||
QWidget(parent)
|
||||
, m_mode(ModeNormal)
|
||||
, m_zoomLevel(0)
|
||||
, m_gridLines(3)
|
||||
, m_showAllHandles(true)
|
||||
, m_pixmapCache(NULL)
|
||||
, m_pixmapIsDirty(true)
|
||||
, m_currentPointIndex(-1)
|
||||
, m_currentPointType(PTypeP)
|
||||
, m_grabOffsetX(0)
|
||||
, m_grabOffsetY(0)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
setAutoFillBackground(false);
|
||||
@@ -42,11 +45,10 @@ BezierSplineEditor::BezierSplineEditor(QWidget* parent) :
|
||||
|
||||
BezierSplineEditor::~BezierSplineEditor()
|
||||
{
|
||||
if (m_pixmapCache)
|
||||
delete m_pixmapCache;
|
||||
delete m_pixmapCache;
|
||||
}
|
||||
|
||||
CubicBezierSpline BezierSplineEditor::spline()
|
||||
CubicBezierSpline BezierSplineEditor::spline() const
|
||||
{
|
||||
return m_spline;
|
||||
}
|
||||
@@ -104,11 +106,13 @@ void BezierSplineEditor::slotZoomOut()
|
||||
|
||||
void BezierSplineEditor::setShowAllHandles(bool show)
|
||||
{
|
||||
m_showAllHandles = show;
|
||||
update();
|
||||
if (m_showAllHandles != show) {
|
||||
m_showAllHandles = show;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int BezierSplineEditor::gridLines()
|
||||
int BezierSplineEditor::gridLines() const
|
||||
{
|
||||
return m_gridLines;
|
||||
}
|
||||
@@ -459,7 +463,7 @@ void BezierSplineEditor::leaveEvent(QEvent* event)
|
||||
QWidget::leaveEvent(event);
|
||||
}
|
||||
|
||||
int BezierSplineEditor::nearestPointInRange(QPointF p, int wWidth, int wHeight, BezierSplineEditor::point_types* sel)
|
||||
int BezierSplineEditor::nearestPointInRange(const QPointF &p, int wWidth, int wHeight, BezierSplineEditor::point_types* sel)
|
||||
{
|
||||
double nearestDistanceSquared = 1000;
|
||||
point_types selectedPoint = PTypeP;
|
||||
|
||||
@@ -29,10 +29,10 @@ class BezierSplineEditor : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BezierSplineEditor(QWidget* parent = 0);
|
||||
virtual ~BezierSplineEditor();
|
||||
explicit BezierSplineEditor(QWidget* parent = 0);
|
||||
~BezierSplineEditor();
|
||||
|
||||
CubicBezierSpline spline();
|
||||
CubicBezierSpline spline() const;
|
||||
void setSpline(const CubicBezierSpline &spline);
|
||||
|
||||
/** @brief Returns the selected point or else BPoint. */
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
void updateCurrentPoint(const BPoint &p, bool final = true);
|
||||
|
||||
/** @brief Number of lines used in grid. */
|
||||
int gridLines();
|
||||
int gridLines() const;
|
||||
|
||||
/** @brief Sets the number of grid lines to draw (in one direction) to @param lines. */
|
||||
void setGridLines(int lines);
|
||||
@@ -100,7 +100,7 @@ private:
|
||||
* @param sel Is filled with the type of the closest point (h1, p, h2)
|
||||
*
|
||||
* If no point is near enough -1 is returned. */
|
||||
int nearestPointInRange(QPointF p, int wWidth, int wHeight, point_types *sel);
|
||||
int nearestPointInRange(const QPointF &p, int wWidth, int wHeight, point_types *sel);
|
||||
|
||||
signals:
|
||||
void modified();
|
||||
|
||||
@@ -74,14 +74,14 @@ BezierSplineWidget::BezierSplineWidget(const QString& spline, QWidget* parent) :
|
||||
m_edit.setSpline(s);
|
||||
|
||||
connect(&m_edit, SIGNAL(modified()), this, SIGNAL(modified()));
|
||||
connect(&m_edit, SIGNAL(currentPoint(const BPoint&)), this, SLOT(slotUpdatePointEntries(const BPoint&)));
|
||||
connect(&m_edit, SIGNAL(currentPoint(BPoint)), this, SLOT(slotUpdatePointEntries(BPoint)));
|
||||
|
||||
connect(m_pX, SIGNAL(valueChanged(double, bool)), this, SLOT(slotUpdatePointP(double, bool)));
|
||||
connect(m_pY, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointP(double, bool)));
|
||||
connect(m_h1X, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH1(double, bool)));
|
||||
connect(m_h1Y, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH1(double, bool)));
|
||||
connect(m_h2X, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH2(double, bool)));
|
||||
connect(m_h2Y, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH2(double, bool)));
|
||||
connect(m_pX, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointP(double,bool)));
|
||||
connect(m_pY, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointP(double,bool)));
|
||||
connect(m_h1X, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH1(double,bool)));
|
||||
connect(m_h1Y, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH1(double,bool)));
|
||||
connect(m_h2X, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH2(double,bool)));
|
||||
connect(m_h2Y, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH2(double,bool)));
|
||||
|
||||
connect(m_ui.buttonLinkHandles, SIGNAL(toggled(bool)), this, SLOT(slotSetHandlesLinked(bool)));
|
||||
connect(m_ui.buttonZoomIn, SIGNAL(clicked()), &m_edit, SLOT(slotZoomIn()));
|
||||
@@ -97,7 +97,7 @@ BezierSplineWidget::BezierSplineWidget(const QString& spline, QWidget* parent) :
|
||||
m_ui.buttonShowAllHandles->setChecked(KdenliveSettings::bezier_showallhandles());
|
||||
}
|
||||
|
||||
QString BezierSplineWidget::spline()
|
||||
QString BezierSplineWidget::spline() const
|
||||
{
|
||||
return m_edit.spline().toString();
|
||||
}
|
||||
@@ -119,14 +119,16 @@ void BezierSplineWidget::slotGridChange()
|
||||
|
||||
void BezierSplineWidget::slotShowPixmap(bool show)
|
||||
{
|
||||
m_showPixmap = show;
|
||||
KdenliveSettings::setBezier_showpixmap(show);
|
||||
if (show && (int)m_mode < 6)
|
||||
m_edit.setPixmap(QPixmap::fromImage(ColorTools::rgbCurvePlane(m_edit.size(), (ColorTools::ColorsRGB)((int)m_mode), 1, palette().background().color().rgb())));
|
||||
else if (show && m_mode == ModeHue)
|
||||
m_edit.setPixmap(QPixmap::fromImage(ColorTools::hsvCurvePlane(m_edit.size(), QColor::fromHsv(200, 200, 200), ColorTools::COM_H, ColorTools::COM_H)));
|
||||
else
|
||||
m_edit.setPixmap(QPixmap());
|
||||
if (m_showPixmap != show) {
|
||||
m_showPixmap = show;
|
||||
KdenliveSettings::setBezier_showpixmap(show);
|
||||
if (show && (int)m_mode < 6)
|
||||
m_edit.setPixmap(QPixmap::fromImage(ColorTools::rgbCurvePlane(m_edit.size(), (ColorTools::ColorsRGB)((int)m_mode), 1, palette().background().color().rgb())));
|
||||
else if (show && m_mode == ModeHue)
|
||||
m_edit.setPixmap(QPixmap::fromImage(ColorTools::hsvCurvePlane(m_edit.size(), QColor::fromHsv(200, 200, 200), ColorTools::COM_H, ColorTools::COM_H)));
|
||||
else
|
||||
m_edit.setPixmap(QPixmap());
|
||||
}
|
||||
}
|
||||
|
||||
void BezierSplineWidget::slotUpdatePointEntries(const BPoint &p)
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "beziersplineeditor.h"
|
||||
#include "ui_bezierspline_ui.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QWidget>
|
||||
|
||||
class DragValue;
|
||||
@@ -34,10 +33,10 @@ class BezierSplineWidget : public QWidget
|
||||
|
||||
public:
|
||||
/** @brief Sets up the UI and sets the spline to @param spline. */
|
||||
BezierSplineWidget(const QString &spline, QWidget* parent = 0);
|
||||
explicit BezierSplineWidget(const QString &spline, QWidget* parent = 0);
|
||||
|
||||
/** @brief Returns the current spline. */
|
||||
QString spline();
|
||||
QString spline() const;
|
||||
|
||||
/** The curvemodes refer to the usage of the spline.
|
||||
* As this widget is currently only used for frei0r.curves the modes are the channels this filter accepts. */
|
||||
|
||||
@@ -27,7 +27,7 @@ BPoint::BPoint() :
|
||||
{
|
||||
}
|
||||
|
||||
BPoint::BPoint(QPointF handle1, QPointF point, QPointF handle2) :
|
||||
BPoint::BPoint(const QPointF &handle1, const QPointF &point, const QPointF &handle2) :
|
||||
h1(handle1),
|
||||
p(point),
|
||||
h2(handle2)
|
||||
@@ -52,7 +52,7 @@ bool BPoint::operator==(const BPoint& point) const
|
||||
point.h2 == h2;
|
||||
}
|
||||
|
||||
void BPoint::setP(QPointF point, bool updateHandles)
|
||||
void BPoint::setP(const QPointF &point, bool updateHandles)
|
||||
{
|
||||
QPointF offset = point - p;
|
||||
p = point;
|
||||
@@ -62,7 +62,7 @@ void BPoint::setP(QPointF point, bool updateHandles)
|
||||
}
|
||||
}
|
||||
|
||||
void BPoint::setH1(QPointF handle1)
|
||||
void BPoint::setH1(const QPointF &handle1)
|
||||
{
|
||||
h1 = handle1;
|
||||
if (handlesLinked) {
|
||||
@@ -73,7 +73,7 @@ void BPoint::setH1(QPointF handle1)
|
||||
}
|
||||
}
|
||||
|
||||
void BPoint::setH2(QPointF handle2)
|
||||
void BPoint::setH2(const QPointF &handle2)
|
||||
{
|
||||
h2 = handle2;
|
||||
if (handlesLinked) {
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
/** @brief Sets the point to -1, -1 to mark it as unusable (until point + handles have proper values) */
|
||||
BPoint();
|
||||
/** @brief Sets up according to the params. Linking detecting is done using autoSetLinked(). */
|
||||
BPoint(QPointF handle1, QPointF point, QPointF handle2);
|
||||
BPoint(const QPointF &handle1, const QPointF &point, const QPointF &handle2);
|
||||
|
||||
/** @brief Returns h1 if i = 0, p if i = 1, h2 if i = 2. */
|
||||
QPointF &operator[](int i);
|
||||
@@ -41,17 +41,17 @@ public:
|
||||
|
||||
/** @brief Sets p to @param point.
|
||||
* @param updateHandles (default = true) Whether to make sure the handles keep their position relative to p. */
|
||||
void setP(QPointF point, bool updateHandles = true);
|
||||
void setP(const QPointF &point, bool updateHandles = true);
|
||||
|
||||
/** @brief Sets h1 to @param handle1.
|
||||
*
|
||||
* If handlesLinked is true h2 is updated. */
|
||||
void setH1(QPointF handle1);
|
||||
void setH1(const QPointF &handle1);
|
||||
|
||||
/** @brief Sets h2 to @param handle2.
|
||||
*
|
||||
* If handlesLinked is true h1 is updated. */
|
||||
void setH2(QPointF handle2);
|
||||
void setH2(const QPointF &handle2);
|
||||
void keepInRange(qreal xMin, qreal xMax);
|
||||
|
||||
/** @brief Sets handlesLinked to true if the handles are in a linked state (line through h1, p, h2) otherwise to false. */
|
||||
|
||||
@@ -48,12 +48,12 @@ void CubicBezierSpline::fromString(const QString& spline)
|
||||
{
|
||||
m_points.clear();
|
||||
|
||||
QStringList bpoints = spline.split('|');
|
||||
const QStringList bpoints = spline.split(QLatin1Char('|'));
|
||||
foreach(const QString &bpoint, bpoints) {
|
||||
QStringList points = bpoint.split('#');
|
||||
const QStringList points = bpoint.split(QLatin1Char('#'));
|
||||
QList <QPointF> values;
|
||||
foreach(const QString &point, points) {
|
||||
QStringList xy = point.split(';');
|
||||
QStringList xy = point.split(QLatin1Char(';'));
|
||||
if (xy.count() == 2)
|
||||
values.append(QPointF(xy.at(0).toDouble(), xy.at(1).toDouble()));
|
||||
}
|
||||
@@ -86,7 +86,7 @@ int CubicBezierSpline::setPoint(int ix, const BPoint& point)
|
||||
return indexOf(point); // in case it changed
|
||||
}
|
||||
|
||||
QList <BPoint> CubicBezierSpline::points()
|
||||
QList <BPoint> CubicBezierSpline::points() const
|
||||
{
|
||||
return m_points;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class CubicBezierSpline : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CubicBezierSpline(QObject* parent = 0);
|
||||
explicit CubicBezierSpline(QObject* parent = 0);
|
||||
CubicBezierSpline(const CubicBezierSpline &spline, QObject* parent = 0);
|
||||
CubicBezierSpline& operator=(const CubicBezierSpline &spline);
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
QString toString() const;
|
||||
|
||||
/** @brief Returns a list of the points defining the spline. */
|
||||
QList <BPoint> points();
|
||||
QList <BPoint> points() const;
|
||||
|
||||
/** @brief Sets the point at index @param ix to @param point and returns its index (it might have changed during validation). */
|
||||
int setPoint(int ix, const BPoint &point);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <KColorButton>
|
||||
#include <KLocalizedString>
|
||||
#include <kdeversion.h>
|
||||
#include <KDebug>
|
||||
|
||||
static QColor stringToColor(QString strColor)
|
||||
{
|
||||
@@ -67,7 +68,7 @@ static QColor stringToColor(QString strColor)
|
||||
return color;
|
||||
}
|
||||
|
||||
static QString colorToString(QColor color, bool alpha)
|
||||
static QString colorToString(const QColor &color, bool alpha)
|
||||
{
|
||||
QString colorStr;
|
||||
QTextStream stream(&colorStr);
|
||||
@@ -77,14 +78,16 @@ static QString colorToString(QColor color, bool alpha)
|
||||
stream.setFieldAlignment(QTextStream::AlignRight);
|
||||
stream.setPadChar('0');
|
||||
stream << color.red() << color.green() << color.blue();
|
||||
if(alpha)
|
||||
{
|
||||
if (alpha) {
|
||||
stream << color.alpha();
|
||||
} else {
|
||||
// MLT always wants 0xRRGGBBAA format
|
||||
stream << "ff";
|
||||
}
|
||||
return colorStr;
|
||||
}
|
||||
|
||||
ChooseColorWidget::ChooseColorWidget(QString text, QString color, QWidget *parent) :
|
||||
ChooseColorWidget::ChooseColorWidget(const QString &text, const QString &color, bool alphaEnabled, QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
@@ -99,6 +102,9 @@ ChooseColorWidget::ChooseColorWidget(QString text, QString color, QWidget *paren
|
||||
rightSideLayout->setSpacing(0);
|
||||
|
||||
m_button = new KColorButton(stringToColor(color), rightSide);
|
||||
#if KDE_IS_VERSION(4,5,0)
|
||||
if (alphaEnabled) m_button->setAlphaChannelEnabled(alphaEnabled);
|
||||
#endif
|
||||
// m_button->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
ColorPickerWidget *picker = new ColorPickerWidget(rightSide);
|
||||
|
||||
@@ -108,11 +114,12 @@ ChooseColorWidget::ChooseColorWidget(QString text, QString color, QWidget *paren
|
||||
rightSideLayout->addWidget(picker, 0, Qt::AlignRight);
|
||||
|
||||
connect(picker, SIGNAL(colorPicked(QColor)), this, SLOT(setColor(QColor)));
|
||||
connect(picker, SIGNAL(displayMessage(const QString&, int)), this, SIGNAL(displayMessage(const QString&, int)));
|
||||
connect(picker, SIGNAL(displayMessage(QString,int)), this, SIGNAL(displayMessage(QString,int)));
|
||||
connect(picker, SIGNAL(disableCurrentFilter(bool)), this, SIGNAL(disableCurrentFilter(bool)));
|
||||
connect(m_button, SIGNAL(changed(QColor)), this, SIGNAL(modified()));
|
||||
}
|
||||
|
||||
QString ChooseColorWidget::getColor()
|
||||
QString ChooseColorWidget::getColor() const
|
||||
{
|
||||
bool alphaChannel = false;
|
||||
#if KDE_IS_VERSION(4,5,0)
|
||||
@@ -121,14 +128,7 @@ QString ChooseColorWidget::getColor()
|
||||
return colorToString(m_button->color(), alphaChannel);
|
||||
}
|
||||
|
||||
void ChooseColorWidget::setAlphaChannelEnabled(bool enabled)
|
||||
{
|
||||
#if KDE_IS_VERSION(4,5,0)
|
||||
m_button->setAlphaChannelEnabled(enabled);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChooseColorWidget::setColor(QColor color)
|
||||
void ChooseColorWidget::setColor(const QColor& color)
|
||||
{
|
||||
m_button->setColor(color);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#ifndef CHOOSECOLORWIDGET_H
|
||||
#define CHOOSECOLORWIDGET_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QWidget>
|
||||
|
||||
class KColorButton;
|
||||
@@ -38,26 +37,26 @@ class ChooseColorWidget : public QWidget
|
||||
public:
|
||||
/** @brief Sets up the widget.
|
||||
* @param text (optional) What the color will be used for
|
||||
* @param color (optional) initial color */
|
||||
ChooseColorWidget(QString text = QString(), QString color = "0xffffffff", QWidget* parent = 0);
|
||||
* @param color (optional) initial color
|
||||
* @param alphaEnabled (optional) Should transparent colors be enabled */
|
||||
explicit ChooseColorWidget(const QString &text = QString(), const QString &color = "0xffffffff", bool alphaEnabled = false, QWidget* parent = 0);
|
||||
|
||||
/** @brief Gets the choosen color. */
|
||||
QString getColor();
|
||||
/** @brief Enable the use of alpha channel.
|
||||
* @param enabled (required) whether alpha is enabled or disabled */
|
||||
void setAlphaChannelEnabled(bool enabled);
|
||||
QString getColor() const;
|
||||
|
||||
private:
|
||||
KColorButton *m_button;
|
||||
|
||||
private slots:
|
||||
/** @brief Updates the different color choosing options to have all selected @param color. */
|
||||
void setColor(QColor color);
|
||||
void setColor(const QColor &color);
|
||||
|
||||
signals:
|
||||
/** @brief Emitted whenever a different color was choosen. */
|
||||
void modified();
|
||||
void displayMessage(const QString&, int);
|
||||
/** @brief When user wants to pick a color, it's better to disable filter so we get proper color values. */
|
||||
void disableCurrentFilter(bool);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <QWheelEvent>
|
||||
|
||||
ClipDurationDialog::ClipDurationDialog(AbstractClipItem *clip, Timecode tc, GenTime min, GenTime max, QWidget * parent):
|
||||
ClipDurationDialog::ClipDurationDialog(AbstractClipItem *clip, const Timecode &tc, const GenTime &min, const GenTime &max, QWidget * parent):
|
||||
QDialog(parent),
|
||||
m_clip(clip),
|
||||
m_min(min),
|
||||
@@ -49,7 +49,7 @@ ClipDurationDialog::ClipDurationDialog(AbstractClipItem *clip, Timecode tc, GenT
|
||||
bool allowCrop = true;
|
||||
if (clip->type() == AVWIDGET) {
|
||||
ClipItem *item = static_cast <ClipItem *>(clip);
|
||||
int t = item->clipType();
|
||||
const int t = item->clipType();
|
||||
if (t == COLOR || t == IMAGE || t == TEXT)
|
||||
allowCrop = false;
|
||||
}
|
||||
@@ -68,10 +68,10 @@ ClipDurationDialog::ClipDurationDialog(AbstractClipItem *clip, Timecode tc, GenT
|
||||
m_cropStart->setValue(m_clip->cropStart());
|
||||
m_cropEnd->setValue(m_clip->maxDuration() - m_clip->cropDuration() - m_clip->cropStart());
|
||||
|
||||
connect(m_pos, SIGNAL(editingFinished()), this, SLOT(slotCheckStart()));
|
||||
connect(m_dur, SIGNAL(editingFinished()), this, SLOT(slotCheckDuration()));
|
||||
connect(m_cropStart, SIGNAL(editingFinished()), this, SLOT(slotCheckCrop()));
|
||||
connect(m_cropEnd, SIGNAL(editingFinished()), this, SLOT(slotCheckEnd()));
|
||||
connect(m_pos, SIGNAL(timeCodeEditingFinished()), this, SLOT(slotCheckStart()));
|
||||
connect(m_dur, SIGNAL(timeCodeEditingFinished()), this, SLOT(slotCheckDuration()));
|
||||
connect(m_cropStart, SIGNAL(timeCodeEditingFinished()), this, SLOT(slotCheckCrop()));
|
||||
connect(m_cropEnd, SIGNAL(timeCodeEditingFinished()), this, SLOT(slotCheckEnd()));
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class ClipDurationDialog : public QDialog, public Ui::ClipDurationDialog_UI
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ClipDurationDialog(AbstractClipItem *clip, Timecode tc, GenTime min, GenTime max, QWidget * parent = 0);
|
||||
explicit ClipDurationDialog(AbstractClipItem *clip, const Timecode &tc, const GenTime &min, const GenTime &max, QWidget * parent = 0);
|
||||
~ClipDurationDialog();
|
||||
GenTime startPos() const;
|
||||
GenTime cropStart() const;
|
||||
|
||||
837
src/clipitem.cpp
837
src/clipitem.cpp
File diff suppressed because it is too large
Load Diff
@@ -46,15 +46,15 @@ class ClipItem : public AbstractClipItem
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, int strobe, int frame_width, bool generateThumbs = true);
|
||||
ClipItem(DocClipBase *clip, const ItemInfo &info, double fps, double speed, int strobe, int frame_width, bool generateThumbs = true);
|
||||
virtual ~ ClipItem();
|
||||
virtual void paint(QPainter *painter,
|
||||
const QStyleOptionGraphicsItem *option,
|
||||
QWidget *);
|
||||
virtual int type() const;
|
||||
void resizeStart(int posx, bool size = true);
|
||||
void resizeEnd(int posx);
|
||||
OPERATIONTYPE operationMode(QPointF pos);
|
||||
void resizeStart(int posx, bool size = true, bool emitChange = true);
|
||||
void resizeEnd(int posx, bool emitChange = true);
|
||||
OPERATIONTYPE operationMode(const QPointF &pos);
|
||||
static int itemHeight();
|
||||
const QString clipProducer() const;
|
||||
int clipType() const;
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
void setClipName(const QString &name);
|
||||
QDomElement xml() const;
|
||||
QDomElement itemXml() const;
|
||||
ClipItem *clone(ItemInfo info) const;
|
||||
ClipItem *clone(const ItemInfo &info) const;
|
||||
const EffectsList effectList() const;
|
||||
void setFadeOut(int pos);
|
||||
void setFadeIn(int pos);
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
EffectsParameterList addEffect(QDomElement effect, bool animate = true);
|
||||
|
||||
/** @brief Deletes the effect with id @param index. */
|
||||
void deleteEffect(QString index);
|
||||
void deleteEffect(const QString &index);
|
||||
|
||||
/** @brief Gets the number of effects in this clip. */
|
||||
int effectsCount();
|
||||
@@ -86,20 +86,27 @@ public:
|
||||
/** @brief Gets a unique (?) effect id. */
|
||||
int effectsCounter();
|
||||
|
||||
/** @brief Gets a copy of the xml of an effect.
|
||||
* @param ix The effect's index in effectlist
|
||||
/** @brief Gets a copy of the xml of an effect.
|
||||
* @param ix The effect's list index (starting from 0)
|
||||
* @return A copy of the effect's xml */
|
||||
QDomElement effectAt(int ix) const;
|
||||
QDomElement effect(int ix) const;
|
||||
|
||||
/** @brief Gets a copy of the xml of an effect.
|
||||
* @param ix The effect's index in effectlist (starting from 1)
|
||||
* @return A copy of the effect's xml */
|
||||
QDomElement effectAtIndex(int ix) const;
|
||||
|
||||
/** @brief Gets the xml of an effect.
|
||||
* @param ix The effect's index in effectlist
|
||||
* @param ix The effect's index in effectlist (starting from 1)
|
||||
* @return The effect's xml */
|
||||
QDomElement getEffectAt(int ix) const;
|
||||
QDomElement getEffectAtIndex(int ix) const;
|
||||
|
||||
/** @brief Replaces an effect.
|
||||
* @param ix The effect's index in effectlist
|
||||
* @param effect The new effect */
|
||||
void updateEffect(QDomElement effect);
|
||||
/** @brief Enable / disable a list of effect from their indexes. */
|
||||
void enableEffects(QList <int> indexes, bool disable);
|
||||
bool moveEffect(QDomElement effect, int ix);
|
||||
void flashClip();
|
||||
void addTransition(Transition*);
|
||||
@@ -127,18 +134,23 @@ public:
|
||||
void updateKeyframeEffect();
|
||||
QDomElement selectedEffect();
|
||||
int selectedEffectIndex() const;
|
||||
void initEffect(QDomElement effect, int diff = 0);
|
||||
|
||||
void initEffect(QDomElement effect, int diff = 0, int offset = 0);
|
||||
|
||||
/** @brief Gets all keyframes.
|
||||
* @param index Number of the effect
|
||||
* @param index Index of the effect
|
||||
* @return a list of strings of keyframes (one string per param) */
|
||||
QStringList keyframes(const int index);
|
||||
|
||||
/** @brief Adjust all geometry keyframes.
|
||||
* @param index Index of the effect */
|
||||
void resizeGeometries(const int index, int width, int height, int previousDuration, int start, int duration);
|
||||
|
||||
/** @brief Sets params with keyframes and updates the visible keyframes.
|
||||
* @param ix Number of the effect
|
||||
* @param keyframes a list of strings of keyframes (one string per param), which should be used */
|
||||
void setKeyframes(const int ix, const QStringList keyframes);
|
||||
void setEffectList(const EffectsList effectList);
|
||||
void setKeyframes(const int ix, const QStringList &keyframes);
|
||||
void setEffectList(const EffectsList &effectList);
|
||||
void setSpeed(const double speed, int strobe);
|
||||
double speed() const;
|
||||
int strobe() const;
|
||||
@@ -148,9 +160,12 @@ public:
|
||||
const ItemInfo speedIndependantInfo() const;
|
||||
int hasEffect(const QString &tag, const QString &id) const;
|
||||
|
||||
/** @brief Adjust keyframes to the new clip. */
|
||||
const QString adjustKeyframes(const QString &keyframes, int offset);
|
||||
/** @brief Makes sure all keyframes are in the clip's cropped duration.
|
||||
* @param cutPos the frame number where the new clip starts
|
||||
* @return Whether or not changes were made */
|
||||
bool checkKeyFrames();
|
||||
bool checkKeyFrames(int width, int height, int previousDuration, int cutPos = -1);
|
||||
QPixmap startThumb() const;
|
||||
QPixmap endThumb() const;
|
||||
void setVideoOnly(bool force);
|
||||
@@ -162,10 +177,10 @@ public:
|
||||
void movedKeyframe(QDomElement effect, int oldpos, int newpos, double value);
|
||||
void updateKeyframes(QDomElement effect);
|
||||
void updateGeometryKeyframes(QDomElement effect, int paramIndex, int width, int height, ItemInfo oldInfo);
|
||||
bool updateNormalKeyframes(QDomElement parameter);
|
||||
bool updateNormalKeyframes(QDomElement parameter, ItemInfo oldInfo);
|
||||
|
||||
/** @brief Adjusts effects after a clip duration change. */
|
||||
QMap<int, QDomElement> adjustEffectsToDuration(int width, int height, ItemInfo oldInfo);
|
||||
QMap<int, QDomElement> adjustEffectsToDuration(int width, int height, const ItemInfo &oldInfo);
|
||||
|
||||
/** Returns the necessary (audio, video, general) producer.
|
||||
* @param track Track of the requested producer
|
||||
@@ -182,12 +197,12 @@ public:
|
||||
|
||||
protected:
|
||||
//virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
|
||||
virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
|
||||
virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
|
||||
virtual void dropEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
|
||||
void dropEvent(QGraphicsSceneDragDropEvent *event);
|
||||
//virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *);
|
||||
//virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *);
|
||||
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||
|
||||
private:
|
||||
DocClipBase *m_clip;
|
||||
@@ -201,6 +216,7 @@ private:
|
||||
bool m_audioOnly;
|
||||
bool m_videoOnly;
|
||||
QColor m_baseColor;
|
||||
QColor m_paintColor;
|
||||
|
||||
QPixmap m_startPix;
|
||||
QPixmap m_endPix;
|
||||
@@ -233,22 +249,23 @@ private slots:
|
||||
void slotGetStartThumb();
|
||||
void slotGetEndThumb();
|
||||
void slotGotAudioData();
|
||||
void slotPrepareAudioThumb(double pixelForOneFrame, int startpixel, int endpixel, int channels);
|
||||
void slotPrepareAudioThumb(double pixelForOneFrame, int startpixel, int endpixel, int channels, int pixelHeight);
|
||||
void animate(qreal value);
|
||||
void slotSetStartThumb(QImage img);
|
||||
void slotSetEndThumb(QImage img);
|
||||
void slotThumbReady(int frame, QImage img);
|
||||
void slotSetStartThumb(const QImage &img);
|
||||
void slotSetEndThumb(const QImage &img);
|
||||
void slotThumbReady(int frame, const QImage &img);
|
||||
/** @brief The thumbnailer has finished to cache all required thumbs. */
|
||||
void slotGotThumbsCache();
|
||||
|
||||
public slots:
|
||||
void slotFetchThumbs();
|
||||
void slotSetStartThumb(const QPixmap pix);
|
||||
void slotSetEndThumb(const QPixmap pix);
|
||||
void slotSetStartThumb(const QPixmap &pix);
|
||||
void slotSetEndThumb(const QPixmap &pix);
|
||||
void slotUpdateRange();
|
||||
|
||||
signals:
|
||||
void getThumb(int, int);
|
||||
void prepareAudioThumb(double, int, int, int);
|
||||
void prepareAudioThumb(double, int, int, int, int);
|
||||
void updateRange();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "abstractclipitem.h"
|
||||
#include "abstractgroupitem.h"
|
||||
#include "titledocument.h"
|
||||
#include "subprojectitem.h"
|
||||
#include "kthumb.h"
|
||||
|
||||
#include <mlt++/Mlt.h>
|
||||
@@ -35,12 +36,19 @@
|
||||
#include <KFileDialog>
|
||||
#include <KApplication>
|
||||
#include <kio/netaccess.h>
|
||||
#include <kio/jobuidelegate.h>
|
||||
|
||||
#include <solid/device.h>
|
||||
#include <solid/storageaccess.h>
|
||||
#include <solid/storagedrive.h>
|
||||
#include <solid/storagevolume.h>
|
||||
|
||||
#include <QGraphicsItemGroup>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include <KFileMetaInfo>
|
||||
|
||||
|
||||
ClipManager::ClipManager(KdenliveDoc *doc) :
|
||||
QObject(),
|
||||
m_audioThumbsQueue(),
|
||||
@@ -52,9 +60,11 @@ ClipManager::ClipManager(KdenliveDoc *doc) :
|
||||
m_clipIdCounter = 1;
|
||||
m_folderIdCounter = 1;
|
||||
m_modifiedTimer.setInterval(1500);
|
||||
connect(&m_fileWatcher, SIGNAL(dirty(const QString &)), this, SLOT(slotClipModified(const QString &)));
|
||||
connect(&m_fileWatcher, SIGNAL(deleted(const QString &)), this, SLOT(slotClipMissing(const QString &)));
|
||||
connect(&m_fileWatcher, SIGNAL(created(const QString &)), this, SLOT(slotClipAvailable(const QString &)));
|
||||
connect(&m_fileWatcher, SIGNAL(dirty(QString)), this, SLOT(slotClipModified(QString)));
|
||||
connect(&m_fileWatcher, SIGNAL(deleted(QString)), this, SLOT(slotClipMissing(QString)));
|
||||
|
||||
// Seems like a dirty signal is emitted anyways when a watched file is created, so don't react twice.
|
||||
//connect(&m_fileWatcher, SIGNAL(created(QString)), this, SLOT(slotClipAvailable(QString)));
|
||||
connect(&m_modifiedTimer, SIGNAL(timeout()), this, SLOT(slotProcessModifiedClips()));
|
||||
|
||||
#if KDE_IS_VERSION(4,5,0)
|
||||
@@ -113,7 +123,7 @@ void ClipManager::clearCache()
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClipManager::requestThumbs(const QString id, QList <int> frames)
|
||||
void ClipManager::slotRequestThumbs(const QString &id, const QList <int>& frames)
|
||||
{
|
||||
m_thumbsMutex.lock();
|
||||
foreach (int frame, frames) {
|
||||
@@ -158,19 +168,42 @@ void ClipManager::slotGetThumbs()
|
||||
QMap<QString, int>::const_iterator i;
|
||||
int max;
|
||||
int done = 0;
|
||||
int thumbType = 0; // 0 = timeline thumb, 1 = project clip zone thumb, 2 = clip properties thumb
|
||||
|
||||
while (!m_requestedThumbs.isEmpty() && !m_abortThumb) {
|
||||
m_thumbsMutex.lock();
|
||||
i = m_requestedThumbs.constBegin();
|
||||
m_processingThumbId = i.key();
|
||||
QList<int> values = m_requestedThumbs.values(m_processingThumbId);
|
||||
m_requestedThumbs.remove(m_processingThumbId);
|
||||
if (m_processingThumbId.startsWith("?")) {
|
||||
// if id starts with ?, it means the request comes from a clip property widget
|
||||
thumbType = 2;
|
||||
m_processingThumbId.remove(0, 1);
|
||||
}
|
||||
if (m_processingThumbId.startsWith("#")) {
|
||||
// if id starts with #, it means the request comes from project tree
|
||||
thumbType = 1;
|
||||
m_processingThumbId.remove(0, 1);
|
||||
}
|
||||
m_thumbsMutex.unlock();
|
||||
qSort(values);
|
||||
DocClipBase *clip = getClipById(m_processingThumbId);
|
||||
if (!clip) continue;
|
||||
max = m_requestedThumbs.size() + values.count();
|
||||
int pos;
|
||||
while (!values.isEmpty() && clip->thumbProducer() && !m_abortThumb) {
|
||||
clip->thumbProducer()->getThumb(values.takeFirst());
|
||||
pos = values.takeFirst();
|
||||
switch (thumbType) {
|
||||
case 1:
|
||||
clip->thumbProducer()->getGenericThumb(pos, SubProjectItem::itemDefaultHeight(), thumbType);
|
||||
break;
|
||||
case 2:
|
||||
clip->thumbProducer()->getGenericThumb(pos, 180, thumbType);
|
||||
break;
|
||||
default:
|
||||
clip->thumbProducer()->getThumb(pos);
|
||||
}
|
||||
done++;
|
||||
if (max > 3) emit displayMessage(i18n("Loading thumbnails"), 100 * done / max);
|
||||
}
|
||||
@@ -194,7 +227,7 @@ void ClipManager::checkAudioThumbs()
|
||||
}
|
||||
|
||||
m_thumbsMutex.lock();
|
||||
for (int i = 0; i < m_clipList.count(); i++) {
|
||||
for (int i = 0; i < m_clipList.count(); ++i) {
|
||||
DocClipBase *clip = m_clipList.at(i);
|
||||
if (clip->hasAudioThumb() && !clip->audioThumbCreated())
|
||||
m_audioThumbsQueue.append(m_clipList.at(i)->getId());
|
||||
@@ -219,7 +252,7 @@ void ClipManager::askForAudioThumb(const QString &id)
|
||||
void ClipManager::slotGetAudioThumbs()
|
||||
{
|
||||
Mlt::Profile prof((char*) KdenliveSettings::current_profile().toUtf8().constData());
|
||||
mlt_audio_format audioFormat = mlt_audio_pcm;
|
||||
mlt_audio_format audioFormat = mlt_audio_s16;
|
||||
while (!m_abortAudioThumb && !m_audioThumbsQueue.isEmpty()) {
|
||||
m_thumbsMutex.lock();
|
||||
m_processingAudioThumbId = m_audioThumbsQueue.takeFirst();
|
||||
@@ -231,11 +264,17 @@ void ClipManager::slotGetAudioThumbs()
|
||||
if (hash.isEmpty()) continue;
|
||||
QString audioPath = projectFolder() + "/thumbs/" + hash + ".thumb";
|
||||
double lengthInFrames = clip->duration().frames(m_doc->fps());
|
||||
//FIXME: should this be hardcoded??
|
||||
int channels = 2;
|
||||
int frequency = 48000;
|
||||
int frequency = 0;
|
||||
int channels = 0;
|
||||
QString data = clip->getProperty("frequency");
|
||||
if (!data.isEmpty()) frequency = data.toInt();
|
||||
if (frequency <= 0) frequency = 48000;
|
||||
data = clip->getProperty("channels");
|
||||
if (!data.isEmpty()) channels = data.toInt();
|
||||
if (channels <= 0) channels = 2;
|
||||
int arrayWidth = 20;
|
||||
double frame = 0.0;
|
||||
int maxVolume = 0;
|
||||
audioByteArray storeIn;
|
||||
QFile f(audioPath);
|
||||
if (QFileInfo(audioPath).size() > 0 && f.open(QIODevice::ReadOnly)) {
|
||||
@@ -255,15 +294,19 @@ void ClipManager::slotGetAudioThumbs()
|
||||
h3 = 0;
|
||||
for (int c = 0; c < channels; c++) {
|
||||
QByteArray audioArray(arrayWidth, '\x00');
|
||||
for (int i = 0; i < arrayWidth; i++) {
|
||||
for (int i = 0; i < arrayWidth; ++i) {
|
||||
audioArray[i] = channelarray.at(h2 + h3 + i);
|
||||
if (audioArray.at(i) > maxVolume) maxVolume = audioArray.at(i);
|
||||
}
|
||||
h3 += arrayWidth;
|
||||
storeIn[z][c] = audioArray;
|
||||
}
|
||||
h2 += h1;
|
||||
}
|
||||
if (!m_abortAudioThumb) clip->updateAudioThumbnail(storeIn);
|
||||
if (!m_abortAudioThumb) {
|
||||
clip->setProperty("audio_max", QString::number(maxVolume - 64));
|
||||
clip->updateAudioThumbnail(storeIn);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -286,9 +329,9 @@ void ClipManager::slotGetAudioThumbs()
|
||||
producer.set("video_index", "-1");
|
||||
|
||||
if (KdenliveSettings::normaliseaudiothumbs()) {
|
||||
Mlt::Filter m_convert(prof, "volume");
|
||||
/*Mlt::Filter m_convert(prof, "volume");
|
||||
m_convert.set("gain", "normalise");
|
||||
producer.attach(m_convert);
|
||||
producer.attach(m_convert);*/
|
||||
}
|
||||
|
||||
int last_val = 0;
|
||||
@@ -310,8 +353,18 @@ void ClipManager::slotGetAudioThumbs()
|
||||
for (int c = 0; c < channels; c++) {
|
||||
QByteArray audioArray;
|
||||
audioArray.resize(arrayWidth);
|
||||
for (int i = 0; i < audioArray.size(); i++) {
|
||||
audioArray[i] = ((*(pcm + c + i * samples / audioArray.size())) >> 9) + 127 / 2 ;
|
||||
for (int i = 0; i < audioArray.size(); ++i) {
|
||||
double pcmval = *(pcm + c + i * samples / audioArray.size());
|
||||
if (pcmval >= 0) {
|
||||
pcmval = sqrt(pcmval) / 2.83 + 64;
|
||||
audioArray[i] = pcmval;
|
||||
if (pcmval > maxVolume) maxVolume = pcmval;
|
||||
}
|
||||
else {
|
||||
pcmval = -sqrt(-pcmval) / 2.83 + 64;
|
||||
audioArray[i] = pcmval;
|
||||
if (-pcmval > maxVolume) maxVolume = -pcmval;
|
||||
}
|
||||
}
|
||||
f.write(audioArray);
|
||||
storeIn[z][c] = audioArray;
|
||||
@@ -327,6 +380,7 @@ void ClipManager::slotGetAudioThumbs()
|
||||
f.remove();
|
||||
} else {
|
||||
clip->updateAudioThumbnail(storeIn);
|
||||
clip->setProperty("audio_max", QString::number(maxVolume - 64));
|
||||
}
|
||||
}
|
||||
m_processingAudioThumbId.clear();
|
||||
@@ -366,7 +420,7 @@ void ClipManager::slotDeleteClips(QStringList ids)
|
||||
QUndoCommand *delClips = new QUndoCommand();
|
||||
delClips->setText(i18np("Delete clip", "Delete clips", ids.size()));
|
||||
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
for (int i = 0; i < ids.size(); ++i) {
|
||||
DocClipBase *clip = getClipById(ids.at(i));
|
||||
if (clip) {
|
||||
new AddClipCommand(m_doc, clip->toXML(), ids.at(i), false, delClips);
|
||||
@@ -377,14 +431,14 @@ void ClipManager::slotDeleteClips(QStringList ids)
|
||||
|
||||
void ClipManager::deleteClip(const QString &clipId)
|
||||
{
|
||||
for (int i = 0; i < m_clipList.count(); i++) {
|
||||
for (int i = 0; i < m_clipList.count(); ++i) {
|
||||
if (m_clipList.at(i)->getId() == clipId) {
|
||||
if (m_clipList.at(i)->clipType() != COLOR && m_clipList.at(i)->clipType() != SLIDESHOW && !m_clipList.at(i)->fileURL().isEmpty()) {
|
||||
DocClipBase *clip = m_clipList.takeAt(i);
|
||||
if (clip->clipType() != COLOR && clip->clipType() != SLIDESHOW && !clip->fileURL().isEmpty()) {
|
||||
//if (m_clipList.at(i)->clipType() == IMAGE || m_clipList.at(i)->clipType() == AUDIO || (m_clipList.at(i)->clipType() == TEXT && !m_clipList.at(i)->fileURL().isEmpty())) {
|
||||
// listen for file change
|
||||
m_fileWatcher.removeFile(m_clipList.at(i)->fileURL().path());
|
||||
m_fileWatcher.removeFile(clip->fileURL().path());
|
||||
}
|
||||
DocClipBase *clip = m_clipList.takeAt(i);
|
||||
delete clip;
|
||||
clip = NULL;
|
||||
break;
|
||||
@@ -401,7 +455,7 @@ DocClipBase *ClipManager::getClipById(QString clipId)
|
||||
{
|
||||
//kDebug() << "++++ CLIP MAN, LOOKING FOR CLIP ID: " << clipId;
|
||||
clipId = clipId.section('_', 0, 0);
|
||||
for (int i = 0; i < m_clipList.count(); i++) {
|
||||
for (int i = 0; i < m_clipList.count(); ++i) {
|
||||
if (m_clipList.at(i)->getId() == clipId) {
|
||||
//kDebug() << "++++ CLIP MAN, FOUND FOR CLIP ID: " << clipId;
|
||||
return m_clipList.at(i);
|
||||
@@ -410,12 +464,12 @@ DocClipBase *ClipManager::getClipById(QString clipId)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const QList <DocClipBase *> ClipManager::getClipByResource(QString resource)
|
||||
const QList <DocClipBase *> ClipManager::getClipByResource(const QString &resource)
|
||||
{
|
||||
QList <DocClipBase *> list;
|
||||
QString clipResource;
|
||||
QString proxyResource;
|
||||
for (int i = 0; i < m_clipList.count(); i++) {
|
||||
for (int i = 0; i < m_clipList.count(); ++i) {
|
||||
clipResource = m_clipList.at(i)->getProperty("resource");
|
||||
proxyResource = m_clipList.at(i)->getProperty("proxy");
|
||||
if (clipResource.isEmpty()) clipResource = m_clipList.at(i)->getProperty("colour");
|
||||
@@ -429,14 +483,14 @@ const QList <DocClipBase *> ClipManager::getClipByResource(QString resource)
|
||||
|
||||
void ClipManager::clearUnusedProducers()
|
||||
{
|
||||
for (int i = 0; i < m_clipList.count(); i++) {
|
||||
for (int i = 0; i < m_clipList.count(); ++i) {
|
||||
if (m_clipList.at(i)->numReferences() == 0) m_clipList.at(i)->deleteProducers();
|
||||
}
|
||||
}
|
||||
|
||||
void ClipManager::resetProducersList(const QList <Mlt::Producer *> prods, bool displayRatioChanged, bool fpsChanged)
|
||||
{
|
||||
for (int i = 0; i < m_clipList.count(); i++) {
|
||||
for (int i = 0; i < m_clipList.count(); ++i) {
|
||||
if (m_clipList.at(i)->numReferences() > 0 || displayRatioChanged || fpsChanged) {
|
||||
m_clipList.at(i)->deleteProducers();
|
||||
}
|
||||
@@ -444,7 +498,7 @@ void ClipManager::resetProducersList(const QList <Mlt::Producer *> prods, bool d
|
||||
QString id;
|
||||
Mlt::Producer *prod;
|
||||
QStringList brokenClips;
|
||||
for (int i = 0; i < prods.count(); i++) {
|
||||
for (int i = 0; i < prods.count(); ++i) {
|
||||
prod = prods.at(i);
|
||||
id = prod->get("id");
|
||||
if (id.contains('_')) id = id.section('_', 0, 0);
|
||||
@@ -462,15 +516,47 @@ void ClipManager::resetProducersList(const QList <Mlt::Producer *> prods, bool d
|
||||
emit checkAllClips(displayRatioChanged, fpsChanged, brokenClips);
|
||||
}
|
||||
|
||||
void ClipManager::slotAddClipList(const KUrl::List urls, const QString &group, const QString &groupId, const QString &comment)
|
||||
void ClipManager::slotAddClip(KIO::Job *job, const KUrl &, const KUrl &dst)
|
||||
{
|
||||
KIO::MetaData meta = job->metaData();
|
||||
QMap <QString, QString> data;
|
||||
data.insert("group", meta.value("group"));
|
||||
data.insert("groupid", meta.value("groupid"));
|
||||
data.insert("comment", meta.value("comment"));
|
||||
kDebug()<<"Finished copying: "<<dst<<" / "<<meta.value("group")<<" / "<<meta.value("groupid");
|
||||
slotAddClipList(KUrl::List () << dst, data);
|
||||
}
|
||||
|
||||
void ClipManager::slotAddClipList(const KUrl::List &urls, const QMap <QString, QString> &data)
|
||||
{
|
||||
QUndoCommand *addClips = new QUndoCommand();
|
||||
// Update list of removable volumes
|
||||
//TODO: update only when new volume is plugged / unplugged
|
||||
listRemovableVolumes();
|
||||
foreach(const KUrl & file, urls) {
|
||||
if (QFile::exists(file.path())) {//KIO::NetAccess::exists(file, KIO::NetAccess::SourceSide, NULL)) {
|
||||
if (!getClipByResource(file.path()).empty()) {
|
||||
if (!data.contains("bypassDuplicate") && !getClipByResource(file.path()).empty()) {
|
||||
if (KMessageBox::warningContinueCancel(kapp->activeWindow(), i18n("Clip <b>%1</b><br />already exists in project, what do you want to do?", file.path()), i18n("Clip already exists")) == KMessageBox::Cancel)
|
||||
continue;
|
||||
}
|
||||
if (isOnRemovableDevice(file)) {
|
||||
int answer = KMessageBox::warningYesNoCancel(kapp->activeWindow(), i18n("Clip <b>%1</b><br /> is on a removable device, will not be available when device is unplugged", file.path()), i18n("File on a Removable Device"), KGuiItem(i18n("Copy file to project folder")), KGuiItem(i18n("Continue")), KStandardGuiItem::cancel(), QString("copyFilesToProjectFolder"));
|
||||
if (answer == KMessageBox::Cancel) continue;
|
||||
else if (answer == KMessageBox::Yes) {
|
||||
// Copy files to project folder
|
||||
QString sourcesFolder = m_doc->projectFolder().path(KUrl::AddTrailingSlash) + "clips/";
|
||||
KIO::NetAccess::mkdir(sourcesFolder, kapp->activeWindow());
|
||||
//KIO::filesize_t m_requestedSize;
|
||||
KIO::CopyJob *copyjob = KIO::copy (file, KUrl(sourcesFolder));
|
||||
//TODO: for some reason, passing metadata does not work...
|
||||
copyjob->addMetaData("group", data.value("group"));
|
||||
copyjob->addMetaData("groupId", data.value("groupId"));
|
||||
copyjob->addMetaData("comment", data.value("comment"));
|
||||
copyjob->ui()->setWindow(kapp->activeWindow());
|
||||
connect(copyjob, SIGNAL(copyingDone(KIO::Job*,KUrl,KUrl,time_t,bool,bool)), this, SLOT(slotAddClip(KIO::Job*,KUrl,KUrl)));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
kDebug() << "Adding clip: " << file.path();
|
||||
QDomDocument doc;
|
||||
QDomElement prod = doc.createElement("producer");
|
||||
@@ -478,23 +564,31 @@ void ClipManager::slotAddClipList(const KUrl::List urls, const QString &group, c
|
||||
prod.setAttribute("resource", file.path());
|
||||
uint id = m_clipIdCounter++;
|
||||
prod.setAttribute("id", QString::number(id));
|
||||
if (!comment.isEmpty()) prod.setAttribute("description", comment);
|
||||
if (!group.isEmpty()) {
|
||||
prod.setAttribute("groupname", group);
|
||||
prod.setAttribute("groupid", groupId);
|
||||
if (data.contains("comment")) prod.setAttribute("description", data.value("comment"));
|
||||
if (data.contains("group")) {
|
||||
prod.setAttribute("groupname", data.value("group"));
|
||||
prod.setAttribute("groupid", data.value("groupId"));
|
||||
}
|
||||
if (data.contains("video_index")) prod.setAttribute("video_index", data.value("video_index"));
|
||||
if (data.contains("audio_index")) prod.setAttribute("audio_index", data.value("audio_index"));
|
||||
|
||||
KMimeType::Ptr type = KMimeType::findByUrl(file);
|
||||
if (type->name().startsWith("image/")) {
|
||||
prod.setAttribute("type", (int) IMAGE);
|
||||
prod.setAttribute("in", 0);
|
||||
prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::image_duration()));
|
||||
prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::image_duration()) - 1);
|
||||
if (KdenliveSettings::autoimagetransparency()) prod.setAttribute("transparency", 1);
|
||||
// Read EXIF metadata for JPEG
|
||||
if (type->is("image/jpeg")) {
|
||||
KFileMetaInfo metaInfo(file.path(), QString("image/jpeg"), KFileMetaInfo::TechnicalInfo);
|
||||
const QHash<QString, KFileMetaInfoItem> metaInfoItems = metaInfo.items();
|
||||
foreach(const KFileMetaInfoItem & metaInfoItem, metaInfoItems) {
|
||||
prod.setAttribute("meta.attr." + metaInfoItem.name().section("#", 1), metaInfoItem.value().toString());
|
||||
QDomElement meta = doc.createElement("metaproperty");
|
||||
meta.setAttribute("name", "meta.attr." + metaInfoItem.name().section('#', 1));
|
||||
QDomText value = doc.createTextNode(metaInfoItem.value().toString());
|
||||
meta.setAttribute("tool", "KDE Metadata");
|
||||
meta.appendChild(value);
|
||||
prod.appendChild(meta);
|
||||
}
|
||||
}
|
||||
} else if (type->is("application/x-kdenlivetitle")) {
|
||||
@@ -506,7 +600,7 @@ void ClipManager::slotAddClipList(const KUrl::List urls, const QString &group, c
|
||||
prod.setAttribute("type", (int) TEXT);
|
||||
// extract embeded images
|
||||
QDomNodeList items = txtdoc.elementsByTagName("content");
|
||||
for (int i = 0; i < items.count() ; i++) {
|
||||
for (int i = 0; i < items.count() ; ++i) {
|
||||
QDomElement content = items.item(i).toElement();
|
||||
if (content.hasAttribute("base64")) {
|
||||
QString titlesFolder = m_doc->projectFolder().path(KUrl::AddTrailingSlash) + "titles/";
|
||||
@@ -517,15 +611,23 @@ void ClipManager::slotAddClipList(const KUrl::List urls, const QString &group, c
|
||||
}
|
||||
}
|
||||
}
|
||||
QString titleData = txtdoc.toString();
|
||||
prod.setAttribute("xmldata", titleData);
|
||||
prod.setAttribute("transparency", 1);
|
||||
prod.setAttribute("in", 0);
|
||||
int out = txtdoc.documentElement().attribute("out").toInt();
|
||||
if (out > 0)
|
||||
prod.setAttribute("out", out);
|
||||
else
|
||||
prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::title_duration()));
|
||||
if (!txtdoc.documentElement().hasAttribute("out")) {
|
||||
prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::title_duration()) - 1);
|
||||
txtdoc.documentElement().setAttribute("out", m_doc->getFramePos(KdenliveSettings::title_duration()) - 1);
|
||||
}
|
||||
else {
|
||||
int out = txtdoc.documentElement().attribute("out").toInt();
|
||||
if (out >= 0)
|
||||
prod.setAttribute("out", out);
|
||||
else {
|
||||
prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::title_duration()) - 1);
|
||||
txtdoc.documentElement().setAttribute("out", m_doc->getFramePos(KdenliveSettings::title_duration()) - 1);
|
||||
}
|
||||
}
|
||||
QString titleData = txtdoc.toString();
|
||||
prod.setAttribute("xmldata", titleData);
|
||||
} else
|
||||
txtfile.close();
|
||||
}
|
||||
@@ -539,9 +641,9 @@ void ClipManager::slotAddClipList(const KUrl::List urls, const QString &group, c
|
||||
}
|
||||
}
|
||||
|
||||
void ClipManager::slotAddClipFile(const KUrl &url, const QString &group, const QString &groupId, const QString &comment)
|
||||
void ClipManager::slotAddClipFile(const KUrl &url, const QMap <QString, QString> &data)
|
||||
{
|
||||
slotAddClipList(KUrl::List(url), group, groupId, comment);
|
||||
slotAddClipList(KUrl::List(url), data);
|
||||
}
|
||||
|
||||
void ClipManager::slotAddXmlClipFile(const QString &name, const QDomElement &xml, const QString &group, const QString &groupId)
|
||||
@@ -561,7 +663,7 @@ void ClipManager::slotAddXmlClipFile(const QString &name, const QDomElement &xml
|
||||
m_doc->commandStack()->push(command);
|
||||
}
|
||||
|
||||
void ClipManager::slotAddColorClipFile(const QString &name, const QString &color, QString duration, const QString &group, const QString &groupId)
|
||||
void ClipManager::slotAddColorClipFile(const QString &name, const QString &color, const QString &duration, const QString &group, const QString &groupId)
|
||||
{
|
||||
QDomDocument doc;
|
||||
QDomElement prod = doc.createElement("producer");
|
||||
@@ -572,7 +674,7 @@ void ClipManager::slotAddColorClipFile(const QString &name, const QString &color
|
||||
uint id = m_clipIdCounter++;
|
||||
prod.setAttribute("id", QString::number(id));
|
||||
prod.setAttribute("in", "0");
|
||||
prod.setAttribute("out", m_doc->getFramePos(duration));
|
||||
prod.setAttribute("out", m_doc->getFramePos(duration) - 1);
|
||||
prod.setAttribute("name", name);
|
||||
if (!group.isEmpty()) {
|
||||
prod.setAttribute("groupname", group);
|
||||
@@ -604,7 +706,7 @@ void ClipManager::slotAddSlideshowClipFile(QMap <QString, QString> properties, c
|
||||
|
||||
|
||||
|
||||
void ClipManager::slotAddTextClipFile(const QString &titleName, int out, const QString &xml, const QString &group, const QString &groupId)
|
||||
void ClipManager::slotAddTextClipFile(const QString &titleName, int duration, const QString &xml, const QString &group, const QString &groupId)
|
||||
{
|
||||
QDomDocument doc;
|
||||
QDomElement prod = doc.createElement("producer");
|
||||
@@ -621,7 +723,7 @@ void ClipManager::slotAddTextClipFile(const QString &titleName, int out, const Q
|
||||
prod.setAttribute("type", (int) TEXT);
|
||||
prod.setAttribute("transparency", "1");
|
||||
prod.setAttribute("in", "0");
|
||||
prod.setAttribute("out", out);
|
||||
prod.setAttribute("out", duration - 1);
|
||||
AddClipCommand *command = new AddClipCommand(m_doc, doc.documentElement(), QString::number(id), true);
|
||||
m_doc->commandStack()->push(command);
|
||||
}
|
||||
@@ -643,16 +745,22 @@ void ClipManager::slotAddTextTemplateClip(QString titleName, const KUrl &path, c
|
||||
prod.setAttribute("transparency", "1");
|
||||
prod.setAttribute("in", "0");
|
||||
|
||||
int out = 0;
|
||||
int duration = 0;
|
||||
QDomDocument titledoc;
|
||||
QFile txtfile(path.path());
|
||||
if (txtfile.open(QIODevice::ReadOnly) && titledoc.setContent(&txtfile)) {
|
||||
txtfile.close();
|
||||
out = titledoc.documentElement().attribute("out").toInt();
|
||||
if (titledoc.documentElement().hasAttribute("duration")) {
|
||||
duration = titledoc.documentElement().attribute("duration").toInt();
|
||||
}
|
||||
else {
|
||||
// keep some time for backwards compatibility - 26/12/12
|
||||
duration = titledoc.documentElement().attribute("out").toInt();
|
||||
}
|
||||
} else txtfile.close();
|
||||
|
||||
if (out == 0) out = m_doc->getFramePos(KdenliveSettings::image_duration());
|
||||
prod.setAttribute("out", out);
|
||||
if (duration == 0) duration = m_doc->getFramePos(KdenliveSettings::title_duration());
|
||||
prod.setAttribute("out", duration - 1);
|
||||
|
||||
AddClipCommand *command = new AddClipCommand(m_doc, doc.documentElement(), QString::number(id), true);
|
||||
m_doc->commandStack()->push(command);
|
||||
@@ -705,7 +813,7 @@ QDomElement ClipManager::groupsXml() const
|
||||
QDomDocument doc;
|
||||
QDomElement groups = doc.createElement("groups");
|
||||
doc.appendChild(groups);
|
||||
for (int i = 0; i < m_groupsList.count(); i++) {
|
||||
for (int i = 0; i < m_groupsList.count(); ++i) {
|
||||
QDomElement group = doc.createElement("group");
|
||||
groups.appendChild(group);
|
||||
QList <QGraphicsItem *> children = m_groupsList.at(i)->childItems();
|
||||
@@ -735,7 +843,7 @@ void ClipManager::slotClipModified(const QString &path)
|
||||
{
|
||||
//kDebug() << "// CLIP: " << path << " WAS MODIFIED";
|
||||
const QList <DocClipBase *> list = getClipByResource(path);
|
||||
for (int i = 0; i < list.count(); i++) {
|
||||
for (int i = 0; i < list.count(); ++i) {
|
||||
DocClipBase *clip = list.at(i);
|
||||
if (clip != NULL) {
|
||||
QString id = clip->getId();
|
||||
@@ -767,7 +875,7 @@ void ClipManager::slotClipMissing(const QString &path)
|
||||
{
|
||||
// kDebug() << "// CLIP: " << path << " WAS MISSING";
|
||||
const QList <DocClipBase *> list = getClipByResource(path);
|
||||
for (int i = 0; i < list.count(); i++) {
|
||||
for (int i = 0; i < list.count(); ++i) {
|
||||
DocClipBase *clip = list.at(i);
|
||||
if (clip != NULL) emit missingClip(clip->getId());
|
||||
}
|
||||
@@ -777,7 +885,7 @@ void ClipManager::slotClipAvailable(const QString &path)
|
||||
{
|
||||
// kDebug() << "// CLIP: " << path << " WAS ADDED";
|
||||
const QList <DocClipBase *> list = getClipByResource(path);
|
||||
for (int i = 0; i < list.count(); i++) {
|
||||
for (int i = 0; i < list.count(); ++i) {
|
||||
DocClipBase *clip = list.at(i);
|
||||
if (clip != NULL) emit availableClip(clip->getId());
|
||||
}
|
||||
@@ -789,3 +897,101 @@ int ClipManager::clipsCount() const
|
||||
}
|
||||
|
||||
|
||||
void ClipManager::listRemovableVolumes()
|
||||
{
|
||||
QList<SolidVolumeInfo> volumes;
|
||||
m_removableVolumes.clear();
|
||||
|
||||
QList<Solid::Device> devices = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
|
||||
|
||||
foreach(const Solid::Device &accessDevice, devices)
|
||||
{
|
||||
// check for StorageAccess
|
||||
if (!accessDevice.is<Solid::StorageAccess>())
|
||||
continue;
|
||||
|
||||
const Solid::StorageAccess *access = accessDevice.as<Solid::StorageAccess>();
|
||||
|
||||
if (!access->isAccessible())
|
||||
continue;
|
||||
|
||||
// check for StorageDrive
|
||||
Solid::Device driveDevice;
|
||||
for (Solid::Device currentDevice = accessDevice; currentDevice.isValid(); currentDevice = currentDevice.parent())
|
||||
{
|
||||
if (currentDevice.is<Solid::StorageDrive>())
|
||||
{
|
||||
driveDevice = currentDevice;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!driveDevice.isValid())
|
||||
continue;
|
||||
|
||||
Solid::StorageDrive *drive = driveDevice.as<Solid::StorageDrive>();
|
||||
if (!drive->isRemovable()) continue;
|
||||
|
||||
// check for StorageVolume
|
||||
Solid::Device volumeDevice;
|
||||
for (Solid::Device currentDevice = accessDevice; currentDevice.isValid(); currentDevice = currentDevice.parent())
|
||||
{
|
||||
if (currentDevice.is<Solid::StorageVolume>())
|
||||
{
|
||||
volumeDevice = currentDevice;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!volumeDevice.isValid())
|
||||
continue;
|
||||
|
||||
Solid::StorageVolume *volume = volumeDevice.as<Solid::StorageVolume>();
|
||||
|
||||
SolidVolumeInfo info;
|
||||
info.path = access->filePath();
|
||||
info.isMounted = access->isAccessible();
|
||||
if (!info.path.isEmpty() && !info.path.endsWith('/'))
|
||||
info.path += '/';
|
||||
info.uuid = volume->uuid();
|
||||
info.label = volume->label();
|
||||
info.isRemovable = drive->isRemovable();
|
||||
m_removableVolumes << info;
|
||||
}
|
||||
}
|
||||
|
||||
bool ClipManager::isOnRemovableDevice(const KUrl &url)
|
||||
{
|
||||
SolidVolumeInfo volume;
|
||||
QString path = url.path(KUrl::RemoveTrailingSlash);
|
||||
int volumeMatch = 0;
|
||||
|
||||
//FIXME: Network shares! Here we get only the volume of the mount path...
|
||||
// This is probably not really clean. But Solid does not help us.
|
||||
foreach (const SolidVolumeInfo &v, m_removableVolumes)
|
||||
{
|
||||
if (v.isMounted && !v.path.isEmpty() && path.startsWith(v.path))
|
||||
{
|
||||
int length = v.path.length();
|
||||
if (length > volumeMatch)
|
||||
{
|
||||
volumeMatch = v.path.length();
|
||||
volume = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return volumeMatch;
|
||||
}
|
||||
|
||||
void ClipManager::projectTreeThumbReady(const QString &id, int frame, const QImage &img, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case 2:
|
||||
emit gotClipPropertyThumbnail(id, img);
|
||||
break;
|
||||
default:
|
||||
emit thumbReady(id, frame, img);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include "clipmanager.moc"
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <KDirWatch>
|
||||
#include <klocale.h>
|
||||
#include <kdeversion.h>
|
||||
#include <KIO/CopyJob>
|
||||
|
||||
#if KDE_IS_VERSION(4,5,0)
|
||||
#include <KImageCache>
|
||||
@@ -52,10 +53,24 @@ class KdenliveDoc;
|
||||
class DocClipBase;
|
||||
class AbstractGroupItem;
|
||||
|
||||
|
||||
class SolidVolumeInfo
|
||||
{
|
||||
|
||||
public:
|
||||
QString path; // mount path of volume, with trailing slash
|
||||
QString uuid; // UUID as from Solid
|
||||
QString label; // volume label (think of CDs)
|
||||
bool isRemovable; // may be removed
|
||||
bool isMounted;
|
||||
|
||||
bool isNull() const { return path.isNull(); }
|
||||
};
|
||||
|
||||
namespace Mlt
|
||||
{
|
||||
class Producer;
|
||||
};
|
||||
}
|
||||
|
||||
class ClipManager: public QObject
|
||||
{
|
||||
@@ -72,21 +87,21 @@ Q_OBJECT public:
|
||||
* @param url file to add
|
||||
* @param group name of the group to insert the file in (can be empty)
|
||||
* @param groupId id of the group (if any) */
|
||||
void slotAddClipFile(const KUrl &url, const QString &group, const QString &groupId, const QString &comment = QString());
|
||||
void slotAddClipFile(const KUrl &url, const QMap<QString, QString> &data);
|
||||
|
||||
/** @brief Adds a list of files to the project.
|
||||
* @param urls files to add
|
||||
* @param group name of the group to insert the files in (can be empty)
|
||||
* @param groupId id of the group (if any)
|
||||
* It checks for duplicated items and asks to the user for instructions. */
|
||||
void slotAddClipList(const KUrl::List urls, const QString &group, const QString &groupId, const QString &comment = QString());
|
||||
void slotAddClipList(const KUrl::List &urls, const QMap<QString, QString> &data);
|
||||
void slotAddTextClipFile(const QString &titleName, int out, const QString &xml, const QString &group, const QString &groupId);
|
||||
void slotAddTextTemplateClip(QString titleName, const KUrl &path, const QString &group, const QString &groupId);
|
||||
void slotAddXmlClipFile(const QString &name, const QDomElement &xml, const QString &group, const QString &groupId);
|
||||
void slotAddColorClipFile(const QString &name, const QString &color, QString duration, const QString &group, const QString &groupId);
|
||||
void slotAddColorClipFile(const QString &name, const QString &color, const QString &duration, const QString &group, const QString &groupId);
|
||||
void slotAddSlideshowClipFile(QMap <QString, QString> properties, const QString &group, const QString &groupId);
|
||||
DocClipBase *getClipById(QString clipId);
|
||||
const QList <DocClipBase *> getClipByResource(QString resource);
|
||||
const QList <DocClipBase *> getClipByResource(const QString &resource);
|
||||
void slotDeleteClips(QStringList ids);
|
||||
void setThumbsProgress(const QString &message, int progress);
|
||||
void checkAudioThumbs();
|
||||
@@ -107,15 +122,18 @@ Q_OBJECT public:
|
||||
void removeGroup(AbstractGroupItem *group);
|
||||
QDomElement groupsXml() const;
|
||||
int clipsCount() const;
|
||||
/** @brief Request creation of a clip thumbnail for specified frames. */
|
||||
void requestThumbs(const QString id, QList <int> frames);
|
||||
/** @brief remove a clip id from the queue list. */
|
||||
void stopThumbs(const QString &id);
|
||||
void projectTreeThumbReady(const QString &id, int frame, const QImage &img, int type);
|
||||
|
||||
#if KDE_IS_VERSION(4,5,0)
|
||||
KImageCache* pixmapCache;
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
/** @brief Request creation of a clip thumbnail for specified frames. */
|
||||
void slotRequestThumbs(const QString &id, const QList<int> &frames);
|
||||
|
||||
private slots:
|
||||
/** A clip was externally modified, monitor for more changes and prepare for reload */
|
||||
void slotClipModified(const QString &path);
|
||||
@@ -125,6 +143,8 @@ private slots:
|
||||
void slotProcessModifiedClips();
|
||||
void slotGetThumbs();
|
||||
void slotGetAudioThumbs();
|
||||
/** @brief Clip has been copied, add it now. */
|
||||
void slotAddClip(KIO::Job *job, const KUrl &, const KUrl &dst);
|
||||
|
||||
private: // Private attributes
|
||||
/** the list of clips in the document */
|
||||
@@ -157,14 +177,25 @@ private: // Private attributes
|
||||
bool m_abortAudioThumb;
|
||||
/** @brief The id of currently processed clip for audio thumbs creation. */
|
||||
QString m_processingAudioThumbId;
|
||||
/** @brief The list of removable drives. */
|
||||
QList<SolidVolumeInfo> m_removableVolumes;
|
||||
|
||||
QPoint m_projectTreeThumbSize;
|
||||
|
||||
/** @brief Get a list of drives, to check if we have files on removable media. */
|
||||
void listRemovableVolumes();
|
||||
/** @brief Check if added file is on a removable drive. */
|
||||
bool isOnRemovableDevice(const KUrl &url);
|
||||
|
||||
signals:
|
||||
void reloadClip(const QString &);
|
||||
void modifiedClip(const QString &);
|
||||
void missingClip(const QString &);
|
||||
void availableClip(const QString &);
|
||||
void checkAllClips(bool displayRatioChanged, bool fpsChanged, QStringList brokenClips);
|
||||
void checkAllClips(bool displayRatioChanged, bool fpsChanged, const QStringList &brokenClips);
|
||||
void displayMessage(const QString &, int);
|
||||
void thumbReady(const QString &id, int, const QImage&);
|
||||
void gotClipPropertyThumbnail(const QString &id, const QImage&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <KStandardDirs>
|
||||
#include <KDebug>
|
||||
#include <KFileItem>
|
||||
#include <KFileDialog>
|
||||
#include <kdeversion.h>
|
||||
#include <KUrlLabel>
|
||||
#include <KRun>
|
||||
@@ -39,9 +40,17 @@
|
||||
#include <Nepomuk/Vocabulary/NIE>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef USE_NEPOMUKCORE
|
||||
#include <Nepomuk2/Variant>
|
||||
#include <Nepomuk2/Resource>
|
||||
#include <Nepomuk2/ResourceManager>
|
||||
#include <Nepomuk2/Vocabulary/NIE>
|
||||
#endif
|
||||
|
||||
|
||||
#include <QDir>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
static const int VIDEOTAB = 0;
|
||||
static const int AUDIOTAB = 1;
|
||||
@@ -53,14 +62,15 @@ static const int METATAB = 6;
|
||||
static const int ADVANCEDTAB = 7;
|
||||
|
||||
|
||||
ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidget * parent) :
|
||||
QDialog(parent),
|
||||
m_clip(clip),
|
||||
m_tc(tc),
|
||||
m_fps(fps),
|
||||
m_count(0),
|
||||
m_clipNeedsRefresh(false),
|
||||
m_clipNeedsReLoad(false)
|
||||
ClipProperties::ClipProperties(DocClipBase *clip, const Timecode &tc, double fps, QWidget * parent) :
|
||||
QDialog(parent)
|
||||
, m_clip(clip)
|
||||
, m_tc(tc)
|
||||
, m_fps(fps)
|
||||
, m_count(0)
|
||||
, m_clipNeedsRefresh(false)
|
||||
, m_clipNeedsReLoad(false)
|
||||
, m_proxyContainer(NULL)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
setFont(KGlobalSettings::toolBarFont());
|
||||
@@ -81,7 +91,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
|
||||
// New display aspect ratio support
|
||||
if (props.contains("force_aspect_num") && props.value("force_aspect_num").toInt() > 0 &&
|
||||
props.contains("force_aspect_den") && props.value("force_aspect_den").toInt() > 0) {
|
||||
props.contains("force_aspect_den") && props.value("force_aspect_den").toInt() > 0) {
|
||||
m_view.clip_force_ar->setChecked(true);
|
||||
m_view.clip_ar_num->setEnabled(true);
|
||||
m_view.clip_ar_den->setEnabled(true);
|
||||
@@ -121,14 +131,16 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
}
|
||||
connect(m_view.clip_force_framerate, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
|
||||
connect(m_view.clip_framerate, SIGNAL(valueChanged(double)), this, SLOT(slotModified()));
|
||||
m_view.clip_progressive->addItem(i18n("Interlaced"), 0);
|
||||
m_view.clip_progressive->addItem(i18n("Progressive"), 1);
|
||||
|
||||
if (props.contains("force_progressive")) {
|
||||
m_view.clip_force_progressive->setChecked(true);
|
||||
m_view.clip_progressive->setEnabled(true);
|
||||
m_view.clip_progressive->setValue(props.value("force_progressive").toInt());
|
||||
m_view.clip_progressive->setCurrentIndex(props.value("force_progressive").toInt());
|
||||
}
|
||||
connect(m_view.clip_force_progressive, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
|
||||
connect(m_view.clip_progressive, SIGNAL(valueChanged(int)), this, SLOT(slotModified()));
|
||||
connect(m_view.clip_progressive, SIGNAL(currentIndexChanged(int)), this, SLOT(slotModified()));
|
||||
|
||||
m_view.clip_fieldorder->addItem(i18n("Bottom first"), 0);
|
||||
m_view.clip_fieldorder->addItem(i18n("Top first"), 1);
|
||||
@@ -191,12 +203,45 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
connect(m_view.clip_full_luma, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
|
||||
|
||||
// Check for Metadata
|
||||
QMap<QString, QString> meta = m_clip->metadata();
|
||||
QMap<QString, QString>::const_iterator i = meta.constBegin();
|
||||
QMap<QString, QStringList> meta = m_clip->metadata();
|
||||
QMap<QString, QStringList>::const_iterator i = meta.constBegin();
|
||||
while (i != meta.constEnd()) {
|
||||
QTreeWidgetItem *metaitem = new QTreeWidgetItem(m_view.metadata_list);
|
||||
QStringList values = i.value();
|
||||
QString parentName;
|
||||
QString iconName;
|
||||
if (values.count() > 1 && !values.at(1).isEmpty()) {
|
||||
parentName = values.at(1);
|
||||
} else {
|
||||
if (KdenliveSettings::ffmpegpath().endsWith("avconv")) {
|
||||
parentName = i18n("Libav");
|
||||
iconName = "meta_libav.png";
|
||||
}
|
||||
else {
|
||||
parentName = i18n("FFmpeg");
|
||||
iconName = "meta_ffmpeg.png";
|
||||
}
|
||||
}
|
||||
QTreeWidgetItem *parent = NULL;
|
||||
QList <QTreeWidgetItem *> matches = m_view.metadata_list->findItems(parentName, Qt::MatchExactly);
|
||||
if (!matches.isEmpty()) {
|
||||
parent = matches.at(0);
|
||||
} else {
|
||||
if (parentName == "Magic Lantern")
|
||||
iconName = "meta_magiclantern.png";
|
||||
parent = new QTreeWidgetItem(m_view.metadata_list, QStringList() << parentName);
|
||||
if (!iconName.isEmpty()) {
|
||||
KIcon icon(KStandardDirs::locate("appdata", iconName));
|
||||
parent->setIcon(0, icon);
|
||||
}
|
||||
}
|
||||
QTreeWidgetItem *metaitem = NULL;
|
||||
if (parent) {
|
||||
metaitem = new QTreeWidgetItem(parent);
|
||||
parent->setExpanded(true);
|
||||
}
|
||||
else metaitem = new QTreeWidgetItem(m_view.metadata_list);
|
||||
metaitem->setText(0, i.key()); //i18n(i.key().section('.', 2, 3).toUtf8().data()));
|
||||
metaitem->setText(1, i.value());
|
||||
metaitem->setText(1, values.at(0));
|
||||
++i;
|
||||
}
|
||||
|
||||
@@ -230,7 +275,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
m_proxyContainer = new QFrame();
|
||||
m_proxyContainer->setFrameShape(QFrame::NoFrame);
|
||||
QHBoxLayout *l = new QHBoxLayout;
|
||||
l->addWidget(new QLabel(i18n("Proxy clip: %1").arg(KIO::convertSize(f.size()))));
|
||||
l->addWidget(new QLabel(i18n("Proxy clip: %1", KIO::convertSize(f.size()))));
|
||||
l->addStretch(5);
|
||||
QPushButton *pb = new QPushButton(i18n("Delete proxy"));
|
||||
l->addWidget(pb);
|
||||
@@ -258,6 +303,9 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
m_view.clip_force_vindex->setEnabled(false);
|
||||
}
|
||||
|
||||
if (t == PLAYLIST)
|
||||
m_view.tabWidget->setTabText(VIDEOTAB, i18n("Playlist"));
|
||||
|
||||
if (t == IMAGE) {
|
||||
m_view.tabWidget->removeTab(SLIDETAB);
|
||||
m_view.tabWidget->removeTab(COLORTAB);
|
||||
@@ -269,7 +317,8 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
m_view.image_transparency->setChecked(props.value("transparency").toInt());
|
||||
connect(m_view.image_transparency, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
|
||||
int width = 180.0 * KdenliveSettings::project_display_ratio();
|
||||
if (width % 2 == 1) width++;
|
||||
if (width % 2 == 1)
|
||||
width++;
|
||||
m_view.clip_thumb->setPixmap(QPixmap(url.path()).scaled(QSize(width, 180), Qt::KeepAspectRatio));
|
||||
} else if (t == COLOR) {
|
||||
m_view.clip_path->setEnabled(false);
|
||||
@@ -282,7 +331,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
m_view.clip_color->setColor(QColor('#' + props.value("colour").right(8).left(6)));
|
||||
connect(m_view.clip_color, SIGNAL(changed(QColor)), this, SLOT(slotModified()));
|
||||
} else if (t == SLIDESHOW) {
|
||||
if (url.fileName().startsWith(".all.")) {
|
||||
if (url.fileName().startsWith(QLatin1String(".all."))) {
|
||||
// the image sequence is defined by mimetype
|
||||
m_view.clip_path->setText(url.directory());
|
||||
} else {
|
||||
@@ -326,7 +375,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
m_view.animation->setCurrentIndex(0);
|
||||
QString path = props.value("resource");
|
||||
QString ext = path.section('.', -1);
|
||||
for (int i = 0; i < m_view.image_type->count(); i++) {
|
||||
for (int i = 0; i < m_view.image_type->count(); ++i) {
|
||||
if (m_view.image_type->itemData(i).toString() == ext) {
|
||||
m_view.image_type->setCurrentIndex(i);
|
||||
break;
|
||||
@@ -340,7 +389,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
m_view.slide_duration_frames->setHidden(true);
|
||||
m_view.luma_duration_frames->setHidden(true);
|
||||
|
||||
parseFolder();
|
||||
parseFolder(false);
|
||||
|
||||
m_view.luma_duration->setText(tc.getTimecodeFromFrames(props.value("luma_duration").toInt()));
|
||||
QString lumaFile = props.value("luma_file");
|
||||
@@ -403,39 +452,12 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
m_view.clip_aproperties->setItemDelegate(del2);
|
||||
m_view.clip_aproperties->setStyleSheet(QString("QTreeWidget { background-color: transparent;}"));
|
||||
m_view.clip_vproperties->setStyleSheet(QString("QTreeWidget { background-color: transparent;}"));
|
||||
loadVideoProperties(props);
|
||||
|
||||
if (props.contains("videocodec"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Video codec") << props.value("videocodec"));
|
||||
m_view.clip_thumb->setMinimumSize(180 * KdenliveSettings::project_display_ratio(), 180);
|
||||
|
||||
if (props.contains("frame_size"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Frame size") << props.value("frame_size"));
|
||||
|
||||
if (props.contains("fps")) {
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Frame rate") << props.value("fps"));
|
||||
if (!m_view.clip_framerate->isEnabled()) m_view.clip_framerate->setValue(props.value("fps").toDouble());
|
||||
}
|
||||
|
||||
if (props.contains("progressive")) {
|
||||
int scanning = props.value("progressive").toInt();
|
||||
QString txt = scanning == 1 ? i18n("Progressive") : i18n("Interlaced");
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Scanning") << txt);
|
||||
}
|
||||
|
||||
if (props.contains("aspect_ratio"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Pixel aspect ratio") << props.value("aspect_ratio"));
|
||||
|
||||
if (props.contains("pix_fmt"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Pixel format") << props.value("pix_fmt"));
|
||||
|
||||
if (props.contains("colorspace"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Colorspace") << ProfilesDialog::getColorspaceDescription(props.value("colorspace").toInt()));
|
||||
|
||||
|
||||
int width = 180.0 * KdenliveSettings::project_display_ratio();
|
||||
if (width % 2 == 1) width++;
|
||||
QPixmap pix = m_clip->thumbProducer()->getImage(url, m_clip->getClipThumbFrame(), width, 180);
|
||||
m_view.clip_thumb->setPixmap(pix);
|
||||
if (t == IMAGE || t == VIDEO) m_view.tabWidget->removeTab(AUDIOTAB);
|
||||
if (t == IMAGE || t == VIDEO || t == PLAYLIST)
|
||||
m_view.tabWidget->removeTab(AUDIOTAB);
|
||||
} else {
|
||||
m_view.tabWidget->removeTab(IMAGETAB);
|
||||
m_view.tabWidget->removeTab(SLIDETAB);
|
||||
@@ -453,8 +475,9 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
}
|
||||
m_view.clip_duration->setInputMask(tc.mask());
|
||||
m_view.clip_duration->setText(tc.getTimecode(m_clip->duration()));
|
||||
if (t != IMAGE && t != COLOR && t != TEXT) m_view.clip_duration->setReadOnly(true);
|
||||
else {
|
||||
if (t != IMAGE && t != COLOR && t != TEXT) {
|
||||
m_view.clip_duration->setReadOnly(true);
|
||||
} else {
|
||||
connect(m_view.clip_duration, SIGNAL(editingFinished()), this, SLOT(slotCheckMaxLength()));
|
||||
connect(m_view.clip_duration, SIGNAL(textChanged(QString)), this, SLOT(slotModified()));
|
||||
}
|
||||
@@ -466,9 +489,20 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
m_view.marker_edit->setToolTip(i18n("Edit marker"));
|
||||
m_view.marker_delete->setIcon(KIcon("trash-empty"));
|
||||
m_view.marker_delete->setToolTip(i18n("Delete marker"));
|
||||
m_view.marker_save->setIcon(KIcon("document-save-as"));
|
||||
m_view.marker_save->setToolTip(i18n("Save markers"));
|
||||
m_view.marker_load->setIcon(KIcon("document-open"));
|
||||
m_view.marker_load->setToolTip(i18n("Load markers"));
|
||||
m_view.analysis_delete->setIcon(KIcon("trash-empty"));
|
||||
m_view.analysis_delete->setToolTip(i18n("Delete analysis data"));
|
||||
m_view.analysis_load->setIcon(KIcon("document-open"));
|
||||
m_view.analysis_load->setToolTip(i18n("Load analysis data"));
|
||||
m_view.analysis_save->setIcon(KIcon("document-save-as"));
|
||||
m_view.analysis_save->setToolTip(i18n("Save analysis data"));
|
||||
|
||||
// Check for Nepomuk metadata
|
||||
// Check for Nepomuk metadata
|
||||
#ifdef USE_NEPOMUK
|
||||
|
||||
#if KDE_IS_VERSION(4,6,0)
|
||||
if (!url.isEmpty()) {
|
||||
Nepomuk::ResourceManager::instance()->init();
|
||||
@@ -479,7 +513,7 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
m_view.clip_license->setText(i18n("License: %1", res.property(Nepomuk::Vocabulary::NIE::license()).toString()));
|
||||
if (ltype.startsWith("http")) {
|
||||
m_view.clip_license->setUrl(ltype);
|
||||
connect(m_view.clip_license, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &)));
|
||||
connect(m_view.clip_license, SIGNAL(leftClickedUrl(QString)), this, SLOT(slotOpenUrl(QString)));
|
||||
}
|
||||
}
|
||||
else m_view.clip_license->setHidden(true);
|
||||
@@ -488,25 +522,59 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg
|
||||
#else
|
||||
m_view.clip_license->setHidden(true);
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_NEPOMUKCORE
|
||||
|
||||
if (!url.isEmpty()) {
|
||||
Nepomuk2::ResourceManager::instance()->init();
|
||||
Nepomuk2::Resource res( url.path() );
|
||||
// Check if file has a license
|
||||
if (res.hasProperty(Nepomuk2::Vocabulary::NIE::license())) {
|
||||
QString ltype = res.property(Nepomuk2::Vocabulary::NIE::licenseType()).toString();
|
||||
m_view.clip_license->setText(i18n("License: %1", res.property(Nepomuk2::Vocabulary::NIE::license()).toString()));
|
||||
if (ltype.startsWith("http")) {
|
||||
m_view.clip_license->setUrl(ltype);
|
||||
connect(m_view.clip_license, SIGNAL(leftClickedUrl(QString)), this, SLOT(slotOpenUrl(QString)));
|
||||
}
|
||||
}
|
||||
else m_view.clip_license->setHidden(true);
|
||||
}
|
||||
else m_view.clip_license->setHidden(true);
|
||||
#else
|
||||
m_view.clip_license->setHidden(true);
|
||||
#endif
|
||||
|
||||
slotFillMarkersList();
|
||||
#endif
|
||||
|
||||
slotFillMarkersList(m_clip);
|
||||
slotUpdateAnalysisData(m_clip);
|
||||
|
||||
connect(m_view.marker_new, SIGNAL(clicked()), this, SLOT(slotAddMarker()));
|
||||
connect(m_view.marker_edit, SIGNAL(clicked()), this, SLOT(slotEditMarker()));
|
||||
connect(m_view.marker_delete, SIGNAL(clicked()), this, SLOT(slotDeleteMarker()));
|
||||
connect(m_view.markers_list, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(slotEditMarker()));
|
||||
connect(m_view.marker_save, SIGNAL(clicked()), this, SLOT(slotSaveMarkers()));
|
||||
connect(m_view.marker_load, SIGNAL(clicked()), this, SLOT(slotLoadMarkers()));
|
||||
connect(m_view.markers_list, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotEditMarker()));
|
||||
|
||||
connect(m_view.analysis_delete, SIGNAL(clicked()), this, SLOT(slotDeleteAnalysis()));
|
||||
connect(m_view.analysis_save, SIGNAL(clicked()), this, SLOT(slotSaveAnalysis()));
|
||||
connect(m_view.analysis_load, SIGNAL(clicked()), this, SLOT(slotLoadAnalysis()));
|
||||
|
||||
connect(this, SIGNAL(accepted()), this, SLOT(slotApplyProperties()));
|
||||
connect(m_view.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(slotApplyProperties()));
|
||||
m_view.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
|
||||
|
||||
m_view.metadata_list->resizeColumnToContents(0);
|
||||
m_view.clip_vproperties->resizeColumnToContents(0);
|
||||
m_view.clip_aproperties->resizeColumnToContents(0);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
|
||||
// Used for multiple clips editing
|
||||
ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap <QString, QString> commonproperties, QWidget * parent) :
|
||||
ClipProperties::ClipProperties(const QList <DocClipBase *> &cliplist, const Timecode &tc, const QMap <QString, QString> &commonproperties, QWidget * parent) :
|
||||
QDialog(parent),
|
||||
m_clip(NULL),
|
||||
m_tc(tc),
|
||||
@@ -518,7 +586,7 @@ ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap
|
||||
setFont(KGlobalSettings::toolBarFont());
|
||||
m_view.setupUi(this);
|
||||
QString title = windowTitle();
|
||||
title.append(" " + i18np("(%1 clip)", "(%1 clips)", cliplist.count()));
|
||||
title.append(' ' + i18np("(%1 clip)", "(%1 clips)", cliplist.count()));
|
||||
setWindowTitle(title);
|
||||
QMap <QString, QString> props = cliplist.at(0)->properties();
|
||||
m_old_props = commonproperties;
|
||||
@@ -540,7 +608,7 @@ ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap
|
||||
if (commonproperties.contains("force_progressive") && !commonproperties.value("force_progressive").isEmpty()) {
|
||||
m_view.clip_force_progressive->setChecked(true);
|
||||
m_view.clip_progressive->setEnabled(true);
|
||||
m_view.clip_progressive->setValue(commonproperties.value("force_progressive").toInt());
|
||||
m_view.clip_progressive->setCurrentIndex(commonproperties.value("force_progressive").toInt());
|
||||
}
|
||||
|
||||
if (commonproperties.contains("force_tff") && !commonproperties.value("force_tff").isEmpty()) {
|
||||
@@ -640,7 +708,9 @@ ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap
|
||||
if (commonproperties.value("out").toInt() > 0) {
|
||||
m_view.clip_force_out->setChecked(true);
|
||||
m_view.clip_out->setText(m_tc.getTimecodeFromFrames(commonproperties.value("out").toInt()));
|
||||
} else m_view.clip_out->setText(KdenliveSettings::image_duration());
|
||||
} else {
|
||||
m_view.clip_out->setText(KdenliveSettings::image_duration());
|
||||
}
|
||||
} else {
|
||||
m_view.clip_force_out->setHidden(true);
|
||||
m_view.clip_out->setHidden(true);
|
||||
@@ -650,9 +720,58 @@ ClipProperties::ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap
|
||||
ClipProperties::~ClipProperties()
|
||||
{
|
||||
QAbstractItemDelegate *del1 = m_view.clip_vproperties->itemDelegate();
|
||||
if (del1) delete del1;
|
||||
delete del1;
|
||||
QAbstractItemDelegate *del2 = m_view.clip_aproperties->itemDelegate();
|
||||
if (del2) delete del2;
|
||||
delete del2;
|
||||
}
|
||||
|
||||
|
||||
void ClipProperties::loadVideoProperties(const QMap <QString, QString> &props)
|
||||
{
|
||||
m_view.clip_vproperties->clear();
|
||||
if (props.contains("videocodec"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Video codec") << props.value("videocodec"));
|
||||
else if (props.contains("videocodecid"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Video codec") << props.value("videocodecid"));
|
||||
|
||||
if (props.contains("frame_size"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Frame size") << props.value("frame_size"));
|
||||
|
||||
if (props.contains("fps")) {
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Frame rate") << props.value("fps"));
|
||||
if (!m_view.clip_framerate->isEnabled()) m_view.clip_framerate->setValue(props.value("fps").toDouble());
|
||||
}
|
||||
|
||||
if (props.contains("progressive")) {
|
||||
int scanning = props.value("progressive").toInt();
|
||||
QString txt = scanning == 1 ? i18n("Progressive") : i18n("Interlaced");
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Scanning") << txt);
|
||||
}
|
||||
|
||||
if (props.contains("aspect_ratio"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Pixel aspect ratio") << props.value("aspect_ratio"));
|
||||
|
||||
if (props.contains("pix_fmt"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Pixel format") << props.value("pix_fmt"));
|
||||
|
||||
if (props.contains("colorspace"))
|
||||
new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Colorspace") << ProfilesDialog::getColorspaceDescription(props.value("colorspace").toInt()));
|
||||
}
|
||||
|
||||
void ClipProperties::slotGotThumbnail(const QString &id, const QImage &img)
|
||||
{
|
||||
if (id != m_clip->getId())
|
||||
return;
|
||||
QPixmap framedPix(img.width(), img.height());
|
||||
framedPix.fill(Qt::transparent);
|
||||
QPainter p(&framedPix);
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(0.5, 0.5, framedPix.width() - 1, framedPix.height() - 1, 4, 4);
|
||||
p.setClipPath(path);
|
||||
p.drawImage(0, 0, img);
|
||||
p.end();
|
||||
m_view.clip_thumb->setPixmap(framedPix);
|
||||
}
|
||||
|
||||
void ClipProperties::slotApplyProperties()
|
||||
@@ -660,10 +779,27 @@ void ClipProperties::slotApplyProperties()
|
||||
if (m_clip != NULL) {
|
||||
QMap <QString, QString> props = properties();
|
||||
emit applyNewClipProperties(m_clip->getId(), m_clip->currentProperties(props), props, needsTimelineRefresh(), needsTimelineReload());
|
||||
QTimer::singleShot(1000, this, SLOT(slotReloadVideoProperties()));
|
||||
if (props.contains("force_aspect_num"))
|
||||
QTimer::singleShot(1000, this, SLOT(slotReloadVideoThumb()));
|
||||
}
|
||||
m_view.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
|
||||
}
|
||||
|
||||
void ClipProperties::slotReloadVideoProperties()
|
||||
{
|
||||
if (m_clip == NULL)
|
||||
return;
|
||||
loadVideoProperties(m_clip->properties());
|
||||
}
|
||||
|
||||
void ClipProperties::slotReloadVideoThumb()
|
||||
{
|
||||
if (m_clip == NULL)
|
||||
return;
|
||||
emit requestThumb(QString('?' + m_clip->getId()), QList<int>() << m_clip->getClipThumbFrame());
|
||||
}
|
||||
|
||||
void ClipProperties::disableClipId(const QString &id)
|
||||
{
|
||||
if (m_clip && m_view.buttonBox->button(QDialogButtonBox::Ok)->isEnabled()) {
|
||||
@@ -703,26 +839,56 @@ void ClipProperties::slotEnableLumaFile(int state)
|
||||
m_view.label_softness->setEnabled(enable);
|
||||
}
|
||||
|
||||
void ClipProperties::slotFillMarkersList()
|
||||
void ClipProperties::slotUpdateAnalysisData(DocClipBase *clip)
|
||||
{
|
||||
if (m_clip != clip) return;
|
||||
m_view.analysis_list->clear();
|
||||
QMap <QString, QString> analysis = clip->analysisData();
|
||||
m_view.analysis_box->setHidden(analysis.isEmpty());
|
||||
QMap<QString, QString>::const_iterator i = analysis.constBegin();
|
||||
while (i != analysis.constEnd()) {
|
||||
QStringList itemtext;
|
||||
itemtext << i.key() << i.value();
|
||||
(void) new QTreeWidgetItem(m_view.analysis_list, itemtext);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void ClipProperties::slotFillMarkersList(DocClipBase *clip)
|
||||
{
|
||||
if (m_clip != clip) return;
|
||||
m_view.markers_list->clear();
|
||||
QList < CommentedTime > marks = m_clip->commentedSnapMarkers();
|
||||
for (int count = 0; count < marks.count(); ++count) {
|
||||
QString time = m_tc.getTimecode(marks[count].time());
|
||||
QStringList itemtext;
|
||||
itemtext << time << marks[count].comment();
|
||||
(void) new QTreeWidgetItem(m_view.markers_list, itemtext);
|
||||
itemtext << time << marks.at(count).comment();
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(m_view.markers_list, itemtext);
|
||||
item->setData(0, Qt::DecorationRole, CommentedTime::markerColor(marks.at(count).markerType()));
|
||||
}
|
||||
}
|
||||
|
||||
void ClipProperties::slotAddMarker()
|
||||
{
|
||||
CommentedTime marker(GenTime(), i18n("Marker"));
|
||||
MarkerDialog d(m_clip, marker, m_tc, i18n("Add Marker"), this);
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
emit addMarker(m_clip->getId(), d.newMarker().time(), d.newMarker().comment());
|
||||
QPointer<MarkerDialog> d = new MarkerDialog(m_clip, marker,
|
||||
m_tc, i18n("Add Marker"), this);
|
||||
if (d->exec() == QDialog::Accepted) {
|
||||
QList <CommentedTime> markers;
|
||||
markers << d->newMarker();
|
||||
emit addMarkers(m_clip->getId(), markers);
|
||||
}
|
||||
QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
|
||||
delete d;
|
||||
}
|
||||
|
||||
void ClipProperties::slotSaveMarkers()
|
||||
{
|
||||
emit saveMarkers(m_clip->getId());
|
||||
}
|
||||
|
||||
void ClipProperties::slotLoadMarkers()
|
||||
{
|
||||
emit loadMarkers(m_clip->getId());
|
||||
}
|
||||
|
||||
void ClipProperties::slotEditMarker()
|
||||
@@ -732,19 +898,57 @@ void ClipProperties::slotEditMarker()
|
||||
if (pos < 0 || pos > marks.count() - 1) return;
|
||||
MarkerDialog d(m_clip, marks.at(pos), m_tc, i18n("Edit Marker"), this);
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
emit addMarker(m_clip->getId(), d.newMarker().time(), d.newMarker().comment());
|
||||
QList <CommentedTime> markers;
|
||||
markers << d.newMarker();
|
||||
emit addMarkers(m_clip->getId(), markers);
|
||||
}
|
||||
QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
|
||||
}
|
||||
|
||||
void ClipProperties::slotDeleteMarker()
|
||||
{
|
||||
QList < CommentedTime > marks = m_clip->commentedSnapMarkers();
|
||||
int pos = m_view.markers_list->currentIndex().row();
|
||||
if (pos < 0 || pos > marks.count() - 1) return;
|
||||
emit addMarker(m_clip->getId(), marks.at(pos).time(), QString());
|
||||
QList < CommentedTime > toDelete;
|
||||
for (int i = 0; i < marks.count(); ++i) {
|
||||
if (m_view.markers_list->topLevelItem(i)->isSelected()) {
|
||||
CommentedTime marker = marks.at(i);
|
||||
marker.setMarkerType(-1);
|
||||
toDelete << marker;
|
||||
}
|
||||
}
|
||||
emit addMarkers(m_clip->getId(), toDelete);
|
||||
}
|
||||
|
||||
QTimer::singleShot(500, this, SLOT(slotFillMarkersList()));
|
||||
void ClipProperties::slotDeleteAnalysis()
|
||||
{
|
||||
QTreeWidgetItem *current = m_view.analysis_list->currentItem();
|
||||
if (current) emit editAnalysis(m_clip->getId(), current->text(0), QString());
|
||||
}
|
||||
|
||||
void ClipProperties::slotSaveAnalysis()
|
||||
{
|
||||
const QString url = KFileDialog::getSaveFileName(KUrl("kfiledialog:///projectfolder"), "text/plain", this, i18n("Save Analysis Data"));
|
||||
if (url.isEmpty())
|
||||
return;
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig(url, KConfig::SimpleConfig);
|
||||
KConfigGroup analysisConfig(config, "Analysis");
|
||||
QTreeWidgetItem *current = m_view.analysis_list->currentItem();
|
||||
analysisConfig.writeEntry(current->text(0), current->text(1));
|
||||
}
|
||||
|
||||
void ClipProperties::slotLoadAnalysis()
|
||||
{
|
||||
const QString url = KFileDialog::getOpenFileName(KUrl("kfiledialog:///projectfolder"), "text/plain", this, i18n("Open Analysis Data"));
|
||||
if (url.isEmpty())
|
||||
return;
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig(url, KConfig::SimpleConfig);
|
||||
KConfigGroup transConfig(config, "Analysis");
|
||||
// read the entries
|
||||
QMap< QString, QString > profiles = transConfig.entryMap();
|
||||
QMapIterator<QString, QString> i(profiles);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
emit editAnalysis(m_clip->getId(), i.key(), i.value());
|
||||
}
|
||||
}
|
||||
|
||||
const QString &ClipProperties::clipId() const
|
||||
@@ -752,7 +956,6 @@ const QString &ClipProperties::clipId() const
|
||||
return m_clip->getId();
|
||||
}
|
||||
|
||||
|
||||
QMap <QString, QString> ClipProperties::properties()
|
||||
{
|
||||
QMap <QString, QString> props;
|
||||
@@ -767,7 +970,7 @@ QMap <QString, QString> ClipProperties::properties()
|
||||
int aspectDenominator = m_view.clip_ar_den->value();
|
||||
if (m_view.clip_force_ar->isChecked()) {
|
||||
if (aspectNumerator != m_old_props.value("force_aspect_num").toInt() ||
|
||||
aspectDenominator != m_old_props.value("force_aspect_den").toInt()) {
|
||||
aspectDenominator != m_old_props.value("force_aspect_den").toInt()) {
|
||||
props["force_aspect_num"] = QString::number(aspectNumerator);
|
||||
props["force_aspect_den"] = QString::number(aspectDenominator);
|
||||
props["force_aspect_ratio"].clear();
|
||||
@@ -795,9 +998,9 @@ QMap <QString, QString> ClipProperties::properties()
|
||||
m_clipNeedsRefresh = true;
|
||||
}
|
||||
|
||||
int progressive = m_view.clip_progressive->value();
|
||||
int progressive = m_view.clip_progressive->currentIndex();
|
||||
if (m_view.clip_force_progressive->isChecked()) {
|
||||
if (progressive != m_old_props.value("force_progressive").toInt()) {
|
||||
if (!m_old_props.contains("force_progressive") || progressive != m_old_props.value("force_progressive").toInt()) {
|
||||
props["force_progressive"] = QString::number(progressive);
|
||||
}
|
||||
} else if (m_old_props.contains("force_progressive") && !m_old_props.value("force_progressive").isEmpty()) {
|
||||
@@ -806,7 +1009,7 @@ QMap <QString, QString> ClipProperties::properties()
|
||||
|
||||
int fieldOrder = m_view.clip_fieldorder->currentIndex();
|
||||
if (m_view.clip_force_fieldorder->isChecked()) {
|
||||
if (fieldOrder != m_old_props.value("force_tff").toInt()) {
|
||||
if (!m_old_props.contains("force_tff") || fieldOrder != m_old_props.value("force_tff").toInt()) {
|
||||
props["force_tff"] = QString::number(fieldOrder);
|
||||
}
|
||||
} else if (m_old_props.contains("force_tff") && !m_old_props.value("force_tff").isEmpty()) {
|
||||
@@ -979,7 +1182,7 @@ bool ClipProperties::needsTimelineReload() const
|
||||
}
|
||||
|
||||
|
||||
void ClipProperties::parseFolder()
|
||||
void ClipProperties::parseFolder(bool reloadThumb)
|
||||
{
|
||||
QString path = m_view.clip_path->text();
|
||||
bool isMime = !(path.contains('%'));
|
||||
@@ -999,15 +1202,29 @@ void ClipProperties::parseFolder()
|
||||
QStringList result = dir.entryList(QDir::Files);
|
||||
|
||||
if (!isMime) {
|
||||
// find pattern
|
||||
QString filter = KUrl(m_view.clip_path->text()).fileName();
|
||||
int offset = 0;
|
||||
QString path = m_view.clip_path->text();
|
||||
if (path.contains('?')) {
|
||||
// New MLT syntax
|
||||
offset = m_view.clip_path->text().section(':', -1).toInt();
|
||||
path = path.section('?', 0, 0);
|
||||
}
|
||||
QString filter = KUrl(path).fileName();
|
||||
QString ext = filter.section('.', -1);
|
||||
filter = filter.section('%', 0, -2);
|
||||
QString regexp = "^" + filter + "\\d+\\." + ext + "$";
|
||||
QString regexp = '^' + filter + "\\d+\\." + ext + '$';
|
||||
QRegExp rx(regexp);
|
||||
QStringList entries;
|
||||
int ix;
|
||||
foreach(const QString & path, result) {
|
||||
if (rx.exactMatch(path)) entries << path;
|
||||
if (rx.exactMatch(path)) {
|
||||
if (offset > 0) {
|
||||
// make sure our image is in the range we want (> begin)
|
||||
ix = path.section(filter, 1).section('.', 0, 0).toInt();
|
||||
if (ix < offset) continue;
|
||||
}
|
||||
entries << path;
|
||||
}
|
||||
}
|
||||
result = entries;
|
||||
}
|
||||
@@ -1022,22 +1239,23 @@ void ClipProperties::parseFolder()
|
||||
}
|
||||
m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
m_view.slide_info->setText(i18np("1 image found", "%1 images found", m_count));
|
||||
QDomElement xml = m_clip->toXML();
|
||||
xml.setAttribute("resource", m_view.clip_path->text() + extension);
|
||||
int width = 180.0 * KdenliveSettings::project_display_ratio();
|
||||
if (width % 2 == 1) width++;
|
||||
QString filePath = m_view.clip_path->text();
|
||||
if (isMime) filePath.append(extension);
|
||||
QPixmap pix = m_clip->thumbProducer()->getImage(KUrl(filePath), 1, width, 180);
|
||||
QMap <QString, QString> props = m_clip->properties();
|
||||
m_view.clip_duration->setText(m_tc.getTimecodeFromFrames(props.value("ttl").toInt() * m_count));
|
||||
m_view.clip_thumb->setPixmap(pix);
|
||||
if (reloadThumb) {
|
||||
int width = 180.0 * KdenliveSettings::project_display_ratio();
|
||||
if (width % 2 == 1) width++;
|
||||
QString filePath = m_view.clip_path->text();
|
||||
if (isMime) filePath.append(extension);
|
||||
QPixmap pix = m_clip->thumbProducer()->getImage(KUrl(filePath), 1, width, 180);
|
||||
m_view.clip_thumb->setPixmap(pix);
|
||||
}
|
||||
}
|
||||
|
||||
void ClipProperties::slotCheckMaxLength()
|
||||
{
|
||||
if (m_clip->maxDuration() == GenTime()) return;
|
||||
int duration = m_tc.getFrameCount(m_view.clip_duration->text());
|
||||
if (m_clip->maxDuration() == GenTime())
|
||||
return;
|
||||
const int duration = m_tc.getFrameCount(m_view.clip_duration->text());
|
||||
if (duration > m_clip->maxDuration().frames(m_fps)) {
|
||||
m_view.clip_duration->setText(m_tc.getTimecode(m_clip->maxDuration()));
|
||||
}
|
||||
@@ -1045,7 +1263,7 @@ void ClipProperties::slotCheckMaxLength()
|
||||
|
||||
void ClipProperties::slotUpdateDurationFormat(int ix)
|
||||
{
|
||||
bool framesFormat = ix == 1;
|
||||
bool framesFormat = (ix == 1);
|
||||
if (framesFormat) {
|
||||
// switching to frames count, update widget
|
||||
m_view.slide_duration_frames->setValue(m_tc.getFrameCount(m_view.slide_duration->text()));
|
||||
@@ -1067,10 +1285,11 @@ void ClipProperties::slotUpdateDurationFormat(int ix)
|
||||
|
||||
void ClipProperties::slotDeleteProxy()
|
||||
{
|
||||
QString proxy = m_clip->getProperty("proxy");
|
||||
if (proxy.isEmpty()) return;
|
||||
emit deleteProxy(proxy);
|
||||
if (m_proxyContainer) delete m_proxyContainer;
|
||||
const QString proxy = m_clip->getProperty("proxy");
|
||||
if (proxy.isEmpty())
|
||||
return;
|
||||
emit deleteProxy(proxy);
|
||||
delete m_proxyContainer;
|
||||
}
|
||||
|
||||
void ClipProperties::slotOpenUrl(const QString &url)
|
||||
|
||||
@@ -32,11 +32,14 @@ class PropertiesViewDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PropertiesViewDelegate(QWidget *parent) : QStyledItemDelegate(parent) {
|
||||
m_height = parent->fontMetrics().height() * 1.5;
|
||||
PropertiesViewDelegate(QWidget *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
m_height = parent->fontMetrics().height() * 1.2;
|
||||
}
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const {
|
||||
return QSize(10, m_height);
|
||||
protected:
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
|
||||
return QSize(QStyledItemDelegate::sizeHint(option, index).width(), m_height);
|
||||
}
|
||||
private:
|
||||
int m_height;
|
||||
@@ -47,8 +50,8 @@ class ClipProperties : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidget * parent = 0);
|
||||
ClipProperties(QList <DocClipBase *>cliplist, Timecode tc, QMap <QString, QString> commonproperties, QWidget * parent);
|
||||
ClipProperties(DocClipBase *clip, const Timecode &tc, double fps, QWidget * parent = 0);
|
||||
ClipProperties(const QList<DocClipBase *> &cliplist, const Timecode &tc, const QMap<QString, QString> &commonproperties, QWidget * parent);
|
||||
virtual ~ClipProperties();
|
||||
QMap <QString, QString> properties();
|
||||
const QString &clipId() const;
|
||||
@@ -56,12 +59,15 @@ public:
|
||||
bool needsTimelineReload() const;
|
||||
void disableClipId(const QString &id);
|
||||
|
||||
public slots:
|
||||
void slotFillMarkersList(DocClipBase *clip);
|
||||
void slotUpdateAnalysisData(DocClipBase *clip);
|
||||
|
||||
private slots:
|
||||
void parseFolder();
|
||||
void parseFolder(bool reloadThumb = true);
|
||||
void slotAddMarker();
|
||||
void slotEditMarker();
|
||||
void slotDeleteMarker();
|
||||
void slotFillMarkersList();
|
||||
void slotCheckMaxLength();
|
||||
void slotEnableLuma(int state);
|
||||
void slotEnableLumaFile(int state);
|
||||
@@ -70,6 +76,14 @@ private slots:
|
||||
void slotModified();
|
||||
void slotDeleteProxy();
|
||||
void slotOpenUrl(const QString &url);
|
||||
void slotSaveMarkers();
|
||||
void slotLoadMarkers();
|
||||
void slotDeleteAnalysis();
|
||||
void slotGotThumbnail(const QString &id, const QImage &img);
|
||||
void slotSaveAnalysis();
|
||||
void slotLoadAnalysis();
|
||||
void slotReloadVideoProperties();
|
||||
void slotReloadVideoThumb();
|
||||
|
||||
private:
|
||||
Ui::ClipProperties_UI m_view;
|
||||
@@ -85,11 +99,16 @@ private:
|
||||
bool m_clipNeedsReLoad;
|
||||
/** Frame with proxy info / delete button */
|
||||
QFrame* m_proxyContainer;
|
||||
void loadVideoProperties(const QMap<QString, QString> &props);
|
||||
|
||||
signals:
|
||||
void addMarker(const QString &, GenTime, QString);
|
||||
void deleteProxy(const QString);
|
||||
void applyNewClipProperties(const QString, QMap <QString, QString> , QMap <QString, QString> , bool, bool);
|
||||
void addMarkers(const QString &, const QList <CommentedTime>&);
|
||||
void deleteProxy(const QString&);
|
||||
void applyNewClipProperties(const QString&, const QMap <QString, QString> &, const QMap <QString, QString> &, bool, bool);
|
||||
void saveMarkers(const QString &id);
|
||||
void loadMarkers(const QString &id);
|
||||
void editAnalysis(const QString &id, const QString &name, const QString &value);
|
||||
void requestThumb(const QString &id, const QList <int>& frames);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -33,16 +33,17 @@
|
||||
#include <QSlider>
|
||||
#include <KFileDialog>
|
||||
|
||||
ClipStabilize::ClipStabilize(const QString &dest, int count, const QString &filterName,QWidget * parent) :
|
||||
QDialog(parent),
|
||||
m_filtername(filterName),
|
||||
m_count(count),
|
||||
vbox(NULL)
|
||||
ClipStabilize::ClipStabilize(const QStringList &urls, const QString &filterName,QWidget * parent) :
|
||||
QDialog(parent),
|
||||
m_filtername(filterName),
|
||||
m_urls(urls),
|
||||
vbox(NULL)
|
||||
{
|
||||
setFont(KGlobalSettings::toolBarFont());
|
||||
setupUi(this);
|
||||
setWindowTitle(i18n("Stabilize Clip"));
|
||||
auto_add->setText(i18np("Add clip to project", "Add clips to project", count));
|
||||
auto_add->setText(i18np("Add clip to project", "Add clips to project", urls.count()));
|
||||
auto_add->setChecked(KdenliveSettings::add_new_clip());
|
||||
|
||||
QPalette p = palette();
|
||||
KColorScheme scheme(p.currentColorGroup(), KColorScheme::View, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
|
||||
@@ -52,79 +53,82 @@ ClipStabilize::ClipStabilize(const QString &dest, int count, const QString &filt
|
||||
QColor light_bg = scheme.shade(KColorScheme::LightShade);
|
||||
|
||||
QString stylesheet(QString("QProgressBar:horizontal {border: 1px solid %1;border-radius:0px;border-top-left-radius: 4px;border-bottom-left-radius: 4px;border-right: 0px;background:%4;padding: 0px;text-align:left center}\
|
||||
QProgressBar:horizontal#dragOnly {background: %1} QProgressBar:horizontal:hover#dragOnly {background: %3} QProgressBar:horizontal:hover {border: 1px solid %3;border-right: 0px;}\
|
||||
QProgressBar::chunk:horizontal {background: %1;} QProgressBar::chunk:horizontal:hover {background: %3;}\
|
||||
QProgressBar:horizontal[inTimeline=\"true\"] { border: 1px solid %2;border-right: 0px;background: %4;padding: 0px;text-align:left center } QProgressBar::chunk:horizontal[inTimeline=\"true\"] {background: %2;}\
|
||||
QAbstractSpinBox#dragBox {border: 1px solid %1;border-top-right-radius: 4px;border-bottom-right-radius: 4px;padding-right:0px;} QAbstractSpinBox::down-button#dragBox {width:0px;padding:0px;}\
|
||||
QAbstractSpinBox::up-button#dragBox {width:0px;padding:0px;} QAbstractSpinBox[inTimeline=\"true\"]#dragBox { border: 1px solid %2;} QAbstractSpinBox:hover#dragBox {border: 1px solid %3;} ")
|
||||
.arg(dark_bg.name()).arg(selected_bg.name()).arg(hover_bg.name()).arg(light_bg.name()));
|
||||
setStyleSheet(stylesheet);
|
||||
QProgressBar:horizontal#dragOnly {background: %1} QProgressBar:horizontal:hover#dragOnly {background: %3} QProgressBar:horizontal:hover {border: 1px solid %3;border-right: 0px;}\
|
||||
QProgressBar::chunk:horizontal {background: %1;} QProgressBar::chunk:horizontal:hover {background: %3;}\
|
||||
QProgressBar:horizontal[inTimeline=\"true\"] { border: 1px solid %2;border-right: 0px;background: %4;padding: 0px;text-align:left center } QProgressBar::chunk:horizontal[inTimeline=\"true\"] {background: %2;}\
|
||||
QAbstractSpinBox#dragBox {border: 1px solid %1;border-top-right-radius: 4px;border-bottom-right-radius: 4px;padding-right:0px;} QAbstractSpinBox::down-button#dragBox {width:0px;padding:0px;}\
|
||||
QAbstractSpinBox::up-button#dragBox {width:0px;padding:0px;} QAbstractSpinBox[inTimeline=\"true\"]#dragBox { border: 1px solid %2;} QAbstractSpinBox:hover#dragBox {border: 1px solid %3;} ")
|
||||
.arg(dark_bg.name()).arg(selected_bg.name()).arg(hover_bg.name()).arg(light_bg.name()));
|
||||
setStyleSheet(stylesheet);
|
||||
|
||||
if (m_count == 1) {
|
||||
QString newFile = dest;
|
||||
newFile.append(".mlt");
|
||||
KUrl dest(newFile);
|
||||
dest_url->setMode(KFile::File);
|
||||
dest_url->setUrl(KUrl(newFile));
|
||||
dest_url->fileDialog()->setOperationMode(KFileDialog::Saving);
|
||||
} else {
|
||||
label_dest->setText(i18n("Destination folder"));
|
||||
dest_url->setMode(KFile::Directory);
|
||||
dest_url->setUrl(KUrl(dest));
|
||||
dest_url->fileDialog()->setOperationMode(KFileDialog::Saving);
|
||||
}
|
||||
if (m_urls.count() == 1) {
|
||||
QString newFile = m_urls.first();
|
||||
newFile.append(".mlt");
|
||||
KUrl dest(newFile);
|
||||
dest_url->setMode(KFile::File);
|
||||
dest_url->setUrl(KUrl(newFile));
|
||||
dest_url->fileDialog()->setOperationMode(KFileDialog::Saving);
|
||||
|
||||
if (m_filtername=="videostab"){
|
||||
QStringList ls;
|
||||
ls << "shutterangle,type,int,value,0,min,0,max,100,tooltip,Angle that Images could be maximum rotated";
|
||||
fillParameters(ls);
|
||||
}else if (m_filtername=="videostab2"){
|
||||
QStringList ls;
|
||||
ls << "accuracy,type,int,value,4,min,1,max,10,tooltip,Accuracy of Shakiness detection";
|
||||
ls << "shakiness,type,int,value,4,min,1,max,10,tooltip,How shaky is the Video";
|
||||
ls << "stepsize,type,int,value,6,min,0,max,100,tooltip,Stepsize of Detection process minimum around";
|
||||
ls << "algo,type,bool,value,1,min,0,max,1,tooltip,0 = Bruteforce 1 = small measurement fields";
|
||||
ls << "mincontrast,type,double,value,0.3,min,0,max,1,factor,1,decimals,2,tooltip,Below this Contrast Field is discarded";
|
||||
ls << "show,type,int,value,0,min,0,max,2,tooltip,0 = draw nothing. 1 or 2 show fields and transforms";
|
||||
ls << "smoothing,type,int,value,10,min,0,max,100,tooltip,number of frames for lowpass filtering";
|
||||
ls << "maxshift,type,int,value,-1,min,-1,max,1000,tooltip,max number of pixels to shift";
|
||||
ls << "maxangle,type,int,value,-1,min,-1,max,1000,tooltip,max anglen to rotate (in rad)";
|
||||
ls << "crop,type,bool,value,0,min,0,max,1,tooltip,0 = keep border 1 = black background";
|
||||
ls << "invert,type,bool,value,0,min,0,max,1,tooltip,invert transform";
|
||||
ls << "realtive,type,bool,value,1,min,0,max,1,tooltip,0 = absolute transform 1= relative";
|
||||
ls << "zoom,type,int,value,0,min,-500,max,500,tooltip,additional zoom during transform";
|
||||
ls << "optzoom,type,bool,value,1,min,0,max,1,tooltip,use optimal zoom (calulated from transforms)";
|
||||
ls << "sharpen,type,double,value,0.8,min,0,max,1,decimals,1,tooltip,sharpen transformed image";
|
||||
fillParameters(ls);
|
||||
} else {
|
||||
label_dest->setText(i18n("Destination folder"));
|
||||
dest_url->setMode(KFile::Directory);
|
||||
dest_url->setUrl(KUrl(KUrl(m_urls.first()).directory()));
|
||||
dest_url->fileDialog()->setOperationMode(KFileDialog::Saving);
|
||||
}
|
||||
|
||||
}
|
||||
if (m_filtername=="videostab"){
|
||||
QStringList ls;
|
||||
ls << "shutterangle,type,int,value,0,min,0,max,180,tooltip,Angle that Images could be maximum rotated";
|
||||
fillParameters(ls);
|
||||
}else if (m_filtername=="videostab2"){
|
||||
// Some default params have to be set:
|
||||
m_fixedParams << "algo=1" << "relative=1";
|
||||
QStringList ls;
|
||||
ls << "accuracy,type,int,value,8,min,1,max,10,tooltip,Accuracy of Shakiness detection";
|
||||
ls << "shakiness,type,int,value,4,min,1,max,10,tooltip,How shaky is the Video";
|
||||
ls << "stepsize,type,int,value,6,min,0,max,100,tooltip,Stepsize of Detection process minimum around";
|
||||
//ls << "algo,type,bool,value,1,min,0,max,1,tooltip,0 = Bruteforce 1 = small measurement fields";
|
||||
ls << "mincontrast,type,double,value,0.3,min,0,max,1,factor,1,decimals,2,tooltip,Below this Contrast Field is discarded";
|
||||
//ls << "show,type,int,value,0,min,0,max,2,tooltip,0 = draw nothing. 1 or 2 show fields and transforms";
|
||||
ls << "smoothing,type,int,value,10,min,0,max,100,tooltip,number of frames for lowpass filtering";
|
||||
ls << "maxshift,type,int,value,-1,min,-1,max,1000,tooltip,max number of pixels to shift";
|
||||
ls << "maxangle,type,double,value,-1,min,-1,max,3.14,decimals,2,tooltip,max angle to rotate (in rad)";
|
||||
ls << "crop,type,bool,value,0,min,0,max,1,tooltip,0 = keep border 1 = black background";
|
||||
//ls << "invert,type,bool,value,0,min,0,max,1,tooltip,invert transform";
|
||||
//ls << "relative,type,bool,value,1,min,0,max,1,tooltip,0 = absolute transform 1= relative";
|
||||
ls << "zoom,type,int,value,0,min,-500,max,500,tooltip,additional zoom during transform";
|
||||
ls << "optzoom,type,bool,value,1,min,0,max,1,tooltip,use optimal zoom (calulated from transforms)";
|
||||
ls << "sharpen,type,double,value,0.8,min,0,max,1,decimals,1,tooltip,sharpen transformed image";
|
||||
fillParameters(ls);
|
||||
|
||||
//connect(buttonBox,SIGNAL(rejected()), this, SLOT(slotAbortStabilize()));
|
||||
}
|
||||
|
||||
vbox=new QVBoxLayout(optionsbox);
|
||||
QHashIterator<QString,QHash<QString,QString> > hi(m_ui_params);
|
||||
while(hi.hasNext()){
|
||||
hi.next();
|
||||
QHash<QString,QString> val=hi.value();
|
||||
if (val["type"]=="int" || val["type"]=="double"){
|
||||
DoubleParameterWidget *dbl=new DoubleParameterWidget(hi.key(), val["value"].toDouble(),
|
||||
val["min"].toDouble(),val["max"].toDouble(),val["value"].toDouble(),
|
||||
"",0/*id*/,""/*suffix*/,val["decimals"]!=""?val["decimals"].toInt():0,this);
|
||||
dbl->setObjectName(hi.key());
|
||||
dbl->setToolTip(val["tooltip"]);
|
||||
connect(dbl,SIGNAL(valueChanged(double)),this,SLOT(slotUpdateParams()));
|
||||
vbox->addWidget(dbl);
|
||||
}else if (val["type"]=="bool"){
|
||||
QCheckBox *ch=new QCheckBox(hi.key(),this);
|
||||
ch->setCheckState(val["value"] == "0" ? Qt::Unchecked : Qt::Checked);
|
||||
ch->setObjectName(hi.key());
|
||||
connect(ch, SIGNAL(stateChanged(int)) , this,SLOT(slotUpdateParams()));
|
||||
ch->setToolTip(val["tooltip"]);
|
||||
vbox->addWidget(ch);
|
||||
connect(buttonBox->button(QDialogButtonBox::Ok),SIGNAL(clicked()), this, SLOT(slotValidate()));
|
||||
|
||||
}
|
||||
}
|
||||
adjustSize();
|
||||
vbox=new QVBoxLayout(optionsbox);
|
||||
QHashIterator<QString,QHash<QString,QString> > hi(m_ui_params);
|
||||
while(hi.hasNext()){
|
||||
hi.next();
|
||||
QHash<QString,QString> val=hi.value();
|
||||
if (val["type"]=="int" || val["type"]=="double"){
|
||||
DoubleParameterWidget *dbl=new DoubleParameterWidget(hi.key(), val["value"].toDouble(),
|
||||
val["min"].toDouble(),val["max"].toDouble(),val["value"].toDouble(),
|
||||
"",0/*id*/,""/*suffix*/,val["decimals"]!=""?val["decimals"].toInt():0,this);
|
||||
dbl->setObjectName(hi.key());
|
||||
dbl->setToolTip(val["tooltip"]);
|
||||
connect(dbl,SIGNAL(valueChanged(double)),this,SLOT(slotUpdateParams()));
|
||||
vbox->addWidget(dbl);
|
||||
}else if (val["type"]=="bool"){
|
||||
QCheckBox *ch=new QCheckBox(hi.key(),this);
|
||||
ch->setCheckState(val["value"] == "0" ? Qt::Unchecked : Qt::Checked);
|
||||
ch->setObjectName(hi.key());
|
||||
connect(ch, SIGNAL(stateChanged(int)) , this,SLOT(slotUpdateParams()));
|
||||
ch->setToolTip(val["tooltip"]);
|
||||
vbox->addWidget(ch);
|
||||
|
||||
}
|
||||
}
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
ClipStabilize::~ClipStabilize()
|
||||
@@ -132,6 +136,7 @@ ClipStabilize::~ClipStabilize()
|
||||
/*if (m_stabilizeProcess.state() != QProcess::NotRunning) {
|
||||
m_stabilizeProcess.close();
|
||||
}*/
|
||||
KdenliveSettings::setAdd_new_clip(auto_add->isChecked());
|
||||
}
|
||||
|
||||
QStringList ClipStabilize::params()
|
||||
@@ -143,11 +148,11 @@ QStringList ClipStabilize::params()
|
||||
params << QString();
|
||||
// filter
|
||||
params << m_filtername;
|
||||
QStringList filterparamsList;
|
||||
QStringList filterparamsList = m_fixedParams;
|
||||
QHashIterator <QString,QHash<QString,QString> > it(m_ui_params);
|
||||
while (it.hasNext()){
|
||||
it.next();
|
||||
filterparamsList << it.key() + "=" + it.value().value("value");
|
||||
filterparamsList << it.key() + '=' + it.value().value("value");
|
||||
}
|
||||
params << filterparamsList.join(" ");
|
||||
|
||||
@@ -161,10 +166,10 @@ QStringList ClipStabilize::params()
|
||||
|
||||
QString ClipStabilize::destination() const
|
||||
{
|
||||
if (m_count == 1)
|
||||
if (m_urls.count() == 1)
|
||||
return dest_url->url().path();
|
||||
else
|
||||
return dest_url->url().directory(KUrl::AppendTrailingSlash);
|
||||
return dest_url->url().path(KUrl::AddTrailingSlash);
|
||||
}
|
||||
|
||||
QString ClipStabilize::desc() const
|
||||
@@ -230,10 +235,10 @@ void ClipStabilize::slotStartStabilize()
|
||||
|
||||
void ClipStabilize::slotUpdateParams()
|
||||
{
|
||||
for (int i=0;i<vbox->count();i++){
|
||||
for (int i=0;i<vbox->count();++i){
|
||||
QWidget* w=vbox->itemAt(i)->widget();
|
||||
QString name=w->objectName();
|
||||
if (name !="" && m_ui_params.contains(name)){
|
||||
if (!name.isEmpty() && m_ui_params.contains(name)){
|
||||
if (m_ui_params[name]["type"]=="int" || m_ui_params[name]["type"]=="double"){
|
||||
DoubleParameterWidget *dbl=(DoubleParameterWidget*)w;
|
||||
m_ui_params[name]["value"]=QString::number((double)(dbl->getValue()));
|
||||
@@ -256,7 +261,7 @@ void ClipStabilize::fillParameters(QStringList lst)
|
||||
m_ui_params.clear();
|
||||
while (!lst.isEmpty()){
|
||||
QString vallist=lst.takeFirst();
|
||||
QStringList cont=vallist.split(",");
|
||||
QStringList cont=vallist.split(',');
|
||||
QString name=cont.takeFirst();
|
||||
while (!cont.isEmpty()){
|
||||
QString valname=cont.takeFirst();
|
||||
@@ -270,6 +275,27 @@ void ClipStabilize::fillParameters(QStringList lst)
|
||||
|
||||
}
|
||||
|
||||
void ClipStabilize::slotValidate()
|
||||
{
|
||||
if (m_urls.count() == 1) {
|
||||
if (QFile::exists(dest_url->url().path())) {
|
||||
if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", dest_url->url().path() )) == KMessageBox::No) return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
KUrl folder(dest_url->url());
|
||||
QStringList existingFiles;
|
||||
foreach(const QString &path, m_urls) {
|
||||
KUrl dest = folder;
|
||||
dest.addPath(KUrl(path).fileName());
|
||||
if (QFile::exists(dest.path() + ".mlt")) existingFiles.append(dest.path() + ".mlt");
|
||||
}
|
||||
if (!existingFiles.isEmpty()) {
|
||||
if (KMessageBox::warningContinueCancelList(this, i18n("The stabilize job will overwrite the following files:"), existingFiles) == KMessageBox::Cancel) return;
|
||||
}
|
||||
}
|
||||
accept();
|
||||
}
|
||||
|
||||
#include "clipstabilize.moc"
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "ui_clipstabilize_ui.h"
|
||||
|
||||
#include <KUrl>
|
||||
#include <QProcess>
|
||||
#include <QFuture>
|
||||
|
||||
class QTimer;
|
||||
@@ -35,14 +34,14 @@ namespace Mlt{
|
||||
class Playlist;
|
||||
class Consumer;
|
||||
class Filter;
|
||||
};
|
||||
}
|
||||
|
||||
class ClipStabilize : public QDialog, public Ui::ClipStabilize_UI
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ClipStabilize(const QString &dest, int count, const QString &filterName,QWidget * parent = 0);
|
||||
explicit ClipStabilize(const QStringList &urls, const QString &filterName,QWidget * parent = 0);
|
||||
~ClipStabilize();
|
||||
/** @brief Should the generated clip be added to current project. */
|
||||
bool autoAddClip() const;
|
||||
@@ -57,16 +56,18 @@ public:
|
||||
private slots:
|
||||
void slotStartStabilize();
|
||||
void slotUpdateParams();
|
||||
void slotValidate();
|
||||
|
||||
private:
|
||||
QString m_filtername;
|
||||
int m_count;
|
||||
QStringList m_urls;
|
||||
QHash<QString,QHash<QString,QString> > m_ui_params;
|
||||
QVBoxLayout *vbox;
|
||||
void fillParameters(QStringList);
|
||||
QStringList m_fixedParams;
|
||||
|
||||
signals:
|
||||
void addClip(KUrl url);
|
||||
void addClip(const KUrl &url);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
|
||||
#include "cliptranscode.h"
|
||||
#include "kdenlivesettings.h"
|
||||
|
||||
#include <KDebug>
|
||||
#include <KGlobalSettings>
|
||||
@@ -26,8 +27,8 @@
|
||||
#include <KFileDialog>
|
||||
|
||||
|
||||
ClipTranscode::ClipTranscode(KUrl::List urls, const QString ¶ms, const QString &description, QWidget * parent) :
|
||||
QDialog(parent), m_urls(urls), m_duration(0)
|
||||
ClipTranscode::ClipTranscode(const KUrl::List &urls, const QString ¶ms, const QStringList &postParams, const QString &description, bool automaticMode, QWidget * parent) :
|
||||
QDialog(parent), m_urls(urls), m_duration(0), m_automaticMode(automaticMode), m_postParams(postParams)
|
||||
{
|
||||
setFont(KGlobalSettings::toolBarFont());
|
||||
setupUi(this);
|
||||
@@ -41,7 +42,11 @@ ClipTranscode::ClipTranscode(KUrl::List urls, const QString ¶ms, const QStri
|
||||
#endif
|
||||
log_text->setHidden(true);
|
||||
setWindowTitle(i18n("Transcode Clip"));
|
||||
if (m_automaticMode) {
|
||||
auto_add->setHidden(true);
|
||||
}
|
||||
auto_add->setText(i18np("Add clip to project", "Add clips to project", m_urls.count()));
|
||||
auto_add->setChecked(KdenliveSettings::add_new_clip());
|
||||
|
||||
if (m_urls.count() == 1) {
|
||||
QString fileName = m_urls.at(0).path(); //.section('.', 0, -1);
|
||||
@@ -52,7 +57,7 @@ ClipTranscode::ClipTranscode(KUrl::List urls, const QString ¶ms, const QStri
|
||||
dest_url->setUrl(dest);
|
||||
dest_url->fileDialog()->setOperationMode(KFileDialog::Saving);
|
||||
urls_list->setHidden(true);
|
||||
connect(source_url, SIGNAL(textChanged(const QString &)), this, SLOT(slotUpdateParams()));
|
||||
connect(source_url, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateParams()));
|
||||
} else {
|
||||
label_source->setHidden(true);
|
||||
source_url->setHidden(true);
|
||||
@@ -60,7 +65,7 @@ ClipTranscode::ClipTranscode(KUrl::List urls, const QString ¶ms, const QStri
|
||||
dest_url->setMode(KFile::Directory);
|
||||
dest_url->setUrl(KUrl(m_urls.at(0).directory()));
|
||||
dest_url->fileDialog()->setOperationMode(KFileDialog::Saving);
|
||||
for (int i = 0; i < m_urls.count(); i++)
|
||||
for (int i = 0; i < m_urls.count(); ++i)
|
||||
urls_list->addItem(m_urls.at(i).path());
|
||||
}
|
||||
if (!params.isEmpty()) {
|
||||
@@ -72,14 +77,14 @@ ClipTranscode::ClipTranscode(KUrl::List urls, const QString ¶ms, const QStri
|
||||
} else transcode_info->setHidden(true);
|
||||
} else {
|
||||
// load Profiles
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc");
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc", KConfig::CascadeConfig);
|
||||
KConfigGroup transConfig(config, "Transcoding");
|
||||
// read the entries
|
||||
QMap< QString, QString > profiles = transConfig.entryMap();
|
||||
QMapIterator<QString, QString> i(profiles);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
QStringList data = i.value().split(";");
|
||||
QStringList data = i.value().split(';');
|
||||
profile_list->addItem(i.key(), data.at(0));
|
||||
if (data.count() > 1) profile_list->setItemData(profile_list->count() - 1, data.at(1), Qt::UserRole + 1);
|
||||
}
|
||||
@@ -91,7 +96,7 @@ ClipTranscode::ClipTranscode(KUrl::List urls, const QString ¶ms, const QStri
|
||||
|
||||
m_transcodeProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||
connect(&m_transcodeProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(slotShowTranscodeInfo()));
|
||||
connect(&m_transcodeProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotTranscodeFinished(int, QProcess::ExitStatus)));
|
||||
connect(&m_transcodeProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotTranscodeFinished(int,QProcess::ExitStatus)));
|
||||
|
||||
ffmpeg_params->setMaximumHeight(QFontMetrics(font()).lineSpacing() * 5);
|
||||
|
||||
@@ -100,6 +105,7 @@ ClipTranscode::ClipTranscode(KUrl::List urls, const QString ¶ms, const QStri
|
||||
|
||||
ClipTranscode::~ClipTranscode()
|
||||
{
|
||||
KdenliveSettings::setAdd_new_clip(auto_add->isChecked());
|
||||
if (m_transcodeProcess.state() != QProcess::NotRunning) {
|
||||
m_transcodeProcess.close();
|
||||
}
|
||||
@@ -121,7 +127,7 @@ void ClipTranscode::slotStartTransCode()
|
||||
QStringList parameters;
|
||||
QString destination;
|
||||
QString params = ffmpeg_params->toPlainText().simplified();
|
||||
if (m_urls.count() > 0 && urls_list->count() > 0) {
|
||||
if (!m_urls.isEmpty() && urls_list->count() > 0) {
|
||||
// We are processing multiple clips
|
||||
source_url->setUrl(m_urls.takeFirst());
|
||||
destination = dest_url->url().path(KUrl::AddTrailingSlash) + source_url->url().fileName();
|
||||
@@ -137,15 +143,34 @@ void ClipTranscode::slotStartTransCode()
|
||||
QString s_url = source_url->url().path();
|
||||
parameters << "-i" << s_url;
|
||||
if (QFile::exists(destination + extension)) {
|
||||
if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", destination + extension)) == KMessageBox::No) return;
|
||||
if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", destination + extension)) == KMessageBox::No) {
|
||||
// Abort operation
|
||||
if (m_automaticMode) {
|
||||
// inform caller that we aborted
|
||||
emit transcodedClip(source_url->url(), KUrl());
|
||||
close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
parameters << "-y";
|
||||
}
|
||||
foreach(QString s, params.split(' '))
|
||||
|
||||
bool replaceVfParams = false;
|
||||
foreach(QString s, params.split(' ')) {
|
||||
if (replaceVfParams) {
|
||||
s= m_postParams.at(1);
|
||||
replaceVfParams = false;
|
||||
}
|
||||
parameters << s.replace("%1", destination);
|
||||
if (s == "-vf") {
|
||||
replaceVfParams = true;
|
||||
}
|
||||
}
|
||||
|
||||
buttonBox->button(QDialogButtonBox::Abort)->setText(i18n("Abort"));
|
||||
|
||||
m_destination = destination + extension;
|
||||
m_transcodeProcess.start("ffmpeg", parameters);
|
||||
m_transcodeProcess.start(KdenliveSettings::ffmpegpath(), parameters);
|
||||
source_url->setEnabled(false);
|
||||
dest_url->setEnabled(false);
|
||||
button_start->setEnabled(false);
|
||||
@@ -197,14 +222,15 @@ void ClipTranscode::slotTranscodeFinished(int exitCode, QProcess::ExitStatus exi
|
||||
}
|
||||
if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
|
||||
log_text->setHtml(log_text->toPlainText() + "<br /><b>" + i18n("Transcoding finished."));
|
||||
if (auto_add->isChecked()) {
|
||||
if (auto_add->isChecked() || m_automaticMode) {
|
||||
KUrl url;
|
||||
if (urls_list->count() > 0) {
|
||||
QString params = ffmpeg_params->toPlainText().simplified();
|
||||
QString extension = params.section("%1", 1, 1).section(' ', 0, 0);
|
||||
url = KUrl(dest_url->url().path(KUrl::AddTrailingSlash) + source_url->url().fileName() + extension);
|
||||
} else url = dest_url->url();
|
||||
emit addClip(url);
|
||||
if (m_automaticMode) emit transcodedClip(source_url->url(), url);
|
||||
else emit addClip(url);
|
||||
}
|
||||
if (urls_list->count() > 0 && m_urls.count() > 0) {
|
||||
m_transcodeProcess.close();
|
||||
@@ -235,7 +261,7 @@ void ClipTranscode::slotTranscodeFinished(int exitCode, QProcess::ExitStatus exi
|
||||
//Refill url list in case user wants to transcode to another format
|
||||
if (urls_list->count() > 0) {
|
||||
m_urls.clear();
|
||||
for (int i = 0; i < urls_list->count(); i++)
|
||||
for (int i = 0; i < urls_list->count(); ++i)
|
||||
m_urls << urls_list->item(i)->text();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,13 +37,15 @@ class ClipTranscode : public QDialog, public Ui::ClipTranscode_UI
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ClipTranscode(KUrl::List urls, const QString ¶ms, const QString &description, QWidget * parent = 0);
|
||||
ClipTranscode(const KUrl::List &urls, const QString ¶ms, const QStringList &postParams, const QString &description, bool automaticMode = false, QWidget * parent = 0);
|
||||
~ClipTranscode();
|
||||
|
||||
public slots:
|
||||
void slotStartTransCode();
|
||||
|
||||
|
||||
private slots:
|
||||
void slotShowTranscodeInfo();
|
||||
void slotStartTransCode();
|
||||
void slotTranscodeFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void slotUpdateParams(int ix = -1);
|
||||
|
||||
@@ -51,15 +53,18 @@ private:
|
||||
QProcess m_transcodeProcess;
|
||||
KUrl::List m_urls;
|
||||
int m_duration;
|
||||
bool m_automaticMode;
|
||||
/** @brief The path for destination transcoded file. */
|
||||
QString m_destination;
|
||||
QStringList m_postParams;
|
||||
|
||||
#if KDE_IS_VERSION(4,7,0)
|
||||
KMessageWidget *m_infoMessage;
|
||||
#endif
|
||||
|
||||
signals:
|
||||
void addClip(KUrl url);
|
||||
void addClip(const KUrl &url);
|
||||
void transcodedClip(const KUrl &source, const KUrl &result);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ HistogramGenerator::HistogramGenerator()
|
||||
}
|
||||
|
||||
QImage HistogramGenerator::calculateHistogram(const QSize ¶deSize, const QImage &image, const int &components,
|
||||
HistogramGenerator::Rec rec, const bool &unscaled, const uint &accelFactor) const
|
||||
HistogramGenerator::Rec rec, bool unscaled, uint accelFactor) const
|
||||
{
|
||||
if (paradeSize.height() <= 0 || paradeSize.width() <= 0 || image.width() <= 0 || image.height() <= 0) {
|
||||
return QImage();
|
||||
@@ -44,7 +44,7 @@ QImage HistogramGenerator::calculateHistogram(const QSize ¶deSize, const QIm
|
||||
const uint ww = paradeSize.width();
|
||||
const uint wh = paradeSize.height();
|
||||
const uint byteCount = iw*ih;
|
||||
const uint stepsize = 4*accelFactor;
|
||||
const uint stepsize = image.depth() / 8 *accelFactor;
|
||||
|
||||
const uchar *bits = image.bits();
|
||||
QRgb *col;
|
||||
@@ -84,7 +84,10 @@ QImage HistogramGenerator::calculateHistogram(const QSize ¶deSize, const QIm
|
||||
|
||||
const int d = 20; // Distance for text
|
||||
const int partH = (wh-nParts*d)/nParts;
|
||||
const float scaling = (float)partH/(byteCount >> 7);
|
||||
float scaling = 0;
|
||||
int div = byteCount >> 7;
|
||||
if ( div > 0 )
|
||||
scaling = (float)partH/(byteCount >> 7);
|
||||
const int dist = 40;
|
||||
|
||||
int wy = 0; // Drawing position
|
||||
@@ -127,7 +130,7 @@ QImage HistogramGenerator::calculateHistogram(const QSize ¶deSize, const QIm
|
||||
}
|
||||
|
||||
QImage HistogramGenerator::drawComponent(const int *y, const QSize &size, const float &scaling, const QColor &color,
|
||||
const bool &unscaled, const uint &max) const
|
||||
bool unscaled, uint max) const
|
||||
{
|
||||
QImage component(max, size.height(), QImage::Format_ARGB32);
|
||||
component.fill(qRgba(0, 0, 0, 0));
|
||||
@@ -156,7 +159,7 @@ QImage HistogramGenerator::drawComponent(const int *y, const QSize &size, const
|
||||
}
|
||||
|
||||
void HistogramGenerator::drawComponentFull(QPainter *davinci, const int *y, const float &scaling, const QRect &rect,
|
||||
const QColor &color, const int &textSpace, const bool &unscaled, const uint &max) const
|
||||
const QColor &color, int textSpace, bool unscaled, uint max) const
|
||||
{
|
||||
QImage component = drawComponent(y, rect.size() - QSize(0, textSpace), scaling, color, unscaled, max);
|
||||
davinci->drawImage(rect.topLeft(), component);
|
||||
|
||||
@@ -22,7 +22,7 @@ class QSize;
|
||||
class HistogramGenerator : public QObject
|
||||
{
|
||||
public:
|
||||
HistogramGenerator();
|
||||
explicit HistogramGenerator();
|
||||
|
||||
/** Recommendation to use.
|
||||
See http://www.poynton.com/ColorFAQ.html for details. */
|
||||
@@ -33,12 +33,12 @@ public:
|
||||
components are OR-ed HistogramGenerator::Components flags and decide with components (Y, R, G, B) to paint.
|
||||
unscaled = true leaves the width at 256 if the widget is wider (to avoid scaling). */
|
||||
QImage calculateHistogram(const QSize ¶deSize, const QImage &image, const int &components, const HistogramGenerator::Rec rec,
|
||||
const bool &unscaled, const uint &accelFactor = 1) const;
|
||||
bool unscaled, uint accelFactor = 1) const;
|
||||
|
||||
QImage drawComponent(const int *y, const QSize &size, const float &scaling, const QColor &color, const bool &unscaled, const uint &max) const;
|
||||
QImage drawComponent(const int *y, const QSize &size, const float &scaling, const QColor &color, bool unscaled, uint max) const;
|
||||
|
||||
void drawComponentFull(QPainter *davinci, const int *y, const float &scaling, const QRect &rect,
|
||||
const QColor &color, const int &textSpace, const bool &unscaled, const uint &max) const;
|
||||
const QColor &color, int textSpace, bool unscaled, uint max) const;
|
||||
|
||||
enum Components { ComponentY = 1<<0, ComponentR = 1<<1, ComponentG = 1<<2, ComponentB = 1<<3, ComponentSum = 1<<4 };
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ RGBParadeGenerator::RGBParadeGenerator()
|
||||
}
|
||||
|
||||
QImage RGBParadeGenerator::calculateRGBParade(const QSize ¶deSize, const QImage &image,
|
||||
const RGBParadeGenerator::PaintMode paintMode, const bool &drawAxis,
|
||||
const bool &drawGradientRef, const uint &accelFactor)
|
||||
const RGBParadeGenerator::PaintMode paintMode, bool drawAxis,
|
||||
bool drawGradientRef, uint accelFactor)
|
||||
{
|
||||
Q_ASSERT(accelFactor >= 1);
|
||||
|
||||
@@ -47,7 +47,7 @@ QImage RGBParadeGenerator::calculateRGBParade(const QSize ¶deSize, const QIm
|
||||
|
||||
} else {
|
||||
QImage parade(paradeSize, QImage::Format_ARGB32);
|
||||
parade.fill(qRgba(0,0,0,0));
|
||||
parade.fill(Qt::transparent);
|
||||
|
||||
QRgb *col;
|
||||
QPainter davinci(¶de);
|
||||
@@ -80,7 +80,7 @@ QImage RGBParadeGenerator::calculateRGBParade(const QSize ¶deSize, const QIm
|
||||
const float wPrediv = (float)(partW-1)/(iw-1);
|
||||
|
||||
StructRGB paradeVals[partW][256];
|
||||
for (uint i = 0; i < partW; i++) {
|
||||
for (uint i = 0; i < partW; ++i) {
|
||||
for (uint j = 0; j < 256; j++) {
|
||||
paradeVals[i][j].r = 0;
|
||||
paradeVals[i][j].g = 0;
|
||||
@@ -89,10 +89,9 @@ QImage RGBParadeGenerator::calculateRGBParade(const QSize ¶deSize, const QIm
|
||||
}
|
||||
|
||||
const uchar *bits = image.bits();
|
||||
const uint stepsize = 4*accelFactor;
|
||||
const uint stepsize = image.depth() / 8 *accelFactor;
|
||||
|
||||
for (uint i = 0, x = 0; i < byteCount; i += stepsize) {
|
||||
|
||||
col = (QRgb *)bits;
|
||||
r = qRed(*col);
|
||||
g = qGreen(*col);
|
||||
@@ -122,7 +121,7 @@ QImage RGBParadeGenerator::calculateRGBParade(const QSize ¶deSize, const QIm
|
||||
const uint offset2 = 2*partW + 2*offset;
|
||||
switch(paintMode) {
|
||||
case PaintMode_RGB:
|
||||
for (uint i = 0; i < partW; i++) {
|
||||
for (uint i = 0; i < partW; ++i) {
|
||||
for (uint j = 0; j < 256; j++) {
|
||||
unscaled.setPixel(i, j, qRgba(255,10,10, CHOP255(gain*paradeVals[i][j].r)));
|
||||
unscaled.setPixel(i+offset1, j, qRgba(10,255,10, CHOP255(gain*paradeVals[i][j].g)));
|
||||
@@ -131,7 +130,7 @@ QImage RGBParadeGenerator::calculateRGBParade(const QSize ¶deSize, const QIm
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (uint i = 0; i < partW; i++) {
|
||||
for (uint i = 0; i < partW; ++i) {
|
||||
for (uint j = 0; j < 256; j++) {
|
||||
unscaled.setPixel(i, j, qRgba(255,255,255, CHOP255(gain*paradeVals[i][j].r)));
|
||||
unscaled.setPixel(i+offset1, j, qRgba(255,255,255, CHOP255(gain*paradeVals[i][j].g)));
|
||||
@@ -148,7 +147,7 @@ QImage RGBParadeGenerator::calculateRGBParade(const QSize ¶deSize, const QIm
|
||||
|
||||
if (drawAxis) {
|
||||
QRgb opx;
|
||||
for (uint i = 0; i <= 10; i++) {
|
||||
for (uint i = 0; i <= 10; ++i) {
|
||||
dy = (float)i/10 * (partH-1);
|
||||
for (uint x = 0; x < ww-distRight; x++) {
|
||||
opx = parade.pixel(x, dy);
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
|
||||
RGBParadeGenerator();
|
||||
QImage calculateRGBParade(const QSize ¶deSize, const QImage &image, const RGBParadeGenerator::PaintMode paintMode,
|
||||
const bool &drawAxis, const bool &drawGradientRef, const uint &accelFactor = 1);
|
||||
bool drawAxis, bool drawGradientRef, uint accelFactor = 1);
|
||||
|
||||
static const QColor colHighlight;
|
||||
static const QColor colLight;
|
||||
|
||||
@@ -118,7 +118,7 @@ QPoint VectorscopeGenerator::mapToCircle(const QSize &targetSize, const QPointF
|
||||
QImage VectorscopeGenerator::calculateVectorscope(const QSize &vectorscopeSize, const QImage &image, const float &gain,
|
||||
const VectorscopeGenerator::PaintMode &paintMode,
|
||||
const VectorscopeGenerator::ColorSpace &colorSpace,
|
||||
const bool &, const uint &accelFactor) const
|
||||
bool, uint accelFactor) const
|
||||
{
|
||||
if (vectorscopeSize.width() <= 0 || vectorscopeSize.height() <= 0 || image.width() <= 0 || image.height() <= 0) {
|
||||
// Invalid size
|
||||
@@ -138,11 +138,11 @@ QImage VectorscopeGenerator::calculateVectorscope(const QSize &vectorscopeSize,
|
||||
QPoint pt;
|
||||
QRgb px;
|
||||
|
||||
const int stepsize = 4 * accelFactor;
|
||||
const int stepsize = image.depth() / 8 * accelFactor;
|
||||
|
||||
// Just an average for the number of image pixels per scope pixel.
|
||||
// NOTE: byteCount() has to be replaced by (img.bytesPerLine()*img.height()) for Qt 4.5 to compile, see: http://doc.trolltech.org/4.6/qimage.html#bytesPerLine
|
||||
double avgPxPerPx = (double) 4*(image.bytesPerLine()*image.height())/scope.size().width()/scope.size().height()/accelFactor;
|
||||
double avgPxPerPx = (double) image.depth() / 8 *(image.bytesPerLine()*image.height())/scope.size().width()/scope.size().height()/accelFactor;
|
||||
|
||||
for (int i = 0; i < (image.bytesPerLine()*image.height()); i+= stepsize) {
|
||||
QRgb *col = (QRgb *) bits;
|
||||
@@ -260,3 +260,5 @@ QImage VectorscopeGenerator::calculateVectorscope(const QSize &vectorscopeSize,
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
#include "vectorscopegenerator.moc"
|
||||
|
||||
@@ -30,13 +30,13 @@ public:
|
||||
QImage calculateVectorscope(const QSize &vectorscopeSize, const QImage &image, const float &gain,
|
||||
const VectorscopeGenerator::PaintMode &paintMode,
|
||||
const VectorscopeGenerator::ColorSpace &colorSpace,
|
||||
const bool&, const uint &accelFactor = 1) const;
|
||||
bool, uint accelFactor = 1) const;
|
||||
|
||||
QPoint mapToCircle(const QSize &targetSize, const QPointF &point) const;
|
||||
static const float scaling;
|
||||
|
||||
signals:
|
||||
void signalCalculationFinished(QImage image, const uint &ms);
|
||||
void signalCalculationFinished(const QImage &image, uint ms);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ WaveformGenerator::~WaveformGenerator()
|
||||
}
|
||||
|
||||
QImage WaveformGenerator::calculateWaveform(const QSize &waveformSize, const QImage &image, WaveformGenerator::PaintMode paintMode,
|
||||
const bool &drawAxis, WaveformGenerator::Rec rec, const uint &accelFactor)
|
||||
bool drawAxis, WaveformGenerator::Rec rec, uint accelFactor)
|
||||
{
|
||||
Q_ASSERT(accelFactor >= 1);
|
||||
|
||||
@@ -57,7 +57,7 @@ QImage WaveformGenerator::calculateWaveform(const QSize &waveformSize, const QIm
|
||||
const uint byteCount = iw*ih;
|
||||
|
||||
uint waveValues[waveformSize.width()][waveformSize.height()];
|
||||
for (int i = 0; i < waveformSize.width(); i++) {
|
||||
for (int i = 0; i < waveformSize.width(); ++i) {
|
||||
for (int j = 0; j < waveformSize.height(); j++) {
|
||||
waveValues[i][j] = 0;
|
||||
}
|
||||
@@ -76,8 +76,9 @@ QImage WaveformGenerator::calculateWaveform(const QSize &waveformSize, const QIm
|
||||
const float wPrediv = (float)(ww-1)/(iw-1);
|
||||
|
||||
const uchar *bits = image.bits();
|
||||
const int bpp = image.depth() / 8;
|
||||
|
||||
for (uint i = 0, x = 0; i < byteCount; i += 4) {
|
||||
for (uint i = 0, x = 0; i < byteCount; i += bpp) {
|
||||
|
||||
Q_ASSERT(bits < image.bits() + byteCount);
|
||||
|
||||
@@ -96,20 +97,20 @@ QImage WaveformGenerator::calculateWaveform(const QSize &waveformSize, const QIm
|
||||
dx = x*wPrediv;
|
||||
waveValues[(int)dx][(int)dy]++;
|
||||
|
||||
bits += 4;
|
||||
x += 4;
|
||||
bits += bpp;
|
||||
x += bpp;
|
||||
if (x > iw) {
|
||||
x -= iw;
|
||||
if (accelFactor > 1) {
|
||||
bits += 4*iw*(accelFactor-1);
|
||||
i += 4*iw*(accelFactor-1);
|
||||
bits += bpp*iw*(accelFactor-1);
|
||||
i += bpp*iw*(accelFactor-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (paintMode) {
|
||||
case PaintMode_Green:
|
||||
for (int i = 0; i < waveformSize.width(); i++) {
|
||||
for (int i = 0; i < waveformSize.width(); ++i) {
|
||||
for (int j = 0; j < waveformSize.height(); j++) {
|
||||
// Logarithmic scale. Needs fine tuning by hand, but looks great.
|
||||
wave.setPixel(i, waveformSize.height()-j-1, qRgba(CHOP255(52*log(0.1*gain*waveValues[i][j])),
|
||||
@@ -120,14 +121,14 @@ QImage WaveformGenerator::calculateWaveform(const QSize &waveformSize, const QIm
|
||||
}
|
||||
break;
|
||||
case PaintMode_Yellow:
|
||||
for (int i = 0; i < waveformSize.width(); i++) {
|
||||
for (int i = 0; i < waveformSize.width(); ++i) {
|
||||
for (int j = 0; j < waveformSize.height(); j++) {
|
||||
wave.setPixel(i, waveformSize.height()-j-1, qRgba(255,242,0, CHOP255(gain*waveValues[i][j])));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (int i = 0; i < waveformSize.width(); i++) {
|
||||
for (int i = 0; i < waveformSize.width(); ++i) {
|
||||
for (int j = 0; j < waveformSize.height(); j++) {
|
||||
wave.setPixel(i, waveformSize.height()-j-1, qRgba(255,255,255, CHOP255(2*gain*waveValues[i][j])));
|
||||
}
|
||||
@@ -140,7 +141,7 @@ QImage WaveformGenerator::calculateWaveform(const QSize &waveformSize, const QIm
|
||||
QRgb opx;
|
||||
davinci.setPen(qRgba(150,255,200,32));
|
||||
davinci.setCompositionMode(QPainter::CompositionMode_Overlay);
|
||||
for (uint i = 0; i <= 10; i++) {
|
||||
for (uint i = 0; i <= 10; ++i) {
|
||||
dy = (float)i/10 * (wh-1);
|
||||
for (uint x = 0; x < ww; x++) {
|
||||
opx = wave.pixel(x, dy);
|
||||
@@ -158,3 +159,5 @@ QImage WaveformGenerator::calculateWaveform(const QSize &waveformSize, const QIm
|
||||
return wave;
|
||||
}
|
||||
#undef CHOP255
|
||||
|
||||
#include "waveformgenerator.moc"
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
~WaveformGenerator();
|
||||
|
||||
QImage calculateWaveform(const QSize &waveformSize, const QImage &image, WaveformGenerator::PaintMode paintMode,
|
||||
const bool &drawAxis, const WaveformGenerator::Rec rec, const uint &accelFactor = 1);
|
||||
bool drawAxis, const WaveformGenerator::Rec rec, uint accelFactor = 1);
|
||||
|
||||
//signals:
|
||||
//void signalCalculationFinished(QImage image, const uint &ms);
|
||||
|
||||
@@ -38,6 +38,23 @@
|
||||
#include <fixx11h.h>
|
||||
#endif
|
||||
|
||||
MyFrame::MyFrame(QWidget* parent) :
|
||||
QFrame(parent)
|
||||
{
|
||||
setFrameStyle(QFrame::Box | QFrame::Plain);
|
||||
setWindowOpacity(0.5);
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void MyFrame::hideEvent ( QHideEvent * event )
|
||||
{
|
||||
QFrame::hideEvent(event);
|
||||
// We need a timer here since hiding the frame will trigger a monitor refresh timer that will
|
||||
// repaint the monitor after 70 ms.
|
||||
QTimer::singleShot(250, this, SIGNAL(getColor()));
|
||||
}
|
||||
|
||||
|
||||
ColorPickerWidget::ColorPickerWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
@@ -59,10 +76,7 @@ ColorPickerWidget::ColorPickerWidget(QWidget *parent) :
|
||||
layout->addWidget(button);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
m_grabRectFrame = new QFrame();
|
||||
m_grabRectFrame->setFrameStyle(QFrame::Box | QFrame::Plain);
|
||||
m_grabRectFrame->setWindowOpacity(0.5);
|
||||
m_grabRectFrame->setWindowFlags(Qt::FramelessWindowHint);
|
||||
m_grabRectFrame = new MyFrame();
|
||||
m_grabRectFrame->hide();
|
||||
}
|
||||
|
||||
@@ -74,6 +88,7 @@ ColorPickerWidget::~ColorPickerWidget()
|
||||
|
||||
void ColorPickerWidget::slotGetAverageColor()
|
||||
{
|
||||
disconnect(m_grabRectFrame, SIGNAL(getColor()), this, SLOT(slotGetAverageColor()));
|
||||
m_grabRect = m_grabRect.normalized();
|
||||
|
||||
int numPixel = m_grabRect.width() * m_grabRect.height();
|
||||
@@ -120,12 +135,14 @@ void ColorPickerWidget::slotGetAverageColor()
|
||||
emit displayMessage(i18n("Calculated average color for rectangle."), -1);
|
||||
|
||||
emit colorPicked(QColor(sumR / numPixel, sumG / numPixel, sumB / numPixel));
|
||||
emit disableCurrentFilter(false);
|
||||
}
|
||||
|
||||
void ColorPickerWidget::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->button() != Qt::LeftButton) {
|
||||
closeEventFilter();
|
||||
emit disableCurrentFilter(false);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
@@ -142,20 +159,20 @@ void ColorPickerWidget::mousePressEvent(QMouseEvent* event)
|
||||
void ColorPickerWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_filterActive) {
|
||||
m_grabRectFrame->hide();
|
||||
|
||||
closeEventFilter();
|
||||
|
||||
m_grabRect.setWidth(event->globalX() - m_grabRect.x());
|
||||
m_grabRect.setHeight(event->globalY() - m_grabRect.y());
|
||||
|
||||
if (m_grabRect.width() * m_grabRect.height() == 0) {
|
||||
m_grabRectFrame->hide();
|
||||
emit colorPicked(grabColor(event->globalPos()));
|
||||
emit disableCurrentFilter(false);
|
||||
} else {
|
||||
// delay because m_grabRectFrame does not hide immediately
|
||||
QTimer::singleShot(50, this, SLOT(slotGetAverageColor()));
|
||||
connect(m_grabRectFrame, SIGNAL(getColor()), this, SLOT(slotGetAverageColor()));
|
||||
m_grabRectFrame->hide();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
@@ -173,6 +190,7 @@ void ColorPickerWidget::mouseMoveEvent(QMouseEvent* event)
|
||||
|
||||
void ColorPickerWidget::slotSetupEventFilter()
|
||||
{
|
||||
emit disableCurrentFilter(true);
|
||||
m_filterActive = true;
|
||||
setFocus();
|
||||
installEventFilter(this);
|
||||
@@ -193,6 +211,7 @@ bool ColorPickerWidget::eventFilter(QObject *object, QEvent *event)
|
||||
// Close color picker on any key press
|
||||
if (event->type() == QEvent::KeyPress || event->type() == QEvent::ShortcutOverride) {
|
||||
closeEventFilter();
|
||||
emit disableCurrentFilter(false);
|
||||
event->setAccepted(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -23,14 +23,27 @@
|
||||
|
||||
#include <QtCore>
|
||||
#include <QWidget>
|
||||
#include <QFrame>
|
||||
|
||||
class QSpinBox;
|
||||
class QFrame;
|
||||
#ifdef Q_WS_X11
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
class MyFrame : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MyFrame(QWidget* parent = 0);
|
||||
|
||||
protected:
|
||||
void hideEvent ( QHideEvent * event );
|
||||
|
||||
signals:
|
||||
void getColor();
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ColorPickerWidget
|
||||
* @brief A widget to pick a color anywhere on the screen.
|
||||
@@ -45,14 +58,14 @@ class ColorPickerWidget : public QWidget
|
||||
|
||||
public:
|
||||
/** @brief Sets up the widget. */
|
||||
ColorPickerWidget(QWidget *parent = 0);
|
||||
explicit ColorPickerWidget(QWidget *parent = 0);
|
||||
/** @brief Makes sure the event filter is removed. */
|
||||
virtual ~ColorPickerWidget();
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent *event);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event);
|
||||
virtual void mouseMoveEvent(QMouseEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
private:
|
||||
@@ -82,8 +95,10 @@ private slots:
|
||||
void slotGetAverageColor();
|
||||
|
||||
signals:
|
||||
void colorPicked(QColor);
|
||||
void colorPicked(const QColor&);
|
||||
void displayMessage(const QString&, int);
|
||||
/** @brief When user wants to pick a color, it's better to disable filter so we get proper color values. */
|
||||
void disableCurrentFilter(bool);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user