Compare commits
958 Commits
vsxu
...
twitterfix
Author | SHA1 | Date | |
---|---|---|---|
|
37ca79aa61 | ||
|
e4bd229ef0 | ||
|
bb62fd6047 | ||
|
e91d9e55f6 | ||
|
b308212214 | ||
|
5766ea382b | ||
|
413bddaf7d | ||
|
2deb9bcdc1 | ||
|
5b2a5b76a4 | ||
|
2558202a52 | ||
|
ac8703c9e7 | ||
|
2ee66a3cda | ||
|
3f5d219549 | ||
|
b1904b877e | ||
|
7ffb3b2fef | ||
|
95dccb8cf9 | ||
|
530d9d7e5f | ||
|
d44028a2af | ||
|
5a1ee4ec3a | ||
|
e426e26e8d | ||
|
1b748201bc | ||
|
45397e82a8 | ||
|
3f494ed5d3 | ||
|
a36ee207e9 | ||
|
70245e34ac | ||
|
965a9b6153 | ||
|
219d4e5f19 | ||
|
41074e15d1 | ||
|
b2e233b127 | ||
|
48b089c3c4 | ||
|
675841e9a7 | ||
|
e0693475d7 | ||
|
b7aef08b7c | ||
|
6c856db4f8 | ||
|
a63a636750 | ||
|
01b6b6887c | ||
|
ad49a5d5af | ||
|
edb34eef59 | ||
|
717b04623f | ||
|
5a8b32691e | ||
|
92423fe925 | ||
|
cdb044b4e4 | ||
|
e26545b195 | ||
|
46fde05aa9 | ||
|
4fdd6ddc45 | ||
|
ebe8df4f91 | ||
|
5ed65cafce | ||
|
d3271cffde | ||
|
46f0ef9552 | ||
|
b052486e2e | ||
|
7326212671 | ||
|
57ab3f73db | ||
|
4507315f3b | ||
|
e96b5cb080 | ||
|
b2c281ad37 | ||
|
337423c52f | ||
|
4b28c15850 | ||
|
77a901a71f | ||
|
b449651452 | ||
|
763ae73d01 | ||
|
ab3c4330df | ||
|
b7a43553fe | ||
|
13b74f1c21 | ||
|
80fe1f0777 | ||
|
2ef10fee39 | ||
|
73e824c859 | ||
|
93cc1fcca8 | ||
|
667a4e5a78 | ||
|
81b8a22d6a | ||
|
b6b3bf1a1c | ||
|
b17b5ed276 | ||
|
de89a0dd83 | ||
|
69f41c41e8 | ||
|
5f1564fd3d | ||
|
2e0d6b0874 | ||
|
5d977d1ca7 | ||
|
246d935c04 | ||
|
084186bdf6 | ||
|
ed4a631619 | ||
|
285b254f76 | ||
|
23757b2819 | ||
|
eb87952ce5 | ||
|
c9704cbe64 | ||
|
5c70221296 | ||
|
0564ac3565 | ||
|
64aea4541d | ||
|
eeba60dfec | ||
|
f874e6b4f0 | ||
|
f7f4cbb781 | ||
|
fdfda2e435 | ||
|
b972558171 | ||
|
3cb1778502 | ||
|
dbbf93bfcd | ||
|
ebd5a98d27 | ||
|
ae807bc7ce | ||
|
647f68bd22 | ||
|
4f947b893f | ||
|
8ce4b3587d | ||
|
2d356c5bae | ||
|
b76b96ef3e | ||
|
ee7986180f | ||
|
2d34a69e0c | ||
|
4c04feb529 | ||
|
fd7f1fe422 | ||
|
3e9e37fdc9 | ||
|
fe58726b69 | ||
|
bf3e2ccb01 | ||
|
33c9f59929 | ||
|
a699348766 | ||
|
45d06c9be5 | ||
|
cf4baf28c3 | ||
|
91205b8fd7 | ||
|
8d6d584bb4 | ||
|
9291ee80c9 | ||
|
4ec75ec49c | ||
|
b05f56491e | ||
|
9df8fc0182 | ||
|
65c8739da5 | ||
|
841b151acc | ||
|
b4dda21704 | ||
|
48ab96a1f6 | ||
|
183b0c8958 | ||
|
fb842a3580 | ||
|
e8247421ab | ||
|
32e1a16ead | ||
|
f9eab019a9 | ||
|
a8354ed1a9 | ||
|
1f0f4e21a8 | ||
|
8b17657da1 | ||
|
e52b9eb36b | ||
|
34656e6395 | ||
|
06338c73f1 | ||
|
ff431b1183 | ||
|
d6f017bc6a | ||
|
cd84015c8d | ||
|
d60b8bda3e | ||
|
95bb3629a1 | ||
|
8cce5dafcd | ||
|
69dbb8a882 | ||
|
6cfac1978e | ||
|
50fbe986d7 | ||
|
3e60adfe37 | ||
|
37f7521d5c | ||
|
42faa354ec | ||
|
f33d446f7f | ||
|
f7b9f8a3d7 | ||
|
380ff0d23d | ||
|
9c995270cf | ||
|
dcc61f56e3 | ||
|
5bb31a2e7c | ||
|
027c716fd7 | ||
|
d2c8196b07 | ||
|
dd4acb0cd2 | ||
|
8c4cfef5a1 | ||
|
eeaba8309d | ||
|
81575c68e8 | ||
|
bb5e5c33ca | ||
|
a071105a26 | ||
|
102ead74bd | ||
|
e72289c078 | ||
|
51e790de2f | ||
|
f64cce1567 | ||
|
755285920c | ||
|
ee8e25b8ce | ||
|
3e781a243e | ||
|
be76cc49d3 | ||
|
021cd54687 | ||
|
8aae86cf16 | ||
|
27eb1b51f1 | ||
|
485d076d73 | ||
|
1324b6fe64 | ||
|
d47adbea63 | ||
|
6034458769 | ||
|
6cc62d24d7 | ||
|
a9c049b0ee | ||
|
2a6766c6d2 | ||
|
393cefb88c | ||
|
4dc3014a37 | ||
|
8589977233 | ||
|
f8d363e3d0 | ||
|
a2c5a949b3 | ||
|
d05fd22999 | ||
|
69987877a1 | ||
|
92b5d3cb84 | ||
|
ff18013f88 | ||
|
3830d44a78 | ||
|
c89b43ac07 | ||
|
42a1119cba | ||
|
3cae004dd4 | ||
|
82b4fdafd3 | ||
|
641eff8472 | ||
|
b2f7c5f7c5 | ||
|
a631afa051 | ||
|
03fbcb8790 | ||
|
7ea8f8aa64 | ||
|
4ed1b4975f | ||
|
43a55d932e | ||
|
cbd25df44d | ||
|
789536c49f | ||
|
79c2c12631 | ||
|
22e05bd6ea | ||
|
7789c1ec2c | ||
|
a9b3ad786c | ||
|
61fb4744f3 | ||
|
906e1147e5 | ||
|
f40500452b | ||
|
2b139103d0 | ||
|
7b801270c2 | ||
|
e27976c8a1 | ||
|
b9e772f3e3 | ||
|
01f98ddc7f | ||
|
e95efe6f76 | ||
|
913663eef0 | ||
|
f59bbc111f | ||
|
fc9a36e28e | ||
|
7b89460aa1 | ||
|
07ba8d307c | ||
|
a453934d08 | ||
|
7adb3fc737 | ||
|
9326813f3f | ||
|
65bc08524e | ||
|
b75a575f51 | ||
|
3b332d6d12 | ||
|
b1210ea43f | ||
|
3a8eb34e35 | ||
|
697599db6c | ||
|
e74ec6ba79 | ||
|
838b802846 | ||
|
57e953409a | ||
|
5452c41760 | ||
|
414f553eb3 | ||
|
7698b2ec38 | ||
|
04358fbafe | ||
|
d30e5df23e | ||
|
455d7816e5 | ||
|
710780f3e9 | ||
|
07430668d2 | ||
|
66b282be6c | ||
|
b5626c0b61 | ||
|
029dd935c9 | ||
|
8392251280 | ||
|
4b3682c1c5 | ||
|
b1a5626e94 | ||
|
32022ce209 | ||
|
c7ecacda32 | ||
|
319a03b791 | ||
|
17bcaf7369 | ||
|
652dd24e7d | ||
|
c0e627b7c6 | ||
|
812bfd7ca5 | ||
|
56edc1ba0c | ||
|
82240ff6c1 | ||
|
7b901c18a9 | ||
|
4a510b436b | ||
|
0677db0419 | ||
|
ab641c88e0 | ||
|
91ebe57dd2 | ||
|
7763a94969 | ||
|
65b01ffbca | ||
|
1d5e124b46 | ||
|
8d6a4335b8 | ||
|
f5873c283a | ||
|
6d6ca1e94a | ||
|
b92f7f551e | ||
|
7fc03770d0 | ||
|
6352542793 | ||
|
dab5d51952 | ||
|
ef8306394f | ||
|
bb9906cd9a | ||
|
a191a7648b | ||
|
12d627f3a7 | ||
|
802fc1f39f | ||
|
4535295dd6 | ||
|
24f2b29806 | ||
|
696dca4af4 | ||
|
4c6f31e7c2 | ||
|
93ad670828 | ||
|
99e09b3b8d | ||
|
b0a1e5ffe1 | ||
|
269319c15d | ||
|
fbe918dd4e | ||
|
46bee7acd4 | ||
|
2a24b4d239 | ||
|
24ec94ed96 | ||
|
9c2e17a660 | ||
|
931cfd8eb2 | ||
|
c630baf774 | ||
|
987345dd58 | ||
|
78d7a376bc | ||
|
b52e0d8470 | ||
|
e3bdfda2ee | ||
|
0aea363abf | ||
|
11895fc198 | ||
|
a48fff23c2 | ||
|
e4d6b1785c | ||
|
9373b6b312 | ||
|
012bc8949e | ||
|
15595b741e | ||
|
f272c5e966 | ||
|
9419c77069 | ||
|
50ce4d3c55 | ||
|
fda71bb583 | ||
|
eb0ed267fa | ||
|
0b796a3085 | ||
|
1695b39abf | ||
|
c84cfc8bf0 | ||
|
53e97e75da | ||
|
ab84f6837a | ||
|
6557b3fb0f | ||
|
db07be002d | ||
|
6f266230f5 | ||
|
31c7c84b5c | ||
|
f7fcfcb452 | ||
|
ddd0af895f | ||
|
1360d28b25 | ||
|
0bc8316319 | ||
|
361fdbe31f | ||
|
134fa6dffd | ||
|
1a45a42a86 | ||
|
c7feb0f6f0 | ||
|
46cb1f01fb | ||
|
3ade68cf25 | ||
|
3cbb6c426b | ||
|
8942cbb9fa | ||
|
177e0a6a80 | ||
|
5a17ad2fd9 | ||
|
e1c7c9df05 | ||
|
3b4c3cd36c | ||
|
1b99cabef9 | ||
|
8bac05eb97 | ||
|
ae2b09ab4e | ||
|
fff849bb88 | ||
|
5feee4ba75 | ||
|
701ef5a69d | ||
|
794bcc6fb1 | ||
|
64ba0b5d7c | ||
|
255cef8092 | ||
|
a99b35e11b | ||
|
d61a99629f | ||
|
7ccccae722 | ||
|
4d02b9945d | ||
|
d2f6a65eb5 | ||
|
08a15f0acb | ||
|
d9f690d9d6 | ||
|
c4a9dd6b32 | ||
|
4ec0117c43 | ||
|
b7b5e60f98 | ||
|
8069baf911 | ||
|
df37fd42fd | ||
|
f72e123140 | ||
|
ba064206c4 | ||
|
a542797038 | ||
|
0cf9a26004 | ||
|
a6754e7467 | ||
|
6e51739ec9 | ||
|
c46c9bba8e | ||
|
613d40a605 | ||
|
4b6eadd956 | ||
|
c6beda5a7b | ||
|
67d943bce3 | ||
|
08fa4bacd1 | ||
|
bc443d25ac | ||
|
78be0b75fe | ||
|
7169c6d070 | ||
|
78a8c3cfc4 | ||
|
68d2cb38de | ||
|
332e9c0448 | ||
|
0eafeb995d | ||
|
2a44de8641 | ||
|
c1a7c63f03 | ||
|
6a24d8ebf5 | ||
|
add5bdf8de | ||
|
90d3661c52 | ||
|
6c4e6725b4 | ||
|
78192cc752 | ||
|
d93c45fd1e | ||
|
066a7a2660 | ||
|
548aa1a194 | ||
|
69d1450b5c | ||
|
066c387ae9 | ||
|
72df118216 | ||
|
556c0b0767 | ||
|
511d353cc6 | ||
|
ffe810349b | ||
|
f42aca9a02 | ||
|
64fbd23008 | ||
|
9db33b7fb6 | ||
|
75d1ab7bbe | ||
|
4871b6b76c | ||
|
28c76e73bd | ||
|
3ea581c4f8 | ||
|
7284a53d0f | ||
|
c5eb71d0de | ||
|
06fbb9e0dc | ||
|
e33923c63f | ||
|
2b09915a0d | ||
|
35c56395da | ||
|
619373c2e5 | ||
|
43806aec62 | ||
|
54aef2cd2e | ||
|
4b38bbff30 | ||
|
4eaff7a45f | ||
|
25fba84b32 | ||
|
042b27ea83 | ||
|
f51f5e4d59 | ||
|
4c5855c95d | ||
|
6a88aefadc | ||
|
feedb1450c | ||
|
bfdc7a3d67 | ||
|
80a1009aa2 | ||
|
bb0e24f074 | ||
|
b6cd43d25f | ||
|
b0e8fd33ce | ||
|
3cb079b014 | ||
|
651bde6b4a | ||
|
03c57d3a0f | ||
|
6ffaa1450e | ||
|
ca375bcc76 | ||
|
1dda0371b5 | ||
|
1b445934a8 | ||
|
3f39b0a95f | ||
|
8bb31492e4 | ||
|
41a3cea05e | ||
|
c6b5ea0380 | ||
|
712805f5b0 | ||
|
1a6f96caaf | ||
|
789a93dbe9 | ||
|
7914fc9551 | ||
|
8a85b8bbc6 | ||
|
a80929e52f | ||
|
ff3770a464 | ||
|
546abf4a6d | ||
|
cfcdbbb728 | ||
|
30791e9bdc | ||
|
4e01387eb9 | ||
|
09ee426710 | ||
|
de3b8c794b | ||
|
94d97a1029 | ||
|
af1a8ea8b4 | ||
|
d82df7f00d | ||
|
570171bddd | ||
|
67d1e6e97c | ||
|
dfa2a80d82 | ||
|
9d77f20710 | ||
|
6d003028c3 | ||
|
1f1f0d5bda | ||
|
662ee55514 | ||
|
d154c141fb | ||
|
e4b90e6305 | ||
|
fd81151996 | ||
|
6a6e2754c4 | ||
|
ebd59724a5 | ||
|
678ad2649f | ||
|
514d399f6b | ||
|
9d88f16aa4 | ||
|
2a6a4c0252 | ||
|
0c308b850d | ||
|
55d80eb547 | ||
|
110824bb06 | ||
|
3b21c91a97 | ||
|
58adc470ce | ||
|
2be9dfc45b | ||
|
1a7f2cc070 | ||
|
84773f7956 | ||
|
155cccb109 | ||
|
30e239c311 | ||
|
f1aa7b6d28 | ||
|
6c48be2563 | ||
|
caf77a0935 | ||
|
6af93841cb | ||
|
396f332d55 | ||
|
624e95a97b | ||
|
3b9fb2c7eb | ||
|
8ba61f5496 | ||
|
e147bf4861 | ||
|
5fc54a7e4c | ||
|
4ad1efbcf5 | ||
|
caf2d18708 | ||
|
80e433abe0 | ||
|
464a32f35d | ||
|
b136eedc8b | ||
|
97f2bb601f | ||
|
90e1af331b | ||
|
cef3e7fac7 | ||
|
22e53172eb | ||
|
ee4dcc3892 | ||
|
f1c33bd67c | ||
|
1161ab2095 | ||
|
c8743cd0e0 | ||
|
cc7ecc6795 | ||
|
e9db3ed319 | ||
|
a40813c3b8 | ||
|
6c45806fbe | ||
|
bfc99e1af9 | ||
|
1cd134d6b0 | ||
|
a80db298c0 | ||
|
a4c805b122 | ||
|
83a35fe3aa | ||
|
57e36d5d01 | ||
|
eeddd067ea | ||
|
3f65e2b73c | ||
|
266e7bed8b | ||
|
47b1990eeb | ||
|
b32f5c4904 | ||
|
bc76ce550c | ||
|
4960e68208 | ||
|
74ef12268e | ||
|
676bf7f6d7 | ||
|
42d488eaac | ||
|
059d0374c6 | ||
|
5d09ff81fb | ||
|
d43db27ce0 | ||
|
5dcf426cdf | ||
|
5b6c4560ae | ||
|
fec670f27c | ||
|
fb13ccd285 | ||
|
b3b70cea82 | ||
|
f84d08e011 | ||
|
7403713d98 | ||
|
e049dcd6af | ||
|
1af928790e | ||
|
48d66649b1 | ||
|
c054d07110 | ||
|
f0f9e6847b | ||
|
b9c61952a6 | ||
|
c3e3944421 | ||
|
eddaec701b | ||
|
87086e5278 | ||
|
9c5966000c | ||
|
b49d810f01 | ||
|
79bfdec895 | ||
|
d8be1fa224 | ||
|
948a438ff2 | ||
|
9f5215302c | ||
|
73d7ba03f5 | ||
|
d623bbefc2 | ||
|
907dad95e1 | ||
|
cdb70b05d2 | ||
|
565217a53a | ||
|
bee6485475 | ||
|
ace18dfa1f | ||
|
95f1162b6e | ||
|
e5bdd2242f | ||
|
deb0eb819c | ||
|
04864c7d79 | ||
|
0dc0067450 | ||
|
a4421df9e9 | ||
|
47774c3894 | ||
|
43c4daa4e3 | ||
|
fc95cee6ce | ||
|
f39e9621a0 | ||
|
704c736046 | ||
|
0d8a8038b7 | ||
|
38ea9653a0 | ||
|
eebf5dfe07 | ||
|
ba46795749 | ||
|
fff8fbfe80 | ||
|
00dade5460 | ||
|
301c1d21fe | ||
|
bac82c0abf | ||
|
8e0f44a374 | ||
|
5593c134cd | ||
|
f414e92b74 | ||
|
02ff39f595 | ||
|
eec8b76de0 | ||
|
68f03dbd13 | ||
|
c54ca78769 | ||
|
ff04ab3b92 | ||
|
cb484a2058 | ||
|
1bd7d37a0a | ||
|
f41872540d | ||
|
4dabbdf247 | ||
|
4392e34882 | ||
|
aec6b557a6 | ||
|
dddeb9e9a7 | ||
|
3c485949b6 | ||
|
27978e5cd3 | ||
|
fa49dde51a | ||
|
6d56d4350a | ||
|
a4ff57fafb | ||
|
8fa4252fd6 | ||
|
753e1b3c90 | ||
|
68d541d2e8 | ||
|
75e9deabc4 | ||
|
d6c7e7f57b | ||
|
e828dadec8 | ||
|
6e929986cb | ||
|
e1b086e3a4 | ||
|
27147a0140 | ||
|
b8d3b3bc5f | ||
|
b18f926fa5 | ||
|
bf0b104d27 | ||
|
c0ab42021e | ||
|
4d77074c78 | ||
|
8ffd79d764 | ||
|
6da14794df | ||
|
f2c3edb8fe | ||
|
e0f60931f7 | ||
|
5b1aa81d1d | ||
|
ac274a50d3 | ||
|
44a1adb922 | ||
|
93c68b4ce1 | ||
|
21eeab61d8 | ||
|
3aa7f5c9de | ||
|
1468d3c0dc | ||
|
6de0656794 | ||
|
0c4ac584e4 | ||
|
b2612f9189 | ||
|
b0486f44b3 | ||
|
819623300d | ||
|
a710782624 | ||
|
42b2779240 | ||
|
195953f4f8 | ||
|
ba82c142ef | ||
|
8d59a33502 | ||
|
2e3132732a | ||
|
a2bfd73d55 | ||
|
ebbedb2b99 | ||
|
57e55d0b88 | ||
|
15194438ee | ||
|
6d068e33ce | ||
|
48d2ac71fa | ||
|
afe6ed8463 | ||
|
6e34b3f620 | ||
|
6f0d29dde9 | ||
|
3e11945c02 | ||
|
bd098e3ff2 | ||
|
b70114a225 | ||
|
d5aed7b6df | ||
|
d86124203c | ||
|
29c49b12b7 | ||
|
d2b719b61c | ||
|
8495c6397a | ||
|
9b1a983cfd | ||
|
8b99d234e8 | ||
|
0e2da32f0c | ||
|
4d91fab887 | ||
|
967c767f0b | ||
|
28f62d850d | ||
|
4f84158bdc | ||
|
ce44b17544 | ||
|
c9a3b697ef | ||
|
ad82b81225 | ||
|
e3f5605c4e | ||
|
66836ae0bd | ||
|
6342e6a9f8 | ||
|
b34b3c7470 | ||
|
19d3cf5bae | ||
|
6408d93dc0 | ||
|
f65b9d7f6f | ||
|
232409b1c4 | ||
|
2efc4ee9d8 | ||
|
a27d918bea | ||
|
8503f5bbe3 | ||
|
b2779a9b6a | ||
|
51087b5e0a | ||
|
39bf8f9f6e | ||
|
496871af04 | ||
|
dab85e2008 | ||
|
042ccbe730 | ||
|
6c6411561b | ||
|
18e3669911 | ||
|
5a57e285ec | ||
|
c5732d0d62 | ||
|
2e6688f42b | ||
|
6409113c0e | ||
|
ccd3e19fac | ||
|
18c16959ed | ||
|
60d11db923 | ||
|
c88058358e | ||
|
c511841f57 | ||
|
240517b0cd | ||
|
fab36b2262 | ||
|
cb85c767de | ||
|
35706f16f7 | ||
|
538db98e2c | ||
|
5c0507323c | ||
|
57490a68f0 | ||
|
66e67fdd4e | ||
|
6dbcac58a4 | ||
|
1aeb5ed807 | ||
|
2d1a036b3d | ||
|
970b3e79a9 | ||
|
c6cd6821bf | ||
|
e1edd9c5ee | ||
|
ccee34eaa7 | ||
|
3f3c855a6d | ||
|
5848e7ba8c | ||
|
7ac68392a6 | ||
|
1ebeae274a | ||
|
2710bca395 | ||
|
dc28a7694b | ||
|
a30c4f9055 | ||
|
ab026b5e2f | ||
|
99aea14b62 | ||
|
cf5c368499 | ||
|
2a58d53145 | ||
|
9a19c9e81e | ||
|
448734190c | ||
|
afe2db8d51 | ||
|
f4603e0cad | ||
|
6cbc8a9539 | ||
|
f3324ce167 | ||
|
5f674dbc83 | ||
|
69cfe8bb2f | ||
|
528121d283 | ||
|
71833b817f | ||
|
df65d040e8 | ||
|
5641f2a07c | ||
|
a602cbe005 | ||
|
f9940ead9f | ||
|
0c7780e5e3 | ||
|
6b6d5f270f | ||
|
0067e376ae | ||
|
935b046acc | ||
|
dd74ce04e6 | ||
|
e3a43e8ca6 | ||
|
c401ea0d91 | ||
|
2d03b8aea0 | ||
|
178aed9174 | ||
|
6552deca61 | ||
|
89009c09be | ||
|
34672c7bed | ||
|
3caeb4642a | ||
|
80b0eacfed | ||
|
aa078e86e5 | ||
|
9daf0a6089 | ||
|
6dead5e7e1 | ||
|
335868ea95 | ||
|
fc45646205 | ||
|
dbd466d3ed | ||
|
292d8c9530 | ||
|
6b68598d1d | ||
|
0d9e248dac | ||
|
46a86fe6a5 | ||
|
a56ca4ddfc | ||
|
6483c55749 | ||
|
5a56a3e060 | ||
|
585f32c4d8 | ||
|
9ea311526c | ||
|
1342fdb9a7 | ||
|
2cc4fccd66 | ||
|
a2d0899285 | ||
|
06cc52744d | ||
|
2878552239 | ||
|
df758aa3f8 | ||
|
f79ed86b57 | ||
|
c9b0c92450 | ||
|
57d1c29d35 | ||
|
cdf7c11b29 | ||
|
be7b5babe9 | ||
|
f7f2c51d4e | ||
|
4889ed6a33 | ||
|
3557686681 | ||
|
58dfc54e00 | ||
|
bddbc7a194 | ||
|
33e0116e4b | ||
|
b07f498516 | ||
|
c77be81e5b | ||
|
11cf2c78d8 | ||
|
77bcc7c7aa | ||
|
934ee4a535 | ||
|
5b97802104 | ||
|
25ec5cb432 | ||
|
8b4b4a8f0c | ||
|
6448cebec6 | ||
|
191ee259d4 | ||
|
dc364726c0 | ||
|
6ac0f68224 | ||
|
3c3078f9f8 | ||
|
b994befc58 | ||
|
56cf0239da | ||
|
69d75362b3 | ||
|
e677656b74 | ||
|
8db9c79e57 | ||
|
e9ee617d94 | ||
|
c9c6534af5 | ||
|
1b9767995b | ||
|
1c561ba7a9 | ||
|
91e307b261 | ||
|
91546d0684 | ||
|
f4c92793e6 | ||
|
52baebc899 | ||
|
63c029554a | ||
|
3900dd27d2 | ||
|
e9fb17dadb | ||
|
56c2f86381 | ||
|
a8440c72e4 | ||
|
cbb5bac075 | ||
|
b7f1f56f77 | ||
|
9fe17cf6f5 | ||
|
d641f06e6d | ||
|
7668f04c0c | ||
|
a73d1cd342 | ||
|
35c4a29cbe | ||
|
f6e00fbb86 | ||
|
3f9503364c | ||
|
36b2a585f9 | ||
|
42220a8c95 | ||
|
540db2860e | ||
|
1ac4efa88a | ||
|
b2247febc1 | ||
|
ea47a5556d | ||
|
b51480f122 | ||
|
55d7fe9e53 | ||
|
e6efa8dac3 | ||
|
ac42abda7f | ||
|
6a6f5dba7a | ||
|
d0b6d09255 | ||
|
cfe42d10ea | ||
|
6ad9e820e3 | ||
|
47a403a9c8 | ||
|
b2fc0935a4 | ||
|
a04d384ac4 | ||
|
325bb0bf8f | ||
|
c2a79d4cbf | ||
|
b17b8356ad | ||
|
a41b174851 | ||
|
458d32ed7c | ||
|
a0383b6664 | ||
|
9b1fc4cd24 | ||
|
2a27ef88f6 | ||
|
d1ecf6d748 | ||
|
396b5cd6e0 | ||
|
55e7d6383b | ||
|
dbcbffb6c4 | ||
|
6b51872c3e | ||
|
79d8b081d7 | ||
|
165276912f | ||
|
413052bf8e | ||
|
b8ccf5a2e9 | ||
|
27cde20dbf | ||
|
01fbbb6683 | ||
|
61b55ab156 | ||
|
502db67510 | ||
|
47e8f4ffc6 | ||
|
46fd72920c | ||
|
399b835436 | ||
|
3e81405086 | ||
|
443c554b36 | ||
|
9f76cdf486 | ||
|
881bf5dd9d | ||
|
8bb9661960 | ||
|
a1c69b0b43 | ||
|
8cdce8e1ca | ||
|
e3f4fdfdd8 | ||
|
0b452cc415 | ||
|
e6f4674064 | ||
|
06be1868ea | ||
|
2412266a34 | ||
|
6638d74687 | ||
|
dc41b29ab7 | ||
|
638718a48c | ||
|
9adc4be099 | ||
|
75ea38010f | ||
|
5083849514 | ||
|
8d75ba4d64 | ||
|
0c231d5532 | ||
|
7e9fa7c2a7 | ||
|
3687ebdc6b | ||
|
8ceb537860 | ||
|
64043e059f | ||
|
011483ec54 | ||
|
b6ce8d282c | ||
|
b54b7f6455 | ||
|
d0a6d8a0a2 | ||
|
a02a9a4fd9 | ||
|
e2749a7676 | ||
|
0a3dc28bdf | ||
|
79fd0278ce | ||
|
488eb387cb | ||
|
99143f6148 | ||
|
82c77e64c6 | ||
|
751af7862c | ||
|
0425bfebac | ||
|
40041f5c1e | ||
|
1d4320afea | ||
|
132460b797 | ||
|
369c8ecd98 | ||
|
478ff17e67 | ||
|
41b146f38a | ||
|
eea70f104f | ||
|
7bae6c6b8a | ||
|
9ab47d769b | ||
|
23d14bd476 | ||
|
d9c3162146 | ||
|
4a1b021753 | ||
|
3418d5295b | ||
|
bf30dc37a2 | ||
|
ecccf87992 | ||
|
0dd4823a23 | ||
|
001b9d0627 | ||
|
6ed4902e00 | ||
|
0cfe2d2357 | ||
|
8f1fa9b728 | ||
|
34dbc50b3a | ||
|
daa6b7b841 | ||
|
21cfb96b1e | ||
|
96eb48090c | ||
|
f17bba773d | ||
|
8eba4c171f | ||
|
f2b1cc6ae3 | ||
|
e8eb7300fc | ||
|
9607d6be00 | ||
|
ddb4bd4563 | ||
|
e5414c8ff6 | ||
|
7e13f1ae62 | ||
|
b78a348712 | ||
|
4e450b36ee | ||
|
b300279e30 | ||
|
e319aa248c | ||
|
39c7af6262 | ||
|
4334840dad | ||
|
22def2c617 | ||
|
cf9389a0de | ||
|
601bc7729a | ||
|
0aa61b9fa8 | ||
|
8483e38f58 | ||
|
a78ef004f0 | ||
|
811b6842c5 | ||
|
d8a8575b55 | ||
|
801d7e5d89 | ||
|
aaf147a39a | ||
|
2d66daec41 | ||
|
f74165424f | ||
|
2e45bf5e26 | ||
|
7783f48bae | ||
|
3607d364e7 | ||
|
aefec1eaac | ||
|
00adb66cf0 | ||
|
b6911525a4 | ||
|
328d055ee1 | ||
|
cef9c620dc | ||
|
eedf940e5f | ||
|
e3785e50f2 | ||
|
aae400bea9 | ||
|
01aa3ee9a5 | ||
|
ccb6d82e88 | ||
|
bfcf4d3bdb | ||
|
eaab5df5be | ||
|
ccde46447e | ||
|
8b862774c9 | ||
|
d50e41f4d2 | ||
|
1736f4caaa | ||
|
9db0b5ed40 | ||
|
13cfda6e1e | ||
|
8e2721236f | ||
|
c906bd4e8f | ||
|
988554934b | ||
|
709a25ce97 | ||
|
fb6d9967dc | ||
|
8f24acd008 | ||
|
f548d36586 | ||
|
c3064d8249 | ||
|
60aec5ac0f | ||
|
abd7edab36 | ||
|
88350b6a6c | ||
|
c7f6144bfe |
9
.tx/config
Normal file
@@ -0,0 +1,9 @@
|
||||
[main]
|
||||
host = https://www.transifex.net
|
||||
|
||||
[tomahawk.tomahawk-master]
|
||||
file_filter = lang/tomahawk_<lang>.ts
|
||||
source_file = lang/tomahawk_en.ts
|
||||
source_lang = en
|
||||
type = QT
|
||||
|
@@ -1,10 +1,7 @@
|
||||
PROJECT( tomahawk )
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.8.6 )
|
||||
SET( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules" )
|
||||
|
||||
IF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 )
|
||||
CMAKE_POLICY(SET CMP0017 NEW)
|
||||
ENDIF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 )
|
||||
CMAKE_POLICY(SET CMP0017 NEW)
|
||||
|
||||
###
|
||||
### Tomahawk application info
|
||||
@@ -15,17 +12,32 @@ SET( TOMAHAWK_APPLICATION_NAME "Tomahawk" )
|
||||
SET( TOMAHAWK_DESCRIPTION_SUMMARY "The social media player" )
|
||||
|
||||
SET( TOMAHAWK_VERSION_MAJOR 0 )
|
||||
SET( TOMAHAWK_VERSION_MINOR 3 )
|
||||
SET( TOMAHAWK_VERSION_MINOR 4 )
|
||||
SET( TOMAHAWK_VERSION_PATCH 99 )
|
||||
|
||||
#SET( TOMAHAWK_VERSION_RC 0 )
|
||||
|
||||
# enforce proper symbol exporting on all platforms
|
||||
add_definitions( "-fvisibility=hidden" )
|
||||
|
||||
# build options
|
||||
option(BUILD_GUI "Build Tomahawk with GUI" ON)
|
||||
option(BUILD_RELEASE "Generate TOMAHAWK_VERSION without GIT info" OFF)
|
||||
option(WITH_BREAKPAD "Build with breakpad integration" ON)
|
||||
option(WITH_CRASHREPORTER "Build with CrashReporter" ON)
|
||||
option(LEGACY_KDE_INTEGRATION "Install tomahawk.protocol file, deprecated since 4.6.0" OFF)
|
||||
|
||||
IF( CMAKE_SYSTEM_PROCESSOR MATCHES "arm" )
|
||||
message(STATUS "Build of breakpad library disabled on this platform.")
|
||||
SET(WITH_BREAKPAD OFF)
|
||||
SET(WITH_CRASHREPORTER OFF)
|
||||
ENDIF()
|
||||
|
||||
# add definitions based on build options
|
||||
IF(WITH_BREAKPAD)
|
||||
message(STATUS "Build with support for breakpad.")
|
||||
ENDIF()
|
||||
|
||||
# generate version string
|
||||
|
||||
# base string used in release and unstable builds
|
||||
@@ -38,7 +50,7 @@ ENDIF()
|
||||
IF( NOT BUILD_RELEASE )
|
||||
INCLUDE( CMakeDateStamp )
|
||||
SET( TOMAHAWK_VERSION_DATE "${CMAKE_DATESTAMP_YEAR}${CMAKE_DATESTAMP_MONTH}${CMAKE_DATESTAMP_DAY}" )
|
||||
IF( ${TOMAHAWK_VERSION_DATE} GREATER 0)
|
||||
IF( TOMAHAWK_VERSION_DATE GREATER 0)
|
||||
SET( TOMAHAWK_VERSION ${TOMAHAWK_VERSION}.${TOMAHAWK_VERSION_DATE} )
|
||||
ENDIF()
|
||||
|
||||
@@ -72,7 +84,7 @@ IF( NOT BUILD_GUI )
|
||||
MESSAGE( STATUS "Building Tomahawk ${TOMAHAWK_VERSION} in HEADLESS mode ***" )
|
||||
ELSE()
|
||||
MESSAGE( STATUS "Building Tomahawk ${TOMAHAWK_VERSION} full GUI version ***" )
|
||||
LIST(APPEND NEEDED_QT4_COMPONENTS "QtGui" "QtWebkit" )
|
||||
LIST(APPEND NEEDED_QT4_COMPONENTS "QtGui" "QtWebkit" "QtUiTools" )
|
||||
ENDIF()
|
||||
|
||||
IF( BUILD_GUI AND UNIX AND NOT APPLE )
|
||||
@@ -80,7 +92,7 @@ IF( BUILD_GUI AND UNIX AND NOT APPLE )
|
||||
ENDIF()
|
||||
|
||||
macro_optional_find_package(Qt4 4.7.0 COMPONENTS ${NEEDED_QT4_COMPONENTS} )
|
||||
macro_log_feature(QT4_FOUND "Qt" "A cross-platform application and UI framework" "http://qt.nokia.com" TRUE "" "If you see this, although libqt4-devel is installed, check whether \n the qtwebkit-devel package is installed as well")
|
||||
macro_log_feature(QT4_FOUND "Qt" "A cross-platform application and UI framework" "http://qt.nokia.com" TRUE "" "If you see this, although libqt4-devel is installed, check whether the \n qtwebkit-devel package and whatever contains QtUiTools is installed too")
|
||||
|
||||
macro_optional_find_package(Phonon 4.5.0)
|
||||
macro_log_feature(PHONON_FOUND "Phonon" "The Phonon multimedia library" "http://phonon.kde.org" TRUE "" "")
|
||||
@@ -109,30 +121,17 @@ 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_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" TRUE "" "")
|
||||
|
||||
macro_optional_find_package(QuaZip)
|
||||
macro_log_feature(QuaZip_FOUND "QuaZip" "Provides support for extracting downloaded resolvers automatically." "http://quazip.sourceforge.net/" FALSE "" "")
|
||||
macro_log_feature(QuaZip_FOUND "QuaZip" "Provides support for extracting downloaded resolvers automatically." "http://quazip.sourceforge.net/" TRUE "" "")
|
||||
|
||||
macro_optional_find_package(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")
|
||||
macro_optional_find_package(Jreen 1.0.5)
|
||||
macro_log_feature(JREEN_FOUND "Jreen" "Qt XMPP Library" "http://qutim.org/jreen / https://github.com/euroelessar/jreen" FALSE "" "Jreen is needed for the Jabber SIP plugin.\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")
|
||||
|
||||
|
||||
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 )
|
||||
macro_log_feature(QuaZip_FOUND "QuaZip" "Provides support for extracting downloaded resolvers automatically. Building internal copy" "http://quazip.sourceforge.net/" FALSE "" "")
|
||||
|
||||
# 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)
|
||||
@@ -211,9 +210,3 @@ ADD_SUBDIRECTORY( src/libtomahawk )
|
||||
SET( TOMAHAWK_LIBRARIES tomahawklib )
|
||||
ADD_SUBDIRECTORY( src )
|
||||
ADD_SUBDIRECTORY( admin )
|
||||
|
||||
IF( BUILD_GUI )
|
||||
IF( NOT DISABLE_CRASHREPORTER )
|
||||
ADD_SUBDIRECTORY( src/breakpad/CrashReporter )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
99
CMakeModules/AddTomahawkPlugin.cmake
Normal file
@@ -0,0 +1,99 @@
|
||||
MACRO(PARSE_ARGUMENTS prefix arg_names option_names)
|
||||
SET(DEFAULT_ARGS)
|
||||
FOREACH(arg_name ${arg_names})
|
||||
SET(${prefix}_${arg_name})
|
||||
ENDFOREACH(arg_name)
|
||||
FOREACH(option ${option_names})
|
||||
SET(${prefix}_${option} FALSE)
|
||||
ENDFOREACH(option)
|
||||
|
||||
SET(current_arg_name DEFAULT_ARGS)
|
||||
SET(current_arg_list)
|
||||
FOREACH(arg ${ARGN})
|
||||
SET(larg_names ${arg_names})
|
||||
LIST(FIND larg_names "${arg}" is_arg_name)
|
||||
IF (is_arg_name GREATER -1)
|
||||
SET(${prefix}_${current_arg_name} ${current_arg_list})
|
||||
SET(current_arg_name ${arg})
|
||||
SET(current_arg_list)
|
||||
ELSE (is_arg_name GREATER -1)
|
||||
SET(loption_names ${option_names})
|
||||
LIST(FIND loption_names "${arg}" is_option)
|
||||
IF (is_option GREATER -1)
|
||||
SET(${prefix}_${arg} TRUE)
|
||||
ELSE (is_option GREATER -1)
|
||||
SET(current_arg_list ${current_arg_list} ${arg})
|
||||
ENDIF (is_option GREATER -1)
|
||||
ENDIF (is_arg_name GREATER -1)
|
||||
ENDFOREACH(arg)
|
||||
SET(${prefix}_${current_arg_name} ${current_arg_list})
|
||||
ENDMACRO(PARSE_ARGUMENTS)
|
||||
|
||||
MACRO(CAR var)
|
||||
SET(${var} ${ARGV1})
|
||||
ENDMACRO(CAR)
|
||||
|
||||
MACRO(CDR var junk)
|
||||
SET(${var} ${ARGN})
|
||||
ENDMACRO(CDR)
|
||||
|
||||
|
||||
macro(add_tomahawk_plugin)
|
||||
parse_arguments(PLUGIN
|
||||
"SOURCES;UI;LINK_LIBRARIES;TYPE;EXPORT_MACRO;COMPILE_DEFINITIONS"
|
||||
"NO_INSTALL"
|
||||
${ARGN}
|
||||
)
|
||||
car(PLUGIN_NAME ${PLUGIN_DEFAULT_ARGS})
|
||||
|
||||
# message("*** Arguments for ${PLUGIN_NAME}")
|
||||
# message("Sources: ${PLUGIN_SOURCES}")
|
||||
# message("Link libraries: ${PLUGIN_LINK_LIBRARIES}")
|
||||
# message("UI: ${PLUGIN_UI}")
|
||||
# message("TYPE: ${PLUGIN_TYPE}")
|
||||
# message("EXPORT_MACRO: ${PLUGIN_EXPORT_MACRO}")
|
||||
|
||||
# create target name once for convenience
|
||||
set(target "tomahawk_${PLUGIN_TYPE}_${PLUGIN_NAME}")
|
||||
|
||||
# qt stuff
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(PLUGIN_UI)
|
||||
qt4_wrap_ui(PLUGIN_UI_SOURCES ${PLUGIN_UI})
|
||||
list(APPEND PLUGIN_SOURCES ${PLUGIN_UI_SOURCES})
|
||||
endif()
|
||||
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/resources.qrc")
|
||||
qt4_add_resources(PLUGIN_RC_SOURCES "resources.qrc")
|
||||
list(APPEND PLUGIN_SOURCES ${PLUGIN_RC_SOURCES})
|
||||
unset(PLUGIN_RC_SOURCES)
|
||||
endif()
|
||||
|
||||
# add target
|
||||
add_library(${target} MODULE ${PLUGIN_SOURCES})
|
||||
|
||||
# definitions - can this be moved into set_target_properties below?
|
||||
add_definitions(${QT_DEFINITIONS})
|
||||
set_target_properties(${target} PROPERTIES AUTOMOC TRUE COMPILE_DEFINITIONS ${PLUGIN_EXPORT_MACRO})
|
||||
if(PLUGIN_COMPILE_DEFINITIONS)
|
||||
# Dear CMake, i hate you! Sincerely, domme
|
||||
# At least in CMake 2.8.8, you CANNOT set more than one COMPILE_DEFINITIONS value
|
||||
# only takes the first one if called multiple times or bails out with wrong number of arguments
|
||||
# when passing in a list, thus i redefine the export macro here in hope it won't mess up other targets
|
||||
add_definitions( "-D${PLUGIN_EXPORT_MACRO}" )
|
||||
|
||||
set_target_properties(${target} PROPERTIES COMPILE_DEFINITIONS ${PLUGIN_COMPILE_DEFINITIONS})
|
||||
endif()
|
||||
|
||||
# add link targets
|
||||
target_link_libraries(${target} tomahawklib)
|
||||
if(PLUGIN_LINK_LIBRARIES)
|
||||
target_link_libraries(${target} ${PLUGIN_LINK_LIBRARIES})
|
||||
endif()
|
||||
|
||||
# make installation optional, maybe useful for dummy plugins one day
|
||||
if(NOT PLUGIN_NO_INSTALL)
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
endmacro()
|
@@ -5,40 +5,32 @@
|
||||
# LIBJREEN_LIBRARY, the path to libjreen
|
||||
# LIBJREEN_FOUND, whether libjreen was found
|
||||
|
||||
FIND_PACKAGE(PkgConfig QUIET)
|
||||
PKG_CHECK_MODULES(PC_JREEN QUIET libjreen)
|
||||
|
||||
find_path(LIBJREEN_INCLUDE_DIR NAMES jreen/jreen.h
|
||||
HINTS
|
||||
~/usr/include
|
||||
/opt/local/include
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/kde4/include
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
${KDE4_INCLUDE_DIR}
|
||||
FIND_PATH(JREEN_INCLUDE_DIR NAMES jreen/jreen.h
|
||||
HINTS
|
||||
${PC_JREEN_INCLUDEDIR}
|
||||
${PC_JREEN_INCLUDE_DIRS}
|
||||
${CMAKE_INSTALL_INCLUDEDIR}
|
||||
${KDE4_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
find_library( LIBJREEN_LIBRARY NAMES jreen
|
||||
PATHS
|
||||
~/usr/lib
|
||||
/opt/local/lib
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
/usr/local/lib
|
||||
/opt/kde4/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib64
|
||||
${KDE4_LIB_DIR}
|
||||
FIND_LIBRARY(JREEN_LIBRARIES NAMES jreen
|
||||
HINTS
|
||||
${PC_JREEN_LIBDIR}
|
||||
${PC_JREEN_LIBRARY_DIRS}
|
||||
${CMAKE_INSTALL_LIBDIR}
|
||||
${KDE4_LIB_DIR}
|
||||
)
|
||||
|
||||
IF(JREEN_LIBRARIES AND JREEN_INCLUDE_DIR AND NOT PC_JREEN_VERSION)
|
||||
MESSAGE(WARNING "You don't have pkg-config and so the Jreen version check does not work!")
|
||||
ENDIF()
|
||||
|
||||
if(LIBJREEN_INCLUDE_DIR AND LIBJREEN_LIBRARY)
|
||||
set(LIBJREEN_FOUND TRUE)
|
||||
message(STATUS "Found libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}")
|
||||
else(LIBJREEN_INCLUDE_DIR AND LIBJREEN_LIBRARY)
|
||||
set(LIBJREEN_FOUND FALSE)
|
||||
if (LIBJREEN_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could NOT find required package libjreen")
|
||||
endif(LIBJREEN_FIND_REQUIRED)
|
||||
endif(LIBJREEN_INCLUDE_DIR AND LIBJREEN_LIBRARY)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Jreen
|
||||
REQUIRED_VARS JREEN_LIBRARIES JREEN_INCLUDE_DIR
|
||||
VERSION_VAR PC_JREEN_VERSION)
|
||||
|
||||
mark_as_advanced(LIBJREEN_INCLUDE_DIR LIBJREEN_LIBRARY)
|
||||
MARK_AS_ADVANCED(JREEN_INCLUDE_DIR JREEN_LIBRARIES)
|
||||
|
@@ -38,7 +38,9 @@ else (QCA2_INCLUDE_DIR AND QCA2_LIBRARIES)
|
||||
|
||||
find_path(QCA2_INCLUDE_DIR qca.h
|
||||
HINTS ${PC_QCA2_INCLUDEDIR} ${PC_QCA2_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES QtCrypto)
|
||||
PATH_SUFFIXES QtCrypto
|
||||
PATHS /usr/local/lib/qca.framework/Headers/
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(QCA2 DEFAULT_MSG QCA2_LIBRARIES QCA2_INCLUDE_DIR)
|
||||
|
@@ -56,7 +56,7 @@ ELSE()
|
||||
include(FindLibraryWithDebug)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(TAGLIB_CFLAGS
|
||||
find_path(TAGLIB_INCLUDES
|
||||
NAMES
|
||||
tag.h
|
||||
PATH_SUFFIXES taglib
|
||||
|
@@ -28,8 +28,8 @@
|
||||
|
||||
; We use official release plugins
|
||||
; mingw32-vlc from obs misses a lot and has even broken ones probably
|
||||
!define VLC_PATH "${SOURCE_PATH}\admin\win\vlc\prefix" ; SIC! ^
|
||||
!define VLC_BIN "${VLC_PATH}\bin"
|
||||
!define VLC_PATH "${SOURCE_PATH}\admin\win\vlc\" ; SIC! ^
|
||||
!define VLC_BIN "${VLC_PATH}"
|
||||
!define VLC_PLUGIN_PATH "${VLC_BIN}\plugins"
|
||||
|
||||
!define NSI_PATH "${SOURCE_PATH}/admin/win/nsi"
|
||||
@@ -279,9 +279,9 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
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"
|
||||
; plugins
|
||||
File "${INSTALL_PATH}\lib\libtomahawk_*_*.dll"
|
||||
!endif
|
||||
!ifndef INSTALL_PATH
|
||||
;Main executable.
|
||||
@@ -294,8 +294,8 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
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"
|
||||
; plugins
|
||||
File "${BUILD_PATH}\libtomahawk_*_*.dll"
|
||||
!endif
|
||||
|
||||
;License & release notes.
|
||||
@@ -307,8 +307,10 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
File "${QT_DLL_PATH}\QtGui4.dll"
|
||||
File "${QT_DLL_PATH}\QtNetwork4.dll"
|
||||
File "${QT_DLL_PATH}\QtSql4.dll"
|
||||
File "${QT_DLL_PATH}\QtXml4.dll"
|
||||
File "${QT_DLL_PATH}\QtScript4.dll"
|
||||
File "${QT_DLL_PATH}\QtUiTools4.dll"
|
||||
File "${QT_DLL_PATH}\QtWebKit4.dll"
|
||||
File "${QT_DLL_PATH}\QtXml4.dll"
|
||||
|
||||
;SQLite driver
|
||||
SetOutPath "$INSTDIR\sqldrivers"
|
||||
@@ -329,13 +331,12 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
File "${MING_BIN}\libstdc++-6.dll"
|
||||
|
||||
;Phonon stuff
|
||||
File "${VLC_BIN}\libphonon.dll"
|
||||
File "${MING_BIN}\libphonon.dll"
|
||||
SetOutPath "$INSTDIR\phonon_backend"
|
||||
File "${VLC_BIN}\phonon_backend\phonon_vlc.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
;VLC
|
||||
;SetOutPath "$INSTDIR\phonon_backend"
|
||||
File "${VLC_BIN}\libvlc.dll"
|
||||
File "${VLC_BIN}\libvlccore.dll"
|
||||
SetOutPath "$INSTDIR\plugins"
|
||||
@@ -351,6 +352,7 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
|
||||
File "${MING_BIN}\libechonest.dll"
|
||||
File "${MING_BIN}\libQTweetLib.dll"
|
||||
File "${MING_BIN}\libquazip.dll"
|
||||
|
||||
; Jabber
|
||||
File "${MING_BIN}\libjreen.dll"
|
||||
|
64
ChangeLog
@@ -1,3 +1,67 @@
|
||||
Version 0.5.0:
|
||||
* Added "Stop playback after this track" context menu items.
|
||||
* You can now import your entire Last.fm playback history into Tomahawk.
|
||||
* Support for multimedia keys (Play, Pause, Next etc.) on Windows & Linux.
|
||||
* When listening privately scrobbling to Last.fm is now disabled.
|
||||
* Added a toolbar with page back / forward buttons and the global search.
|
||||
* New grid view with direct playback controls.
|
||||
* Added a track page showing a song's lyrics and other similar tracks.
|
||||
* Separate Loved Tracks and Recently Played views per source.
|
||||
|
||||
Version 0.4.2:
|
||||
* Fix ZeroConf protocol showing IP addresses instead of host names.
|
||||
* Updated translations for various languages.
|
||||
* Resuming playback restores correct volume settings.
|
||||
* Reduced CPU usage during playback.
|
||||
* Fixed not starting up due to case sensitivity issue on OS X.
|
||||
* Fixed volume issue (too quiet) on Windows.
|
||||
|
||||
Version 0.4.1:
|
||||
* Fixed various crashes.
|
||||
* Fixed issues with auto-updating XSPF playlists.
|
||||
* Double-clicking a playlist starts playing it.
|
||||
* Resolvers can now return disc number and album position for results.
|
||||
* Fixed sorting playlists by track number.
|
||||
* Fixed issues with changing proxy.
|
||||
* Fixed Twitter authentication issues.
|
||||
* Fixed Grooveshark support on Windows.
|
||||
|
||||
Version 0.4.0:
|
||||
* Added visual notification for database indexing job.
|
||||
* Fixed icons not appearing in resolvers list.
|
||||
* Fixed various UI glitches and stray error messages in stations.
|
||||
* Fixed bug where album page would resolve bottom-to-top.
|
||||
* Fixed bug where Footnotes would not update when changing selected album.
|
||||
* Fixed dragging albums and artists from charts, album, and artist views.
|
||||
* Fixed bug where filter text would be one step behind filter value.
|
||||
* Fixed bug where resolvers would enable themselves after auto-updating.
|
||||
* Fixed occasional crash when dropping tracks onto New Station item.
|
||||
* Added jump-to-current-track support for search results page.
|
||||
* Fixed non-resolving tracks when dragging from album view.
|
||||
* Fixed fetching album covers for albums with special characters.
|
||||
* Show errors and continue gracefully when resolved audio is not available.
|
||||
* Fixed various crashes on exit.
|
||||
* Added basic command-line options for playback control.
|
||||
* Bumped up web api timeouts to allow web clients to finish resolving.
|
||||
* Added filename suggestion when exporting a playlist.
|
||||
* Cleaned up highlighting of artist names in album view.
|
||||
* Cleaned up alignment of playlist items.
|
||||
* Fixed potential crash when searching.
|
||||
* Added support for disc number.
|
||||
* Added SoundCloudWall.com charts.
|
||||
* Added ability to "lock on" to a user when listening along, to skip along.
|
||||
* Fixed bug where loved tracks would be refreshed much too often.
|
||||
* Fixed some font size issues.
|
||||
* Sped up Tomahawk startup by moving chart loading into a separate thread.
|
||||
* Added support for parsing Grooveshark and Tinysong tracks and playlists.
|
||||
* Reorganized sidebar to follow more logical item groupings.
|
||||
* Added artist and album results to global searches.
|
||||
* Fixed style and contrast issues when using GTK styles.
|
||||
* Fixed paths to artwork when using MPRIS2 interface.
|
||||
* Fixed out of sync Show/Hide menu items on OS X when hidden with cmd-h.
|
||||
* Fixed /Volumes directory not showing up on OS X.
|
||||
* Fixed startup crash on OS X.
|
||||
|
||||
Version 0.3.3:
|
||||
* Automatically load Super Collection tracks when no official release
|
||||
information is available.
|
||||
|
12
README
@@ -13,7 +13,7 @@ Compiling Tomahawk
|
||||
|
||||
Detailed building instructions for Ubuntu
|
||||
-----------------------------------------
|
||||
See: http://wiki.tomahawk-player.org/mediawiki/index.php/Building_Ubuntu_Binary_on_Maverick_(10.10)
|
||||
See: http://wiki.tomahawk-player.org/mediawiki/index.php/Building_Ubuntu_Binary_on_Precise_(12.04)
|
||||
|
||||
Detailed building instructions for OS X
|
||||
---------------------------------------
|
||||
@@ -27,7 +27,7 @@ Doxygen Documentation
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
CMake 2.8.0 - http://www.cmake.org/
|
||||
CMake 2.8.6 - 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/
|
||||
@@ -38,14 +38,14 @@ Dependencies
|
||||
|
||||
The following dependencies are optional, but recommended:
|
||||
|
||||
Attica 0.2.0 - ftp://ftp.kde.org/pub/kde/stable/attica/
|
||||
Jreen 1.0.1 - https://github.com/euroelessar/jreen
|
||||
QTweetLib 0.3.0 - https://github.com/minimoog/QTweetLib
|
||||
Attica 0.3.0 - ftp://ftp.kde.org/pub/kde/stable/attica/
|
||||
QuaZip 0.4.3 - http://quazip.sourceforge.net/
|
||||
Jreen 1.0.5 - http://qutim.org/jreen / https://github.com/euroelessar/jreen
|
||||
QTweetLib 0.5.0 - https://github.com/minimoog/QTweetLib
|
||||
|
||||
Third party libraries that we ship with our source:
|
||||
|
||||
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,6 +1,6 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# This file is part of Clementine.
|
||||
# This file is part of Tomahawk.
|
||||
# It was inspired in large part by the macdeploy script in Clementine.
|
||||
#
|
||||
# Clementine is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -199,11 +199,10 @@ QT_PLUGINS = [
|
||||
]
|
||||
|
||||
TOMAHAWK_PLUGINS = [
|
||||
'libtomahawk_sipjabber.dylib',
|
||||
'libtomahawk_sipgoogle.dylib',
|
||||
'libtomahawk_siptwitter.dylib',
|
||||
'libtomahawk_sipzeroconf.dylib',
|
||||
'libtomahawk_qtweetlib.dylib',
|
||||
'libtomahawk_account_xmpp.so',
|
||||
'libtomahawk_account_google.so',
|
||||
'libtomahawk_account_twitter.so',
|
||||
'libtomahawk_account_zeroconf.so',
|
||||
]
|
||||
|
||||
QT_PLUGINS_SEARCH_PATH=[
|
||||
@@ -250,7 +249,7 @@ frameworks_dir = os.path.join(bundle_dir, 'Contents', 'Frameworks')
|
||||
commands.append(['mkdir', '-p', frameworks_dir])
|
||||
resources_dir = os.path.join(bundle_dir, 'Contents', 'Resources')
|
||||
commands.append(['mkdir', '-p', resources_dir])
|
||||
plugins_dir = os.path.join(bundle_dir, 'Contents', 'plugins')
|
||||
plugins_dir = os.path.join(bundle_dir, 'Contents', 'PlugIns')
|
||||
binary = os.path.join(bundle_dir, 'Contents', 'MacOS', bundle_name)
|
||||
|
||||
fixed_libraries = []
|
||||
@@ -491,16 +490,11 @@ def FindVLCPlugin(name):
|
||||
FixBinary(binary)
|
||||
|
||||
for plugin in VLC_PLUGINS:
|
||||
FixVLCPlugin(FindVLCPlugin(plugin), '.')
|
||||
FixVLCPlugin(FindVLCPlugin(plugin), '../Frameworks/vlc/plugins')
|
||||
|
||||
for plugin in TOMAHAWK_PLUGINS:
|
||||
FixPlugin(plugin, '../MacOS')
|
||||
|
||||
try:
|
||||
FixPlugin('spotify_tomahawkresolver', '../MacOS')
|
||||
except:
|
||||
print 'Failed to find spotify resolver'
|
||||
|
||||
try:
|
||||
FixPlugin('tomahawk_crash_reporter', '../MacOS')
|
||||
except:
|
||||
|
@@ -3,9 +3,12 @@ SET(MINGW_PREFIX "i686-w64-mingw32")
|
||||
# this one is important
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
|
||||
|
||||
# specify the cross compiler
|
||||
SET(CMAKE_C_COMPILER ccache ${MINGW_PREFIX}-gcc)
|
||||
SET(CMAKE_C_FLAGS "-fno-keep-inline-dllexport")
|
||||
SET(CMAKE_CXX_COMPILER ccache ${MINGW_PREFIX}-g++)
|
||||
SET(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS})
|
||||
SET(CMAKE_RC_COMPILER /usr/bin/${MINGW_PREFIX}-windres)
|
||||
|
||||
# where is the target environment containing libraries
|
||||
@@ -15,13 +18,6 @@ SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
|
||||
|
||||
|
||||
# libs with broken find modules
|
||||
SET(TAGLIB_FOUND true)
|
||||
SET(TAGLIB_LIBRARIES ${CMAKE_FIND_ROOT_PATH}/lib/libtag.dll.a)
|
||||
SET(TAGLIB_INCLUDES ${CMAKE_FIND_ROOT_PATH}/include/taglib)
|
||||
|
||||
# configure qt variables
|
||||
SET(QT_LIBRARY_DIR /usr/${MINGW_PREFIX}/bin)
|
||||
SET(QT_PLUGINS_DIR ${CMAKE_FIND_ROOT_PATH}/lib/qt4/plugins/)
|
||||
SET(QT_QTUITOOLS_LIBRARY_RELEASE ${CMAKE_FIND_ROOT_PATH}/lib/libQtUiTools.a)
|
||||
SET(QT_QTUITOOLS_LIBRARY_DEBUG ${CMAKE_FIND_ROOT_PATH}/lib/libQtUiToolsd.a)
|
||||
SET(QT_QTUITOOLS_LIBRARY ${QT_QTUITOOLS_LIBRARY_RELEASE})
|
@@ -1,51 +1,52 @@
|
||||
#!/bin/bash
|
||||
mkdir -p vlc/
|
||||
|
||||
if [ "$1" = "-c" ] ; then
|
||||
echo "Continuing last download.."
|
||||
rm -rvf vlc/prefix/
|
||||
rm -rvf vlc/
|
||||
else
|
||||
echo "Remove old vlc dir..."
|
||||
rm -rvf vlc/*
|
||||
echo "Update archive..."
|
||||
fi
|
||||
|
||||
cd vlc/
|
||||
rm -rvf vlc/
|
||||
|
||||
|
||||
echo "Download phonon archive..."
|
||||
#wget -c "http://downloads.sourceforge.net/project/vlc/1.1.9/win32/vlc-1.1.9-win32.7z?r=http%3A%2F%2Fwww.videolan.org%2Fvlc%2Fdownload-windows.html&ts=1306272584&use_mirror=leaseweb"
|
||||
#wget -c "http://download.tomahawk-player.org/tomahawk-vlc-0.1.zip"
|
||||
#wget -c http://people.videolan.org/~jb/phonon/phonon-vlc-last.7z
|
||||
wget -c http://people.videolan.org/~jb/phonon/phonon_phonon-vlc_20111128.7z
|
||||
# wget -c "http://downloads.sourceforge.net/project/vlc/1.1.9/win32/vlc-1.1.9-win32.7z?r=http%3A%2F%2Fwww.videolan.org%2Fvlc%2Fdownload-windows.html&ts=1306272584&use_mirror=leaseweb"
|
||||
# wget -c "http://download.tomahawk-player.org/tomahawk-vlc-0.1.zip"
|
||||
# wget -c http://people.videolan.org/~jb/phonon/phonon-vlc-last.7z
|
||||
# wget -c http://people.videolan.org/~jb/phonon/phonon_phonon-vlc_20111128.7z
|
||||
wget -c http://download.tomahawk-player.org/test/pvlc.tar.bz2
|
||||
|
||||
echo "Extract binary..."
|
||||
7z x phonon*.7z
|
||||
#mv -v vlc-*/ vlc/
|
||||
#unzip tomahawk-vlc-0.1.zip
|
||||
# 7z x phonon*.7z
|
||||
# mv -v vlc-*/ vlc/
|
||||
# unzip tomahawk-vlc-0.1.zip
|
||||
tar xvjf pvlc.tar.bz2
|
||||
|
||||
echo "Download phonon_vlc_no_video.dll..."
|
||||
wget -c http://people.videolan.org/~jb/phonon/phonon_vlc_no_video.dll
|
||||
cp -v phonon_vlc_no_video.dll prefix/bin/phonon_backend/phonon_vlc.dll
|
||||
# echo "Download phonon_vlc_no_video.dll..."
|
||||
# wget -c http://people.videolan.org/~jb/phonon/phonon_vlc_no_video.dll
|
||||
# cp -v phonon_vlc_no_video.dll prefix/bin/phonon_backend/phonon_vlc.dll
|
||||
|
||||
echo "Strip unneeded plugins from vlc/plugins..."
|
||||
cd prefix/bin/plugins
|
||||
rm -rvf libold* libvcd* libdvd* liblibass* libx264* libschroe* liblibmpeg2* \
|
||||
libstream_out_* libmjpeg_plugin* libh264_plugin* libzvbi_plugin* lib*sub* \
|
||||
*qt4* *skins2* libaccess_bd_plugin.dll \
|
||||
libaudiobargraph_* libball_plugin.dll \
|
||||
libdirac_plugin.dll \
|
||||
libgnutls_plugin.dll \
|
||||
libcaca_plugin.dll \
|
||||
libfreetype_plugin.dll \
|
||||
libaccess_output_shout_plugin.dll \
|
||||
libremoteosd_plugin.dll \
|
||||
libsdl_image_plugin.dll \
|
||||
libvout_sdl_plugin.dll \
|
||||
libpng_plugin.dll \
|
||||
libgoom_plugin.dll \
|
||||
libatmo_plugin.dll \
|
||||
libmux_ts_plugin.dll \
|
||||
libkate_plugin.dll \
|
||||
libtaglib_plugin.dll
|
||||
# echo "Strip unneeded plugins from vlc/plugins..."
|
||||
# cd prefix/bin/plugins
|
||||
# rm -rvf libold* libvcd* libdvd* liblibass* libx264* libschroe* liblibmpeg2* \
|
||||
# libstream_out_* libmjpeg_plugin* libh264_plugin* libzvbi_plugin* lib*sub* \
|
||||
# *qt4* *skins2* libaccess_bd_plugin.dll \
|
||||
# libaudiobargraph_* libball_plugin.dll \
|
||||
# libdirac_plugin.dll \
|
||||
# libgnutls_plugin.dll \
|
||||
# libcaca_plugin.dll \
|
||||
# libfreetype_plugin.dll \
|
||||
# libaccess_output_shout_plugin.dll \
|
||||
# libremoteosd_plugin.dll \
|
||||
# libsdl_image_plugin.dll \
|
||||
# libvout_sdl_plugin.dll \
|
||||
# libpng_plugin.dll \
|
||||
# libgoom_plugin.dll \
|
||||
# libatmo_plugin.dll \
|
||||
# libmux_ts_plugin.dll \
|
||||
# libkate_plugin.dll \
|
||||
# libtaglib_plugin.dll
|
||||
|
||||
|
||||
# this is for vlc-1.2
|
||||
|
BIN
data/icons/tomahawk-icon-128x128-grayscale.png
Normal file
After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 68 KiB |
BIN
data/images/album-placeholder-grid.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
BIN
data/images/artist-placeholder-grid.png
Normal file
After Width: | Height: | Size: 356 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 286 B |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 3.5 KiB |
BIN
data/images/collection.png
Normal file
After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
BIN
data/images/grooveshark.png
Normal file
After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.0 KiB |
BIN
data/images/jump-link.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
data/images/lastfm-icon.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 1.0 MiB |
BIN
data/images/new-releases.png
Normal file
After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 12 KiB |
BIN
data/images/playlist-header-tiled.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 68 KiB |
BIN
data/images/spotifycore-logo.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
BIN
data/images/track-icon.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 1.0 MiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
20
data/misc/tomahawk_pubkey.pem
Normal file
@@ -0,0 +1,20 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIDOzCCAi0GByqGSM44BAEwggIgAoIBAQDRltnNbKWFroVCsG1nTSdlTDmo7fjl
|
||||
tgOuQ0YB2s0a1bcqgQ5YJRE59pFvF/z2pkHEHdyBA6USd9N7/T9lolwNcJoByJpO
|
||||
MobUNs04elqZXliriaAdoSb2g6ZpxiedppbbyNP/BlK6o+zpyn0LVYXDI/OwJFzS
|
||||
xjGXM+rBEWdUJnogZxV31gF9W3yD1Quz6icBulT9V/Soo6me9Mc60ooKSYj4Zgqd
|
||||
3ln8tG90RFnWfbb0nbrITvR3ll6XXLfn081tjhymcXqHcgvaaqcmpKWL6ZWwX1mH
|
||||
3t1pImnif/tSSZPG21KGE3FtuQ/+YFo19apQ6U6l8kaSFxqcDLAYzBy9AhUA/QfN
|
||||
8WEIvzOEZ9uSWT7lYy64mUkCggEABsUmcs3kwjrmszIAAmPIowA0DBrxWZL03JBV
|
||||
bDKT6tNHZaFFlCufVSjiL1EFZjRARC16OWYaDcElUsZYFMcsNIIa8LyDQaq6+SSm
|
||||
quhMO5heeJiYPrutDiJzbJr0+HoY77Ll+Q4/cEkl0UAN4Ovp18WKwaq6GpHAvBnv
|
||||
71LunLGAKsVb5joXBQ8In6zQkibJhgiBJwzLK90/j0OTiDaaOwM3PsAegORBVlVE
|
||||
TAk4AQmawmF8nBGLzTyKXl83J571ku1Mm2JTl16jMYziKARKXYBmkcP1at0YddVK
|
||||
WWpAwRKSxOucVJYfV58JqmjZqst8BBeH6esQKr5dklUvvDMaEwOCAQYAAoIBAQCw
|
||||
5mo+8/R3S9cNYg9o8JNJGdSbMhSkurILHh9WNElsIC3RNtPcpijmAnWtXTVDhe6w
|
||||
77wLj37tUuFGbsu2qPXtZoup35emf9DDshZ5w5UOclPaZ9HYjlC1H64c6d66Rllk
|
||||
fY6FRDv9qVfjT84APbvMDrk6csJ5YHxFPDaqeQaFB0nxFiCMVwjEx+ZSvQNK1jJ2
|
||||
o2gtuOvSPVSphsMeJ72DDNxO+SRRVnOmWaxg9rlmFuGle6Z+UJ2FItfmPEvhSBMY
|
||||
hzndUbC7Wi4sIpBzbm9O5MiPYMv0VmN+0t1156EiC9uR4f7AKH2S94dnQob/YeY0
|
||||
jMH+XxU/wzGUCmsOx1lx
|
||||
-----END PUBLIC KEY-----
|
3819
lang/tomahawk_ar.ts
Normal file
3848
lang/tomahawk_bg.ts
Normal file
3838
lang/tomahawk_ca.ts
Normal file
3157
lang/tomahawk_de.ts
3947
lang/tomahawk_en.ts
2664
lang/tomahawk_es.ts
3843
lang/tomahawk_fr.ts
Normal file
@@ -1,9 +1,14 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/lang">
|
||||
<file>tomahawk_en.qm</file>
|
||||
<file>tomahawk_bg.qm</file>
|
||||
<file>tomahawk_de.qm</file>
|
||||
<file>tomahawk_sv.qm</file>
|
||||
<file>tomahawk_es.qm</file>
|
||||
<file>tomahawk_fr.qm</file>
|
||||
<file>tomahawk_pl.qm</file>
|
||||
<file>tomahawk_pt_BR.qm</file>
|
||||
<file>tomahawk_ru.qm</file>
|
||||
<file>tomahawk_es.qm</file>
|
||||
<file>tomahawk_sv.qm</file>
|
||||
<file>tomahawk_ja.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
3817
lang/tomahawk_ja.ts
Normal file
3065
lang/tomahawk_pl.ts
3832
lang/tomahawk_ru.ts
Normal file
3684
lang/tomahawk_sv.ts
3815
lang/tomahawk_tr.ts
Normal file
3815
lang/tomahawk_zh_CN.ts
Normal file
3816
lang/tomahawk_zh_TW.ts
Normal file
@@ -1,7 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>data/images/avatar-dude-plus.png</file>
|
||||
<file>data/images/avatar-dude.png</file>
|
||||
<file>data/images/back-pressed.png</file>
|
||||
<file>data/images/back-rest.png</file>
|
||||
<file>data/images/filter.png</file>
|
||||
@@ -9,6 +7,8 @@
|
||||
<file>data/images/not-loved.png</file>
|
||||
<file>data/images/no-album-art-placeholder.png</file>
|
||||
<file>data/images/no-artist-image-placeholder.png</file>
|
||||
<file>data/images/artist-placeholder-grid.png</file>
|
||||
<file>data/images/album-placeholder-grid.png</file>
|
||||
<file>data/images/track-placeholder.png</file>
|
||||
<file>data/images/now-playing-panel.png</file>
|
||||
<file>data/images/now-playing-speaker.png</file>
|
||||
@@ -66,12 +66,10 @@
|
||||
<file>data/images/echonest_logo.png</file>
|
||||
<file>data/images/loading-animation.gif</file>
|
||||
<file>data/images/info.png</file>
|
||||
<file>data/images/home.png</file>
|
||||
<file>data/images/back.png</file>
|
||||
<file>data/images/forward.png</file>
|
||||
<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>
|
||||
@@ -87,6 +85,7 @@
|
||||
<file>data/images/station.png</file>
|
||||
<file>data/images/new-additions.png</file>
|
||||
<file>data/images/charts.png</file>
|
||||
<file>data/images/new-releases.png</file>
|
||||
<file>data/images/loved_playlist.png</file>
|
||||
<file>data/images/dashboard.png</file>
|
||||
<file>data/images/artist-icon.png</file>
|
||||
@@ -133,6 +132,15 @@
|
||||
<file>data/images/headphones-bigger.png</file>
|
||||
<file>data/images/no-album-no-case.png</file>
|
||||
<file>data/images/rdio.png</file>
|
||||
<file>data/images/grooveshark.png</file>
|
||||
<file>data/images/lastfm-icon.png</file>
|
||||
<file>data/images/spotifycore-logo.png</file>
|
||||
<file>data/images/playlist-header-tiled.png</file>
|
||||
<file>data/images/share.png</file>
|
||||
<file>data/sql/dbmigrate-27_to_28.sql</file>
|
||||
<file>data/images/process-stop.png</file>
|
||||
<file>data/icons/tomahawk-icon-128x128-grayscale.png</file>
|
||||
<file>data/images/collection.png</file>
|
||||
<file>data/misc/tomahawk_pubkey.pem</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
784
src/AccountDelegate.cpp
Normal file
@@ -0,0 +1,784 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011-2012 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 "AccountDelegate.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "accounts/AccountModel.h"
|
||||
#include "accounts/Account.h"
|
||||
#include "accounts/AccountManager.h"
|
||||
|
||||
#include "utils/TomahawkUtils.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/AnimatedSpinner.h"
|
||||
#include "utils/Closure.h"
|
||||
#include "Source.h"
|
||||
|
||||
#define CHILD_ACCOUNT_HEIGHT 24
|
||||
|
||||
#define PADDING 4
|
||||
#define PADDING_BETWEEN_STARS 2
|
||||
#define STAR_SIZE 12
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#define ROW_HEIGHT_MULTIPLIER 4.9
|
||||
#else
|
||||
#define ROW_HEIGHT_MULTIPLIER 5.7
|
||||
#endif
|
||||
|
||||
#define ICONSIZE 40
|
||||
#define WRENCH_SIZE 24
|
||||
#define SMALL_WRENCH_SIZE 16
|
||||
#define STATUS_ICON_SIZE 13
|
||||
#define CHECK_LEFT_EDGE 8
|
||||
#define REMOVE_ICON_SIZE 12
|
||||
|
||||
using namespace Tomahawk;
|
||||
using namespace Accounts;
|
||||
|
||||
AccountDelegate::AccountDelegate( QObject* parent )
|
||||
: QStyledItemDelegate ( parent )
|
||||
, m_accountRowHeight( -1 )
|
||||
, m_model( 0 )
|
||||
{
|
||||
|
||||
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_onlineIcon.load( RESPATH "images/sipplugin-online.png" );
|
||||
m_offlineIcon.load( RESPATH "images/sipplugin-offline.png" );
|
||||
m_removeIcon.load( RESPATH "images/list-remove.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_onlineIcon = m_onlineIcon.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
m_offlineIcon = m_offlineIcon.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
m_onHoverStar = m_onHoverStar.scaled( STAR_SIZE, STAR_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
m_removeIcon = m_removeIcon.scaled( REMOVE_ICON_SIZE, REMOVE_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
m_defaultCover = m_defaultCover.scaled( ICONSIZE, ICONSIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
}
|
||||
|
||||
|
||||
QSize
|
||||
AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() );
|
||||
if ( m_accountRowHeight < 0 )
|
||||
{
|
||||
// Haven't calculated normal item height yet, do it once and save it
|
||||
QStyleOptionViewItemV4 opt( option );
|
||||
initStyleOption( &opt, index );
|
||||
m_accountRowHeight = ROW_HEIGHT_MULTIPLIER * opt.fontMetrics.height();
|
||||
}
|
||||
|
||||
if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::UniqueFactory || rowType == AccountModel::CustomAccount )
|
||||
{
|
||||
|
||||
return QSize( 200, m_accountRowHeight );
|
||||
}
|
||||
else if ( rowType == AccountModel::TopLevelFactory )
|
||||
{
|
||||
// Make more space for each account we have to show.
|
||||
AccountFactory* fac = qobject_cast< AccountFactory* >( index.data( AccountModel::AccountData ).value< QObject* >() );
|
||||
if ( fac->isUnique() )
|
||||
return QSize( 200, m_accountRowHeight );
|
||||
|
||||
const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >();
|
||||
const QSize s = QSize( 200, m_accountRowHeight + 12 * accts.size()-1 );
|
||||
|
||||
if ( s != m_sizeHints[ index ] )
|
||||
const_cast< AccountDelegate* >( this )->sizeHintChanged( index ); // FU KTHBBQ
|
||||
|
||||
m_sizeHints[ index ] = s;
|
||||
return s;
|
||||
}
|
||||
|
||||
return QSize();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption( &opt, index );
|
||||
|
||||
// draw the background
|
||||
const QWidget* w = opt.widget;
|
||||
QStyle* style = w ? w->style() : QApplication::style();
|
||||
style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w );
|
||||
|
||||
painter->setRenderHint( QPainter::Antialiasing );
|
||||
|
||||
if ( m_model == 0 || m_model != index.model() )
|
||||
m_model = const_cast<QAbstractItemModel*>( index.model() );
|
||||
|
||||
QFont titleFont = opt.font;
|
||||
titleFont.setBold( true );
|
||||
titleFont.setPointSize( titleFont.pointSize() + 2 );
|
||||
const QFontMetrics titleMetrics( titleFont );
|
||||
|
||||
QFont authorFont = opt.font;
|
||||
authorFont.setItalic( true );
|
||||
authorFont.setPointSize( authorFont.pointSize() - 1 );
|
||||
#ifdef Q_OS_MAC
|
||||
authorFont.setPointSize( authorFont.pointSize() - 1 );
|
||||
#endif
|
||||
const QFontMetrics authorMetrics( authorFont );
|
||||
|
||||
QFont descFont = authorFont;
|
||||
descFont.setItalic( false );
|
||||
const QFontMetrics descMetrics( descFont );
|
||||
|
||||
QFont installFont = opt.font;
|
||||
installFont.setPointSize( installFont.pointSize() - 1 );
|
||||
const QFontMetrics installMetrics( descFont );
|
||||
|
||||
const int height = opt.rect.height();
|
||||
const int center = height / 2 + opt.rect.top();
|
||||
|
||||
// Left account enable/disable checkbox
|
||||
const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() );
|
||||
int leftEdge = PADDING;
|
||||
// draw checkbox first
|
||||
const int checkboxYPos = ( center ) - ( WRENCH_SIZE / 2 );
|
||||
QRect checkRect = QRect( leftEdge, checkboxYPos, WRENCH_SIZE, WRENCH_SIZE );
|
||||
QStyleOptionViewItemV4 opt2 = opt;
|
||||
opt2.rect = checkRect;
|
||||
|
||||
if ( !m_loadingSpinners.contains( index ) )
|
||||
{
|
||||
drawCheckBox( opt2, painter, opt.widget );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_ASSERT( m_loadingSpinners[ index ] );
|
||||
if ( m_loadingSpinners[ index ] )
|
||||
{
|
||||
const QPixmap pm = m_loadingSpinners[index]->pixmap();
|
||||
painter->drawPixmap( checkRect, pm );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
leftEdge += WRENCH_SIZE + PADDING / 2;
|
||||
|
||||
// Pixmap
|
||||
QPixmap p = index.data( Qt::DecorationRole ).value< QPixmap >();
|
||||
QRect pixmapRect( leftEdge + PADDING, center - ICONSIZE/2, ICONSIZE, ICONSIZE );
|
||||
if ( p.isNull() ) // default image... TODO
|
||||
p = m_defaultCover;
|
||||
else
|
||||
p = p.scaled( pixmapRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
painter->drawPixmap( pixmapRect, p );
|
||||
|
||||
// Draw config wrench if there is one
|
||||
const bool hasConfigWrench = index.data( AccountModel::HasConfig ).toBool();
|
||||
int rightEdge = opt.rect.right();
|
||||
m_cachedConfigRects[ index ] = QRect();
|
||||
if ( hasConfigWrench )
|
||||
{
|
||||
const QRect confRect = QRect( rightEdge - 2*PADDING - WRENCH_SIZE, center - WRENCH_SIZE / 2, WRENCH_SIZE, WRENCH_SIZE );
|
||||
QStyleOptionToolButton topt;
|
||||
topt.rect = confRect;
|
||||
topt.pos = confRect.topLeft();
|
||||
|
||||
drawConfigWrench( painter, opt, topt );
|
||||
|
||||
m_cachedConfigRects[ index ] = confRect;
|
||||
rightEdge = confRect.left();
|
||||
|
||||
}
|
||||
|
||||
// Draw individual accounts and add account button for factories
|
||||
m_cachedButtonRects[ index ] = QRect();
|
||||
|
||||
bool canDelete = index.data( AccountModel::CanDeleteRole ) .toBool();
|
||||
if ( rowType == Tomahawk::Accounts::AccountModel::TopLevelFactory )
|
||||
{
|
||||
const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >();
|
||||
|
||||
QRect btnRect;
|
||||
const QString btnText = tr( "Add Account" );
|
||||
const int btnWidth = installMetrics.width( btnText ) + 2*PADDING;
|
||||
|
||||
if ( accts.isEmpty() )
|
||||
{
|
||||
Q_ASSERT( !hasConfigWrench );
|
||||
|
||||
// Draw button in center of row
|
||||
btnRect= QRect( opt.rect.right() - PADDING - btnWidth, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 2*PADDING );
|
||||
rightEdge = btnRect.left();
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->save();
|
||||
painter->setFont( installFont );
|
||||
rightEdge = drawAccountList( painter, opt, accts, rightEdge );
|
||||
painter->restore();
|
||||
|
||||
btnRect = QRect( opt.rect.right() - PADDING - btnWidth, opt.rect.bottom() - installMetrics.height() - 3*PADDING, btnWidth, installMetrics.height() + 2*PADDING );
|
||||
#ifdef Q_WS_MAC
|
||||
btnRect.adjust( -4, 0, 4, 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
leftEdge = btnRect.left();
|
||||
m_cachedButtonRects[ index ] = btnRect;
|
||||
|
||||
painter->save();
|
||||
painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) );
|
||||
|
||||
drawRoundedButton( painter, btnRect );
|
||||
|
||||
painter->setFont( installFont );
|
||||
painter->drawText( btnRect, Qt::AlignCenter, btnText );
|
||||
painter->restore();
|
||||
}
|
||||
else if ( rowType == AccountModel::UniqueFactory )
|
||||
{
|
||||
// Display as usual, except if it has an account, show the status.
|
||||
const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >();
|
||||
if ( !accts.isEmpty() )
|
||||
{
|
||||
Q_ASSERT( accts.size() == 1 );
|
||||
|
||||
rightEdge = drawStatus( painter, QPointF( rightEdge, center - painter->fontMetrics().height()/2 ), accts.first(), true );
|
||||
}
|
||||
|
||||
}
|
||||
else if ( canDelete )
|
||||
{
|
||||
const QString btnText = tr( "Remove Account" );
|
||||
const int btnWidth = installMetrics.width( btnText ) + 2*PADDING;
|
||||
QRect btnRect;
|
||||
|
||||
if ( hasConfigWrench )
|
||||
btnRect = QRect( opt.rect.right() - PADDING - btnWidth, opt.rect.bottom() - installMetrics.height() - 3*PADDING, btnWidth, installMetrics.height() + 2*PADDING );
|
||||
else
|
||||
btnRect = QRect( opt.rect.right() - PADDING - btnWidth, center - ( installMetrics.height() + 4 ) / 2, btnWidth, installMetrics.height() + 2*PADDING );
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
btnRect.adjust( -4, 2, 4, -2 );
|
||||
#endif
|
||||
leftEdge = btnRect.left();
|
||||
m_cachedButtonRects[ index ] = btnRect;
|
||||
|
||||
painter->save();
|
||||
painter->setPen( opt.palette.color( QPalette::Active, QPalette::AlternateBase ) );
|
||||
|
||||
drawRoundedButton( painter, btnRect, true );
|
||||
|
||||
painter->setFont( installFont );
|
||||
painter->drawText( btnRect, Qt::AlignCenter, btnText );
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
// Draw the title and description
|
||||
// title
|
||||
QString title = index.data( Qt::DisplayRole ).toString();
|
||||
const int rightTitleEdge = rightEdge - PADDING;
|
||||
const int leftTitleEdge = pixmapRect.right() + PADDING;
|
||||
painter->setFont( titleFont );
|
||||
QRect textRect;
|
||||
const bool canRate = index.data( AccountModel::CanRateRole ).toBool();
|
||||
if ( canRate )
|
||||
{
|
||||
textRect = QRect( leftTitleEdge, opt.rect.top() + PADDING, rightTitleEdge - leftTitleEdge, painter->fontMetrics().height() );
|
||||
}
|
||||
else
|
||||
{
|
||||
textRect = QRect( leftTitleEdge, opt.rect.top() + PADDING, rightTitleEdge - leftTitleEdge, center - opt.rect.top() - PADDING );
|
||||
}
|
||||
painter->drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, title );
|
||||
|
||||
// author
|
||||
QString author = index.data( AccountModel::AuthorRole ).toString();
|
||||
int runningBottom = textRect.bottom();
|
||||
if ( !author.isEmpty() && canRate )
|
||||
{
|
||||
painter->save();
|
||||
painter->setFont( authorFont );
|
||||
painter->setPen( QColor( Qt::gray ).darker( 150 ) );
|
||||
const int authorWidth = authorMetrics.width( author );
|
||||
const QRect authorRect( textRect.left(), textRect.bottom() + PADDING/2, authorWidth + 6, authorMetrics.height() );
|
||||
painter->drawText( authorRect, Qt::AlignLeft | Qt::AlignVCenter, author );
|
||||
painter->restore();
|
||||
|
||||
runningBottom = authorRect.bottom();
|
||||
}
|
||||
|
||||
// description
|
||||
QString desc = index.data( AccountModel::DescriptionRole ).toString();
|
||||
const int descWidth = rightEdge - leftTitleEdge - PADDING;
|
||||
painter->setFont( descFont );
|
||||
const QRect descRect( leftTitleEdge, runningBottom + PADDING, descWidth, painter->fontMetrics().height() );
|
||||
desc = painter->fontMetrics().elidedText( desc, Qt::ElideRight, descWidth );
|
||||
painter->drawText( descRect, Qt::AlignLeft | Qt::TextWordWrap | Qt::AlignTop, desc );
|
||||
runningBottom = descRect.bottom();
|
||||
|
||||
if ( index.data( AccountModel::CanRateRole ).toBool() )
|
||||
{
|
||||
// rating stars
|
||||
const int rating = index.data( AccountModel::RatingRole ).toInt();
|
||||
|
||||
// int runningEdge = opt.rect.right() - 2*PADDING - ratingWidth;
|
||||
int runningEdge = textRect.left();
|
||||
// int starsTop = opt.rect.bottom() - 3*PADDING - m_ratingStarNegative.height();
|
||||
int starsTop = runningBottom + PADDING;
|
||||
for ( int i = 1; i < 6; i++ )
|
||||
{
|
||||
QRect r( runningEdge, starsTop, m_ratingStarPositive.width(), m_ratingStarPositive.height() );
|
||||
// QRect r( runningEdge, opt.rect.top() + PADDING, m_ratingStarPositive.width(), m_ratingStarPositive.height() );
|
||||
if ( i == 1 )
|
||||
m_cachedStarRects[ index ] = r;
|
||||
|
||||
const bool userHasRated = index.data( AccountModel::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
|
||||
QString count = tr( "%1 downloads" ).arg( index.data( AccountModel::DownloadCounterRole ).toInt() );
|
||||
painter->setFont( descFont );
|
||||
const int countW = painter->fontMetrics().width( count );
|
||||
const QRect countRect( runningEdge + 50, starsTop, countW, painter->fontMetrics().height() );
|
||||
count = painter->fontMetrics().elidedText( count, Qt::ElideRight, rightEdge - PADDING - countRect.left() );
|
||||
painter->drawText( countRect, Qt::AlignLeft | Qt::TextWordWrap, count );
|
||||
// runningEdge = authorRect.x();
|
||||
}
|
||||
|
||||
// Title and description!
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
AccountDelegate::drawAccountList( QPainter* painter, QStyleOptionViewItemV4& opt, const QList< Account* > accts, int rightEdge ) const
|
||||
{
|
||||
// list each account name, and show the online, offline icon
|
||||
const int textHeight = painter->fontMetrics().height() + 1;
|
||||
const int mid = opt.rect.bottom() - opt.rect.height() / 2;
|
||||
int runningRightEdge = rightEdge;
|
||||
int current = 0;
|
||||
|
||||
int leftOfAccounts = rightEdge;
|
||||
|
||||
if ( accts.size() % 2 == 1 )
|
||||
{
|
||||
// If there's an odd number, the center one is centered
|
||||
current = mid - ((textHeight + PADDING/2) * (accts.size()/2) ) - textHeight / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Even number, center between the middle ones
|
||||
current = mid - ((textHeight + PADDING/2) * (accts.size()/2) );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < accts.size(); i++ )
|
||||
{
|
||||
// draw lightbulb and text
|
||||
runningRightEdge = drawStatus( painter, QPointF( rightEdge - PADDING, current), accts.at( i ) );
|
||||
|
||||
const QString label = accts.at( i )->accountFriendlyName();
|
||||
const QPoint textTopLeft( runningRightEdge - PADDING - painter->fontMetrics().width( label ), current);
|
||||
painter->drawText( QRect( textTopLeft, QSize( painter->fontMetrics().width( label ) + 1, textHeight ) ), label );
|
||||
|
||||
current += textHeight + PADDING/2;
|
||||
|
||||
leftOfAccounts = qMin( leftOfAccounts, textTopLeft.x() );
|
||||
}
|
||||
|
||||
return leftOfAccounts;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
|
||||
{
|
||||
if ( event->type() != QEvent::MouseButtonPress &&
|
||||
event->type() != QEvent::MouseButtonRelease &&
|
||||
event->type() != QEvent::MouseButtonDblClick &&
|
||||
event->type() != QEvent::MouseMove )
|
||||
return false;
|
||||
|
||||
if ( event->type() == QEvent::MouseButtonPress )
|
||||
{
|
||||
// Show the config wrench as depressed on click
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
if ( me->button() == Qt::LeftButton && m_cachedConfigRects.contains( index ) && m_cachedConfigRects[ index ].contains( me->pos() ) )
|
||||
{
|
||||
m_configPressed = index;
|
||||
|
||||
const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() );
|
||||
if ( rowType == AccountModel::TopLevelAccount ||
|
||||
rowType == AccountModel::CustomAccount )
|
||||
{
|
||||
Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() );
|
||||
Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account!
|
||||
|
||||
emit openConfig( acct );
|
||||
}
|
||||
else if ( rowType == AccountModel::TopLevelFactory )
|
||||
{
|
||||
AccountFactory* fac = qobject_cast< AccountFactory* >( index.data( AccountModel::AccountData ).value< QObject* >() );
|
||||
Q_ASSERT( fac ); // Should not be showing a config wrench if there is no account!
|
||||
emit openConfig( fac );
|
||||
}
|
||||
else if ( rowType == AccountModel::UniqueFactory )
|
||||
{
|
||||
const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >();
|
||||
|
||||
Q_ASSERT( !accts.isEmpty() ); // If there's no account, why is there a config widget for this factory?
|
||||
Q_ASSERT( accts.size() == 1 );
|
||||
emit openConfig( accts.first() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else if ( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick )
|
||||
{
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
if ( m_configPressed.isValid() )
|
||||
emit update( m_configPressed );
|
||||
|
||||
m_configPressed = QModelIndex();
|
||||
|
||||
if ( checkRectForIndex( option, index ).contains( me->pos() ) )
|
||||
{
|
||||
// Check box for this row
|
||||
|
||||
// eat the double click events inside the check rect
|
||||
if( event->type() == QEvent::MouseButtonDblClick ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() );
|
||||
Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked;
|
||||
return model->setData( index, newState, AccountModel::CheckboxClickedRole );
|
||||
}
|
||||
else if ( m_cachedButtonRects.contains( index ) && m_cachedButtonRects[ index ].contains( me->pos() ) )
|
||||
{
|
||||
// Install/create/etc button for this row
|
||||
model->setData( index, true, AccountModel::CustomButtonRole );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_cachedStarRects.contains( index ) )
|
||||
{
|
||||
QRect fullStars = m_cachedStarRects[ index ];
|
||||
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, AccountModel::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;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountDelegate::drawRoundedButton( QPainter* painter, const QRect& btnRect, bool red ) const
|
||||
{
|
||||
QPainterPath btnPath;
|
||||
const int radius = 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;
|
||||
if ( !red )
|
||||
{
|
||||
g.setColorAt( 0, QColor(54, 127, 211) );
|
||||
g.setColorAt( 0.5, QColor(43, 104, 182) );
|
||||
}
|
||||
else
|
||||
{
|
||||
g.setColorAt( 0, QColor(206, 63, 63) );
|
||||
g.setColorAt( 0.5, QColor(170, 52, 52) );
|
||||
}
|
||||
//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 );
|
||||
|
||||
if ( !red )
|
||||
{
|
||||
g.setColorAt( 0, QColor(34, 85, 159) );
|
||||
g.setColorAt( 0.5, QColor(35, 79, 147) );
|
||||
}
|
||||
else
|
||||
{
|
||||
g.setColorAt( 0, QColor(150, 50, 50) );
|
||||
g.setColorAt( 0.5, QColor(130, 40, 40) );
|
||||
}
|
||||
painter->fillPath( btnPath, g );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
AccountDelegate::drawStatus( QPainter* painter, const QPointF& rightTopEdge, Account* acct, bool drawText ) const
|
||||
{
|
||||
QPixmap p;
|
||||
QString statusText;
|
||||
const Account::ConnectionState state = acct->connectionState();
|
||||
if ( state == Account::Connected )
|
||||
{
|
||||
p = m_onlineIcon;
|
||||
statusText = tr( "Online" );
|
||||
}
|
||||
else if ( state == Account::Connecting )
|
||||
{
|
||||
p = m_offlineIcon;
|
||||
statusText = tr( "Connecting..." );
|
||||
}
|
||||
else
|
||||
{
|
||||
p = m_offlineIcon;
|
||||
statusText = tr( "Offline" );
|
||||
}
|
||||
|
||||
const int yPos = rightTopEdge.y();
|
||||
const QRect connectIconRect( rightTopEdge.x() - STATUS_ICON_SIZE, yPos, STATUS_ICON_SIZE, STATUS_ICON_SIZE );
|
||||
|
||||
if ( state == Account::Connecting )
|
||||
{
|
||||
if ( !m_connectingSpinners.contains( acct ) )
|
||||
{
|
||||
AnimatedSpinner* anim = new AnimatedSpinner( connectIconRect.size(), true );
|
||||
_detail::Closure* closure = new _detail::Closure( anim, SIGNAL( requestUpdate() ), const_cast<AccountDelegate*>(this), SLOT( doUpdateIndexWithAccount( Tomahawk::Accounts::Account* ) ), C_ARG( Tomahawk::Accounts::Account*, acct ) );
|
||||
closure->setAutoDelete( false );
|
||||
|
||||
m_connectingSpinners[ acct ] = anim;
|
||||
}
|
||||
|
||||
const QPixmap pm = m_connectingSpinners[acct]->pixmap();
|
||||
painter->drawPixmap( connectIconRect, pm );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_connectingSpinners.contains( acct ) )
|
||||
delete m_connectingSpinners.take( acct );
|
||||
|
||||
painter->drawPixmap( connectIconRect, p );
|
||||
}
|
||||
|
||||
|
||||
int leftEdge = connectIconRect.x();
|
||||
if ( drawText )
|
||||
{
|
||||
int width = painter->fontMetrics().width( statusText );
|
||||
int statusTextX = connectIconRect.x() - PADDING - width;
|
||||
painter->drawText( QRect( statusTextX, yPos, width, painter->fontMetrics().height() ), statusText );
|
||||
|
||||
leftEdge = statusTextX;
|
||||
}
|
||||
|
||||
return leftEdge;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountDelegate::drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const
|
||||
{
|
||||
QStyle* style = w ? w->style() : QApplication::style();
|
||||
opt.checkState == Qt::Checked ? opt.state |= QStyle::State_On : opt.state |= QStyle::State_Off;
|
||||
style->drawPrimitive( QStyle::PE_IndicatorViewItemCheck, &opt, p, w );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountDelegate::drawConfigWrench ( QPainter* painter, QStyleOptionViewItemV4& opt, QStyleOptionToolButton& topt ) const
|
||||
{
|
||||
const QWidget* w = opt.widget;
|
||||
QStyle* style = w ? w->style() : QApplication::style();
|
||||
|
||||
// draw it the same size as the check belox
|
||||
topt.font = opt.font;
|
||||
topt.icon = QIcon( RESPATH "images/configure.png" );
|
||||
topt.iconSize = QSize( 14, 14 );
|
||||
topt.subControls = QStyle::SC_ToolButton;
|
||||
topt.activeSubControls = QStyle::SC_None;
|
||||
topt.features = QStyleOptionToolButton::None;
|
||||
bool pressed = ( m_configPressed == opt.index );
|
||||
topt.state = pressed ? QStyle::State_On : QStyle::State_Raised;
|
||||
if( opt.state & QStyle::State_MouseOver || pressed )
|
||||
topt.state |= QStyle::State_HasFocus;
|
||||
style->drawComplexControl( QStyle::CC_ToolButton, &topt, painter, w );
|
||||
}
|
||||
|
||||
|
||||
|
||||
QRect
|
||||
AccountDelegate::checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const
|
||||
{
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption( &opt, idx );
|
||||
|
||||
// Top level item, return the corresponding rect
|
||||
const int ypos = ( opt.rect.top() + opt.rect.height() / 2 ) - ( WRENCH_SIZE / 2 );
|
||||
const QRect checkRect = QRect( PADDING, ypos, WRENCH_SIZE, WRENCH_SIZE );
|
||||
|
||||
return checkRect;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
AccountDelegate::startInstalling( const QPersistentModelIndex& idx )
|
||||
{
|
||||
qDebug() << "START INSTALLING:" << idx.data( Qt::DisplayRole ).toString();
|
||||
QStyleOptionViewItemV4 opt;
|
||||
initStyleOption( &opt, idx );
|
||||
|
||||
AnimatedSpinner* anim = new AnimatedSpinner( checkRectForIndex( opt, idx ).size(), true );
|
||||
_detail::Closure* closure = NewClosure( anim, SIGNAL( requestUpdate() ), this, SLOT( doUpdateIndex( const QPersistentModelIndex& ) ), idx );
|
||||
closure->setAutoDelete( false );
|
||||
|
||||
m_loadingSpinners[ idx ] = anim;
|
||||
|
||||
update( idx );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountDelegate::doneInstalling ( const QPersistentModelIndex& idx )
|
||||
{
|
||||
qDebug() << "STOP INSTALLING:" << idx.data( Qt::DisplayRole ).toString();
|
||||
Q_ASSERT( m_loadingSpinners.contains( idx ) );
|
||||
if ( !m_loadingSpinners.contains( idx ) )
|
||||
return;
|
||||
|
||||
delete m_loadingSpinners.take( idx );
|
||||
|
||||
update( idx );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountDelegate::errorInstalling( const QPersistentModelIndex& idx )
|
||||
{
|
||||
// Just hide the loading spinner as we do after a successful install
|
||||
qDebug() << "ERROR INSTALLING index:" << idx;
|
||||
doneInstalling( idx );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountDelegate::doUpdateIndex( const QPersistentModelIndex& idx )
|
||||
{
|
||||
emit update( idx );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountDelegate::doUpdateIndexWithAccount( Account* account )
|
||||
{
|
||||
// Urgh, have to go through the list and check based on the type
|
||||
for ( int i = 0; i < m_model->rowCount(); i++ )
|
||||
{
|
||||
const QModelIndex index = m_model->index( i, 0, QModelIndex() );
|
||||
const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() );
|
||||
if ( rowType == AccountModel::TopLevelAccount ||
|
||||
rowType == AccountModel::CustomAccount )
|
||||
{
|
||||
Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() );
|
||||
|
||||
if ( account == acct )
|
||||
{
|
||||
emit update( index );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ( rowType == AccountModel::TopLevelFactory || rowType == AccountModel::UniqueFactory )
|
||||
{
|
||||
const QList< Account* > accts = index.data( AccountModel::ChildrenOfFactoryRole ).value< QList< Tomahawk::Accounts::Account* > >();
|
||||
if ( accts.contains( account ) )
|
||||
{
|
||||
emit update( index );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
90
src/AccountDelegate.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011-2012 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 ACCOUNTDELEGATE_H
|
||||
#define ACCOUNTDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include "accounts/AccountModel.h"
|
||||
|
||||
class AnimatedSpinner;
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
namespace Accounts
|
||||
{
|
||||
|
||||
class Account;
|
||||
|
||||
class AccountDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AccountDelegate( 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;
|
||||
|
||||
public slots:
|
||||
void startInstalling( const QPersistentModelIndex& idx );
|
||||
void doneInstalling ( const QPersistentModelIndex& idx );
|
||||
void errorInstalling ( const QPersistentModelIndex& idx );
|
||||
|
||||
|
||||
void doUpdateIndex( const QPersistentModelIndex& idx );
|
||||
|
||||
protected:
|
||||
virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
|
||||
|
||||
signals:
|
||||
void update( const QModelIndex& idx );
|
||||
void openConfig( Tomahawk::Accounts::Account* );
|
||||
void openConfig( Tomahawk::Accounts::AccountFactory* );
|
||||
|
||||
private slots:
|
||||
void doUpdateIndexWithAccount( Tomahawk::Accounts::Account* account );
|
||||
|
||||
private:
|
||||
void drawRoundedButton( QPainter* painter, const QRect& buttonRect, bool red = false ) const;
|
||||
// Returns new left edge
|
||||
int drawStatus( QPainter* painter, const QPointF& rightTopEdge, Account* acct, bool drawText = false ) const;
|
||||
void drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const;
|
||||
void drawConfigWrench( QPainter* painter, QStyleOptionViewItemV4& option, QStyleOptionToolButton& topt ) const;
|
||||
// returns new left edge
|
||||
int drawAccountList( QPainter* painter, QStyleOptionViewItemV4& option, const QList< Account* > accounts, int rightEdge ) const;
|
||||
|
||||
QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const;
|
||||
|
||||
QPixmap m_offlineIcon, m_onlineIcon, m_defaultCover, m_onHoverStar, m_ratingStarPositive, m_ratingStarNegative, m_removeIcon;
|
||||
int m_hoveringOver;
|
||||
QPersistentModelIndex m_hoveringItem, m_configPressed;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_cachedButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_cachedStarRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_cachedConfigRects;
|
||||
mutable QHash< QPersistentModelIndex, QSize > m_sizeHints;
|
||||
mutable QHash< QPersistentModelIndex, AnimatedSpinner* > m_loadingSpinners;
|
||||
mutable QHash< Account*, AnimatedSpinner* > m_connectingSpinners;
|
||||
mutable int m_accountRowHeight;
|
||||
|
||||
mutable QAbstractItemModel* m_model;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ACCOUNTDELEGATE_H
|
138
src/AccountFactoryWrapper.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/* === 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 "AccountFactoryWrapper.h"
|
||||
|
||||
#include "accounts/Account.h"
|
||||
#include "accounts/AccountManager.h"
|
||||
#include "GuiHelpers.h"
|
||||
#include "AccountFactoryWrapperDelegate.h"
|
||||
#include "DelegateConfigWrapper.h"
|
||||
#include "ui_AccountFactoryWrapper.h"
|
||||
#include "Source.h"
|
||||
|
||||
using namespace Tomahawk::Accounts;
|
||||
AccountFactoryWrapper::AccountFactoryWrapper( AccountFactory* factory, QWidget* parent )
|
||||
: QDialog( parent, Qt::Sheet )
|
||||
, m_factory( factory )
|
||||
, m_ui( new Ui_AccountFactoryWrapper )
|
||||
{
|
||||
m_ui->setupUi( this );
|
||||
|
||||
setWindowTitle( factory->prettyName() );
|
||||
|
||||
m_ui->factoryIcon->setPixmap( factory->icon() );
|
||||
m_ui->factoryDescription->setText( factory->description() );
|
||||
|
||||
m_addButton = m_ui->buttonBox->addButton( tr( "Add Account" ), QDialogButtonBox::ActionRole );
|
||||
|
||||
AccountFactoryWrapperDelegate* del = new AccountFactoryWrapperDelegate( m_ui->accountsList );
|
||||
m_ui->accountsList->setItemDelegate( del );
|
||||
|
||||
connect( del, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) );
|
||||
connect( del, SIGNAL( removeAccount( Tomahawk::Accounts::Account* ) ), this, SLOT( removeAccount( Tomahawk::Accounts::Account* ) ) );
|
||||
connect( del, SIGNAL( checkOrUncheck( QModelIndex, Tomahawk::Accounts::Account* , Qt::CheckState ) ), this, SLOT( accountCheckedOrUnchecked( QModelIndex ,Tomahawk::Accounts::Account* ,Qt::CheckState ) ) );
|
||||
load();
|
||||
|
||||
connect( m_ui->buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
|
||||
connect( m_ui->buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
|
||||
connect( m_ui->buttonBox, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( buttonClicked( QAbstractButton* ) ) );
|
||||
|
||||
|
||||
connect ( AccountManager::instance(), SIGNAL( added( Tomahawk::Accounts::Account* ) ), this, SLOT( load() ) );
|
||||
connect ( AccountManager::instance(), SIGNAL( removed( Tomahawk::Accounts::Account* ) ), this, SLOT( load() ) );
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
setContentsMargins( 0, 0, 0, 0 );
|
||||
m_ui->verticalLayout->setSpacing( 6 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
AccountFactoryWrapper::load()
|
||||
{
|
||||
m_ui->accountsList->clear();
|
||||
foreach ( Account* acc, AccountManager::instance()->accounts() )
|
||||
{
|
||||
if ( AccountManager::instance()->factoryForAccount( acc ) == m_factory )
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem( m_ui->accountsList );
|
||||
item->setData( 0, AccountRole, QVariant::fromValue< QObject *>( acc ) );
|
||||
item->setCheckState( 0, acc->enabled() ? Qt::Checked : Qt::Unchecked );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_ui->accountsList->model()->rowCount() == 0 )
|
||||
accept();
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
const int padding = 7;
|
||||
#else
|
||||
const int padding = 8;
|
||||
#endif
|
||||
const int height = m_ui->accountsList->model()->rowCount( QModelIndex() ) * ACCOUNT_ROW_HEIGHT + padding;
|
||||
|
||||
m_ui->accountsList->setFixedHeight( height );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountFactoryWrapper::openAccountConfig( Account* account )
|
||||
{
|
||||
TomahawkUtils::openAccountConfig( account, this, false );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountFactoryWrapper::removeAccount( Tomahawk::Accounts::Account* acct )
|
||||
{
|
||||
AccountManager::instance()->removeAccount( acct );
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
void
|
||||
AccountFactoryWrapper::accountCheckedOrUnchecked( const QModelIndex& index, Account* acct, Qt::CheckState newstate )
|
||||
{
|
||||
QTreeWidgetItem* item = m_ui->accountsList->topLevelItem( index.row() );
|
||||
Q_ASSERT( item );
|
||||
|
||||
if ( newstate == Qt::Checked )
|
||||
{
|
||||
item->setCheckState( 0, Qt::Checked );
|
||||
AccountManager::instance()->enableAccount( acct );
|
||||
}
|
||||
else if ( newstate == Qt::Unchecked )
|
||||
{
|
||||
item->setCheckState( 0, Qt::Unchecked );
|
||||
AccountManager::instance()->disableAccount( acct );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountFactoryWrapper::buttonClicked( QAbstractButton* button )
|
||||
{
|
||||
if ( button == m_addButton )
|
||||
{
|
||||
TomahawkUtils::createAccountFromFactory( m_factory, this );
|
||||
}
|
||||
else
|
||||
reject();
|
||||
}
|
||||
|
62
src/AccountFactoryWrapper.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* === 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 ACCOUNTFACTORYWRAPPER_H
|
||||
#define ACCOUNTFACTORYWRAPPER_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QModelIndex>
|
||||
|
||||
class QAbstractButton;
|
||||
namespace Tomahawk {
|
||||
namespace Accounts {
|
||||
class AccountFactory;
|
||||
class Account;
|
||||
}
|
||||
}
|
||||
|
||||
class Ui_AccountFactoryWrapper;
|
||||
|
||||
// class AccountFactoryWrapper_
|
||||
class AccountFactoryWrapper : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ExtraRoles {
|
||||
AccountRole = Qt::UserRole + 140
|
||||
};
|
||||
|
||||
explicit AccountFactoryWrapper( Tomahawk::Accounts::AccountFactory* factory, QWidget* parent = 0 );
|
||||
virtual ~AccountFactoryWrapper() {}
|
||||
|
||||
public slots:
|
||||
void openAccountConfig( Tomahawk::Accounts::Account* );
|
||||
void removeAccount( Tomahawk::Accounts::Account* );
|
||||
void accountCheckedOrUnchecked( const QModelIndex& , Tomahawk::Accounts::Account* , Qt::CheckState );
|
||||
|
||||
private slots:
|
||||
void buttonClicked( QAbstractButton* );
|
||||
void load();
|
||||
|
||||
private:
|
||||
Tomahawk::Accounts::AccountFactory* m_factory;
|
||||
Ui_AccountFactoryWrapper* m_ui;
|
||||
QPushButton* m_addButton;
|
||||
};
|
||||
|
||||
#endif // ACCOUNTFACTORYWRAPPER_H
|
110
src/AccountFactoryWrapper.ui
Normal file
@@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AccountFactoryWrapper</class>
|
||||
<widget class="QDialog" name="AccountFactoryWrapper">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>507</width>
|
||||
<height>150</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="factoryIcon">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="factoryDescription">
|
||||
<property name="text">
|
||||
<string>Description goes here</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="accountsList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="autoScroll">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerItem</enum>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="headerHidden">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="expandsOnDoubleClick">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
187
src/AccountFactoryWrapperDelegate.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/* === 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 "AccountFactoryWrapperDelegate.h"
|
||||
#include "accounts/Account.h"
|
||||
#include "AccountFactoryWrapper.h"
|
||||
#include "utils/TomahawkUtils.h"
|
||||
#include "Source.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
|
||||
using namespace Tomahawk::Accounts;
|
||||
|
||||
#define ICON_SIZE 15
|
||||
#define CONFIG_WRENCH_SIZE 20
|
||||
#define PADDING 4
|
||||
|
||||
AccountFactoryWrapperDelegate::AccountFactoryWrapperDelegate( QObject* parent )
|
||||
: QStyledItemDelegate( parent )
|
||||
{
|
||||
m_removePixmap.load( RESPATH "images/list-remove.png" );
|
||||
m_onlineIcon.load( RESPATH "images/sipplugin-online.png" );
|
||||
m_offlineIcon.load( RESPATH "images/sipplugin-offline.png" );
|
||||
|
||||
m_removePixmap = m_removePixmap.scaled( ICON_SIZE, ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
m_onlineIcon = m_onlineIcon.scaled( ICON_SIZE, ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
m_offlineIcon = m_offlineIcon.scaled( ICON_SIZE, ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
m_configIcon.addFile( RESPATH "images/configure.png", QSize( CONFIG_WRENCH_SIZE - 8, CONFIG_WRENCH_SIZE - 8 ) );
|
||||
}
|
||||
|
||||
void
|
||||
AccountFactoryWrapperDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption( &opt, index );
|
||||
|
||||
const int center = opt.rect.height() / 2 + opt.rect.top();
|
||||
const int topIcon = center - ICON_SIZE/2;
|
||||
|
||||
// draw the background
|
||||
const QWidget* w = opt.widget;
|
||||
QStyle* style = w ? w->style() : QApplication::style();
|
||||
style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w );
|
||||
|
||||
Account* acc = qobject_cast< Account* >( index.data( AccountFactoryWrapper::AccountRole ).value< QObject* >() );
|
||||
Q_ASSERT( acc );
|
||||
|
||||
// Checkbox on left edge, then text
|
||||
const QRect checkRect( PADDING/4, PADDING/4 + opt.rect.top(), opt.rect.height() - PADDING/4, opt.rect.height() - PADDING/4 );
|
||||
m_cachedCheckRects[ index ] = checkRect;
|
||||
QStyleOptionViewItemV4 opt2 = opt;
|
||||
opt2.rect = checkRect;
|
||||
opt.checkState == Qt::Checked ? opt2.state |= QStyle::State_On : opt2.state |= QStyle::State_Off;
|
||||
style->drawPrimitive( QStyle::PE_IndicatorViewItemCheck, &opt2, painter, w );
|
||||
|
||||
// name on left
|
||||
painter->drawText( opt.rect.adjusted( checkRect.right() + PADDING, PADDING, -PADDING, -PADDING ), Qt::AlignLeft | Qt::AlignVCenter, acc->accountFriendlyName() );
|
||||
|
||||
// remove, config, status on right
|
||||
const QRect pmRect( opt.rect.right() - PADDING - m_removePixmap.width(), topIcon, ICON_SIZE, ICON_SIZE );
|
||||
painter->drawPixmap( pmRect, m_removePixmap );
|
||||
m_cachedButtonRects[ index ] = pmRect;
|
||||
|
||||
const QRect confRect( pmRect.left() - PADDING - CONFIG_WRENCH_SIZE, center - CONFIG_WRENCH_SIZE/2, CONFIG_WRENCH_SIZE, CONFIG_WRENCH_SIZE );
|
||||
|
||||
QStyleOptionToolButton topt;
|
||||
topt.rect = confRect;
|
||||
topt.pos = confRect.topLeft();
|
||||
topt.font = opt.font;
|
||||
topt.icon = m_configIcon;
|
||||
topt.iconSize = QSize( CONFIG_WRENCH_SIZE - 8, CONFIG_WRENCH_SIZE - 8 );
|
||||
topt.subControls = QStyle::SC_ToolButton;
|
||||
topt.activeSubControls = QStyle::SC_None;
|
||||
topt.features = QStyleOptionToolButton::None;
|
||||
bool pressed = ( m_configPressed == opt.index );
|
||||
topt.state = pressed ? QStyle::State_On : QStyle::State_Raised;
|
||||
if( opt.state & QStyle::State_MouseOver || pressed )
|
||||
topt.state |= QStyle::State_HasFocus;
|
||||
style->drawComplexControl( QStyle::CC_ToolButton, &topt, painter, w );
|
||||
m_cachedConfigRects[ index ] = confRect;
|
||||
|
||||
QPixmap p;
|
||||
QString statusText;
|
||||
Account::ConnectionState state = acc->connectionState();
|
||||
if ( state == Account::Connected )
|
||||
{
|
||||
p = m_onlineIcon;
|
||||
statusText = tr( "Online" );
|
||||
}
|
||||
else if ( state == Account::Connecting )
|
||||
{
|
||||
p = m_offlineIcon;
|
||||
statusText = tr( "Connecting..." );
|
||||
}
|
||||
else
|
||||
{
|
||||
p = m_offlineIcon;
|
||||
statusText = tr( "Offline" );
|
||||
}
|
||||
|
||||
const QRect connectIconRect( confRect.left() - PADDING - ICON_SIZE, topIcon, ICON_SIZE, ICON_SIZE );
|
||||
painter->drawPixmap( connectIconRect, p );
|
||||
|
||||
int width = painter->fontMetrics().width( statusText );
|
||||
painter->drawText( QRect( connectIconRect.left() - PADDING - width, center - painter->fontMetrics().height()/2, width, painter->fontMetrics().height() ), statusText );
|
||||
|
||||
}
|
||||
|
||||
QSize
|
||||
AccountFactoryWrapperDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
|
||||
{
|
||||
return QSize( 200, ACCOUNT_ROW_HEIGHT );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AccountFactoryWrapperDelegate::editorEvent( QEvent* event, QAbstractItemModel*, const QStyleOptionViewItem&, const QModelIndex& index )
|
||||
{
|
||||
if ( event->type() != QEvent::MouseButtonPress &&
|
||||
event->type() != QEvent::MouseButtonRelease &&
|
||||
event->type() != QEvent::MouseButtonDblClick &&
|
||||
event->type() != QEvent::MouseMove )
|
||||
return false;
|
||||
|
||||
if ( event->type() == QEvent::MouseButtonPress )
|
||||
{
|
||||
// Show the config wrench as depressed on click
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
if ( me->button() == Qt::LeftButton && m_cachedConfigRects.contains( index ) && m_cachedConfigRects[ index ].contains( me->pos() ) )
|
||||
{
|
||||
m_configPressed = index;
|
||||
Account* acct = qobject_cast< Account* >( index.data( AccountFactoryWrapper::AccountRole ).value< QObject* >() );
|
||||
Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account!
|
||||
|
||||
emit openConfig( acct );
|
||||
|
||||
return true;
|
||||
}
|
||||
} else if ( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick )
|
||||
{
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
if ( m_configPressed.isValid() )
|
||||
emit update( m_configPressed );
|
||||
|
||||
m_configPressed = QModelIndex();
|
||||
Account* acct = qobject_cast< Account* >( index.data( AccountFactoryWrapper::AccountRole ).value< QObject* >() );
|
||||
|
||||
if ( m_cachedCheckRects.contains( index ) && m_cachedCheckRects[ index ].contains( me->pos() ) )
|
||||
{
|
||||
// Check box for this row
|
||||
// eat the double click events inside the check rect
|
||||
if( event->type() == QEvent::MouseButtonDblClick ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() );
|
||||
Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked;
|
||||
emit checkOrUncheck( index, acct, newState );
|
||||
}
|
||||
if ( m_cachedButtonRects.contains( index ) && m_cachedButtonRects[ index ].contains( me->pos() ) )
|
||||
{
|
||||
emit removeAccount( acct );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
61
src/AccountFactoryWrapperDelegate.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2012, 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 ACCOUNTFACTORYWRAPPERDELEGATE_H
|
||||
#define ACCOUNTFACTORYWRAPPERDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
#define ACCOUNT_ROW_HEIGHT 20
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace Accounts {
|
||||
class Account;
|
||||
}
|
||||
}
|
||||
|
||||
class AccountFactoryWrapperDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AccountFactoryWrapperDelegate( 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;
|
||||
virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
|
||||
|
||||
signals:
|
||||
void update( const QModelIndex& );
|
||||
|
||||
void openConfig( Tomahawk::Accounts::Account* );
|
||||
void removeAccount( Tomahawk::Accounts::Account* );
|
||||
|
||||
void checkOrUncheck( const QModelIndex& row, Tomahawk::Accounts::Account* account, Qt::CheckState newState );
|
||||
|
||||
private:
|
||||
QPixmap m_removePixmap, m_offlineIcon, m_onlineIcon;
|
||||
QIcon m_configIcon;
|
||||
QModelIndex m_configPressed;
|
||||
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_cachedCheckRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_cachedButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_cachedConfigRects;
|
||||
};
|
||||
|
||||
#endif // ACCOUNTFACTORYWRAPPERDELEGATE_H
|
@@ -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 2010-2011, Jeff Mitchell <jeff@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
|
||||
@@ -16,23 +17,24 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "audiocontrols.h"
|
||||
#include "ui_audiocontrols.h"
|
||||
#include "AudioControls.h"
|
||||
#include "ui_AudioControls.h"
|
||||
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QtGui/QDropEvent>
|
||||
#include <QtGui/QMouseEvent>
|
||||
|
||||
#include "audio/audioengine.h"
|
||||
#include "playlist/playlistview.h"
|
||||
#include "database/database.h"
|
||||
#include "widgets/imagebutton.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
#include "album.h"
|
||||
#include "dropjob.h"
|
||||
#include "globalactionmanager.h"
|
||||
#include "viewmanager.h"
|
||||
#include "audio/AudioEngine.h"
|
||||
#include "playlist/PlaylistView.h"
|
||||
#include "database/Database.h"
|
||||
#include "widgets/ImageButton.h"
|
||||
#include "utils/TomahawkUtils.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "Album.h"
|
||||
#include "DropJob.h"
|
||||
#include "SocialWidget.h"
|
||||
#include "GlobalActionManager.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -40,9 +42,10 @@ using namespace Tomahawk;
|
||||
AudioControls::AudioControls( QWidget* parent )
|
||||
: QWidget( parent )
|
||||
, ui( new Ui::AudioControls )
|
||||
, m_repeatMode( PlaylistInterface::NoRepeat )
|
||||
, m_repeatMode( PlaylistModes::NoRepeat )
|
||||
, m_shuffled( false )
|
||||
, m_lastSliderCheck( 0 )
|
||||
, m_parent( parent )
|
||||
{
|
||||
ui->setupUi( this );
|
||||
setAcceptDrops( true );
|
||||
@@ -81,6 +84,7 @@ AudioControls::AudioControls( QWidget* parent )
|
||||
ui->repeatButton->setPixmap( RESPATH "images/repeat-off-pressed.png", QIcon::Off, QIcon::Active );
|
||||
ui->volumeLowButton->setPixmap( RESPATH "images/volume-icon-muted.png" );
|
||||
ui->volumeHighButton->setPixmap( RESPATH "images/volume-icon-full.png" );
|
||||
ui->socialButton->setPixmap( RESPATH "images/share.png" );
|
||||
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
|
||||
ui->loveButton->setCheckable( true );
|
||||
|
||||
@@ -92,16 +96,12 @@ AudioControls::AudioControls( QWidget* parent )
|
||||
ui->metaDataArea->setStyleSheet( "QWidget#metaDataArea {\nborder-width: 4px;\nborder-image: url(" RESPATH "images/now-playing-panel.png) 4 4 4 4 stretch stretch; }" );
|
||||
|
||||
ui->seekSlider->setEnabled( true );
|
||||
ui->seekSlider->setTimeLine( &m_sliderTimeLine );
|
||||
ui->volumeSlider->setRange( 0, 100 );
|
||||
ui->volumeSlider->setValue( AudioEngine::instance()->volume() );
|
||||
|
||||
m_phononTickCheckTimer.setSingleShot( true );
|
||||
|
||||
m_sliderTimeLine.setCurveShape( QTimeLine::LinearCurve );
|
||||
ui->seekSlider->setTimeLine( &m_sliderTimeLine );
|
||||
|
||||
m_defaultCover = QPixmap( RESPATH "images/no-album-no-case.png" ).scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
connect( &m_phononTickCheckTimer, SIGNAL( timeout() ), SLOT( phononTickCheckTimeout() ) );
|
||||
connect( &m_sliderTimeLine, SIGNAL( frameChanged( int ) ), ui->seekSlider, SLOT( setValue( int ) ) );
|
||||
|
||||
@@ -121,8 +121,9 @@ AudioControls::AudioControls( QWidget* parent )
|
||||
connect( ui->shuffleButton, SIGNAL( clicked() ), SLOT( onShuffleClicked() ) );
|
||||
|
||||
connect( ui->artistTrackLabel, SIGNAL( clickedArtist() ), SLOT( onArtistClicked() ) );
|
||||
connect( ui->artistTrackLabel, SIGNAL( clickedTrack() ), SLOT( onTrackClicked() ) );
|
||||
connect( ui->albumLabel, SIGNAL( clickedAlbum() ), SLOT( onAlbumClicked() ) );
|
||||
connect( ui->artistTrackLabel, SIGNAL( clickedTrack() ), SLOT( onTrackClicked() ) );
|
||||
connect( ui->albumLabel, SIGNAL( clickedAlbum() ), SLOT( onAlbumClicked() ) );
|
||||
connect( ui->socialButton, SIGNAL( clicked() ), SLOT( onSocialButtonClicked() ) );
|
||||
connect( ui->loveButton, SIGNAL( clicked( bool ) ), SLOT( onLoveButtonClicked( bool ) ) );
|
||||
|
||||
// <From AudioEngine>
|
||||
@@ -201,17 +202,22 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result )
|
||||
|
||||
ui->seekSlider->setRange( 0, duration );
|
||||
ui->seekSlider->setValue( 0 );
|
||||
ui->seekSlider->setEnabled( AudioEngine::instance()->canSeek() );
|
||||
|
||||
m_phononTickCheckTimer.stop();
|
||||
|
||||
m_sliderTimeLine.stop();
|
||||
m_sliderTimeLine.setDuration( duration );
|
||||
m_sliderTimeLine.setFrameRange( 0, duration );
|
||||
m_sliderTimeLine.setCurveShape( QTimeLine::LinearCurve );
|
||||
m_sliderTimeLine.setCurrentTime( 0 );
|
||||
m_seekMsecs = -1;
|
||||
|
||||
ui->seekSlider->setVisible( true );
|
||||
|
||||
int updateRate = (double)1000 / ( (double)ui->seekSlider->contentsRect().width() / (double)( duration / 1000 ) );
|
||||
m_sliderTimeLine.setUpdateInterval( qBound( 40, updateRate, 500 ) );
|
||||
|
||||
m_noTimeChange = false;
|
||||
m_lastSliderCheck = 0;
|
||||
}
|
||||
@@ -222,12 +228,12 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result )
|
||||
{
|
||||
if ( !m_currentTrack.isNull() )
|
||||
{
|
||||
disconnect( m_currentTrack->album().data(), SIGNAL( updated() ), this, SLOT( onAlbumCoverUpdated() ) );
|
||||
disconnect( m_currentTrack->toQuery().data(), SIGNAL( updated() ), this, SLOT( onCoverUpdated() ) );
|
||||
disconnect( m_currentTrack->toQuery().data(), SIGNAL( socialActionsLoaded() ), this, SLOT( onSocialActionsLoaded() ) );
|
||||
}
|
||||
|
||||
m_currentTrack = result;
|
||||
connect( m_currentTrack->album().data(), SIGNAL( updated() ), SLOT( onAlbumCoverUpdated() ) );
|
||||
connect( m_currentTrack->toQuery().data(), SIGNAL( updated() ), SLOT( onCoverUpdated() ) );
|
||||
connect( m_currentTrack->toQuery().data(), SIGNAL( socialActionsLoaded() ), SLOT( onSocialActionsLoaded() ) );
|
||||
|
||||
ui->artistTrackLabel->setResult( result );
|
||||
@@ -239,39 +245,42 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result )
|
||||
ui->timeLabel->setText( TomahawkUtils::timeToString( 0 ) );
|
||||
ui->timeLeftLabel->setFixedWidth( ui->timeLeftLabel->fontMetrics().width( QString( duration.length() + 1, QChar( '0' ) ) ) );
|
||||
ui->timeLeftLabel->setText( "-" + duration );
|
||||
m_lastTextSecondShown = 0;
|
||||
|
||||
ui->stackedLayout->setCurrentWidget( ui->pauseButton );
|
||||
|
||||
ui->loveButton->setEnabled( true );
|
||||
ui->loveButton->setVisible( true );
|
||||
ui->socialButton->setEnabled( true );
|
||||
ui->socialButton->setVisible( true );
|
||||
|
||||
setAlbumCover();
|
||||
setCover();
|
||||
setSocialActions();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioControls::onAlbumCoverUpdated()
|
||||
AudioControls::onCoverUpdated()
|
||||
{
|
||||
Album* album = qobject_cast< Album* >( sender() );
|
||||
if ( !album || album != m_currentTrack->album().data() )
|
||||
Query* query = qobject_cast< Query* >( sender() );
|
||||
if ( !query || !m_currentTrack || query != m_currentTrack->toQuery().data() )
|
||||
return;
|
||||
|
||||
setAlbumCover();
|
||||
setCover();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioControls::setAlbumCover()
|
||||
AudioControls::setCover()
|
||||
{
|
||||
if ( !m_currentTrack->album()->cover().isNull() )
|
||||
if ( !m_currentTrack->toQuery()->cover( ui->coverImage->size() ).isNull() )
|
||||
{
|
||||
QPixmap cover;
|
||||
cover.loadFromData( m_currentTrack->album()->cover() );
|
||||
ui->coverImage->setPixmap( cover.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
|
||||
cover = m_currentTrack->toQuery()->cover( ui->coverImage->size() );
|
||||
ui->coverImage->setPixmap( cover, false );
|
||||
}
|
||||
else
|
||||
ui->coverImage->setPixmap( m_defaultCover );
|
||||
ui->coverImage->setPixmap( TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::ScaledCover, ui->coverImage->size() ), true );
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +288,7 @@ void
|
||||
AudioControls::onSocialActionsLoaded()
|
||||
{
|
||||
Query* query = qobject_cast< Query* >( sender() );
|
||||
if ( !query || query != m_currentTrack->toQuery().data() )
|
||||
if ( !query || !m_currentTrack || !query->equals( m_currentTrack->toQuery() ) )
|
||||
return;
|
||||
|
||||
setSocialActions();
|
||||
@@ -316,7 +325,6 @@ AudioControls::onPlaybackResumed()
|
||||
{
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||
ui->stackedLayout->setCurrentWidget( ui->pauseButton );
|
||||
ui->loveButton->setVisible( true );
|
||||
m_sliderTimeLine.resume();
|
||||
}
|
||||
|
||||
@@ -343,7 +351,7 @@ AudioControls::onPlaybackStopped()
|
||||
ui->ownerLabel->setText( "" );
|
||||
ui->timeLabel->setText( "" );
|
||||
ui->timeLeftLabel->setText( "" );
|
||||
ui->coverImage->setPixmap( QPixmap() );
|
||||
ui->coverImage->setPixmap( QPixmap(), true );
|
||||
ui->seekSlider->setVisible( false );
|
||||
m_sliderTimeLine.stop();
|
||||
m_sliderTimeLine.setCurrentTime( 0 );
|
||||
@@ -351,12 +359,22 @@ AudioControls::onPlaybackStopped()
|
||||
ui->stackedLayout->setCurrentWidget( ui->playPauseButton );
|
||||
ui->loveButton->setEnabled( false );
|
||||
ui->loveButton->setVisible( false );
|
||||
ui->socialButton->setEnabled( false );
|
||||
ui->socialButton->setVisible( false );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioControls::onPlaybackTimer( qint64 msElapsed )
|
||||
{
|
||||
const int seconds = msElapsed / 1000;
|
||||
if ( seconds != m_lastTextSecondShown && !m_currentTrack.isNull() )
|
||||
{
|
||||
ui->timeLabel->setText( TomahawkUtils::timeToString( seconds ) );
|
||||
ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( m_currentTrack->duration() - seconds ) );
|
||||
m_lastTextSecondShown = seconds;
|
||||
}
|
||||
|
||||
//tDebug( LOGEXTRA ) << Q_FUNC_INFO << "msElapsed =" << msElapsed << "and timer current time =" << m_sliderTimeLine.currentTime() << "and m_seekMsecs =" << m_seekMsecs;
|
||||
if ( msElapsed > 0 && msElapsed != m_lastSliderCheck && m_seekMsecs == -1 && msElapsed - 500 < m_lastSliderCheck )
|
||||
return;
|
||||
@@ -373,13 +391,10 @@ AudioControls::onPlaybackTimer( qint64 msElapsed )
|
||||
if ( sender() != &m_phononTickCheckTimer )
|
||||
m_phononTickCheckTimer.start( 1000 );
|
||||
|
||||
const int seconds = msElapsed / 1000;
|
||||
ui->timeLabel->setText( TomahawkUtils::timeToString( seconds ) );
|
||||
ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( m_currentTrack->duration() - seconds ) );
|
||||
|
||||
int currentTime = m_sliderTimeLine.currentTime();
|
||||
if ( m_noTimeChange )
|
||||
{
|
||||
if ( m_sliderTimeLine.currentTime() != msElapsed )
|
||||
if ( currentTime != msElapsed )
|
||||
{
|
||||
m_sliderTimeLine.setPaused( true );
|
||||
m_noTimeChange = false;
|
||||
@@ -388,12 +403,12 @@ AudioControls::onPlaybackTimer( qint64 msElapsed )
|
||||
m_sliderTimeLine.resume();
|
||||
}
|
||||
}
|
||||
else if ( m_sliderTimeLine.currentTime() >= msElapsed || m_seekMsecs != -1 )
|
||||
else if ( currentTime >= msElapsed || m_seekMsecs != -1 )
|
||||
{
|
||||
m_sliderTimeLine.setPaused( true );
|
||||
|
||||
m_noTimeChange = false;
|
||||
if ( m_sliderTimeLine.currentTime() == msElapsed )
|
||||
if ( currentTime == msElapsed )
|
||||
m_noTimeChange = true;
|
||||
|
||||
m_sliderTimeLine.setCurrentTime( msElapsed );
|
||||
@@ -403,12 +418,10 @@ AudioControls::onPlaybackTimer( qint64 msElapsed )
|
||||
}
|
||||
else if ( m_sliderTimeLine.duration() > msElapsed && m_sliderTimeLine.state() == QTimeLine::NotRunning && AudioEngine::instance()->state() == AudioEngine::Playing )
|
||||
{
|
||||
ui->seekSlider->setEnabled( AudioEngine::instance()->canSeek() );
|
||||
m_sliderTimeLine.start();
|
||||
}
|
||||
else if ( m_sliderTimeLine.state() == QTimeLine::Paused && AudioEngine::instance()->state() != AudioEngine::Paused )
|
||||
{
|
||||
ui->seekSlider->setEnabled( AudioEngine::instance()->canSeek() );
|
||||
m_sliderTimeLine.resume();
|
||||
}
|
||||
|
||||
@@ -417,13 +430,13 @@ AudioControls::onPlaybackTimer( qint64 msElapsed )
|
||||
|
||||
|
||||
void
|
||||
AudioControls::onRepeatModeChanged( PlaylistInterface::RepeatMode mode )
|
||||
AudioControls::onRepeatModeChanged( PlaylistModes::RepeatMode mode )
|
||||
{
|
||||
m_repeatMode = mode;
|
||||
|
||||
switch ( m_repeatMode )
|
||||
{
|
||||
case PlaylistInterface::NoRepeat:
|
||||
case PlaylistModes::NoRepeat:
|
||||
{
|
||||
// switch to RepeatOne
|
||||
ui->repeatButton->setPixmap( RESPATH "images/repeat-off-rest.png" );
|
||||
@@ -431,7 +444,7 @@ AudioControls::onRepeatModeChanged( PlaylistInterface::RepeatMode mode )
|
||||
}
|
||||
break;
|
||||
|
||||
case PlaylistInterface::RepeatOne:
|
||||
case PlaylistModes::RepeatOne:
|
||||
{
|
||||
// switch to RepeatAll
|
||||
ui->repeatButton->setPixmap( RESPATH "images/repeat-1-on-rest.png" );
|
||||
@@ -439,7 +452,7 @@ AudioControls::onRepeatModeChanged( PlaylistInterface::RepeatMode mode )
|
||||
}
|
||||
break;
|
||||
|
||||
case PlaylistInterface::RepeatAll:
|
||||
case PlaylistModes::RepeatAll:
|
||||
{
|
||||
// switch to NoRepeat
|
||||
ui->repeatButton->setPixmap( RESPATH "images/repeat-all-on-rest.png" );
|
||||
@@ -458,24 +471,24 @@ AudioControls::onRepeatClicked()
|
||||
{
|
||||
switch ( m_repeatMode )
|
||||
{
|
||||
case PlaylistInterface::NoRepeat:
|
||||
case PlaylistModes::NoRepeat:
|
||||
{
|
||||
// switch to RepeatOne
|
||||
ViewManager::instance()->setRepeatMode( PlaylistInterface::RepeatOne );
|
||||
ViewManager::instance()->setRepeatMode( PlaylistModes::RepeatOne );
|
||||
}
|
||||
break;
|
||||
|
||||
case PlaylistInterface::RepeatOne:
|
||||
case PlaylistModes::RepeatOne:
|
||||
{
|
||||
// switch to RepeatAll
|
||||
ViewManager::instance()->setRepeatMode( PlaylistInterface::RepeatAll );
|
||||
ViewManager::instance()->setRepeatMode( PlaylistModes::RepeatAll );
|
||||
}
|
||||
break;
|
||||
|
||||
case PlaylistInterface::RepeatAll:
|
||||
case PlaylistModes::RepeatAll:
|
||||
{
|
||||
// switch to NoRepeat
|
||||
ViewManager::instance()->setRepeatMode( PlaylistInterface::NoRepeat );
|
||||
ViewManager::instance()->setRepeatMode( PlaylistModes::NoRepeat );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -531,7 +544,8 @@ AudioControls::onAlbumClicked()
|
||||
void
|
||||
AudioControls::onTrackClicked()
|
||||
{
|
||||
ViewManager::instance()->showCurrentTrack();
|
||||
ViewManager::instance()->show( m_currentTrack->toQuery() );
|
||||
// ViewManager::instance()->showCurrentTrack();
|
||||
}
|
||||
|
||||
|
||||
@@ -574,16 +588,21 @@ AudioControls::droppedTracks( QList< query_ptr > tracks )
|
||||
{
|
||||
// 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++ )
|
||||
{
|
||||
ViewManager::instance()->queue()->model()->append( tracks[ i ] );
|
||||
}
|
||||
ViewManager::instance()->queue()->model()->append( tracks );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioControls::onSocialButtonClicked()
|
||||
{
|
||||
SocialWidget* sw = new SocialWidget( m_parent );
|
||||
sw->setPosition( QCursor::pos() );
|
||||
sw->setQuery( m_currentTrack->toQuery() );
|
||||
sw->show();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioControls::onLoveButtonClicked( bool checked )
|
||||
{
|
@@ -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 2010-2011, Jeff Mitchell <jeff@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
|
||||
@@ -23,9 +24,9 @@
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QTimeLine>
|
||||
|
||||
#include "result.h"
|
||||
#include "playlistinterface.h"
|
||||
#include "query.h"
|
||||
#include "Result.h"
|
||||
#include "PlaylistInterface.h"
|
||||
#include "Query.h"
|
||||
|
||||
class QDropEvent;
|
||||
class QDragEnterEvent;
|
||||
@@ -49,9 +50,9 @@ signals:
|
||||
void pausePressed();
|
||||
|
||||
public slots:
|
||||
void onRepeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode );
|
||||
void onRepeatModeChanged( Tomahawk::PlaylistModes::RepeatMode mode );
|
||||
void onShuffleModeChanged( bool enabled );
|
||||
|
||||
|
||||
protected:
|
||||
void changeEvent( QEvent* e );
|
||||
void dragEnterEvent ( QDragEnterEvent* );
|
||||
@@ -60,7 +61,7 @@ protected:
|
||||
|
||||
private slots:
|
||||
void phononTickCheckTimeout();
|
||||
|
||||
|
||||
void onPlaybackStarted( const Tomahawk::result_ptr& result );
|
||||
void onPlaybackLoading( const Tomahawk::result_ptr& result );
|
||||
void onPlaybackPaused();
|
||||
@@ -77,24 +78,22 @@ private slots:
|
||||
void onArtistClicked();
|
||||
void onAlbumClicked();
|
||||
void onTrackClicked();
|
||||
void onSocialButtonClicked();
|
||||
void onLoveButtonClicked( bool );
|
||||
|
||||
void onAlbumCoverUpdated();
|
||||
|
||||
void droppedTracks( QList<Tomahawk::query_ptr> );
|
||||
|
||||
void onCoverUpdated();
|
||||
void onSocialActionsLoaded();
|
||||
|
||||
private:
|
||||
void setAlbumCover();
|
||||
void setCover();
|
||||
void setSocialActions();
|
||||
|
||||
Ui::AudioControls *ui;
|
||||
|
||||
QPixmap m_defaultCover;
|
||||
Ui::AudioControls* ui;
|
||||
|
||||
Tomahawk::result_ptr m_currentTrack;
|
||||
Tomahawk::PlaylistInterface::RepeatMode m_repeatMode;
|
||||
Tomahawk::PlaylistModes::RepeatMode m_repeatMode;
|
||||
bool m_shuffled;
|
||||
|
||||
QTimer m_phononTickCheckTimer;
|
||||
@@ -102,6 +101,9 @@ private:
|
||||
qint64 m_seekMsecs;
|
||||
qint64 m_lastSliderCheck;
|
||||
bool m_noTimeChange;
|
||||
qint64 m_lastTextSecondShown;
|
||||
|
||||
QWidget* m_parent;
|
||||
};
|
||||
|
||||
#endif // AUDIOCONTROLS_H
|
@@ -142,7 +142,7 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="coverImage">
|
||||
<widget class="FadingPixmap" name="coverImage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -151,14 +151,14 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>58</width>
|
||||
<height>58</height>
|
||||
<width>60</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>58</width>
|
||||
<height>58</height>
|
||||
<width>60</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
@@ -287,6 +287,22 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ImageButton" name="socialButton">
|
||||
<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>social</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ImageButton" name="loveButton">
|
||||
<property name="sizePolicy">
|
||||
@@ -554,12 +570,17 @@
|
||||
<customwidget>
|
||||
<class>ImageButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>widgets/imagebutton.h</header>
|
||||
<header>widgets/ImageButton.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QueryLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>widgets/querylabel.h</header>
|
||||
<header>widgets/QueryLabel.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>FadingPixmap</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>widgets/FadingPixmap.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
@@ -58,4 +58,7 @@ if (APPLE)
|
||||
FILE(COPY ${CMAKE_SOURCE_DIR}/admin/mac/sparkle_pub.pem
|
||||
DESTINATION "${CMAKE_BINARY_DIR}/tomahawk.app/Contents/Resources")
|
||||
|
||||
FILE(COPY /usr/bin/SetFile DESTINATION "${CMAKE_BINARY_DIR}/tomahawk.app/Contents/MacOS")
|
||||
FILE(COPY /usr/bin/GetFileInfo DESTINATION "${CMAKE_BINARY_DIR}/tomahawk.app/Contents/MacOS")
|
||||
|
||||
endif (APPLE)
|
||||
|
@@ -37,115 +37,78 @@ ENDIF()
|
||||
#ENDFOREACH( moddir )
|
||||
|
||||
SET( tomahawkSources ${tomahawkSources}
|
||||
web/api_v1.cpp
|
||||
web/Api_v1.cpp
|
||||
|
||||
musicscanner.cpp
|
||||
shortcuthandler.cpp
|
||||
scanmanager.cpp
|
||||
ubuntuunityhack.cpp
|
||||
tomahawkapp.cpp
|
||||
MusicScanner.cpp
|
||||
ShortcutHandler.cpp
|
||||
ScanManager.cpp
|
||||
UbuntuUnityHack.cpp
|
||||
TomahawkApp.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
IF(LIBLASTFM_FOUND)
|
||||
SET(tomahawkSources ${tomahawkSources}
|
||||
scrobbler.cpp
|
||||
Scrobbler.cpp
|
||||
)
|
||||
ENDIF(LIBLASTFM_FOUND)
|
||||
|
||||
SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
||||
sourcetree/sourcesmodel.cpp
|
||||
sourcetree/sourcesproxymodel.cpp
|
||||
sourcetree/sourcetreeview.cpp
|
||||
sourcetree/sourcedelegate.cpp
|
||||
sourcetree/animationhelper.cpp
|
||||
sourcetree/items/sourcetreeitem.cpp
|
||||
sourcetree/items/sourceitem.cpp
|
||||
sourcetree/items/playlistitems.cpp
|
||||
sourcetree/items/categoryitems.cpp
|
||||
sourcetree/items/genericpageitems.cpp
|
||||
sourcetree/items/temporarypageitem.cpp
|
||||
sourcetree/items/groupitem.cpp
|
||||
sourcetree/items/historyitem.cpp
|
||||
sourcetree/SourcesModel.cpp
|
||||
sourcetree/SourcesProxyModel.cpp
|
||||
sourcetree/SourceTreeView.cpp
|
||||
sourcetree/SourceDelegate.cpp
|
||||
sourcetree/AnimationHelper.cpp
|
||||
sourcetree/items/SourceTreeItem.cpp
|
||||
sourcetree/items/SourceItem.cpp
|
||||
sourcetree/items/PlaylistItems.cpp
|
||||
sourcetree/items/CategoryItems.cpp
|
||||
sourcetree/items/GenericPageItems.cpp
|
||||
sourcetree/items/TemporaryPageItem.cpp
|
||||
sourcetree/items/GroupItem.cpp
|
||||
sourcetree/items/HistoryItem.cpp
|
||||
|
||||
breakpad/BreakPad.cpp
|
||||
utils/GuiHelpers.cpp
|
||||
|
||||
tomahawktrayicon.cpp
|
||||
audiocontrols.cpp
|
||||
settingsdialog.cpp
|
||||
diagnosticsdialog.cpp
|
||||
configdelegatebase.cpp
|
||||
sipconfigdelegate.cpp
|
||||
resolverconfigdelegate.cpp
|
||||
settingslistdelegate.cpp
|
||||
resolversmodel.cpp
|
||||
tomahawkwindow.cpp
|
||||
accounts/lastfm/LastFmAccount.cpp
|
||||
accounts/lastfm/LastFmConfig.cpp
|
||||
accounts/lastfm/LastFmInfoPlugin.cpp
|
||||
|
||||
accounts/spotify/SpotifyAccount.cpp
|
||||
accounts/spotify/SpotifyAccountConfig.cpp
|
||||
accounts/spotify/SpotifyPlaylistUpdater.cpp
|
||||
|
||||
TomahawkTrayIcon.cpp
|
||||
AudioControls.cpp
|
||||
SettingsDialog.cpp
|
||||
DiagnosticsDialog.cpp
|
||||
AccountDelegate.cpp
|
||||
SettingsListDelegate.cpp
|
||||
DelegateConfigWrapper.cpp
|
||||
TomahawkWindow.cpp
|
||||
LoadXSPFDialog.cpp
|
||||
AccountFactoryWrapper.cpp
|
||||
AccountFactoryWrapperDelegate.cpp
|
||||
SocialWidget.cpp
|
||||
)
|
||||
|
||||
SET( tomahawkHeaders ${tomahawkHeaders}
|
||||
tomahawkapp.h
|
||||
|
||||
web/api_v1.h
|
||||
|
||||
musicscanner.h
|
||||
scanmanager.h
|
||||
ubuntuunityhack.h
|
||||
shortcuthandler.h
|
||||
)
|
||||
|
||||
IF(LIBLASTFM_FOUND)
|
||||
SET(tomahawkHeaders ${tomahawkHeaders}
|
||||
scrobbler.h
|
||||
)
|
||||
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
|
||||
sourcetree/sourcesproxymodel.h
|
||||
sourcetree/sourcetreeview.h
|
||||
sourcetree/sourcedelegate.h
|
||||
sourcetree/animationhelper.h
|
||||
sourcetree/items/sourcetreeitem.h
|
||||
sourcetree/items/sourceitem.h
|
||||
sourcetree/items/playlistitems.h
|
||||
sourcetree/items/categoryitems.h
|
||||
sourcetree/items/genericpageitems.h
|
||||
sourcetree/items/temporarypageitem.h
|
||||
sourcetree/items/groupitem.h
|
||||
sourcetree/items/historyitem.h
|
||||
|
||||
tomahawktrayicon.h
|
||||
audiocontrols.h
|
||||
settingsdialog.h
|
||||
diagnosticsdialog.h
|
||||
configdelegatebase.h
|
||||
resolverconfigdelegate.h
|
||||
sipconfigdelegate.h
|
||||
settingslistdelegate.h
|
||||
resolversmodel.h
|
||||
delegateconfigwrapper.h
|
||||
tomahawkwindow.h
|
||||
LoadXSPFDialog.h
|
||||
)
|
||||
IF( WITH_BREAKPAD )
|
||||
LIST(APPEND tomahawkSourcesGui breakpad/BreakPad.cpp)
|
||||
ENDIF()
|
||||
|
||||
SET( tomahawkUI ${tomahawkUI}
|
||||
tomahawkwindow.ui
|
||||
diagnosticsdialog.ui
|
||||
stackedsettingsdialog.ui
|
||||
proxydialog.ui
|
||||
TomahawkWindow.ui
|
||||
DiagnosticsDialog.ui
|
||||
StackedSettingsDialog.ui
|
||||
ProxyDialog.ui
|
||||
|
||||
audiocontrols.ui
|
||||
accounts/lastfm/LastFmConfig.ui
|
||||
accounts/spotify/SpotifyAccountConfig.ui
|
||||
|
||||
GetNewStuffDialog.ui
|
||||
AudioControls.ui
|
||||
LoadXSPFDialog.ui
|
||||
AccountFactoryWrapper.ui
|
||||
SocialWidget.ui
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
@@ -171,6 +134,7 @@ INCLUDE_DIRECTORIES(
|
||||
${TAGLIB_INCLUDES}
|
||||
${PHONON_INCLUDES}
|
||||
${QJSON_INCLUDE_DIR}
|
||||
${LIBATTICA_INCLUDE_DIR}
|
||||
${LIBECHONEST_INCLUDE_DIR}
|
||||
${LIBECHONEST_INCLUDE_DIR}/..
|
||||
)
|
||||
@@ -187,42 +151,41 @@ ENDIF( UNIX )
|
||||
IF( APPLE )
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/thirdparty/SPMediaKeyTap )
|
||||
|
||||
SET( tomahawkHeaders ${tomahawkHeaders} mac/tomahawkapp_mac.h mac/macshortcuthandler.h )
|
||||
SET( tomahawkSources ${tomahawkSources} mac/tomahawkapp_mac.mm mac/macshortcuthandler.cpp )
|
||||
|
||||
IF(HAVE_SPARKLE)
|
||||
SET( tomahawkHeaders ${tomahawkHeaders} ${SPARKLE}/Headers )
|
||||
ENDIF(HAVE_SPARKLE)
|
||||
SET( tomahawkSources ${tomahawkSources} mac/TomahawkApp_Mac.mm mac/MacShortcutHandler.cpp )
|
||||
ENDIF( APPLE )
|
||||
|
||||
IF(GLOOX_FOUND)
|
||||
INCLUDE_DIRECTORIES( ${GLOOX_INCLUDE_DIR} )
|
||||
SET( tomahawkHeaders ${tomahawkHeaders} xmppbot/xmppbot.h )
|
||||
SET( tomahawkSources ${tomahawkSources} xmppbot/xmppbot.cpp )
|
||||
SET( tomahawkSources ${tomahawkSources} xmppbot/XmppBot.cpp )
|
||||
ENDIF(GLOOX_FOUND)
|
||||
ADD_SUBDIRECTORY( sip )
|
||||
|
||||
ADD_SUBDIRECTORY( accounts )
|
||||
ADD_SUBDIRECTORY( infoplugins )
|
||||
|
||||
IF(QCA2_FOUND)
|
||||
INCLUDE_DIRECTORIES( ${QCA2_INCLUDE_DIR} )
|
||||
ENDIF(QCA2_FOUND)
|
||||
|
||||
INCLUDE(GNUInstallDirs)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
include( ${CMAKE_SOURCE_DIR}/lang/translations.cmake )
|
||||
|
||||
SET( final_src ${final_src} ${tomahawkMoc} ${tomahawkSources} ${tomahawkHeaders} ${trans_outfile})
|
||||
SET( final_src ${final_src} ${tomahawkMoc} ${tomahawkSources} ${trans_outfile})
|
||||
|
||||
IF( BUILD_GUI )
|
||||
LIST(APPEND tomahawkHeaders ${tomahawkHeadersGui})
|
||||
LIST(APPEND tomahawkSources ${tomahawkSourcesGui})
|
||||
qt4_wrap_ui( tomahawkUI_H ${tomahawkUI} )
|
||||
|
||||
IF( WITH_CRASHREPORTER )
|
||||
ADD_SUBDIRECTORY( breakpad/CrashReporter )
|
||||
ENDIF()
|
||||
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 )
|
||||
@@ -230,13 +193,14 @@ IF( UNIX AND NOT APPLE )
|
||||
ENDIF( UNIX AND NOT APPLE )
|
||||
IF( APPLE )
|
||||
ADD_EXECUTABLE( tomahawk MACOSX_BUNDLE ${final_src} )
|
||||
SET_TARGET_PROPERTIES(tomahawk PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_BINARY_DIR}/Info.plist"
|
||||
)
|
||||
SET_TARGET_PROPERTIES(tomahawk PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_BINARY_DIR}/Info.plist")
|
||||
ENDIF( APPLE )
|
||||
IF( WIN32 )
|
||||
ADD_EXECUTABLE( tomahawk WIN32 ${final_src} )
|
||||
ENDIF( WIN32 )
|
||||
|
||||
SET_TARGET_PROPERTIES(tomahawk PROPERTIES AUTOMOC TRUE)
|
||||
|
||||
MESSAGE( STATUS "OS_SPECIFIC_LINK_LIBRARIES: ${OS_SPECIFIC_LINK_LIBRARIES}" )
|
||||
|
||||
SET(LINK_LIBRARIES "")
|
||||
@@ -249,9 +213,11 @@ ENDIF(GLOOX_FOUND)
|
||||
IF(QCA2_FOUND)
|
||||
SET(LINK_LIBRARIES ${LINK_LIBRARIES} ${QCA2_LIBRARIES} )
|
||||
ENDIF(QCA2_FOUND)
|
||||
IF(WITH_BREAKPAD)
|
||||
SET(LINK_LIBRARIES ${LINK_LIBRARIES} tomahawk_breakpad)
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES( tomahawk
|
||||
tomahawk_breakpad
|
||||
${LINK_LIBRARIES}
|
||||
${TOMAHAWK_LIBRARIES}
|
||||
${PHONON_LIBS}
|
||||
|
@@ -17,9 +17,11 @@
|
||||
#cmakedefine LEOPARD
|
||||
#cmakedefine HAVE_SPARKLE
|
||||
|
||||
#cmakedefine WITH_BREAKPAD
|
||||
#cmakedefine WITH_CRASHREPORTER
|
||||
|
||||
#cmakedefine LIBLASTFM_FOUND
|
||||
#cmakedefine GLOOX_FOUND
|
||||
#cmakedefine QCA2_FOUND
|
||||
#cmakedefine LIBATTICA_FOUND
|
||||
|
||||
#endif // CONFIG_H_IN
|
@@ -19,7 +19,7 @@
|
||||
#ifndef CONFIGDELEGATEBASE_H
|
||||
#define CONFIGDELEGATEBASE_H
|
||||
|
||||
#include "dllmacro.h"
|
||||
#include "DllMacro.h"
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
@@ -36,16 +36,15 @@ public:
|
||||
virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
|
||||
|
||||
// if you want to use a checkbox, you need to have this say where to paint it
|
||||
virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0;
|
||||
virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx, int role ) const = 0;
|
||||
// if you want to use a config wrench, you need to have this say where to paint it
|
||||
virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0;
|
||||
|
||||
virtual QList<int> extraCheckRoles() const { return QList<int>(); }
|
||||
signals:
|
||||
void configPressed( const QModelIndex& idx );
|
||||
|
||||
protected:
|
||||
void drawCheckBox( QStyleOptionViewItemV4& opt, QPainter* p, const QWidget* w ) const;
|
||||
void drawConfigWrench( QPainter* painter, QStyleOptionViewItemV4& option, QStyleOptionToolButton& topt ) const;
|
||||
|
||||
private:
|
||||
QModelIndex m_configPressed;
|
158
src/DelegateConfigWrapper.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/* === 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 "DelegateConfigWrapper.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
|
||||
DelegateConfigWrapper::DelegateConfigWrapper( QWidget* conf, QWidget* aboutWidget, const QString& title, QWidget* parent, Qt::WindowFlags flags )
|
||||
: QDialog( parent, flags )
|
||||
, m_widget( conf )
|
||||
, m_aboutW( aboutWidget )
|
||||
, m_deleted( false )
|
||||
{
|
||||
m_widget->setWindowFlags( Qt::Sheet );
|
||||
#ifdef Q_WS_MAC
|
||||
m_widget->setVisible( true );
|
||||
#endif
|
||||
setWindowTitle( title );
|
||||
QVBoxLayout* v = new QVBoxLayout( this );
|
||||
v->setContentsMargins( 0, 0, 0, 0 );
|
||||
v->addWidget( m_widget );
|
||||
|
||||
QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Ok | QDialogButtonBox::Cancel;
|
||||
if ( m_aboutW )
|
||||
{
|
||||
m_aboutW->hide();
|
||||
buttons |= QDialogButtonBox::Help;
|
||||
}
|
||||
|
||||
m_buttons = new QDialogButtonBox( buttons, Qt::Horizontal, this );
|
||||
m_okButton = m_buttons->button( QDialogButtonBox::Ok );
|
||||
connect( m_buttons, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( closed( QAbstractButton* ) ) );
|
||||
connect( this, SIGNAL( rejected() ), this, SLOT( rejected() ) );
|
||||
|
||||
if ( m_aboutW )
|
||||
{
|
||||
connect( m_buttons->button( QDialogButtonBox::Help ), SIGNAL( clicked( bool ) ), this, SLOT( aboutClicked( bool ) ) );
|
||||
m_buttons->button( QDialogButtonBox::Help )->setText( tr( "About" ) );
|
||||
}
|
||||
|
||||
v->addWidget( m_buttons );
|
||||
|
||||
setLayout( v );
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
setSizeGripEnabled( false );
|
||||
setMinimumSize( sizeHint() );
|
||||
setMaximumSize( sizeHint() ); // to remove the resize grip on osx this is the only way
|
||||
|
||||
if( conf->metaObject()->indexOfSignal( "sizeHintChanged()" ) > -1 )
|
||||
connect( conf, SIGNAL( sizeHintChanged() ), this, SLOT( updateSizeHint() ) );
|
||||
#else
|
||||
m_widget->setVisible( true );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DelegateConfigWrapper::setShowDelete( bool del )
|
||||
{
|
||||
if ( del )
|
||||
m_deleteButton = m_buttons->addButton( tr( "Delete Account" ), QDialogButtonBox::DestructiveRole );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DelegateConfigWrapper::toggleOkButton( bool dataError )
|
||||
{
|
||||
// if dataError is True we want to set the button enabled to false
|
||||
m_okButton->setEnabled( !dataError );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DelegateConfigWrapper::closed( QAbstractButton* b )
|
||||
{
|
||||
QDialogButtonBox* buttons = qobject_cast< QDialogButtonBox* >( sender() );
|
||||
|
||||
if ( buttons->standardButton( b ) == QDialogButtonBox::Help )
|
||||
return;
|
||||
|
||||
// let the config widget live to see another day
|
||||
layout()->removeWidget( m_widget );
|
||||
m_widget->setParent( 0 );
|
||||
m_widget->setVisible( false );
|
||||
|
||||
if ( buttons->standardButton( b ) == QDialogButtonBox::Ok )
|
||||
done( QDialog::Accepted );
|
||||
else if ( b == m_deleteButton )
|
||||
{
|
||||
m_deleted = true;
|
||||
emit closedWithDelete();
|
||||
reject();
|
||||
}
|
||||
else
|
||||
done( QDialog::Rejected );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DelegateConfigWrapper::rejected()
|
||||
{
|
||||
layout()->removeWidget( m_widget );
|
||||
m_widget->setParent( 0 );
|
||||
m_widget->setVisible( false );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DelegateConfigWrapper::updateSizeHint()
|
||||
{
|
||||
hide();
|
||||
setSizeGripEnabled( false );
|
||||
setMinimumSize( sizeHint() );
|
||||
setMaximumSize( sizeHint() );
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DelegateConfigWrapper::aboutClicked( bool )
|
||||
{
|
||||
Q_ASSERT( m_aboutW );
|
||||
m_aboutW->show();
|
||||
|
||||
QDialog d( this );
|
||||
d.setWindowTitle( tr( "About this Account" ) );
|
||||
QVBoxLayout* v = new QVBoxLayout( &d );
|
||||
v->addWidget( m_aboutW );
|
||||
QDialogButtonBox* bbox = new QDialogButtonBox( QDialogButtonBox::Ok, Qt::Horizontal, &d );
|
||||
v->addWidget( bbox );
|
||||
|
||||
d.setLayout( v );
|
||||
connect( bbox, SIGNAL( clicked( QAbstractButton* ) ), &d, SLOT( accept() ) );
|
||||
d.exec();
|
||||
v->removeWidget( m_aboutW );
|
||||
|
||||
m_aboutW->setParent( 0 );
|
||||
m_aboutW->hide();
|
||||
|
||||
}
|
||||
|
61
src/DelegateConfigWrapper.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* === 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 RESOLVER_CONFIG_WRAPPER
|
||||
#define RESOLVER_CONFIG_WRAPPER
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QDebug>
|
||||
|
||||
class DelegateConfigWrapper : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DelegateConfigWrapper( QWidget* conf, QWidget* aboutWidget, const QString& title, QWidget* parent, Qt::WindowFlags flags = 0 );
|
||||
|
||||
~DelegateConfigWrapper() {}
|
||||
|
||||
void setShowDelete( bool del );
|
||||
|
||||
bool deleted() const { return m_deleted; }
|
||||
|
||||
public slots:
|
||||
void toggleOkButton( bool dataError );
|
||||
void closed( QAbstractButton* b );
|
||||
|
||||
// we get a rejected() signal emitted if the user presses escape (and no clicked() signal )
|
||||
void rejected();
|
||||
|
||||
void updateSizeHint();
|
||||
|
||||
signals:
|
||||
void closedWithDelete();
|
||||
|
||||
private slots:
|
||||
void aboutClicked( bool );
|
||||
|
||||
private:
|
||||
QDialogButtonBox* m_buttons;
|
||||
QWidget* m_widget, *m_aboutW;
|
||||
QPushButton *m_okButton, *m_deleteButton;
|
||||
bool m_deleted;
|
||||
};
|
||||
|
||||
#endif
|
@@ -1,6 +1,7 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Dominik Schmidt <dev@dominik-schmidt.de>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@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
|
||||
@@ -16,14 +17,14 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "diagnosticsdialog.h"
|
||||
#include "ui_diagnosticsdialog.h"
|
||||
#include "DiagnosticsDialog.h"
|
||||
#include "ui_DiagnosticsDialog.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sip/SipHandler.h>
|
||||
#include <network/servent.h>
|
||||
#include <sourcelist.h>
|
||||
#include "accounts/AccountManager.h"
|
||||
#include "network/Servent.h"
|
||||
#include "SourceList.h"
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QDialogButtonBox>
|
||||
@@ -31,7 +32,8 @@
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
|
||||
#include "utils/logger.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "sip/SipHandler.h"
|
||||
|
||||
|
||||
DiagnosticsDialog::DiagnosticsDialog( QWidget *parent )
|
||||
@@ -90,40 +92,43 @@ void DiagnosticsDialog::updateLogView()
|
||||
log.append("\n\n");
|
||||
|
||||
|
||||
// Peers
|
||||
log.append("SIP PLUGINS:\n");
|
||||
QList< Tomahawk::source_ptr > sources = SourceList::instance()->sources( true );
|
||||
Q_FOREACH(SipPlugin *sip, SipHandler::instance()->allPlugins())
|
||||
// Peers / Accounts, TODO
|
||||
log.append("ACCOUNTS:\n");
|
||||
const QList< Tomahawk::source_ptr > sources = SourceList::instance()->sources( true );
|
||||
const QList< Tomahawk::Accounts::Account* > accounts = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType );
|
||||
foreach ( Tomahawk::Accounts::Account* account, accounts )
|
||||
{
|
||||
Q_ASSERT(sip);
|
||||
Q_ASSERT( account && account->sipPlugin() );
|
||||
if ( !account || !account->sipPlugin() )
|
||||
continue;
|
||||
|
||||
QString stateString;
|
||||
switch( sip->connectionState() )
|
||||
switch( account->connectionState() )
|
||||
{
|
||||
case SipPlugin::Connecting:
|
||||
case Tomahawk::Accounts::Account::Connecting:
|
||||
stateString = "Connecting";
|
||||
break;
|
||||
|
||||
case SipPlugin::Connected:
|
||||
case Tomahawk::Accounts::Account::Connected:
|
||||
stateString = "Connected";
|
||||
break;
|
||||
|
||||
case SipPlugin::Disconnected:
|
||||
case Tomahawk::Accounts::Account::Disconnected:
|
||||
stateString = "Disconnected";
|
||||
break;
|
||||
case SipPlugin::Disconnecting:
|
||||
case Tomahawk::Accounts::Account::Disconnecting:
|
||||
stateString = "Disconnecting";
|
||||
}
|
||||
log.append(
|
||||
QString(" %2 (%1): %3 (%4)\n")
|
||||
.arg(sip->name())
|
||||
.arg(sip->friendlyName())
|
||||
.arg(sip->accountName())
|
||||
.arg(stateString)
|
||||
QString( " %2 (%1): %3 (%4)\n" )
|
||||
.arg( account->accountServiceName() )
|
||||
.arg( account->sipPlugin()->friendlyName() )
|
||||
.arg( account->accountFriendlyName())
|
||||
.arg( stateString )
|
||||
);
|
||||
|
||||
Q_FOREACH( const QString &peerId, sip->peersOnline() )
|
||||
foreach( const QString &peerId, account->sipPlugin()->peersOnline() )
|
||||
{
|
||||
/* enable this again, when we check the source has this peerId
|
||||
/* enable this again, when we check the Source.has this peerId
|
||||
bool connected = false;
|
||||
Q_FOREACH( const Tomahawk::source_ptr &source, sources )
|
||||
{
|
||||
@@ -165,7 +170,6 @@ void DiagnosticsDialog::updateLogView()
|
||||
}
|
||||
log.append("\n");
|
||||
}
|
||||
|
||||
ui->logView->setPlainText(log);
|
||||
}
|
||||
|
@@ -1,323 +0,0 @@
|
||||
/* === 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;
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
/* === 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
|
@@ -1,54 +0,0 @@
|
||||
/* === 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 );
|
||||
|
||||
setMinimumSize( 560, 350 );
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
setMaximumSize( 560, 350 );
|
||||
setSizeGripEnabled( false );
|
||||
|
||||
ui->listView->setAttribute( Qt::WA_MacShowFocusRect, false );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
GetNewStuffDialog::~GetNewStuffDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
@@ -1,67 +0,0 @@
|
||||
<?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>
|
@@ -1,156 +0,0 @@
|
||||
/* === 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;
|
||||
}
|
@@ -1,64 +0,0 @@
|
||||
/* === 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
|
@@ -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 2010-2011, Jeff Mitchell <jeff@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
|
||||
@@ -28,7 +29,6 @@
|
||||
|
||||
#define TOMAHAWK_APPLICATION QApplication
|
||||
#include <QApplication>
|
||||
#include "tomahawkwindow.h"
|
||||
|
||||
#endif
|
||||
|
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
|
||||
#include "LoadXSPFDialog.h"
|
||||
#include "TomahawkSettings.h"
|
||||
#include "Source.h"
|
||||
|
||||
#include "ui_LoadXSPFDialog.h"
|
||||
#include <QFileDialog>
|
||||
@@ -44,7 +46,11 @@ LoadXSPFDialog::~LoadXSPFDialog()
|
||||
void
|
||||
LoadXSPFDialog::getLocalFile()
|
||||
{
|
||||
QString url = QFileDialog::getOpenFileName( this, tr( "Load XSPF File" ), QDir::homePath(), tr( "XSPF Files (*.xspf)" ) );
|
||||
const QString path = TomahawkSettings::instance()->importXspfPath();
|
||||
QString url = QFileDialog::getOpenFileName( this, tr( "Load XSPF File" ), path, tr( "XSPF Files (*.xspf)" ) );
|
||||
if ( !url.isEmpty() )
|
||||
TomahawkSettings::instance()->setImportXspfPath( QFileInfo( url ).absoluteDir().absolutePath() );
|
||||
|
||||
m_ui->lineEdit->setText( url );
|
||||
}
|
||||
|
||||
|
@@ -19,7 +19,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Playlist Url</string>
|
||||
<string>Playlist URL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|