Compare commits
668 Commits
touchmahaw
...
threadedau
Author | SHA1 | Date | |
---|---|---|---|
|
20dfb26808 | ||
|
a11651f563 | ||
|
aaa2417e74 | ||
|
add5308bc3 | ||
|
b431c34d5f | ||
|
4ba59c07f9 | ||
|
681521e5a5 | ||
|
8731665257 | ||
|
e406fb90a9 | ||
|
5dabdd73a1 | ||
|
179d84c39b | ||
|
e5636a446e | ||
|
27c7b3fc17 | ||
|
7e35961874 | ||
|
c0688dfc1f | ||
|
f6078403e0 | ||
|
0569ee0f1a | ||
|
7badddb99c | ||
|
d0e0d53ee7 | ||
|
6e176c77a6 | ||
|
ba8cfc3e91 | ||
|
2f97ff63f3 | ||
|
641759c362 | ||
|
ae938cf04c | ||
|
8f13fcdda6 | ||
|
29bca56e56 | ||
|
297b230669 | ||
|
1c6c52056f | ||
|
25bb7bd547 | ||
|
8c175b88c5 | ||
|
85c7cb4186 | ||
|
09a7d790ad | ||
|
d49a43709d | ||
|
96fe10cc9f | ||
|
8626678d23 | ||
|
2a27cbde0d | ||
|
1f10444d5c | ||
|
1bb8ff97d4 | ||
|
518546b525 | ||
|
17e1003714 | ||
|
011ece182f | ||
|
8e742a06d9 | ||
|
3c024ab7ac | ||
|
f216a0fe82 | ||
|
f9b5bda925 | ||
|
edf47aefd1 | ||
|
203b2b251c | ||
|
987e6b97dc | ||
|
4a93e54e63 | ||
|
658201eb98 | ||
|
c0e486df3f | ||
|
e0177ed895 | ||
|
b325d9bf0f | ||
|
9e01e92839 | ||
|
83c53b7150 | ||
|
2fb7c5c289 | ||
|
e9ed034dc7 | ||
|
f88ee0fc82 | ||
|
68188a7958 | ||
|
b537a237a8 | ||
|
1fc3c4c2f2 | ||
|
8d695c5091 | ||
|
d3f4046396 | ||
|
b80f3717b8 | ||
|
7f9fc557a9 | ||
|
14639337d4 | ||
|
0c136e6815 | ||
|
3057cdab5d | ||
|
539f2eb700 | ||
|
4c0c610b15 | ||
|
6ec8f127c0 | ||
|
5db219d571 | ||
|
f3eb8fa30a | ||
|
f70da74f46 | ||
|
35bbfac2c5 | ||
|
b304bf008d | ||
|
ebe39d9fac | ||
|
4bafeb34fd | ||
|
8e1cefbbb7 | ||
|
2d4fb5e00b | ||
|
6e2ac3b931 | ||
|
3c7d73d4ae | ||
|
fca7d05ed7 | ||
|
cf649cdafe | ||
|
7c5a4065df | ||
|
475633c328 | ||
|
f542e97a70 | ||
|
c7ac6b5670 | ||
|
2d92cdade0 | ||
|
b53f83aa95 | ||
|
fa5728d773 | ||
|
85662bb478 | ||
|
a1b3538131 | ||
|
06ba09f357 | ||
|
f70f61ac2f | ||
|
953a271bee | ||
|
0ead914d02 | ||
|
ac8a4b5a3a | ||
|
e3bb4c9b14 | ||
|
d88eaacf8d | ||
|
1a541c43ad | ||
|
edd69b30e0 | ||
|
d85291ae3e | ||
|
ff0ebfbcc1 | ||
|
e0ca2178d0 | ||
|
69f1d776eb | ||
|
2ae503612b | ||
|
f53369089a | ||
|
2f5ebd2071 | ||
|
56cb000130 | ||
|
db5313129e | ||
|
844eb3868a | ||
|
1c14f562ad | ||
|
b26bd5e296 | ||
|
52b77464f1 | ||
|
8152207334 | ||
|
e7826d725e | ||
|
3523609cad | ||
|
663752010c | ||
|
d6778a55cf | ||
|
9418fd0fb8 | ||
|
124706afab | ||
|
cf818f64c6 | ||
|
b94445b32a | ||
|
f025edf095 | ||
|
09bbc9c28d | ||
|
a98f6db089 | ||
|
673fdf1b67 | ||
|
8ebbb55842 | ||
|
df31cbbe77 | ||
|
5c700394a8 | ||
|
d442c2158a | ||
|
11779e2037 | ||
|
855180f905 | ||
|
372eda8f2f | ||
|
e941f74f99 | ||
|
4350fad789 | ||
|
cce80ff535 | ||
|
c82845d22a | ||
|
7ab68fb418 | ||
|
ae56d51076 | ||
|
aa8898a720 | ||
|
e9ab459b30 | ||
|
65779b18eb | ||
|
ca0166d8fd | ||
|
5f62c1abb2 | ||
|
f94fd218a0 | ||
|
f3dfc9631c | ||
|
44fa85af6b | ||
|
cd04d027a0 | ||
|
7829be0936 | ||
|
b98d591077 | ||
|
29fa5c4cd9 | ||
|
70608158fe | ||
|
106740abca | ||
|
1c50db9ce9 | ||
|
2dfa25fbee | ||
|
fa577aa018 | ||
|
0e83e47f1a | ||
|
c1ee97fc40 | ||
|
ec66cf29f3 | ||
|
f1200ac74d | ||
|
be1827e554 | ||
|
b46af3405e | ||
|
6c2ed4baed | ||
|
247e8ffbf4 | ||
|
52d93e8881 | ||
|
5d2e3f37f1 | ||
|
455136a722 | ||
|
ec8fd589e0 | ||
|
5ea8586c59 | ||
|
47cd4de267 | ||
|
22a502fd59 | ||
|
fce45b1d8d | ||
|
2b7623b6d5 | ||
|
5f73c3fb0e | ||
|
9476c3a3de | ||
|
5d13694530 | ||
|
5df328424d | ||
|
51d89c7210 | ||
|
f8d48cc9fc | ||
|
5f7bd6087f | ||
|
7549d73115 | ||
|
5eef57f3b8 | ||
|
4ad6b2bebf | ||
|
af5211aada | ||
|
58b625ef03 | ||
|
4ffbd839eb | ||
|
f8def37879 | ||
|
205bde833f | ||
|
e2bb4d7340 | ||
|
b040870cf1 | ||
|
4de60911cd | ||
|
058808aa61 | ||
|
253d65d5a3 | ||
|
2b682a14ae | ||
|
84d817c9d4 | ||
|
4db10f8195 | ||
|
2277c14882 | ||
|
359fd9761d | ||
|
e9fa2259a7 | ||
|
746d24da50 | ||
|
e341120f64 | ||
|
4e71a56b18 | ||
|
6ec80ee427 | ||
|
28a8ca444b | ||
|
a75e827d62 | ||
|
3dbb4fad41 | ||
|
ecf70e7b86 | ||
|
53c1e0986b | ||
|
16f49b58a8 | ||
|
1df01c77e3 | ||
|
27073eb4f4 | ||
|
eb3d9553ed | ||
|
188dc0b3bd | ||
|
4e7672fd63 | ||
|
6c35a435f0 | ||
|
5263b21138 | ||
|
49d40186be | ||
|
660a7cd059 | ||
|
ad739d0ce8 | ||
|
4e8d0d46fe | ||
|
02713c1661 | ||
|
8d561b5a56 | ||
|
25ece740e2 | ||
|
1c66534cb8 | ||
|
08610eee13 | ||
|
b8ccf9b2af | ||
|
537115fac5 | ||
|
3924521aed | ||
|
8bbe15edee | ||
|
0a686337f8 | ||
|
98d939a81b | ||
|
e1c6e83b98 | ||
|
d41e30c359 | ||
|
4bb63d428f | ||
|
85f970ea2d | ||
|
3411dde52f | ||
|
4a63606c84 | ||
|
2d439ed959 | ||
|
0e213abfd4 | ||
|
be737a24f2 | ||
|
f796f1f133 | ||
|
b2dc6f1f3c | ||
|
d73800bd5f | ||
|
52bb303ffa | ||
|
4e8c99554a | ||
|
428dbe8f0e | ||
|
f24a25b370 | ||
|
4107c01ad1 | ||
|
24c7b0074a | ||
|
378aae9567 | ||
|
742f73f028 | ||
|
52930918f2 | ||
|
be0f2e7e45 | ||
|
6134c4fdec | ||
|
5f1a2df610 | ||
|
d3d29acf09 | ||
|
b32b84f8c7 | ||
|
95ce975d40 | ||
|
8532189b54 | ||
|
1223d3dac3 | ||
|
a6c838cd39 | ||
|
03f0870f53 | ||
|
931959ecc8 | ||
|
b34037f26f | ||
|
f95e2ad703 | ||
|
5fac4a34bd | ||
|
3f9c2366f2 | ||
|
a708f37cd6 | ||
|
dd1071f180 | ||
|
576a886937 | ||
|
1208035da3 | ||
|
7944c9f826 | ||
|
6ee7df9514 | ||
|
4a3b6aa1d3 | ||
|
77b8224949 | ||
|
c4c94de1ac | ||
|
75cb466909 | ||
|
fd6235995f | ||
|
840460d960 | ||
|
3b46f3fe32 | ||
|
a2281dcf58 | ||
|
a19eb9c447 | ||
|
ceffbb6a77 | ||
|
c5439b4e7d | ||
|
0b227eff42 | ||
|
033b4cc6cc | ||
|
4fdec44755 | ||
|
6606bd4185 | ||
|
7cc964dfc5 | ||
|
b3bfc2b464 | ||
|
a937ac265c | ||
|
1058dd93f1 | ||
|
f4f9a148af | ||
|
d07f191a1e | ||
|
0ba9a9e076 | ||
|
ac7aadf615 | ||
|
3873189d79 | ||
|
891692d914 | ||
|
2d31de245f | ||
|
8c587e9b75 | ||
|
84622380d6 | ||
|
0736a65f2a | ||
|
658deb3bcd | ||
|
cfed5be1ca | ||
|
9fa4033b2a | ||
|
2c620ba440 | ||
|
01bf3a3818 | ||
|
8641222395 | ||
|
b4aedd606c | ||
|
ee1afc665f | ||
|
57e31e1319 | ||
|
46f6941325 | ||
|
61f3e1854c | ||
|
5cb327af38 | ||
|
648b2d69f9 | ||
|
e4f8c229b4 | ||
|
189e3ea348 | ||
|
e2c71e7a18 | ||
|
3b1268bbfd | ||
|
248d26fe69 | ||
|
afcac34208 | ||
|
9aa6e2a338 | ||
|
434acf21a4 | ||
|
aaf0df736b | ||
|
bb0d82aa10 | ||
|
9556414bf5 | ||
|
172ccd0428 | ||
|
31a9c75c08 | ||
|
fde7ef75af | ||
|
af7b20ee55 | ||
|
0277d1213e | ||
|
c62c4fa1d9 | ||
|
a520f7bff3 | ||
|
37f5b9114e | ||
|
d2dc3082b1 | ||
|
bd4d5da641 | ||
|
dad65da497 | ||
|
49aadaab0e | ||
|
864d665494 | ||
|
719151b44e | ||
|
1c3a9da5ed | ||
|
154b672d47 | ||
|
cfa2268c05 | ||
|
d37fd8955c | ||
|
a7d30582a6 | ||
|
0a570849c5 | ||
|
442d1b2713 | ||
|
9749df00d1 | ||
|
8a9a48fda1 | ||
|
777ebd77c8 | ||
|
36855783a7 | ||
|
8595539dea | ||
|
687ed02df0 | ||
|
3b861983e6 | ||
|
9caf9fc98f | ||
|
f58ba2926e | ||
|
049184bdfd | ||
|
6d6f51fdb6 | ||
|
2ee085d13d | ||
|
fb8a761278 | ||
|
625a7b8fda | ||
|
b15bef72df | ||
|
0aa65e2d95 | ||
|
53acf6420e | ||
|
f54dee3ccc | ||
|
b494d5ae79 | ||
|
7975140452 | ||
|
11ea67632c | ||
|
af09c04834 | ||
|
90d6492de6 | ||
|
73bcbd2590 | ||
|
faf3558754 | ||
|
37719a247e | ||
|
08df9f924f | ||
|
5812b2bec1 | ||
|
1d54be04e0 | ||
|
de98665b00 | ||
|
f23af07f6a | ||
|
9904367106 | ||
|
46a73566f5 | ||
|
2de19a1c94 | ||
|
5594e25dcf | ||
|
0c47327fc4 | ||
|
d6bf6744d8 | ||
|
094e8653ff | ||
|
5d6f31a25d | ||
|
545b6abfa1 | ||
|
d8270bddfa | ||
|
dfb03eabe6 | ||
|
6ea9dc4f1b | ||
|
acfaf3970e | ||
|
4402bd8f03 | ||
|
56280db289 | ||
|
6ebc103bc5 | ||
|
a40253da26 | ||
|
8f181bc4a0 | ||
|
625dc0304b | ||
|
5f9c21120d | ||
|
1e6bbba189 | ||
|
13ac8c093a | ||
|
d7e68f3a1d | ||
|
d60b38b3aa | ||
|
e47b750d21 | ||
|
ff764df4af | ||
|
630439cddf | ||
|
8b477e1f71 | ||
|
e021695230 | ||
|
70f00872a1 | ||
|
f14ae332eb | ||
|
76ff49a8ba | ||
|
dad726b6ca | ||
|
4aa8ec6bb8 | ||
|
757f1c6175 | ||
|
cfa5c9932e | ||
|
4bbb07ee1f | ||
|
66581fcaa2 | ||
|
b83e9bbf82 | ||
|
48a3ad29ff | ||
|
cede16bc50 | ||
|
e57105669c | ||
|
17480fd887 | ||
|
42d8476ea1 | ||
|
d901f0ba86 | ||
|
cea780b85b | ||
|
381e89d3df | ||
|
b4a8e32f44 | ||
|
26a7d37298 | ||
|
9291c75669 | ||
|
f61d0a07b1 | ||
|
999e0ad4c2 | ||
|
1721a0b693 | ||
|
2ceb075706 | ||
|
9a84a7deea | ||
|
1f6323941b | ||
|
c6c91181ab | ||
|
e4e9f1bec8 | ||
|
18d9360ad3 | ||
|
efbbdf1e72 | ||
|
624c05bdf4 | ||
|
e0d63535a6 | ||
|
7832dd42b2 | ||
|
d49294d288 | ||
|
b84a884387 | ||
|
9eeed5223c | ||
|
f520b6d5d0 | ||
|
d3ce2162ca | ||
|
1cc1ba2b7a | ||
|
6c0d984990 | ||
|
08e4da1c8a | ||
|
ba77ca4292 | ||
|
398d2c7cce | ||
|
b513a34fb8 | ||
|
272c31f132 | ||
|
ef9a790df0 | ||
|
f020df31d2 | ||
|
d26cf3de9d | ||
|
6af4ff6537 | ||
|
5c4a7dd273 | ||
|
41fb2ee1dc | ||
|
656221dcc0 | ||
|
2b8825f814 | ||
|
020da4d5c8 | ||
|
e0d1fb72a8 | ||
|
6d61173bca | ||
|
0f4b1bc91b | ||
|
36738fc9e4 | ||
|
5750f51bdd | ||
|
c569678a26 | ||
|
af19a09a3c | ||
|
92fb2dbb0d | ||
|
bc33bd8420 | ||
|
27c2bc1b2d | ||
|
337be1f989 | ||
|
6c9c3ce7ec | ||
|
495fe05a75 | ||
|
ab61314e0f | ||
|
70c1cc8829 | ||
|
b6c1d06165 | ||
|
d40ed14d80 | ||
|
6970ea39e4 | ||
|
2ce5bb1fea | ||
|
6fb920c826 | ||
|
40dc30044f | ||
|
b9515d3408 | ||
|
b99a1a753c | ||
|
e1d4088d98 | ||
|
a1cd3cf5bb | ||
|
cf054875b5 | ||
|
61e934bacc | ||
|
13a1eed144 | ||
|
a2cc3ee2fd | ||
|
483386e440 | ||
|
695902d962 | ||
|
6d62fb8c1e | ||
|
9f0febe402 | ||
|
bbb28032e7 | ||
|
97b57009c9 | ||
|
c96ecd9697 | ||
|
e0edb2b15b | ||
|
f32bab7733 | ||
|
bc266e1f7c | ||
|
5b48442006 | ||
|
bf009c8854 | ||
|
898ad5804e | ||
|
dfd36d459b | ||
|
5ceb04e571 | ||
|
4ca29feab1 | ||
|
95e1d8c5a3 | ||
|
22e69bbb8c | ||
|
b8aa4e1bc3 | ||
|
b6cc9dae09 | ||
|
e6a394e8e7 | ||
|
4e09f52b22 | ||
|
903ea66b36 | ||
|
525072f757 | ||
|
b741d163a1 | ||
|
b1a135fff9 | ||
|
d8d7347394 | ||
|
d8b07cee9c | ||
|
729c9237fe | ||
|
b2fc9cb8ac | ||
|
89c04ea3f6 | ||
|
93bf2e1bb9 | ||
|
0504bec81d | ||
|
7f9ded7816 | ||
|
c915f2f161 | ||
|
034510cdda | ||
|
6899b38944 | ||
|
b3aa6c9a6c | ||
|
eddc7bbf4e | ||
|
9bc112090d | ||
|
0b37514cfe | ||
|
e93ef1dd6e | ||
|
fe7b798cda | ||
|
a0cd7869bc | ||
|
c2d0382bae | ||
|
bb09c15c30 | ||
|
0a68b36295 | ||
|
b4a8154eae | ||
|
869640b2e2 | ||
|
de982f8b50 | ||
|
0ed8e62de8 | ||
|
5f677d4c83 | ||
|
6218cec38a | ||
|
c2d9baa9d9 | ||
|
8f6cc7846a | ||
|
a2f139c204 | ||
|
22d3048017 | ||
|
1367d82006 | ||
|
9572c440ea | ||
|
45b57b715f | ||
|
48e3eb877d | ||
|
9ec9fb9362 | ||
|
f32c1f1338 | ||
|
4f14ce96cb | ||
|
aeeff01d64 | ||
|
2bc71743de | ||
|
0cffdf124a | ||
|
789b698e7a | ||
|
0dbe87e2f4 | ||
|
0e069c6b88 | ||
|
f4ccb9f802 | ||
|
3bf2fa1237 | ||
|
7609906994 | ||
|
c626a161cd | ||
|
bcf84c2b8c | ||
|
d15878555f | ||
|
5121d060db | ||
|
f48c2c9b5c | ||
|
2c9c5ea8bb | ||
|
2b8a1fa2ca | ||
|
6c55d1e510 | ||
|
577a706b9f | ||
|
e7d78ea52e | ||
|
2b947254d5 | ||
|
32da3965f8 | ||
|
44e10db28d | ||
|
bc96846839 | ||
|
1425b68c39 | ||
|
f3e45bd240 | ||
|
d2bd6b8744 | ||
|
dbb9d14deb | ||
|
6ec2fae320 | ||
|
ef81026ffb | ||
|
45a276cf33 | ||
|
c6259d2feb | ||
|
3a7cab851d | ||
|
158bbff8de | ||
|
3f457d4a00 | ||
|
9cb06d70b2 | ||
|
e616e33239 | ||
|
c2c6ace3e5 | ||
|
7fa7fe3886 | ||
|
8f61715b6d | ||
|
e4918e777e | ||
|
19da9ef754 | ||
|
0a07750efb | ||
|
c78fe2f701 | ||
|
9ea1fa7f4b | ||
|
b9087ad7b7 | ||
|
efaa1eb18f | ||
|
89f39f1a1f | ||
|
b0ae9fead5 | ||
|
983acfc7e4 | ||
|
79920efe4f | ||
|
b250d13362 | ||
|
df13198c5c | ||
|
202c4b821e | ||
|
e789066b9b | ||
|
46ffedf530 | ||
|
fd72e7fa4e | ||
|
a9e08a7104 | ||
|
442a933f9b | ||
|
a2d6d82d83 | ||
|
2a7adda968 | ||
|
98aaec0ffd | ||
|
c0183aa359 | ||
|
c3197a39b0 | ||
|
6789c1f032 | ||
|
6fe1d178dd | ||
|
859d2e8641 | ||
|
3787eefa48 | ||
|
54f280f792 | ||
|
401f691359 | ||
|
77b0adaf7f | ||
|
7b5ab89fef | ||
|
464170cca9 | ||
|
dcdb937cf3 | ||
|
2c180c6123 | ||
|
1540b7b5bf | ||
|
030b91ba9f | ||
|
76d4821295 | ||
|
e72cf5423c | ||
|
ad7ac35422 | ||
|
ea21848811 | ||
|
a65d037def | ||
|
a667fbd8b4 | ||
|
92240b6e0c | ||
|
20eeaf73ac | ||
|
a1314347f9 | ||
|
fab69e3cae | ||
|
cc2cc8397e | ||
|
fe7d128056 | ||
|
d3a8f57e1c | ||
|
96c279275e | ||
|
d6a504c38b | ||
|
b1224c0a2b | ||
|
694787c8d6 | ||
|
8a6254c47e | ||
|
216d4511f7 | ||
|
043aa8755d | ||
|
e772dcecad | ||
|
ac99970bd4 | ||
|
7547250631 | ||
|
06bd6edc8c | ||
|
98aa2a447e | ||
|
00973e6365 | ||
|
dc11760640 | ||
|
1f955ae8d5 | ||
|
8c6ef2f533 | ||
|
d4f12d6d33 | ||
|
00f2195dd2 | ||
|
23ecf1264f | ||
|
7fcdbe9c9e | ||
|
8fa8f9b733 | ||
|
7a731c0fa5 |
1
.gitignore
vendored
@@ -17,3 +17,4 @@ clang/
|
||||
win/
|
||||
gcc/
|
||||
tags
|
||||
.DS_Store
|
||||
|
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "thirdparty/jreen"]
|
||||
path = thirdparty/jreen
|
||||
url = git://github.com/euroelessar/jreen.git
|
||||
[submodule "thirdparty/qtweetlib/QTweetLib"]
|
||||
path = thirdparty/qtweetlib/QTweetLib
|
||||
url = git://github.com/minimoog/QTweetLib.git
|
||||
|
@@ -15,7 +15,7 @@ SET( TOMAHAWK_APPLICATION_NAME "Tomahawk" )
|
||||
SET( TOMAHAWK_DESCRIPTION_SUMMARY "The social media player" )
|
||||
|
||||
SET( TOMAHAWK_VERSION_MAJOR 0 )
|
||||
SET( TOMAHAWK_VERSION_MINOR 2 )
|
||||
SET( TOMAHAWK_VERSION_MINOR 3 )
|
||||
SET( TOMAHAWK_VERSION_PATCH 99 )
|
||||
|
||||
#SET( TOMAHAWK_VERSION_RC 0 )
|
||||
@@ -24,8 +24,6 @@ SET( TOMAHAWK_VERSION_PATCH 99 )
|
||||
# build options
|
||||
option(BUILD_GUI "Build Tomahawk with GUI" ON)
|
||||
option(BUILD_RELEASE "Generate TOMAHAWK_VERSION without GIT info" OFF)
|
||||
option(BUILD_GUI_QML"Build Tomahawk with QML Support" OFF)
|
||||
|
||||
|
||||
# generate version string
|
||||
|
||||
@@ -50,7 +48,6 @@ IF( NOT BUILD_RELEASE )
|
||||
ENDIF()
|
||||
|
||||
|
||||
|
||||
# set paths
|
||||
SET( THIRDPARTY_DIR ${CMAKE_SOURCE_DIR}/thirdparty )
|
||||
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
|
||||
@@ -73,11 +70,6 @@ ELSE()
|
||||
MESSAGE( STATUS "Building Tomahawk ${TOMAHAWK_VERSION} full GUI version ***" )
|
||||
LIST(APPEND NEEDED_QT4_COMPONENTS "QtGui" "QtWebkit" )
|
||||
ENDIF()
|
||||
IF( BUILD_GUI_QML )
|
||||
MESSAGE( STATUS "Building Tomahawk QML version ***" )
|
||||
LIST(APPEND NEEDED_QT4_COMPONENTS "QtDeclarative" )
|
||||
ENDIF()
|
||||
|
||||
|
||||
IF( BUILD_GUI AND UNIX AND NOT APPLE )
|
||||
FIND_PACKAGE( X11 )
|
||||
@@ -92,8 +84,8 @@ if(PHONON_FOUND)
|
||||
message(STATUS "Phonon found; ensure that phonon-vlc is at least 0.4")
|
||||
endif()
|
||||
|
||||
macro_optional_find_package(LibEchonest 1.1.7)
|
||||
macro_log_feature(LIBECHONEST_FOUND "Echonest" "Qt library for communicating with The Echo Nest" "http://projects.kde.org/libechonest" TRUE "" "libechonest 1.1.8 is needed for dynamic playlists and the infosystem")
|
||||
macro_optional_find_package(LibEchonest 1.1.10)
|
||||
macro_log_feature(LIBECHONEST_FOUND "Echonest" "Qt library for communicating with The Echo Nest" "http://projects.kde.org/libechonest" TRUE "" "libechonest 1.1.10 is needed for dynamic playlists and the infosystem")
|
||||
|
||||
macro_optional_find_package(CLucene 0.9.23)
|
||||
macro_log_feature(CLucene_FOUND "CLucene" "The open-source, C++ search engine" "http://clucene.sf.net" TRUE "" "CLucene is used for indexing the collection")
|
||||
@@ -112,14 +104,39 @@ macro_log_feature(Boost_FOUND "Boost" "Provides free peer-reviewed portable C++
|
||||
macro_optional_find_package(QCA2)
|
||||
macro_log_feature(QCA2_FOUND "QCA2" "Provides encryption and signing functions required for Grooveshark resolver" "http://delta.affinix.com/qca/" FALSE "" "")
|
||||
|
||||
macro_optional_find_package(LibAttica)
|
||||
macro_log_feature(LIBATTICA_FOUND "libattica" "Provides support for automatic fetching and managing of resolvers from the tomahawk website" "https://projects.kde.org/projects/kdesupport/attica" FALSE "" "")
|
||||
|
||||
macro_optional_find_package(QuaZip)
|
||||
macro_log_feature(QuaZip_FOUND "QuaZip" "Provides support for extracting downloaded resolvers autmatically. Will build internal copy instead." "http://quazip.sourceforge.net/" FALSE "" "")
|
||||
|
||||
IF( NOT QuaZip_FOUND )
|
||||
add_subdirectory( ${CMAKE_SOURCE_DIR}/src/libtomahawk/thirdparty/quazip )
|
||||
SET( QuaZip_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/libtomahawk/thirdparty/quazip )
|
||||
SET( QuaZip_LIBRARY quazip )
|
||||
SET( QuaZip_LIBRARIES ${QuaZip_LIBRARY} )
|
||||
SET( QuaZip_FOUND true )
|
||||
|
||||
# copy headers to build/quazip so we can use proper includes inside the code
|
||||
FILE( COPY ${CMAKE_SOURCE_DIR}/src/libtomahawk/thirdparty/quazip/quazip/ DESTINATION ${CMAKE_BINARY_DIR}/libtomahawk/thirdparty/quazip )
|
||||
ENDIF()
|
||||
|
||||
# required
|
||||
#While we distribute our own liblastfm2, don't need to look for it
|
||||
#macro_optional_find_package(LibLastFm 0.3.3)
|
||||
#macro_log_feature(LIBLASTFM_FOUND "LastFm" "Qt library for the Last.fm webservices" "https://github.com/mxcl/liblastfm" FALSE "" "liblastfm is needed for scrobbling tracks to Last.fm and fetching cover artwork")
|
||||
set(LIBLASTFM_FOUND true)
|
||||
|
||||
#### submodules start
|
||||
|
||||
# this installs headers and such and should really be handled in a separate package by packagers
|
||||
IF( INTERNAL_JREEN )
|
||||
IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.gitmodules)
|
||||
EXECUTE_PROCESS(COMMAND git submodule init WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
|
||||
EXECUTE_PROCESS(COMMAND git submodule update WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
|
||||
ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.gitmodules)
|
||||
ENDIF()
|
||||
|
||||
IF( INTERNAL_JREEN )
|
||||
ADD_SUBDIRECTORY( ${THIRDPARTY_DIR}/jreen )
|
||||
SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include )
|
||||
@@ -132,20 +149,9 @@ ELSE( INTERNAL_JREEN )
|
||||
ENDIF( INTERNAL_JREEN )
|
||||
macro_log_feature(LIBJREEN_FOUND "Jreen" "Qt XMPP Library" "https://github.com/euroelessar/jreen" FALSE "" "Jreen is needed for the Jabber SIP plugin. \n\n Use -DINTERNAL_JREEN=ON to build the git submodule inside Tomahawk \n Be aware this installs a full jreen with headers and everything!\n")
|
||||
|
||||
# this installs headers and such and should really be handled in a separate package by packagers
|
||||
IF( INTERNAL_QTWEETLIB )
|
||||
ADD_SUBDIRECTORY( ${THIRDPARTY_DIR}/qtweetlib )
|
||||
# copy headers to build/QTweetLib so we can use proper includes inside the code
|
||||
FILE( COPY ${CMAKE_SOURCE_DIR}/thirdparty/qtweetlib/QTweetLib/src/ DESTINATION ${CMAKE_BINARY_DIR}/QTweetLib )
|
||||
SET( QTWEETLIB_INCLUDE_DIR ${CMAKE_BINARY_DIR} )
|
||||
SET( QTWEETLIB_LIBRARY tomahawk_qtweetlib )
|
||||
SET( QTWEETLIB_LIBRARIES ${QTWEETLIB_LIBRARY} )
|
||||
SET( QTWEETLIB_FOUND true )
|
||||
MESSAGE(STATUS "INTERNAL libQTweetLib: ${QTWEETLIB_INCLUDE_DIR}, ${QTWEETLIB_LIBRARY}")
|
||||
ELSE( INTERNAL_QTWEETLIB )
|
||||
macro_optional_find_package(QTweetLib)
|
||||
ENDIF( INTERNAL_QTWEETLIB )
|
||||
macro_log_feature(QTWEETLIB_FOUND "QTweetLib" "Qt Twitter Library" "https://github.com/minimoog/QTweetLib" FALSE "" "QTweetLib is needed for the Twitter SIP plugin. \n\n Use -DINTERNAL_QTWEETLIB=ON to build the git submodule inside Tomahawk \n")
|
||||
macro_optional_find_package(QTweetLib)
|
||||
macro_log_feature(QTWEETLIB_FOUND "QTweetLib" "Qt Twitter Library" "https://github.com/minimoog/QTweetLib" FALSE "" "QTweetLib is needed for the Twitter SIP plugin.\n")
|
||||
#### submodules end
|
||||
|
||||
### libportfwd
|
||||
SET( LIBPORTFWD_INCLUDE_DIR ${THIRDPARTY_DIR}/libportfwd/include )
|
||||
@@ -154,8 +160,8 @@ SET( LIBPORTFWD_LIBRARIES ${LIBPORTFWD_LIBRARY} )
|
||||
ADD_SUBDIRECTORY( ${THIRDPARTY_DIR}/libportfwd )
|
||||
|
||||
# we need pthreads too
|
||||
macro_optional_find_package(Threads)
|
||||
macro_log_feature(THREADS_FOUND "Threads" "Threading Library" "" TRUE "" "Platform specific library for threading")
|
||||
#macro_optional_find_package(Threads)
|
||||
#macro_log_feature(THREADS_FOUND "Threads" "Threading Library" "" TRUE "" "Platform specific library for threading")
|
||||
|
||||
macro_optional_find_package(KDE4)
|
||||
macro_optional_find_package(KDE4Installed)
|
||||
@@ -205,3 +211,6 @@ ADD_SUBDIRECTORY( src/libtomahawk )
|
||||
SET( TOMAHAWK_LIBRARIES tomahawklib )
|
||||
ADD_SUBDIRECTORY( src )
|
||||
ADD_SUBDIRECTORY( admin )
|
||||
IF(BUILD_GUI)
|
||||
ADD_SUBDIRECTORY( src/breakpad/CrashReporter )
|
||||
ENDIF()
|
||||
|
@@ -12,7 +12,15 @@
|
||||
INCLUDE(CheckSymbolExists)
|
||||
INCLUDE(FindLibraryWithDebug)
|
||||
|
||||
# try to locate a patched unstable version (for comp's sake *sigh*) first
|
||||
FIND_PACKAGE(CLuceneUnstable)
|
||||
IF(CLUCENEUNSTABLE_FOUND)
|
||||
SET(CLucene_FOUND TRUE)
|
||||
SET(CLUCENE_INCLUDE_DIR ${CLUCENE_UNSTABLE_INCLUDE_DIRS})
|
||||
SET(CLUCENE_LIBRARIES ${CLUCENE_UNSTABLE_LIBS})
|
||||
|
||||
#MESSAGE(FATAL_ERROR NARF)
|
||||
ELSE(CLUCENEUNSTABLE_FOUND)
|
||||
IF(CLucene_FIND_VERSION)
|
||||
SET(CLUCENE_MIN_VERSION ${CLucene_FIND_VERSION})
|
||||
ELSEIF()
|
||||
@@ -99,6 +107,7 @@ ENDIF (CLUCENE_LIBRARY_DIR)
|
||||
IF(CLUCENE_INCLUDE_DIR AND CLUCENE_LIBRARIES AND CLUCENE_LIBRARY_DIR AND CLUCENE_GOOD_VERSION)
|
||||
SET(CLucene_FOUND TRUE)
|
||||
ENDIF(CLUCENE_INCLUDE_DIR AND CLUCENE_LIBRARIES AND CLUCENE_LIBRARY_DIR AND CLUCENE_GOOD_VERSION)
|
||||
ENDIF(CLUCENEUNSTABLE_FOUND)
|
||||
|
||||
IF(CLucene_FOUND)
|
||||
IF(NOT CLucene_FIND_QUIETLY)
|
||||
|
37
CMakeModules/FindCLuceneUnstable.cmake
Normal file
@@ -0,0 +1,37 @@
|
||||
# - Try to find clucene-unstable
|
||||
# This is a workaround for distros, that want to ship a recent enough clucene but don't want to replace the old version
|
||||
#
|
||||
# CLUCENEUNSTABLE_FOUND - system has clucene-unstable
|
||||
# CLUCENE_UNSTABLE_INCLUDE_DIR - the clucene-unstable include directories
|
||||
# CLUCENE_UNSTABLE_LIBS - link these to use clucene-unstable
|
||||
#
|
||||
# (c) Dominik Schmidt <dev@dominik-schmidt.de>
|
||||
#
|
||||
|
||||
# Include dir
|
||||
find_path(CLUCENE_UNSTABLE_INCLUDE_DIR
|
||||
NAMES CLucene.h
|
||||
PATH_SUFFIXES clucene-unstable
|
||||
PATHS ${KDE4_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
# Finally the library itself
|
||||
find_library(CLUCENE_UNSTABLE_SHARED_LIB
|
||||
NAMES clucene-unstable-shared
|
||||
PATHS ${KDE4_LIB_DIR}
|
||||
)
|
||||
|
||||
find_library(CLUCENE_UNSTABLE_CORE_LIB
|
||||
NAMES clucene-unstable-core
|
||||
PATHS ${KDE4_LIB_DIR}
|
||||
)
|
||||
|
||||
|
||||
SET( CLUCENE_UNSTABLE_LIBS ${CLUCENE_UNSTABLE_SHARED_LIB} ${CLUCENE_UNSTABLE_CORE_LIB} )
|
||||
SET( CLUCENE_UNSTABLE_INCLUDE_DIRS ${CLUCENE_UNSTABLE_INCLUDE_DIR})
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CLuceneUnstable DEFAULT_MSG CLUCENE_UNSTABLE_LIBS CLUCENE_UNSTABLE_INCLUDE_DIRS)
|
||||
|
||||
|
||||
MARK_AS_ADVANCED(CLUCENE_UNSTABLE_LIBS CLUCENE_UNSTABLE_INCLUDE_DIRS)
|
||||
|
63
CMakeModules/FindLibAttica.cmake
Normal file
@@ -0,0 +1,63 @@
|
||||
# Try to find the Attica library
|
||||
# Once done this will define
|
||||
#
|
||||
# LIBATTICA_FOUND Indicates that Attica was found
|
||||
# LIBATTICA_LIBRARIES Libraries needed to use Attica
|
||||
# LIBATTICA_LIBRARY_DIRS Paths needed for linking against Attica
|
||||
# LIBATTICA_INCLUDE_DIR Path needed for finding Attica include files
|
||||
#
|
||||
# The minimum required version of LibAttica can be specified using the
|
||||
# standard syntax, e.g. find_package(LibAttica 0.20)
|
||||
|
||||
# Copyright (c) 2009 Frederik Gladhorn <gladhorn@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
|
||||
# Support LIBATTICA_MIN_VERSION for compatibility:
|
||||
IF(NOT LibAttica_FIND_VERSION)
|
||||
SET(LibAttica_FIND_VERSION "${LIBATTICA_MIN_VERSION}")
|
||||
ENDIF(NOT LibAttica_FIND_VERSION)
|
||||
|
||||
# the minimum version of LibAttica we require
|
||||
IF(NOT LibAttica_FIND_VERSION)
|
||||
SET(LibAttica_FIND_VERSION "0.1.0")
|
||||
ENDIF(NOT LibAttica_FIND_VERSION)
|
||||
|
||||
|
||||
IF (NOT WIN32)
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
PKG_CHECK_MODULES(PC_LIBATTICA QUIET libattica)
|
||||
SET(LIBATTICA_DEFINITIONS ${PC_ATTICA_CFLAGS_OTHER})
|
||||
ENDIF (NOT WIN32)
|
||||
|
||||
FIND_PATH(LIBATTICA_INCLUDE_DIR attica/provider.h
|
||||
HINTS
|
||||
${PC_LIBATTICA_INCLUDEDIR}
|
||||
${PC_LIBATTICA_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES attica
|
||||
)
|
||||
|
||||
# Store the version number in the cache, so we don't have to search everytime:
|
||||
IF(LIBATTICA_INCLUDE_DIR AND NOT LIBATTICA_VERSION)
|
||||
FILE(READ ${LIBATTICA_INCLUDE_DIR}/attica/version.h LIBATTICA_VERSION_CONTENT)
|
||||
STRING (REGEX MATCH "LIBATTICA_VERSION_STRING \".*\"\n" LIBATTICA_VERSION_MATCH "${LIBATTICA_VERSION_CONTENT}")
|
||||
IF(LIBATTICA_VERSION_MATCH)
|
||||
STRING(REGEX REPLACE "LIBATTICA_VERSION_STRING \"(.*)\"\n" "\\1" _LIBATTICA_VERSION ${LIBATTICA_VERSION_MATCH})
|
||||
ENDIF(LIBATTICA_VERSION_MATCH)
|
||||
SET(LIBATTICA_VERSION "${_LIBATTICA_VERSION}" CACHE STRING "Version number of LibAttica" FORCE)
|
||||
ENDIF(LIBATTICA_INCLUDE_DIR AND NOT LIBATTICA_VERSION)
|
||||
|
||||
|
||||
FIND_LIBRARY(LIBATTICA_LIBRARIES NAMES attica libattica
|
||||
HINTS
|
||||
${PC_LIBATTICA_LIBDIR}
|
||||
${PC_LIBATTICA_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibAttica REQUIRED_VARS LIBATTICA_LIBRARIES LIBATTICA_INCLUDE_DIR
|
||||
VERSION_VAR LIBATTICA_VERSION)
|
||||
|
||||
MARK_AS_ADVANCED(LIBATTICA_INCLUDE_DIR LIBATTICA_LIBRARIES)
|
@@ -19,53 +19,19 @@ macro(_phonon_find_version)
|
||||
file(READ ${_phonon_namespace_header_file} _phonon_header LIMIT 5000 OFFSET 1000)
|
||||
string(REGEX MATCH "define PHONON_VERSION_STR \"(4\\.[0-9]+\\.[0-9a-z]+)\"" _phonon_version_match "${_phonon_header}")
|
||||
set(PHONON_VERSION "${CMAKE_MATCH_1}")
|
||||
message(STATUS "Phonon Version: ${PHONON_VERSION}")
|
||||
endmacro(_phonon_find_version)
|
||||
|
||||
if(PHONON_FOUND)
|
||||
# Already found, nothing more to do except figuring out the version
|
||||
# the dirs listed with HINTS are searched before the default sets of dirs
|
||||
find_library(PHONON_LIBRARY NAMES phonon HINTS ${KDE4_LIB_INSTALL_DIR} ${QT_LIBRARY_DIR})
|
||||
find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h HINTS ${KDE4_INCLUDE_INSTALL_DIR} ${QT_INCLUDE_DIR} ${INCLUDE_INSTALL_DIR} ${QT_LIBRARY_DIR})
|
||||
|
||||
if(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||
set(PHONON_LIBS ${phonon_LIB_DEPENDS} ${PHONON_LIBRARY})
|
||||
set(PHONON_INCLUDES ${PHONON_INCLUDE_DIR}/KDE ${PHONON_INCLUDE_DIR})
|
||||
_phonon_find_version()
|
||||
else(PHONON_FOUND)
|
||||
if(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||
set(PHONON_FIND_QUIETLY TRUE)
|
||||
endif(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||
endif(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||
|
||||
# As discussed on kde-buildsystem: first look at CMAKE_PREFIX_PATH, then at the suggested PATHS (kde4 install dir)
|
||||
find_library(PHONON_LIBRARY NAMES phonon phonon4 PATHS ${KDE4_LIB_INSTALL_DIR} ${QT_LIBRARY_DIR})
|
||||
# then at the default system locations (CMAKE_SYSTEM_PREFIX_PATH, i.e. /usr etc.)
|
||||
find_library(PHONON_LIBRARY NAMES phonon phonon4)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Phonon DEFAULT_MSG PHONON_INCLUDE_DIR PHONON_LIBRARY)
|
||||
|
||||
find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h PATHS ${KDE4_INCLUDE_INSTALL_DIR} ${QT_INCLUDE_DIR} ${INCLUDE_INSTALL_DIR} ${QT_LIBRARY_DIR})
|
||||
find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h)
|
||||
|
||||
_phonon_find_version()
|
||||
if(PHONON_INCLUDE_DIR AND PHONON_LIBRARY AND NOT PHONON_VERSION VERSION_LESS ${Phonon_FIND_VERSION})
|
||||
set(PHONON_LIBS ${phonon_LIB_DEPENDS} ${PHONON_LIBRARY})
|
||||
set(PHONON_INCLUDES ${PHONON_INCLUDE_DIR}/KDE ${PHONON_INCLUDE_DIR})
|
||||
set(PHONON_FOUND TRUE)
|
||||
else(PHONON_INCLUDE_DIR AND PHONON_LIBRARY AND NOT PHONON_VERSION VERSION_LESS ${Phonon_FIND_VERSION})
|
||||
set(PHONON_FOUND FALSE)
|
||||
endif(PHONON_INCLUDE_DIR AND PHONON_LIBRARY AND NOT PHONON_VERSION VERSION_LESS ${Phonon_FIND_VERSION})
|
||||
|
||||
if(PHONON_FOUND)
|
||||
if(NOT PHONON_FIND_QUIETLY)
|
||||
message(STATUS "Found Phonon: ${PHONON_LIBRARY}")
|
||||
message(STATUS "Found Phonon Includes: ${PHONON_INCLUDES}")
|
||||
endif(NOT PHONON_FIND_QUIETLY)
|
||||
else(PHONON_FOUND)
|
||||
if(Phonon_FIND_REQUIRED)
|
||||
if(NOT PHONON_INCLUDE_DIR)
|
||||
message(STATUS "Phonon includes NOT found!")
|
||||
endif(NOT PHONON_INCLUDE_DIR)
|
||||
if(NOT PHONON_LIBRARY)
|
||||
message(STATUS "Phonon library NOT found!")
|
||||
endif(NOT PHONON_LIBRARY)
|
||||
message(FATAL_ERROR "Phonon library or includes NOT found!")
|
||||
else(Phonon_FIND_REQUIRED)
|
||||
message(STATUS "Unable to find Phonon")
|
||||
endif(Phonon_FIND_REQUIRED)
|
||||
endif(PHONON_FOUND)
|
||||
|
||||
|
||||
mark_as_advanced(PHONON_INCLUDE_DIR PHONON_LIBRARY PHONON_INCLUDES)
|
||||
endif(PHONON_FOUND)
|
||||
mark_as_advanced(PHONON_INCLUDE_DIR PHONON_LIBRARY)
|
||||
|
11
CMakeModules/FindQuaZip.cmake
Normal file
@@ -0,0 +1,11 @@
|
||||
find_package(Qt4)
|
||||
find_path(QuaZip_INCLUDE_DIR quazip.h ${CMAKE_INSTALL_PREFIX}/include/quazip ${CMAKE_INSTALL_PREFIX}/include /usr/include/quazip /usr/local/include/quazip ${QT_INCLUDE_DIR}/quazip ${QT_INCLUDE_DIR} ${QUAZIP_DIR}/include/quazip ${QUAZIP_DIR}/quazip ${QUAZIP_DIR}/include)
|
||||
find_library(QuaZip_LIBRARY NAMES quazip PATHS ${CMAKE_INSTALL_PREFIX}/lib64 ${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/Library/Frameworks ${QUAZIP_DIR}/lib64 ${QUAZIP_DIR}/lib ${QUAZIP_DIR}/quazip ${QUAZIP_DIR})
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(quazip DEFAULT_MSG QuaZip_LIBRARY QuaZip_INCLUDE_DIR)
|
||||
set(QuaZip_LIBRARIES ${QuaZip_LIBRARY})
|
||||
mark_as_advanced(QuaZip_LIBRARY QuaZip_INCLUDE_DIR)
|
||||
|
||||
if(QuaZip_LIBRARY AND QuaZip_INCLUDE_DIR)
|
||||
set(QuaZip_FOUND TRUE)
|
||||
endif()
|
@@ -273,9 +273,13 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
;Main executable.
|
||||
File "${INSTALL_PATH}\bin\tomahawk.exe"
|
||||
|
||||
File "${INSTALL_PATH}\bin\CrashReporter.exe"
|
||||
File "${INSTALL_PATH}\bin\libtomahawk_breakpad.dll"
|
||||
|
||||
File "${INSTALL_PATH}\bin\libqxtweb-standalone.dll"
|
||||
File "${INSTALL_PATH}\bin\libtomahawk_portfwd.dll"
|
||||
File "${INSTALL_PATH}\bin\libtomahawk_lastfm2.dll"
|
||||
File "${INSTALL_PATH}\bin\libquazip.dll"
|
||||
File "${INSTALL_PATH}\bin\libtomahawklib.dll"
|
||||
File "${INSTALL_PATH}\lib\libtomahawk_sip*.dll"
|
||||
!endif
|
||||
@@ -283,10 +287,14 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
;Main executable.
|
||||
File "${BUILD_PATH}\tomahawk.exe"
|
||||
|
||||
File "${BUILD_PATH}\CrashReporter.exe"
|
||||
File "${BUILD_PATH}\libtomahawk_breakpad.dll"
|
||||
|
||||
File "${BUILD_PATH}\libtomahawklib.dll"
|
||||
File "${BUILD_PATH}\libqxtweb-standalone.dll"
|
||||
File "${BUILD_PATH}\libtomahawk_portfwd.dll"
|
||||
File "${BUILD_PATH}\libtomahawk_lastfm2.dll"
|
||||
File "${BUILD_PATH}\libquazip.dll"
|
||||
File "${BUILD_PATH}\libtomahawk_sip*.dll"
|
||||
!endif
|
||||
|
||||
@@ -346,7 +354,6 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
File "${MING_BIN}\libvorbisenc-2.dll" ; OGG
|
||||
|
||||
|
||||
|
||||
; Other
|
||||
File "${MING_BIN}\libqjson.dll"
|
||||
File "${MING_BIN}\libtag.dll"
|
||||
@@ -370,6 +377,7 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
File "${MING_LIB}\libclucene-shared.dll"
|
||||
|
||||
File "${MING_BIN}\libqtsparkle.dll"
|
||||
File "${MING_BIN}\libattica.dll"
|
||||
SectionEnd
|
||||
|
||||
SectionGroup "Shortcuts"
|
||||
|
73
ChangeLog
@@ -1,10 +1,81 @@
|
||||
Version 0.3.1:
|
||||
* Fixed not resolving to local files.
|
||||
* Fixed shutdown crash on Windows.
|
||||
* Support more widget types in Javascript resolver configs.
|
||||
* Fixed bug where red headphone would be visible on My Collection
|
||||
when listened along to source went offline.
|
||||
* Draw author name as well as avatar in recently played playlists.
|
||||
* Fixed Tomahawk integration in Unity.
|
||||
* Fixed incorrect item selected in source tree when deleting temporary
|
||||
pages.
|
||||
* Fixed currently played label disappearing after 10 minutes regardless
|
||||
of length of track.
|
||||
* Fixed crash on Sparkle upgrade on OS X.
|
||||
|
||||
Version 0.3.0:
|
||||
* Make artist names in the album view clickable.
|
||||
* Don't start playing if a tomahawk:// link was clicked while Tomahawk
|
||||
is paused.
|
||||
* Make artist name clickable in header of Album pages.
|
||||
* Added a drop shadow to cover images, and put placeholder in jewel case.
|
||||
* Added shuffle and repeat support to tree view.
|
||||
* Draw a speaker next to the currently playing playlist.
|
||||
* Refresh station previews whenever a filter is changed.
|
||||
* Support and show official releases on album and track pages.
|
||||
* Filter out duplicates from station previews and upcoming tracks.
|
||||
* Added YouTube resolver.
|
||||
* Fixed bug where going offline then online would not re-connect to many
|
||||
peers.
|
||||
* Added support for auto-updating live XSPF playlists.
|
||||
* Don't show an age of 41 years for tracks that have no age information.
|
||||
* Show config UI for resolvers that have them as soon as you add them.
|
||||
* Add support for Echo Nest Personal Catalogs and User Radio. Synchronize
|
||||
your catalog with The Echo Nest and enable personal recommendations
|
||||
from you and your friends.
|
||||
* Added support for Grooveshark resolver (requires Grooveshark Anywhere).
|
||||
* Fixed re-resolving when resolvers or sources go off- / online.
|
||||
* Correctly sort recently played tracks on the Dashboard.
|
||||
* Show a Lion full-screen toggle button if running on Lion.
|
||||
* Show a list of users who are currently listening along to you.
|
||||
* Show headphone icon in source item to allow users to listen along; paint
|
||||
headphones red on a source if you are currently listening along to it.
|
||||
* Added new job status view in the bottom of the source list that displays
|
||||
current jobs such as resolving, parsing playlists, and loading from
|
||||
database.
|
||||
* Parse and convert a Spotify playlist url when dropped anywhere on the
|
||||
sidebar.
|
||||
* Convert resolvers to use asynchronous calls to avoid blocking Tomahawk's
|
||||
UI, greatly increasing responsiveness of Tomahawk while resolving.
|
||||
* Fixed no playlists overlay not disappearing when playlists were added.
|
||||
* Add support for parsing itunes track, artist and album links.
|
||||
* Fixed crash when syncing playlists with peers.
|
||||
* Add support for browsing, downloading and rating resolvers from within
|
||||
Tomahawk directly.
|
||||
* Support multi-folder selection and scanning.
|
||||
* Fixed handling of special characters in tomahawk:// links
|
||||
* Improve sidebar performance by caching pixmaps and shrinking them.
|
||||
* Send updated playlists to peers when tracks are moved/copied.
|
||||
* Remove splitter handles in sidebar.
|
||||
* Fixed Tomahawk preventing system shutdown / logout.
|
||||
* Ignore leading 'The' when sorting artists.
|
||||
* Added Charts page, which shows various sources' top hits & artists.
|
||||
* The Collection tree-views can now be filtered.
|
||||
* Moved the song queue below to the left, below the sidebar.
|
||||
* Fixed crash when pressing enter in an empty playlist.
|
||||
* Moved the song queue to the bottom of the sidebar.
|
||||
* Added Footnotes, a contextual view that you can slide it.
|
||||
* Show recently added playlists in dashboard rather than recently opened
|
||||
playlists.
|
||||
* Fixed seek slider and give it some smooth animation between ticks.
|
||||
* Fixed Twitter issue where it would repeatedly send DMs to friends.
|
||||
* Add a new drag and drop menu when dropping items onto playlists,
|
||||
allowing users to drop the dragged tracks, the whole album, or
|
||||
the whole artists's tracks.
|
||||
* Bring Tomahawk window to the front when clicking a Tomahawk link.
|
||||
* Fixed crash in source list when initially syncing with remote sources.
|
||||
* Open temporary artist, album, and search playlists as temporary items
|
||||
in the sidebar.
|
||||
* Fixed sorting of playlists and items in the artist view.
|
||||
* Allow dragging and dropping albums and artists to playlists.
|
||||
* Added MPRIS 2.1 support.
|
||||
|
||||
Version 0.2.3:
|
||||
|
27
README
@@ -27,18 +27,25 @@ Doxygen Documentation
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
CMake 2.8.0 http://www.cmake.org/
|
||||
Qt 4.7.0 http://qt.nokia.com/
|
||||
QJson 0.7.1 http://qjson.sourceforge.net/
|
||||
SQLite 3.6.22 http://www.sqlite.org/
|
||||
TagLib 1.6.2 http://developer.kde.org/~wheeler/taglib.html
|
||||
Boost 1.3x http://www.boost.org/
|
||||
CLucene 0.9.23 (0.9.21 will fail) http://clucene.sourceforge.net/download.shtml
|
||||
libechonest 1.1.8 http://projects.kde.org/projects/playground/libs/libechonest/
|
||||
CMake 2.8.0 - http://www.cmake.org/
|
||||
Qt 4.7.0 - http://qt.nokia.com/
|
||||
QJson 0.7.1 - http://qjson.sourceforge.net/
|
||||
SQLite 3.6.22 - http://www.sqlite.org/
|
||||
TagLib 1.6.2 - http://developer.kde.org/~wheeler/taglib.html
|
||||
Boost 1.3 - http://www.boost.org/
|
||||
CLucene 0.9.23 (0.9.21 will fail) - http://clucene.sourceforge.net/download.shtml
|
||||
libechonest 1.2.0 - http://projects.kde.org/projects/playground/libs/libechonest/
|
||||
|
||||
The following dependencies are optional, but recommended:
|
||||
|
||||
Attica 0.2.0 - ftp://ftp.kde.org/pub/kde/stable/attica/
|
||||
jreen (Git) - https://github.com/euroelessar/jreen
|
||||
QTweetLib 0.3.0 - https://github.com/minimoog/QTweetLib
|
||||
|
||||
Third party libraries that we ship with our source:
|
||||
|
||||
MiniUPnP http://miniupnp.free.fr/
|
||||
liblastfm 0.4.0 http://github.com/jonocole/liblastfm/
|
||||
MiniUPnP 1.6 - http://miniupnp.free.fr/
|
||||
liblastfm 0.4.0 - http://github.com/jonocole/liblastfm/
|
||||
QuaZip 0.4.3 - http://quazip.sourceforge.net/
|
||||
|
||||
Enjoy!
|
||||
|
@@ -1,3 +1,3 @@
|
||||
IF(WIN32)
|
||||
INSTALL(DIRECTORY win DESTINATION share/tomahawk/admin )
|
||||
ENDIF(WIN32)
|
||||
ENDIF(WIN32)
|
||||
|
5
admin/copy_syms.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
DUMPID=`head -n1 $1 | cut -f4 -d' '`
|
||||
mkdir -p $2/$DUMPID
|
||||
cp $1 $2/$DUMPID/
|
@@ -41,7 +41,7 @@ VERSION=$1
|
||||
|
||||
header "Copying Sparkle framework"
|
||||
cp -R /Library/Frameworks/Sparkle.framework Contents/Frameworks
|
||||
|
||||
|
||||
header "Creating DMG"
|
||||
cd ..
|
||||
|
||||
|
@@ -207,7 +207,7 @@ TOMAHAWK_PLUGINS = [
|
||||
]
|
||||
|
||||
QT_PLUGINS_SEARCH_PATH=[
|
||||
'/usr/local/Cellar/qt/4.7.3/plugins',
|
||||
'/usr/local/Cellar/qt/4.7.4/plugins',
|
||||
]
|
||||
|
||||
|
||||
@@ -500,6 +500,11 @@ try:
|
||||
FixPlugin('spotify_tomahawkresolver', '../MacOS')
|
||||
except:
|
||||
print 'Failed to find spotify resolver'
|
||||
|
||||
try:
|
||||
FixPlugin('CrashReporter', '../MacOS')
|
||||
except:
|
||||
print 'Failed to find CrashReporter'
|
||||
|
||||
for plugin in QT_PLUGINS:
|
||||
FixPlugin(FindQtPlugin(plugin), os.path.dirname(plugin))
|
||||
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 204 KiB |
Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.5 KiB |
BIN
data/images/downloading.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 3.4 KiB |
BIN
data/images/headphones-bigger.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
data/images/headphones-off.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
data/images/headphones-sidebar.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
data/images/headphones.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
data/images/itunes.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 68 KiB |
BIN
data/images/no-album-no-case.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
data/images/now-playing-speaker-dark.png
Normal file
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 3.2 KiB |
BIN
data/images/private-listening.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
data/images/rdio.png
Normal file
After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 5.1 KiB |
BIN
data/images/spotify-logo.png
Normal file
After Width: | Height: | Size: 53 KiB |
BIN
data/images/star-hover.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
data/images/star-unstarred.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
data/images/starred.png
Normal file
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 563 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 3.8 KiB |
BIN
data/images/uploading.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
@@ -184,6 +184,21 @@ Tomahawk.syncRequest = function(url)
|
||||
}
|
||||
};
|
||||
|
||||
Tomahawk.asyncRequest = function(url, callback)
|
||||
{
|
||||
var xmlHttpRequest = new XMLHttpRequest();
|
||||
xmlHttpRequest.open('GET', url, true);
|
||||
xmlHttpRequest.onreadystatechange = function() {
|
||||
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
|
||||
callback.call(window, xmlHttpRequest);
|
||||
} else if (xmlHttpRequest.readyState === 4) {
|
||||
Tomahawk.log("Failed to do GET request: to: " + url);
|
||||
Tomahawk.log("Status Code was: " + xmlHttpRequest.status);
|
||||
}
|
||||
}
|
||||
xmlHttpRequest.send(null);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Secure Hash Algorithm (SHA256)
|
||||
|
10
data/sql/dbmigrate-26_to_27.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
-- Script to migate from db version 6 to 27
|
||||
-- Nothing to do
|
||||
|
||||
CREATE TABLE IF NOT EXISTS collection_attributes (
|
||||
id INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, -- source id, null for local source
|
||||
k TEXT NOT NULL,
|
||||
v TEXT NOT NULL
|
||||
);
|
||||
UPDATE settings SET v = '27' WHERE k == 'schema_version';
|
||||
|
@@ -4,7 +4,6 @@
|
||||
<file>data/images/avatar-dude.png</file>
|
||||
<file>data/images/back-pressed.png</file>
|
||||
<file>data/images/back-rest.png</file>
|
||||
<file>data/images/cover-shadow.png</file>
|
||||
<file>data/images/filter.png</file>
|
||||
<file>data/images/loved.png</file>
|
||||
<file>data/images/not-loved.png</file>
|
||||
@@ -13,6 +12,7 @@
|
||||
<file>data/images/track-placeholder.png</file>
|
||||
<file>data/images/now-playing-panel.png</file>
|
||||
<file>data/images/now-playing-speaker.png</file>
|
||||
<file>data/images/now-playing-speaker-dark.png</file>
|
||||
<file>data/images/pause-pressed.png</file>
|
||||
<file>data/images/pause-rest.png</file>
|
||||
<file>data/images/play-pressed.png</file>
|
||||
@@ -72,6 +72,7 @@
|
||||
<file>data/images/music-icon.png</file>
|
||||
<file>data/images/configure.png</file>
|
||||
<file>data/images/create-playlist.png</file>
|
||||
<file>data/images/private-listening.png</file>
|
||||
<file>data/images/add.png</file>
|
||||
<file>data/images/recently-played.png</file>
|
||||
<file>data/images/supercollection.png</file>
|
||||
@@ -91,6 +92,9 @@
|
||||
<file>data/images/artist-icon.png</file>
|
||||
<file>data/images/album-icon.png</file>
|
||||
<file>data/images/search-icon.png</file>
|
||||
<file>data/images/star-hover.png</file>
|
||||
<file>data/images/starred.png</file>
|
||||
<file>data/images/star-unstarred.png</file>
|
||||
<file>data/images/track-icon-22x22.png</file>
|
||||
<file>data/images/track-icon-32x32.png</file>
|
||||
<file>data/images/track-icon-16x16.png</file>
|
||||
@@ -108,6 +112,7 @@
|
||||
<file>data/sql/dbmigrate-23_to_24.sql</file>
|
||||
<file>data/sql/dbmigrate-24_to_25.sql</file>
|
||||
<file>data/sql/dbmigrate-25_to_26.sql</file>
|
||||
<file>data/sql/dbmigrate-26_to_27.sql</file>
|
||||
<file>data/js/tomahawk.js</file>
|
||||
<file>data/images/avatar_frame.png</file>
|
||||
<file>data/images/drop-all-songs.png</file>
|
||||
@@ -115,5 +120,15 @@
|
||||
<file>data/images/drop-top-songs.png</file>
|
||||
<file>data/images/drop-song.png</file>
|
||||
<file>data/images/drop-album.png</file>
|
||||
<file>data/images/spotify-logo.png</file>
|
||||
<file>data/images/itunes.png</file>
|
||||
<file>data/images/uploading.png</file>
|
||||
<file>data/images/downloading.png</file>
|
||||
<file>data/images/headphones.png</file>
|
||||
<file>data/images/headphones-off.png</file>
|
||||
<file>data/images/headphones-sidebar.png</file>
|
||||
<file>data/images/headphones-bigger.png</file>
|
||||
<file>data/images/no-album-no-case.png</file>
|
||||
<file>data/images/rdio.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -1,8 +1,3 @@
|
||||
SET( OS_SPECIFIC_LINK_LIBRARIES
|
||||
${OS_SPECIFIC_LINK_LIBRARIES}
|
||||
tomahawklib
|
||||
)
|
||||
|
||||
FILE( GLOB _icons "${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon-*.png" )
|
||||
FOREACH( _file ${_icons} )
|
||||
STRING( REPLACE "${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon-" "" _res ${_file} )
|
||||
@@ -10,6 +5,6 @@ FOREACH( _file ${_icons} )
|
||||
INSTALL( FILES ${_file} RENAME tomahawk.png DESTINATION share/icons/hicolor/${_res}/apps )
|
||||
ENDFOREACH( _file )
|
||||
|
||||
INSTALL( FILES ${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon.svg RENAME tomahawk.svg DESTINATION share/icons/hicolor/scalable )
|
||||
INSTALL( FILES ${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon.svg RENAME tomahawk.svg DESTINATION share/icons/hicolor/scalable/apps )
|
||||
|
||||
INSTALL( FILES ${CMAKE_SOURCE_DIR}/admin/unix/tomahawk.desktop DESTINATION share/applications )
|
||||
|
@@ -1,10 +1,11 @@
|
||||
SET( TOMAHAWK_LIBRARIES tomahawklib )
|
||||
SET( TOMAHAWK_LIBRARIES tomahawklib )
|
||||
|
||||
SET( OS_SPECIFIC_LINK_LIBRARIES
|
||||
${OS_SPECIFIC_LINK_LIBRARIES}
|
||||
${COREAUDIO_LIBRARY}
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
|
||||
crypto
|
||||
SPMediaKeyTap
|
||||
|
||||
/System/Library/Frameworks/AppKit.framework
|
||||
@@ -26,12 +27,15 @@ if (APPLE)
|
||||
# Uses Darwin kernel version.
|
||||
# 9.8.0 -> 10.5/Leopard
|
||||
# 10.4.0 -> 10.6/Snow Leopard
|
||||
# 11.x.x -> Lion
|
||||
string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${CMAKE_HOST_SYSTEM_VERSION})
|
||||
if (DARWIN_VERSION GREATER 9)
|
||||
if (DARWIN_VERSION GREATER 10)
|
||||
SET(LION 1)
|
||||
elseif (DARWIN_VERSION GREATER 9)
|
||||
SET(SNOW_LEOPARD 1)
|
||||
elseif (DARWIN_VERSION GREATER 8)
|
||||
SET(LEOPARD 1)
|
||||
endif (DARWIN_VERSION GREATER 9)
|
||||
endif (DARWIN_VERSION GREATER 10)
|
||||
|
||||
# Use two different sparkle update tracks for debug and release
|
||||
# We have to change the URL in the Info.plist file :-/
|
||||
|
@@ -37,12 +37,10 @@ ENDIF()
|
||||
SET( tomahawkSources ${tomahawkSources}
|
||||
web/api_v1.cpp
|
||||
|
||||
resolvers/scriptresolver.cpp
|
||||
resolvers/qtscriptresolver.cpp
|
||||
|
||||
musicscanner.cpp
|
||||
shortcuthandler.cpp
|
||||
scanmanager.cpp
|
||||
ubuntuunityhack.cpp
|
||||
tomahawkapp.cpp
|
||||
main.cpp
|
||||
)
|
||||
@@ -66,8 +64,8 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
||||
sourcetree/items/genericpageitems.cpp
|
||||
sourcetree/items/temporarypageitem.cpp
|
||||
|
||||
transferview.cpp
|
||||
PipelineStatusView.cpp
|
||||
breakpad/BreakPad.cpp
|
||||
|
||||
tomahawktrayicon.cpp
|
||||
audiocontrols.cpp
|
||||
settingsdialog.cpp
|
||||
@@ -78,7 +76,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
||||
settingslistdelegate.cpp
|
||||
resolversmodel.cpp
|
||||
tomahawkwindow.cpp
|
||||
tomahawkdesktopwindow.cpp
|
||||
LoadXSPFDialog.cpp
|
||||
)
|
||||
|
||||
SET( tomahawkHeaders ${tomahawkHeaders}
|
||||
@@ -86,11 +84,9 @@ SET( tomahawkHeaders ${tomahawkHeaders}
|
||||
|
||||
web/api_v1.h
|
||||
|
||||
resolvers/scriptresolver.h
|
||||
resolvers/qtscriptresolver.h
|
||||
|
||||
musicscanner.h
|
||||
scanmanager.h
|
||||
ubuntuunityhack.h
|
||||
shortcuthandler.h
|
||||
)
|
||||
|
||||
@@ -100,6 +96,12 @@ IF(LIBLASTFM_FOUND)
|
||||
)
|
||||
ENDIF(LIBLASTFM_FOUND)
|
||||
|
||||
IF(LIBATTICA_FOUND)
|
||||
SET( tomahawkSourcesGui ${tomahawkSourcesGui} GetNewStuffDialog.cpp GetNewStuffDelegate.cpp GetNewStuffModel.cpp )
|
||||
SET( tomahawkHeadersGui ${tomahawkHeadersGui} GetNewStuffDialog.h GetNewStuffDelegate.h GetNewStuffModel.h )
|
||||
INCLUDE_DIRECTORIES( ${LIBATTICA_INCLUDE_DIR} )
|
||||
ENDIF(LIBATTICA_FOUND)
|
||||
|
||||
|
||||
SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
||||
sourcetree/sourcesmodel.h
|
||||
@@ -114,8 +116,6 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
||||
sourcetree/items/genericpageitems.h
|
||||
sourcetree/items/temporarypageitem.h
|
||||
|
||||
transferview.h
|
||||
PipelineStatusView.h
|
||||
tomahawktrayicon.h
|
||||
audiocontrols.h
|
||||
settingsdialog.h
|
||||
@@ -127,16 +127,19 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
||||
resolversmodel.h
|
||||
delegateconfigwrapper.h
|
||||
tomahawkwindow.h
|
||||
tomahawkdesktopwindow.h
|
||||
LoadXSPFDialog.h
|
||||
)
|
||||
|
||||
SET( tomahawkUI ${tomahawkUI}
|
||||
tomahawkdesktopwindow.ui
|
||||
tomahawkwindow.ui
|
||||
diagnosticsdialog.ui
|
||||
stackedsettingsdialog.ui
|
||||
proxydialog.ui
|
||||
|
||||
audiocontrols.ui
|
||||
|
||||
GetNewStuffDialog.ui
|
||||
LoadXSPFDialog.ui
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
@@ -157,6 +160,7 @@ INCLUDE_DIRECTORIES(
|
||||
${THIRDPARTY_DIR}/qxt/qxtweb-standalone/qxtweb
|
||||
${THIRDPARTY_DIR}/qtweetlib/qtweetlib/src
|
||||
${THIRDPARTY_DIR}/qtweetlib/tomahawk-custom
|
||||
${THIRDPARTY_DIR}/breakpad
|
||||
|
||||
${TAGLIB_INCLUDES}
|
||||
${PHONON_INCLUDES}
|
||||
@@ -196,10 +200,6 @@ IF(QCA2_FOUND)
|
||||
INCLUDE_DIRECTORIES( ${QCA2_INCLUDE_DIR} )
|
||||
ENDIF(QCA2_FOUND)
|
||||
|
||||
kde4_add_app_icon( tomahawkSources "${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon-*.png" )
|
||||
qt4_add_resources( RC_SRCS "../resources.qrc" )
|
||||
qt4_wrap_cpp( tomahawkMoc ${tomahawkHeaders} )
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
@@ -207,13 +207,17 @@ include( ${CMAKE_SOURCE_DIR}/lang/translations.cmake )
|
||||
|
||||
SET( final_src ${final_src} ${tomahawkMoc} ${tomahawkSources} ${tomahawkHeaders} ${trans_outfile})
|
||||
|
||||
IF( "${gui}" STREQUAL "no" )
|
||||
ELSE()
|
||||
IF( BUILD_GUI )
|
||||
LIST(APPEND tomahawkHeaders ${tomahawkHeadersGui})
|
||||
LIST(APPEND tomahawkSources ${tomahawkSourcesGui})
|
||||
qt4_wrap_ui( tomahawkUI_H ${tomahawkUI} )
|
||||
qt4_wrap_cpp( tomahawkMocGui ${tomahawkHeadersGui} )
|
||||
SET( final_src ${final_src} ${tomahawkUI_H} ${tomahawkMocGui} ${tomahawkSourcesGui} ${RC_SRCS} )
|
||||
ENDIF()
|
||||
|
||||
kde4_add_app_icon( tomahawkSources "${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon-*.png" )
|
||||
qt4_add_resources( RC_SRCS "../resources.qrc" )
|
||||
qt4_wrap_cpp( tomahawkMoc ${tomahawkHeaders} )
|
||||
SET( final_src ${final_src} ${tomahawkUI_H} ${tomahawkMoc} ${tomahawkSources} ${RC_SRCS} )
|
||||
|
||||
IF( UNIX AND NOT APPLE )
|
||||
ADD_EXECUTABLE( tomahawk ${final_src} )
|
||||
ENDIF( UNIX AND NOT APPLE )
|
||||
@@ -235,12 +239,12 @@ ENDIF(LIBLASTFM_FOUND)
|
||||
IF(GLOOX_FOUND)
|
||||
SET(LINK_LIBRARIES ${LINK_LIBRARIES} ${GLOOX_LIBRARIES} )
|
||||
ENDIF(GLOOX_FOUND)
|
||||
|
||||
IF(QCA2_FOUND)
|
||||
SET(LINK_LIBRARIES ${LINK_LIBRARIES} ${QCA2_LIBRARIES} )
|
||||
ENDIF(QCA2_FOUND)
|
||||
|
||||
SET( tomahawkLinkLibraries
|
||||
TARGET_LINK_LIBRARIES( tomahawk
|
||||
tomahawk_breakpad
|
||||
${LINK_LIBRARIES}
|
||||
${TOMAHAWK_LIBRARIES}
|
||||
${PHONON_LIBS}
|
||||
@@ -253,13 +257,6 @@ SET( tomahawkLinkLibraries
|
||||
${TAGLIB_LIBRARIES}
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES( tomahawk ${tomahawkLinkLibraries} )
|
||||
|
||||
IF( BUILD_GUI_QML )
|
||||
# sic! add_subdirectory would make it harder to reuse ${final_src}
|
||||
INCLUDE( active/CMakeLists.txt )
|
||||
ENDIF()
|
||||
|
||||
IF( APPLE )
|
||||
IF(HAVE_SPARKLE)
|
||||
MESSAGE("Sparkle Found, installing framekwork in bundle")
|
||||
|
@@ -4,7 +4,7 @@ ADD_DEFINITIONS( -g )
|
||||
ADD_DEFINITIONS( -fno-operator-names )
|
||||
ADD_DEFINITIONS( -fPIC )
|
||||
|
||||
SET( QXTWEB_LIBRARIES qxtweb-standalone )
|
||||
SET( QXTWEB_LIBRARIES qxtweb-standalone )
|
||||
|
||||
IF( APPLE )
|
||||
INCLUDE( "CMakeLists.osx.txt" )
|
||||
|
@@ -3,6 +3,7 @@ SET( CMAKE_BUILD_TYPE "Release" )
|
||||
ADD_DEFINITIONS( /DNOMINMAX )
|
||||
ADD_DEFINITIONS( /DWIN32_LEAN_AND_MEAN )
|
||||
ADD_DEFINITIONS( -static-libgcc )
|
||||
ADD_DEFINITIONS( -DUNICODE )
|
||||
|
||||
SET( QXTWEB_LIBRARIES qxtweb-standalone )
|
||||
|
||||
|
323
src/GetNewStuffDelegate.cpp
Normal file
@@ -0,0 +1,323 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GetNewStuffDelegate.h"
|
||||
|
||||
#include "GetNewStuffModel.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#include <QtGui/QPainter>
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
#include "AtticaManager.h"
|
||||
|
||||
#define PADDING 4
|
||||
#define PADDING_BETWEEN_STARS 2
|
||||
#define STAR_SIZE 12
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
#define SIZEHINT_HEIGHT 70
|
||||
#else
|
||||
#define SIZEHINT_HEIGHT 60
|
||||
#endif
|
||||
|
||||
GetNewStuffDelegate::GetNewStuffDelegate( QObject* parent )
|
||||
: QStyledItemDelegate ( parent )
|
||||
, m_widestTextWidth( 0 )
|
||||
, m_hoveringOver( -1 )
|
||||
{
|
||||
m_defaultCover.load( RESPATH "images/sipplugin-online.png" );
|
||||
m_ratingStarPositive.load( RESPATH "images/starred.png" );
|
||||
m_ratingStarNegative.load( RESPATH "images/star-unstarred.png" );
|
||||
m_onHoverStar.load( RESPATH "images/star-hover.png" );
|
||||
|
||||
m_ratingStarPositive = m_ratingStarPositive.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
m_ratingStarNegative = m_ratingStarNegative.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
m_onHoverStar = m_onHoverStar.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
const int w = SIZEHINT_HEIGHT - 2*PADDING;
|
||||
m_defaultCover = m_defaultCover.scaled( w, w, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
// save the widest wifth
|
||||
QFont f( QApplication::font() );
|
||||
f.setPointSize( f.pointSize() - 1 );
|
||||
QFontMetrics fm( f );
|
||||
QStringList l = QStringList() << tr( "Installed" ) << tr( "Installing" ) << tr( "Failed" ) << tr( "Uninstalling" );
|
||||
foreach ( const QString& str, l )
|
||||
{
|
||||
if ( fm.width( str ) > m_widestTextWidth )
|
||||
m_widestTextWidth = fm.width( str );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GetNewStuffDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption( &opt, index );
|
||||
|
||||
QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget );
|
||||
|
||||
painter->setRenderHint( QPainter::Antialiasing );
|
||||
|
||||
QFont titleFont = opt.font;
|
||||
titleFont.setBold( true );
|
||||
titleFont.setPointSize( titleFont.pointSize() + 2 );
|
||||
QFontMetrics titleMetrics( titleFont );
|
||||
|
||||
QFont authorFont = opt.font;
|
||||
authorFont.setItalic( true );
|
||||
authorFont.setPointSize( authorFont.pointSize() - 1 );
|
||||
QFontMetrics authorMetrics( authorFont );
|
||||
|
||||
QFont descFont = authorFont;
|
||||
descFont.setItalic( false );
|
||||
QFontMetrics descMetrics( descFont );
|
||||
|
||||
QFont installFont = opt.font;
|
||||
installFont.setPointSize( installFont.pointSize() - 1 );
|
||||
QFontMetrics installMetrics( descFont );
|
||||
|
||||
const int height = opt.rect.height();
|
||||
const int center = height / 2 + opt.rect.top();
|
||||
|
||||
// Pixmap
|
||||
QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >();
|
||||
const int pixmapWidth = height - 2*PADDING;
|
||||
QRect pixmapRect( PADDING, PADDING + opt.rect.top(), pixmapWidth, pixmapWidth );
|
||||
if ( p.isNull() ) // default image... TODO
|
||||
p = m_defaultCover;
|
||||
else
|
||||
p = p.scaled( pixmapRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
painter->drawPixmap( pixmapRect, p );
|
||||
|
||||
// Go from right edge now, stars, install button, and downloaded info
|
||||
|
||||
// install / status button
|
||||
AtticaManager::ResolverState state = static_cast< AtticaManager::ResolverState >( index.data( GetNewStuffModel::StateRole ).toInt() );
|
||||
QString actionText;
|
||||
switch( state )
|
||||
{
|
||||
case AtticaManager::Uninstalled:
|
||||
actionText = tr( "Install" );
|
||||
break;
|
||||
case AtticaManager::Installing:
|
||||
actionText = tr( "Installing" );
|
||||
break;
|
||||
case AtticaManager::Upgrading:
|
||||
actionText = tr( "Upgrading" );
|
||||
break;
|
||||
case AtticaManager::Failed:
|
||||
actionText = tr( "Failed" );
|
||||
break;
|
||||
case AtticaManager::Installed:
|
||||
actionText = tr( "Uninstall" );
|
||||
break;
|
||||
case AtticaManager::NeedsUpgrade:
|
||||
actionText = tr( "Upgrade" );
|
||||
break;
|
||||
}
|
||||
|
||||
const int btnWidth = m_widestTextWidth + 7;
|
||||
const int leftEdge = opt.rect.width() - PADDING - btnWidth - 3;
|
||||
const QRect btnRect( leftEdge, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 4 );
|
||||
m_cachedButtonRects[ QPair<int, int>(index.row(), index.column()) ] = btnRect;
|
||||
|
||||
QPen saved = painter->pen();
|
||||
painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) );
|
||||
|
||||
QPainterPath btnPath;
|
||||
const int radius = 3;
|
||||
//btnPath.addRoundedRect( btnRect, 3, 3 );
|
||||
// draw top half gradient
|
||||
const int btnCenter = btnRect.bottom() - ( btnRect.height() / 2 );
|
||||
btnPath.moveTo( btnRect.left(), btnCenter );
|
||||
btnPath.lineTo( btnRect.left(), btnRect.top() + radius );
|
||||
btnPath.quadTo( QPoint( btnRect.topLeft() ), QPoint( btnRect.left() + radius, btnRect.top() ) );
|
||||
btnPath.lineTo( btnRect.right() - radius, btnRect.top() );
|
||||
btnPath.quadTo( QPoint( btnRect.topRight() ), QPoint( btnRect.right(), btnRect.top() + radius ) );
|
||||
btnPath.lineTo( btnRect.right(),btnCenter );
|
||||
btnPath.lineTo( btnRect.left(), btnCenter );
|
||||
|
||||
QLinearGradient g;
|
||||
g.setColorAt( 0, QColor(54, 127, 211) );
|
||||
g.setColorAt( 0.5, QColor(43, 104, 182) );
|
||||
//painter->setPen( bg.darker() );
|
||||
painter->fillPath( btnPath, g );
|
||||
//painter->drawPath( btnPath );
|
||||
|
||||
btnPath = QPainterPath();
|
||||
btnPath.moveTo( btnRect.left(), btnCenter );
|
||||
btnPath.lineTo( btnRect.left(), btnRect.bottom() - radius );
|
||||
btnPath.quadTo( QPoint( btnRect.bottomLeft() ), QPoint( btnRect.left() + radius, btnRect.bottom() ) );
|
||||
btnPath.lineTo( btnRect.right() - radius, btnRect.bottom() );
|
||||
btnPath.quadTo( QPoint( btnRect.bottomRight() ), QPoint( btnRect.right(), btnRect.bottom() - radius ) );
|
||||
btnPath.lineTo( btnRect.right(), btnCenter );
|
||||
btnPath.lineTo( btnRect.left(), btnCenter );
|
||||
|
||||
g.setColorAt( 0, QColor(34, 85, 159) );
|
||||
g.setColorAt( 0.5, QColor(35, 79, 147) );
|
||||
painter->fillPath( btnPath, g );
|
||||
|
||||
painter->setFont( installFont );
|
||||
painter->drawText( btnRect, Qt::AlignCenter, actionText );
|
||||
|
||||
painter->setPen( saved );
|
||||
|
||||
// rating stars
|
||||
int rating = index.data( GetNewStuffModel::RatingRole ).toInt();
|
||||
const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS );
|
||||
int runningEdge = ( btnRect.right() - btnRect.width() / 2 ) - ratingWidth / 2;
|
||||
for ( int i = 1; i < 6; i++ )
|
||||
{
|
||||
QRect r( runningEdge, btnRect.top() - m_ratingStarPositive.height() - PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() );
|
||||
if ( i == 1 )
|
||||
m_cachedStarRects[ QPair<int, int>(index.row(), index.column()) ] = r;
|
||||
|
||||
const bool userHasRated = index.data( GetNewStuffModel::UserHasRatedRole ).toBool();
|
||||
if ( !userHasRated && // Show on-hover animation if the user hasn't rated it yet, and is hovering over it
|
||||
m_hoveringOver > -1 &&
|
||||
m_hoveringItem == index )
|
||||
{
|
||||
if ( i <= m_hoveringOver ) // positive star
|
||||
painter->drawPixmap( r, m_onHoverStar );
|
||||
else
|
||||
painter->drawPixmap( r, m_ratingStarNegative );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( i <= rating ) // positive or rated star
|
||||
{
|
||||
if ( userHasRated )
|
||||
painter->drawPixmap( r, m_onHoverStar );
|
||||
else
|
||||
painter->drawPixmap( r, m_ratingStarPositive );
|
||||
}
|
||||
else
|
||||
painter->drawPixmap( r, m_ratingStarNegative );
|
||||
}
|
||||
runningEdge += m_ratingStarPositive.width() + PADDING_BETWEEN_STARS;
|
||||
}
|
||||
|
||||
// downloaded num times, underneath button
|
||||
QString count = tr( "%1 downloads" ).arg( index.data( GetNewStuffModel::DownloadCounterRole ).toInt() );
|
||||
const QRect countRect( btnRect.left(), btnRect.bottom() + PADDING, btnRect.width(), opt.rect.bottom() - PADDING - btnRect.bottom() );
|
||||
QFont countFont = descFont;
|
||||
countFont.setPointSize( countFont.pointSize() - 2 );
|
||||
countFont.setBold( true );
|
||||
painter->setFont( countFont );
|
||||
painter->drawText( countRect, Qt::AlignCenter | Qt::TextWordWrap, count );
|
||||
|
||||
// author and version
|
||||
QString author = index.data( GetNewStuffModel::AuthorRole ).toString();
|
||||
const int authorWidth = authorMetrics.width( author );
|
||||
const int topTextLine = opt.rect.top() + PADDING;
|
||||
const QRect authorRect( btnRect.x() - 3*PADDING - authorWidth, topTextLine, authorWidth + 6, authorMetrics.height() );
|
||||
painter->setFont( authorFont );
|
||||
painter->drawText( authorRect, Qt::AlignCenter, author );
|
||||
|
||||
const QRect versionRect = authorRect.translated( 0, authorRect.height() );
|
||||
QString version = index.data( GetNewStuffModel::VersionRole ).toString();
|
||||
painter->drawText( versionRect, Qt::AlignCenter, version );
|
||||
|
||||
// title
|
||||
QString title = index.data( Qt::DisplayRole ).toString();
|
||||
const int rightTitleEdge = authorRect.left() - PADDING;
|
||||
const int leftTitleEdge = pixmapRect.right() + PADDING;
|
||||
const QRect textRect( leftTitleEdge, topTextLine, rightTitleEdge - leftTitleEdge, versionRect.bottom() - opt.rect.top() - PADDING );
|
||||
painter->setFont( titleFont );
|
||||
painter->drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, title );
|
||||
|
||||
// description
|
||||
QString desc = index.data( GetNewStuffModel::DescriptionRole ).toString();
|
||||
const int descWidth = btnRect.left() - leftTitleEdge - PADDING;
|
||||
const QRect descRect( leftTitleEdge, versionRect.bottom(), descWidth, opt.rect.bottom() - versionRect.bottom() + PADDING );
|
||||
painter->setFont( descFont );
|
||||
painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap, desc );
|
||||
}
|
||||
|
||||
|
||||
QSize
|
||||
GetNewStuffDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
Q_UNUSED( option );
|
||||
Q_UNUSED( index );
|
||||
return QSize( 200, SIZEHINT_HEIGHT );
|
||||
}
|
||||
|
||||
bool
|
||||
GetNewStuffDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
|
||||
{
|
||||
Q_UNUSED( option );
|
||||
|
||||
if ( event->type() != QEvent::MouseButtonRelease &&
|
||||
event->type() != QEvent::MouseMove )
|
||||
return false;
|
||||
|
||||
if ( event->type() == QEvent::MouseButtonRelease && m_cachedButtonRects.contains( QPair<int, int>( index.row(), index.column() ) ) )
|
||||
{
|
||||
QRect rect = m_cachedButtonRects[ QPair<int, int>( index.row(), index.column() ) ];
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
|
||||
if ( rect.contains( me->pos() ) )
|
||||
{
|
||||
model->setData( index, true );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_cachedStarRects.contains( QPair<int, int>( index.row(), index.column() ) ) )
|
||||
{
|
||||
QRect fullStars = m_cachedStarRects[ QPair<int, int>( index.row(), index.column() ) ];
|
||||
const int starsWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS );
|
||||
fullStars.setWidth( starsWidth );
|
||||
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
|
||||
if ( fullStars.contains( me->pos() ) )
|
||||
{
|
||||
const int eachStar = starsWidth / 5;
|
||||
const int clickOffset = me->pos().x() - fullStars.x();
|
||||
const int whichStar = (clickOffset / eachStar) + 1;
|
||||
|
||||
if ( event->type() == QEvent::MouseButtonRelease )
|
||||
{
|
||||
model->setData( index, whichStar, GetNewStuffModel::RatingRole );
|
||||
}
|
||||
else if ( event->type() == QEvent::MouseMove )
|
||||
{
|
||||
// 0-indexed
|
||||
m_hoveringOver = whichStar;
|
||||
m_hoveringItem = index;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_hoveringOver > -1 )
|
||||
{
|
||||
emit update( m_hoveringItem );
|
||||
m_hoveringOver = -1;
|
||||
m_hoveringItem = QPersistentModelIndex();
|
||||
}
|
||||
return false;
|
||||
}
|
50
src/GetNewStuffDelegate.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GETNEWSTUFFDELEGATE_H
|
||||
#define GETNEWSTUFFDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
|
||||
class
|
||||
GetNewStuffDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GetNewStuffDelegate( QObject* parent = 0 );
|
||||
virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
virtual QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
|
||||
signals:
|
||||
void update( const QModelIndex& idx );
|
||||
|
||||
protected:
|
||||
virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
|
||||
|
||||
private:
|
||||
QPixmap m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative;
|
||||
|
||||
int m_widestTextWidth;
|
||||
int m_hoveringOver;
|
||||
QPersistentModelIndex m_hoveringItem;
|
||||
mutable QHash< QPair<int, int>, QRect > m_cachedButtonRects;
|
||||
mutable QHash< QPair<int, int>, QRect > m_cachedStarRects;
|
||||
};
|
||||
|
||||
#endif // GETNEWSTUFFDELEGATE_H
|
53
src/GetNewStuffDialog.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GetNewStuffDialog.h"
|
||||
|
||||
#include "ui_GetNewStuffDialog.h"
|
||||
#include "GetNewStuffDelegate.h"
|
||||
#include "GetNewStuffModel.h"
|
||||
|
||||
GetNewStuffDialog::GetNewStuffDialog( QWidget *parent, Qt::WindowFlags f )
|
||||
: QDialog( parent, f )
|
||||
, ui( new Ui::GetNewStuffDialog )
|
||||
, m_model( new GetNewStuffModel( this ) )
|
||||
{
|
||||
ui->setupUi( this );
|
||||
|
||||
ui->listView->setModel( m_model );
|
||||
GetNewStuffDelegate* del = new GetNewStuffDelegate( ui->listView );
|
||||
connect( del, SIGNAL( update( QModelIndex ) ), ui->listView, SLOT( update( QModelIndex ) ) );
|
||||
ui->listView->setItemDelegate( del );
|
||||
ui->listView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
|
||||
|
||||
ui->listView->setMouseTracking( true );
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
setMinimumSize( 510, 350 );
|
||||
setMaximumSize( 510, 350 );
|
||||
setSizeGripEnabled( false );
|
||||
|
||||
ui->listView->setAttribute( Qt::WA_MacShowFocusRect, false );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
GetNewStuffDialog::~GetNewStuffDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
41
src/GetNewStuffDialog.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GETNEWSTUFFDIALOG_H
|
||||
#define GETNEWSTUFFDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class GetNewStuffModel;
|
||||
namespace Ui {
|
||||
class GetNewStuffDialog;
|
||||
}
|
||||
|
||||
class GetNewStuffDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GetNewStuffDialog( QWidget *parent = 0, Qt::WindowFlags f = 0 );
|
||||
~GetNewStuffDialog();
|
||||
|
||||
private:
|
||||
Ui::GetNewStuffDialog *ui;
|
||||
GetNewStuffModel* m_model;
|
||||
};
|
||||
|
||||
#endif // GETNEWSTUFFDIALOG_H
|
67
src/GetNewStuffDialog.ui
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GetNewStuffDialog</class>
|
||||
<widget class="QDialog" name="GetNewStuffDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>449</width>
|
||||
<height>282</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Download New Resolvers</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QListView" name="listView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>GetNewStuffDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>GetNewStuffDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
156
src/GetNewStuffModel.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GetNewStuffModel.h"
|
||||
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QUrl>
|
||||
#include "AtticaManager.h"
|
||||
|
||||
GetNewStuffModel::GetNewStuffModel( QObject* parent )
|
||||
: QAbstractListModel ( parent )
|
||||
{
|
||||
|
||||
if ( AtticaManager::instance()->resolversLoaded() )
|
||||
m_contentList = AtticaManager::instance()->resolvers();
|
||||
|
||||
connect( AtticaManager::instance(), SIGNAL( resolversReloaded( Attica::Content::List ) ), this, SLOT( resolversReloaded( Attica::Content::List ) ) );
|
||||
connect( AtticaManager::instance(), SIGNAL( resolverStateChanged( QString ) ), this, SLOT( resolverStateChanged( QString ) ) );
|
||||
|
||||
}
|
||||
|
||||
GetNewStuffModel::~GetNewStuffModel()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
GetNewStuffModel::resolversReloaded( const Attica::Content::List& resolvers )
|
||||
{
|
||||
beginResetModel();
|
||||
m_contentList = resolvers;
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void
|
||||
GetNewStuffModel::resolverStateChanged( const QString& resolverId )
|
||||
{
|
||||
for ( int i = 0; i < m_contentList.count(); i++ )
|
||||
{
|
||||
const Attica::Content resolver = m_contentList[ i ];
|
||||
if ( resolver.id() == resolverId )
|
||||
{
|
||||
QModelIndex idx = index( i, 0, QModelIndex() );
|
||||
emit dataChanged( idx, idx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
GetNewStuffModel::data( const QModelIndex& index, int role ) const
|
||||
{
|
||||
if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) )
|
||||
return QVariant();
|
||||
|
||||
Attica::Content resolver = m_contentList[ index.row() ];
|
||||
switch ( role )
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
return resolver.name();
|
||||
case Qt::DecorationRole:
|
||||
return QVariant::fromValue< QPixmap >( AtticaManager::instance()->iconForResolver( resolver ) );
|
||||
case DownloadUrlRole:
|
||||
// TODO
|
||||
return QUrl();
|
||||
case RatingRole:
|
||||
return resolver.rating() / 20; // rating is out of 100
|
||||
case DownloadCounterRole:
|
||||
return resolver.downloads();
|
||||
case VersionRole:
|
||||
return resolver.version();
|
||||
case DescriptionRole:
|
||||
return resolver.description();
|
||||
case TypeRole:
|
||||
return ResolverType;
|
||||
case AuthorRole:
|
||||
return resolver.author();
|
||||
case StateRole:
|
||||
return (int)AtticaManager::instance()->resolverState( resolver );
|
||||
case UserHasRatedRole:
|
||||
return AtticaManager::instance()->userHasRated( resolver );
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
int
|
||||
GetNewStuffModel::rowCount( const QModelIndex& parent ) const
|
||||
{
|
||||
Q_UNUSED( parent );
|
||||
return m_contentList.count();
|
||||
}
|
||||
|
||||
bool
|
||||
GetNewStuffModel::setData( const QModelIndex &index, const QVariant &value, int role )
|
||||
{
|
||||
Q_UNUSED( value );
|
||||
if ( !hasIndex( index.row(), index.column(), index.parent() ) )
|
||||
return false;
|
||||
|
||||
|
||||
Attica::Content resolver = m_contentList[ index.row() ];
|
||||
AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( resolver );
|
||||
if ( role == Qt::EditRole )
|
||||
{
|
||||
switch( state )
|
||||
{
|
||||
case AtticaManager::Uninstalled:
|
||||
// install
|
||||
AtticaManager::instance()->installResolver( resolver );
|
||||
break;
|
||||
case AtticaManager::Installing:
|
||||
case AtticaManager::Upgrading:
|
||||
// Do nothing, busy
|
||||
break;
|
||||
case AtticaManager::Installed:
|
||||
// Uninstall
|
||||
AtticaManager::instance()->uninstallResolver( resolver );
|
||||
break;
|
||||
case AtticaManager::NeedsUpgrade:
|
||||
AtticaManager::instance()->upgradeResolver( resolver );
|
||||
break;
|
||||
default:
|
||||
//FIXME -- this handles e.g. Failed
|
||||
break;
|
||||
};
|
||||
} else if ( role == RatingRole )
|
||||
{
|
||||
// For now only allow rating if a resolver is installed!
|
||||
if ( state != AtticaManager::Installed && state != AtticaManager::NeedsUpgrade )
|
||||
return false;
|
||||
if ( AtticaManager::instance()->userHasRated( resolver ) )
|
||||
return false;
|
||||
m_contentList[ index.row() ].setRating( value.toInt() * 20 );
|
||||
AtticaManager::instance()->uploadRating( m_contentList[ index.row() ] );
|
||||
}
|
||||
emit dataChanged( index, index );
|
||||
|
||||
return true;
|
||||
}
|
64
src/GetNewStuffModel.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GETNEWSTUFFMODEL_H
|
||||
#define GETNEWSTUFFMODEL_H
|
||||
|
||||
#include <QModelIndex>
|
||||
|
||||
#include <attica/content.h>
|
||||
#include <QPixmap>
|
||||
|
||||
class GetNewStuffModel: public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum NewStuffRoles {
|
||||
// DisplayRole is title
|
||||
// DecorationRole is qicon for item
|
||||
DownloadUrlRole = Qt::UserRole + 1,
|
||||
RatingRole = Qt::UserRole + 2,
|
||||
DownloadCounterRole = Qt::UserRole + 3,
|
||||
VersionRole = Qt::UserRole + 4,
|
||||
DescriptionRole = Qt::UserRole + 5,
|
||||
TypeRole = Qt::UserRole + 6, // Category in attica-speak. What sort of item this is (resolver, etc).
|
||||
AuthorRole = Qt::UserRole + 7,
|
||||
StateRole = Qt::UserRole + 8,
|
||||
UserHasRatedRole = Qt::UserRole + 9
|
||||
};
|
||||
|
||||
enum Types {
|
||||
ResolverType = 0,
|
||||
};
|
||||
|
||||
explicit GetNewStuffModel( QObject* parent = 0 );
|
||||
virtual ~GetNewStuffModel();
|
||||
|
||||
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
|
||||
virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const;
|
||||
virtual bool setData( const QModelIndex &index, const QVariant &value, int role );
|
||||
|
||||
private slots:
|
||||
void resolversReloaded( const Attica::Content::List& );
|
||||
void resolverStateChanged( const QString& resolverId );
|
||||
|
||||
private:
|
||||
Attica::Content::List m_contentList;
|
||||
};
|
||||
|
||||
#endif // GETNEWSTUFFMODEL_H
|
64
src/LoadXSPFDialog.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "LoadXSPFDialog.h"
|
||||
|
||||
#include "ui_LoadXSPFDialog.h"
|
||||
#include <QFileDialog>
|
||||
|
||||
LoadXSPFDialog::LoadXSPFDialog( QWidget* parent, Qt::WindowFlags f )
|
||||
: QDialog( parent, f )
|
||||
, m_ui( new Ui_LoadXSPF )
|
||||
{
|
||||
m_ui->setupUi( this );
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
m_ui->horizontalLayout->setContentsMargins( 0, 0, 0, 0 );
|
||||
m_ui->horizontalLayout->setSpacing( 5 );
|
||||
m_ui->verticalLayout->setContentsMargins( 0, 10, 0, 0 );
|
||||
m_ui->verticalLayout->setSpacing( 0 );
|
||||
#endif
|
||||
|
||||
connect( m_ui->buttonBox, SIGNAL( accepted() ), SLOT( accept() ) );
|
||||
connect( m_ui->buttonBox, SIGNAL( rejected() ), SLOT( reject() ) );
|
||||
|
||||
connect( m_ui->navigateButton, SIGNAL( clicked( bool ) ), this, SLOT( getLocalFile() ) );
|
||||
}
|
||||
|
||||
LoadXSPFDialog::~LoadXSPFDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LoadXSPFDialog::getLocalFile()
|
||||
{
|
||||
QString url = QFileDialog::getOpenFileName( this, tr( "Load XSPF File" ), QDir::homePath(), ".xspf" );
|
||||
m_ui->lineEdit->setText( url );
|
||||
}
|
||||
|
||||
QString
|
||||
LoadXSPFDialog::xspfUrl() const
|
||||
{
|
||||
return m_ui->lineEdit->text();
|
||||
}
|
||||
|
||||
bool
|
||||
LoadXSPFDialog::autoUpdate() const
|
||||
{
|
||||
return m_ui->autoUpdate->isChecked();
|
||||
}
|
43
src/LoadXSPFDialog.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOADXSPFDIALOG_H
|
||||
#define LOADXSPFDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class Ui_LoadXSPF;
|
||||
|
||||
class LoadXSPFDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LoadXSPFDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 );
|
||||
virtual ~LoadXSPFDialog();
|
||||
|
||||
QString xspfUrl() const;
|
||||
bool autoUpdate() const;
|
||||
|
||||
public slots:
|
||||
void getLocalFile();
|
||||
|
||||
private:
|
||||
Ui_LoadXSPF* m_ui;
|
||||
};
|
||||
|
||||
#endif // LOADXSPFDIALOG_H
|
102
src/LoadXSPFDialog.ui
Normal file
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LoadXSPF</class>
|
||||
<widget class="QDialog" name="LoadXSPF">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>444</width>
|
||||
<height>121</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Load XSPF</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Playlist Url</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit">
|
||||
<property name="placeholderText">
|
||||
<string>Enter URL...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="navigateButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="autoUpdate">
|
||||
<property name="text">
|
||||
<string>Automatically update</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>LoadXSPF</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>LoadXSPF</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@@ -1,6 +1,7 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -16,7 +17,7 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PipelineStatusView.h"
|
||||
#include "JobStatusView.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QVBoxLayout>
|
||||
@@ -28,7 +29,7 @@
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
PipelineStatusView::PipelineStatusView( AnimatedSplitter* parent )
|
||||
JobStatusView::JobStatusView( AnimatedSplitter* parent )
|
||||
: AnimatedWidget( parent )
|
||||
, m_parent( parent )
|
||||
{
|
||||
@@ -76,7 +77,7 @@ PipelineStatusView::PipelineStatusView( AnimatedSplitter* parent )
|
||||
|
||||
|
||||
void
|
||||
PipelineStatusView::onPipelineUpdate( const query_ptr& query )
|
||||
JobStatusView::onPipelineUpdate( const query_ptr& query )
|
||||
{
|
||||
QTreeWidgetItem* ti = m_tree->invisibleRootItem()->child( 0 );
|
||||
|
||||
@@ -100,7 +101,7 @@ PipelineStatusView::onPipelineUpdate( const query_ptr& query )
|
||||
|
||||
|
||||
QSize
|
||||
PipelineStatusView::sizeHint() const
|
||||
JobStatusView::sizeHint() const
|
||||
{
|
||||
unsigned int y = 0;
|
||||
y += m_tree->header()->height();
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -16,23 +17,24 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIPELINESTATUSVIEW_H
|
||||
#define PIPELINESTATUSVIEW_H
|
||||
#ifndef JOBSTATUSVIEW_H
|
||||
#define JOBSTATUSVIEW_H
|
||||
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "widgets/animatedsplitter.h"
|
||||
#include "query.h"
|
||||
|
||||
class StreamConnection;
|
||||
|
||||
class PipelineStatusView : public AnimatedWidget
|
||||
class JobStatusView : public AnimatedWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PipelineStatusView( AnimatedSplitter* parent );
|
||||
virtual ~PipelineStatusView()
|
||||
explicit JobStatusView( AnimatedSplitter* parent );
|
||||
virtual ~JobStatusView()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -42,8 +44,8 @@ private slots:
|
||||
void onPipelineUpdate( const Tomahawk::query_ptr& query = Tomahawk::query_ptr() );
|
||||
|
||||
private:
|
||||
QTreeWidget* m_tree;
|
||||
QTreeView* m_tree;
|
||||
AnimatedSplitter* m_parent;
|
||||
};
|
||||
|
||||
#endif // TRANSFERVIEW_H
|
||||
#endif // JOBSTATUSVIEW_H
|
||||
|
@@ -1,30 +0,0 @@
|
||||
|
||||
|
||||
SET( touchmahawkSources ${final_src} )
|
||||
#LIST( REMOVE_ITEM touchmahawkSources "main.cpp" )
|
||||
|
||||
SET( touchmahawkHeaders
|
||||
active/tomahawktouchwindow.h
|
||||
)
|
||||
|
||||
SET( touchmahawkSources
|
||||
${touchmahawkSources}
|
||||
active/tomahawktouchwindow.cpp
|
||||
|
||||
# active/main.cpp
|
||||
)
|
||||
|
||||
|
||||
qt4_wrap_cpp( touchmahawkMoc ${touchmahawkHeaders} )
|
||||
|
||||
SET( touchmahawkFinalSources ${touchmahawkMoc} ${touchmahawkSources} )
|
||||
SET( touchmahawkLinkLibraries
|
||||
kdeclarative
|
||||
${tomahawkLinkLibraries}
|
||||
) #${QT_QTDECLARATIVE_LIBRARY}
|
||||
|
||||
ADD_EXECUTABLE( active-tomahawk ${touchmahawkFinalSources} )
|
||||
TARGET_LINK_LIBRARIES( active-tomahawk ${touchmahawkLinkLibraries} )
|
||||
SET_TARGET_PROPERTIES( active-tomahawk PROPERTIES COMPILE_FLAGS -DTOUCHMAHAWK )
|
||||
INSTALL( TARGETS active-tomahawk DESTINATION bin )
|
||||
|
@@ -1,134 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "active/tomahawktouchwindow.h"
|
||||
|
||||
#include "utils/logger.h"
|
||||
#include "audio/audioengine.h"
|
||||
#include "globalactionmanager.h"
|
||||
#include "sourcesmodel.h"
|
||||
#include "items/sourcetreeitem.h"
|
||||
#include "items/collectionitem.h"
|
||||
#include "viewmanager.h"
|
||||
|
||||
|
||||
#include "libtomahawk/playlist/treeproxymodel.h"
|
||||
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QtDeclarative>
|
||||
|
||||
#define QMLGUI "/home/domme/dev/sources/tomahawk-qml"
|
||||
|
||||
TomahawkTouchWindow::TomahawkTouchWindow()
|
||||
: m_view(0)
|
||||
, m_currentPlaylistTreeModel(0)
|
||||
{
|
||||
QFileSystemWatcher* watcher = new QFileSystemWatcher;
|
||||
watcher->addPath( QMLGUI );
|
||||
|
||||
connect( watcher, SIGNAL( directoryChanged( QString ) ), SLOT( loadQml() ));
|
||||
loadQml();
|
||||
|
||||
setCentralWidget( m_view );
|
||||
setWindowTitle("Touch-ma-hawk");
|
||||
}
|
||||
|
||||
|
||||
TomahawkTouchWindow::~TomahawkTouchWindow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TomahawkTouchWindow::play(const QModelIndex& index )
|
||||
{
|
||||
TreeModelItem* item = m_currentPlaylistTreeModel->sourceModel()->itemFromIndex( m_currentPlaylistTreeModel->mapToSource( index ) );
|
||||
if ( item )
|
||||
{
|
||||
m_currentPlaylistTreeModel->sourceModel()->setCurrentItem( item->index );
|
||||
AudioEngine::instance()->playItem( m_currentPlaylistTreeModel, item->result() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TomahawkTouchWindow::activateItem(const QModelIndex& index)
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << index;
|
||||
SourceTreeItem* item = qobject_cast< SourceTreeItem* >( s_sourcesModel->data( index, SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >() );
|
||||
item->activate();
|
||||
|
||||
CollectionItem* collectionItem = qobject_cast< CollectionItem* >( item );
|
||||
if( collectionItem )
|
||||
{
|
||||
tLog() << "Activate collectionItem!";
|
||||
Tomahawk::collection_ptr collection = collectionItem->source()->collection();
|
||||
|
||||
TreeModel* model = ViewManager::instance()->treeModelForCollection( collection );
|
||||
TreeProxyModel* proxyModel = m_modelProxyModels.value( model );
|
||||
if( !proxyModel )
|
||||
{
|
||||
proxyModel = new TreeProxyModel();
|
||||
//m_currentPlaylistTreeModel->setDynamicSortFilter( true );
|
||||
proxyModel->setSourceTreeModel( model );
|
||||
proxyModel->sort(TreeModel::Name, Qt::AscendingOrder );
|
||||
//m_currentPlaylistTreeModel->setShowModes( false );
|
||||
//m_currentPlaylistTreeModel->setSortRole( );
|
||||
}
|
||||
|
||||
m_currentPlaylistTreeModel = proxyModel;
|
||||
emit currentTreeModelChanged();
|
||||
//m_view->rootContext()->setContextProperty( "currentPlaylistTreeModel", m_currentPlaylistTreeModel );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
TomahawkTouchWindow::loadQml()
|
||||
{
|
||||
tLog() << Q_FUNC_INFO;
|
||||
qmlRegisterType<AudioEngine>("org.tomahawkplayer.qmlcomponents", 1, 0, "AudioEngine");
|
||||
qmlRegisterType<TreeProxyModel>("org.tomahawkplayer.qmlcomponents", 1, 0, "TreeProxyModel");
|
||||
|
||||
if( !m_view )
|
||||
{
|
||||
tLog()<< Q_FUNC_INFO << "create qml view";
|
||||
m_view = new QDeclarativeView;
|
||||
m_view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
|
||||
m_view->show();
|
||||
}
|
||||
|
||||
tLog()<< Q_FUNC_INFO << "clear component cache";
|
||||
m_view->engine()->clearComponentCache();
|
||||
|
||||
tLog()<< Q_FUNC_INFO << "set context property";
|
||||
QDeclarativeContext* context = m_view->rootContext();
|
||||
|
||||
tLog()<< Q_FUNC_INFO << "make objects accessible from qml";
|
||||
context->setContextProperty( "touchWindow", this );
|
||||
context->setContextProperty( "audioEngine", AudioEngine::instance() );
|
||||
context->setContextProperty( "globalActionManager", GlobalActionManager::instance() );
|
||||
context->setContextProperty( "sourcesModel", s_sourcesModel );
|
||||
|
||||
// don't start in an undefined state
|
||||
m_currentPlaylistTreeModel = 0;
|
||||
//context->setContextProperty( "currentPlaylistTreeModel", m_currentPlaylistTreeModel );
|
||||
|
||||
tLog()<< Q_FUNC_INFO << "set source";
|
||||
m_view->setSource( QUrl::fromLocalFile( QMLGUI "/main.qml" ) );
|
||||
}
|
@@ -1,62 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOMAHAWKTOUCHWINDOW_H
|
||||
#define TOMAHAWKTOUCHWINDOW_H
|
||||
|
||||
#include "tomahawkwindow.h"
|
||||
|
||||
#include <QtDeclarative>
|
||||
|
||||
class TomahawkTouchWindow;
|
||||
class QFileSystemWatcher;
|
||||
class TreeModel;
|
||||
class TreeProxyModel;
|
||||
|
||||
class TomahawkTouchWindow : public TomahawkWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( TreeProxyModel* currentTreeModel READ currentTreeModel NOTIFY currentTreeModelChanged )
|
||||
|
||||
public:
|
||||
TomahawkTouchWindow();
|
||||
~TomahawkTouchWindow();
|
||||
|
||||
|
||||
Q_INVOKABLE void play( const QModelIndex& index );
|
||||
Q_INVOKABLE void activateItem( const QModelIndex& index );
|
||||
|
||||
signals:
|
||||
void currentTreeModelChanged();
|
||||
|
||||
private slots:
|
||||
void loadQml();
|
||||
|
||||
private:
|
||||
TreeProxyModel* currentTreeModel() { return m_currentPlaylistTreeModel; }
|
||||
|
||||
|
||||
QDeclarativeView* m_view;
|
||||
QFileSystemWatcher* m_watcher;
|
||||
|
||||
TreeProxyModel* m_currentPlaylistTreeModel;
|
||||
QHash< TreeModel*, TreeProxyModel* > m_modelProxyModels;
|
||||
};
|
||||
|
||||
#endif // TOMAHAWKTOUCHWINDOW_H
|
||||
|
@@ -128,7 +128,7 @@ AudioControls::AudioControls( QWidget* parent )
|
||||
connect( AudioEngine::instance(), SIGNAL( timerMilliSeconds( qint64 ) ), SLOT( onPlaybackTimer( qint64 ) ) );
|
||||
connect( AudioEngine::instance(), SIGNAL( volumeChanged( int ) ), SLOT( onVolumeChanged( int ) ) );
|
||||
|
||||
m_defaultCover = QPixmap( RESPATH "images/no-album-art-placeholder.png" )
|
||||
m_defaultCover = QPixmap( RESPATH "images/no-album-no-case.png" )
|
||||
.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
@@ -207,14 +207,14 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result )
|
||||
|
||||
ui->seekSlider->setVisible( true );
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
|
||||
Tomahawk::InfoSystem::InfoStringHash trackInfo;
|
||||
trackInfo["artist"] = result->artist()->name();
|
||||
trackInfo["album"] = result->album()->name();
|
||||
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData;
|
||||
requestData.caller = s_acInfoIdentifier;
|
||||
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo );
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
@@ -538,6 +538,7 @@ AudioControls::dropEvent( QDropEvent* e )
|
||||
if ( DropJob::acceptsMimeData( e->mimeData() ) )
|
||||
{
|
||||
DropJob *dj = new DropJob();
|
||||
dj->setDropAction( DropJob::Append );
|
||||
connect( dj, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( droppedTracks( QList<Tomahawk::query_ptr> ) ) );
|
||||
dj->tracksFromMimeData( e->mimeData() );
|
||||
|
||||
@@ -551,8 +552,8 @@ AudioControls::droppedTracks( QList< query_ptr > tracks )
|
||||
{
|
||||
if ( !tracks.isEmpty() )
|
||||
{
|
||||
// queue and play the first if nothign is playing
|
||||
GlobalActionManager::instance()->handleOpenTrack( tracks.first() );
|
||||
// queue and play the first no matter what
|
||||
GlobalActionManager::instance()->handlePlayTrack( tracks.first() );
|
||||
|
||||
// just queue the rest
|
||||
for ( int i = 1; i < tracks.size(); i++ )
|
||||
@@ -566,7 +567,7 @@ AudioControls::droppedTracks( QList< query_ptr > tracks )
|
||||
void
|
||||
AudioControls::onLoveButtonClicked( bool checked )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
|
||||
Tomahawk::InfoSystem::InfoStringHash trackInfo;
|
||||
trackInfo["title"] = m_currentTrack->track();
|
||||
trackInfo["artist"] = m_currentTrack->artist()->name();
|
||||
trackInfo["album"] = m_currentTrack->album()->name();
|
||||
@@ -575,7 +576,7 @@ AudioControls::onLoveButtonClicked( bool checked )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_acInfoIdentifier, Tomahawk::InfoSystem::InfoLove,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) );
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ) );
|
||||
|
||||
DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "true") );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
||||
@@ -585,7 +586,7 @@ AudioControls::onLoveButtonClicked( bool checked )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_acInfoIdentifier, Tomahawk::InfoSystem::InfoUnLove,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) );
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ) );
|
||||
|
||||
DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "false" ) );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
||||
|
@@ -25,10 +25,12 @@
|
||||
#include "result.h"
|
||||
#include "playlistinterface.h"
|
||||
#include "infosystem/infosystem.h"
|
||||
#include "query.h"
|
||||
|
||||
class QDropEvent;
|
||||
class QDragEnterEvent;
|
||||
class QDragMoveEvent;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class AudioControls;
|
||||
|
@@ -261,21 +261,56 @@
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="ImageButton" name="loveButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
<widget class="QLabel" name="ownerLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>7</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>love</string>
|
||||
<string>Owner</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="socialLayout">
|
||||
<item>
|
||||
<spacer name="socialSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ImageButton" name="loveButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>love</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
@@ -284,31 +319,13 @@
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>13</height>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="ownerLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>7</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Owner</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
145
src/breakpad/BreakPad.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BreakPad.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
#include <string.h>
|
||||
|
||||
#define CRASH_REPORTER_BINARY "CrashReporter"
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
static bool
|
||||
LaunchUploader( const char* dump_dir, const char* minidump_id, void* that, bool succeeded )
|
||||
{
|
||||
// DON'T USE THE HEAP!!!
|
||||
// So that indeed means, no QStrings, no qDebug(), no QAnything, seriously!
|
||||
|
||||
if ( !succeeded )
|
||||
return false;
|
||||
|
||||
const char* crashReporter = static_cast<BreakPad*>(that)->crashReporter();
|
||||
pid_t pid = fork();
|
||||
|
||||
if ( pid == -1 ) // fork failed
|
||||
return false;
|
||||
if ( pid == 0 )
|
||||
{
|
||||
// we are the fork
|
||||
execl( crashReporter,
|
||||
crashReporter,
|
||||
dump_dir,
|
||||
minidump_id,
|
||||
minidump_id,
|
||||
(char*) 0 );
|
||||
|
||||
// execl replaces this process, so no more code will be executed
|
||||
// unless it failed. If it failed, then we should return false.
|
||||
printf( "Error: Can't launch CrashReporter!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// we called fork()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
BreakPad::BreakPad( const QString& path )
|
||||
#ifdef Q_OS_LINUX
|
||||
: google_breakpad::ExceptionHandler( path.toStdString(), 0, LaunchUploader, this, true )
|
||||
#else
|
||||
: google_breakpad::ExceptionHandler( path.toStdString(), 0, LaunchUploader, this, true, 0 )
|
||||
#endif
|
||||
{
|
||||
QString reporter = QString( "%1/%2" ).arg( qApp->applicationDirPath() ).arg( CRASH_REPORTER_BINARY );
|
||||
|
||||
char* creporter;
|
||||
std::string sreporter = reporter.toStdString();
|
||||
creporter = new char[ sreporter.size() + 1 ];
|
||||
strcpy( creporter, sreporter.c_str() );
|
||||
|
||||
m_crashReporter = creporter;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
static bool
|
||||
LaunchUploader( const wchar_t* dump_dir, const wchar_t* minidump_id, void* that, EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *assertion, bool succeeded )
|
||||
{
|
||||
if ( !succeeded )
|
||||
return false;
|
||||
|
||||
// DON'T USE THE HEAP!!!
|
||||
// So that indeed means, no QStrings, no qDebug(), no QAnything, seriously!
|
||||
|
||||
// broken in mingw, hardcode it for now
|
||||
|
||||
// const char* productName = static_cast<BreakPad*>(that)->productName();s
|
||||
// convert productName to widechars, which sadly means the product name must be Latin1
|
||||
|
||||
wchar_t product_name[ 256 ] = L"tomahawk";;
|
||||
|
||||
// char* out = (char*)product_name;
|
||||
// const char* in = productName - 1;
|
||||
// do {
|
||||
// *out++ = *++in; //latin1 chars fit in first byte of each wchar
|
||||
// *out++ = '\0'; //every second byte is NULL
|
||||
// }
|
||||
// while (*in);
|
||||
|
||||
wchar_t command[MAX_PATH * 3 + 6];
|
||||
wcscpy( command, CRASH_REPORTER_BINARY L" \"" );
|
||||
wcscat( command, dump_dir );
|
||||
wcscat( command, L"\" \"" );
|
||||
wcscat( command, minidump_id );
|
||||
wcscat( command, L"\" \"" );
|
||||
wcscat( command, product_name );
|
||||
wcscat( command, L"\"" );
|
||||
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
ZeroMemory( &si, sizeof( si ) );
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_SHOWNORMAL;
|
||||
ZeroMemory( &pi, sizeof(pi) );
|
||||
|
||||
if (CreateProcess( NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
|
||||
{
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
TerminateProcess( GetCurrentProcess(), 1 );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
BreakPad::BreakPad( const QString& path )
|
||||
: google_breakpad::ExceptionHandler( path.toStdWString(), 0, LaunchUploader, this, true )
|
||||
{
|
||||
}
|
||||
|
||||
#endif // WIN32
|
47
src/breakpad/BreakPad.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QString>
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include "client/mac/handler/exception_handler.h"
|
||||
#elif defined WIN32
|
||||
# include "client/windows/handler/exception_handler.h"
|
||||
#elif defined __linux__
|
||||
# include "client/linux/handler/exception_handler.h"
|
||||
#endif
|
||||
|
||||
class BreakPad : public google_breakpad::ExceptionHandler
|
||||
{
|
||||
const char* m_productName; // yes! It MUST be const char[]
|
||||
const char* m_crashReporter; // again, const char[]
|
||||
|
||||
public:
|
||||
BreakPad( const QString &dump_write_dirpath );
|
||||
|
||||
~BreakPad()
|
||||
{}
|
||||
|
||||
void setProductName( const char* s ) { m_productName = s; };
|
||||
const char* productName() const { return m_productName; }
|
||||
|
||||
void setCrashReporter( const char* s ) { m_crashReporter = s; };
|
||||
const char* crashReporter() const { return m_crashReporter; }
|
||||
};
|
||||
|
||||
#undef char
|
20
src/breakpad/CrashReporter/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
PROJECT( CrashReporter )
|
||||
|
||||
FIND_PACKAGE( Qt4 REQUIRED )
|
||||
SET( QT_USE_QTNETWORK TRUE )
|
||||
|
||||
SET( crashreporter_SOURCES main.cpp CrashReporter.cpp )
|
||||
SET( crashreporter_HEADERS CrashReporter.h )
|
||||
SET( crashreporter_UI CrashReporter.ui )
|
||||
SET( crashreporter_RC ../../../resources.qrc )
|
||||
|
||||
QT4_WRAP_CPP( crashreporter_HEADERS_MOC ${crashreporter_HEADERS} )
|
||||
QT4_WRAP_UI( crashreporter_UI_HEADERS ${crashreporter_UI} )
|
||||
QT4_ADD_RESOURCES( crashreporter_RC_RCC ${crashreporter_RC} )
|
||||
|
||||
INCLUDE( ${QT_USE_FILE} )
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/src ../../libtomahawk )
|
||||
ADD_DEFINITIONS( ${QT_DEFINITIONS} )
|
||||
|
||||
ADD_EXECUTABLE( CrashReporter WIN32 ${crashreporter_SOURCES} ${crashreporter_HEADERS_MOC} ${crashreporter_UI_HEADERS} ${crashreporter_RC_RCC} )
|
||||
TARGET_LINK_LIBRARIES( CrashReporter ${QT_LIBRARIES} tomahawklib )
|
186
src/breakpad/CrashReporter/CrashReporter.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CrashReporter.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QDir>
|
||||
#include <QDateTime>
|
||||
#include <QHttp>
|
||||
|
||||
#include "utils/tomahawkutils.h"
|
||||
|
||||
#define LOGFILE TomahawkUtils::appLogDir().filePath( "Tomahawk.log" ).toLocal8Bit()
|
||||
#define RESPATH ":/data/"
|
||||
|
||||
|
||||
CrashReporter::CrashReporter( const QStringList& args )
|
||||
{
|
||||
setWindowIcon( QIcon( RESPATH "icons/tomahawk-icon-128x128.png" ) );
|
||||
|
||||
ui.setupUi( this );
|
||||
|
||||
ui.logoLabel->setPixmap( QPixmap( RESPATH "icons/tomahawk-icon-128x128.png" ).scaled( QSize( 55, 55 ), Qt::KeepAspectRatio, Qt::SmoothTransformation ) );
|
||||
ui.progressBar->setRange( 0, 100 );
|
||||
ui.progressBar->setValue( 0 );
|
||||
ui.progressLabel->setPalette( Qt::gray );
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
QFont f = ui.bottomLabel->font();
|
||||
f.setPointSize( 10 );
|
||||
ui.bottomLabel->setFont( f );
|
||||
f.setPointSize( 11 );
|
||||
ui.progressLabel->setFont( f );
|
||||
ui.progressLabel->setIndent( 3 );
|
||||
#else
|
||||
ui.vboxLayout->setSpacing( 16 );
|
||||
ui.progressBar->setTextVisible( false );
|
||||
ui.progressLabel->setIndent( 1 );
|
||||
ui.bottomLabel->setDisabled( true );
|
||||
ui.bottomLabel->setIndent( 1 );
|
||||
|
||||
// adjust the spacer since we adjusted the spacing above
|
||||
for ( int x = 0; x < ui.vboxLayout->count(); ++x )
|
||||
{
|
||||
if ( QSpacerItem* spacer = ui.vboxLayout->itemAt( x )->spacerItem() )
|
||||
{
|
||||
spacer->changeSize( 6, 2, QSizePolicy::Minimum, QSizePolicy::Fixed );
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif //Q_WS_MAC
|
||||
|
||||
m_http = new QHttp( "oops.tomahawk-player.org", 80, this );
|
||||
|
||||
connect( m_http, SIGNAL( done( bool ) ), SLOT( onDone() ), Qt::QueuedConnection );
|
||||
connect( m_http, SIGNAL( dataSendProgress( int, int ) ), SLOT( onProgress( int, int ) ) );
|
||||
|
||||
m_dir = args.value( 1 );
|
||||
m_minidump = m_dir + '/' + args.value( 2 ) + ".dmp";
|
||||
m_product_name = args.value( 3 );
|
||||
|
||||
setFixedSize( sizeHint() );
|
||||
|
||||
QTimer::singleShot( 0, this, SLOT( send() ) );
|
||||
}
|
||||
|
||||
|
||||
static QByteArray
|
||||
contents( const QString& path )
|
||||
{
|
||||
QFile f( path );
|
||||
f.open( QFile::ReadOnly );
|
||||
return f.readAll();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CrashReporter::send()
|
||||
{
|
||||
QByteArray body;
|
||||
|
||||
// socorro expects a 10 digit build id
|
||||
QRegExp rx( "(\\d+\\.\\d+\\.\\d+).(\\d+)" );
|
||||
rx.exactMatch( TomahawkUtils::appFriendlyVersion() );
|
||||
QString const version = rx.cap( 1 );
|
||||
QString const buildId = rx.cap( 2 ).leftJustified( 10, '0' );
|
||||
|
||||
// add parameters
|
||||
typedef QPair<QByteArray, QByteArray> Pair;
|
||||
QList<Pair> pairs;
|
||||
pairs << Pair( "BuildID", buildId.toUtf8() )
|
||||
<< Pair( "ProductName", m_product_name.toUtf8() )
|
||||
<< Pair( "Version", TomahawkUtils::appFriendlyVersion().toLocal8Bit() )
|
||||
<< Pair( "Vendor", "Tomahawk" )
|
||||
<< Pair( "timestamp", QByteArray::number( QDateTime::currentDateTime().toTime_t() ) );
|
||||
|
||||
foreach ( Pair const pair, pairs )
|
||||
{
|
||||
body += "--thkboundary\r\n";
|
||||
body += "Content-Disposition: form-data; name=\"" +
|
||||
pair.first + "\"\r\n\r\n" +
|
||||
pair.second + "\r\n";
|
||||
}
|
||||
|
||||
// add minidump file
|
||||
body += "--thkboundary\r\n";
|
||||
body += "Content-Disposition: form-data; name=\"upload_file_minidump\"; filename=\""
|
||||
+ QFileInfo( m_minidump ).fileName() + "\"\r\n";
|
||||
body += "Content-Type: application/octet-stream\r\n";
|
||||
body += "\r\n";
|
||||
body += contents( m_minidump );
|
||||
body += "\r\n";
|
||||
|
||||
// add logfile
|
||||
body += "--thkboundary\r\n";
|
||||
body += "Content-Disposition: form-data; name=\"upload_file_tomahawklog\"; filename=\"Tomahawk.log\"\r\n";
|
||||
body += "Content-Type: application/x-gzip\r\n";
|
||||
body += "\r\n";
|
||||
body += qCompress( contents( LOGFILE ) );
|
||||
body += "\r\n";
|
||||
body += "--thkboundary--\r\n";
|
||||
|
||||
QHttpRequestHeader header( "POST", "/addreport.php" );
|
||||
header.setContentType( "multipart/form-data; boundary=thkboundary" );
|
||||
header.setValue( "HOST", "oops.tomahawk-player.org" );
|
||||
|
||||
m_http->request( header, body );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CrashReporter::onProgress( int done, int total )
|
||||
{
|
||||
if ( total )
|
||||
{
|
||||
QString const msg = tr( "Uploaded %L1 of %L2 KB." ).arg( done / 1024 ).arg( total / 1024 );
|
||||
|
||||
ui.progressBar->setMaximum( total );
|
||||
ui.progressBar->setValue( done );
|
||||
ui.progressLabel->setText( msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CrashReporter::onDone()
|
||||
{
|
||||
QByteArray data = m_http->readAll();
|
||||
ui.progressBar->setValue( ui.progressBar->maximum() );
|
||||
ui.button->setText( tr( "Close" ) );
|
||||
|
||||
QString const response = QString::fromUtf8( data );
|
||||
|
||||
if ( m_http->error() != QHttp::NoError || !response.startsWith( "CrashID=" ) )
|
||||
{
|
||||
onFail( m_http->error(), m_http->errorString() );
|
||||
}
|
||||
else
|
||||
ui.progressLabel->setText( tr( "Sent! <b>Many thanks</b>." ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CrashReporter::onFail( int error, const QString& errorString )
|
||||
{
|
||||
ui.button->setText( tr( "Close" ) );
|
||||
ui.progressLabel->setText( tr( "Failed to send crash info." ) );
|
||||
qDebug() << "Error:" << error << errorString;
|
||||
}
|
52
src/breakpad/CrashReporter/CrashReporter.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CRASHREPORTER_H
|
||||
#define CRASHREPORTER_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QFile>
|
||||
|
||||
#include "ui_CrashReporter.h"
|
||||
|
||||
|
||||
class CrashReporter : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CrashReporter( const QStringList& argv );
|
||||
|
||||
private:
|
||||
Ui::CrashReporter ui;
|
||||
|
||||
QString m_minidump;
|
||||
QString m_dir;
|
||||
QString m_product_name;
|
||||
class QHttp* m_http;
|
||||
|
||||
public slots:
|
||||
void send();
|
||||
|
||||
private slots:
|
||||
void onDone();
|
||||
void onProgress( int done, int total );
|
||||
void onFail( int error, const QString& errorString );
|
||||
};
|
||||
|
||||
#endif // CRASHREPORTER_H
|
223
src/breakpad/CrashReporter/CrashReporter.ui
Normal file
@@ -0,0 +1,223 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CrashReporter</class>
|
||||
<widget class="QDialog" name="CrashReporter">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>438</width>
|
||||
<height>196</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Tomahawk Crash Reporter</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="logoLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>55</width>
|
||||
<height>55</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>55</width>
|
||||
<height>55</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="topLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><p><b>Sorry!</b>&nbsp;Tomahawk crashed. Information about the crash is now being sent to Tomahawk HQ so that we can fix the bug.</p></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>6</width>
|
||||
<height>6</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="progressLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="button">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Abort</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="bottomLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>You can disable sending crash reports in the configuration dialog.</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>button</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>CrashReporter</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>424</x>
|
||||
<y>154</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>247</x>
|
||||
<y>195</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
56
src/breakpad/CrashReporter/main.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CrashReporter.h"
|
||||
|
||||
#include <QTranslator>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
const char* k_usage =
|
||||
"Usage:\n"
|
||||
" CrashReporter <logDir> <dumpFileName> <productName>\n";
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
// used by some Qt stuff, eg QSettings
|
||||
// leave first! As Settings object is created quickly
|
||||
QCoreApplication::setApplicationName( "Tomahawk" );
|
||||
QCoreApplication::setOrganizationName( "Tomahawk" );
|
||||
QCoreApplication::setOrganizationDomain( "tomahawk-player.org" );
|
||||
|
||||
QApplication app( argc, argv );
|
||||
|
||||
QString langCode;
|
||||
QTranslator translatorApp;
|
||||
QTranslator translatorQt;
|
||||
|
||||
/* app.installTranslator( &translatorApp );
|
||||
app.installTranslator( &translatorQt );*/
|
||||
|
||||
if ( app.arguments().size() != 4 )
|
||||
{
|
||||
std::cout << k_usage;
|
||||
return 1;
|
||||
}
|
||||
|
||||
CrashReporter reporter( app.arguments() );
|
||||
reporter.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
@@ -11,6 +11,7 @@
|
||||
#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
|
||||
#define CMAKE_SYSTEM "${CMAKE_SYSTEM}"
|
||||
|
||||
#cmakedefine LION
|
||||
#cmakedefine SNOW_LEOPARD
|
||||
#cmakedefine LEOPARD
|
||||
#cmakedefine HAVE_SPARKLE
|
||||
@@ -18,5 +19,6 @@
|
||||
#cmakedefine LIBLASTFM_FOUND
|
||||
#cmakedefine GLOOX_FOUND
|
||||
#cmakedefine QCA2_FOUND
|
||||
#cmakedefine LIBATTICA_FOUND
|
||||
|
||||
#endif // CONFIG_H_IN
|
||||
|
@@ -30,7 +30,7 @@ public:
|
||||
DelegateConfigWrapper( QWidget* conf, const QString& title, QWidget* parent, Qt::WindowFlags flags = 0 ) : QDialog( parent, flags ), m_widget( conf )
|
||||
{
|
||||
m_widget->setWindowFlags( Qt::Sheet );
|
||||
#ifdef Q_OS_MAC
|
||||
#ifdef Q_WS_MAC
|
||||
m_widget->setVisible( true );
|
||||
#endif
|
||||
|
||||
@@ -47,12 +47,13 @@ public:
|
||||
|
||||
setLayout( v );
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#ifdef Q_WS_MAC
|
||||
setSizeGripEnabled( false );
|
||||
setMinimumSize( sizeHint() );
|
||||
setMaximumSize( sizeHint() ); // to remove the resize grip on osx this is the only way
|
||||
|
||||
connect( conf, SIGNAL( sizeHintChanged() ), this, SLOT( updateSizeHint() ) );
|
||||
if( conf->metaObject()->indexOfSignal( "sizeHintChanged()" ) > -1 )
|
||||
connect( conf, SIGNAL( sizeHintChanged() ), this, SLOT( updateSizeHint() ) );
|
||||
#else
|
||||
m_widget->setVisible( true );
|
||||
#endif
|
||||
@@ -86,7 +87,8 @@ public slots:
|
||||
m_widget->setVisible( false );
|
||||
}
|
||||
|
||||
void updateSizeHint() {
|
||||
void updateSizeHint()
|
||||
{
|
||||
hide();
|
||||
setSizeGripEnabled( false );
|
||||
setMinimumSize( sizeHint() );
|
||||
|
@@ -123,6 +123,7 @@ void DiagnosticsDialog::updateLogView()
|
||||
|
||||
Q_FOREACH( const QString &peerId, sip->peersOnline() )
|
||||
{
|
||||
/* enable this again, when we check the source has this peerId
|
||||
bool connected = false;
|
||||
Q_FOREACH( const Tomahawk::source_ptr &source, sources )
|
||||
{
|
||||
@@ -131,33 +132,35 @@ void DiagnosticsDialog::updateLogView()
|
||||
connected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
QString versionString = SipHandler::instance()->versionString( peerId );
|
||||
SipInfo sipInfo = SipHandler::instance()->sipInfo( peerId );
|
||||
if( !sipInfo.isValid() )
|
||||
log.append(
|
||||
QString(" %1: %2 (%3) %4\n")
|
||||
QString(" %1: %2 %3" /*"(%4)"*/ "\n")
|
||||
.arg( peerId )
|
||||
.arg( "sipinfo invalid" )
|
||||
.arg( connected ? "connected" : "not connected")
|
||||
.arg( versionString )
|
||||
// .arg( connected ? "connected" : "not connected")
|
||||
);
|
||||
else if( sipInfo.isVisible() )
|
||||
log.append(
|
||||
QString(" %1: %2:%3 (%4) %5\n")
|
||||
QString(" %1: %2:%3 %4" /*" (%5)"*/ "\n")
|
||||
.arg( peerId )
|
||||
.arg( sipInfo.host().hostName() )
|
||||
.arg( sipInfo.port() )
|
||||
.arg( connected ? "connected" : "not connected")
|
||||
.arg( versionString )
|
||||
// .arg( connected ? "connected" : "not connected")
|
||||
|
||||
);
|
||||
else
|
||||
log.append(
|
||||
QString(" %1: visible: false (%2) %3\n")
|
||||
QString(" %1: visible: false %2" /*" (%3)"*/ "\n")
|
||||
.arg( peerId )
|
||||
.arg( connected ? "connected" : "not connected")
|
||||
.arg( versionString )
|
||||
// .arg( connected ? "connected" : "not connected")
|
||||
|
||||
);
|
||||
}
|
||||
log.append("\n");
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#ifdef ENABLE_HEADLESS
|
||||
|
||||
#define TOMAHAWK_APPLICATION QCoreApplication
|
||||
#include <QApplication>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#else
|
||||
|
||||
|
557
src/libtomahawk/AtticaManager.cpp
Normal file
@@ -0,0 +1,557 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AtticaManager.h"
|
||||
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "pipeline.h"
|
||||
|
||||
#include <attica/downloaditem.h>
|
||||
#include <quazip.h>
|
||||
#include <quazipfile.h>
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QTemporaryFile>
|
||||
#include <QDir>
|
||||
#include <QTimer>
|
||||
|
||||
#include "utils/logger.h"
|
||||
|
||||
using namespace Attica;
|
||||
|
||||
AtticaManager* AtticaManager::s_instance = 0;
|
||||
|
||||
|
||||
AtticaManager::AtticaManager( QObject* parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
connect( &m_manager, SIGNAL( providerAdded( Attica::Provider ) ), this, SLOT( providerAdded( Attica::Provider ) ) );
|
||||
|
||||
// resolvers
|
||||
m_manager.addProviderFile( QUrl( "http://bakery.tomahawk-player.org:10480/resolvers/providers.xml" ) );
|
||||
}
|
||||
|
||||
|
||||
AtticaManager::~AtticaManager()
|
||||
{
|
||||
savePixmapsToCache();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::loadPixmapsFromCache()
|
||||
{
|
||||
QDir cacheDir = TomahawkUtils::appDataDir();
|
||||
if ( !cacheDir.cd( "atticacache" ) ) // doesn't exist, no cache
|
||||
return;
|
||||
|
||||
qDebug() << "Loading resolvers from cache dir:" << cacheDir.absolutePath();
|
||||
qDebug() << "Currently we know about these resolvers:" << m_resolverStates.keys();
|
||||
foreach ( const QString& file, cacheDir.entryList( QStringList() << "*.png", QDir::Files | QDir::NoSymLinks ) )
|
||||
{
|
||||
// load all the pixmaps
|
||||
QFileInfo info( file );
|
||||
if ( !m_resolverStates.contains( info.baseName() ) )
|
||||
{
|
||||
tLog() << "Found resolver icon cached for resolver we no longer see in synchrotron repo:" << info.baseName();
|
||||
continue;
|
||||
}
|
||||
|
||||
QPixmap* icon = new QPixmap( cacheDir.absoluteFilePath( file ) );
|
||||
m_resolverStates[ info.baseName() ].pixmap = icon;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::savePixmapsToCache()
|
||||
{
|
||||
QDir cacheDir = TomahawkUtils::appDataDir();
|
||||
if ( !cacheDir.cd( "atticacache" ) ) // doesn't exist, create
|
||||
{
|
||||
cacheDir.mkdir( "atticacache" );
|
||||
cacheDir.cd( "atticache" );
|
||||
}
|
||||
|
||||
foreach( const QString& id, m_resolverStates.keys() )
|
||||
{
|
||||
if ( !m_resolverStates[ id ].pixmap )
|
||||
continue;
|
||||
|
||||
const QString filename = cacheDir.absoluteFilePath( QString( "%1.png" ).arg( id ) );
|
||||
if ( !m_resolverStates[ id ].pixmap->save( filename ) )
|
||||
{
|
||||
tLog() << "Failed to open cache file for writing:" << filename;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QPixmap
|
||||
AtticaManager::iconForResolver( const Content& resolver )
|
||||
{
|
||||
if ( !m_resolverStates[ resolver.id() ].pixmap )
|
||||
return QPixmap();
|
||||
|
||||
return *m_resolverStates.value( resolver.id() ).pixmap;
|
||||
}
|
||||
|
||||
|
||||
Content::List
|
||||
AtticaManager::resolvers() const
|
||||
{
|
||||
return m_resolvers;
|
||||
}
|
||||
|
||||
|
||||
AtticaManager::ResolverState
|
||||
AtticaManager::resolverState ( const Content& resolver ) const
|
||||
{
|
||||
if ( !m_resolverStates.contains( resolver.id() ) )
|
||||
{
|
||||
return AtticaManager::Uninstalled;
|
||||
}
|
||||
|
||||
return m_resolverStates[ resolver.id() ].state;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AtticaManager::resolversLoaded() const
|
||||
{
|
||||
return !m_resolvers.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
AtticaManager::pathFromId( const QString& resolverId ) const
|
||||
{
|
||||
if ( !m_resolverStates.contains( resolverId ) )
|
||||
return QString();
|
||||
|
||||
return m_resolverStates.value( resolverId ).scriptPath;
|
||||
}
|
||||
|
||||
void
|
||||
AtticaManager::uploadRating( const Content& c )
|
||||
{
|
||||
m_resolverStates[ c.id() ].userRating = c.rating();
|
||||
|
||||
for ( int i = 0; i < m_resolvers.count(); i++ )
|
||||
{
|
||||
if ( m_resolvers[ i ].id() == c.id() )
|
||||
{
|
||||
Attica::Content atticaContent = m_resolvers[ i ];
|
||||
atticaContent.setRating( c.rating() );
|
||||
m_resolvers[ i ] = atticaContent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TomahawkSettings::instance()->setAtticaResolverStates( m_resolverStates );
|
||||
|
||||
PostJob* job = m_resolverProvider.voteForContent( c.id(), (uint)c.rating() );
|
||||
connect( job, SIGNAL( finished( Attica::BaseJob* ) ), job, SLOT( deleteLater() ) );
|
||||
|
||||
job->start();
|
||||
|
||||
emit resolverStateChanged( c.id() );
|
||||
}
|
||||
|
||||
bool
|
||||
AtticaManager::userHasRated( const Content& c ) const
|
||||
{
|
||||
return m_resolverStates[ c.id() ].userRating != -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::providerAdded( const Provider& provider )
|
||||
{
|
||||
if ( provider.name() == "Tomahawk Resolvers" )
|
||||
{
|
||||
m_resolverProvider = provider;
|
||||
|
||||
ListJob< Content >* job = m_resolverProvider.searchContents( Category::List(), QString(), Provider::Downloads, 0, 30 );
|
||||
connect( job, SIGNAL( finished( Attica::BaseJob* ) ), this, SLOT( resolversList( Attica::BaseJob* ) ) );
|
||||
job->start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::resolversList( BaseJob* j )
|
||||
{
|
||||
ListJob< Content >* job = static_cast< ListJob< Content >* >( j );
|
||||
|
||||
m_resolvers = job->itemList();
|
||||
m_resolverStates = TomahawkSettings::instance()->atticaResolverStates();
|
||||
|
||||
// load icon cache from disk, and fetch any we are missing
|
||||
loadPixmapsFromCache();
|
||||
|
||||
foreach ( Content resolver, m_resolvers )
|
||||
{
|
||||
if ( !m_resolverStates.contains( resolver.id() ) )
|
||||
m_resolverStates.insert( resolver.id(), Resolver() );
|
||||
|
||||
if ( !m_resolverStates.value( resolver.id() ).pixmap && !resolver.icons().isEmpty() && !resolver.icons().first().url().isEmpty() )
|
||||
{
|
||||
QNetworkReply* fetch = TomahawkUtils::nam()->get( QNetworkRequest( resolver.icons().first().url() ) );
|
||||
fetch->setProperty( "resolverId", resolver.id() );
|
||||
|
||||
connect( fetch, SIGNAL( finished() ), this, SLOT( resolverIconFetched() ) );
|
||||
}
|
||||
}
|
||||
|
||||
syncServerData();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::resolverIconFetched()
|
||||
{
|
||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( reply );
|
||||
|
||||
const QString resolverId = reply->property( "resolverId" ).toString();
|
||||
|
||||
if ( !reply->error() == QNetworkReply::NoError )
|
||||
{
|
||||
tLog() << "Failed to fetch resolver icon image:" << reply->errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
QPixmap* icon = new QPixmap;
|
||||
icon->loadFromData( data );
|
||||
m_resolverStates[ resolverId ].pixmap = icon;
|
||||
}
|
||||
|
||||
void
|
||||
AtticaManager::syncServerData()
|
||||
{
|
||||
// look for any newer. m_resolvers has list from server, and m_resolverStates will contain any locally installed ones
|
||||
// also update ratings
|
||||
foreach ( const QString& id, m_resolverStates.keys() )
|
||||
{
|
||||
Resolver r = m_resolverStates[ id ];
|
||||
for ( int i = 0; i < m_resolvers.size(); i++ )
|
||||
{
|
||||
Attica::Content upstream = m_resolvers[ i ];
|
||||
// same resolver
|
||||
if ( id != upstream.id() )
|
||||
continue;
|
||||
|
||||
// Update our rating with the server's idea of rating if we haven't rated it
|
||||
if ( m_resolverStates[ id ].userRating != -1 )
|
||||
{
|
||||
upstream.setRating( m_resolverStates[ id ].userRating );
|
||||
m_resolvers[ i ] = upstream;
|
||||
}
|
||||
|
||||
// DO we need to upgrade?
|
||||
if ( ( r.state == Installed || r.state == NeedsUpgrade ) &&
|
||||
!upstream.version().isEmpty() )
|
||||
{
|
||||
if ( newerVersion( r.version, upstream.version() ) )
|
||||
{
|
||||
m_resolverStates[ id ].state = NeedsUpgrade;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AtticaManager::newerVersion( const QString& older, const QString& newer ) const
|
||||
{
|
||||
// Dumb version comparison. Expects two strings, X.Y and Z.V. Returns true if Z > v || Z == V && V > Y
|
||||
// DOES NOT support X.Y.Z version strings
|
||||
if ( older.isEmpty() || newer.isEmpty() )
|
||||
return false;
|
||||
|
||||
QPair<int, int> oldVer, newVer;
|
||||
QStringList parts = older.split( "." );
|
||||
|
||||
if ( parts.size() == 1 )
|
||||
{
|
||||
oldVer.first = parts[ 0 ].toInt();
|
||||
oldVer.second = 0;
|
||||
}
|
||||
else if ( parts.size() == 2 )
|
||||
{
|
||||
oldVer.first = parts[ 0 ].toInt();
|
||||
oldVer.second = parts[ 1 ].toInt();;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
parts = newer.split( "." );
|
||||
if ( parts.size() == 1 )
|
||||
{
|
||||
newVer.first = parts[ 0 ].toInt();
|
||||
newVer.second = 0;
|
||||
}
|
||||
else if ( parts.size() == 2 )
|
||||
{
|
||||
newVer.first = parts[ 0 ].toInt();
|
||||
newVer.second = parts[ 1 ].toInt();;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
// Do the comparison
|
||||
if ( newVer.first > oldVer.first )
|
||||
return true;
|
||||
if ( newVer.first == oldVer.first &&
|
||||
newVer.second > oldVer.second )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
AtticaManager::installResolver( const Content& resolver )
|
||||
{
|
||||
Q_ASSERT( !resolver.id().isNull() );
|
||||
|
||||
if ( m_resolverStates[ resolver.id() ].state != Upgrading )
|
||||
m_resolverStates[ resolver.id() ].state = Installing;
|
||||
|
||||
m_resolverStates[ resolver.id() ].scriptPath = resolver.attribute( "mainscript" );
|
||||
m_resolverStates[ resolver.id() ].version = resolver.version();
|
||||
emit resolverStateChanged( resolver.id() );
|
||||
|
||||
ItemJob< DownloadItem >* job = m_resolverProvider.downloadLink( resolver.id() );
|
||||
connect( job, SIGNAL( finished( Attica::BaseJob* ) ), this, SLOT( resolverDownloadFinished( Attica::BaseJob* ) ) );
|
||||
job->setProperty( "resolverId", resolver.id() );
|
||||
|
||||
job->start();
|
||||
}
|
||||
|
||||
void
|
||||
AtticaManager::upgradeResolver( const Content& resolver )
|
||||
{
|
||||
Q_ASSERT( m_resolverStates.contains( resolver.id() ) );
|
||||
Q_ASSERT( m_resolverStates[ resolver.id() ].state == NeedsUpgrade );
|
||||
|
||||
if ( !m_resolverStates.contains( resolver.id() ) || m_resolverStates[ resolver.id() ].state != NeedsUpgrade )
|
||||
return;
|
||||
|
||||
m_resolverStates[ resolver.id() ].state = Upgrading;
|
||||
emit resolverStateChanged( resolver.id() );
|
||||
|
||||
uninstallResolver( resolver );
|
||||
installResolver( resolver );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::resolverDownloadFinished ( BaseJob* j )
|
||||
{
|
||||
ItemJob< DownloadItem >* job = static_cast< ItemJob< DownloadItem >* >( j );
|
||||
|
||||
if ( job->metadata().error() == Attica::Metadata::NoError )
|
||||
{
|
||||
DownloadItem item = job->result();
|
||||
QUrl url = item.url();
|
||||
// download the resolver itself :)
|
||||
QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
||||
connect( reply, SIGNAL( finished() ), this, SLOT( payloadFetched() ) );
|
||||
reply->setProperty( "resolverId", job->property( "resolverId" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog() << "Failed to do resolver download job!" << job->metadata().error();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::payloadFetched()
|
||||
{
|
||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( reply );
|
||||
|
||||
// we got a zip file, save it to a temporary file, then unzip it to our destination data dir
|
||||
if ( reply->error() == QNetworkReply::NoError )
|
||||
{
|
||||
QTemporaryFile f( QDir::tempPath() + QDir::separator() + "tomahawkattica_XXXXXX.zip" );
|
||||
if ( !f.open() )
|
||||
{
|
||||
tLog() << "Failed to write zip file to temp file:" << f.fileName();
|
||||
return;
|
||||
}
|
||||
f.write( reply->readAll() );
|
||||
f.close();
|
||||
|
||||
QString resolverId = reply->property( "resolverId" ).toString();
|
||||
QDir dir( extractPayload( f.fileName(), resolverId ) );
|
||||
QString resolverPath = dir.absoluteFilePath( m_resolverStates[ resolverId ].scriptPath );
|
||||
|
||||
if ( !resolverPath.isEmpty() )
|
||||
{
|
||||
// update with absolute, not relative, path
|
||||
m_resolverStates[ resolverId ].scriptPath = resolverPath;
|
||||
|
||||
// Do the install / add to tomahawk
|
||||
Tomahawk::Pipeline::instance()->addScriptResolver( resolverPath, true );
|
||||
m_resolverStates[ resolverId ].state = Installed;
|
||||
TomahawkSettings::instance()->setAtticaResolverStates( m_resolverStates );
|
||||
emit resolverInstalled( resolverId );
|
||||
emit resolverStateChanged( resolverId );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog() << "Failed to download attica payload...:" << reply->errorString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
AtticaManager::extractPayload( const QString& filename, const QString& resolverId ) const
|
||||
{
|
||||
// uses QuaZip to extract the temporary zip file to the user's tomahawk data/resolvers directory
|
||||
QuaZip zipFile( filename );
|
||||
if ( !zipFile.open( QuaZip::mdUnzip ) )
|
||||
{
|
||||
tLog() << "Failed to QuaZip open:" << zipFile.getZipError();
|
||||
return QString();
|
||||
}
|
||||
|
||||
if ( !zipFile.goToFirstFile() )
|
||||
{
|
||||
tLog() << "Failed to go to first file in zip archive: " << zipFile.getZipError();
|
||||
return QString();
|
||||
}
|
||||
|
||||
QDir resolverDir = TomahawkUtils::appDataDir();
|
||||
if ( !resolverDir.mkpath( QString( "atticaresolvers/%1" ).arg( resolverId ) ) )
|
||||
{
|
||||
tLog() << "Failed to mkdir resolver save dir: " << TomahawkUtils::appDataDir().absoluteFilePath( QString( "atticaresolvers/%1" ).arg( resolverId ) );
|
||||
return QString();
|
||||
}
|
||||
resolverDir.cd( QString( "atticaresolvers/%1" ).arg( resolverId ) );
|
||||
tDebug() << "Installing resolver to:" << resolverDir.absolutePath();
|
||||
|
||||
QuaZipFile fileInZip( &zipFile );
|
||||
do
|
||||
{
|
||||
QuaZipFileInfo info;
|
||||
zipFile.getCurrentFileInfo( &info );
|
||||
|
||||
if ( !fileInZip.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
tLog() << "Failed to open file inside zip archive:" << info.name << zipFile.getZipName() << "with error:" << zipFile.getZipError();
|
||||
continue;
|
||||
}
|
||||
|
||||
QFile out( resolverDir.absoluteFilePath( fileInZip.getActualFileName() ) );
|
||||
|
||||
QStringList parts = fileInZip.getActualFileName().split( "/" );
|
||||
if ( parts.size() > 1 )
|
||||
{
|
||||
QStringList dirs = parts.mid( 0, parts.size() - 1 );
|
||||
QString dirPath = dirs.join( "/" ); // QDir translates / to \ internally if necessary
|
||||
resolverDir.mkpath( dirPath );
|
||||
}
|
||||
|
||||
// make dir if there is one needed
|
||||
QDir d( fileInZip.getActualFileName() );
|
||||
|
||||
tDebug() << "Writing to output file..." << out.fileName();
|
||||
if ( !out.open( QIODevice::WriteOnly ) )
|
||||
{
|
||||
tLog() << "Failed to open resolver extract file:" << out.errorString() << info.name;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
out.write( fileInZip.readAll() );
|
||||
out.close();
|
||||
fileInZip.close();
|
||||
|
||||
} while ( zipFile.goToNextFile() );
|
||||
|
||||
return resolverDir.absolutePath();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::uninstallResolver( const QString& pathToResolver )
|
||||
{
|
||||
// User manually removed a resolver not through attica dialog, simple remove
|
||||
QRegExp r( ".*([^/]*)/contents/code/main.js" );
|
||||
r.indexIn( pathToResolver );
|
||||
const QString& atticaId = r.cap( 1 );
|
||||
tDebug() << "Got resolver ID to remove:" << atticaId;
|
||||
if ( !atticaId.isEmpty() ) // this is an attica-installed resolver, mark as uninstalled
|
||||
{
|
||||
foreach ( const Content& resolver, m_resolvers )
|
||||
{
|
||||
if ( resolver.id() == atticaId ) // this is the one
|
||||
{
|
||||
m_resolverStates[ atticaId ].state = Uninstalled;
|
||||
TomahawkSettings::instance()->setAtticaResolverState( atticaId, Uninstalled );
|
||||
|
||||
doResolverRemove( atticaId );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::uninstallResolver( const Content& resolver )
|
||||
{
|
||||
if ( m_resolverStates[ resolver.id() ].state != Upgrading )
|
||||
{
|
||||
emit resolverUninstalled( resolver.id() );
|
||||
emit resolverStateChanged( resolver.id() );
|
||||
|
||||
m_resolverStates[ resolver.id() ].state = Uninstalled;
|
||||
TomahawkSettings::instance()->setAtticaResolverState( resolver.id(), Uninstalled );
|
||||
}
|
||||
|
||||
Tomahawk::Pipeline::instance()->removeScriptResolver( pathFromId( resolver.id() ) );
|
||||
doResolverRemove( resolver.id() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::doResolverRemove( const QString& id ) const
|
||||
{
|
||||
// uninstalling is easy... just delete it! :)
|
||||
QDir resolverDir = TomahawkUtils::appDataDir();
|
||||
if ( !resolverDir.cd( QString( "atticaresolvers/%1" ).arg( id ) ) )
|
||||
return;
|
||||
|
||||
if ( id.isEmpty() )
|
||||
return;
|
||||
|
||||
// sanity check
|
||||
if ( !resolverDir.absolutePath().contains( "atticaresolvers" ) ||
|
||||
!resolverDir.absolutePath().contains( id ) )
|
||||
return;
|
||||
|
||||
TomahawkUtils::removeDirectory( resolverDir.absolutePath() );
|
||||
}
|
130
src/libtomahawk/AtticaManager.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ATTICAMANAGER_H
|
||||
#define ATTICAMANAGER_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QPixmap>
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
#ifdef LIBATTICA_FOUND
|
||||
#include <attica/provider.h>
|
||||
#include <attica/providermanager.h>
|
||||
#include <attica/content.h>
|
||||
#endif
|
||||
|
||||
class DLLEXPORT AtticaManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ResolverState {
|
||||
Uninstalled = 0,
|
||||
Installing,
|
||||
Installed,
|
||||
NeedsUpgrade,
|
||||
Upgrading,
|
||||
Failed
|
||||
};
|
||||
|
||||
struct Resolver {
|
||||
QString version, scriptPath;
|
||||
int userRating; // 0-100
|
||||
ResolverState state;
|
||||
QPixmap* pixmap;
|
||||
|
||||
Resolver( const QString& v, const QString& path, int userR, ResolverState s )
|
||||
: version( v ), scriptPath( path ), userRating( userR ), state( s ), pixmap( 0 ) {}
|
||||
Resolver() : userRating( -1 ), state( Uninstalled ), pixmap( 0 ) {}
|
||||
};
|
||||
|
||||
typedef QHash< QString, AtticaManager::Resolver > StateHash;
|
||||
|
||||
static AtticaManager* instance()
|
||||
{
|
||||
if ( !s_instance )
|
||||
s_instance = new AtticaManager();
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
explicit AtticaManager ( QObject* parent = 0 );
|
||||
#ifdef LIBATTICA_FOUND
|
||||
|
||||
virtual ~AtticaManager();
|
||||
#else
|
||||
virtual ~AtticaManager() {}
|
||||
#endif
|
||||
|
||||
#ifdef LIBATTICA_FOUND
|
||||
|
||||
bool resolversLoaded() const;
|
||||
|
||||
Attica::Content::List resolvers() const;
|
||||
ResolverState resolverState( const Attica::Content& resolver ) const;
|
||||
QPixmap iconForResolver( const Attica::Content& id ); // Looks up in icon cache
|
||||
|
||||
void installResolver( const Attica::Content& resolver );
|
||||
void upgradeResolver( const Attica::Content& resolver );
|
||||
void uninstallResolver( const Attica::Content& resolver );
|
||||
void uninstallResolver( const QString& pathToResolver );
|
||||
QString pathFromId( const QString& resolverId ) const;
|
||||
|
||||
void uploadRating( const Attica::Content& c );
|
||||
bool userHasRated( const Attica::Content& c ) const;
|
||||
|
||||
|
||||
signals:
|
||||
void resolversReloaded( const Attica::Content::List& resolvers );
|
||||
|
||||
void resolverStateChanged( const QString& resolverId );
|
||||
void resolverInstalled( const QString& resolverId );
|
||||
void resolverUninstalled( const QString& resolverId );
|
||||
|
||||
private slots:
|
||||
void providerAdded( const Attica::Provider& );
|
||||
void resolversList( Attica::BaseJob* );
|
||||
void resolverDownloadFinished( Attica::BaseJob* );
|
||||
void payloadFetched();
|
||||
|
||||
void loadPixmapsFromCache();
|
||||
void savePixmapsToCache();
|
||||
void resolverIconFetched();
|
||||
|
||||
void syncServerData();
|
||||
bool newerVersion( const QString& older, const QString& newer ) const;
|
||||
|
||||
private:
|
||||
QString extractPayload( const QString& filename, const QString& resolverId ) const;
|
||||
void doResolverRemove( const QString& id ) const;
|
||||
|
||||
Attica::ProviderManager m_manager;
|
||||
|
||||
Attica::Provider m_resolverProvider;
|
||||
Attica::Content::List m_resolvers;
|
||||
StateHash m_resolverStates;
|
||||
#endif
|
||||
|
||||
static AtticaManager* s_instance;
|
||||
};
|
||||
|
||||
#endif // ATTICAMANAGER_H
|
@@ -12,33 +12,12 @@ add_definitions( ${QT_DEFINITIONS} )
|
||||
add_definitions( -DQT_SHARED )
|
||||
add_definitions( -DDLLEXPORT_PRO )
|
||||
|
||||
set( libSources
|
||||
tomahawksettings.cpp
|
||||
sourcelist.cpp
|
||||
pipeline.cpp
|
||||
|
||||
aclsystem.cpp
|
||||
artist.cpp
|
||||
album.cpp
|
||||
collection.cpp
|
||||
playlist.cpp
|
||||
resolver.cpp
|
||||
query.cpp
|
||||
result.cpp
|
||||
source.cpp
|
||||
sourceplaylistinterface.cpp
|
||||
viewpage.cpp
|
||||
viewmanager.cpp
|
||||
globalactionmanager.cpp
|
||||
set( libGuiSources
|
||||
contextmenu.cpp
|
||||
dropjob.cpp
|
||||
|
||||
sip/SipPlugin.cpp
|
||||
sip/SipHandler.cpp
|
||||
sip/SipModel.cpp
|
||||
sip/sipinfo.cpp
|
||||
|
||||
audio/audioengine.cpp
|
||||
globalactionmanager.cpp
|
||||
viewpage.cpp
|
||||
viewmanager.cpp
|
||||
|
||||
context/ContextPage.cpp
|
||||
context/ContextWidget.cpp
|
||||
@@ -47,63 +26,23 @@ set( libSources
|
||||
context/pages/WikipediaContext.cpp
|
||||
context/pages/WebContext.cpp
|
||||
|
||||
database/database.cpp
|
||||
database/fuzzyindex.cpp
|
||||
database/databasecollection.cpp
|
||||
database/localcollection.cpp
|
||||
database/databaseworker.cpp
|
||||
database/databaseimpl.cpp
|
||||
database/databaseresolver.cpp
|
||||
database/databasecommand.cpp
|
||||
database/databasecommandloggable.cpp
|
||||
database/databasecommand_resolve.cpp
|
||||
database/databasecommand_allartists.cpp
|
||||
database/databasecommand_allalbums.cpp
|
||||
database/databasecommand_alltracks.cpp
|
||||
database/databasecommand_addfiles.cpp
|
||||
database/databasecommand_deletefiles.cpp
|
||||
database/databasecommand_dirmtimes.cpp
|
||||
database/databasecommand_filemtimes.cpp
|
||||
database/databasecommand_loadfile.cpp
|
||||
database/databasecommand_logplayback.cpp
|
||||
database/databasecommand_addsource.cpp
|
||||
database/databasecommand_sourceoffline.cpp
|
||||
database/databasecommand_collectionstats.cpp
|
||||
database/databasecommand_loadplaylistentries.cpp
|
||||
database/databasecommand_modifyplaylist.cpp
|
||||
database/databasecommand_playbackhistory.cpp
|
||||
database/databasecommand_setplaylistrevision.cpp
|
||||
database/databasecommand_loadallplaylists.cpp
|
||||
database/databasecommand_loadallsortedplaylists.cpp
|
||||
database/databasecommand_loadallsources.cpp
|
||||
database/databasecommand_createplaylist.cpp
|
||||
database/databasecommand_deleteplaylist.cpp
|
||||
database/databasecommand_renameplaylist.cpp
|
||||
database/databasecommand_loadops.cpp
|
||||
database/databasecommand_updatesearchindex.cpp
|
||||
database/databasecommand_setdynamicplaylistrevision.cpp
|
||||
database/databasecommand_createdynamicplaylist.cpp
|
||||
database/databasecommand_loaddynamicplaylist.cpp
|
||||
database/databasecommand_loaddynamicplaylistentries.cpp
|
||||
database/databasecommand_loadallautoplaylists.cpp
|
||||
database/databasecommand_loadallstations.cpp
|
||||
database/databasecommand_deletedynamicplaylist.cpp
|
||||
database/databasecommand_addclientauth.cpp
|
||||
database/databasecommand_clientauthvalid.cpp
|
||||
database/databasecommand_socialaction.cpp
|
||||
database/databasecommand_loadsocialactions.cpp
|
||||
database/databasecommand_genericselect.cpp
|
||||
database/database.cpp
|
||||
jobview/JobStatusView.cpp
|
||||
jobview/JobStatusModel.cpp
|
||||
jobview/JobStatusDelegate.cpp
|
||||
jobview/PipelineStatusItem.cpp
|
||||
jobview/TransferStatusItem.cpp
|
||||
jobview/LatchedStatusItem.cpp
|
||||
|
||||
infobar/infobar.cpp
|
||||
|
||||
infosystem/infosystemcache.cpp
|
||||
infosystem/infosystem.cpp
|
||||
infosystem/infosystemworker.cpp
|
||||
infosystem/infoplugins/generic/echonestplugin.cpp
|
||||
infosystem/infoplugins/generic/lastfmplugin.cpp
|
||||
infosystem/infoplugins/generic/chartsplugin.cpp
|
||||
infosystem/infoplugins/generic/spotifyPlugin.cpp
|
||||
infosystem/infoplugins/generic/hypemPlugin.cpp
|
||||
infosystem/infoplugins/generic/musixmatchplugin.cpp
|
||||
infosystem/infoplugins/generic/musicbrainzPlugin.cpp
|
||||
infosystem/infoplugins/generic/RoviPlugin.cpp
|
||||
|
||||
playlist/treemodel.cpp
|
||||
playlist/treeproxymodel.cpp
|
||||
@@ -133,16 +72,7 @@ set( libSources
|
||||
playlist/customplaylistview.cpp
|
||||
playlist/ViewHeader.cpp
|
||||
|
||||
playlist/topbar/topbar.cpp
|
||||
playlist/topbar/clearbutton.cpp
|
||||
playlist/topbar/searchlineedit.cpp
|
||||
playlist/topbar/lineedit.cpp
|
||||
playlist/topbar/searchbutton.cpp
|
||||
|
||||
playlist/dynamic/DynamicPlaylist.cpp
|
||||
playlist/dynamic/DynamicControl.cpp
|
||||
playlist/dynamic/GeneratorFactory.cpp
|
||||
playlist/dynamic/GeneratorInterface.cpp
|
||||
playlist/dynamic/DynamicView.cpp
|
||||
playlist/dynamic/DynamicModel.cpp
|
||||
playlist/dynamic/echonest/EchonestGenerator.cpp
|
||||
@@ -156,31 +86,30 @@ set( libSources
|
||||
playlist/dynamic/widgets/CollapsibleControls.cpp
|
||||
playlist/dynamic/widgets/DynamicSetupWidget.cpp
|
||||
playlist/dynamic/widgets/LoadingSpinner.cpp
|
||||
playlist/dynamic/database/DatabaseControl.cpp
|
||||
playlist/dynamic/database/DatabaseGenerator.cpp
|
||||
|
||||
network/bufferiodevice.cpp
|
||||
network/msgprocessor.cpp
|
||||
network/streamconnection.cpp
|
||||
network/dbsyncconnection.cpp
|
||||
network/remotecollection.cpp
|
||||
network/portfwdthread.cpp
|
||||
network/servent.cpp
|
||||
network/connection.cpp
|
||||
network/controlconnection.cpp
|
||||
playlist/topbar/topbar.cpp
|
||||
playlist/topbar/clearbutton.cpp
|
||||
playlist/topbar/searchlineedit.cpp
|
||||
playlist/topbar/lineedit.cpp
|
||||
playlist/topbar/searchbutton.cpp
|
||||
|
||||
resolvers/scriptresolver.cpp
|
||||
resolvers/qtscriptresolver.cpp
|
||||
|
||||
sip/SipModel.cpp
|
||||
|
||||
utils/tomahawkutils.cpp
|
||||
utils/logger.cpp
|
||||
utils/proxystyle.cpp
|
||||
utils/widgetdragfilter.cpp
|
||||
utils/xspfloader.cpp
|
||||
utils/xspfgenerator.cpp
|
||||
utils/jspfloader.cpp
|
||||
utils/spotifyparser.cpp
|
||||
utils/itunesparser.cpp
|
||||
utils/rdioparser.cpp
|
||||
utils/shortenedlinkparser.cpp
|
||||
utils/stylehelper.cpp
|
||||
utils/dropjobnotifier.cpp
|
||||
utils/proxystyle.cpp
|
||||
|
||||
widgets/checkdirtree.cpp
|
||||
widgets/querylabel.cpp
|
||||
widgets/imagebutton.cpp
|
||||
widgets/animatedsplitter.cpp
|
||||
@@ -193,19 +122,258 @@ set( libSources
|
||||
widgets/whatshotwidget.cpp
|
||||
widgets/RecentlyPlayedPlaylistsModel.cpp
|
||||
widgets/RecentPlaylistsModel.cpp
|
||||
widgets/OverlayButton.cpp
|
||||
widgets/overlaywidget.cpp
|
||||
widgets/HeaderLabel.cpp
|
||||
widgets/HeaderWidget.cpp
|
||||
widgets/combobox.cpp
|
||||
widgets/ToggleButton.cpp
|
||||
widgets/SocialPlaylistWidget.cpp
|
||||
widgets/infowidgets/sourceinfowidget.cpp
|
||||
widgets/infowidgets/ArtistInfoWidget.cpp
|
||||
widgets/infowidgets/AlbumInfoWidget.cpp
|
||||
widgets/kbreadcrumbselectionmodel.cpp
|
||||
widgets/breadcrumbbar.cpp
|
||||
widgets/breadcrumbbuttonbase.cpp
|
||||
widgets/headerbreadcrumb.cpp
|
||||
widgets/siblingcrumbbutton.cpp
|
||||
widgets/Breadcrumb.cpp
|
||||
widgets/BreadcrumbButton.cpp
|
||||
)
|
||||
|
||||
set( libGuiHeaders
|
||||
contextmenu.h
|
||||
dropjob.h
|
||||
viewpage.h
|
||||
viewmanager.h
|
||||
globalactionmanager.h
|
||||
|
||||
context/ContextPage.h
|
||||
context/ContextWidget.h
|
||||
context/pages/TopTracksContext.h
|
||||
context/pages/RelatedArtistsContext.h
|
||||
context/pages/WikipediaContext.h
|
||||
context/pages/WebContext.h
|
||||
|
||||
infobar/infobar.h
|
||||
|
||||
infosystem/infoplugins/generic/echonestplugin.h
|
||||
infosystem/infoplugins/generic/lastfmplugin.h
|
||||
infosystem/infoplugins/generic/chartsplugin.h
|
||||
infosystem/infoplugins/generic/spotifyPlugin.h
|
||||
infosystem/infoplugins/generic/hypemPlugin.h
|
||||
infosystem/infoplugins/generic/musixmatchplugin.h
|
||||
infosystem/infoplugins/generic/musicbrainzPlugin.h
|
||||
infosystem/infoplugins/generic/RoviPlugin.h
|
||||
|
||||
playlist/topbar/topbar.h
|
||||
playlist/topbar/clearbutton.h
|
||||
playlist/topbar/searchlineedit.h
|
||||
playlist/topbar/lineedit.h
|
||||
playlist/topbar/lineedit_p.h
|
||||
playlist/topbar/searchbutton.h
|
||||
|
||||
playlist/treemodel.h
|
||||
playlist/treeproxymodel.h
|
||||
playlist/treeheader.h
|
||||
playlist/treeitemdelegate.h
|
||||
playlist/collectionproxymodel.h
|
||||
playlist/collectionflatmodel.h
|
||||
playlist/collectionview.h
|
||||
playlist/playlistmodel.h
|
||||
playlist/playlistproxymodel.h
|
||||
playlist/playlistview.h
|
||||
playlist/playlistitemdelegate.h
|
||||
playlist/queueproxymodel.h
|
||||
playlist/queueview.h
|
||||
playlist/trackmodel.h
|
||||
playlist/trackmodelitem.h
|
||||
playlist/trackproxymodel.h
|
||||
playlist/trackview.h
|
||||
playlist/trackheader.h
|
||||
playlist/treemodelitem.h
|
||||
playlist/albumitem.h
|
||||
playlist/albummodel.h
|
||||
playlist/albumproxymodel.h
|
||||
playlist/albumitemdelegate.h
|
||||
playlist/albumview.h
|
||||
playlist/artistview.h
|
||||
playlist/customplaylistview.h
|
||||
playlist/ViewHeader.h
|
||||
|
||||
playlist/dynamic/DynamicPlaylist.h
|
||||
playlist/dynamic/GeneratorInterface.h
|
||||
playlist/dynamic/DynamicView.h
|
||||
playlist/dynamic/DynamicModel.h
|
||||
playlist/dynamic/echonest/EchonestGenerator.h
|
||||
playlist/dynamic/echonest/EchonestControl.h
|
||||
playlist/dynamic/echonest/EchonestSteerer.h
|
||||
playlist/dynamic/widgets/DynamicWidget.h
|
||||
playlist/dynamic/widgets/DynamicControlWrapper.h
|
||||
playlist/dynamic/widgets/DynamicControlList.h
|
||||
playlist/dynamic/widgets/ReadOrWriteWidget.h
|
||||
playlist/dynamic/widgets/MiscControlWidgets.h
|
||||
playlist/dynamic/widgets/CollapsibleControls.h
|
||||
playlist/dynamic/widgets/DynamicSetupWidget.h
|
||||
playlist/dynamic/widgets/LoadingSpinner.h
|
||||
|
||||
resolvers/scriptresolver.h
|
||||
resolvers/qtscriptresolver.h
|
||||
|
||||
sip/SipModel.h
|
||||
|
||||
utils/widgetdragfilter.h
|
||||
utils/xspfgenerator.h
|
||||
utils/jspfloader.h
|
||||
utils/spotifyparser.h
|
||||
utils/itunesparser.h
|
||||
utils/rdioparser.h
|
||||
utils/shortenedlinkparser.h
|
||||
utils/dropjobnotifier.h
|
||||
|
||||
widgets/checkdirtree.h
|
||||
widgets/querylabel.h
|
||||
widgets/animatedcounterlabel.h
|
||||
widgets/imagebutton.h
|
||||
widgets/animatedsplitter.h
|
||||
widgets/elidedlabel.h
|
||||
widgets/newplaylistwidget.h
|
||||
widgets/searchwidget.h
|
||||
widgets/SeekSlider.h
|
||||
widgets/playlisttypeselectordlg.h
|
||||
widgets/welcomewidget.h
|
||||
widgets/whatshotwidget.h
|
||||
widgets/RecentlyPlayedPlaylistsModel.h
|
||||
widgets/RecentPlaylistsModel.h
|
||||
widgets/OverlayButton.h
|
||||
widgets/overlaywidget.h
|
||||
widgets/HeaderLabel.h
|
||||
widgets/HeaderWidget.h
|
||||
widgets/combobox.h
|
||||
widgets/ToggleButton.h
|
||||
widgets/SocialPlaylistWidget.h
|
||||
widgets/infowidgets/sourceinfowidget.h
|
||||
widgets/infowidgets/ArtistInfoWidget.h
|
||||
widgets/infowidgets/ArtistInfoWidget_p.h
|
||||
widgets/infowidgets/AlbumInfoWidget.h
|
||||
widgets/Breadcrumb.h
|
||||
widgets/BreadcrumbButton.h
|
||||
|
||||
jobview/JobStatusView.h
|
||||
jobview/JobStatusModel.h
|
||||
jobview/JobStatusDelegate.h
|
||||
jobview/JobStatusItem.h
|
||||
jobview/PipelineStatusItem.h
|
||||
jobview/TransferStatusItem.h
|
||||
jobview/LatchedStatusItem.h
|
||||
|
||||
thirdparty/Qocoa/qsearchfield.h
|
||||
|
||||
)
|
||||
|
||||
set( libSources
|
||||
tomahawksettings.cpp
|
||||
sourcelist.cpp
|
||||
pipeline.cpp
|
||||
|
||||
aclsystem.cpp
|
||||
actioncollection.cpp
|
||||
artist.cpp
|
||||
album.cpp
|
||||
collection.cpp
|
||||
playlist.cpp
|
||||
resolver.cpp
|
||||
query.cpp
|
||||
result.cpp
|
||||
source.cpp
|
||||
sourceplaylistinterface.cpp
|
||||
playlistinterface.cpp
|
||||
LatchManager.cpp
|
||||
|
||||
EchonestCatalogSynchronizer.cpp
|
||||
|
||||
sip/SipPlugin.cpp
|
||||
sip/SipHandler.cpp
|
||||
sip/sipinfo.cpp
|
||||
|
||||
audio/audioengine.cpp
|
||||
audio/audioenginethread.cpp
|
||||
|
||||
database/database.cpp
|
||||
database/fuzzyindex.cpp
|
||||
database/databasecollection.cpp
|
||||
database/localcollection.cpp
|
||||
database/databaseworker.cpp
|
||||
database/databaseimpl.cpp
|
||||
database/databaseresolver.cpp
|
||||
database/databasecommand.cpp
|
||||
database/databasecommandloggable.cpp
|
||||
database/databasecommand_resolve.cpp
|
||||
database/databasecommand_allartists.cpp
|
||||
database/databasecommand_allalbums.cpp
|
||||
database/databasecommand_alltracks.cpp
|
||||
database/databasecommand_addfiles.cpp
|
||||
database/databasecommand_deletefiles.cpp
|
||||
database/databasecommand_dirmtimes.cpp
|
||||
database/databasecommand_filemtimes.cpp
|
||||
database/databasecommand_loadfiles.cpp
|
||||
database/databasecommand_logplayback.cpp
|
||||
database/databasecommand_addsource.cpp
|
||||
database/databasecommand_sourceoffline.cpp
|
||||
database/databasecommand_collectionstats.cpp
|
||||
database/databasecommand_loadplaylistentries.cpp
|
||||
database/databasecommand_modifyplaylist.cpp
|
||||
database/databasecommand_playbackhistory.cpp
|
||||
database/databasecommand_setplaylistrevision.cpp
|
||||
database/databasecommand_loadallplaylists.cpp
|
||||
database/databasecommand_loadallsortedplaylists.cpp
|
||||
database/databasecommand_loadallsources.cpp
|
||||
database/databasecommand_createplaylist.cpp
|
||||
database/databasecommand_deleteplaylist.cpp
|
||||
database/databasecommand_renameplaylist.cpp
|
||||
database/databasecommand_loadops.cpp
|
||||
database/databasecommand_updatesearchindex.cpp
|
||||
database/databasecommand_setdynamicplaylistrevision.cpp
|
||||
database/databasecommand_createdynamicplaylist.cpp
|
||||
database/databasecommand_loaddynamicplaylist.cpp
|
||||
database/databasecommand_loaddynamicplaylistentries.cpp
|
||||
database/databasecommand_loadallautoplaylists.cpp
|
||||
database/databasecommand_loadallstations.cpp
|
||||
database/databasecommand_deletedynamicplaylist.cpp
|
||||
database/databasecommand_addclientauth.cpp
|
||||
database/databasecommand_clientauthvalid.cpp
|
||||
database/databasecommand_socialaction.cpp
|
||||
database/databasecommand_loadsocialactions.cpp
|
||||
database/databasecommand_genericselect.cpp
|
||||
database/databasecommand_setcollectionattributes.cpp
|
||||
database/databasecommand_collectionattributes.cpp
|
||||
database/databasecommand_trackattributes.cpp
|
||||
database/databasecommand_settrackattributes.cpp
|
||||
database/database.cpp
|
||||
|
||||
infosystem/infosystem.cpp
|
||||
infosystem/infosystemcache.cpp
|
||||
infosystem/infosystemworker.cpp
|
||||
|
||||
network/bufferiodevice.cpp
|
||||
network/msgprocessor.cpp
|
||||
network/streamconnection.cpp
|
||||
network/dbsyncconnection.cpp
|
||||
network/remotecollection.cpp
|
||||
network/portfwdthread.cpp
|
||||
network/servent.cpp
|
||||
network/connection.cpp
|
||||
network/controlconnection.cpp
|
||||
|
||||
playlist/PlaylistUpdaterInterface.cpp
|
||||
playlist/dynamic/DynamicPlaylist.cpp
|
||||
playlist/dynamic/GeneratorFactory.cpp
|
||||
playlist/dynamic/GeneratorInterface.cpp
|
||||
playlist/dynamic/DynamicPlaylistRevision.cpp
|
||||
playlist/XspfUpdater.cpp
|
||||
playlist/dynamic/database/DatabaseGenerator.cpp
|
||||
playlist/dynamic/database/DatabaseControl.cpp
|
||||
playlist/dynamic/DynamicControl.cpp
|
||||
|
||||
utils/tomahawkutils.cpp
|
||||
utils/logger.cpp
|
||||
utils/qnr_iodevicestream.cpp
|
||||
utils/xspfloader.cpp
|
||||
|
||||
thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp
|
||||
thirdparty/kdsingleapplicationguard/kdsharedmemorylocker.cpp
|
||||
@@ -220,34 +388,27 @@ set( libHeaders
|
||||
functimeout.h
|
||||
|
||||
aclsystem.h
|
||||
actioncollection.h
|
||||
collection.h
|
||||
query.h
|
||||
resolver.h
|
||||
result.h
|
||||
source.h
|
||||
sourceplaylistinterface.h
|
||||
viewmanager.h
|
||||
globalactionmanager.h
|
||||
contextmenu.h
|
||||
dropjob.h
|
||||
LatchManager.h
|
||||
|
||||
artist.h
|
||||
album.h
|
||||
playlist.h
|
||||
|
||||
EchonestCatalogSynchronizer.h
|
||||
|
||||
sip/SipPlugin.h
|
||||
sip/SipHandler.h
|
||||
sip/SipModel.h
|
||||
sip/sipinfo.h
|
||||
|
||||
audio/audioengine.h
|
||||
|
||||
context/ContextPage.h
|
||||
context/ContextWidget.h
|
||||
context/pages/TopTracksContext.h
|
||||
context/pages/RelatedArtistsContext.h
|
||||
context/pages/WikipediaContext.h
|
||||
context/pages/WebContext.h
|
||||
audio/audioenginethread.h
|
||||
|
||||
database/database.h
|
||||
database/fuzzyindex.h
|
||||
@@ -264,7 +425,7 @@ set( libHeaders
|
||||
database/databasecommand_deletefiles.h
|
||||
database/databasecommand_dirmtimes.h
|
||||
database/databasecommand_filemtimes.h
|
||||
database/databasecommand_loadfile.h
|
||||
database/databasecommand_loadfiles.h
|
||||
database/databasecommand_logplayback.h
|
||||
database/databasecommand_addsource.h
|
||||
database/databasecommand_sourceoffline.h
|
||||
@@ -295,16 +456,15 @@ set( libHeaders
|
||||
database/databasecommand_socialaction.h
|
||||
database/databasecommand_loadsocialactions.h
|
||||
database/databasecommand_genericselect.h
|
||||
database/databasecommand_setcollectionattributes.h
|
||||
database/databasecommand_collectionattributes.h
|
||||
database/databasecommand_trackattributes.h
|
||||
database/databasecommand_settrackattributes.h
|
||||
|
||||
infobar/infobar.h
|
||||
|
||||
infosystem/infosystem.h
|
||||
infosystem/infosystem.h
|
||||
infosystem/infosystemworker.h
|
||||
infosystem/infosystemcache.h
|
||||
infosystem/infoplugins/generic/echonestplugin.h
|
||||
infosystem/infoplugins/generic/lastfmplugin.h
|
||||
infosystem/infoplugins/generic/musixmatchplugin.h
|
||||
infosystem/infoplugins/generic/musicbrainzPlugin.h
|
||||
|
||||
network/bufferiodevice.h
|
||||
network/msgprocessor.h
|
||||
@@ -316,109 +476,24 @@ set( libHeaders
|
||||
network/controlconnection.h
|
||||
network/portfwdthread.h
|
||||
|
||||
playlist/treemodel.h
|
||||
playlist/treeproxymodel.h
|
||||
playlist/treeheader.h
|
||||
playlist/treeitemdelegate.h
|
||||
playlist/collectionproxymodel.h
|
||||
playlist/collectionflatmodel.h
|
||||
playlist/collectionview.h
|
||||
playlist/playlistmodel.h
|
||||
playlist/playlistproxymodel.h
|
||||
playlist/playlistview.h
|
||||
playlist/playlistitemdelegate.h
|
||||
playlist/queueproxymodel.h
|
||||
playlist/queueview.h
|
||||
playlist/trackmodel.h
|
||||
playlist/trackmodelitem.h
|
||||
playlist/trackproxymodel.h
|
||||
playlist/trackview.h
|
||||
playlist/trackheader.h
|
||||
playlist/treemodelitem.h
|
||||
playlist/albumitem.h
|
||||
playlist/albummodel.h
|
||||
playlist/albumproxymodel.h
|
||||
playlist/albumitemdelegate.h
|
||||
playlist/albumview.h
|
||||
playlist/artistview.h
|
||||
playlist/customplaylistview.h
|
||||
playlist/ViewHeader.h
|
||||
|
||||
playlist/topbar/topbar.h
|
||||
playlist/topbar/clearbutton.h
|
||||
playlist/topbar/searchlineedit.h
|
||||
playlist/topbar/lineedit.h
|
||||
playlist/topbar/lineedit_p.h
|
||||
playlist/topbar/searchbutton.h
|
||||
|
||||
playlist/PlaylistUpdaterInterface.h
|
||||
playlist/dynamic/DynamicPlaylist.h
|
||||
playlist/dynamic/DynamicControl.h
|
||||
playlist/dynamic/GeneratorInterface.h
|
||||
playlist/dynamic/DynamicView.h
|
||||
playlist/dynamic/DynamicModel.h
|
||||
playlist/dynamic/echonest/EchonestGenerator.h
|
||||
playlist/dynamic/echonest/EchonestControl.h
|
||||
playlist/dynamic/echonest/EchonestSteerer.h
|
||||
playlist/dynamic/widgets/DynamicWidget.h
|
||||
playlist/dynamic/widgets/DynamicControlWrapper.h
|
||||
playlist/dynamic/widgets/DynamicControlList.h
|
||||
playlist/dynamic/widgets/ReadOrWriteWidget.h
|
||||
playlist/dynamic/widgets/MiscControlWidgets.h
|
||||
playlist/dynamic/widgets/CollapsibleControls.h
|
||||
playlist/dynamic/widgets/DynamicSetupWidget.h
|
||||
playlist/dynamic/widgets/LoadingSpinner.h
|
||||
playlist/dynamic/database/DatabaseControl.h
|
||||
playlist/dynamic/GeneratorFactory.h
|
||||
playlist/XspfUpdater.h
|
||||
playlist/dynamic/database/DatabaseGenerator.h
|
||||
|
||||
utils/widgetdragfilter.h
|
||||
utils/xspfloader.h
|
||||
utils/xspfgenerator.h
|
||||
utils/jspfloader.h
|
||||
utils/spotifyparser.h
|
||||
utils/rdioparser.h
|
||||
utils/shortenedlinkparser.h
|
||||
utils/stylehelper.h
|
||||
|
||||
widgets/querylabel.h
|
||||
widgets/animatedcounterlabel.h
|
||||
widgets/imagebutton.h
|
||||
widgets/animatedsplitter.h
|
||||
widgets/elidedlabel.h
|
||||
widgets/newplaylistwidget.h
|
||||
widgets/searchwidget.h
|
||||
widgets/SeekSlider.h
|
||||
widgets/playlisttypeselectordlg.h
|
||||
widgets/welcomewidget.h
|
||||
widgets/whatshotwidget.h
|
||||
widgets/RecentlyPlayedPlaylistsModel.h
|
||||
widgets/RecentPlaylistsModel.h
|
||||
widgets/overlaywidget.h
|
||||
widgets/HeaderLabel.h
|
||||
widgets/HeaderWidget.h
|
||||
widgets/combobox.h
|
||||
widgets/SocialPlaylistWidget.h
|
||||
widgets/infowidgets/sourceinfowidget.h
|
||||
widgets/infowidgets/ArtistInfoWidget.h
|
||||
widgets/infowidgets/AlbumInfoWidget.h
|
||||
widgets/kbreadcrumbselectionmodel.h
|
||||
widgets/kbreadcrumbselectionmodel_p.h
|
||||
widgets/breadcrumbbar.h
|
||||
widgets/breadcrumbbuttonbase.h
|
||||
widgets/headerbreadcrumb.h
|
||||
widgets/siblingcrumbbutton.h
|
||||
playlist/dynamic/database/DatabaseControl.h
|
||||
playlist/dynamic/DynamicControl.h
|
||||
|
||||
thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.h
|
||||
thirdparty/Qocoa/qsearchfield.h
|
||||
|
||||
utils/xspfloader.h
|
||||
utils/qnr_iodevicestream.h
|
||||
)
|
||||
|
||||
set( libHeaders_NoMOC
|
||||
viewpage.h
|
||||
|
||||
infosystem/infoplugins/unix/imageconverter.h
|
||||
|
||||
playlist/dynamic/GeneratorInterface.h
|
||||
playlist/dynamic/GeneratorFactory.h
|
||||
|
||||
utils/tomahawkutils.h
|
||||
)
|
||||
|
||||
@@ -445,7 +520,6 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.
|
||||
${LIBECHONEST_INCLUDE_DIR}
|
||||
${LIBECHONEST_INCLUDE_DIR}/..
|
||||
${CLUCENE_INCLUDE_DIR}
|
||||
${CLUCENE_LIBRARY_DIR}
|
||||
${PHONON_INCLUDES}
|
||||
${CMAKE_BINARY_DIR}/thirdparty/liblastfm2/src
|
||||
|
||||
@@ -453,18 +527,28 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.
|
||||
|
||||
${LIBPORTFWD_INCLUDE_DIR}
|
||||
${THIRDPARTY_DIR}/qxt/qxtweb-standalone/qxtweb
|
||||
|
||||
${QuaZip_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
IF(QCA2_FOUND)
|
||||
INCLUDE_DIRECTORIES( ${QCA2_INCLUDE_DIR} )
|
||||
ENDIF(QCA2_FOUND)
|
||||
|
||||
IF(LIBATTICA_FOUND)
|
||||
SET( libGuiSources ${libGuiSources} AtticaManager.cpp )
|
||||
SET( libGuiHeaders ${libGuiHeaders} AtticaManager.h )
|
||||
INCLUDE_DIRECTORIES( ${LIBATTICA_INCLUDE_DIR} )
|
||||
ENDIF(LIBATTICA_FOUND)
|
||||
|
||||
IF( UNIX AND NOT APPLE )
|
||||
SET( libSources ${libSources}
|
||||
SET( libGuiSources ${libGuiSources}
|
||||
infosystem/infoplugins/unix/mprispluginrootadaptor.cpp
|
||||
infosystem/infoplugins/unix/mprispluginplayeradaptor.cpp
|
||||
infosystem/infoplugins/unix/mprisplugin.cpp
|
||||
infosystem/infoplugins/unix/fdonotifyplugin.cpp
|
||||
infosystem/infoplugins/unix/imageconverter.cpp )
|
||||
|
||||
SET( libHeaders ${libHeaders}
|
||||
SET( libGuiHeaders ${libGuiHeaders}
|
||||
infosystem/infoplugins/unix/mprispluginrootadaptor.h
|
||||
infosystem/infoplugins/unix/mprispluginplayeradaptor.h
|
||||
infosystem/infoplugins/unix/mprisplugin.h
|
||||
@@ -518,21 +602,34 @@ IF( APPLE )
|
||||
/System/Library/Frameworks/AppKit.framework
|
||||
)
|
||||
ELSE( APPLE )
|
||||
SET( libSources ${libSources} thirdparty/Qocoa/qsearchfield.cpp )
|
||||
SET( libGuiSources ${libGuiSources} thirdparty/Qocoa/qsearchfield.cpp )
|
||||
ENDIF( APPLE )
|
||||
|
||||
IF(LIBLASTFM_FOUND)
|
||||
SET(LINK_LIBRARIES ${LINK_LIBRARIES} tomahawk_lastfm2 )
|
||||
ENDIF(LIBLASTFM_FOUND)
|
||||
|
||||
IF(BUILD_GUI)
|
||||
LIST(APPEND libSources ${libGuiSources} )
|
||||
LIST(APPEND libHeaders ${libGuiHeaders} )
|
||||
ENDIF()
|
||||
|
||||
qt4_wrap_ui( libUI_H ${libUI} )
|
||||
qt4_wrap_cpp( libMoc ${libHeaders} )
|
||||
|
||||
SET( libSources ${libSources} ${libUI_H} ${libHeaders_NoMOC} )
|
||||
|
||||
add_library( tomahawklib SHARED ${libSources} ${libMoc} )
|
||||
ADD_LIBRARY( tomahawklib SHARED ${libSources} ${libMoc} )
|
||||
|
||||
target_link_libraries( tomahawklib
|
||||
IF(QCA2_FOUND)
|
||||
SET(LINK_LIBRARIES ${LINK_LIBRARIES} ${QCA2_LIBRARIES} )
|
||||
ENDIF(QCA2_FOUND)
|
||||
|
||||
IF(LIBATTICA_FOUND)
|
||||
SET( LINK_LIBRARIES ${LINK_LIBRARIES} ${LIBATTICA_LIBRARIES} ${QuaZip_LIBRARIES} )
|
||||
ENDIF(LIBATTICA_FOUND)
|
||||
|
||||
TARGET_LINK_LIBRARIES( tomahawklib
|
||||
# Thirdparty shipped with tomahawk
|
||||
${LIBPORTFWD_LIBRARIES}
|
||||
|
||||
|
366
src/libtomahawk/EchonestCatalogSynchronizer.cpp
Normal file
@@ -0,0 +1,366 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EchonestCatalogSynchronizer.h"
|
||||
|
||||
#include "collection.h"
|
||||
#include "database/database.h"
|
||||
#include "database/databasecommand_genericselect.h"
|
||||
#include "database/databasecommand_setcollectionattributes.h"
|
||||
#include "database/databasecommand_loadfiles.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "sourcelist.h"
|
||||
#include "query.h"
|
||||
|
||||
#include <echonest/CatalogUpdateEntry.h>
|
||||
#include <echonest/Config.h>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
EchonestCatalogSynchronizer* EchonestCatalogSynchronizer::s_instance = 0;
|
||||
|
||||
EchonestCatalogSynchronizer::EchonestCatalogSynchronizer( QObject *parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
m_syncing = TomahawkSettings::instance()->enableEchonestCatalogs();
|
||||
|
||||
qRegisterMetaType<QList<QStringList> >("QList<QStringList>");
|
||||
|
||||
connect( TomahawkSettings::instance(), SIGNAL( changed() ), this, SLOT( checkSettingsChanged() ) );
|
||||
connect( SourceList::instance()->getLocal()->collection().data(), SIGNAL( tracksAdded( QList<unsigned int> ) ), this, SLOT( tracksAdded( QList<unsigned int> ) ), Qt::QueuedConnection );
|
||||
connect( SourceList::instance()->getLocal()->collection().data(), SIGNAL( tracksRemoved( QList<unsigned int> ) ), this, SLOT( tracksRemoved( QList<unsigned int> ) ), Qt::QueuedConnection );
|
||||
|
||||
const QByteArray artist = TomahawkSettings::instance()->value( "collection/artistCatalog" ).toByteArray();
|
||||
const QByteArray song = TomahawkSettings::instance()->value( "collection/songCatalog" ).toByteArray();
|
||||
|
||||
if ( !artist.isEmpty() )
|
||||
m_artistCatalog.setId( artist );
|
||||
if ( !song.isEmpty() )
|
||||
m_songCatalog.setId( song );
|
||||
|
||||
// Sanity check
|
||||
if ( !song.isEmpty() && !m_syncing )
|
||||
{
|
||||
// Not syncing but have a catalog id... lets fix this
|
||||
QNetworkReply* r = m_songCatalog.deleteCatalog();
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( catalogDeleted() ) );
|
||||
r->setProperty( "type", "song" );
|
||||
}
|
||||
if ( !artist.isEmpty() && !m_syncing )
|
||||
{
|
||||
QNetworkReply* r = m_artistCatalog.deleteCatalog();
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( catalogDeleted() ) );
|
||||
r->setProperty( "type", "artist" );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::checkSettingsChanged()
|
||||
{
|
||||
if ( TomahawkSettings::instance()->enableEchonestCatalogs() && !m_syncing )
|
||||
{
|
||||
// enable, and upload whole db
|
||||
m_syncing = true;
|
||||
|
||||
tDebug() << "Echonest Catalog sync pref changed, uploading!!";
|
||||
uploadDb();
|
||||
} else if ( !TomahawkSettings::instance()->enableEchonestCatalogs() && m_syncing )
|
||||
{
|
||||
|
||||
tDebug() << "Found echonest change, doing catalog deletes!";
|
||||
// delete all track nums and catalog ids from our peers
|
||||
{
|
||||
DatabaseCommand_SetTrackAttributes* cmd = new DatabaseCommand_SetTrackAttributes( DatabaseCommand_SetTrackAttributes::EchonestCatalogId );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
{
|
||||
DatabaseCommand_SetCollectionAttributes* cmd = new DatabaseCommand_SetCollectionAttributes( DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog, true );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
|
||||
if ( !m_songCatalog.id().isEmpty() )
|
||||
{
|
||||
QNetworkReply* r = m_songCatalog.deleteCatalog();
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( catalogDeleted() ) );
|
||||
r->setProperty( "type", "song" );
|
||||
}
|
||||
if ( !m_artistCatalog.id().isEmpty() )
|
||||
{
|
||||
QNetworkReply* r = m_artistCatalog.deleteCatalog();
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( catalogDeleted() ) );
|
||||
r->setProperty( "type", "artist" );
|
||||
}
|
||||
m_syncing = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::catalogDeleted()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
QString toDel = QString( "collection/%1Catalog" ).arg( r->property( "type" ).toString() );
|
||||
|
||||
try
|
||||
{
|
||||
// HACK libechonest bug, should be a static method but it's not. Doesn't actually use any instance vars though
|
||||
m_songCatalog.parseDelete( r );
|
||||
// If we didn't throw, no errors, so clear our config
|
||||
TomahawkSettings::instance()->setValue( toDel, QString() );
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
tLog() << "Error in libechonest parsing catalog delete:" << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::uploadDb()
|
||||
{
|
||||
// create two catalogs: uuid_song, and uuid_artist.
|
||||
QNetworkReply* r = Echonest::Catalog::create( QString( "%1_song" ).arg( Database::instance()->dbid() ), Echonest::CatalogTypes::Song );
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( songCreateFinished() ) );
|
||||
|
||||
// r = Echonest::Catalog::create( QString( "%1_artist" ).arg( Database::instance()->dbid() ), Echonest::CatalogTypes::Artist );
|
||||
// connect( r, SIGNAL( finished() ), this, SLOT( artistCreateFinished() ) );
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::songCreateFinished()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
tDebug() << "Finished creating song catalog, updating data now!!";
|
||||
try
|
||||
{
|
||||
m_songCatalog = Echonest::Catalog::parseCreate( r );
|
||||
TomahawkSettings::instance()->setValue( "collection/songCatalog", m_songCatalog.id() );
|
||||
QSharedPointer< DatabaseCommand > cmd( new DatabaseCommand_SetCollectionAttributes( DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog,
|
||||
m_songCatalog.id() ) );
|
||||
Database::instance()->enqueue( cmd );
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
tLog() << "Echonest threw an exception parsing song catalog create:" << e.what();
|
||||
return;
|
||||
}
|
||||
|
||||
QString sql( "SELECT file.id, track.name, artist.name, album.name "
|
||||
"FROM file, artist, track, file_join "
|
||||
"LEFT OUTER JOIN album "
|
||||
"ON file_join.album = album.id "
|
||||
"WHERE file.id = file_join.file "
|
||||
"AND file_join.artist = artist.id "
|
||||
"AND file_join.track = track.id "
|
||||
"AND file.source IS NULL");
|
||||
DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( sql, DatabaseCommand_GenericSelect::Track, true );
|
||||
connect( cmd, SIGNAL( rawData( QList< QStringList > ) ), this, SLOT( rawTracksAdd( QList< QStringList > ) ) );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::artistCreateFinished()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
// We don't support artist catalogs at the moment
|
||||
return;
|
||||
/*
|
||||
try
|
||||
{
|
||||
m_artistCatalog = Echonest::Catalog::parseCreate( r );
|
||||
TomahawkSettings::instance()->setValue( "collection/artistCatalog", m_artistCatalog.id() );
|
||||
|
||||
// QSharedPointer< DatabaseCommand > cmd( new DatabaseCommand_SetCollectionAttributes( SourceList::instance()->getLocal(),
|
||||
// DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog,
|
||||
// m_songCatalog.id() ) );
|
||||
// Database::instance()->enqueue( cmd );
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
tLog() << "Echonest threw an exception parsing artist catalog create:" << e.what();
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::rawTracksAdd( const QList< QStringList >& tracks )
|
||||
{
|
||||
tDebug() << "Got raw tracks, num:" << tracks.size();
|
||||
|
||||
// int limit = ( tracks.size() < 1000 ) ? tracks.size() : 1000;
|
||||
|
||||
int cur = 0;
|
||||
while ( cur < tracks.size() )
|
||||
{
|
||||
int prev = cur;
|
||||
cur = ( cur + 2000 > tracks.size() ) ? tracks.size() : cur + 2000;
|
||||
|
||||
tDebug() << "Enqueueing a batch of tracks to upload to echonest catalog:" << cur - prev;
|
||||
Echonest::CatalogUpdateEntries entries;
|
||||
for ( int i = prev; i < cur; i++ )
|
||||
{
|
||||
if ( tracks[i][1].isEmpty() || tracks[i][2].isEmpty() )
|
||||
continue;
|
||||
entries.append( entryFromTrack( tracks[i], Echonest::CatalogTypes::Update ) );
|
||||
}
|
||||
tDebug() << "Done queuing:" << entries.size() << "tracks";
|
||||
m_queuedUpdates.enqueue( entries );
|
||||
}
|
||||
|
||||
doUploadJob();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::doUploadJob()
|
||||
{
|
||||
if ( m_queuedUpdates.isEmpty() )
|
||||
return;
|
||||
|
||||
Echonest::CatalogUpdateEntries entries = m_queuedUpdates.dequeue();
|
||||
tDebug() << "Updating number of entries:" << entries.count();
|
||||
|
||||
QNetworkReply* updateJob = m_songCatalog.update( entries );
|
||||
connect( updateJob, SIGNAL( finished() ), this, SLOT( songUpdateFinished() ) );
|
||||
}
|
||||
|
||||
|
||||
Echonest::CatalogUpdateEntry
|
||||
EchonestCatalogSynchronizer::entryFromTrack( const QStringList& track, Echonest::CatalogTypes::Action action ) const
|
||||
{
|
||||
//qDebug() << "UPLOADING:" << track[0] << track[1] << track[2];
|
||||
Echonest::CatalogUpdateEntry entry;
|
||||
entry.setAction( action );
|
||||
entry.setItemId(track[ 0 ].toLatin1() ); // track dbid
|
||||
entry.setSongName( escape( track[ 1 ] ) );
|
||||
entry.setArtistName( escape( track[ 2 ] ) );
|
||||
entry.setRelease( escape( track[ 3 ] ) );
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::songUpdateFinished()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
try
|
||||
{
|
||||
QByteArray ticket = m_songCatalog.parseTicket( r );
|
||||
QNetworkReply* tJob = m_songCatalog.status( ticket );
|
||||
connect( tJob, SIGNAL( finished() ), this, SLOT( checkTicket() ) );
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
tLog() << "Echonest threw an exception parsing catalog update finished:" << e.what();
|
||||
}
|
||||
|
||||
doUploadJob();
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::checkTicket()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
try
|
||||
{
|
||||
Echonest::CatalogStatus status = m_songCatalog.parseStatus( r );
|
||||
|
||||
tLog() << "Catalog status update:" << status.status << status.details << status.items;
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
tLog() << "Echonest threw an exception parsing catalog create:" << e.what();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::tracksAdded( const QList< unsigned int >& tracks )
|
||||
{
|
||||
if ( !m_syncing || m_songCatalog.id().isEmpty() || tracks.isEmpty() )
|
||||
return;
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Got tracks added from db, fetching metadata" << tracks;
|
||||
// Get the result_ptrs from the tracks
|
||||
DatabaseCommand_LoadFiles* cmd = new DatabaseCommand_LoadFiles( tracks );
|
||||
connect( cmd, SIGNAL( results( QList<Tomahawk::result_ptr> ) ), this, SLOT( loadedResults( QList<Tomahawk::result_ptr> ) ) );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::loadedResults( const QList<result_ptr>& results )
|
||||
{
|
||||
QList< QStringList > rawTracks;
|
||||
qDebug() << Q_FUNC_INFO << "Got track metadata..." << results.size();
|
||||
|
||||
foreach( const result_ptr& result, results )
|
||||
{
|
||||
if ( result.isNull() )
|
||||
continue;
|
||||
|
||||
qDebug() << "Metadata for item:" << result->fileId();
|
||||
|
||||
const QString artist = result->artist().isNull() ? QString() : result->artist()->name();
|
||||
const QString album = result->album().isNull() ? QString() : result->album()->name();
|
||||
rawTracks << ( QStringList() << QString::number( result->fileId() ) << result->track() << artist << album );
|
||||
}
|
||||
rawTracksAdd( rawTracks );
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::tracksRemoved( const QList< unsigned int >& trackIds )
|
||||
{
|
||||
|
||||
if ( !m_syncing || m_songCatalog.id().isEmpty() || trackIds.isEmpty() )
|
||||
return;
|
||||
|
||||
|
||||
Echonest::CatalogUpdateEntries entries;
|
||||
entries.reserve( trackIds.size() );
|
||||
|
||||
foreach ( unsigned int id, trackIds )
|
||||
{
|
||||
tDebug() << "Deleting item with id:" << id;
|
||||
Echonest::CatalogUpdateEntry e( Echonest::CatalogTypes::Delete );
|
||||
e.setItemId( QString::number( id ).toLatin1() );
|
||||
entries.append( e );
|
||||
}
|
||||
|
||||
QNetworkReply* reply = m_songCatalog.update( entries );
|
||||
connect( reply, SIGNAL( finished() ), this, SLOT( songUpdateFinished() ) );
|
||||
}
|
||||
|
||||
QByteArray
|
||||
EchonestCatalogSynchronizer::escape( const QString &in ) const
|
||||
{
|
||||
// TODO echonest chokes on some chars in the output. But if we percent-encode those chars it works
|
||||
// We can't percent-encode the whole string, because then any UTF-8 chars that have been url-encoded, fail.
|
||||
// God this sucks. It's going to break...
|
||||
QString clean = in;
|
||||
clean.replace( "&", "%25" );
|
||||
clean.replace( ";", "%3B" );
|
||||
return clean.toUtf8();
|
||||
//return QUrl::toPercentEncoding( in. );
|
||||
}
|
91
src/libtomahawk/EchonestCatalogSynchronizer.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECHONESTCATALOGSYNCHRONIZER_H
|
||||
#define ECHONESTCATALOGSYNCHRONIZER_H
|
||||
|
||||
#include "dllmacro.h"
|
||||
#include "query.h"
|
||||
#include "database/databasecommand_trackattributes.h"
|
||||
|
||||
#include <echonest/Catalog.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QQueue>
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class DLLEXPORT EchonestCatalogSynchronizer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static EchonestCatalogSynchronizer* instance() {
|
||||
if ( !s_instance )
|
||||
{
|
||||
s_instance = new EchonestCatalogSynchronizer;
|
||||
}
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
explicit EchonestCatalogSynchronizer(QObject *parent = 0);
|
||||
|
||||
Echonest::Catalog songCatalog() const { return m_songCatalog; }
|
||||
Echonest::Catalog artistCatalog() const { return m_artistCatalog; }
|
||||
|
||||
signals:
|
||||
void knownCatalogsChanged();
|
||||
|
||||
private slots:
|
||||
void checkSettingsChanged();
|
||||
void tracksAdded( const QList<unsigned int>& );
|
||||
void tracksRemoved( const QList<unsigned int>& );
|
||||
|
||||
void loadedResults( const QList<Tomahawk::result_ptr>& results );
|
||||
|
||||
// Echonest slots
|
||||
void songCreateFinished();
|
||||
void artistCreateFinished();
|
||||
void songUpdateFinished();
|
||||
void catalogDeleted();
|
||||
|
||||
void checkTicket();
|
||||
|
||||
void rawTracksAdd( const QList< QStringList >& tracks );
|
||||
private:
|
||||
void uploadDb();
|
||||
QByteArray escape( const QString& in ) const;
|
||||
|
||||
Echonest::CatalogUpdateEntry entryFromTrack( const QStringList&, Echonest::CatalogTypes::Action action ) const;
|
||||
void doUploadJob();
|
||||
|
||||
bool m_syncing;
|
||||
|
||||
Echonest::Catalog m_songCatalog;
|
||||
Echonest::Catalog m_artistCatalog;
|
||||
|
||||
QQueue< Echonest::CatalogUpdateEntries > m_queuedUpdates;
|
||||
|
||||
static EchonestCatalogSynchronizer* s_instance;
|
||||
|
||||
friend class ::DatabaseCommand_SetCollectionAttributes;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // ECHONESTCATALOGSYNCHRONIZER_H
|
139
src/libtomahawk/LatchManager.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "LatchManager.h"
|
||||
|
||||
#include "actioncollection.h"
|
||||
#include "audio/audioengine.h"
|
||||
#include "database/database.h"
|
||||
|
||||
#include <QtCore/QStateMachine>
|
||||
#include <QtCore/QState>
|
||||
#include "sourcelist.h"
|
||||
#include "database/databasecommand_socialaction.h"
|
||||
#include "sourceplaylistinterface.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
LatchManager::LatchManager( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_state( NotLatched )
|
||||
{
|
||||
connect( AudioEngine::instance(), SIGNAL( playlistChanged( Tomahawk::PlaylistInterface* ) ), this, SLOT( playlistChanged( Tomahawk::PlaylistInterface* ) ) );
|
||||
}
|
||||
|
||||
LatchManager::~LatchManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
LatchManager::isLatched( const source_ptr& src )
|
||||
{
|
||||
return m_state == Latched && m_latchedOnTo == src;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LatchManager::latchRequest( const source_ptr& source )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( isLatched( source ) )
|
||||
return;
|
||||
|
||||
m_state = Latching;
|
||||
m_waitingForLatch = source;
|
||||
AudioEngine::instance()->playItem( source->getPlaylistInterface().data(), source->getPlaylistInterface()->nextItem() );
|
||||
}
|
||||
|
||||
void
|
||||
LatchManager::playlistChanged( PlaylistInterface* )
|
||||
{
|
||||
// If we were latched on and changed, send the listening along stop
|
||||
if ( m_latchedOnTo.isNull() )
|
||||
{
|
||||
if ( m_waitingForLatch.isNull() )
|
||||
return; // Neither latched on nor waiting to be latched on, no-op
|
||||
|
||||
m_latchedOnTo = m_waitingForLatch;
|
||||
m_latchedInterface = m_waitingForLatch->getPlaylistInterface();
|
||||
m_waitingForLatch.clear();
|
||||
m_state = Latched;
|
||||
|
||||
DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction();
|
||||
cmd->setSource( SourceList::instance()->getLocal() );
|
||||
cmd->setAction( "latchOn");
|
||||
cmd->setComment( m_latchedOnTo->userName() );
|
||||
cmd->setTimestamp( QDateTime::currentDateTime().toTime_t() );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
|
||||
ActionCollection::instance()->getAction( "latchOn" )->setText( tr( "&Catch Up" ) );
|
||||
|
||||
// If not, then keep waiting
|
||||
return;
|
||||
}
|
||||
|
||||
// We're current latched, and the user changed playlist, so stop
|
||||
SourcePlaylistInterface* origsourcepi = dynamic_cast< SourcePlaylistInterface* >( m_latchedInterface.data() );
|
||||
Q_ASSERT( origsourcepi );
|
||||
const source_ptr source = origsourcepi->source();
|
||||
|
||||
DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction();
|
||||
cmd->setSource( SourceList::instance()->getLocal() );
|
||||
cmd->setAction( "latchOff");
|
||||
cmd->setComment( source->userName() );
|
||||
cmd->setTimestamp( QDateTime::currentDateTime().toTime_t() );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
|
||||
if ( !m_waitingForLatch.isNull() &&
|
||||
m_waitingForLatch != m_latchedOnTo )
|
||||
{
|
||||
// We are asked to latch on immediately to another source
|
||||
m_latchedOnTo.clear();
|
||||
m_latchedInterface.clear();
|
||||
|
||||
// call ourselves to hit the "create latch" condition
|
||||
playlistChanged( 0 );
|
||||
return;
|
||||
}
|
||||
m_latchedOnTo.clear();
|
||||
m_waitingForLatch.clear();
|
||||
m_latchedInterface.clear();
|
||||
|
||||
m_state = NotLatched;
|
||||
|
||||
ActionCollection::instance()->getAction( "latchOn" )->setText( tr( "&Listen Along" ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LatchManager::catchUpRequest()
|
||||
{
|
||||
//it's a catch-up -- logic in audioengine should take care of it
|
||||
AudioEngine::instance()->next();
|
||||
}
|
||||
|
||||
void
|
||||
LatchManager::unlatchRequest( const source_ptr& source )
|
||||
{
|
||||
Q_UNUSED( source );
|
||||
AudioEngine::instance()->stop();
|
||||
AudioEngine::instance()->setPlaylist( 0 );
|
||||
|
||||
ActionCollection::instance()->getAction( "latchOn" )->setText( tr( "&Listen Along" ) );
|
||||
}
|
65
src/libtomahawk/LatchManager.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LATCHMANAGER_H
|
||||
#define LATCHMANAGER_H
|
||||
|
||||
#include "dllmacro.h"
|
||||
#include "source.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class QState;
|
||||
class QStateMachine;
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class DLLEXPORT LatchManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LatchManager( QObject* parent = 0 );
|
||||
virtual ~LatchManager();
|
||||
|
||||
bool isLatched( const source_ptr& src );
|
||||
|
||||
public slots:
|
||||
void latchRequest( const Tomahawk::source_ptr& source );
|
||||
void unlatchRequest( const Tomahawk::source_ptr& source );
|
||||
void catchUpRequest();
|
||||
|
||||
private slots:
|
||||
|
||||
void playlistChanged( Tomahawk::PlaylistInterface* );
|
||||
private:
|
||||
enum State {
|
||||
NotLatched = 0,
|
||||
Latching,
|
||||
Latched
|
||||
};
|
||||
|
||||
State m_state;
|
||||
source_ptr m_latchedOnTo;
|
||||
source_ptr m_waitingForLatch;
|
||||
playlistinterface_ptr m_latchedInterface;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LATCHMANAGER_H
|
@@ -21,7 +21,7 @@
|
||||
#include <QMutexLocker>
|
||||
#include <QVariant>
|
||||
|
||||
#include <tomahawksettings.h>
|
||||
#include "tomahawksettings.h"
|
||||
|
||||
#include "utils/logger.h"
|
||||
|
||||
|
64
src/libtomahawk/actioncollection.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "actioncollection.h"
|
||||
#include <tomahawksettings.h>
|
||||
#include <utils/tomahawkutils.h>
|
||||
|
||||
ActionCollection* ActionCollection::s_instance = 0;
|
||||
ActionCollection* ActionCollection::instance()
|
||||
{
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
|
||||
ActionCollection::ActionCollection( QObject *parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
s_instance = this;
|
||||
initActions();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActionCollection::initActions()
|
||||
{
|
||||
m_actionCollection[ "latchOn" ] = new QAction( tr( "&Listen Along" ), this );
|
||||
m_actionCollection[ "latchOff" ] = new QAction( tr( "&Stop Listening Along" ), this );
|
||||
|
||||
bool isPublic = TomahawkSettings::instance()->privateListeningMode() == TomahawkSettings::PublicListening;
|
||||
QAction *privacyToggle = new QAction( tr( QString( isPublic ? "&Listen Privately" : "&Listen Publicly" ).toAscii().constData() ), this );
|
||||
privacyToggle->setIcon( QIcon( RESPATH "images/private-listening.png" ) );
|
||||
privacyToggle->setIconVisibleInMenu( isPublic );
|
||||
m_actionCollection[ "togglePrivacy" ] = privacyToggle;
|
||||
}
|
||||
|
||||
|
||||
ActionCollection::~ActionCollection()
|
||||
{
|
||||
s_instance = 0;
|
||||
foreach( QString key, m_actionCollection.keys() )
|
||||
delete m_actionCollection[ key ];
|
||||
}
|
||||
|
||||
|
||||
QAction*
|
||||
ActionCollection::getAction( const QString& name )
|
||||
{
|
||||
return m_actionCollection.contains( name ) ? m_actionCollection[ name ] : 0;
|
||||
}
|
47
src/libtomahawk/actioncollection.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOMAHAWKACTIONCOLLECTION_H
|
||||
#define TOMAHAWKACTIONCOLLECTION_H
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
#include <QtGui/QAction>
|
||||
|
||||
|
||||
class DLLEXPORT ActionCollection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static ActionCollection* instance();
|
||||
|
||||
ActionCollection( QObject *parent);
|
||||
~ActionCollection();
|
||||
|
||||
void initActions();
|
||||
|
||||
QAction* getAction( const QString &name );
|
||||
|
||||
private:
|
||||
static ActionCollection* s_instance;
|
||||
|
||||
QHash< QString, QAction* > m_actionCollection;
|
||||
};
|
||||
|
||||
#endif
|