wallch-4.0/0000755000175000017500000000000012301477401011272 5ustar alexalexwallch-4.0/data/0000755000175000017500000000000012301477401012203 5ustar alexalexwallch-4.0/data/bash_autocompletion/0000755000175000017500000000000012301477401016242 5ustar alexalexwallch-4.0/data/bash_autocompletion/wallch0000644000175000017500000000066412301477401017445 0ustar alexalex_wallch() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="-h --help --change --start --earth --potd --clock --website --stop --next --previous --pause --cache --fcache --quit --version" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi } complete -o default -o bashdefault -F _wallch wallch wallch-4.0/data/wallch-nautilus.desktop0000644000175000017500000000072012301477401016711 0ustar alexalex[Desktop Entry] Version=4 Name=Wallch Comment=Change desktop wallpapers automatically Exec=/usr/bin/wallch %U Icon=wallch Terminal=false Type=Application Categories=Utility;Application; MimeType=inode/directory; Actions=Change_Wallpaper;Start; [Desktop Action Change_Wallpaper] Name=Change Wallpaper Once Exec=/usr/bin/wallch --change TargetEnvironmet=Unity [Desktop Action Start] Name=Start/Stop Wallpapers Exec=/usr/bin/wallch --start TargetEnvironment=Unity wallch-4.0/data/pixmap/0000755000175000017500000000000012301477401013501 5ustar alexalexwallch-4.0/data/pixmap/wallch.png0000644000175000017500000002670312301477401015471 0ustar alexalexPNG  IHDR>abKGD pHYsttIME6؏vtEXtCommentCreated with GIMPW IDATxwxgy?=l˒-ےd{$v '&@4-o^mCK % $@ ABJo[^򔇼e˒|#ɒ|$/Is]t;sg`:T^.-O}`@:{][\ < ,fCHvĽ{e1ث8n1 5 pU lby@0V8grm( ]@(^p& 5T#8;d 7^cx!jE=1a^>eFgb` 5  ~Z8y30 gdIo 6\ 4]aGŽ5Q1L|t!}D`TX\Ϳ,' )pd欁k͗lg[ Vihb @7_gu6!5Ab@sM vppGV *7Npnz )vN ?XDdu+͌` qp4bX0 @y-oa! %n0P uwApv}X Q>~8a<: @]= ]> 5+<L2d񼧍go;MS`6ëæP & wM"؁O1 w_Y< ^5u7o Mxxo#v]'  "vn(.Lẃ)#)xX" ̀hX^m7^>; T;f1 ك냓giLoD6:B0tL& jl !!0g >b{BM^b/*dy8vMW?uߴG4FCb,Bd8'~8> ǡT΀s`@ذ>a!0rxPQ &gÃ7AJ"\ [C}yo[ < Aw&nTlIpay|˥m`p Rv1+*\`hY=GdJah cCΜ?3T  'ߡRULK؄xι[km?5Co#p>Gyܐ& pvP|e)|v8v^XE"n xDR^~rWMZDPq_rQm 両"d*[%dCaf., r p|iu`Sg]YeP/8]&۰}ZVؘnʚ66 *P ,{ĥ'td&=G|M|Vr3ۦC? +|>!5]khh{+8+_^%KqTWu?i {I+tYg(qii4i8Lw`m(|uٴQp yh7*WÖ}pX?=(-AGp,|c1@,p'IvXgwKi?=&xG 1a0LϑY; [͒"{wzE}`pi}m=/+M޻\rf濎ʲdmb`Llإ; Q4,^ ƶl`(\s;.f-SaL~O[jq;Ji3 F93b/.,ҹ$E峽>Ļ+m/^߬ab̆٣!# .5p~m3tg c%!雨)p R @vTU+sW-B߽f°F: ⠨DљdDepƽD0pKZ܄ ]hSC(` {P/:x]x}8S%0#W!ޣm#=j| *۰W ޢTA!i%mb %nVm}<:S9&KBsH?q=cB\C'E"]EM(C&Eeh4I9!n@/RXe5X[Z({Tt6yzM)IJ5]KR&_vܱpu0<]e~X NGwX=[mkޯdOH[ K(1 ƕll Ơn\dzRPR/&_}p8,DZv5W)ݛP|8tRĎ[0I$L^ιgoEYVnՙ0 >@Z( v!mnC#Nu3R˚![o0u(5}dmFgqy㐨%s`VH#%׍a*l eZwHd]^u!b,`%"+-IhBC~teQnMp"Ѽs*WkI7*laĹW/_o]\nާ}GQeyJ.$9HZq*F` Ly,Ŧ4Zr3Jۭ&N3?$~ JO 8[| AAW0mdiY?ڒr{AfB')V֢VY% 'Kdd?xNf95\$׬F_+4vtV,~Bp?4ni x_] gfh3K{UAD/ߞ#0%(;N`{$:-!sd䷌N glﵨ0WVRSTLT\v?t5(C7r8m e="˚nCQˏ& Nc:o+zˬ4=G9GJP%*:SbK+ U ՘6f򫓨¾#$@``+^I1M~ 8A9?C=7WJHuo k5Y1, w"2gˀ/K.f?ƫyb.:;UHK+#X(fRH0:*\dL2y/ϣCN3keW@_b*RfqeZl[b@_T&tBjV禀%&gyƄ$Dw Xxj% <-ߢ|yG+?vm -~&PRa Q%!Z3q8?ccy ,.y2ȥZN4qR_OCNf5^CN种o'ΟLkK)sfvkGXoJm>H}>Hk+D](,7Pp'y2j8l:䢪Y:]_79&X~d⵰9TlaI m(bӮ7\X!*^A`' TAnf}:2n}T+UsIݎ- ${E#{\KjUfZeL+hy:6m?e>a ]]\RUJ̟ abr\MqAk|][Y@66NKILקNs{I?{r뾋7XTvFWk;S-M zb HoQ9մQ*wLӥ*NKdfI:n7+ڞx`߽RƫcwQ *qrK 7(.h0V) X(a(p#+ +'pLU&][QUN0mQ(k@Pn"1y(7uLSuLTzWmաG-Ķn5*2Cy/:봑Ef1^A.nΪdjȠhYCEjr \LC J~|3.)c|/2h&S)PDIv7U4E'\נ4oa !bx Kn+ũ./QчϦLtQf*fkwoY-H3W08`R'se%JFYpQ^y "~mgB{چ)ve^a|C«\dxun\1MQZ4-1;Ȯ0^ε>ʨB%]Q^=L}뚺èi=^d|ϡ>H%lC^o W1gI *zY|fV?FfY9! \W)XRQa Ԗ] 2 ײX2]!{0WC d'N_^QVS$3NP y@:b*>Y&o?Hqw!U\ TيP#,O%2tsxQ;c6O? R_I&=O͖+j(>htm$- 3hN}_T`܃޴ qQrx1~;j:Va͆_}#E'e{^n &Q&ʶkRmN2A-@JHFb#uܠ.߾n3s`QXO=j _vgR݋9?(@yw AEZb&|%:w(i!/Wo-d_.ŜFW/,%^ĝLs=?j8:u \W|vcFMS桓[~nѸ׀aZPp#{h?yW/,߅w^fHOއ9sSf]xM8vՊnp=RzWb;28C'Chc$Ijz猅cui 4ZHşyJ80xf|icw9 3,`Q--EOfϺMݚ;zEEhZVA6?i1/N[h{l([޹qb>y>3$p~5 !oލ,΃7p'wNl$b2i$(zJC-SǍե8+~3ANYsG $΍;Wk1vBwl9'#߾ƾ| _ljS.;BjA.* r9w,4Y^Zy,Ћ`4痻54YFe(bP?oWm3 NvPgC7ܐX,Ѻ1 6B4x빃5M:@En}F M( o讃k`FB}̭um&q[^4IrnBC;M7hq+J:feӒ:@%~M=|J F%xܒ'W/"׻v" ? Tiqh) <"~ v-(u+uޡ጑:tOp㣅 Pmv\ 1(0 T T̞7c$ W-ӏWce/FCQZ؍@GUG. zBc\J w!{h_nT>4M6J~q5},juiWsgMPCED#LP @j4]Q8Ӝ!rt)BnĎʛpttjH Bs&I+JB76uT{@r=W8i*n4A*p_$Yg)g fv=^W`o-P5Р~)P xȅ5B ׇiAw{f4;Z} ㄷv%n`WS9?٩c4}mnJ s7x ;tQtC=s oryuXCC4'1F#A^m> ]G q{p`k+Ʈ @*j2Ghό]icaNhFEj˨ư6$:ltKONat֚ҷ`v4C"& fpO`AQr4۸KgгrtϢPnI˫goхICR[^I AwEgݓ;CvAB {T2kت;~ƒ2K tUNC{LB3.`yҬ@qXL&?QE\|\7(m'ÏG:iO-Vnʀ5} J5AdU/`7W3hi!b_JU {Q;[{i^4ƥ %8[npku=LB |C͢FNʼnWzk\=FtKbڿQZ4ʥ)A8/.w~{EThM~A(_e?;لՎJA+thZA[xZ{y*Pi\JJ0_5*mXT՞ A,k+ikb|rzeL{aU-ew|e{C1=&{ @R[Ln'+Rt ܠ,`\.NpNrD;qn&y܈,3k㽂(ߑohJ5<Ow1;?77)h0d"C O9$5ICϟц1Wс6VP2rEtphHTm7T {ໟg)$:J:;# Ål6ĴReϢZ!fF 55IJ}z\ڛ l833Y8gpz^PP{,vw8R\8i3>_d^`ާ /Jd\A?ϕ%8;_!6w]w uqu3J"=F>Cd;;*8 ?L&ΜSo¶'*ˇ@-Z m[(rmZ2\ko4w~Wbk8!~WMWQqgq~8Z4}do,'^05:G|7A-jƸPhJe:0#>g&~6twÓo"VWmMlv,{s٪&81:vL)OϑEشO$҄0l? Eojڌk&a]zMIo/YJQﹴ aE(%"LW>$fXA#o.rѧs?OtMl~y\o߱󣃳0~*_b ˍ<)Aۼ_*WcV4]ZՑ/@#Orif{ N@W|2F6g Q'W7ٰGB)#T s.!/U#>ᆽ*1l-rϟ.7O3V4O, ߸KijT=NQ&2:B9dD|1]XewK)y=w>+_P$ʼnl MMVOTI3r4eJT9Ҝ4<6Мr<a.~Ե`:#׽7 oSɲnQ.a0`T8 x<6K)D|e-5O//*!ױPӒ/ ; cpeIxrXK<'j/K+*ƙ3VϽ4,T݅~6P{ '\™]FEqe o(`AL.ft/TK4_}y UAY//x v.8r Sf(Λ[ʭm'3~LSQ-jn\ !yXulSQc!QB]|xf\Bny b"e?vp%7=G(eK:#U>utA&ݧGyW Jѡ H:h, @Vno)>'8'R,% 3Xe.KR͚%lp* HO|r%@zw4ڜFF636J)赻ԣ5@&͑ק^y_Md&?|eUt2n468ے Q% %JG¡E_^'L+6i)ktዋ<~퉶Q'_I _}tq#T?&q4uxa咖mJ@çYa:Y&iJz5WC@`)p &&1#n&}D mWMAMWb p$ m!~j^Ӂ|qO"!`늼љ /L{jlTPÔm @ l*_J]ڠݖYbبG㚙+w'Ԍ,AUѫ}&Om Ʉ˷ >J4*n~!XYp2soU₅. t5*3[n}nTxr'*WVCap%^ $a{M}mYXڧxUo&#YQɻd{s Bsy֍=F?@ &<OlHh5Kמ##Koa1{׍uX`h}W(OЍ[z$PsQTݓt($c}$?)͢VRynC=`o{(pL[8^LHH´B'L-Ba# 9Ml_Xi\A3;Pa%4챳p?ڬAE3_)/ 룡ƚ:jW3>A0!(D^hvG>8IENDB`wallch-4.0/data/translations/0000755000175000017500000000000012301477401014724 5ustar alexalexwallch-4.0/data/translations/wallch_el.ts0000644000175000017500000022522712301477401017240 0ustar alexalex About Website Ιστοσελίδα The Wallch (Wallpaper Changer) authors Οι δημιουργοί του Wallch (Wallpaper Changer) In random order: Σε τυχαία σειρά: Don't click it again. Μην το πατήσεις ξανά. ColorsGradients Select Color Επέλεξε χρώμα CropImage If you want to select a large area, just click on the beggining of it, hold the Shift key and click on the end of it. Άμα θέλετε να επιλέξετε μια μεγάλη περιοχή απλά πατήστε στην αρχή, κρατήστε το shift και μετά πατήστε στο τέλος της. Global Rotation is not supported for GIF files! Η περιστροφή δεν υποστηρίζεται για GIF αρχεία! Error! Σφάλμα! Hey! Γεια! You just won the game. Μόλις νίκησες το παιχνίδι. second δευτερόλεπτο seconds δευτερόλεπτα minute λεπτό minutes λεπτά hour ώρα hours ώρες day μέρα days μέρες Today's Picture Of The Day is not available! Η σημερινή εικόνα της ημέρας δεν είναι διαθέσιμη! Current wallpaper has been changed! Το wallpaper άλλαξε! Time is Η ώρα είναι Pause Παύση Start Αρχή could not be found. Start-up options cannot be enabled. δεν μπορούσε να βρεθεί. Οι επιλογές για την εκκίνηση δεν μπορούσαν να ενεργοποιηθούν. Error Σφάλμα Failed to change wallpaper. If your Desktop Environment is not listed at "Preferences->Integration-> Current Desktop Environment", then it is not supported. Πρόβλημα κατά την αλλαγή φόντου. Αν το περιβάλλον εργασίας σας δεν απαριθμείτε στις"Προτιμήσεις->Ενσωμάτωση->Τρέχων περιβάλλον εργασίας" τότε δεν υποστηρίζεται το Wallch στο σύστημα σας. Failed to change wallpaper. Maybe your Windows version is not supported? Usually Windows XP fail to change .jpg images. Πρόβλημα κατά την αλλαγή φόντου. Ίσως η έκδοση των Windows που έχετε να μην υποστηρίζετε. Συνήθως τα Windows Xp αποτυγχάνουν να αλλάξουν .jpg εικόνες. Failed to change wallpaper. Maybe your Windows version is not supported? Usually Windows XP fails to change JPEG images. Πρόβλημα κατά την αλλαγή φόντου. Ίσως η έκδοση των Windows που έχετε να μην υποστηρίζεται; Συνήθως τα Windows Xp αποτυγχάνουν να αλλάξουν .JPEG εικόνες. History History Entries Καταχωρήσεις This image doesn't seem to exist! Αυτή η εικόνα φαίνεται πως δεν υπάρχει! Picture Of The Day Image Εικόνα της ημέρας Wallpaper Clock Image Εικόνα ρολογιού Live Website Image Εικόνα ζωντανής ιστοσελίδας Open Folder Άνοιξε τον φάκελο Copy path to clipboard Αντιγραφή μονοπατιού στο πρόχειρο (cpipboard) Properties Ιδιότητες Launch in Browser Άνοιξε στον περιηγητή Copy link to clipboard Αντέγραψε τον σύνδεσμο στο πρόχειρο (clipboard) This file maybe doesn't exist or it's not an image. Please perform a check for the file and try again. Αυτό το αρχείο πιθανόν να μην υπάρχει ή να μην είναι εικόνα. Παρακαλώ κάντε έναν έλγχο για το αρχείο και ξαναπροσπαθήστε. Remove this entry Διαγράψτε αυτήν την καταχώρηση Live Earth Image Εικόνα ζωντανής γης LineEditShortCut Warning Προειδοποίηση The key sequence you chose is not valid or it is taken by another application. Ο συνδυασμός τον πλήκτρων που διάλεξες δεν είναι έγκυρος ή χρησιμοποιείτε από κάποια άλλη εφαρμογή. MainWindow hour ώρα &Edit &Επεξεργασία &File &Αρχείο &Help &Βοήθεια &Next &Επόμενη St&op &Σταμάτα This file maybe doesn't exist or it's not an image. Please perform a check for the file and try again. Αυτό το αρχείο πιθανόν να μην υπάρχει ή να μην είναι εικόνα. Παρακαλώ κάντε έναν έλγχο για το αρχείο και ξαναπροσπαθήστε. hours ώρες Copy image to clipboard Αντιγραφή εικόνας στο πρόχειρο &About &Περί &Start &Ξεκίνα Rotate Right Δεξιά Περιστροφή Get Help Online Πάρε Βοήθεια Διαδικτυακά Report A Bug Ανάφερε Bug minutes λεπτά Pau&se &Πάυση Open folder Άνοιγμα φακέλου Properties Ιδιότητες Proceed to next image Προχώρα στην επόμενη εικόνα minute λεπτό Preview Προβολή &Previous &Προηγούμενη Set this item as Background Ορισμός του αντικειμένου ως Background Rotate Left Αριστερή Περιστροφή Stop the wallpaper changing module Σταμάτα το άλλαγμα των wallpaper Statistics Στατιστικά Proceed to previous image Προχώρα στην προηγούμενη εικόνα Copy path to clipboard Αντιγραφή μονοπατιού στο πρόχειρο Start/Pause the wallpaper changing module Ξεκίνα/Παύσε το άλλαγμα των wallpaper Choose Folder Διάλεξε Φάκελο Delete image from disk Διαγραφή εικόνας από τον δίσκο Donate Δωρεά Error Σφάλμα Wallpapers Φόντα οθόνης Live Earth Ζωντανή Γη Wallpaper clocks Φόντα ρολογιού Live Website Ζωντανή ιστοσελίδα Other Άλλα Pictures location: Μονοπάτι εικόνων: My Pictures Οι εικόνες μου Add monitored folders Πρόσθεσε παρακολουθούμενους φακέλους Browse... Αναζήτηση... Interval: Χρονικό διάστημα: Shuffle Τυχαία αναπαραγωγή Activate Picture Of The Day Ενεργοποίησε την Εικόνα Της Ημέρας Deactivate Picture Of The Day Απενεργοποίησε την Εικόνα Της Ημέρας Install Εγκατάσταση Unistall Απεγκατάσταση Deactivate Wallpaper Clock Απενεργοποίησε το Φόντο Ρολογιού Activate Wallpaper Clock Ενεργοποίησε το Φόντο Ρολογιού January,February... Ιανουάριος, Φεβρουάριους... Month Μήνας Day of month Μέρα του μήνα Monday,Tuesday... Δευτέρα, Τρίτη... Day of week Μέρα της εβδομάδας Hour Ώρα Minutes Λεπτά Live Website is a feature that allows you to have a website as your desktop background. Η ζωντανή ιστοσελίδα είναι μια λειτουρηεία που σου επιτρέπει να έχεις μια ιστοσελίδα σαν παρασκήνιο. Website: Ιστοσελίδα: Timeout till giving-up: Χρόνος μέχρι να εγκαταλείψει: Crop the image Περίκοψε την εικόνα Crop Tool Εργαλείο περικοπής Activate Live Website Ενεργοποίησε την Ζωντανή Ιστοσελίδα Deactivate Live Website Απενεργοποίησε την Ζωντανή Ιστοσελίδα Select the default background color Επέλεξε το προεπιλεγμένο χρώμα παρασκηνίου Tile Επαναλαμβανόμενο Zoom Μεγέθυνση Center Κέντρο Scale Κλίμακα Fill Πλήρες Span Γεφύρωμα &Preferences &Προτιμήσεις Preferences Προτιμήσεις Quit Έξοδος Contents Περιεχόμενα &History &Ιστορικό History Ιστορικό Open Current Image's Path Άνοιξε το μονοπάτι του τρέχων παρασκηνίου What is my screen resolution? Ποια είναι η ανάλυση της οθόνης μου; Calculating... Υπολογίζεται... Wallpaper Clock Φόντο ρολογιού Please stop the current process and try again. Σταμάτησε την αλλαγή wallpapers και ξαναδοκίμασε. Import Wallpaper Clock(s) Εισήγαγε φόντο(α) ρολογιού Wallpaper clock already installed. Αυτό το φόντο ρολογιού είναι ήδη εγκαταστημένο. No wallpaper clock has been installed to preview Δεν έχει εγκατασταθεί κάποιο φόντο ρολογιού για προεπισκόπηση day μέρα Invalid address specified! Λάθος διεύθυνση! No wallpaper clock has been selected to preview Δεν έχει επιλεχτεί κάποιο φόντο ρολογιού για προεπισκόπηση Load system's pictures folder Φόρτωσε τις εικόνες του συστήματος What is my Screen Resolution Ποια είναι η ανάλυση της οθόνης μου Picture Of The Day Εικόνα Της Ημέρας Picture of they day viewer Προβολή εικόνων της μέρας Delete Current Image Διέγραψε το τρέχων παρασκήνιο Internet Connection Σύνδεση στο διαδίκτυο There was a problem while trying to download what you requested. Please check your internet connection. Υπήρξε κάποιο πρόβλημε στην προσπάθεια να κατεβάσουμε την εικόνα που ζητήσατε. Παρακαλώ ελέγξτε αν είσται συνδεδεμένοι στο διαδίκτυο. No image selected to preview Δεν έχει επιλεχθεί κάποια εικόνα για προεισκόπηση No live earth has been downloaded to preview Δεν έχει κατεβεί εικόνα του ζωντανού φόντου γης για προεισκόπηση No website image to preview Δεν υπάρχει εικόνα ιστοσελίδας για προεισκόπηση Confirm deletion Επιβεβαιώστε την διαγραφή Error! Σφάλμα! Image deletion failed possibly because you don't have the permissions to delete the image or the image doesn't exist Η διαγραφή της εικόνας απέτυχε λογικά γιατί δεν έχετε την άδεια να την διαγράψετε ή απλά η εικόνα δεν υπάρχει Warning! Προειδοποίηση! Image deletion. Διαγραφή εικόνας. This action is going to permanently delete Αυτή η ενέργεια πρόκειται να διαγράψει τελείως images. Are you sure? εικόνες. Είστε σίγουροι; There was a problem with the deletion of the following files: Υπήρξε πρόβλημα με την διαγραφή των εξής αρχείων: Start from this image Άρχισε από αυτήν την φωτογραφία Open containing folder of all images Άνοιξε τον φάκελο που περιέχει όλες τις εικόνες Delete images from disk Διέγραψε τις εικόνες από τον δίσκο Too many folders to open. Είναι πολλοί οι φάκελοι για να ανοίξουν. This action is going to open Αυτή η ενέργεια πρόκειται να ανοίξει folders. Are you sure? φακέλους. Είστε σίγουροι; Right-click for options Δεξί κλικ για επιλογές We couldn't find your Pictures folder. Δεν μπορούσαμε να βρούμε τον φάκελο των εικόνων. You haven't selected any of the options (day of week etc...), thus the wallpaper clock will not be activated. You can use the wallpaper of the default wallpaper clock as a background, instead. Δεν έχετε επιλέξει κάποια από τις επιλογές (μέρα της βδομάδας κτλπ..), και για αυτό το φόντο ρολογιού δεν θα ενεργοποιηθεί. Μπορείτε να χρησιμοποιήσετε το παρασκήνιο του φόντο ρολογιού όμως. The number above represents your screen/monitor resolution (In width and height). Ο παραπάνω αριθμός αντιπροσωπεύει την ανάλυση της οθόνης σας (σε μήκος και ύψος). Am/Pm Πμ/Μμ Picture of the day is being chosen from Η εικόνα της ημέρας διαλέγεται από την Style Στυλ is highly recommended for this feature , είναι προτεινόμενο για αυτήν την διαδικασία Download wallpaper clocks from Κατέβασε φόντα ρολογιού από seconds δευτερόλεπτα Processing Request Επεξεργάζεται η αίτηση σας week εβδομάδα No picture of the day has been downloaded to preview Δεν έχει κατεβεί κάποια εικόνα της ημέρας για προεισκόπηση Your screen resolution is Η ανάλυση της οθόνης σας είναι Not enough pictures to start chaning wallpapers. Δεν υπάρχουν αρκετές φωτογραφίες ώστε να αρχίσει να αλλάζει παρασκήνια. Are you sure you want to permanently delete the selected image? Είσται σίγουροι ότι θέλετε να διαγράψετε τελείως το τρέχων παρασκήνιο; No default wallpaper clock has been set. Δεν έχει τεθεί προεπιλεγμένο φόντο ρολογιού. You can also drag&drop a .wcz file to install a wallpaper clock Μπορείς επίσης να κάνεις drag&drop ένα .wcz αρχείο για να εγκαταστήσεις ένα φόντο ρολογιού Find an image by name Βρες μια εικόνα από το όνομα της Are you sure you want to permanently delete the current image? Σίγουρα θέλετε να διαγράψετε την τωρινή εικόνα; There was a problem deleting the current image. Please make sure you have the permission to delete the image or that the image exists. Υπήρξε κάποιο πρόβλημα διαγράφοντας την τωρινή εικόνα. Σιγουρέψτε ότι έχετε την άδεια να διαγράψετε την εικόνα ή ότι η εικόνα υπάρχει. Activate Live Earth Ενεργοποίησε την Ζωντανή Γη Deactivate Live Earth Απενεργοποίησε την Ζωντανή Γη Include image description on the picture. Συμπερίλιψη της περιγραφής της εικόνας. Add Login Details Πρόσθεσε λεπτομέρειες εισόδου Username: Όνομα χρήστη: Username Όνομα χρήστη Password: Κωδικός: Password Κωδικός Wallch is a free application developed in our spare time. You can always ask for new features/bug fixes but we need a good motivation to deliver them fast. By making a donation you support the developers and the open source community in general. Το Wallch είναι μια δωρεάν εφαρμογή, αναπτυγμένη στον ελεύθερο μας χρόνο. Μπορείτε πάντα να ρωτήσετε για νέα χαρακτηριστικά/διόρθωση σφαλμάτων αλλά χρειαζόμαστε ένα καλό κίνητρο για να τα φτιάξουμε γρήγορα. Με το να κάνετε μια δωρεά υποστηρίζετε τους προγραμματιστές και την κοινότητα του ελεύθερου κώδικα γενικότερα. How to use Wallch? Πως να χρησιμοποιήσετε το Wallch; Download 1000 HD Wallpapers Κατεβάστε 1000 Υψηλής ανάλυσης εικόνες Wallch is developed by Το Wallch αναπτύχθηκε από την ομάδα Auto Αυτόματα Centered Επίκεντρο Tiled Σκεπασμένο Stretched Τεντωμένο Scaled Κλιμακωτό Zoomed Μεγενθυμένο Empty Άδειο Fit Προσαρμοσμένο Stretch Τέντωμα Location is not available Η τοποθεσία δεν είναι διαθέσιμη referes to a location that is unavailable. αναφέρετε σε μια τοποθεσία που δεν είναι διαθέσιμη. It could be on a hard drive on this computer so check if that disk is properly inserted, or it could be on a network so check if you are connected to the Internet or your network, and then try again. Delete this folder from the list? Θα μπορούσε να είναι σε ένα εξωτερικό δίσκο, οπότε ελέγξτε αν αυτός ο δίσκος είναι κατάλληλα εισαγμένος, ή θα μπορούσε να είναι σε ένα δίκτυο οοτε ελέγξτε αν είστε συνδεδεμένοι στο δίκτυο και προσπαθήστε ξανά. Να διαγράψω αυτόν τον φάκελο από την λίστα; Desktop Backgrounds Φόντα επιφάνειας εργασίας Invalid username or password specified. Δώθηκε λάθος όνομα χρήστη η κωδικό. Changes every ½ hour the desktop background to a flat map that shows the sunlight and the clouds. Internet connection is required. Αλλάζει κάθε μισή ώρα το φόντο σε ένα επιτραπέζιο χάρτη που δείχνει το ηλιακό φώς και τα σύννεφα. Απαιτείτε σύνδεση στο διαδίκτυο. Edit description settings Επεξεργάσου τις ρυθμίσεις για την περιγραφή Learn more about our projects at: Μάθετε περισσότερα για τα project μας στο: Redirect to a certain page Ανακατεύθυνση σε μια συγκεκριμένη σελίδα Current Image Τωρινή εικόνα Copy Name Αντέγραψε το όνομα Copy Path Αντέγραψε το μονοπάτι Copy Image Αντέγραψε την εικόνα Delete Διέγραψε Open Folder Άνοιξε τον φάκελο None Κανένα Learn more about our projects at: Μάθετε περισσότερα για τα projects μας στο: PotdPreview Picture Of The Day Desciption Options Επιλογές για την εικόνα της ημέρας Getting Picture Of The Day Preview Κατεβαίνει μια προεισκόπηση της εικόνας της ημέρας Font to use: Γραμματοσειρά: Description position: Θέση της περιγραφής: Bottom Κάτω Top Πάνω Text Color Χρώμα κειμένου Background Color Χρώμα φόντου Cancel Ακύρωση OK Εντάξει The Picture Of The Day Image used for preview failed to download. Please check your internet connection. Η εικόνα ημέρα για την προεισκόπηση απέτυχε να κατέβει. Ελέγξτε αν είσται συνδεδεμένοι στο δίκτυο. Select Color Επέλεξε χρώμα Left: Αριστερά: Right: Δεξιά: Bottom: Κάτω: Top: Πάνω: Margins Περιθώρια PotdViewer Error! Σφάλμα! You are not connected to internet. Δεν είσται συνδεδεμένοι στο διαδίκτυο. Try another date. Maybe Wikipedia has't selected a picture of the day for: Προσπάθησε μια άλλη ημερομηνία. Ίσως η Wikipedia δεν έχει επιλέξει εικόνα για: Download failed Το κατέβασμα απέτυχε Couldn't find image url. Contact us, and include the specific date that shows this error! Δεν μπορούσε να βρεθεί ο σύνδεσμος της εικόνας. Επικοινωνήστε μαζί μας, αναφέροντας την ημερομηνία που παρουσιάστηκε το πρόβλημα! Save As Αποθήκευση ως Files Αρχεία All Files Όλα τα αρχεία Couldn't find image url. Try another date! Δεν μπορούσα να βρώ το url της εικόνας. Δοκίμασε μια άλλη ημερομηνία! We couldn't find the description for this date Δεν μπορούσαμε να βρούμε περιγραφή για την συγκεκριμένη εικόνα Error Σφάλμα Something went wrong while saving the file! Κάτι πήγε στραβά κατά την αποθήκευση του αρχείου! Save Αποθήκευση Cancel Ακύρωση Downloading Κατεβαίνει Preferences Press here and give a combination Πατήστε εδώ και δώστε έναν συνδυασμό Reset Preferences Επαναφορά Προτιμήσεων Are you sure you want to reset your Wallch preferences? Είστε σίγουροι ότι θέλετε να επαναφέρετε τις προτιμήσεις του Wallch; second δευτερόλεπτο seconds δευτερόλεπτα minute λεπτό minutes λεπτά hour ώρα hours ώρες day μέρα days μέρες Error Σφάλμα Interval Χρόνος already exists. υπάρχει ήδη. You need to have at least two intervals Πρέπει να έχετε τουλάχιστον δύο χρόνους Warning Προειδοποίηση This option will alter your images. You can also rotate your images manually via the right click menu. Αυτή η επιλογή θα μεταβάλει τις εικόνες. Μπορείς επίσης να περιστρέψετε τις εικόνες πατόντας δεξί κλικ στην εικόνα. QObject Confirm deletion Επιβεβαιώστε την διαγραφή Error Σφάλμα There was a problem deleting the current image. Please make sure you have the permission to delete the image or that the image exists. Υπήρξε κάποιο πρόβλημα διαγράφοντας την τωρινή εικόνα. Σιγουρέψτε ότι έχετε την άδεια να διαγράψετε την εικόνα ή ότι η εικόνα υπάρχει. Are you sure you want to permanently delete the current image? Σίγουρα θέλετε να διαγράψετε την τωρινή εικόνα; seconds δευτερόλεπτα minute λεπτό minutes λεπτά hour ώρα hours ώρες day μέρα WebsitePreview Some of the requested pages failed to load successfully. Μερικές από τις ζητούμενες σελίδες απέτυχαν να φορτώσουν. Simple authentication failed. Please check your username and/or password. Η απλή πιστοποίηση απέτυχε. Παρακαλώ ελέγξτε το όνομα χρήστη και/ή των κωδικό. Username and/or password fields are not found. Please check that you are pointing at the login page. Τα πεδία όνομα χρήστη και/ή η κωδικού δεν βρέθηκαν. Παρακαλώ ελέγξτε ότι ζητάτε την σελίδα εισόδου. The timeout has been reached and the image has yet to be created! Το χρονικό όριο έφτασε το όριο του και η εικόνα δεν δημιουργήθηκε! Unknown error! Please try with a different web page. Άγωνστο σφάλμα. Παρακαλώ προσπάθηστε με μια διαφορετική σελίδα. Done! Τέλος! Failed! Απέτυχε! Close Κλείσιμο about About Περί Close Κλείσιμο About Wallch Περί του Wallch Licence Άδεια Translated by Μεταφρασμένο από Wallch allows your desktop wallpaper to change automatically Το Wallch επιτρέπει την αυτόματη αλλαγή του background σας Credits Συντελεστές Written by Γραμμένο από colors_gradients Colors & Gradients Χρώματα & διαβαθμίσεις Solid Color Χρώμα χωρίς διαβαθμίσεις Change Primary Color Άλλαξε το πρωτεύων χρώμα Switch colors Εναλλαγή των χρωμάτων Change Secondary Color Άλλαξε το δευτερεύων χρώμα Remove Background Αφαίρεσε το παρασκήνιο &OK &Εντάξει Shading Type Τύπος σκίασης Vertical Gradient Κάθετη κλίση Horizontal Gradient Οριζόντια κλίση Colors Χρώματα Primary Color Πρωτεύων χρώμα Secondary Color Δευτερεύων χρώμα Result Αποτέλεσμα Set desktop primary color depending on the average color of the current background Άλλαξε το πρωτεύων χρώμα ανάλογα το χρώμα του τρέχων φοντου crop_image Select an area to crop Επιλέξτε μια περιοχή για περικοπή Cancel Ακύρωση &OK &Εντάξει history &Close &Κλείσιμο &Remove History &Διαγραφή Ιστορικού History Ιστορικό nonGUI No default wallpaper clock has been set. Δεν έχει τεθεί προεπιλεγμένο φόντο ρολογιού. The default wallpaper clock does not exist Το προεπιλεγμένο φόντο ρολογιού δεν υπάρχει Show Εμφάνισε Wallpapers Φόντα οθόνης Live Earth Ζωντανό Φόντο Γης Wallpaper Clocks Φόντο ρολογιού Live Website Ζωντανής ιστοσελίδα Preferences Προτιμήσεις About Περί Quit Έξοδος Picture Of The Day Εικόνα Της Ημέρας At least one option (month, hour etc) must be selected for wallpaper clock to start. Τουλάχιστον μια επιλογή (μήνας,ώρα κλπ) πρέπει να είναι επιλεγμένη ώστε να αρχίσει το φόντο ρολογιού. There are not enough valid pictures for the process to continue. Δεν υπάρχουν αρκετές έγκυρες εικόνες για την διαδικασία να συνεχίσει. Folder doesn't exist for the process to continue. Ο φάκελος δεν υπάρχει έτσι ώστε να συνεχίσει η διαδικασία. Current Image Τωρινή εικόνα Open Folder Άνοιξε τον φάκελο Delete Διέγραψε Properties Ιδιότητες Copy Path Αντέγραψε το μονοπάτι Copy Name Αντέγραψε το όνομα Copy Image Αντέγραψε την εικόνα Show In File Browser Δείξε στον περιηγητή αρχείων Exit Έξοδος This file maybe doesn't exist or it's not an image. Please perform a check for the file and try again. Αυτό το αρχείο πιθανόν να μην υπάρχει ή να μην είναι εικόνα. Παρακαλώ κάντε έναν έλγχο για το αρχείο και ξαναπροσπαθήστε. You cannot change wallpapers if they are less than 2! Δεν μπορείς να αλλάξεις εικόνες άμα είναι λιγότερες από δύο! The default folder has changed. Ο αθετούμενος φάκελος άλλαξε. Pause Παύση Next Επόμενο Previous Προηγούμενο Start Ξεκίνα Change wallpaper once Άλλαξε φόντο μια φορά Information Πληροφορίες potd_viewer Picture of the day viewer Προβολή εικόνων της μέρας Previous day Προηγούμενη μέρα Next day Επόμενη μέρα Save Image Αποθήκευσε την εικόνα Close Κλείσιμο preferences &Save &Αποθήκευση Save and close the dialog Αποθήκευση και κλείσιμο διαλόγου &Close &Κλείσιμο Notification on Wallpaper change Ειδοποίηση στην αλλαγή φόντου Reset Preferences Επαναφορά Προτιμήσεων Preferences Προτιμήσεις Reset preferences to the default onces Επαναφορά προτιμήσεων στις αρχικές Polish (pl) Πολωνικά (pl) General Γενικά Arabic (su) Αραβικά (su) Bosnian (bs) Βοσνιακά (bs) Croatian (hr) Κροατικά (hr) Danish (da) Δανέζικα (da) French (fr) Γαλλικά (fr) German (de) Γερμανικά (de) Hebrew (he) Εβραϊκά (he) Italian (it) Ιταλικά (it) Norwegian (nb) Νορβηγικά (nb) Portuguese (pt) Πορτογαλικά (pt) Russian (ru) Ρώσσικα (ru) Slovak (sk) Σλοβακική (sk) Spanish (es) Ισπανικά (es) Swedish (sv) Σουηδικά (sv) Turkish (tr) Τούρκικα (tr) Integration Ενσωμάτωση On clicking 'Start' first timeout then change wallpaper Όταν πατήσεις "Ξεκίνημα" το Wallch θα περιμένει το χρονικό όριο και μετά θα αλλάξει φόντο Style of list: Στυλ της λίστας: Icons Εικονίδια Paths Μονοπάτια Set Up Custom Intervals Επέλεξε προσαρμοσμένους χρόνους Add Πρόσθεσε second(s) δευτερόλεπτο(α) minute(s) λεπτό(ά) hour(s) ώρα(ες) day(s) μέρα(ες) Remove Διέγραψε Use random time instead of the above intervals: Χρησιμοποίησε τυχαίο χρόνο αντί των παραπάνω χρόνων: From: Από: seconds δευτερόλεπτα to: πρός: Keep History of wallpapers changed Κράτα ιστορικό για τα φόντα που έχουν αλλάξει (You will need to restart Wallch) (Θα πρέπει να επανεκκινήσετε το Wallch) Enable Unity ProgressBar Ενεργοποίησε την γραμμή προόδου των Unity (Will also change indicator icon) (Θα αλλάξει επίσης το εικονίδιο του indicator) Rotate image on change, based on Exif data (will alter image) Περίστρεψε την εικόνα, βάση των δεδομένων Exif (θα μεταβάλλει την εικόνα) Interval independent of application close Οι χρόνοι να είναι ανεξάρτητοι από το κλείσιμο της εφαρμογής Autodetect Αυτόματη ανίχνευση Theme: Θέμα: Dutch (nl) Ολλανδικά (nl) Startup timeout: Χρονική καθυστέρηση στην εκκίνηση: Wallch will wait the above time before launching Το Wallch θα περιμένει τον παραπάνω χρόνο πριν τρέξει Wallpapers Φόντα οθόνης Live Website Ζωντανό δίκτυο For wallpaper clocks, show notification only when hour changes Για τα φόντο ρολογιού, δείξε ειδοποίηση μόνο όταν αλλάζει η ώρα Start Wallch on System's startup Άνοιξε το Wallch στην εκκίνηση του συστήματος It will continue the feature that was previously running Θα συνεχίσει το χαρακτηριστικό που προηγουμένως έτρεχε If the feature that was previously running was 'Wallpapers', Wallch will pick a random picture and change the desktop background once at System Startup Άμα το χαρακτηριστικό που έτρεχε πριν είναι το 'Φόντα Οθόνης', το Wallch θα επιλέξει μια τυχαία εικόνα και θα αλλάξει το φόντο μια φορά στην εκκίνηση του συστήματος Javascript is enabled H Javascript να είναι ενεργοποιημένη Javascript can read clipboard Η javascript μπορεί να διαβάζει το πρόχειρα (clipboard) Java is enabled To Java να είναι ενεργοποιημένο Load Images Φόρτωσε εικόνες Add more username fields (comma separated): Πρόσθεσε περισσότερα ονόματα χρήστη (χωρισμένα με κώμα): Add more password fields (comma separated): Πρόσθεσε παραπάνω κωδικούς (χωρισμένους με κόμμα): Attempt simple (popup) login authentication Προσπάθησε μια απλή είσοδο ταυτότητας After load is finished, prior to taking the snapshot, wait Αφού έχει φορτώσει,πριν πάρει στιγμιότυπο,το Wallch να περιμένει Current Desktop Environment Το τωρινό περιβάλλον εργασίας (Desktop Environment) Help Βοήθεια Below settings change the behaviour only for the 'Wallpapers' feature Παρακάτω είναι ρυθμίσεις που αλλάζουν την συμπεριφορά μόνο για το 'Wallpapers' Below settings change the behaviour only for the 'Live Website' feature Παρακάτω είναι ρυθμίσεις που αλλάζουν την συμπεριφορά μόνο για τo 'Live Website' Username or email Όνομα χρήστη ή email Password Κωδικός Show preview screen Δείξε την οθόνη προεπισκόπησης Language: Γλώσσα: English (en) Αγγλικά (en) Greek (el) Ελληνικά (el) Use Shortcut for the "Next Wallpaper": Χρησιμοποίησε συντόμευση για το "Επόμενο Φόντο": properties Name: Όνομα: Size: Μέγεθος: &Close &Κλείσιμο Width: Πλάτος: Properties Ιδιότητες Location: Τοποθεσία: Height: Ύψος: Set as Background Θέσε ώς φόντο οθόνης Dimensions: Διαστάσεις: Image Type: Τύπος εικόνας: Created: Δημιουργήθηκε: Modified: Επεξεργάστηκε: Open Image's Location Ανοιγμά φακέλου εικόνας statistics &OK &Εντάξει &Reset &Επαναφορά Program's uptime: Το πρόγραμμα τρέχει: Launched times of program: Το πρόγραμμα έχει ανοιχτεί: Statistics Στατιστικά Wallpapers changed: Φόντα που έχουν αλλάξει: Total: Σύνολο: Current Session: Τρέχουσα περίοδο: website_preview Preview Live Website with your preferences Προεπισκόπηση της ζωντανής ιστοσελίδας με τις ρυθμίσεις Cancel Ακύρωση Generating Image... Δημιουργείται η εικόνα... Timeout till giving-up: Χρόνος μέχρι να εγκαταλείψει: wallch-4.0/data/to_usr_share/0000755000175000017500000000000012301477401014700 5ustar alexalexwallch-4.0/data/to_usr_share/wallch/0000755000175000017500000000000012301477401016152 5ustar alexalexwallch-4.0/data/to_usr_share/wallch/translations/0000755000175000017500000000000012301477401020673 5ustar alexalexwallch-4.0/data/to_usr_share/wallch/translations/wallch_pt.ts0000644000175000017500000030354412301477401023231 0ustar alexalex About Website Website The Wallch (Wallpaper Changer) authors Os autores do Wallch (Wallpaper Changer) In random order: Em ordem aleatória: Don't click it again. Não clicar outra vez. ColorsGradients Select Color Selecionar Cor CropImage If you want to select a large area, just click on the beggining of it, hold the Shift key and click on the end of it. Para selecionar uma ára grande, clique no início, pressione a tecla Shift e sem largar clique no fim. Global Rotation is not supported for GIF files! A rotação não é suportada nos ficheiros GIF! Error! Erro! Hey! Ei! You just won the game. Acaba de ganhar o jogo. Time is A hora é second segundo seconds segundos Pause Pausa Start Iniciar could not be found. Start-up options cannot be enabled. não foi encontrado. As opções de arranque não podem ser ativadas. minute minuto Today's Picture Of The Day is not available! Hoje a Fotografia do Dia não está disponível! Error Erro Failed to change wallpaper. If your Desktop Environment is not listed at "Preferences->Integration-> Current Desktop Environment", then it is not supported. Falha ao mudar o fundo de parede. Se o seu Ambiente de Trabalho não estiver listado em "Prefências->Integração->Ambiente de Trabalho Atual", então não é suportado. Failed to change wallpaper. Maybe your Windows version is not supported? Usually Windows XP fail to change .jpg images. Falah ao mudar o fundo de parede. Possivelmente esta versão do Windows não é suportada. Normalmente o Windows XP falha ao mudar imagens .jpg. Current wallpaper has been changed! O papel de parede atual foi alterado! minutes minutos hour hora hours horas day dia days dias History History Entries Items do Histórico This image doesn't seem to exist! Esta imagem não parece existir! Live Earth Image Imagem do Mundo Em Direto Picture Of The Day Image Imagem Fotografia do Dia Wallpaper Clock Image Imagem Relógio no Fundo de Parede Live Website Image Imagem Website Em Direto Open Folder Abrir Pasta Copy path to clipboard Copiar caminho para o clipboard Properties Propriedades Launch in Browser Executar no Navegador Copy link to clipboard Copiar ligação para o clipboard This file maybe doesn't exist or it's not an image. Please perform a check for the file and try again. Possivelmente não existe este ficheiro ou não é uma imagem. Por favor verifique o ficheiro e tente novamente. Remove this entry Remover este item LineEditShortCut Warning Aviso The key sequence you chose is not valid or it is taken by another application. A sequências de teclas escolhida não é válida ou já está a ser usada por outra aplicação. MainWindow Preview Pre-visualizar Proceed to previous image Proseguir para a imagem anterior &Previous &Anterior Proceed to next image Proseguir para a próxima imagem &Next &Próxima Start/Pause the wallpaper changing module Iniciar/Pausar o módulo de mudnaça do wallpaper Wallpapers Fundos de Parede Live Earth Mundo Em Direto Wallpaper clocks Relógios de fundos de parede Live Website Website Em Direto Picture Of The Day Fotografia Do Dia Other Outro Pictures location: Localização das fotografias: My Pictures As Minhas Fotografias Add monitored folders Adicionar pastas monitoradas Browse... Pesquisar... &Start &Iniciar Stop the wallpaper changing module Parar o módulo de mudnaça do fundo de parede St&op P&arar Interval: Intervalo: Shuffle Baralhar Activate Picture Of The Day Activar a Fotografia Do Dia Deactivate Picture Of The Day Desactivar a Fotografia Do Dia Picture of they day viewer Visualizador da Fotografia do dia You can also drag&drop a .wcz file to install a wallpaper clock Também pode arrastar&largar um ficheiro .wcz para instalar um relógio de papel de parede Install Instalar Unistall Desinstalar Deactivate Wallpaper Clock Desativar Relógio de Papel de Parede Activate Wallpaper Clock Ativar Relógio do Papel de Parede Activate Live Earth Ativar o Mundo em Direto Deactivate Live Earth Desativar o Mundo em Direto Include image description on the picture. Incluir a descrição da imagem na fotografia. January,February... Janeiro, Fevereiro... Month Mês Day of month Dia do mês Monday,Tuesday... Segunda, Terça... Day of week Dia da semana Hour Hora Minutes Live Website is a feature that allows you to have a website as your desktop background. Website em Direto é uma funcionalidade que permite que tenha uma página web como fundo da área de trabalho. Website: Website: Add Login Details Adicionar Detalhes do Login Username: Nome de utilizador: Username Nome de utilizador Password: Palavra passe: Password Palavra passe Timeout till giving-up: Tempo de espera até desistir: Crop the image Cortar a imagem Crop Tool Ferramenta de Corte Activate Live Website Ativar o Website em Direto Deactivate Live Website Desativar o Website em Direto Download 1000 HD Wallpapers Descarregar 1000 Papeis de Parede em HD Delete Current Image Apagar a Imagem Atual Select the default background color Selecionar a cor por omissão do fundo Tile Em Mosaico Zoom Ampliar Center Centrar Scale Escalar Fill Preencher Span Expandir &File &Ficheiro Open Current Image's Path Abrir o Caminho da Imagem Atual What is my screen resolution? Qual a resolução do meu ecrã? &Edit &Editar Changes every ½ hour the desktop background to a flat map that shows the sunlight and the clouds. Internet connection is required. Mudar o fundo da área de trabalho a cada ½ hora para um mundo plano que mostra a luz solar e as nuvens. É requerida uma ligação à internet. Edit description settings Editar a descrição das definições Redirect to a certain page Redirecionar para uma determinada página Wallch is a free application developed in our spare time. You can always ask for new features/bug fixes but we need a good motivation to deliver them fast. By making a donation you support the developers and the open source community in general. Wallch é uma aplicação livre desenvolvida no nosso tempo livre. Pode pedir novas funcionalidades/resolução de erros mas nós precisamos de uma boa motivação para as implementar rapidamente. ao fazer uma doação irá suportar os desenvolvedores e a comunidade open-source em geral. &Help A&juda &About Acerca &de Report A Bug Reportar Um Problema Get Help Online Procurar Ajuda Online How to use Wallch? Como usar o Wallch? Statistics Estatísticas Donate Doar Am/Pm Am/Pm &Preferences &Preferências Preferences Preferências Quit Sair Contents Conteúdo &History &Histórico History Histórico Calculating... A calcular... Wallpaper Clock Relógio de Papel de Parede Set this item as Background Defina este item como Fundo Picture of the day is being chosen from A Fotografia do dia é escolhida a partir de Style Estilo is highly recommended for this feature é altamente recomendável para esta funcionalidade Download wallpaper clocks from Descarregar fundos da área de trabalho a partir de seconds segundos Processing Request A processar o pedido week semana No picture of the day has been downloaded to preview Não foi descarregada nenhuma fotografia do dia para pré-visualizar Not enough pictures to start chaning wallpapers. Não há fotografias suficientes para iniciar a mudanças de fundos da área de trabalho. Are you sure you want to permanently delete the selected image? Tem a certeza que deseja apagar de forma permanente a imagem selecionada? Delete image from disk Apagar imagem do disco Rotate Right Rodar à Direita Rotate Left Rodar à Esquerda Copy path to clipboard Copiar caminho para o clipboard Copy image to clipboard Copiar a imagem para o clipboard Open folder Abrir directoria Properties Propriedades No default wallpaper clock has been set. Não foi definido nenhum relógio de papel de parede por omissão. Please stop the current process and try again. Por favor termine o processo actual e tente novamente. Import Wallpaper Clock(s) Importar Relógio(s) do Fundo da Área de Trabalho Wallpaper clock already installed. Relógio do Fundo da Área de Trabalho já instalado. No wallpaper clock has been installed to preview Não foi instalado nenhum relógio do Fundo da Área de Trabalho para pré-visualizar Learn more about our Projects at: Saiba mais acerca dos nossos projetos em: Internet Connection Ligação à Internet There was a problem while trying to download what you requested. Please check your internet connection. Ocoreu um problema ao tentar descarregar o seu pedido. Verifique a sua ligação à internet. No image selected to preview Não foi selecionada nenhuma imagem para pré-visualizar No live earth has been downloaded to preview Não foi descarregado nenhum mundo em direto para pré-visualizar No website image to preview Não há nenhuma imagem de website para pré-visualizar Confirm deletion Confirmar apagar Error! Erro! Image deletion failed possibly because you don't have the permissions to delete the image or the image doesn't exist Exclusão da imagem falhou possivelmente porque não tem as permissões para apagar a imagem ou a imagem não existe Warning! Aviso! Image deletion. Exclusãio da Imagem. This action is going to permanently delete Esta ação irá apagar de forma permanente images. Are you sure? imagens. Tem a certeza? There was a problem with the deletion of the following files: Ocorreu um problema com a exclusão dos seguintes ficheiros: Start from this image Iniciar nesta imagem Find an image by name Procurar uma imagem por nome Open containing folder of all images Abrir a pasta que contém todas as imagens Delete images from disk Apagar imagens do disco Too many folders to open. Demasiadas pastas para abrir. This action is going to open Esta ação irá abrir folders. Are you sure? pastas. Tem a certeza? Right-click for options Clique-direito para opções We couldn't find your Pictures folder. Não encontrada a pasta das suas Fotografias. You haven't selected any of the options (day of week etc...), thus the wallpaper clock will not be activated. You can use the wallpaper of the default wallpaper clock as a background, instead. Não selecionou nenhuma opção (dia da semana, etc...), por isso o relógio do fundo da área de trabalho não será ativado. Em contrapartido, pode usar o fundo da área de trabalho por omissão do relógio como fundo. Are you sure you want to permanently delete the current image? Tem a certeza que deseja apagar definitivamente a imagem atual? There was a problem deleting the current image. Please make sure you have the permission to delete the image or that the image exists. Ocorreu um problema ao apagar a imagem atual. Verifique se tem permissões para apagar a imagem e que a mesma existe. Your screen resolution is A sua resolução de ecrã é The number above represents your screen/monitor resolution (In width and height). O número acima representa a resolução do seu monitor/ecrã (em lagura e altura). day dia Invalid address specified! Especificado um endereço inválido! No wallpaper clock has been selected to preview Não foi especificado nenhum relógio do Fundo da Área de Trabalho para pré-visualizar Choose Folder Escolha a Pasta Load system's pictures folder Carregar a pasta de fotografias do sistema What is my Screen Resolution Qual a resolução do meu ecrã Error Erro Pau&se Pau&sa Invalid username or password specified. Nome de utilizador e palavra-passe inválida. This file maybe doesn't exist or it's not an image. Please perform a check for the file and try again. Possivelmente não existe este ficheiro ou não é uma imagem. Por favor verifique o ficheiro e tente novamente. minute minuto Wallch is developed by Wallch é desenvolvido por Auto Auto Centered Centrado Tiled Em Mosaico Stretched Esticado Scaled Escalado Zoomed Ampliado Empty Vazio Fit Caber Stretch Esticar minutes minutos hour hora hours horas Location is not available Localização não disponível referes to a location that is unavailable. refere-se a uma localização não disponível. It could be on a hard drive on this computer so check if that disk is properly inserted, or it could be on a network so check if you are connected to the Internet or your network, and then try again. Delete this folder from the list? Poderá estar num disco rígido no computador pelo que verifique se esse disco está inserido corretamente, ou poderá estar numa rede pelo que verifique se está ligado à Internet ou à rede e tente novamente. Apagar esta pasta na lista? Desktop Backgrounds Fundos da Área de Trabalho PotdPreview Picture Of The Day Desciption Options Descriçãos das Opções da Fotografia Do Dia Getting Picture Of The Day Preview A buscar a Pr-visualização da Fotografia Do Dia Font to use: Fonte a usar: Description position: Posição da descrição: Bottom Fundo Top Topo Text Color Cor do Texto Background Color Cor do Fundo Margins Margens Left: Esquerda: Right: Direita: Bottom: Fundo: Cancel Cancelar OK OK Top: Topo: The Picture Of The Day Image used for preview failed to download. Please check your internet connection. Falhou a descarga da pre-visualização da imagem Fotografia Do Dia. Verifique a ligação à internet. Select Color Selecionar a Cor PotdViewer Error! Erro! You are not connected to internet. Não está ligado à internet. Try another date. Maybe Wikipedia has't selected a picture of the day for: Tente uotra data. Possivelmente o Wikipedia não selecionou a fotografia do dia para: Download failed Descarga falhada Couldn't find image url. Try another date! Endereço da imagem não encontrado. Tente outra data! We couldn't find the description for this date Não foi possível encontrar a descrição para esta data Couldn't find image url. Contact us, and include the specific date that shows this error! Endereço da imagem não encontrado. Contacte-nos, e inclua a data específica que provocou este erro! Save As Guardar Como Files Ficheiros All Files Todos os Ficheiros Error Erro Something went wrong while saving the file! Ocorreu um erro enquanto o ficheiro era gravado! Save Guardar Cancel Cancelar Downloading Descarregar Preferences Press here and give a combination Pressione aqui e introduza uma combinação Reset Preferences Reiniciar Preferências Are you sure you want to reset your Wallch preferences? Tem a certeza que deseja reiniciar as preferências do Wallch? second segundo seconds segundos minute minuto minutes minutos hour hora hours horas day dia days dias Error Erro Interval Intervalo already exists. já existe. You need to have at least two intervals Tem de indicar pelo menos dois intervalos Warning Aviso This option will alter your images. You can also rotate your images manually via the right click menu. Esta opção irá alterar as suas imagens, Tembém pode rodar as imagens manualmente usando o menu do clique direito. QObject seconds segundos minute minuto minutes minutos hour hora hours horas day dia Confirm deletion Confirmar apagar Are you sure you want to permanently delete the current image? Tem a certeza que deseja apagar definitivamente a imagem atual? Error Erro There was a problem deleting the current image. Please make sure you have the permission to delete the image or that the image exists. Ocorreu um problema ao apagar a imagem atual. Verifique se tem permissões para apagar a imagem e que a mesma existe. WebsitePreview Some of the requested pages failed to load successfully. Algumas das páginas requeridas falharam no carregamento. Simple authentication failed. Please check your username and/or password. Autenticação simples falhada. Por favor verifique o nome de utilizador e/ou a palavra-passe. Username and/or password fields are not found. Please check that you are pointing at the login page. Os campos nome e/ou palavra-passe não foram encontrados. Verifique que está a apontar para a página de autenticação. The timeout has been reached and the image has yet to be created! O tempo de espera foi ultrapassado e a imagem não foi criada! Unknown error! Please try with a different web page. Erro desconhecido! Por favor tente uma página web diferente. Done! Feito! Failed! Falhou! Close Fechar about About Wallch Acerca de Wallch Close Fechar Credits Créditos Licence Licença About Acerca de Wallch allows your desktop wallpaper to change automatically Wallch possibilita a mudança do wallpaper automaticamente Written by Escrito por Translated by Traduzido por colors_gradients Colors & Gradients Cores & Gradientes Solid Color Cor Sólida Change Primary Color Mudar a Cor Primária Switch colors Trocar cores Shading Type Tipo de Sombra Vertical Gradient Gradiente Vertical Horizontal Gradient Gradiente Horizontal Colors Cores Primary Color Cor Primária Secondary Color Cor Secundária Change Secondary Color Mudar Cor Secundária Result Resultado Set desktop primary color depending on the average color of the current background Definir a cor primária da área de trabalho dependendo da média de cores do fundo atual Remove Background Remover o Fundo &OK &OK crop_image Select an area to crop Selecionar a área a cortar Cancel Cancelar &OK &OK history History Histórico &Remove History &Remover Histórico &Close Fe&char nonGUI No default wallpaper clock has been set. Não foi definido nenhum relógio de papel de parede por omissão. The default wallpaper clock does not exist O relógio do papel de parede por omissão não existe At least one option (month, hour etc) must be selected for wallpaper clock to start. Tem de ser selecionada pelo menos uma opção (mês, hota, etc...) para que o relógio do papel de parede se inicie. Show Mostrar Wallpapers Papeis de Parede Change wallpaper once Mudar o papel de parede uma vez Pause Pausa Next Seguinte Previous Anterior Picture Of The Day Fotografia Do Dia Live Earth Mundo Em Direto Wallpaper Clocks Relógios de fundos de parede Live Website Website Em Direto There are not enough valid pictures for the process to continue. Não existem fotografias válidas suficientes para que o processo continue. Folder doesn't exist for the process to continue. A pasta não existe para que o processo continue. Current Image Imagem Atual Open Folder Abrir Pasta Delete Apagar Properties Propriedades Preferences Preferências About Acerca de Quit Sair Copy Path Copiar Caminho Copy Name Copiar Nome Copy Image Copiar Imagem Show In File Browser Mostrar no Ficheiros Exit Sair Start Iniciar This file maybe doesn't exist or it's not an image. Please perform a check for the file and try again. Possivelmente não existe este ficheiro ou não é uma imagem. Por favor verifique o ficheiro e tente novamente. You cannot change wallpapers if they are less than 2! Não pode mudar de papeis de parede se existirem menos de 2! The default folder has changed. A pasta por omissão foi alterada. potd_viewer Picture of the day viewer Visualizar a fotografia do dia Previous day Dia anterior Next day Dia seguinte Save Image Guardar Imagem Close Fechar preferences Preferences Preferências Integration Integração Rotate image on change, based on Exif data (will alter image) Rodar a imagem ao mudar, basiado nos dados Exif (irá alterar a imagem) Interval independent of application close Intervalo independente do fecho da aplicação (You will need to restart Wallch) (Será necessário reiniciar o Wallch) Enable Unity ProgressBar Ativar a barra de progresso do Unity (Will also change indicator icon) (Também irá alterar o ícone indicador) Start Wallch on System's startup Iniciar o Wallch no arranque do sistema It will continue the feature that was previously running Irá continuar a funcionalidade que estava previamente a executar If the feature that was previously running was 'Wallpapers', Wallch will pick a random picture and change the desktop background once at System Startup Se a funcoinalidade que estava previamente a executar era 'Fundos da Área de Trabalho', o Wallch irá escolher aleatoriamente uma fotografia e mudar o fundo da área de trabalho uma vez no Arranque do Sistema Use Shortcut for the "Next Wallpaper": Usar um Atalho para o 'Fundo da Área de Trabalho Seguinte': Javascript is enabled Javascript está ativado Javascript can read clipboard Javascript pode ler o clipboard Java is enabled Javascript ativado Load Images Carregar Imagens Add more username fields (comma separated): Adicionar mais campos para o nome de utilizador (separados por vírgula): Add more password fields (comma separated): Adicionar mais campos para a palabra-passe (separados por vírgula): Attempt simple (popup) login authentication Tentar autenticação simples (popup) After load is finished, prior to taking the snapshot, wait Depois do arranque terminado, antes de tirar um instantâneo, esperar Username or email Nome de utilizador ou email Password Palavra passe Current Desktop Environment Ambiente de Trabalho Atual Help Ajuda Reset preferences to the default onces Reiniciar preferências para as por omissão Reset Preferences Reiniciar Preferências &Close Fe&char Save and close the dialog Guardar e fechar a caixa de diálogo &Save &Guardar Polish (pl) Polaco (pl) Below settings change the behaviour only for the 'Wallpapers' feature A definições abaixo apenas alteram o comportamento para a funcionalidade 'Fundos da Área de Trabalho' On clicking 'Start' first timeout then change wallpaper Ao clicar 'Iniciar' primeiro o tempo de espera e depois muda o fundo da área de trabalho Style of list: Estilo da lista: Icons Icónes Paths Caminhos Set Up Custom Intervals Definir Intervalos Personalizados Add Adicionar second(s) segundo(s) minute(s) minutos(s) hour(s) hora(s) day(s) dia(s) Remove Remover Use random time instead of the above intervals: Usar um tempo aleatório em vez dos intervalos acima indicados: From: De: seconds segundos to: para: Keep History of wallpapers changed Guardar os Histórico de papeis de parede alterados Dutch (nl) Holandês (nl) Startup timeout: Tempo de espera de arranque: Wallch will wait the above time before launching o Wallch irá esperar o tempo definido acima antes de executar Below settings change the behaviour only for the 'Live Website' feature A definições abaixo apenas alteram o comportamento para a funcionalidade 'Website em Direto' Theme: Tema: Autodetect Auto-detetar Arabic (su) Árabe (su) Wallpapers Papeis de Parede Live Website Website Em Direto For wallpaper clocks, show notification only when hour changes Para relógios do fundo da área de trabalho, mostra uma notificação apenas quando a hora muda Show preview screen Mostra o ecrã de pré-visualização Language: Língua: Bosnian (bs) Bósnia (bs) Croatian (hr) Croata (hr) Danish (da) Dinamarquês (da) English (en) Inglês (en) French (fr) Francês (fr) German (de) Alemão (de) Greek (el) Grego (el) Hebrew (he) Hebraico (he) Italian (it) Italiano (it) Norwegian (nb) Norueguês (nb) Portuguese (pt) Português (pt) Russian (ru) Russo (ru) Slovak (sk) Eslováco (sk) Spanish (es) Espanhol (es) Swedish (sv) Suéco (sv) Turkish (tr) Turco (tr) Notification on Wallpaper change Avisar aquando da mudança do wallpaper General Geral properties Properties Propriedades Width: Largura: Location: Localização: Height: Altura: Dimensions: Dimensões: Name: Nome: Image Type: Tipo de Imagem: Created: Criado: Modified: Modificado: Set as Background Definir como Fundo Open Image's Location Abrir a Localização da Imagem &Close Fe&char Size: Tamanho: statistics Statistics Estatísticas Program's uptime: Tempo em execução: Wallpapers changed: Papel de parede alterado: Launched times of program: Execuções do programa: Total: Total: Current Session: Sessão Atual: &Reset &Reiniciar &OK &OK website_preview Preview Live Website with your preferences Pre-visualizar o Website Em Direto com as suas preferências Cancel Cancelar Generating Image... A gerar a imagem... Timeout till giving-up: Tempo de espera até desistir: wallch-4.0/data/to_usr_share/wallch/files/0000755000175000017500000000000012301477401017254 5ustar alexalexwallch-4.0/data/to_usr_share/wallch/files/indicator_radiance_normal.png0000644000175000017500000001120412301477401025132 0ustar alexalexPNG  IHDR@@iqbKGD pHYst$IDATx[il\uνo,D"(QhdK8qȰF ƭ4F"Ni 844hPi:تزDY4XP\E g޻!9HKnx,o9|Kmy[_U8Eh&<쳿Qط (+ :\X__?Hm8q.K.s.0Ɯ#A6+baill̶ں:%yd#D`5-Tԭs Z={ItddH,} VA$Ua."9R__?TSSΝ [Z+ldE$$.UaP 0"oƘA{fpMGi瓨#NrR' DIK2J2A( b5-|O5m<_w3ꂵιE$o y+m$W,(@j(Tpƅ< )^g1y>dWv\{+8* n I I`"‚WOLɟOx@'ypbÆ m "d'䢋ZpOzPY9aⒺWZn&dYcJH7\0_+[" $=;9}Wߚ4wqxD$N26CI7.P`b Xҕ?{v;1u͙Z m۶9ٍ$A%Ŭ9ϰ~Ac^1e'y0Br1҃Ijs6رv9s c&nfҺӕOݽ9kƘg@qW$ɈSՕeee=͸yWpqg BdD @UG2g%$ZIrWՍ$[THxD1ƘSNA~A$S}ǏꂱƸ15ugsc']$3<3ZF lڴ AP("8u7BJ?Ovj9."{}!cDn݊Ѕ0b'C`b_O܍$K:ƽ}v<X~}t|||y7:ޥkI֐tzD"᏾'{-HYxtEg"l^|kVpmڴ ee8WAs:UMȊȰȹD"1堪DD"*wNac- @c ))xs'S{?555SfDD~uaؽg{LT8UPeͬXWU=ƍﺾֺ0 Apomum4X__-$`(3ڴ0 i%]c+aakk֭Xb,\(R[[566%Kpk|UU:-QTI͛qѩtvv" `B#<@|k$7BizU"[W$ti3T*0Ӆ0 CcLouu5k}_tsHRWjt!y\1͈iN0#ktf$?raz(T.OU?A5$ 'nB1ǝsYr7(c |ϤRRնͱ0 g u8t/"'D?vZ$eeea0ɵ$eJ(%Qp!jF1c>qG믉L"3mʌTbEԍXsX&#\6 0Iw+U9i* @EdƗUTUA,#YaИөpɒbe9fz}r;w)_  '(7~H+|hרj9g`aCw(--ׂzzzk|!sDDBdk.\%KflsR+Ca8K2QH YAyy~Y&DOR2WpeƍfF5ZErF1YgkZȗH$~{{5`dd#PBaaqffm__\I O{aa9䜻1tApO^q7bÆ  zu!1=s֚a{ia紘-[ ܪk =ϩ\.wsnبOgzMpa^U7y9km=@DN!Yo%$0؜7t:D"9%C@ZD6[kѱ$ؙjokkC2*w9-Ft."9e3QJqR9/*ssnK~eZFWU8޳w^mett+J0|/q1Y]S1HXkQ^^6˶ PwQܜ / D32dD"c18pVB:F*jsuNxcٽ[cr~ G.#J 2|1T0AιJׇTj R)`E>_c?L {'JZ4MMMO]ݻcL/NZGUgR΅7'y3KsWpcdd0/D',`ž}dFgT8^f)3˜sQUjvڅ +K=ڑ>~~Dۇ6cP雡^˗7ɚ5k}p.'uajXlXa~XUmްO5zu!HDN>}G.q\$}k?ŢСC(L&0<eP9wK.jIi麟>(êUjǎ; =… RƘߝftέZ_E N:5h__'a0L J B ӺCĸ- 'HnZ4~ituuD$OAɦs9L&H:Ԅ͛79J=gTygVWWcxxxA8xZ[[D?qٲez{O/T*R7<9&Fkjjtpp%ݻ|޽sܧŎWyqӱX ǎtxRV^H$KRC7EeX}rTfH$L;vZY=\e&s8UH!? f{{{7-&---֖fbbZfE;}z\X yp<rڸq#ĉxvY09%iat>| s9"3grJXkKdm1Egƥ1,D"ߎD"?NGU囧 :FCU Ou/WT,OIyqU--d2r[n:{x+0 oVN+#0.K #΋ƘgO-V^8{&Iwzmmt&8fι<ɟ+3"ZD7JJJ0tG泃?F޵m6YعK bA9GBDhu^$#tEE/sn|-oߜM <IENDB`wallch-4.0/data/to_usr_share/wallch/files/indicator_ambiance_left.png0000644000175000017500000001054512301477401024574 0ustar alexalexPNG  IHDR@@iqbKGD pHYstIDATxkpgu}%YmImْs77BC tzZir)ôi CI!åN)1 $KʷVd]}$dYG. ч}+}j~H:/"#P&y1vJx@Tہ"}"rHU϶R_j,TC9D9q灑dOOl:]iT߫ ޚI<9vՏ=U= 0/'C%: * S?:{ߝ|"t䓑L@dxxj ?x&wccD&:8HqyZ߸q?;JUѾ>}٠D zgv6:Edp'& 0b.^L&obG2Uq/d AUEFUnܹxdx8Qi0u)%LM _mKBz@T&D^lVJсDYܗ^B ˗"Bܖyb*U [kyEUK)pϝ#:4Da"CCOęc@9N F:42U q|[*@7ݔcg)"##D70@xdw|),uuAu"|<]ѡoUApp""3g ;|ѣNƙ B!LUf [Pض֭kBN/"SGw(\uF<]ცzP欞ɔO8ŝX(~C6 仺1b K|NDL]52w=7Տ)VAC!LM V (/gDx PgFmԱU`$9Wju[Gaf mojBc ol3)4.G ">ܖJV9Ctp७cjk)RISSs/  ~grb.&_.( ㅭ[OZ[h,6T5@}Ł ,hS@8tרj,"iKfd{{Ƙ?Vߞz (ɌϘVVu#I~TU8`PJ)6K]l̝j5z"QwZ"8tE0N;z~f>>>= A8 "1T" "?<"2w#U\)]UTOxξ<`LY 4(nޠ;& 911B[*5xE9`$1=I$+}>ŘF01W-@RU+D3ɞnAHoKtE9@U_+w䤬FeHPܶ-ԅO:X/ I6-,@[*5 ײGU. 񧟮ff鎍5]ƪAUVeiACCO.~̻5?O8P׉HgÉh"ᾴwR}pꗡA]]Plk3pRKc}qӎOvrpPR)dC^u+={1Вh"6G=oOTuc&9' ilKvݵ-A}6_9P񼇭,l( ;UuZDwٖ ?t/ &ЦswرԔ΂gʥhl)<9~~s)PܲDbmTsTKDT%9eI "0 `Ky@ _sϝ['ZdnfLcCG|iϞ yGV7Y665qkPXLr==jyaLOMz`BpXA4ZK0 !ã33sa r(ؘbLN`ЫˢHR6+N'{z&P5@#"$lh"޽˽;熇 ;ˡ$'tl,^Sm w9zOu,%-fvzəUFD/nzT2/er򖹦g%0NWXt6nt\wx<``,55MMQiԆգ z a'5ryӎH*0g[V5 F1& ,"U&H]=%BHP]v-~CZ™BCmL竭54<, ^&":a["/Ysd.o5;q~G)66-fhEd]Vgv׮sZ^m9iYQvQ VkwqBY GORUt:'O̲7*R SSC;/vt<|赗m*`3 -3NO?jZfPDߖJZ#46,EEWH#)wfˊhFɖaG@ֲʅZ._YsgU@cL'\GYq־m/r).%~, ģAdiU6;pʽ{H>_krj]>[̍Հo//7xܺ n,l~-|gƀ n$i[2evb߾zgz-M$N[*mD2U8cDUmKk"1w7ډM BGMe75Qlo/SSToߗls9cޮg0"rӖJ=#/n~4sPd%ߴ1; 擤13=Mxt^ 4Z\>l[U?=wy<{E^Ny+m;v2[!qB'ӄj"uN4`?}JYtRUK _j撳A>n%3G`|voj29K&^NMwϞ21&j T}.xZ3 m1|@D`SEDeϋc+ŕa UݖAf zkȂ&٩{T͖c,<"".",c>8N~xјzYpA#P5576/E)4³1bcMU_a+%<|JUlK+IT}v}+hʻgΜzV=35ITbdқz[Gr^TTXRz|TD>8V 1v~U} x¥35u"rh>q"?G$74H) ZZb:bk/"O==y+^IGUPKǝDyTTTRr O2%{zN]OMQK>.o.oK [DnV<1}"# I'{z&W x^XDUu Eyn5@lQ ,U)@8jU` u&A"KEo"jݼ("p8a۶Wϫs@IENDB`wallch-4.0/data/to_usr_share/wallch/files/indicator_radiance_left.png0000644000175000017500000001155312301477401024603 0ustar alexalexPNG  IHDR@@iqbKGD pHYst IDATx[il\u}o6."DJJe9Mn;i E]HФhhN A Nܦ@6).qD؉mٲ$k'ShKH$rf޻|1o%ٲD 8$gޛgݼMR$s/"]!$7lذ޽;KX_! )1v ƍkU$d!'@Sٳ'|KPϓ\$@""Oc۷[|k;U $7U I >/"#ݻ׽e(u;J$:F`ꀃy_p}I.+#Y `Ʉ*;ܯbs1.8@^*:g Mq$[HU: LՒJLh C ĠAHpw"8d ~ 31_=/;;+N#\B@**CXhK,^aB=}ȫZgyѾLdɏx7y&_׺e֡5f-Y*U$i`oF 5744^<68fxSc 2W ǘRGFFfl޼y9"G7)Ho-ZmAH"[gH` b5NDpLD^2@kU&铤1f[<LOO;`MU ǣ U,\[ZUhֳc7.2P2eRZ_5WDۈb6ZU QZZcǎMvܼysI~`SR9ak EzE;c>Ǎ1L YDD搬WvUdeE~\U7:r4ƼݩQR3.pй8$^Q\Ul) Z̞H~ 3 `w{F^7~Z*as^U}SKk%D䬈}Od.?sch,B*JHE[`ebyiZ| aOlnooOdzkV|1@%bo:umY$Åx$Eh !8YK \"`o[9---a.r-Q9xԩ X/)I={|@>@R@2kiZSELce*acpј"gTtww8=nzse|yC6nܘRS9?ڹ46ʋ/hc7{U={#399kf4GOϾ.Z*VZ˜<琘F9h<}<< ЮXB__v~|OU}?ܳgόtĉڝιO/p0XQZX'jV(ƌ-8yr0 9/1b1ZkM*Wc~zwy ιs-7wm7ϹD6jU H|c_qR E:)“AP$HDd/d,Jgb ^UO\W 0NXT?ڲzP1x)#"8y4e}}ï䲈!PE0IҋB!LrHQU-yu``L0|fwYP[mxdN2CIVk+S$5)^DpW^y%`?[n  y:O2i{s|}Q0I& 5]x r$N˱^5F)U˷i6=WH3"rx?ݰ;=RU9 fYD>  N" #wb;UBGD.tuwݍ\Z;;r9'8< ('Q@pٗN'n'9x`$UuV o ^paTNJ&T\5V ELtZJ"]hii.@"j_,}^O/c "/HeXHbE#t:tι:L&'Iknniᛛι$c"}]/`:D<UE$զ˜,;~#6455-RU+ӇH>(01w7cEW0FF|n J_]re7pH*Q9:$bElG9iKf:}fsns+FTuM0MW\_P6DsDb⦵"' FAdUqN! aNJ+#G!C`vΎ9'`VUcΔ+V(~/)wzLoo +rL@g aCpI"`!H"CuĊJG**&4pCCCCUUUUusa$"#III7=:7lcs|$ըrJ5kHVu,ODQΔ|¬9GNpUvp+V3$0#"3Z;wZ~~$׎&f>| S$3ZԇW$xlT+p e|(bF=餯 _K̔ue\[?u'{KQUʠPFq#oiGNFygU?5<1222p¯]X5Kf͚-8:>>>7T@E?*F҂mK)D~"2TVWWS$,arFR1Ɔ$Yޑ Ɗw_s௜sX_ܛ VVVGj~"#"%cT/L_ 6_$IRŋh*e !VO]]]oAeU+<{&L>;|[tzI(וƒ TC}UH4s F IFaZ"Xh=1#/Rp_l~~᳉ȩD"pB.^uvLU׃|vXu ~ fr)0R~-U`H"#_D"l6Q+)~0qIzɓuNi@K]Lz+EdV`q\!x"}znN&GsqN+Hx,ٳ;}tvF6DlMM!U'd|Qb 3H9Ci/"tz FDH׬q畖6JRd2᧝sU"2žRVVxoo- -Ʋ\6)g6ufp(n&"a֊`1X*F u!'gmmWuI#Ъ =x/+*fZ̯Zk?6s c ֊`1 x(R vVY $瘾%"c̳xwww72ݸlٲtp}BUIʍcšK@-vc4Z[g9U@DrƘk2N2X&YmsAUΛdA_E(5[jTqR=aL:۬y=n,ܹs^=rmfdW,31O8綐DB5,(6h:7ʘ\FM߉_}GDb{ssk۷on/_|N.[k}v\~`rjIn/9bygRg{/nc0I69HEwbזfIENDB`wallch-4.0/data/to_usr_share/wallch/files/indicator_radiance_right.png0000644000175000017500000001160112301477401024760 0ustar alexalexPNG  IHDR@@iqbKGD pHYst!IDATx[il\u}oP"}Ǣv.IQv v&q:q6nS4dqvEEiINᤈSh%P9)hJgܡ#ʒ(; < !y;9;Y%o;;;HVݾ}{m!y57nIr#vJN0:::HC gyƘ;w~:U}H!xD7"i7{o%%y $N1{߾}up x>JrI_:DGB{0p#: K 0p1; ^m$j T#C[C[{:@B| RDƘ'޽&Q'mER7S+y T2;yr1 323-#"]%$7@TYYJ P <}<4qD`LfEJD^2y/^ 7uu6.\xxM$,(S tuj!]$E.,ɏ3x$V]]]"(I#YLR@H+ T9 e"Q3tBI2/drUUUjk{`W͛#h^_ o YWb"{Dvl˗K( ݻB`c{ dͬ䊝K$E/cܻwUwnF .bC6,\p@pKCd2aũS] Q7 =sɄB8+-M80 PW@˕5}DܘԎdOjkC}/FGG7~9O ?Q)IbJ744<}E |R^Qupp0<>>>|tU] (WUs.?VZzq;ZJn6MD$&"<}p A I.rPBb~Yi~c"bdF_s1@+(cCY cJ|~D TlFff"3{I}M7I*S,r^j}[#PEuuC"W-N: %sF|ҸpBddV3ػg_ܘwJKKyRk椈 &YJe0m.$ zW"+4(h>`R_ 9kXPh33=2\MziCa8(ODΓs^HZ[$gN{*p޼ f8iDN* Ts/ xZhkk, BgZ[[Dd'ugr3|#W#9Հ&2WssBUZ"HR1֯_{U4IN$MVN!ǀÃ$Ia$Hrh1U]ӤlhWSu ־Tj9LcڹS/ -[UD^ 0T͞c@T*5'TUW?kQI;}gM~Xvpdo{"!}c]Jމj@em^Zmj-[OlaBD.Kpv{ y^6%]{㘻IћApIٵ$]do<8 i DpaVkmmm!$,|Wnsq~/,kn^s#g#K|8L>m΁C?weph=n>yPUoL;m К_ 8rc=:m~?<bD PU=v1ׄiA"hOaV9zEd, }O81uىUtqOA)%o62eDbw{ItN iʞ!hn]X89\]AemW>DCWJJJ&hv5{ʕ%ɩ>ܗ6+Jdj$DNgmd#GHZAUWUmSF@DO<'O]MW-`Z[Z 'ۃ v 6D>X{A$Rc@GulaLDA$bC}Y3ߟ:nkYmYc"rzKw]fY8HL|@ H.IT\gfqk1ٙ{,[vJ\gV{}<ITc>wb+aeDǬ"rNU'D$%cguw4V=YejUD2Q);:ژhms/f/Ϩ{f{I1OT#@"ϊ?K2z O=s M ! UuP!aܩ)_LMܘDx P('" VZT{NM[L*p(0 $QtL|!'N{j[sZQ_%/3|hYy_H R>,ɤp,<0m;} Pc —JH:}ZTG% 箽ve#\S4e7TuW|0=έ ǀs@Gh*G y^,M|U5*ԏi UC"~yC{eum%F`z+? I|wّio?Qǖ=wnvc#بMs"F[gpQr>pG.4`ib]iߣi\ctjT0,ɤ7'X.Uۿ&PyRo"MyUu, tꔈ<]֖+>. B 6k_O~9pB0^HGk-Qa#5ϳT|.gsLLj8@&l ԗ1Fd*-k0⛥Pf"XD4Ex^Ume5"RVW| Pn2i:':l)9U+XpU/"p8,Vڬ M"RQYYknȲϽDJ5XeZ;:pg\z',]{yU]koL&-2=vYng*団),l~psb1;Kx@ZkFZ]SU%y8 L PN'vrhli$btvN-q4XwXh54ȫsWf#\ᅵ I&l @<^ԆBd<^lQZwXCa:_vzzή̦M}}O.LYB_H\zyk53Nwջ1uz{k狺Õlx~WdutFwt3]]cE"("㪚r.RӊkmnWw9c̟c?5fVWdf{ŨAȞԍ7&*+q}<ݠUZ{cd̞]Nto@$Nǎ]Ծ5%g: <+=c~m'dMEdf^qWԢ\U}5+._kc|69k}G}xܽ[5 ݽά)s1Bv${z yXD>o֢%Z ݢ, w6(=@\Z&a+ė̼Nn7% ;D~,"*G/uܳŽ,o6A1#LC\U}I>9DHD{/e힠w ,1f;6_q]6])F8<}c?j$r06S_:s&ٙFjD,ָ4H:RgO{ڨbzsvrµQ/jUݶ+xtS'-8 +󭅦9 x]Y[*|"GbVrar\c$)`iT|*$IMQ3Q(~Q)>E%PP`eIWM~eXj?ھSHMI\̛"HwWdw]>DU:;92:Jׁ+Oϒ)۾Bpa$=I?>o+q nku=lI`@ҳ H>k{w5K@O[HKm8LCk' M٫>[#Pa!CKyWZߐ`xqs!} (oII`a#5nTs!.Sb`CFWؾHy!I~ɉEC$sL(T*j ƁÒDE I3TOoSn_|'*'3NE_ 2?6/pvՓ6dcr2ؾ5w?WEq\toۜmo9D/ے$l>6oE9RK,'̄88tȂ n !pw7 ֬y;_}! Q#h2tZl#X*rpAv^( 9r 9J$ˀb-!~i-`\j?a <Iح^DK*ω@v(Nd/в8jB]ݮ#G8ǟ ]}i46AF=NhJBҿw-Z@M}]]4l{y-+JؘEJR{E}p>b`&M"Ҹ}$r@풒{[nepv#0^]+;j4rv,)Gj GTpodڵsF@ER,]6{:cP 642|K0dL`imI"Ԏ$n f$`iXY ][2Y N8~\*}4I\m HST Ԑ ,[ǧaզMtQ( ILP8SvF\>O?kQRsX,*vt)(W*`,L 8l[l!ھflllso !,ʥ ۗyIc&Y# 2~< yR)}}NFFGt65 ܐ5H!O^I#G@މ u$}q+Hn C*<=l% 8U$uEN@$~/W664U*ZaÄI%{/زerp5kdD6<2 oYP(/$iCn9UÚ SI ;^s2A.mXy -]:37l043u?D#1qO@<` Lq ]rx4;G77`ȤgKBc4q[h\18{Ɖ?QKDQZ޽sU{%'~oG|>!IּlE (-L3zí!KGFFؿsgU!<46..J7[tI}H8iim%wC@-xОvBgݦٕr{OHyI oDQM/xgHj 5IjiX1}w[ RiKMK.AFxcS sT0)[@i嘭6M4Ft Ng3]۶jm_g'+/%tsIlIM )鿁'%%1WCsznX,敎׭66?ג6M:ɁKTo,k{Es%N S]477s\$ŬVXB:]6Rλ"t#w[:jJ|UtEXtCommentCreated with GIMPW%tEXtdate:create2013-01-05T15:15:57+02:00nsA%tEXtdate:modify2013-01-05T15:15:57+02:00.IENDB`wallch-4.0/data/man/0000755000175000017500000000000012301477401012756 5ustar alexalexwallch-4.0/data/man/wallch.1.gz0000644000175000017500000000275412301477401014741 0ustar alexalexeSwallch.1W]o9}ϯ xZi-m4jDypf<+3I\ۓ/̵ǹ_'}<>tN. #Ig]NmˆN#N襥F蕴bo)ޝ3bzv_ånvaP=s"QmAWDԙD߷jcZ^#TI(+k]D3O餣 mUfpT L F8Cʪ|B!P\o񉤰BZRzUJ25FR%WT\NxK7;z(="8kOZGR˕ ˠӻ]Ro5;(R)4m]ϊ۴oiK E)_[WJWKIHMHb2op )Ȫ 2ũmKQ6CNC KI7Ìz$;h͉SyːTH22Zb~A&lN'ӇC}{BoR";ȒL"d#; 6Bbi~bv{y~wskhyr`:'>t ?BNy'Vtel 2BVlVLq@R6}"[U(Xߠ9rf> M<х֔OD jD c=4tzYOjNko|Uʂ#3)aK%O|jO<"InB4pJwvw(crfTX͞hw$n 0|f!̂쾬.ƒ0 9R]~a -]vOT=7g+[Vnx1 ގcw%W>_"^71u̝M˅Rzl`,LD$/(mr0!֤0V:t" q-eGjS~st g6; v 32/ Ҫ70*Jrb|yꢟ'qΰDAV-%FF):  ̙;`(PЈ#336c+'`0(r]!?I,6W@ # | Ot#C"%(j漁h'GL iG EjǘǑEE;ƅs7~i*V>0]10v2˻R`0+*%@\"Ѡ;hǝM)c/TmZթ繘*k%5e;tK9BՌ9%(~)Ԅc>MMydPsrՙx(!JPP o/&jXrXMCJ͙S[s?@$Tnq ^?=J{˗0㊝ҿ-Ļbr w4An>90m/&B~^wallch-4.0/src/0000755000175000017500000000000012301477401012061 5ustar alexalexwallch-4.0/src/colors_gradients.ui0000644000175000017500000003144212301477401015765 0ustar alexalex colors_gradients 0 0 480 490 Colors & Gradients 9 75 true Shading Type 10 Qt::NoFocus Solid Color true buttonGroup_2 Qt::NoFocus Vertical Gradient buttonGroup_2 Qt::NoFocus Horizontal Gradient buttonGroup_2 Qt::Horizontal 9 75 true Colors 0 Primary Color Qt::AlignCenter Qt::Horizontal 40 20 Qt::Horizontal QSizePolicy::Ignored 1 20 75 75 75 75 13 Qt::NoFocus Change Primary Color 60 60 Qt::Horizontal QSizePolicy::Ignored 1 20 61 31 61 31 13 Qt::NoFocus Switch colors :/icons/Pictures/change.png:/icons/Pictures/change.png 40 40 Qt::Horizontal QSizePolicy::Ignored 1 20 75 75 75 75 13 Qt::NoFocus Change Secondary Color 60 60 Qt::Horizontal QSizePolicy::Ignored 1 20 Qt::Horizontal 40 20 Secondary Color Qt::AlignCenter Result Qt::AlignHCenter|Qt::AlignTop Qt::Horizontal 40 20 70 70 70 70 false Qt::Horizontal 40 20 Qt::NoFocus Set desktop primary color depending on the average color of the current background Qt::Horizontal Qt::Horizontal 40 20 Qt::NoFocus Remove Background Qt::Horizontal 40 20 Qt::Vertical 20 40 Qt::Horizontal 40 20 &OK wallch-4.0/src/colors_gradients.h0000644000175000017500000000424012301477401015573 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef COLORS_GRADIENTS_H #define COLORS_GRADIENTS_H #define QT_NO_KEYWORDS #include #include #include #include #include #include "glob.h" namespace Ui { class colors_gradients; } class ColorsGradients : public QDialog { Q_OBJECT public: explicit ColorsGradients(QWidget *parent = 0); ~ColorsGradients(); private Q_SLOTS: void on_average_color_checkbox_clicked(bool checked); void on_saveButton_clicked(); void on_primary_color_button_clicked(); void on_secondary_color_button_clicked(); void on_change_order_clicked(); void on_remove_background_clicked(); void on_solid_radioButton_clicked(); void on_vertical_radioButton_clicked(); void on_horizontal_radioButton_clicked(); private: Ui::colors_gradients *ui; QString secondaryColor_; QString primaryColor_; QImage createVerticalHorizontalImage(const QString &type); void actionForSecondaryButtons(bool action); #ifdef ON_LINUX void setDesktopSecondaryColor(const QString &colorName); #endif void setDesktopColor(const QString &colorName); void updateGradientsOnlyColors(bool updateLeftRightSolid); Q_SIGNALS: void updateDesktopColor(QString colorName); void updateTv(); void updateColorButtonSignal(QImage image); }; #endif // COLORS_GRADIENTS_H wallch-4.0/src/potd_preview.cpp0000644000175000017500000002501312301477401015275 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include "potd_preview.h" #include "ui_potd_preview.h" #include "glob.h" #include #include #include #include #include PotdPreview::PotdPreview(QWidget *parent) : QDialog(parent), ui(new Ui::PotdPreview) { ui->setupUi(this); ui->potdFontComboBox->setCurrentFont(QFont(gv.potdDescriptionFont)); ui->potd_description_bottom_radioButton->setChecked(gv.potdDescriptionBottom); if(gv.potdDescriptionBottom){ ui->bottom_top_margin_label->setText(tr("Bottom:")); } else { ui->bottom_top_margin_label->setText(tr("Top:")); } ui->potd_description_top_radioButton->setChecked(!gv.potdDescriptionBottom); ui->left_margin_spinbox->setValue(gv.potdDescriptionLeftMargin); ui->right_margin_spinbox->setValue(gv.potdDescriptionRightMargin); ui->bottom_top_margin_spinbox->setValue(gv.potdDescriptionBottomTopMargin); textColor_=gv.potdDescriptionColor; backgroundColor_=gv.potdDescriptionBackgroundColor; originalTextColor_=textColor_; originalBackgroundColor_=backgroundColor_; originalTextFont_=gv.potdDescriptionFont; originalTop_=ui->potd_description_top_radioButton->isChecked(); originalLeftMargin_=gv.potdDescriptionLeftMargin; originalRightMargin_=gv.potdDescriptionRightMargin; originalBottomTopMargin_=gv.potdDescriptionBottomTopMargin; if(QFile::exists(gv.wallchHomePath+POTD_PREVIEW_IMAGE)){ QImage *image = new QImage(gv.wallchHomePath+POTD_PREVIEW_IMAGE); fetchFinished(image); } else { ui->potdLabel->hide(); ui->potdFontComboBox->hide(); ui->potd_description_bottom_radioButton->hide(); ui->potd_description_top_radioButton->hide(); ui->descrPos_label->hide(); ui->font_label->hide(); ui->textColorPotd->hide(); ui->backgroundColorPotd->hide(); ui->ok->hide(); ui->margins_label->hide(); ui->left_margin_label->hide(); ui->left_margin_spinbox->hide(); ui->right_margin_label->hide(); ui->right_margin_spinbox->hide(); ui->bottom_top_margin_label->hide(); ui->bottom_top_margin_spinbox->hide(); this->adjustSize(); (void) new QShortcut(Qt::Key_Escape, this, SLOT(on_cancel_clicked())); fileDownloader_=new QNetworkAccessManager(this); QObject::connect(fileDownloader_, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadedImage(QNetworkReply*))); getPotdPreviewImage(); } } PotdPreview::~PotdPreview() { if(currentNetworkRequest_){ currentNetworkRequest_->deleteLater(); } if(originalImage_){ delete originalImage_; } delete ui; } void PotdPreview::resizeEvent(QResizeEvent *) { QSize scaledSize = currentPixmap_.size(); scaledSize.scale(ui->potdLabel->size(), Qt::KeepAspectRatio); if (!ui->potdLabel->pixmap() || scaledSize != ui->potdLabel->pixmap()->size()){ updateLabel(); } } void PotdPreview::updateLabel() { ui->potdLabel->setPixmap(currentPixmap_.scaled(ui->potdLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); } void PotdPreview::getPotdPreviewImage(){ if(currentBackupLinkIndex_>=potdPreviewImages_.count()){ imageFetchfailed(); } else { currentNetworkRequest_=fileDownloader_->get(QNetworkRequest(QUrl(potdPreviewImages_.at(currentBackupLinkIndex_)))); } } void PotdPreview::imageFetchfailed(){ fetchFailed_=true; ui->infoLabel->setText(tr("The Picture Of The Day Image used for preview failed to download. Please check your internet connection.")); ui->cancel->hide(); ui->ok->show(); } void PotdPreview::downloadedImage(QNetworkReply *reply){ currentNetworkRequest_=NULL; if(reply==NULL){ currentBackupLinkIndex_++; getPotdPreviewImage(); return; } else if(reply->error()){ reply->deleteLater(); currentBackupLinkIndex_++; getPotdPreviewImage(); return; } QImage *img = new QImage(); img->loadFromData(reply->readAll()); reply->deleteLater(); if(img->isNull()){ currentBackupLinkIndex_++; getPotdPreviewImage(); return; } img->save(gv.wallchHomePath+POTD_PREVIEW_IMAGE, "JPG", 100); fetchFinished(img); } void PotdPreview::fetchFinished(QImage *img){ originalImage_=img; currentPixmap_ = QPixmap().fromImage(*img); updateLabel(); ui->potdLabel->show(); ui->potdFontComboBox->show(); ui->potd_description_bottom_radioButton->show(); ui->potd_description_top_radioButton->show(); ui->descrPos_label->show(); ui->font_label->show(); ui->textColorPotd->show(); ui->backgroundColorPotd->show(); ui->ok->show(); ui->margins_label->show(); ui->left_margin_label->show(); ui->left_margin_spinbox->show(); ui->right_margin_label->show(); ui->right_margin_spinbox->show(); ui->bottom_top_margin_label->show(); ui->bottom_top_margin_spinbox->show(); ui->infoLabel->hide(); ui->progressBar->hide(); fetchFinished_=true; writeDescription(); } void PotdPreview::writeDescription(){ if(originalImage_==NULL){ return; } QImage image = QImage(*originalImage_); QPainter drawer(&image); QFont font = ui->potdFontComboBox->currentFont(); font.setPixelSize(image.width()/55); drawer.setFont(font); QRect drawRect; drawRect=drawer.fontMetrics().boundingRect(QRect(0, 0, image.width()-(ui->left_margin_spinbox->value()+ui->right_margin_spinbox->value()), image.height()), (Qt::TextWordWrap | Qt::AlignCenter), potdDescription_); drawRect.setX(0); drawRect.setWidth(image.width()); int newY; if(ui->potd_description_bottom_radioButton->isChecked()){ newY=image.height()-drawRect.height()-ui->bottom_top_margin_spinbox->value(); } else { newY=ui->bottom_top_margin_spinbox->value(); } int oldH=drawRect.height(); drawRect.setY(newY); drawRect.setHeight(oldH); QColor backgroundColor=QColor(backgroundColor_); backgroundColor.setAlpha(176); drawer.fillRect(drawRect, QBrush(backgroundColor)); drawRect.setX(ui->left_margin_spinbox->value()); drawRect.setWidth(image.width()-(ui->left_margin_spinbox->value()+ui->right_margin_spinbox->value())); drawer.setPen(QColor(textColor_)); drawer.drawText(drawRect, (Qt::TextWordWrap | Qt::AlignCenter), potdDescription_, &drawRect); drawer.end(); currentPixmap_ = QPixmap().fromImage(image); updateLabel(); } void PotdPreview::on_textColorPotd_clicked() { QColorDialog::ColorDialogOptions options = QFlag(0); QColor textColor = QColorDialog::getColor(QColor(textColor_), this, tr("Select Color"), options); if(textColor.isValid()){ textColor_=textColor.name(); writeDescription(); } } void PotdPreview::on_backgroundColorPotd_clicked() { QColorDialog::ColorDialogOptions options = QFlag(0); QColor backgroundColor = QColorDialog::getColor(QColor(backgroundColor_), this, tr("Select Color"), options); if(backgroundColor.isValid()){ backgroundColor_=backgroundColor.name(); writeDescription(); } } void PotdPreview::on_potdFontComboBox_currentFontChanged() { if(fetchFinished_){ writeDescription(); } } void PotdPreview::on_potd_description_bottom_radioButton_clicked() { ui->bottom_top_margin_label->setText(tr("Bottom:")); if(fetchFinished_){ writeDescription(); } } void PotdPreview::on_potd_description_top_radioButton_clicked() { ui->bottom_top_margin_label->setText(tr("Top:")); if(fetchFinished_){ writeDescription(); } } void PotdPreview::on_ok_clicked() { if(!fetchFailed_){ gv.potdDescriptionBottom=ui->potd_description_bottom_radioButton->isChecked(); gv.potdDescriptionFont=ui->potdFontComboBox->currentFont().family(); gv.potdDescriptionColor=textColor_; gv.potdDescriptionBackgroundColor=backgroundColor_; gv.potdDescriptionLeftMargin=ui->left_margin_spinbox->value(); gv.potdDescriptionRightMargin=ui->right_margin_spinbox->value(); gv.potdDescriptionBottomTopMargin=ui->bottom_top_margin_spinbox->value(); settings->setValue("potd_description_bottom", gv.potdDescriptionBottom); settings->setValue("potd_description_font", gv.potdDescriptionFont); settings->setValue("potd_text_color", gv.potdDescriptionColor); settings->setValue("potd_background_color", gv.potdDescriptionBackgroundColor); settings->setValue("potd_description_left_margin", gv.potdDescriptionLeftMargin); settings->setValue("potd_description_right_margin", gv.potdDescriptionRightMargin); settings->setValue("potd_description_bottom_top_margin", gv.potdDescriptionBottomTopMargin); settings->sync(); if(originalTextColor_!=textColor_ || originalBackgroundColor_!=backgroundColor_ || originalTextFont_!=gv.potdDescriptionFont || originalTop_!=ui->potd_description_top_radioButton->isChecked() || originalLeftMargin_!=gv.potdDescriptionLeftMargin || originalRightMargin_!=gv.potdDescriptionRightMargin || originalBottomTopMargin_!=gv.potdDescriptionBottomTopMargin){ Q_EMIT potdPreferencesChanged(); } } this->close(); } void PotdPreview::on_cancel_clicked() { if(currentNetworkRequest_){ currentNetworkRequest_->abort(); } this->close(); } void PotdPreview::on_left_margin_spinbox_valueChanged() { writeDescription(); } void PotdPreview::on_right_margin_spinbox_valueChanged() { on_left_margin_spinbox_valueChanged(); } void PotdPreview::on_bottom_top_margin_spinbox_valueChanged() { on_left_margin_spinbox_valueChanged(); } wallch-4.0/src/properties.ui0000644000175000017500000002071012301477401014614 0ustar alexalex properties 0 0 441 408 Properties :/icons/Pictures/wallpaper.png:/icons/Pictures/wallpaper.png Qt::Horizontal 40 20 Left Arrow Right Arrow Qt::Horizontal 40 20 0 0 157 101 false Qt::AlignCenter 0 0 Image Type: 0 0 Size: 0 0 Location: 0 0 Created: Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 0 0 Modified: Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Dimensions: 0 0 Name: Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse true Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Qt::Horizontal 40 20 Set as Background Open Image's Location &Close true wallch-4.0/src/notification.ui0000644000175000017500000001005312301477401015105 0ustar alexalex Notification 0 0 392 82 392 82 Notification background-color:orange 0 Qt::Vertical 20 40 Qt::Horizontal 40 20 106 60 :/icons/Pictures/tempbig.jpg true Qt::Horizontal 40 20 Qt::Vertical 20 40 Qt::Vertical 20 40 0 0 12 Current wallpaper has been changed Qt::Vertical 20 40 wallch-4.0/src/mainwindow.cpp0000644000175000017500000055115312301477401014753 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include #include #include #include #include #include #include #include #include #include #include #ifdef ON_WIN32 #include #endif #include "mainwindow.h" #include "math.h" MainWindow *mainWindowInstance; MainWindow::MainWindow(Global *globalParser, WebsiteSnapshot *websiteSnapshotP, int timeout_count, QStringList previous_pictures_from_main, int last_random_delay, int last_normal_picture, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); mainWindowInstance=this; if(globalParser==NULL){ globalParser_ = new Global(true); } else { globalParser_=globalParser; } connect(globalParser_, SIGNAL(onlineRequestFailed()), this, SLOT(onlineRequestFailed())); connect(globalParser_, SIGNAL(onlineImageRequestReady(QString)), this, SLOT(onlineImageRequestReady(QString))); if(websiteSnapshotP!=NULL){ websiteSnapshot_=websiteSnapshotP; } else { websiteSnapshot_=NULL; } QDesktopWidget dim; gv.screenWidth=dim.width(); gv.screenHeight=dim.height(); imagePreviewResizeFactorX_ = SCREEN_LABEL_SIZE_X*2.0/(gv.screenWidth*1.0); imagePreviewResizeFactorY_ = SCREEN_LABEL_SIZE_Y*2.0/(gv.screenHeight*1.0); //Moving the window to the center of screen! this->move(QApplication::desktop()->availableGeometry().center() - this->rect().center()); this->resize(QSize(this->width(),this->minimumHeight())); gv.potdOnlineUrl=settings->value("potd_online_url", POTD_ONLINE_URL).toString(); gv.potdOnlineUrlB=settings->value("potd_online_urlB", POTD_ONLINE_URL_B).toString(); gv.liveEarthOnlineUrl=settings->value("line_earth_online_url", LIVEARTH_ONLINE_URL).toString(); gv.liveEarthOnlineUrlB=settings->value("live_earth_online_urlB", LIVEARTH_ONLINE_URL_B).toString(); gv.potdIncludeDescription = settings->value("potd_include_description", true).toBool(); gv.potdDescriptionBottom = settings->value("potd_description_bottom", true).toBool(); gv.potdDescriptionFont = settings->value("potd_description_font", "Ubuntu").toString(); gv.potdDescriptionColor = settings->value("potd_text_color", "#FFFFFF").toString(); gv.potdDescriptionBackgroundColor = settings->value("potd_background_color", "#000000").toString(); #ifdef ON_LINUX gv.potdDescriptionLeftMargin = settings->value("potd_description_left_margin", (gv.currentDE==UnityGnome ? 125 : 0)).toInt(); #else gv.potdDescriptionLeftMargin = settings->value("potd_description_left_margin", (0)).toInt(); #endif gv.potdDescriptionRightMargin = settings->value("potd_description_right_margin", 0).toInt(); gv.potdDescriptionBottomTopMargin = settings->value("potd_description_bottom_top_margin", 0).toInt(); on_include_description_checkBox_clicked(gv.potdIncludeDescription); gv.iconMode=settings->value("icon_style", true).toBool(); if(gv.iconMode){ ui->listWidget->setIconSize(WALLPAPERS_LIST_ICON_SIZE+WALLPAPERS_LIST_ITEMS_OFFSET); ui->listWidget->setUniformItemSizes(true); } else { ui->listWidget->setViewMode(QListView::ListMode); } connect(&futureWatcherWallClocksPreview_, SIGNAL(finished()), this, SLOT(wallpaperClocksPreviewImageGenerationFinished())); connect(&futureWatcherWallpapersPreview_, SIGNAL(finished()), this, SLOT(wallpapersPreviewImageGenerationFinished())); resetWatchFolders(); setupTimers(); connectSignalSlots(); setupKeyboardShortcuts(); setupThemeFallbacks(); changeCurrentThemeTo(gv.currentTheme); clocksRadioButtonsGroup = new QButtonGroup(this); //setting the slider's value... secondsInWallpapersSlider_=settings->value("delay", DEFAULT_SLIDER_DELAY).toInt(); gv.defaultWallpaperClock=settings->value("default_wallpaper_clock", "").toString(); gv.randomImagesEnabled=settings->value("random_images_enabled", false).toBool(); timeForNext_ = new QProgressBar(this); timeForNext_->setMaximumWidth(290); opacityEffect_ = new QGraphicsOpacityEffect(this); opacityEffect2_ = new QGraphicsOpacityEffect(this); gv.previewImagesOnScreen=settings->value("preview_images_on_screen", true).toBool(); if(!gv.previewImagesOnScreen) { ui->preview_widget->setMinimumHeight(0); ui->preview_widget->hide(); } gv.independentIntervalEnabled=settings->value("independent_interval_enabled", true).toBool(); gv.rotateImages=settings->value("rotation", false).toBool(); gv.firstTimeout=settings->value("first_timeout", false).toBool(); gv.showNotification=settings->value("notification", false).toBool(); gv.saveHistory = settings->value("history", true).toBool(); gv.setAverageColor = settings->value("average_color", false).toBool(); #ifdef ON_LINUX gv.unityProgressbarEnabled=settings->value("unity_progressbar_enabled", true).toBool(); #endif gv.randomTimeEnabled=settings->value("random_time_enabled", false).toBool(); gv.randomTimeFrom=settings->value("random_time_from", 300).toInt(); gv.randomTimeTo=settings->value("random_time_to", 1200).toInt(); gv.useShortcutNext=settings->value("use_shortcut_next", false).toBool(); if(gv.randomTimeFrom>gv.randomTimeTo-3){ Global::error("The randomness is misconfigured, please head to the Preferences dialog to configure it properly!"); gv.randomTimeEnabled=false; } if(gv.randomImagesEnabled){ srand(time(0)); } if(gv.wallpapersRunning) { loadWallpapersPage(); if(ui->listWidget->count() < LEAST_WALLPAPERS_FOR_START){ startButtonsSetEnabled(false); } else{ startButtonsSetEnabled(true); } if(gv.processPaused){ actAsStart_=true; ui->startButton->setText(tr("&Start")); ui->startButton->setIcon(QIcon::fromTheme("media-playback-start", QIcon(":/icons/Pictures/media-playback-start.svg"))); animateProgressbarOpacity(1); findSeconds(true); secondsLeft_=(timeout_count+1); indexOfCurrentImage_=last_normal_picture; initialRandomSeconds_=last_random_delay; Global::resetSleepProtection(secondsLeft_); updateSeconds(); stopButtonsSetEnabled(true); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ dbusmenu_menuitem_property_set_bool(gv.unityPauseAction, DBUSMENU_MENUITEM_PROP_VISIBLE, false); } #endif previousAndNextButtonsSetEnabled(false); timeForNext_->setFormat(timeForNext_->format()+" - Paused."); } else { //starting the process... actAsStart_=false; ui->startButton->setText(tr("Pau&se")); ui->startButton->setIcon(QIcon::fromTheme("media-playback-pause", QIcon(":/icons/Pictures/media-playback-pause.svg"))); animateProgressbarOpacity(1); findSeconds(true); startWasJustClicked_=true; secondsLeft_=timeout_count; indexOfCurrentImage_=last_normal_picture; initialRandomSeconds_=last_random_delay; startUpdateSeconds(); stopButtonsSetEnabled(true); previousAndNextButtonsSetEnabled(true); } ui->stackedWidget->setCurrentIndex(0); } else if(gv.liveEarthRunning) { secondsLeft_=timeout_count; ui->activate_livearth->setEnabled(false); ui->deactivate_livearth->setEnabled(true); startUpdateSeconds(); on_page_1_earth_clicked(); animateProgressbarOpacity(1); } else if(gv.potdRunning) { ui->deactivate_potd->setEnabled(true); ui->activate_potd->setEnabled(false); on_page_2_potd_clicked(); startPotd(false); } else if(gv.wallpaperClocksRunning) { ui->deactivate_clock->setEnabled(true); ui->activate_clock->setEnabled(false); totalSeconds_=secondsLeft_=timeout_count; startUpdateSeconds(); setProgressbarsValue(100); on_page_3_clock_clicked(); animateProgressbarOpacity(1); } else if(gv.liveWebsiteRunning) { secondsLeft_=timeout_count; ui->deactivate_website->setEnabled(true); ui->activate_website->setEnabled(false); startUpdateSeconds(); on_page_4_web_clicked(); animateProgressbarOpacity(1); } else { //nothing's running, so just open the application.. stopButtonsSetEnabled(false); previousAndNextButtonsSetEnabled(false); hideTimeForNext(); switch(settings->value("current_page", 0).toInt()){ default: case 0: on_page_0_wallpapers_clicked(); break; case 1: on_page_1_earth_clicked(); break; case 2: on_page_2_potd_clicked(); break; case 3: on_page_3_clock_clicked(); break; case 4: on_page_4_web_clicked(); break; } //the app has opened normally, so there is no point in keeping a previous independent interval if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(-1, 0); } } //in case there were any previous pictures in main (from the --start argument)... previousBackgrounds_=previous_pictures_from_main; ui->shuffle_images_checkbox->setChecked(gv.randomImagesEnabled); if(gv.randomTimeEnabled){ ui->timerSlider->setEnabled(false); ui->wallpapers_slider_time->setEnabled(false); ui->interval_label->setEnabled(false); } if(gv.currentDE==LXDE){ ui->set_desktop_color->hide(); } //enable shortcut key if(gv.useShortcutNext){ gv.nextShortcut=settings->value("shortcut", "").toString(); #ifdef ON_LINUX keybinder_init(); bindKey(gv.nextShortcut); #endif } //enabling dragandrop at the whole program setAcceptDrops(true); connect(ui->listWidget->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(launchTimerToUpdateIcons())); ui->statusBar->addPermanentWidget(timeForNext_, 0); refreshIntervals(); ui->label_3->setText("

"+tr("Picture of the day is being chosen from")+" Wikipedia

"); ui->melloristudio_label->setText("

"+tr("Wallch is developed by")+" Mellori Studio.

"); ui->melloristudio_link_label->setText("

"+tr("Learn more about our projects at:")+" melloristudio.com

"); ui->label_5->setText("

"+tr("Style")+" "+tr("Scale")+" "+tr("is highly recommended for this feature")+"

"); ui->label_9->setText("

"+tr("Download wallpaper clocks from")+" VladStudio.com

"); processingOnlineRequest_=false; //processing request (loading gif) ui->process_request_label->hide(); processingRequestGif_ = new QMovie(this); processingRequestGif_->setFileName(":/icons/Pictures/process_request.gif"); ui->process_request_label->setMovie(processingRequestGif_); //for manually searching for files or re-selecting a picture after a folder contents have changed match_ = new QRegExp(); match_->setCaseSensitivity(Qt::CaseInsensitive); match_->setPatternSyntax(QRegExp::Wildcard); QTimer::singleShot(10, this, SLOT(setButtonColor())); QTimer::singleShot(20, this, SLOT(setStyle())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::closeEvent(QCloseEvent * event) { strongMinimize(); event->ignore(); } void MainWindow::actionsOnClose() { appAboutToClose_=true; this->hide(); #ifdef ON_LINUX app_indicator_set_status(gv.applicationIndicator, APP_INDICATOR_STATUS_PASSIVE); #endif } void MainWindow::changeEvent(QEvent *e) { if(gv.preferencesDialogShown || addDialogShown_ || historyShown_){ this->showNormal(); } switch (e->type()){ case QEvent::LanguageChange: ui->retranslateUi(this); break; case QEvent::WindowStateChange: if(isMinimized()){ this->hide(); } break; default: break; } QMainWindow::changeEvent(e); } void MainWindow::resizeEvent(QResizeEvent *e){ if(!gv.mainwindowLoaded){ return; } if(!ui->stackedWidget->currentIndex()){ launchTimerToUpdateIcons(); } //screen preview is not getting updated when we resize the window, so we do it manually if(ui->screen_label->pixmap()) { QPixmap *pixmap = new QPixmap(*ui->screen_label->pixmap()); if(gv.previewImagesOnScreen && gv.mainwindowLoaded) { if(pixmap){ ui->screen_label_transition->setPixmap(*pixmap); } else{ ui->screen_label_transition->clear(); } ui->screen_label->setPixmap(*pixmap); } } else { QString temp=ui->screen_label_text->text(); ui->screen_label_text->clear(); ui->screen_label_text->setText(temp); } QMainWindow::resizeEvent(e); if(this->width()minimumWidth()){ QTimer::singleShot(100, this, SLOT(wrongSizeOfWindow())); } } void MainWindow::wrongSizeOfWindow() { this->resize(QSize(this->minimumWidth(),this->height())); } void MainWindow::strongShowApp(){ #ifdef ON_WIN32 this->showNormal(); this->activateWindow(); #else this->show(); this->activateWindow(); Qt::WindowFlags eFlags = this->windowFlags(); eFlags |= Qt::WindowStaysOnTopHint; this->setWindowFlags(eFlags); this->show(); eFlags &= ~Qt::WindowStaysOnTopHint; this->setWindowFlags(eFlags); this->show(); #endif } void MainWindow::strongMinimize(){ this->setWindowState(Qt::WindowMaximized); //dirty trick this->setWindowState(Qt::WindowMinimized); } void MainWindow::setupTimers(){ //Timer to updates progressbar and launch the changing process updateSecondsTimer_ = new QTimer(this); connect(updateSecondsTimer_, SIGNAL(timeout()), this, SLOT(updateSeconds())); //Timer for folder monitoring researchFoldersTimer_ = new QTimer(this); connect(researchFoldersTimer_, SIGNAL(timeout()), this, SLOT(researchFolders())); //Timer that updates the configuration for timing once it is changed updateCheckTime_ = new QTimer(this); connect(updateCheckTime_, SIGNAL(timeout()), this, SLOT(updateTiming())); //Timer if you click one of the checkboxes of wallpaper clock, if wallpaper clock is running wallpaperClockWait_ = new QTimer(this); wallpaperClockWait_->setSingleShot(true); connect(wallpaperClockWait_, SIGNAL(timeout()), this, SLOT(clockCheckboxClickedWhileRunning())); //Timer that update the icons of the visible items iconUpdater_ = new QTimer(this); connect(iconUpdater_, SIGNAL(timeout()), this, SLOT(updateVisibleIcons())); iconUpdater_->setSingleShot(true); cacheSizeChecker_ = new QTimer(this); connect(cacheSizeChecker_, SIGNAL(timeout()), this, SLOT(fixCacheSizeThreaded())); cacheSizeChecker_->setSingleShot(true); //Timer to hide progressbar hideProgress_ = new QTimer(this); connect(hideProgress_, SIGNAL(timeout()), this, SLOT(hideTimeForNext())); hideProgress_->setSingleShot(true); #ifdef ON_LINUX indicatorChangeNormalTimer_ = new QTimer(this); connect(indicatorChangeNormalTimer_, SIGNAL(timeout()), this, SLOT(indicatorSetNormal())); indicatorChangeNormalTimer_->setSingleShot(true); #endif } void MainWindow::setupThemeFallbacks(){ //File Menubar ui->actionQuit_Ctrl_Q->setIcon(QIcon::fromTheme("application-exit", QIcon(":/icons/Pictures/application-exit.svg"))); //Extras Menubar ui->actionHistory->setIcon(QIcon::fromTheme("task-due", QIcon(":/icons/Pictures/task-due.svg"))); ui->action_Preferences->setIcon(QIcon::fromTheme("preferences-desktop", QIcon(":/icons/Pictures/preferences-desktop.svg"))); //Wallpapers page ui->previous_Button->setIcon(QIcon::fromTheme("media-seek-backward", QIcon(":/icons/Pictures/media-seek-backward.svg"))); ui->startButton->setIcon(QIcon::fromTheme("media-playback-start", QIcon(":/icons/Pictures/media-playback-start.svg"))); ui->stopButton->setIcon(QIcon::fromTheme("media-playback-stop", QIcon(":/icons/Pictures/media-playback-stop.svg"))); ui->next_Button->setIcon(QIcon::fromTheme("media-seek-forward", QIcon(":/icons/Pictures/media-seek-forward.svg"))); ui->search_close->setIcon(QIcon::fromTheme("window-close", QIcon(":/icons/Pictures/window-close.svg"))); ui->search_down->setIcon(QIcon::fromTheme("go-down", QIcon(":/icons/Pictures/go-down.svg"))); ui->search_up->setIcon(QIcon::fromTheme("go-up", QIcon(":/icons/Pictures/go-up.svg"))); //Wallpaper clocks page ui->install_clock->setIcon(QIcon::fromTheme("list-add", QIcon(":/icons/Pictures/list-add.svg"))); //Live website page ui->edit_crop->setIcon(QIcon::fromTheme("applications-accessories", QIcon(":/icons/Pictures/applications-accessories.svg"))); } void MainWindow::connectSignalSlots(){ connect(ui->month_checkBox, SIGNAL(clicked()), this, SLOT(clockCheckboxClicked())); connect(ui->day_month_checkBox, SIGNAL(clicked()), this, SLOT(clockCheckboxClicked())); connect(ui->day_week_checkBox, SIGNAL(clicked()), this, SLOT(clockCheckboxClicked())); connect(ui->am_checkBox, SIGNAL(clicked()), this, SLOT(clockCheckboxClicked())); connect(ui->hour_checkBox, SIGNAL(clicked()), this, SLOT(clockCheckboxClicked())); connect(ui->minutes_checkBox, SIGNAL(clicked()), this, SLOT(clockCheckboxClicked())); connect(ui->website, SIGNAL(textChanged(QString)), this, SLOT(update_website_settings())); connect(ui->website_slider, SIGNAL(valueChanged(int)), this, SLOT(update_website_settings())); connect(ui->website_crop_checkbox, SIGNAL(clicked()), this, SLOT(update_website_settings())); connect(ui->add_login_details, SIGNAL(clicked()), this, SLOT(update_website_settings())); connect(ui->username, SIGNAL(textChanged(QString)), this, SLOT(update_website_settings())); connect(ui->password, SIGNAL(textChanged(QString)), this, SLOT(update_website_settings())); connect(ui->final_webpage, SIGNAL(textChanged(QString)), this, SLOT(update_website_settings())); } void MainWindow::setupKeyboardShortcuts(){ (void) new QShortcut(Qt::Key_Escape, this, SLOT(escapePressed())); (void) new QShortcut(Qt::Key_Delete, this, SLOT(deletePressed())); (void) new QShortcut(Qt::ALT + Qt::Key_Return, this, SLOT(showProperties())); (void) new QShortcut(Qt::ALT + Qt::Key_1, this, SLOT(on_page_0_wallpapers_clicked())); (void) new QShortcut(Qt::ALT + Qt::Key_2, this, SLOT(on_page_1_earth_clicked())); (void) new QShortcut(Qt::ALT + Qt::Key_3, this, SLOT(on_page_2_potd_clicked())); (void) new QShortcut(Qt::ALT + Qt::Key_4, this, SLOT(on_page_3_clock_clicked())); (void) new QShortcut(Qt::ALT + Qt::Key_5, this, SLOT(on_page_4_web_clicked())); (void) new QShortcut(Qt::ALT + Qt::Key_6, this, SLOT(on_page_5_other_clicked())); (void) new QShortcut(Qt::CTRL + Qt::Key_F, this, SLOT(showHideSearchBox())); (void) new QShortcut(Qt::Key_Return, this, SLOT(enterPressed())); (void) new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(previousPage())); (void) new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(nextPage())); (void) new QShortcut(Qt::ALT + Qt::Key_F4, this, SLOT(escapePressed())); } void MainWindow::closeWhatsRunning(){ if(gv.wallpapersRunning){ on_stopButton_clicked(); } else if(gv.liveEarthRunning){ on_deactivate_livearth_clicked(); } else if(gv.potdRunning){ on_deactivate_potd_clicked(); } else if(gv.wallpaperClocksRunning){ on_deactivate_clock_clicked(); } else if(gv.liveWebsiteRunning){ on_deactivate_website_clicked(); } } QString MainWindow::base64Encode(const QString &string){ return QByteArray().append(string).toBase64(); } void MainWindow::resetWatchFolders(){ /* * Unfortunately, this is the only way to completely reset QFileSystemWatcher, because * the removePaths(s) function fails miserably most of the times. */ if(gv.mainwindowLoaded){ delete watchFolders_; } watchFolders_ = new QFileSystemWatcher(this); connect(watchFolders_, SIGNAL(directoryChanged(QString)), this, SLOT(folderChanged())); } void MainWindow::onlineRequestFailed(){ bool somethingWasRunning=processingOnlineRequest_; closeWhatsRunning(); processRequestStop(); if(somethingWasRunning) { QMessageBox::warning(this, tr("Internet Connection"), tr("There was a problem while trying to download what you requested. Please check your internet connection.")); } } void MainWindow::onlineImageRequestReady(QString image){ imageTransition(image); processRequestStop(); } void MainWindow::escapePressed(){ if(ui->stackedWidget->currentIndex()==0 && ui->search_box->hasFocus() && searchIsOn_){ on_search_close_clicked(); } else{ strongMinimize(); } } void MainWindow::deletePressed(){ if(ui->stackedWidget->currentIndex()==0 && ui->listWidget->selectedItems().count()>0){ if(ui->listWidget->selectedItems().count()>1){ removeImagesFromDisk(); } else{ removeImageFromDisk(); } } else if(ui->stackedWidget->currentIndex()==3 && ui->clocksTableWidget->selectedItems().count()>0){ uninstall_clock(); } } void MainWindow::startUpdateSeconds(){ if(updateSecondsTimer_->isActive()){ updateSecondsTimer_->stop(); } updateSeconds(); updateSecondsTimer_->start(1000); if(timeForNext_->isHidden()){ timeForNext_->show(); #ifdef ON_LINUX if(gv.currentDE==UnityGnome && gv.unityProgressbarEnabled){ Global::setUnityProgressBarEnabled(true); } #endif } } void MainWindow::updatePotdProgress(){ int secsToPotd = Global::getSecondsTillHour("00:00"); if(secsToPotd<=3600){ //less than one hour left timeForNext_->setFormat(secondsToHms(secsToPotd)); } else { timeForNext_->setFormat(secondsToHm(secsToPotd)); } setProgressbarsValue(short(((float) (secsToPotd/86400.0)) * 100)); } void MainWindow::setProgressbarsValue(short value){ timeForNext_->setValue(value); #ifdef ON_LINUX if(gv.currentDE==UnityGnome && gv.unityProgressbarEnabled){ Global::setUnityProgressbarValue((float)(value/100.0)); } #endif } void MainWindow::imageTransition(const QString &filename) { if(!gv.previewImagesOnScreen || !gv.mainwindowLoaded){ return; } if(filename=="preview_clock"){ if(!futureWatcherWallClocksPreview_.isFinished()){ futureWatcherWallClocksPreview_.cancel(); } QFuture future = QtConcurrent::run(std::bind(&MainWindow::wallpaperClocksPreview, this, gv.defaultWallpaperClock, ui->minutes_checkBox->isChecked(), ui->hour_checkBox->isChecked(), ui->am_checkBox->isChecked(), ui->day_week_checkBox->isChecked(), ui->day_month_checkBox->isChecked(), ui->month_checkBox->isChecked())); futureWatcherWallClocksPreview_.setFuture(future); } else { if(!futureWatcherWallpapersPreview_.isFinished()){ futureWatcherWallpapersPreview_.cancel(); } QFuture future = QtConcurrent::run(this, &MainWindow::scaleWallpapersPreview, filename); futureWatcherWallpapersPreview_.setFuture(future); } } void MainWindow::wallpaperClocksPreviewImageGenerationFinished(){ if(futureWatcherWallClocksPreview_.isCanceled()){ QImage *result=futureWatcherWallClocksPreview_.result(); if(result!=NULL){ delete result; } return; } QImage *image = futureWatcherWallClocksPreview_.result(); QImage *old = image; image = new QImage(old->scaled(QSize(old->width()*imagePreviewResizeFactorX_, old->height()*imagePreviewResizeFactorY_), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); delete old; setupAnimationsAndChangeImage(image); } void MainWindow::wallpapersPreviewImageGenerationFinished(){ if(futureWatcherWallpapersPreview_.isCanceled()){ QImage *result=futureWatcherWallpapersPreview_.result(); if(result!=NULL){ delete result; } return; } setupAnimationsAndChangeImage(futureWatcherWallpapersPreview_.result()); } QImage *MainWindow::scaleWallpapersPreview(QString filename){ QImageReader reader(filename); reader.setScaledSize(QSize(reader.size().width()*imagePreviewResizeFactorX_, reader.size().height()*imagePreviewResizeFactorY_)); QImage *image = new QImage(reader.read()); return image; } void MainWindow::setupAnimationsAndChangeImage(QImage *image){ if(ui->screen_label->pixmap()) { ui->screen_label_transition->setPixmap(*ui->screen_label->pixmap()); } else { ui->screen_label_transition->clear(); } ui->screen_label_text->clear(); opacityEffect_->setOpacity(false); ui->screen_label->setGraphicsEffect(opacityEffect_); QPropertyAnimation* increaseOpacityAnimation = new QPropertyAnimation(this); increaseOpacityAnimation->setTargetObject(opacityEffect_); increaseOpacityAnimation->setPropertyName("opacity"); increaseOpacityAnimation->setDuration(IMAGE_TRANSITION_SPEED); increaseOpacityAnimation->setStartValue(opacityEffect_->opacity()); increaseOpacityAnimation->setEndValue(1); increaseOpacityAnimation->setEasingCurve(QEasingCurve::OutQuad); increaseOpacityAnimation->start(QAbstractAnimation::DeleteWhenStopped); if(ui->screen_label->isHidden()){ ui->screen_label->show(); } opacityEffect2_->setOpacity(true); ui->screen_label_transition->setGraphicsEffect(opacityEffect2_); QPropertyAnimation* decreaseOpacityAnimation = new QPropertyAnimation(this); decreaseOpacityAnimation->setTargetObject(opacityEffect2_); decreaseOpacityAnimation->setPropertyName("opacity"); decreaseOpacityAnimation->setDuration(IMAGE_TRANSITION_SPEED); decreaseOpacityAnimation->setStartValue(opacityEffect2_->opacity()); decreaseOpacityAnimation->setEndValue(0); decreaseOpacityAnimation->setEasingCurve(QEasingCurve::OutQuad); decreaseOpacityAnimation->start(QAbstractAnimation::DeleteWhenStopped); QtConcurrent::run(this, &MainWindow::setPreviewImage, image); } void MainWindow::hideScreenLabel() { if(!gv.previewImagesOnScreen){ return; } if(ui->screen_label->pixmap()){ ui->screen_label_transition->setPixmap(QPixmap::fromImage(ui->screen_label->pixmap()->toImage())); } else { ui->screen_label_transition->clear(); return; } ui->screen_label->clear(); opacityEffect2_->setOpacity(true); ui->screen_label_transition->setGraphicsEffect(opacityEffect2_); QPropertyAnimation* anim = new QPropertyAnimation(this); anim->setTargetObject(opacityEffect2_); anim->setPropertyName("opacity"); anim->setDuration(IMAGE_TRANSITION_SPEED); anim->setStartValue(opacityEffect2_->opacity()); anim->setEndValue(false); anim->setEasingCurve(QEasingCurve::OutQuad); anim->start(QAbstractAnimation::DeleteWhenStopped); } void MainWindow::setPreviewImage(QImage *image){ if(!gv.previewImagesOnScreen){ if(image!=NULL){ delete image; } return; } if(image && !image->isNull()){ #ifdef ON_LINUX DesktopStyle desktopStyle=getDesktopStyle(); if(image->format()==QImage::Format_Indexed8){ //painting on QImage::Format_Indexed8 is not supported QImage *old=image; image = new QImage(QSize(old->width(), old->height()), QImage::Format_ARGB32_Premultiplied); QPainter painter(image); painter.drawImage(QPoint(0, 0), *old); painter.end(); delete old; } QImage colorsGradientsImage(75, 75, QImage::Format_RGB32); //bring me some food right meow! bool previewColorsAndGradientsMeow=true; if(desktopStyle==Tile || desktopStyle==Stretch){ //the preview of the background color(s) is meaningless for the current styling previewColorsAndGradientsMeow=false; } ColoringType coloringType=Global::getColoringType(); if(previewColorsAndGradientsMeow || desktopStyle==NoneStyle){ if(desktopStyle==NoneStyle){ QImage *old=image; image = new QImage(); delete old; } QString primaryColor; if(gv.setAverageColor) { primaryColor = QColor::fromRgb(image->scaled(1, 1, Qt::IgnoreAspectRatio, Qt::FastTransformation).pixel(0, 0)).name(); } else { primaryColor = Global::getPrimaryColor(); } colorsGradientsImage.fill(primaryColor); if(coloringType!=SolidColor && coloringType!=NoneColor) { QString secondaryColor=Global::getSecondaryColor(); short alpha=255; short softness=0; QPainter painter(&colorsGradientsImage); QColor color(secondaryColor); for(short i=75;i>0;i--){ if(!softness){ alpha-=1; if(alpha<=244){ softness=1; } } else if(softness==1){ alpha-=3; if(alpha<=205){ softness=2; } } else if(softness==2){ alpha-=4; } color.setAlpha(alpha); painter.fillRect(i-1, 0, 1, 75, QColor(color)); } painter.end(); if(coloringType==VerticalColor){ //just rotate the image colorsGradientsImage = colorsGradientsImage.transformed(QTransform().rotate(90), Qt::SmoothTransformation); } } } int vScreenWidth= int((float)imagePreviewResizeFactorX_*gv.screenWidth); int vScreenHeight=int((float)imagePreviewResizeFactorY_*gv.screenHeight); //making the preview exactly like it will be shown at the desktop switch(desktopStyle){ //Many thanks to http://askubuntu.com/questions/226816/background-setting-cropping-options case Tile: { //Tile (or "wallpaper" picture-option) /* * How it works (in Unity-Gnome): * We have to repeat the image in case its width or height is less than the screen's * If only one of the width or height are less then the screen's, then the one that * is greater or equal is centered */ if(image->width() < vScreenWidth || image->height() < vScreenHeight){ QImage originalImage = *image; //find how many times (rounded UPWARDS) short timesX = (vScreenWidth+originalImage.width()-1)/originalImage.width(); short timesY = (vScreenHeight+originalImage.height()-1)/originalImage.height(); QImage *old=image; image = new QImage(image->copy(0, 0, vScreenWidth, vScreenHeight)); delete old; image->fill(Qt::black); QPainter painter(image); if(timesX>1 && timesY>1){ //both width and height of the image are less than the screen's for(short i=0; i1){ //timesY equals 1, this means the image's height is greater or equal to gv.screenHeight. So, the image must be centered on the height. short yPos = 0-(originalImage.height()-vScreenHeight)/2.0; for(short i=0; icopy(0, 0, vScreenWidth, vScreenHeight)); delete old; image->fill(Qt::black); QPainter painter(image); painter.drawPixmap((vScreenWidth-originalImage.width())/2, (vScreenHeight-originalImage.height())/2, QPixmap::fromImage(originalImage)); painter.end(); } else { //just start from the top left of the image and fill the rest. QImage *old=image; image = new QImage(image->copy(0, 0, vScreenWidth, vScreenHeight)); delete old; } } break; } case Zoom: { //Zoom /* * How it works: * It calculates the max of vScreenWidth/imageWidth and vScreenHeight/imageHeight. * It stretches the corresponding dimension to fit the screen. * The other dimension is centered. */ QImage originalImage = *image; QImage *old=image; image = new QImage(vScreenWidth, vScreenHeight, QImage::Format_ARGB32_Premultiplied); delete old; image->fill(Qt::transparent); QPainter painter(image); float widthFactor = (float) vScreenWidth / originalImage.width(); float heightFactor = (float) vScreenHeight / originalImage.height(); int newWidth, newHeight; if(widthFactor>heightFactor){ //it expands via the width, so center the height newWidth = floor (originalImage.width() * widthFactor + 0.5); newHeight = floor (originalImage.height() * widthFactor + 0.5); painter.drawPixmap(0, (vScreenHeight-newHeight)/2, newWidth, newHeight, QPixmap::fromImage(originalImage)); } else { //it expands via the height, so center the width newWidth = floor (originalImage.width() * heightFactor + 0.5); newHeight = floor (originalImage.height() * heightFactor + 0.5); painter.drawPixmap((vScreenWidth-newWidth)/2, 0, newWidth, newHeight, QPixmap::fromImage(originalImage)); } painter.end(); break; } case Center: { //Center /* * How it works: * If the image is smaller than the screen's width then just center it. Everything else is black. * If one or more dimensions of the image are larger than the screen's just crop the image to the * screen's dimension and center it. */ QImage originalImage = *image; QImage *old=image; image = new QImage(vScreenWidth, vScreenHeight, QImage::Format_ARGB32_Premultiplied); delete old; image->fill(Qt::transparent); QPainter painter(image); painter.drawPixmap((vScreenWidth-originalImage.width())/2, (vScreenHeight-originalImage.height())/2, QPixmap::fromImage(originalImage)); painter.end(); break; } case Scale: { //Scale - same as Span. /* * How it works: * It calculates the min of vScreenWidth/imageWidth and vScreenHeight/imageHeight. * It stretches the corresponding dimension to fit the screen. * The other dimension is centered. */ QImage originalImage = *image; QImage *old=image; image = new QImage(vScreenWidth, vScreenHeight, QImage::Format_ARGB32_Premultiplied); delete old; image->fill(Qt::transparent); QPainter painter(image); float width_factor = (float) vScreenWidth / originalImage.width(); float height_factor = (float) vScreenHeight / originalImage.height(); int new_width, new_height; if(width_factorwidth() > 2*SCREEN_LABEL_SIZE_X || image->height() > 2*SCREEN_LABEL_SIZE_Y){ image = new QImage(image->scaled(2*SCREEN_LABEL_SIZE_X, 2*SCREEN_LABEL_SIZE_Y, Qt::IgnoreAspectRatio, Qt::FastTransformation).scaled(SCREEN_LABEL_SIZE_X, SCREEN_LABEL_SIZE_Y, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } else { image = new QImage(image->scaled(SCREEN_LABEL_SIZE_X, SCREEN_LABEL_SIZE_Y, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } delete old; } if(previewColorsAndGradientsMeow || desktopStyle==NoneStyle){ colorsGradientsImage=colorsGradientsImage.scaled(SCREEN_LABEL_SIZE_X, SCREEN_LABEL_SIZE_Y, Qt::IgnoreAspectRatio, Qt::FastTransformation); QPainter painter; painter.begin(&colorsGradientsImage); painter.drawPixmap(0, 0, QPixmap::fromImage(*image)); painter.end(); QImage *old=image; image = new QImage(colorsGradientsImage); delete old; } #else QImage *old = image; image = new QImage(image->scaled(2*SCREEN_LABEL_SIZE_X, 2*SCREEN_LABEL_SIZE_Y, Qt::IgnoreAspectRatio, Qt::FastTransformation).scaled(SCREEN_LABEL_SIZE_X, SCREEN_LABEL_SIZE_Y, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); delete old; #endif //#ifdef ON_LINUX ui->screen_label->setPixmap(QPixmap::fromImage(*image)); } delete image; } void MainWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasFormat("text/plain")){ event->acceptProposedAction(); } } void MainWindow::dropEvent(QDropEvent *event) { switch(ui->stackedWidget->currentIndex()){ case 0: { //something was dropped inside the Wallpapers page! QList urlList = event->mimeData()->urls(); for (QList::const_iterator i = urlList.begin(); i != urlList.end();i++) { //removing extra characters from the absolute path... QString dropped_temp=(*i).toString(); QString droppedfile = dropped_temp.mid(7, dropped_temp.length()-2); addFolderForMonitor(droppedfile); } break; } case 3: { QList urlList = event->mimeData()->urls(); for (QList::const_iterator i = urlList.begin(); i != urlList.end();i++) { QString dropped_temp=(*i).toString(); QString droppedfile = dropped_temp.mid(7, dropped_temp.length()-2); if(droppedfile.endsWith(".wcz")){ //wallpaper clock! Install it! installWallpaperClock(droppedfile); } } break; } default: event->acceptProposedAction(); return; } event->acceptProposedAction(); } void MainWindow::animateProgressbarOpacity(bool show){ if(hideProgress_->isActive()){ hideProgress_->stop(); } opacityEffect_->setOpacity(!show); if(show) { timeForNext_->show(); } else { hideProgress_->start(400); } #ifdef ON_LINUX if(gv.currentDE==UnityGnome && gv.unityProgressbarEnabled){ Global::setUnityProgressBarEnabled(show); } #endif //#ifdef ON_LINUX timeForNext_->setGraphicsEffect(opacityEffect_); QPropertyAnimation* anim = new QPropertyAnimation(this); anim->setTargetObject(opacityEffect_); anim->setPropertyName("opacity"); anim->setDuration(400); anim->setStartValue(opacityEffect_->opacity()); anim->setEndValue(show); anim->setEasingCurve(QEasingCurve::OutQuad); anim->start(QAbstractAnimation::DeleteWhenStopped); } void MainWindow::hideTimeForNext() { timeForNext_->hide(); timeForNext_->setFormat(tr("Calculating...")); setProgressbarsValue(100); } void MainWindow::findSeconds(bool typeCountSeconds) { int count_seconds=gv.customIntervalsInSeconds.at(ui->timerSlider->value()-1); if(typeCountSeconds) { //true,its time to change wallpaper and we want //to change the seconds_left to the current value of slider and to temp save the current value of slider. secondsLeft_=totalSeconds_=count_seconds; } else { //false, we just changed the value of the slider and we want the value to be converted //in seconds BUT we don't want seconds_left or tmp_slider to be changed. secondsInWallpapersSlider_=count_seconds; } } void MainWindow::processRequestStart(){ if(processingOnlineRequest_){ return; } processingOnlineRequest_=true; ui->process_request_label->show(); processingRequestGif_->start(); if(gv.previewImagesOnScreen){ ui->screen_label_info->setText(tr("Processing Request")+"..."); } } void MainWindow::processRequestStop(){ if(!processingOnlineRequest_){ return; } processingOnlineRequest_=false; processingRequestGif_->stop(); ui->process_request_label->hide(); if(gv.previewImagesOnScreen){ ui->screen_label_info->clear(); } if(gv.potdRunning){ QString filename=Global::getFilename(gv.wallchHomePath+POTD_IMAGE+"*"); if(!filename.isEmpty() && ui->stackedWidget->currentIndex()==2 && QFile::exists(filename)){ imageTransition(filename); } } } void MainWindow::setStyle(){ #ifdef ON_LINUX if(gv.currentDE==UnityGnome || gv.currentDE==Gnome || gv.currentDE==Mate){ ui->image_style_combo->addItem(tr("Tile")); ui->image_style_combo->addItem(tr("Zoom")); ui->image_style_combo->addItem(tr("Center")); ui->image_style_combo->addItem(tr("Scale")); if(gv.currentDE==Mate){ ui->image_style_combo->addItem(tr("Stretched")); } else { ui->image_style_combo->addItem(tr("Fill")); } ui->image_style_combo->addItem(tr("Span")); QString style; if(gv.currentDE==Mate){ style=Global::gsettingsGet("org.mate.background", "picture-options"); } else { style=Global::gsettingsGet("org.gnome.desktop.background", "picture-options"); } short index=0; if (style=="zoom") { index=1; } else if (style=="centered"){ index=2; } else if (style=="scaled") { index=3; } else if (style=="stretched") { index=4; } else if (style=="spanned") { index=5; } ui->image_style_combo->setCurrentIndex(index); } else if(gv.currentDE==XFCE){ ui->image_style_combo->addItem(tr("None")); ui->image_style_combo->addItem(tr("Centered")); ui->image_style_combo->addItem(tr("Tiled")); ui->image_style_combo->addItem(tr("Stretched")); ui->image_style_combo->addItem(tr("Scaled")); ui->image_style_combo->addItem(tr("Zoomed")); int index=0; Q_FOREACH(QString entry, Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("image-style")){ QString imageStyle=Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry); index=imageStyle.toInt(); } } if(indeximage_style_combo->count() && index>=0){ ui->image_style_combo->setCurrentIndex(index); } } else if(gv.currentDE==LXDE){ ui->image_style_combo->addItem(tr("Empty")); ui->image_style_combo->addItem(tr("Fill")); ui->image_style_combo->addItem(tr("Fit")); ui->image_style_combo->addItem(tr("Center")); ui->image_style_combo->addItem(tr("Tile")); int value = Global::getPcManFmValue("wallpaper_mode").toInt(); if(valueimage_style_combo->count() && value>=0){ ui->image_style_combo->setCurrentIndex(value); } } #else ui->image_style_combo->addItem(tr("Tile")); ui->image_style_combo->addItem(tr("Center")); ui->image_style_combo->addItem(tr("Stretch")); if(settings->value("windows_major_version").toInt()==6 && settings->value("windows_minor_version").toInt()>= 1) { ui->image_style_combo->addItem(tr("Fit")); ui->image_style_combo->addItem(tr("Fill")); } QSettings desktop_settings("HKEY_CURRENT_USER\\Control Panel\\Desktop", QSettings::NativeFormat); switch(desktop_settings.value("WallpaperStyle").toInt()) { default: case 0: if(desktop_settings.value("TileWallpaper")!=0){ ui->image_style_combo->setCurrentIndex(0); } else{ ui->image_style_combo->setCurrentIndex(1); } break; case 2: ui->image_style_combo->setCurrentIndex(2); break; case 6: ui->image_style_combo->setCurrentIndex(3); break; case 10: ui->image_style_combo->setCurrentIndex(4); break; } #endif //#ifdef ON_LINUX gv.mainwindowLoaded=true; updateScreenLabel(); } DesktopStyle MainWindow::getDesktopStyle(){ DesktopStyle desktopStyle=Stretch; if(gv.currentDE==UnityGnome || gv.currentDE==Gnome || gv.currentDE==Mate){ switch(ui->image_style_combo->currentIndex()){ default: case 0: desktopStyle=Tile; break; case 1: desktopStyle=Zoom; break; case 2: desktopStyle=Center; break; case 5: case 3: desktopStyle=Scale; break; case 4: desktopStyle=Stretch; break; } } else if(gv.currentDE==XFCE){ switch(ui->image_style_combo->currentIndex()){ case 0: desktopStyle=NoneStyle; break; case 1: desktopStyle=Center; break; case 2: desktopStyle=Tile; break; default: case 3: desktopStyle=Stretch; break; case 4: desktopStyle=Scale; break; case 5: desktopStyle=Zoom; break; } } else if(gv.currentDE==LXDE){ switch(ui->image_style_combo->currentIndex()){ case 0: desktopStyle=NoneStyle; break; default: case 1: desktopStyle=Stretch; break; case 2: desktopStyle=Scale; break; case 3: desktopStyle=Center; break; case 4: desktopStyle=Tile; break; } } return desktopStyle; } void MainWindow::setButtonColor() { QString colorName; #ifdef ON_LINUX colorName=Global::getPrimaryColor(); #else QSettings collorSetting("HKEY_CURRENT_USER\\Control Panel\\Colors", QSettings::NativeFormat); colorName=collorSetting.value("Background", "0 0 0").toString(); QList rgb; QString temp; for(short i=0; colorName.size()>i; i++) { if(i==colorName.size()-1) { temp.append(colorName.at(i)); rgb.append(temp.toInt()); } else if(colorName.at(i)==' ') { rgb.append(temp.toInt()); temp.clear(); } else{ temp.append(colorName.at(i)); } } colorName=QColor(rgb.at(0), rgb.at(1), rgb.at(2)).name(); #endif //#ifdef ON_LINUX setButtonColor(colorName); } void MainWindow::setButtonColor(const QString &color_name){ #ifdef ON_WINDOWS QImage image(40, 19, QImage::Format_ARGB32_Premultiplied); image.fill(color_name); ui->set_desktop_color->setIcon(QIcon(QPixmap::fromImage(image))); #else #endif ColoringType coloringType=Global::getColoringType(); if(coloringType == SolidColor){ QImage image(40, 19, QImage::Format_ARGB32_Premultiplied); image.fill(color_name); ui->set_desktop_color->setIcon(QIcon(QPixmap::fromImage(image))); } else { QString secondaryColor=Global::getSecondaryColor(); QImage image(75, 75, QImage::Format_RGB32); image.fill(Qt::white); QColor color(color_name); image.fill(color); color.setNamedColor(secondaryColor); short alpha=255; short softness=0; QPainter paint; paint.begin(&image); for(short i=75;i>0;i--){ if(!softness){ alpha-=1; if(alpha<=244){ softness=1; } } else if(softness==1){ alpha-=3; if(alpha<=205){ softness=2; } } else if(softness==2){ alpha-=4; } color.setAlpha(alpha); paint.fillRect(i-1, 0, 1, 75, QColor(color)); } paint.end(); if(coloringType == VerticalColor) { image = image.transformed(QTransform().rotate(+90), Qt::SmoothTransformation); } updateColorButton(image); } } void MainWindow::on_image_style_combo_currentIndexChanged(int index) { if(!gv.mainwindowLoaded){ return; } #ifdef ON_LINUX if(gv.currentDE==Gnome || gv.currentDE==UnityGnome || gv.currentDE==Mate){ QString type; switch(index){ case 0: type="wallpaper"; break; default: case 1: type="zoom"; break; case 2: type="centered"; break; case 3: type="scaled"; break; case 4: type="stretched"; break; case 5: type="spanned"; break; } if(gv.currentDE==Mate){ Global::gsettingsSet("org.mate.background", "picture-options", type); } else { Global::gsettingsSet("org.gnome.desktop.background", "picture-options", type); } } else if(gv.currentDE==XFCE){ Q_FOREACH(QString entry, Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("image-style")){ QProcess::startDetached("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry << "-s" << QString::number(index)); } } } else if(gv.currentDE==LXDE){ QString style; switch(index){ default: case 0: style="color"; break; case 1: style="stretch"; break; case 2: style="fit"; break; case 3: style="center"; break; case 4: style="tile"; break; } QProcess::startDetached("pcmanfm", QStringList() << "--wallpaper-mode="+style); } #else /* * ----------Reference: http://msdn.microsoft.com/en-us/library/bb773190(VS.85).aspx#desktop------------ * Two registry values are set in the Control Panel\Desktop key. * TileWallpaper * 0: The wallpaper picture should not be tiled * 1: The wallpaper picture should be tiled * WallpaperStyle * 0: The image is centered if TileWallpaper=0 or tiled if TileWallpaper=1 * 2: The image is stretched to fill the screen * 6: The image is resized to fit the screen while maintaining the aspect * ratio. (Windows 7 and later) * 10: The image is resized and cropped to fill the screen while * maintaining the aspect ratio. (Windows 7 and later) * ----------------------------------------------------------------------------------------------------- */ /* * Unfortunately QSettings can't manage to change a registry DWORD, * so we have to go with the Windows' way. */ HRESULT hr = S_OK; HKEY hKey = NULL; hr = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_READ | KEY_WRITE, &hKey)); if (SUCCEEDED(hr)) { PWSTR pszWallpaperStyle; PWSTR pszTileWallpaper; wchar_t zero[10] = L"0"; wchar_t one[10] = L"1"; wchar_t two[10] = L"2"; wchar_t six[10] = L"6"; wchar_t ten[10] = L"10"; switch (index) { case 0: //tile pszWallpaperStyle = zero; pszTileWallpaper = one; break; case 1: //center pszWallpaperStyle = zero; pszTileWallpaper = zero; break; case 2: //stretch pszWallpaperStyle = two; pszTileWallpaper = zero; break; case 3: //fit (Windows 7 and later) pszWallpaperStyle = six; pszTileWallpaper = zero; break; case 4: //fill (Windows 7 and later) pszWallpaperStyle = ten; pszTileWallpaper = zero; break; } //set the WallpaperStyle and TileWallpaper registry values. DWORD cbData = lstrlen(pszWallpaperStyle) * sizeof(*pszWallpaperStyle); hr = HRESULT_FROM_WIN32(RegSetValueEx(hKey, L"WallpaperStyle", 0, REG_SZ, reinterpret_cast(pszWallpaperStyle), cbData)); if (SUCCEEDED(hr)) { cbData = lstrlen(pszTileWallpaper) * sizeof(*pszTileWallpaper); hr = HRESULT_FROM_WIN32(RegSetValueEx(hKey, L"TileWallpaper", 0, REG_SZ, reinterpret_cast(pszTileWallpaper), cbData)); } RegCloseKey(hKey); } //set the desktop background to the already current background image now with the style changed! #ifdef UNICODE SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, (PVOID) Global::currentBackgroundImage().toLocal8Bit().data(), SPIF_UPDATEINIFILE); #else SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (PVOID) Global::currentBackgroundImage().toLocal8Bit().data(), SPIF_UPDATEINIFILE); #endif #endif //#ifdef ON_LINUX if(ui->screen_label_text->text().isEmpty()){ updateScreenLabel(); } } void MainWindow::actionsOnWallpaperChange(){ if(gv.wallpapersRunning) { if(!currentFolderExists()){ return; } if(gv.randomTimeEnabled) { srand(time(0)); secondsLeft_=(rand()%(gv.randomTimeTo-gv.randomTimeFrom+1))+gv.randomTimeFrom; initialRandomSeconds_=secondsLeft_; totalSeconds_=secondsLeft_; } else { findSeconds(true); } if(startWasJustClicked_){ startWasJustClicked_=false; if(!gv.firstTimeout){ changeImage(); } } else { if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(-1, 0); } changeImage(); } Global::saveSecondsLeftNow(secondsLeft_, 0); } else if(gv.wallpaperClocksRunning){ QString currentWallpaperClock=Global::wallpaperClockNow(gv.defaultWallpaperClock, ui->minutes_checkBox->isChecked(), ui->hour_checkBox->isChecked(), ui->am_checkBox->isChecked(), ui->day_week_checkBox->isChecked(), ui->day_month_checkBox->isChecked(), ui->month_checkBox->isChecked()); if(gv.setAverageColor){ setAverageColor(currentWallpaperClock); } if(ui->minutes_checkBox->isChecked()){ secondsLeft_=60; } else if (ui->hour_checkBox->isChecked()){ secondsLeft_=gv.refreshhourinterval*60; } else if(ui->am_checkBox->isChecked() && gv.amPmEnabled){ secondsLeft_=43200; } else if(ui->day_week_checkBox->isChecked() || ui->day_month_checkBox->isChecked() || ui->month_checkBox->isChecked()){ secondsLeft_=86400; } totalSeconds_=secondsLeft_; } else if(gv.liveWebsiteRunning){ ui->timeout_text_label->show(); ui->website_timeout_label->show(); processRequestStart(); websiteSnapshot_->start(); secondsLeft_=Global::websiteSliderValueToSeconds(ui->website_slider->value()); Global::saveSecondsLeftNow(secondsLeft_, 2); } else if(gv.liveEarthRunning){ processRequestStart(); globalParser_->livearth(); secondsLeft_=1800; Global::saveSecondsLeftNow(secondsLeft_, 1); } else if(gv.potdRunning){ justUpdatedPotd_=true; //time has come QString lastDaySet=settings->value("last_day_potd_was_set", "").toString(); QString dateTimeNow = QDateTime::currentDateTime().toString("dd.MM.yyyy"); if(settings->value("potd_preferences_have_changed", false).toBool() || dateTimeNow!=lastDaySet){ //the previous time that photoofday changed was another day or the settings have changed processRequestStart(); globalParser_->potd(); } else { /* * The previous time was today, so the picture must be still there, * so re-set it as background, no need to download anything! */ QString filename = Global::getFilename(gv.wallchHomePath+POTD_IMAGE+"*"); Global::debug("Picture of the day has already been downloaded."); if(filename.isEmpty()){ Global::error("Probably you set the picture of the day today but you removed the original\n"\ "downloaded photo. If it didn't happen like this, please report this as a bug!\n"\ "Wallch will now attemp to download again the Picture Of The Day."); processRequestStart(); globalParser_->potd(); } Global::setBackground(filename, true, true, 3); } } } void MainWindow::updateSeconds(){ /* * This function updates the seconds of the progressbar of Wallch and launches * the corresponding action when the seconds have passed! */ if(gv.potdRunning){ if(Global::timeNowToString()=="00:00"){ if(!justUpdatedPotd_){ actionsOnWallpaperChange(); } } else { justUpdatedPotd_=false; } updatePotdProgress(); } else { gv.runningTimeOfProcess = QDateTime::currentDateTime(); if(secondsLeft_<=0){ actionsOnWallpaperChange(); gv.timeToFinishProcessInterval = gv.runningTimeOfProcess.addSecs(secondsLeft_); } //in case the computer went to hibernate/suspend take actions if(secondsLeft_!=gv.runningTimeOfProcess.secsTo(gv.timeToFinishProcessInterval)) { int secondsToChange = gv.runningTimeOfProcess.secsTo(gv.timeToFinishProcessInterval); if(secondsToChange<=0) { //the wallpaper should've already changed! actionsOnWallpaperChange(); gv.timeToFinishProcessInterval = gv.runningTimeOfProcess.addSecs(secondsLeft_); } else if (!(gv.wallpaperClocksRunning&& (secondsLeft_-secondsToChange<-1 || secondsLeft_-secondsToChange>1))){ //the time has yet to come, just update if(abs(secondsLeft_-secondsToChange)>1){ secondsLeft_=secondsToChange; } } } timeForNext_->setFormat(secondsToHms(secondsLeft_)); if(gv.wallpapersRunning) { if(gv.randomTimeEnabled){ setProgressbarsValue((secondsLeft_*100)/initialRandomSeconds_); } else{ setProgressbarsValue((secondsLeft_*100)/(totalSeconds_)); } } else if(gv.wallpaperClocksRunning){ setProgressbarsValue(secondsLeft_*100/totalSeconds_); } else if(gv.liveWebsiteRunning){ setProgressbarsValue((secondsLeft_*100)/(Global::websiteSliderValueToSeconds(ui->website_slider->value()))); if(processingOnlineRequest_ && timePassedForLiveWebsiteRequest_<=WEBSITE_TIMEOUT){ ui->website_timeout_label->setText(QString::number(WEBSITE_TIMEOUT+1-(timePassedForLiveWebsiteRequest_++))+" "+tr("seconds")+"..."); } } else if(gv.liveEarthRunning){ setProgressbarsValue(secondsLeft_*100/1800); } secondsLeft_--; } } void MainWindow::nextKeySignal(const char *, void *){ mainWindowInstance->click_shortcut_next(); } void MainWindow::click_shortcut_next(){ on_next_Button_clicked(); } #ifdef ON_LINUX void MainWindow::bindKey(const QString &key){ if(!keybinder_bind(key.toLocal8Bit().data(), nextKeySignal, NULL)){ //key could not be binded! Global::error("I probably could not bind the key sequence: '"+key+"'"); } } void MainWindow::unbindKey(const QString &key){ keybinder_unbind(key.toLocal8Bit().data(), nextKeySignal); } #endif void MainWindow::on_website_slider_valueChanged(int value) { ui->website_interval_slider_label->setText(secondsToMh(Global::websiteSliderValueToSeconds(value))); } void MainWindow::setThemeToAmbiance(){ ui->page_0_wallpapers->setStyleSheet(AMBIANCE_THEME_STYLESHEET); ui->page_1_earth->setStyleSheet(AMBIANCE_THEME_STYLESHEET); ui->page_2_potd->setStyleSheet(AMBIANCE_THEME_STYLESHEET); ui->page_3_clock->setStyleSheet(AMBIANCE_THEME_STYLESHEET); ui->page_4_web->setStyleSheet(AMBIANCE_THEME_STYLESHEET); ui->page_5_other->setStyleSheet(AMBIANCE_THEME_STYLESHEET); ui->sep1->setPixmap(AMBIANCE_SEPARATOR); ui->sep2->setPixmap(AMBIANCE_SEPARATOR); ui->sep3->setPixmap(AMBIANCE_SEPARATOR); ui->sep4->setPixmap(AMBIANCE_SEPARATOR); ui->sep5->setPixmap(AMBIANCE_SEPARATOR); ui->widget->setStyleSheet("QWidget { background-image: url(:/icons/Pictures/ambiance_not_checked.png); }"); } void MainWindow::setThemeToRadiance(){ ui->page_0_wallpapers->setStyleSheet(RADIANCE_THEME_STYLESHEET); ui->page_1_earth->setStyleSheet(RADIANCE_THEME_STYLESHEET); ui->page_2_potd->setStyleSheet(RADIANCE_THEME_STYLESHEET); ui->page_3_clock->setStyleSheet(RADIANCE_THEME_STYLESHEET); ui->page_4_web->setStyleSheet(RADIANCE_THEME_STYLESHEET); ui->page_5_other->setStyleSheet(RADIANCE_THEME_STYLESHEET); ui->sep1->setPixmap(RADIANCE_SEPARATOR); ui->sep2->setPixmap(RADIANCE_SEPARATOR); ui->sep3->setPixmap(RADIANCE_SEPARATOR); ui->sep4->setPixmap(RADIANCE_SEPARATOR); ui->sep5->setPixmap(RADIANCE_SEPARATOR); ui->widget->setStyleSheet("QWidget { background-image: url(:/icons/Pictures/radiance_not_checked.png); }"); } void MainWindow::changeCurrentThemeTo(const QString &theme) { gv.currentTheme=theme; if(theme=="ambiance") { setThemeToAmbiance(); } else if(theme=="radiance") { setThemeToRadiance(); } else { //autodetect! QString curTheme; #ifdef ON_LINUX if(gv.currentDE==Gnome || gv.currentDE==UnityGnome){ curTheme = Global::gsettingsGet("org.gnome.desktop.interface", "gtk-theme"); } else { if(gv.currentTheme=="ambiance"){ curTheme="Ambiance"; } else { curTheme="Radiance"; } } #endif if(curTheme=="Ambiance"){ gv.currentTheme="ambiance"; setThemeToAmbiance(); } else { gv.currentTheme="radiance"; setThemeToRadiance(); } } } void MainWindow::closeEverythingThatsRunning(short excludingFeature) { if(excludingFeature!=1 && gv.wallpapersRunning){ on_stopButton_clicked(); } else if(excludingFeature!=2 && gv.liveEarthRunning){ on_deactivate_livearth_clicked(); } else if(excludingFeature!=3 && gv.potdRunning){ on_deactivate_potd_clicked(); } else if(excludingFeature!=4 && gv.wallpaperClocksRunning){ on_deactivate_clock_clicked(); } else if(excludingFeature!=5 && gv.liveWebsiteRunning){ on_deactivate_website_clicked(); } } QString MainWindow::secondsToHms(int seconds){ int minutes_left=0, hours_left=0, finalSeconds; if(seconds>=60){ minutes_left=seconds/60; if(minutes_left>=60){ hours_left=minutes_left/60; } minutes_left=minutes_left-hours_left*60; finalSeconds=seconds-(hours_left*3600+minutes_left*60); } else{ finalSeconds=seconds; } if(!hours_left && !minutes_left){ return QString::number(finalSeconds)+"s"; } else if(!hours_left){ if(finalSeconds){ return QString::number(minutes_left)+"m " + QString::number(finalSeconds)+"s"; } else{ return QString::number(minutes_left)+"m"; } } else if(!minutes_left){ if(finalSeconds){ return QString::number(hours_left) + "h " + QString::number(finalSeconds)+"s"; } else{ return QString::number(hours_left) + "h"; } } else { if(finalSeconds){ return QString::number(hours_left) + "h " + QString::number(minutes_left)+"m " + QString::number(finalSeconds)+"s"; } else{ return QString::number(hours_left) + "h " + QString::number(minutes_left)+"m"; } } } QString MainWindow::secondsToHm(int seconds){ if(seconds<=60){ return QString("1m"); } else if(seconds<=3600){ return QString::number(seconds/60)+QString("m"); } else { int hours=seconds/3600; seconds-=hours*3600; int minutes=seconds/60; if(minutes){ return QString::number(hours)+QString("h ")+QString::number(minutes)+QString("m"); } else{ return QString::number(hours)+QString("h"); } } } QString MainWindow::secondsToMh(int seconds) { if (seconds<60){ return QString(QString::number(seconds) + " "+tr("seconds")); } else if(seconds==60){ return QString("1 "+tr("minute")); } else if(seconds<3600){ return QString(QString::number(seconds/60) + " "+tr("minutes")); } else if(seconds==3600){ return QString("1 "+tr("hour")); } else if(seconds<86400){ return QString(QString::number(seconds/3600) + " "+tr("hours")); } else if(seconds==86400){ return QString("1 "+tr("day")); } else if(seconds==604800){ return QString("1 "+tr("week")); } return QString(""); } void MainWindow::setAverageColor(const QString &image){ //sets the desktop background color, updates mainwindow's primary color box setButtonColor(Global::setAverageColor(image)); } QString MainWindow::fixBasenameSize(const QString &basename){ if(basename.length()>35){ return basename.left(32)+"..."; } return basename; } void MainWindow::tvPreview(bool show) { showTvMinimumHeight_ = new QPropertyAnimation(ui->preview_widget, "minimumHeight"); showTvMinimumHeight_->setDuration(350); showTvMinimumHeight_->setStartValue(ui->preview_widget->minimumHeight()); if(show) { ui->preview_widget->show(); ui->screen_label->clear(); ui->screen_label_text->clear(); QTimer::singleShot(400, this, SLOT(updateScreenLabel())); showTvMinimumHeight_->setEndValue(281); } else { QTimer::singleShot(430, this, SLOT(hideTv())); showTvMinimumHeight_->setEndValue(0); } showTvMinimumHeight_->start(); } void MainWindow::hideTv() { ui->preview_widget->hide(); delete showTvMinimumHeight_; } void MainWindow::updateScreenLabel() { ui->screen_label_info->clear(); ui->screen_label_text->clear(); switch(ui->stackedWidget->currentIndex()){ case 0: if(ui->listWidget->count()==0 || ui->listWidget->selectedItems().count()==0) { changeTextOfScreenLabelTo(tr("No image selected to preview")); } else{ on_listWidget_itemSelectionChanged(); } break; case 1: { QString filename=Global::getFilename(gv.wallchHomePath+"liveEarth*"); if(!filename.isEmpty()){ imageTransition(filename); } else { changeTextOfScreenLabelTo(tr("No live earth has\nbeen downloaded to preview")); } break; } case 2: { QString filename=Global::getFilename(gv.wallchHomePath+POTD_IMAGE+"*"); if(!filename.isEmpty()){ imageTransition(filename); } else { changeTextOfScreenLabelTo(tr("No picture of the day has\nbeen downloaded to preview")); } break; } case 3: if(ui->clocksTableWidget->rowCount()==0) { changeTextOfScreenLabelTo(tr("No wallpaper clock has been\ninstalled to preview")); } else if(ui->clocksTableWidget->rowCount()!=0 && ui->clocksTableWidget->selectedItems().count()==0) { changeTextOfScreenLabelTo(tr("No wallpaper clock has been\nselected to preview")); } else if(ui->clocksTableWidget->rowCount()!=0 && ui->clocksTableWidget->selectedItems().count()!=0) { imageTransition("preview_clock"); } break; case 4: if(QFile::exists(gv.wallchHomePath+LW_PREVIEW_IMAGE)){ imageTransition(gv.wallchHomePath+LW_PREVIEW_IMAGE); } else { changeTextOfScreenLabelTo(tr("No website image to preview")); } break; case 5: changeTextOfScreenLabelTo("Mellori Studio"); break; } } void MainWindow::changeTextOfScreenLabelTo(const QString &text) { if(!gv.previewImagesOnScreen){ return; } hideScreenLabel(); opacityEffect_->setOpacity(false); ui->screen_label_text->setGraphicsEffect(opacityEffect_); QPropertyAnimation* anim = new QPropertyAnimation(this); anim->setTargetObject(opacityEffect_); anim->setPropertyName("opacity"); anim->setDuration(IMAGE_TRANSITION_SPEED+50); anim->setStartValue(opacityEffect_->opacity()); anim->setEndValue(true); anim->setEasingCurve(QEasingCurve::OutQuad); anim->start(QAbstractAnimation::DeleteWhenStopped); ui->screen_label_text->setText(text); } #ifdef ON_LINUX void MainWindow::unityProgressbarSetEnabled(bool enabled){ if(gv.wallpapersRunning || gv.liveEarthRunning || gv.potdRunning || gv.wallpaperClocksRunning || gv.liveWebsiteRunning ){ Global::setUnityProgressBarEnabled(enabled); if(enabled){ Global::setUnityProgressbarValue(0); } } } void MainWindow::indicatorSetNormal(){ Global::changeIndicatorIcon("normal"); } #endif //#ifdef ON_LINUX void MainWindow::updateColorButton(QImage image) { ui->set_desktop_color->setIcon(QIcon(QPixmap::fromImage(image.scaled(40, 19, Qt::IgnoreAspectRatio, Qt::FastTransformation)))); } //Wallpapers code void MainWindow::justChangeWallpaper(){ if(!wallpapersPageLoaded_){ loadWallpapersPage(); if(ui->listWidget->count()timerSlider->setEnabled(false); ui->wallpapers_slider_time->setEnabled(false); ui->interval_label->setEnabled(false); } else { ui->timerSlider->setEnabled(true); ui->wallpapers_slider_time->setEnabled(true); ui->interval_label->setEnabled(true); } } srand(time(0)); Global::setBackground(getPathOfListItem(rand()%ui->listWidget->count()), true, true, 1); } void MainWindow::on_startButton_clicked(){ if(!wallpapersPageLoaded_){ loadWallpapersPage(); if(ui->listWidget->count()timerSlider->setEnabled(false); ui->wallpapers_slider_time->setEnabled(false); ui->interval_label->setEnabled(false); } else { ui->timerSlider->setEnabled(true); ui->wallpapers_slider_time->setEnabled(true); ui->interval_label->setEnabled(true); } } if (!ui->startButton->isEnabled()){ //this is the case it is launched from the indicator #ifdef ON_LINUX Global::changeIndicatorSelection("none"); #endif //#ifdef ON_LINUX globalParser_->desktopNotify(tr("Not enough pictures to start chaning wallpapers."), false, "info"); Global::error("Too few images for wallpaper feature to start. Make sure there are at least 2 pictures at the selected folder."); return; } closeEverythingThatsRunning(1); startPauseWallpaperChangingProcess(); } void MainWindow::startPauseWallpaperChangingProcess(){ if(!currentFolderExists()){ return; } if (actAsStart_){ actAsStart_=false; //the next time act like pause is pressed gv.wallpapersRunning=true; Global::updateStartup(); startWasJustClicked_=true; ui->startButton->setText(tr("Pau&se")); ui->startButton->setIcon(QIcon::fromTheme("media-playback-pause", QIcon(":/icons/Pictures/media-playback-pause.svg"))); shuffleWasChecked_=ui->shuffle_images_checkbox->isChecked(); if(!gv.processPaused){ if(shuffleWasChecked_){ if(firstRandomImageIsntRandom_){ firstRandomImageIsntRandom_=false; Global::generateRandomImages(ui->listWidget->count(), indexOfCurrentImage_); indexOfCurrentImage_=0; } else { Global::generateRandomImages(ui->listWidget->count(), -1); } } } if(gv.processPaused){ //If the process was paused, then we need to continue from where it is left, not from the next second secondsLeft_+=1; } Global::resetSleepProtection(secondsLeft_); if(!gv.processPaused){ //if the process wasn't paused, then the progressbar is hidden. Add an animation so as to show it animateProgressbarOpacity(1); if(gv.randomTimeEnabled) { srand(time(0)); secondsLeft_=(rand()%(gv.randomTimeTo-gv.randomTimeFrom+1))+gv.randomTimeFrom; initialRandomSeconds_=secondsLeft_; totalSeconds_=secondsLeft_; } } gv.processPaused=false; #ifdef ON_LINUX if(gv.currentDE==UnityGnome && gv.unityProgressbarEnabled){ dbusmenu_menuitem_property_set_bool(gv.unityPauseAction, DBUSMENU_MENUITEM_PROP_VISIBLE, true); Global::setUnityProgressBarEnabled(true); } Global::changeIndicatorSelection("wallpapers"); #else Q_EMIT signalRecreateTray(); #endif //#ifdef ON_LINUX startUpdateSeconds(); stopButtonsSetEnabled(true); previousAndNextButtonsSetEnabled(true); on_page_0_wallpapers_clicked(); } else { actAsStart_=true; //<- the next time act like start is pressed gv.processPaused=true; ui->startButton->setText(tr("&Start")); ui->startButton->setIcon(QIcon::fromTheme("media-playback-start", QIcon(":/icons/Pictures/media-playback-start.svg"))); #ifdef ON_LINUX Global::changeIndicatorSelection("pause"); if(gv.currentDE==UnityGnome){ dbusmenu_menuitem_property_set_bool(gv.unityPauseAction, DBUSMENU_MENUITEM_PROP_VISIBLE, false); } #else Q_EMIT signalRecreateTray(); #endif //#ifdef ON_LINUX updateSecondsTimer_->stop(); timeForNext_->setFormat(timeForNext_->format()+" - Paused."); previousAndNextButtonsSetEnabled(false); if(ui->listWidget->count() != 0){ ui->shuffle_images_checkbox->setEnabled(true); } if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(secondsLeft_, 0); } } } void MainWindow::on_stopButton_clicked(){ if (!ui->stopButton->isEnabled()){ return; } if(ui->listWidget->count()!=0){ ui->shuffle_images_checkbox->setEnabled(true); } actAsStart_=true; ui->startButton->setText(tr("&Start")); ui->startButton->setIcon(QIcon::fromTheme("media-playback-start", QIcon(":/icons/Pictures/media-playback-start.svg"))); animateProgressbarOpacity(0); gv.processPaused=false; firstRandomImageIsntRandom_=false; indexOfCurrentImage_=0; secondsLeft_=0; if(updateSecondsTimer_->isActive()){ updateSecondsTimer_->stop(); } previousAndNextButtonsSetEnabled(false); if(ui->listWidget->count() < LEAST_WALLPAPERS_FOR_START){ startButtonsSetEnabled(false); } else { startButtonsSetEnabled(true); } stopButtonsSetEnabled(false); gv.wallpapersRunning=false; Global::updateStartup(); #ifdef ON_LINUX Global::changeIndicatorSelection("none"); if(gv.currentDE==UnityGnome && gv.unityLauncherEntry){ dbusmenu_menuitem_property_set_bool(gv.unityPauseAction, DBUSMENU_MENUITEM_PROP_VISIBLE, false); } if(gv.currentDE==UnityGnome && gv.unityProgressbarEnabled){ Global::setUnityProgressBarEnabled(false); } #else Q_EMIT signalRecreateTray(); #endif //#ifdef ON_LINUX if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(-1, 0); } } void MainWindow::on_next_Button_clicked() { if (!ui->next_Button->isEnabled() || !currentFolderExists()){ return; } updateSecondsTimer_->stop(); #ifdef ON_LINUX Global::changeIndicatorIcon("right"); indicatorChangeNormalTimer_->start(INDICATOR_SCROLL_INTERVAL); #endif secondsLeft_=0; startUpdateSeconds(); } void MainWindow::on_previous_Button_clicked() { if(!ui->previous_Button->isEnabled() || !currentFolderExists()){ return; } updateSecondsTimer_->stop(); QString image; if(ui->shuffle_images_checkbox->isChecked()){ if(previousBackgrounds_.count()>1){ image=previousBackgrounds_.at(previousBackgrounds_.count()-2); if(QImage(image).isNull()){ return; } previousBackgrounds_.removeLast(); } else { image=getPathOfListItem(gv.randomImages[gv.currentRandomImageIndex]); if(QImage(image).isNull()){ return; } int listCount=ui->listWidget->count(); if(gv.currentRandomImageIndex>=(listCount-1)){ Global::generateRandomImages(listCount, -1); } else { gv.currentRandomImageIndex++; } } Global::setBackground(image, true, true, 1); if(gv.rotateImages && gv.iconMode){ forceUpdateIconOf(gv.randomImages[gv.currentRandomImageIndex]); } } else { if(indexOfCurrentImage_==1){ indexOfCurrentImage_=ui->listWidget->count()+1; } image=getPathOfListItem(indexOfCurrentImage_-2); if(QImage(image).isNull()){ return; } Global::setBackground(image, true, true, 1); if(gv.rotateImages && gv.iconMode){ forceUpdateIconOf(indexOfCurrentImage_-2); } indexOfCurrentImage_--; } if(gv.randomTimeEnabled){ srand(time(0)); secondsLeft_=(rand()%(gv.randomTimeTo-gv.randomTimeFrom+1))+gv.randomTimeFrom; initialRandomSeconds_=secondsLeft_; } else { findSeconds(true); } #ifdef ON_LINUX Global::changeIndicatorIcon("left"); indicatorChangeNormalTimer_->start(INDICATOR_SCROLL_INTERVAL); #endif Global::resetSleepProtection(secondsLeft_); startUpdateSeconds(); } bool MainWindow::currentFolderExists() { if(QDir(currentFolder_).exists()){ return true; } else { int index=ui->pictures_location_comboBox->currentIndex(); ui->pictures_location_comboBox->setItemText(index, Global::basenameOf(currentFolder_)+" (0)" ); ui->listWidget->clear(); if(gv.wallpapersRunning){ on_stopButton_clicked(); } if(QMessageBox::question(this, tr("Location is not available"), currentFolder_+" "+tr("referes to a location that is unavailable.")+" "+ tr("It could be on a hard drive on this computer so check if that disk is properly inserted, or it could be on a network so check if you are connected to the Internet or your network, and then try again. Delete this folder from the list?"))==QMessageBox::Yes) { ui->pictures_location_comboBox->setCurrentIndex(0); ui->pictures_location_comboBox->removeItem(index); updatePicturesLocations(); } else { ui->pictures_location_comboBox->setCurrentIndex(0); } return false; } } void MainWindow::on_listWidget_itemSelectionChanged() { if(!gv.mainwindowLoaded || !gv.previewImagesOnScreen){ return; } if(ui->listWidget->selectedItems().count()==1){ QString filename=getPathOfListItem(); if(!processingOnlineRequest_){ ui->screen_label_info->setText(fixBasenameSize(Global::basenameOf(filename))); } imageTransition(filename); } } void MainWindow::on_listWidget_itemDoubleClicked() { if(!ui->listWidget->count()){ return; } int curRow=ui->listWidget->currentRow(); if(curRow<0){ return; } QString pic = getPathOfListItem(curRow); if(!QFile::exists(pic) || QImage(pic).isNull()){ return; } Global::addPreviousBackground(previousBackgrounds_, pic); Global::setBackground(pic, true, true, 1); if(gv.rotateImages && gv.iconMode){ forceUpdateIconOf(curRow); } if(gv.currentDE==LXDE){ DesktopStyle desktopStyle=getDesktopStyle(); if(desktopStyle==NoneStyle){ ui->image_style_combo->setCurrentIndex(2); } } } void MainWindow::startWithThisImage(){ closeEverythingThatsRunning(0); indexOfCurrentImage_=ui->listWidget->currentRow(); if(ui->shuffle_images_checkbox->isChecked()){ firstRandomImageIsntRandom_=true; } on_startButton_clicked(); } void MainWindow::removeImageFromDisk(){ if (QMessageBox::question(this, tr("Confirm deletion"), tr("Are you sure you want to permanently delete the selected image?")) == QMessageBox::Yes) { QString image_filename = getPathOfListItem(ui->listWidget->currentRow()); if(!QFile::remove(image_filename)){ QMessageBox::warning(this, tr("Error!"), tr("Image deletion failed possibly because you don't have the permissions to delete the image or the image doesn't exist")); } else { //remove the cache of the image, in case it exists QString cache_filename=gv.cachePath+Global::originalToCacheName(image_filename); qint64 cache_file_size=QFile(cache_filename).size(); if(QFile::remove(cache_filename)){ //file successfully removed, remove the size of it from the current cache size! Global::addToCacheSize(cache_file_size*-1); } } } else { return; } if(ui->listWidget->count()<=1){ startButtonsSetEnabled(false); } } void MainWindow::removeImagesFromDisk(){ int selectedCount=ui->listWidget->selectedItems().count(); if(QMessageBox::question(this, tr("Warning!"), tr("Image deletion.")+"

"+tr("This action is going to permanently delete")+" "+QString::number(selectedCount)+" "+tr("images. Are you sure?"))==QMessageBox::Yes){ QStringList imagesThatFailedToDelete; for(int i=0;ilistWidget->selectedItems().at(i)->statusTip().isEmpty()){ curImage = ui->listWidget->selectedItems().at(i)->toolTip(); } else { curImage = ui->listWidget->selectedItems().at(i)->statusTip(); } } else { curImage = ui->listWidget->selectedItems().at(i)->text(); } if(!QFile::remove(curImage)){ imagesThatFailedToDelete << curImage; } else { //remove the cache of the image, in case it exists QString cacheFilename=gv.cachePath+Global::originalToCacheName(curImage); qint64 cacheFileSize=QFile(cacheFilename).size(); if(QFile::remove(cacheFilename)){ //file successfully removed, remove the size of it from the current cache size! Global::addToCacheSize(cacheFileSize*-1); } } } if(imagesThatFailedToDelete.count()>0){ QString all_images = "\n"+imagesThatFailedToDelete.join("\n"); QMessageBox::warning(this, tr("Error!"), tr("There was a problem with the deletion of the following files:")+all_images); } } } void MainWindow::rotateRight(){ if(!ui->listWidget->currentItem()->isSelected()){ return; } QString path = getPathOfListItem(); if(!QFile::exists(path) || QImage(path).isNull()){ return; } Global::rotateImg(path, 6, false); if(gv.iconMode){ forceUpdateIconOf(ui->listWidget->currentRow()); } else if(gv.previewImagesOnScreen){ updateScreenLabel(); } if(path==Global::currentBackgroundImage()){ Global::setBackground(path, false, false, 1); } } void MainWindow::rotateLeft(){ if(!ui->listWidget->currentItem()->isSelected()){ return; } QString path = getPathOfListItem(); if(!QFile::exists(path) || QImage(path).isNull()){ return; } Global::rotateImg(path, 8, false); if(gv.iconMode){ forceUpdateIconOf(ui->listWidget->currentRow()); } else if(gv.previewImagesOnScreen){ updateScreenLabel(); } if(path==Global::currentBackgroundImage()){ Global::setBackground(path, false, false, 1); } } void MainWindow::copyImagePath(){ QApplication::clipboard()->setText(getPathOfListItem()); } void MainWindow::copyImage(){ QApplication::clipboard()->setImage(QImage(getPathOfListItem()), QClipboard::Clipboard); } QString MainWindow::getPathOfListItem(int index /* = -1*/){ /* * Returns the full path of the listwidget item at 'index' * Returns the full path of the current item's path if index==-1 */ if(index==-1){ index=ui->listWidget->currentRow(); } if(gv.iconMode){ if(ui->listWidget->item(index)->statusTip().isEmpty()){ return ui->listWidget->item(index)->toolTip(); } else { return ui->listWidget->item(index)->statusTip(); } } else { return ui->listWidget->item(index)->text(); } } void MainWindow::on_listWidget_customContextMenuRequested() { if(!currentFolderExists()) return; int selectedCount = ui->listWidget->selectedItems().count(); if(selectedCount==0){ return; } if (selectedCount<2){ listwidgetMenu_ = new QMenu(this); listwidgetMenu_->addAction(tr("Set this item as Background"), this, SLOT(on_listWidget_itemDoubleClicked())); if(ui->listWidget->count()>2){ listwidgetMenu_->addAction(tr("Start from this image"), this, SLOT(startWithThisImage())); } listwidgetMenu_->addAction(tr("Delete image from disk"), this, SLOT(removeImageFromDisk())); listwidgetMenu_->addAction(tr("Rotate Right"), this, SLOT(rotateRight())); listwidgetMenu_->addAction(tr("Rotate Left"), this, SLOT(rotateLeft())); listwidgetMenu_->addAction(tr("Copy path to clipboard"), this, SLOT(copyImagePath())); listwidgetMenu_->addAction(tr("Copy image to clipboard"), this, SLOT(copyImage())); listwidgetMenu_->addAction(tr("Open folder"), this, SLOT(openImageFolder())); listwidgetMenu_->addAction(tr("Find an image by name"), this, SLOT(showHideSearchBoxMenu())); listwidgetMenu_->addAction(tr("Properties"), this, SLOT(showProperties())); listwidgetMenu_->popup(MENU_POPUP_POS); } else { //more than one file has been selected, show shorter menu with massive options listwidgetMenu_ = new QMenu(this); listwidgetMenu_->addAction(tr("Open containing folder of all images"), this, SLOT(openImageFolderMassive())); listwidgetMenu_->addAction(tr("Delete images from disk"), this, SLOT(removeImagesFromDisk())); listwidgetMenu_->popup(MENU_POPUP_POS); } } void MainWindow::addFolderForMonitor(const QString &folder){ if(QDir(folder).exists()){ short count = ui->pictures_location_comboBox->count(); for(short i=0; ipictures_location_comboBox->itemData(i).toString())) { ui->pictures_location_comboBox->setCurrentIndex(i); return; } } ui->pictures_location_comboBox->addItem(Global::basenameOf(folder)); ui->pictures_location_comboBox->setItemData(count, folder); ui->pictures_location_comboBox->setCurrentIndex(count); updatePicturesLocations(); } } void MainWindow::changeImage(){ //this function handles the change of the image of the wallpapers page. QString image; if(shuffleWasChecked_!=ui->shuffle_images_checkbox->isChecked()){ shuffleWasChecked_=ui->shuffle_images_checkbox->isChecked(); //the suffle has changed state! if(shuffleWasChecked_){ Global::generateRandomImages(ui->listWidget->count(), -1); } else { processRunningResetPictures(true); } } if(shuffleWasChecked_){ int listCount = ui->listWidget->count(); if(gv.currentRandomImageIndex>=gv.randomImages.count()){ Global::generateRandomImages(listCount, -1); } image=getPathOfListItem(gv.randomImages[gv.currentRandomImageIndex]); if(!QImage(image).isNull()){ Global::addPreviousBackground(previousBackgrounds_, image); Global::setBackground(image, true, true, 1); if(gv.rotateImages && gv.iconMode){ forceUpdateIconOf(gv.randomImages[gv.currentRandomImageIndex]); } } if(gv.currentRandomImageIndex>=(listCount-1)){ Global::generateRandomImages(listCount, -1); //the loop has ended... } else { gv.currentRandomImageIndex++; } } else { if(indexOfCurrentImage_>=ui->listWidget->count() || indexOfCurrentImage_<0){ indexOfCurrentImage_=0; } image=getPathOfListItem(indexOfCurrentImage_); if(!QImage(image).isNull()){ Global::setBackground(image, true, true, 1); if(gv.rotateImages && gv.iconMode){ forceUpdateIconOf(indexOfCurrentImage_); } } indexOfCurrentImage_++; } } void MainWindow::searchFor(const QString &term){ ui->listWidget->clearSelection(); searchList_.clear(); int listCount=ui->listWidget->count(); if(gv.iconMode){ for(int i=0;ilistWidget->item(i)->statusTip().isEmpty()){ searchList_ << Global::basenameOf(ui->listWidget->item(i)->toolTip()); } else { searchList_ << Global::basenameOf(ui->listWidget->item(i)->statusTip()); } } } else { for(int i=0; ilistWidget->item(i)->text()); } } match_->setPattern("*"+term+"*"); currentSearchItemIndex = searchList_.indexOf(*match_, 0); if(currentSearchItemIndex < 0){ doesntMatch(); } else { ui->listWidget->scrollToItem(ui->listWidget->item(currentSearchItemIndex)); ui->listWidget->setCurrentItem(ui->listWidget->item(currentSearchItemIndex)); ui->listWidget->item(currentSearchItemIndex)->setSelected(true); doesMatch(); } } void MainWindow::continueToNextMatch(){ ui->listWidget->clearSelection(); if(currentSearchItemIndex >= ui->listWidget->count()+1){ //restart the search... currentSearchItemIndex=searchList_.indexOf(*match_, 0); if(currentSearchItemIndex<0){ return; } ui->listWidget->scrollToItem(ui->listWidget->item(currentSearchItemIndex)); ui->listWidget->setCurrentItem(ui->listWidget->item(currentSearchItemIndex)); } else { //continue the search.. currentSearchItemIndex = searchList_.indexOf(*match_, currentSearchItemIndex+1); if(currentSearchItemIndex<0){ //restart the search... currentSearchItemIndex=searchList_.indexOf(*match_, 0); if(currentSearchItemIndex<0){ return; } } ui->listWidget->scrollToItem(ui->listWidget->item(currentSearchItemIndex)); ui->listWidget->setCurrentItem(ui->listWidget->item(currentSearchItemIndex)); ui->listWidget->item(currentSearchItemIndex)->setSelected(true); } } void MainWindow::continueToPreviousMatch(){ ui->listWidget->clearSelection(); if(currentSearchItemIndex < 0){ //restart the search... currentSearchItemIndex=searchList_.lastIndexOf(*match_, searchList_.count()-1); if(currentSearchItemIndex<0){ return; } ui->listWidget->scrollToItem(ui->listWidget->item(currentSearchItemIndex)); ui->listWidget->setCurrentItem(ui->listWidget->item(currentSearchItemIndex)); } else { //continue the search.. currentSearchItemIndex = searchList_.lastIndexOf(*match_, currentSearchItemIndex-1); if(currentSearchItemIndex < 0){ //restart the search... currentSearchItemIndex=searchList_.lastIndexOf(*match_, searchList_.count()-1); if(currentSearchItemIndex<0){ return; } } ui->listWidget->scrollToItem(ui->listWidget->item(currentSearchItemIndex)); ui->listWidget->setCurrentItem(ui->listWidget->item(currentSearchItemIndex)); ui->listWidget->item(currentSearchItemIndex)->setSelected(true); } } void MainWindow::openImageFolder(){ if(!ui->listWidget->currentItem()->isSelected()){ return; } Global::openFolderOf(getPathOfListItem()); } void MainWindow::openImageFolderMassive(){ QStringList parent_folders; int selected_count=ui->listWidget->selectedItems().count(); short total_folders_count=0; for(int i=0;ilistWidget->selectedItems().at(i)->statusTip().isEmpty()){ currentImage = ui->listWidget->selectedItems().at(i)->toolTip(); } else{ currentImage = ui->listWidget->selectedItems().at(i)->statusTip(); } } else{ currentImage = ui->listWidget->selectedItems().at(i)->text(); } QString image_folder = Global::dirnameOf(currentImage); if(!parent_folders.contains(image_folder)){ parent_folders << image_folder; total_folders_count++; } } if(total_folders_count>5){ if(QMessageBox::question(this, tr("Warning!"), tr("Too many folders to open.")+"

"+tr("This action is going to open")+" "+QString::number(total_folders_count)+" "+tr("folders. Are you sure?"))!=QMessageBox::Yes){ return; } } for(short i=0;istart(3000); } ui->wallpapers_slider_time->setText(customIntervals_.at(value-1)); settings->setValue("delay", secondsInWallpapersSlider_); settings->setValue( "timeSlider", ui->timerSlider->value()); } void MainWindow::updateTiming(){ if(updateCheckTime_->isActive()){ updateCheckTime_->stop(); } if(!wallpapersPageLoaded_){ return; } settings->setValue( "timeSlider", ui->timerSlider->value()); settings->setValue( "delay", secondsInWallpapersSlider_ ); settings->sync(); } void MainWindow::startButtonsSetEnabled(bool enabled) { ui->startButton->setEnabled(enabled); #ifdef ON_LINUX if(gv.currentDE==UnityGnome && gv.unityLauncherEntry){ dbusmenu_menuitem_property_set_bool(gv.unityPauseAction, DBUSMENU_MENUITEM_PROP_VISIBLE, !enabled); } #endif //#ifdef ON_LINUX } void MainWindow::stopButtonsSetEnabled(bool enabled) { ui->stopButton->setEnabled(enabled); #ifdef ON_LINUX if(gv.currentDE==UnityGnome && gv.unityLauncherEntry){ dbusmenu_menuitem_property_set_bool(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_VISIBLE, enabled); dbusmenu_menuitem_property_set_bool(gv.unityPauseAction, DBUSMENU_MENUITEM_PROP_VISIBLE, enabled); } #endif //#ifdef ON_LINUX } void MainWindow::previousAndNextButtonsSetEnabled(bool enabled){ ui->next_Button->setEnabled(enabled); ui->previous_Button->setEnabled(enabled); #ifdef ON_LINUX if(gv.currentDE==UnityGnome && gv.unityLauncherEntry){ dbusmenu_menuitem_property_set_bool(gv.unityNextAction, DBUSMENU_MENUITEM_PROP_VISIBLE, enabled); dbusmenu_menuitem_property_set_bool(gv.unityPreviousAction, DBUSMENU_MENUITEM_PROP_VISIBLE, enabled); } #endif //#ifdef ON_LINUX } void MainWindow::random_time_changed(short index) { if(index) { ui->timerSlider->setEnabled(false); ui->wallpapers_slider_time->setEnabled(false); ui->interval_label->setEnabled(false); } else { ui->timerSlider->setEnabled(true); ui->wallpapers_slider_time->setEnabled(true); ui->interval_label->setEnabled(true); } } void MainWindow::monitor(const QStringList &paths){ /* * Monitor outside * For the people inside * A prevention of crime * A passing of time * * A monitor outside * A monitor outside * * They come and they go * It's a passing of time * They come and they go * Whilst we sit in our homes * * Sit back, sit back, sit back * Sit back and enjoy * * Monitor - Siouxsie and the Banshees */ int itemCount=0; Q_FOREACH(QString path, paths){ monitor(path, itemCount); } if(gv.iconMode){ launchTimerToUpdateIcons(); } switch(ui->pictures_location_comboBox->currentIndex()){ case 0: ui->pictures_location_comboBox->setItemText(0, gv.currentOSName+" "+tr("Desktop Backgrounds")+" ("+QString::number(itemCount)+")"); break; case 1: ui->pictures_location_comboBox->setItemText(1,tr("My Pictures")+" ("+QString::number(itemCount)+ ")"); break; default: ui->pictures_location_comboBox->setItemText(ui->pictures_location_comboBox->currentIndex(), Global::basenameOf(currentFolder_)+" ("+QString::number(itemCount)+ ")"); break; } } void MainWindow::monitor(const QString &path, int &itemCount) { if(monitoredFoldersList_.contains(path, Qt::CaseSensitive)){ return; } watchFolders_->addPath(path); monitoredFoldersList_ << path; addFilesToWallpapers(path, itemCount); if(ui->listWidget->count() < LEAST_WALLPAPERS_FOR_START){ startButtonsSetEnabled(false); } else { startButtonsSetEnabled(true); } } void MainWindow::folderChanged() { /* * This function just launches the research_folders_timer. * This is done in order to prevent researching the folders constantly, when multiple changes * are being made in a very short period of time. */ if(researchFoldersTimer_->isActive()){ researchFoldersTimer_->stop(); } researchFoldersTimer_->start(RESEARCH_FOLDERS_TIMEOUT); } void MainWindow::researchFolders() { researchFoldersTimer_->stop(); if(gv.previewImagesOnScreen){ //keep the current selected file (it will be selected again after the folder researching has finished) if(ui->listWidget->selectedItems().count()){ if(gv.iconMode){ if(ui->listWidget->selectedItems().at(0)->statusTip().isEmpty()){ nameOfSelectionPriorFolderChange_=ui->listWidget->selectedItems().at(0)->toolTip(); } else { nameOfSelectionPriorFolderChange_=ui->listWidget->selectedItems().at(0)->statusTip(); } } else { nameOfSelectionPriorFolderChange_=ui->listWidget->selectedItems().at(0)->text(); } } } if(searchIsOn_){ on_search_close_clicked(); } ui->search_box->clear(); ui->listWidget->clear(); monitoredFoldersList_.clear(); resetWatchFolders(); monitor(Global::listFolders(currentFolder_, true, true)); if(ui->listWidget->count() < LEAST_WALLPAPERS_FOR_START){ if(gv.wallpapersRunning){ on_stopButton_clicked(); } } else { startButtonsSetEnabled(true); } if(gv.wallpapersRunning){ processRunningResetPictures(false); } if(gv.previewImagesOnScreen && ui->stackedWidget->currentIndex()==0){ searchFor(nameOfSelectionPriorFolderChange_); ui->screen_label_info->clear(); updateScreenLabel(); } } void MainWindow::addFilesToWallpapers(const QString &path, int &itemCount){ QDir currrentDirectory(path, QString(""), QDir::Name, QDir::Files); if(gv.iconMode){ Q_FOREACH(QString file, currrentDirectory.entryList(IMAGE_FILTERS)){ QListWidgetItem *item = new QListWidgetItem; item->setIcon(imageLoading_); item->setSizeHint(WALLPAPERS_LIST_ICON_SIZE+WALLPAPERS_LIST_ITEMS_OFFSET); item->setToolTip(path+"/"+file); ui->listWidget->addItem(item); itemCount++; } } else { QString temp; Q_FOREACH(QString file, currrentDirectory.entryList(IMAGE_FILTERS)){ temp=path+"/"+file; QListWidgetItem *item = new QListWidgetItem; item->setText(temp); item->setToolTip(tr("Right-click for options")); item->setStatusTip(temp); ui->listWidget->addItem(item); itemCount++; } } } void MainWindow::changePathsToIcons() { ui->listWidget->setIconSize(WALLPAPERS_LIST_ICON_SIZE); ui->listWidget->setViewMode(QListView::IconMode); ui->listWidget->setUniformItemSizes(true); ui->listWidget->setDragEnabled(false); gv.iconMode=true; int listCount=ui->listWidget->count(); for(int i=0;ilistWidget->item(i)->statusTip(); ui->listWidget->item(i)->setToolTip(status); ui->listWidget->item(i)->setStatusTip(""); ui->listWidget->item(i)->setText(""); ui->listWidget->item(i)->setSizeHint(WALLPAPERS_LIST_ICON_SIZE+WALLPAPERS_LIST_ITEMS_OFFSET); ui->listWidget->item(i)->setIcon(imageLoading_); } launchTimerToUpdateIcons(); if(gv.previewImagesOnScreen && ui->stackedWidget->currentIndex()==0){ hideScreenLabel(); updateScreenLabel(); } if(searchIsOn_){ on_search_close_clicked(); } ui->search_box->clear(); } void MainWindow::changeIconsToPaths(){ ui->listWidget->setViewMode(QListView::ListMode); ui->listWidget->setUniformItemSizes(false); ui->listWidget->setIconSize(QSize(-1, -1)); gv.iconMode=false; int file_count=ui->listWidget->count(); QFont font; font.defaultFamily(); for(int i=0;ilistWidget->item(i)->setTextAlignment(Qt::AlignLeft); ui->listWidget->item(i)->setFont(font); if(!ui->listWidget->item(i)->statusTip().isEmpty()){ ui->listWidget->item(i)->setText(ui->listWidget->item(i)->statusTip()); } else { QString path=ui->listWidget->item(i)->toolTip(); ui->listWidget->item(i)->setText(path); ui->listWidget->item(i)->setStatusTip(path); ui->listWidget->item(i)->setToolTip(tr("Right-click for options")); } ui->listWidget->item(i)->setIcon(QIcon("")); ui->listWidget->item(i)->setData(Qt::SizeHintRole, QVariant()); } if(gv.previewImagesOnScreen && ui->stackedWidget->currentIndex()==0){ hideScreenLabel(); updateScreenLabel(); } if(searchIsOn_){ on_search_close_clicked(); } ui->search_box->clear(); } void MainWindow::launchTimerToUpdateIcons(){ if(gv.iconMode){ if(iconUpdater_->isActive()){ iconUpdater_->stop(); } currentlyUpdatingIcons_=false; iconUpdater_->start(300); } } void MainWindow::updateVisibleIcons(){ if(!ui->listWidget->count()){ return; } currentlyUpdatingIcons_=true; QListWidgetItem* minItem=ui->listWidget->itemAt(0, 0); QListWidgetItem* maxItem=ui->listWidget->itemAt(ui->listWidget->width()-30, ui->listWidget->height()-5); int diff=30; while(!maxItem){ diff+=5; maxItem=ui->listWidget->itemAt(ui->listWidget->width()-diff, ui->listWidget->height()-5); if(ui->listWidget->width()-diff<0){ maxItem=ui->listWidget->item(ui->listWidget->count()-1); } } int min_row=ui->listWidget->row(minItem); int max_row=ui->listWidget->row(maxItem); for (int row = min_row; row <= max_row; row++) { if(!currentlyUpdatingIcons_ || appAboutToClose_){ //either a new timer has been launched for this function or the application is about to close. return; } if(!ui->listWidget->item(row)){ continue; //<- in case the icons are loading and the user chooses to clear the list or the item has somehow been removed } if(ui->listWidget->item(row)->statusTip().isEmpty()){ if(updateIconOf(row)==false){ //some image was null, go for the next row (which now is row--) row--; } } } } bool MainWindow::updateIconOf(int index){ //updates the icon of the given row (item). It only works in icon mode, of course. QString originalImagePath=ui->listWidget->item(index)->toolTip(); QString cachedImagePath=Global::originalToCacheName(originalImagePath); bool haveToCache=true; QString imagePath; if(QFile(gv.cachePath+cachedImagePath).exists()) { imagePath=gv.cachePath+cachedImagePath; haveToCache=false; } else { imagePath=originalImagePath; } QImageReader imageReader(imagePath); if(!imageReader.canRead()){ if(ui->listWidget->count()>1){ QString currentPath; if(ui->listWidget->item(index)->toolTip().isEmpty()){ currentPath=ui->listWidget->item(index)->statusTip(); } else{ currentPath=ui->listWidget->item(index)->toolTip(); } delete ui->listWidget->item(index); } else{ ui->listWidget->clear(); } return false; } else { QImage img; if(haveToCache){ /* * The reason that here a check for the dimensions of the image is not being done * (so as not to cache it if it is already too small) is because of this bug: * https://bugreports.qt-project.org/browse/QTBUG-24831 * I could create a very small symlink to the target of the image but QFile::size * does not return the size of the symlink but the size of the actual file and * this creates problems with managing the size of the cache. Also, saving images * slightly smaller than CACHED_IMAGES_SIZE as resized (to CACHED_IMAGES_SIZE) * resulted in smaller images than the originals(!). Finally, in Preferences it * is clearly stated how many images (on average) there are per cache MiB (CACHE_IMAGES_PER_MiB), * so even if I could get the symlink's size then CACHE_IMAGES_PER_MiB would be wrong * (in favor of the user, but still wrong). */ imageReader.setScaledSize(QSize(CACHED_IMAGES_SIZE)); img=imageReader.read(); if(img.save(gv.cachePath+cachedImagePath)){ cacheSizeChanged(gv.cachePath+cachedImagePath); } } else { img.load(imagePath); } ui->listWidget->item(index)->setIcon(QIcon(QPixmap::fromImage(img))); ui->listWidget->item(index)->setStatusTip(originalImagePath); ui->listWidget->item(index)->setToolTip(tr("Right-click for options")); qApp->processEvents(QEventLoop::AllEvents); return true; } } void MainWindow::forceUpdateIconOf(int index){ if(ui->listWidget->item(index)->statusTip().isEmpty()){ //image icon has not been updated, anyway (it wasn't any time visible to the user), just delete it if it is cached QString cache_name = gv.cachePath+Global::originalToCacheName(ui->listWidget->item(index)->toolTip()); if(QFile(cache_name).exists()){ QFile::remove(cache_name); } return; } //update the image and save the cache of it QString original_name=ui->listWidget->item(index)->statusTip(); QImage img(original_name); img=img.scaled(CACHED_IMAGES_SIZE, Qt::IgnoreAspectRatio, Qt::FastTransformation); QString cache_full_path=gv.cachePath+Global::originalToCacheName(original_name); if(img.save(cache_full_path)){ cacheSizeChanged(cache_full_path); } ui->listWidget->item(index)->setIcon(QIcon(QPixmap::fromImage(img))); if(gv.previewImagesOnScreen && ui->listWidget->currentRow()==index && ui->stackedWidget->currentIndex()==0){ updateScreenLabel(); } } void MainWindow::fixCacheSizeThreaded(){ QtConcurrent::run(this, &MainWindow::fixCacheSizeGlobalCallback); } void MainWindow::fixCacheSizeGlobalCallback(){ Global(false).fixCacheSize(currentFolder_); } void MainWindow::cacheSizeChanged(const QString &newCacheImage){ if(Global::addToCacheSize(QFile(newCacheImage).size())){ if(cacheSizeChecker_->isActive()){ cacheSizeChecker_->stop(); cacheSizeChecker_->start(CHECK_CACHE_SIZE_TIMEOUT); } cacheSizeChecker_->start(CHECK_CACHE_SIZE_TIMEOUT); } } void MainWindow::on_browse_folders_clicked() { addDialogShown_=true; QString initial_folder=settings->value("last_opened_folder", "").toString(); if(!QDir(initial_folder).exists() || initial_folder.isEmpty()){ initial_folder=gv.homePath+"/"+gv.defaultPicturesLocation; if(!QDir(initial_folder).exists()){ initial_folder=gv.homePath; } } QString folder = QFileDialog::getExistingDirectory(this, tr("Choose Folder"), initial_folder); addDialogShown_=false; if(folder.isEmpty()){ return; } settings->setValue("last_opened_folder", folder); settings->sync(); addFolderForMonitor(folder); } void MainWindow::enterPressed(){ if(ui->search_box->hasFocus()){ if(ui->search_box->text().isEmpty()){ return; } continueToNextMatch(); } else if(ui->stackedWidget->currentIndex()==0){ on_listWidget_itemDoubleClicked(); } } void MainWindow::delayed_pictures_location_change() { ui->pictures_location_comboBox->setCurrentIndex(tempForDelayedPicturesLocationChange_); } void MainWindow::on_pictures_location_comboBox_currentIndexChanged(int index) { if(searchIsOn_){ on_search_close_clicked(); } ui->search_box->clear(); if(!monitoredFoldersList_.isEmpty()) { monitoredFoldersList_.clear(); resetWatchFolders(); ui->listWidget->clear(); } currentFolder_=ui->pictures_location_comboBox->itemData(index).toString(); if(QDir(currentFolder_).exists()) { monitor(Global::listFolders(currentFolder_, true, true)); if ( ui->listWidget->count() < LEAST_WALLPAPERS_FOR_START ){ startButtonsSetEnabled(false); } else{ startButtonsSetEnabled(true); } settings->setValue("currentFolder_index", ui->pictures_location_comboBox->currentIndex()); settings->sync(); if(ui->listWidget->count()){ ui->listWidget->setCurrentRow(0); } if(gv.wallpapersRunning){ processRunningResetPictures(false); } } else { startButtonsSetEnabled(false); if(gv.wallpapersRunning){ on_stopButton_clicked(); } if(gv.mainwindowLoaded) { if(index==0){ QMessageBox::warning(this, tr("Load system's pictures folder"), tr("We couldn't find your Pictures folder.")); } else if(index==1){ QMessageBox::warning(this, tr("Load system's pictures folder"), tr("We couldn't find your Pictures folder.")); } else{ currentFolderExists(); } } } } void MainWindow::processRunningResetPictures(bool fromRandomImagesToNormal){ /* * This function handles the case when the parent folder for the wallpapers is changed * or when the shuffle_images_checkbox is checked/unchecked whilw the wallpaper changing process * is running normally. If the shuffle_images_checkbox is checked it will generate random images * but if it is not then it has to know if it had to do with the folder changing or with the * unchecking of shuffle_images_checkbox */ int listCount = ui->listWidget->count(); if(fromRandomImagesToNormal){ //go to the next image of the previous random image if(gv.currentRandomImageIndex==0){ gv.currentRandomImageIndex=gv.randomImages.count()-1; } else{ gv.currentRandomImageIndex--; } if(gv.randomImages[gv.currentRandomImageIndex]==(gv.randomImages.count()-1)){ //the previous random image was at the end of the list, the new has to be at the beginning indexOfCurrentImage_=0; } else { indexOfCurrentImage_=gv.randomImages[gv.currentRandomImageIndex]+1; } } else { //folder has changed/updated if(ui->shuffle_images_checkbox->isChecked()){ if(listCount=LEAST_WALLPAPERS_FOR_START) { indexOfCurrentImage_=0; //start from the beginning of the new folder secondsLeft_=0; } else{ on_stopButton_clicked();//not enough pictures to continue } } } void MainWindow::updatePicturesLocations() { // Updates the configuration of the pictures_locations settings->beginWriteArray("pictures_locations"); settings->remove(""); short count = ui->pictures_location_comboBox->count(); for (short i = 0; i < count; ++i) { settings->setArrayIndex(i); settings->setValue("item", ui->pictures_location_comboBox->itemData(i)); } settings->endArray(); settings->sync(); } void MainWindow::on_search_box_textChanged(const QString &arg1) { if(!arg1.isEmpty()){ searchFor(arg1); } } void MainWindow::on_search_up_clicked() { if(ui->search_box->text().isEmpty()){ return; } ui->search_box->setFocus(); continueToPreviousMatch(); } void MainWindow::on_search_down_clicked() { ui->search_box->setFocus(); enterPressed(); } void MainWindow::doesntMatch(){ QPalette pal; pal.setColor(QPalette::Text, Qt::red); ui->search_box->setPalette(pal); } void MainWindow::doesMatch(){ QPalette pal; pal.setColor(QPalette::Text, Qt::black); ui->search_box->setPalette(pal); } void MainWindow::showHideSearchBoxMenu(){ if(searchIsOn_){ ui->search_box->setFocus(); return; } showHideSearchBox(); } void MainWindow::showHideSearchBox(){ if(!ui->stackedWidget->currentIndex()==0){ return; } openCloseSearch_->setStartValue(ui->search_widget->maximumHeight()); if(!searchIsOn_) { ui->search_widget->show(); openCloseSearch_->setEndValue(30); ui->search_box->setFocus(); on_search_box_textChanged(ui->search_box->text()); //in case a previous search exists } else { searchList_.clear(); openCloseSearch_->setEndValue(0); } openCloseSearch_->start(); searchIsOn_=!searchIsOn_; } void MainWindow::openCloseSearchAnimationFinished() { if(openCloseSearch_->endValue()==0){ ui->search_widget->hide(); } } void MainWindow::on_search_close_clicked() { if(ui->stackedWidget->currentIndex()!=0){ return; } showHideSearchBox(); } void MainWindow::refreshIntervals() { customIntervals_.clear(); gv.customIntervalsInSeconds.clear(); short size=settings->beginReadArray("custom_intervals_in_seconds"); settings->endArray(); if(size==0) { gv.customIntervalsInSeconds=DEFAULT_INTERVALS_IN_SECONDS; customIntervals_ = gv.defaultIntervals; settings->beginWriteArray("custom_intervals_in_seconds"); for (short i = 0; i < 17; ++i) { settings->setArrayIndex(i); settings->setValue("item", gv.customIntervalsInSeconds.at(i)); } settings->endArray(); settings->sync(); size=17; } else { settings->beginReadArray("custom_intervals_in_seconds"); for(short i=0; isetArrayIndex(i); int seconds=settings->value("item").toInt(); gv.customIntervalsInSeconds << seconds; customIntervals_ << Global::secondsToMinutesHoursDays(seconds); } settings->endArray(); } for(short i=0; iwallpapers_slider_time->text()) { ui->timerSlider->setValue(i+1); break; } } ui->timerSlider->setMaximum(customIntervals_.count()); on_timerSlider_valueChanged(ui->timerSlider->value()); } //Live Earth code void MainWindow::on_activate_livearth_clicked() { if(!ui->activate_livearth->isEnabled()){ #ifdef ON_LINUX Global::changeIndicatorSelection("none"); #endif //#ifdef ON_LINUX return; } closeEverythingThatsRunning(2); on_page_1_earth_clicked(); startLivearth(); } void MainWindow::startLivearth() { ui->activate_livearth->setEnabled(false); ui->deactivate_livearth->setEnabled(true); gv.liveEarthRunning=true; Global::updateStartup(); #ifdef ON_LINUX Global::changeIndicatorSelection("earth"); if(gv.currentDE==UnityGnome){ dbusmenu_menuitem_property_set_bool(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_VISIBLE, true); } #else Q_EMIT signalRecreateTray(); #endif //#ifdef ON_LINUX setProgressbarsValue(100); startUpdateSeconds(); animateProgressbarOpacity(1); } void MainWindow::on_deactivate_livearth_clicked() { if(!ui->deactivate_livearth->isEnabled()){ return; } gv.liveEarthRunning=false; Global::updateStartup(); secondsLeft_=0; processRequestStop(); #ifdef ON_LINUX Global::changeIndicatorSelection("none"); if(gv.currentDE==UnityGnome){ dbusmenu_menuitem_property_set_bool(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_VISIBLE, false); } #else Q_EMIT signalUncheckRunningFeatureOnTray(); #endif //#ifdef ON_LINUX stopLivearth(); ui->deactivate_livearth->setEnabled(false); ui->activate_livearth->setEnabled(true); } void MainWindow::stopLivearth(){ globalParser_->abortDownload(); if(updateSecondsTimer_->isActive()){ updateSecondsTimer_->stop(); } if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(-1, 1); } animateProgressbarOpacity(0); } //Picture of they day code void MainWindow::on_activate_potd_clicked() { if(!ui->activate_potd->isEnabled()){ #ifdef ON_LINUX Global::changeIndicatorSelection("none"); #endif //#ifdef ON_LINUX return; } closeEverythingThatsRunning(3); on_page_2_potd_clicked(); startPotd(true); } void MainWindow::startPotd(bool launch_now){ ui->deactivate_potd->setEnabled(true); ui->activate_potd->setEnabled(false); gv.potdRunning=true; Global::updateStartup(); justUpdatedPotd_=false; if(launch_now){ actionsOnWallpaperChange(); } animateProgressbarOpacity(1); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ dbusmenu_menuitem_property_set_bool(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_VISIBLE, true); } Global::changeIndicatorSelection("potd"); #else Q_EMIT signalRecreateTray(); #endif //#ifdef ON_LINUX startUpdateSeconds(); updatePotdProgress(); } void MainWindow::on_deactivate_potd_clicked() { if(!ui->deactivate_potd->isEnabled()){ return; } secondsLeft_=0; processRequestStop(); globalParser_->abortDownload(); if(updateSecondsTimer_->isActive()){ updateSecondsTimer_->stop(); } animateProgressbarOpacity(0); gv.potdRunning=false; Global::updateStartup(); ui->activate_potd->setEnabled(true); ui->deactivate_potd->setEnabled(false); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ dbusmenu_menuitem_property_set_bool(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_VISIBLE, false); } Global::changeIndicatorSelection("none"); #else Q_EMIT signalUncheckRunningFeatureOnTray(); #endif //#ifdef ON_LINUX } void MainWindow::restartPotdIfRunningAfterSettingChange(){ if(!gv.potdRunning){ settings->setValue("potd_preferences_have_changed", true); settings->sync(); return; } Global::remove(gv.wallchHomePath+POTD_IMAGE+"*"); on_deactivate_potd_clicked(); settings->setValue("last_day_potd_was_set", ""); settings->sync(); startPotd(true); } void MainWindow::on_label_3_linkActivated() { Global::openUrl("http://en.wikipedia.org/wiki/Wikipedia:Picture_of_the_day"); } //Wallpaper clocks code void MainWindow::on_install_clock_clicked() { QStringList paths = QFileDialog::getOpenFileNames(this, tr("Import Wallpaper Clock(s)"), gv.homePath, "*.wcz"); if(paths.isEmpty()){ return; } Q_FOREACH(QString path, paths){ installWallpaperClock(path); } if(!gv.wallpaperClocksRunning){ ui->clocksTableWidget->selectRow(ui->clocksTableWidget->rowCount()); } ui->clocksTableWidget->setFocus(); } void MainWindow::installWallpaperClock(const QString ¤tPath){ currentWallpaperClockPath_=gv.wallchHomePath+"Wallpaper_clocks/"+QFileInfo(currentPath).baseName(); if(QDir(gv.wallchHomePath+"Wallpaper_clocks/").exists()){ if(QFile::exists(currentWallpaperClockPath_)) { QMessageBox::warning(this, tr("Error!"), QString(tr("Wallpaper clock already installed.")+" ("+currentWallpaperClockPath_+")")); return; } } else { QDir().mkpath(gv.wallchHomePath+"Wallpaper_clocks/"); } #ifdef ON_LINUX unzipArchive_ = new QProcess(this); QStringList params; params << "-qq" << "-o" << currentPath << "-d" << currentWallpaperClockPath_; connect(unzipArchive_, SIGNAL(finished(int)), this, SLOT(addClockToList())); unzipArchive_->start("unzip", params); unzipArchive_->waitForFinished(); #else unzip(currentPath, currentWallpaperClockPath_); #endif ui->clocksTableWidget->setFocus(); if(!gv.wallpaperClocksRunning) ui->clocksTableWidget->selectRow(ui->clocksTableWidget->rowCount()-1); } void MainWindow::addClockToList(){ #ifdef ON_LINUX if(unzipArchive_&& !unzipArchive_->isOpen()){ unzipArchive_->deleteLater(); } #endif QFile file(currentWallpaperClockPath_+"/clock.ini"); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ Global::error("I could not open your clock.ini file successfully!"); return; } QString clockName, clockWidth, clockHeight; QTextStream in(&file); bool name_found=false, w_found=false, h_found=false; while(!in.atEnd()) { QString line=in.readLine(); if(!name_found){ if(line.left(5)=="name=") { clockName=line.right(line.count()-5); name_found=true; } } if(!w_found){ if(line.left(6)=="width=") { clockWidth=line.right(line.count()-6); w_found=true; } } if(!h_found){ if(line.left(7)=="height=") { clockHeight=line.right(line.count()-7); h_found=true; } } } file.close(); int old_r_count=ui->clocksTableWidget->rowCount(); ui->clocksTableWidget->insertRow(ui->clocksTableWidget->rowCount()); //adding radio button, which one is selected is the one that will be used when Wallpaper clocks are activated QWidget* wdg = new QWidget; QRadioButton *radiobutton_item = new QRadioButton(this); clocksRadioButtonsGroup->addButton(radiobutton_item); connect(radiobutton_item, SIGNAL(clicked()), this, SLOT(clockRadioButton_check_state_changed())); radiobutton_item->setFocusPolicy(Qt::NoFocus); QHBoxLayout* layout = new QHBoxLayout(wdg); layout->addWidget(radiobutton_item); layout->setAlignment( Qt::AlignCenter ); layout->setMargin(0); wdg->setLayout(layout); ui->clocksTableWidget->setCellWidget(old_r_count, 0, wdg); //adding preview image QLabel *label_item = new QLabel(this); label_item->setAlignment(Qt::AlignCenter); label_item->setPixmap(QPixmap(currentWallpaperClockPath_+"/preview100x75.jpg").scaled(80, 60, Qt::KeepAspectRatio, Qt::SmoothTransformation)); ui->clocksTableWidget->setCellWidget(old_r_count, 1, label_item); //adding title of clock and dimensions QTableWidgetItem *name_item = new QTableWidgetItem; name_item->setText(clockName+"\n"+clockWidth+"x"+clockHeight); name_item->setData(32, currentWallpaperClockPath_); name_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); ui->clocksTableWidget->setItem(old_r_count,2,name_item); ui->activate_clock->setEnabled(true); } #ifdef ON_WIN32 void MainWindow::unzip(QString input, const QString &outputDirectory){ QDir baseDir(outputDirectory); baseDir.mkpath(baseDir.path()); QZipReader unzip(input, QIODevice::ReadOnly); QList allFiles = unzip.fileInfoList(); Q_FOREACH (QZipReader::FileInfo fi, allFiles) { const QString absPath = outputDirectory + QDir::separator() + fi.filePath; if(fi.isDir){ if (!baseDir.mkpath(fi.filePath)){ continue; } if (!QFile::setPermissions(absPath, fi.permissions)){ continue; } } else if (fi.isFile) { QFile file(absPath); if( file.open(QFile::WriteOnly) ) { file.write(unzip.fileData(fi.filePath), unzip.fileData(fi.filePath).size()); file.setPermissions(fi.permissions); file.close(); } } qApp->processEvents(QEventLoop::AllEvents); } unzip.close(); addClockToList(); } #endif void MainWindow::uninstall_clock() { if(currentlyUninstallingWallpaperClock_ || ui->clocksTableWidget->rowCount()==0 ){ return; } if(gv.wallpaperClocksRunning) { return; } currentlyUninstallingWallpaperClock_=true; if(!QDir(gv.defaultWallpaperClock).removeRecursively()){ Global::error("Could not delete wallpaper clock, check folder's and subfolders' permissions."); } if(ui->clocksTableWidget->rowCount()==1){ ui->activate_clock->setEnabled(false); if(gv.previewImagesOnScreen){ changeTextOfScreenLabelTo(tr("No wallpaper clock has been\ninstalled to preview")); } } ui->clocksTableWidget->removeRow(ui->clocksTableWidget->currentRow()); currentlyUninstallingWallpaperClock_=false; } void MainWindow::on_clocksTableWidget_customContextMenuRequested() { clockwidgetMenu_ = new QMenu(this); clockwidgetMenu_->addAction(tr("Unistall"), this, SLOT(uninstall_clock())); clockwidgetMenu_->actions().at(0)->setIcon(QIcon::fromTheme("list-remove", QIcon(":/icons/Pictures/list-remove.svg"))); if(gv.wallpaperClocksRunning){ clockwidgetMenu_->actions().at(0)->setEnabled(false); } clockwidgetMenu_->popup(MENU_POPUP_POS); } void MainWindow::clockRadioButton_check_state_changed() { int rowCount=ui->clocksTableWidget->rowCount(); for(int i=0; iclocksTableWidget->cellWidget(i, 0 ); if( w ) { QRadioButton* radioButton = w->findChild(); if( radioButton && radioButton->isChecked()) { ui->clocksTableWidget->selectRow(i); break; } } } } void MainWindow::on_clocksTableWidget_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn) { Q_UNUSED(currentColumn); Q_UNUSED(previousColumn); if(currentRow==previousRow || (ui->clocksTableWidget->rowCount()==1 && currentlyUninstallingWallpaperClock_)){ return; } gv.defaultWallpaperClock=ui->clocksTableWidget->item(currentRow,2)->data(32).toString(); settings->setValue("default_wallpaper_clock", gv.defaultWallpaperClock); if(gv.wallpaperClocksRunning){ Global::wallpaperClockNow(gv.defaultWallpaperClock, ui->minutes_checkBox->isChecked(), ui->hour_checkBox->isChecked(), ui->am_checkBox->isChecked(), ui->day_week_checkBox->isChecked(), ui->day_month_checkBox->isChecked(), ui->month_checkBox->isChecked()); } QWidget* w = ui->clocksTableWidget->cellWidget(currentRow, 0 ); if( w ) { QRadioButton* radioButton = w->findChild(); if( radioButton ) { radioButton->setChecked(true); } } //just installed first wallpaper clock.. Selection has not yet been applied, so select first row in order to preview if(ui->clocksTableWidget->rowCount()==1 && ui->clocksTableWidget->selectedItems().count()==0){ ui->clocksTableWidget->selectRow(0); } if(ui->clocksTableWidget->rowCount()==0 || ui->clocksTableWidget->selectedItems().count()==0) { if(gv.previewImagesOnScreen){ hideScreenLabel(); } } else { if(gv.previewImagesOnScreen){ imageTransition("preview_clock"); } } } void MainWindow::on_activate_clock_clicked() { closeEverythingThatsRunning(4); if(!wallpaperClocksPageLoaded_){ loadWallpaperClocksPage(); } if(!ui->activate_clock->isEnabled()){ #ifdef ON_LINUX Global::changeIndicatorSelection("none"); #endif //#ifdef ON_LINUX globalParser_->desktopNotify(tr("No default wallpaper clock has been set."), false, "info"); Global::error("No default wallpaper clock has been set. Make sure that after installing the wallpaper clock you have clicked at set as default."); return; } on_page_3_clock_clicked(); if(ui->minutes_checkBox->isChecked() || ui->hour_checkBox->isChecked() || (ui->am_checkBox->isChecked() && gv.amPmEnabled) || ui->day_week_checkBox->isChecked() || ui->day_month_checkBox->isChecked() || ui->month_checkBox->isChecked()) { Global::readClockIni(gv.defaultWallpaperClock); QString currentWallpaperClock = Global::wallpaperClockNow(gv.defaultWallpaperClock, ui->minutes_checkBox->isChecked(), ui->hour_checkBox->isChecked(), ui->am_checkBox->isChecked(), ui->day_week_checkBox->isChecked(), ui->day_month_checkBox->isChecked(), ui->month_checkBox->isChecked()); if(gv.setAverageColor){ setAverageColor(currentWallpaperClock); } QTime time = QTime::currentTime(); float seconds_left_for_min=0; if(time.minute()==59 && time.hour()!=23){ seconds_left_for_min=time.secsTo(QTime(time.hour()+1,0,1)); } else if (time.minute()==59 && time.hour()==23){ seconds_left_for_min=time.secsTo(QTime(23,59,59))+2; } else{ seconds_left_for_min=time.secsTo(QTime(time.hour(),time.minute()+1,1)); } ui->activate_clock->setEnabled(false); ui->deactivate_clock->setEnabled(true); gv.wallpaperClocksRunning=true; Global::updateStartup(); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ dbusmenu_menuitem_property_set_bool(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_VISIBLE, true); } Global::changeIndicatorSelection("clocks"); #else Q_EMIT signalRecreateTray(); #endif //#ifdef ON_LINUX if(ui->minutes_checkBox->isChecked()) { secondsLeft_=seconds_left_for_min; } else if(ui->hour_checkBox->isChecked()) { secondsLeft_=(((QString::number(time.minute()/gv.refreshhourinterval).toInt()+1)*gv.refreshhourinterval-time.minute()-1)*60+seconds_left_for_min); } else if(ui->am_checkBox->isChecked() && gv.amPmEnabled) { float seconds_left_for_am_pm=0; if (time.hour()>=12){ seconds_left_for_am_pm=time.secsTo(QTime(23,59,59))+2; } else{ seconds_left_for_am_pm=time.secsTo(QTime(12,0,1)); } secondsLeft_=seconds_left_for_am_pm; } else if(ui->day_week_checkBox->isChecked() || ui->day_month_checkBox->isChecked()) { float seconds_left_for_next_day=time.secsTo(QTime(23,59,59))+2; secondsLeft_=seconds_left_for_next_day; } else if(ui->month_checkBox->isChecked()) { float seconds_left_for_next_day=time.secsTo(QTime(23,59,59))+2; secondsLeft_=seconds_left_for_next_day; } totalSeconds_=secondsLeft_; Global::resetSleepProtection(secondsLeft_); startUpdateSeconds(); setProgressbarsValue(100); animateProgressbarOpacity(1); } else { if (QMessageBox::question(this,tr("Wallpaper Clock"), tr("You haven't selected any of the options (day of week etc...), thus the wallpaper clock will not be activated. You can use the wallpaper of the default wallpaper clock as a background, instead.")) == QMessageBox::Yes) { QString pic=gv.defaultWallpaperClock+"/bg.jpg"; Global::setBackground(pic, true, true, 4); } } } void MainWindow::on_deactivate_clock_clicked() { if(!ui->deactivate_clock->isEnabled()){ return; } ui->deactivate_clock->setEnabled(false); ui->activate_clock->setEnabled(true); if(updateSecondsTimer_->isActive()){ updateSecondsTimer_->stop(); } animateProgressbarOpacity(0); gv.wallpaperClocksRunning=false; Global::updateStartup(); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ dbusmenu_menuitem_property_set_bool(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_VISIBLE, false); } Global::changeIndicatorSelection("none"); #else Q_EMIT signalUncheckRunningFeatureOnTray(); #endif //#ifdef ON_LINUX secondsLeft_=0; } QImage *MainWindow::wallpaperClocksPreview(const QString &wallClockPath, bool minuteCheck, bool hourCheck, bool amPmCheck, bool dayWeekCheck, bool dayMonthCheck, bool monthCheck) { short hour_inte=0; short am_pm_en=0; short images_of_hour=0; //reading clock.ini of wallpaper clock in order to get the gv.refreshhourinterval,if there are images for am or pm and the total of hour images QFile file(wallClockPath+"/clock.ini"); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ Global::error("I could not open the clock.ini file ("+wallClockPath+"/clock.ini) for reading successfully!"); return NULL; } QTextStream in(&file); while(!in.atEnd()) { QString line=in.readLine(); if(line.startsWith("refreshhourinterval=")){ hour_inte=QString(line.right(line.count()-20)).toInt(); } else if(line.startsWith("ampmenabled=")){ am_pm_en=QString(line.right(line.count()-12)).toInt(); } else if(line.startsWith("ampmenabled=")){ images_of_hour=QString(line.right(line.count()-11)).toInt(); } } file.close(); if(hour_inte==0){ return NULL; } QDateTime datetime = QDateTime::currentDateTime(); //12h format is needed for the analog clocks short hour_12h_format=0; QString am_or_pm; if (datetime.time().hour()>=12){ am_or_pm="pm"; } else { am_or_pm="am"; } if(images_of_hour==24 || datetime.time().hour()<12 ){ hour_12h_format=datetime.time().hour(); } else if(images_of_hour!=24 && datetime.time().hour()>=12){ hour_12h_format=datetime.time().hour()-12; } QImage *merged = new QImage(wallClockPath+"/bg.jpg"); QPainter painter(merged); if(monthCheck){ painter.drawPixmap(0, 0, QPixmap(wallClockPath+"/month"+QString::number(datetime.date().month())+".png")); } if(dayWeekCheck){ painter.drawPixmap(0, 0, QPixmap(wallClockPath+"/weekday"+QString::number(datetime.date().dayOfWeek())+".png")); } if(dayMonthCheck){ painter.drawPixmap(0, 0, QPixmap(wallClockPath+"/day"+QString::number(datetime.date().day())+".png")); } if(hourCheck){ painter.drawPixmap(0, 0, QPixmap(wallClockPath+"/hour"+QString::number(hour_12h_format*(60/hour_inte)+QString::number(datetime.time().minute()/hour_inte).toInt())+".png")); } if(minuteCheck){ painter.drawPixmap(0, 0, QPixmap(wallClockPath+"/minute"+QString::number(datetime.time().minute())+".png")); } if(am_pm_en && amPmCheck){ painter.drawPixmap(0, 0, QPixmap(wallClockPath+"/"+am_or_pm+".png")); } painter.end(); return merged; } void MainWindow::clockCheckboxClickedWhileRunning() { if(ui->minutes_checkBox->isChecked() || ui->hour_checkBox->isChecked() || (ui->am_checkBox->isChecked() && gv.amPmEnabled) || ui->day_week_checkBox->isChecked() || ui->day_month_checkBox->isChecked() || ui->month_checkBox->isChecked()) { QString currentWallpaperClock = Global::wallpaperClockNow(gv.defaultWallpaperClock, ui->minutes_checkBox->isChecked(), ui->hour_checkBox->isChecked(), ui->am_checkBox->isChecked(), ui->day_week_checkBox->isChecked(), ui->day_month_checkBox->isChecked(), ui->month_checkBox->isChecked()); if(gv.setAverageColor){ setAverageColor(currentWallpaperClock); } QTime time = QTime::currentTime(); float seconds_left_for_min=0; if(time.minute()==59 && time.hour()!=23){ seconds_left_for_min=time.secsTo(QTime(time.hour()+1,0,1)); } else if (time.minute()==59 && time.hour()==23){ seconds_left_for_min=time.secsTo(QTime(23,59,59))+2; } else { seconds_left_for_min=time.secsTo(QTime(time.hour(),time.minute()+1,1)); } ui->activate_clock->setEnabled(false); ui->deactivate_clock->setEnabled(true); if(ui->minutes_checkBox->isChecked()){ secondsLeft_=seconds_left_for_min; } else if(ui->hour_checkBox->isChecked()){ secondsLeft_=(((QString::number(time.minute()/gv.refreshhourinterval).toInt()+1)*gv.refreshhourinterval-time.minute()-1)*60+seconds_left_for_min); } else if(ui->am_checkBox->isChecked() && gv.amPmEnabled) { float seconds_left_for_am_pm=0; if (time.hour()>=12){ seconds_left_for_am_pm=time.secsTo(QTime(23,59,59))+2; } else{ seconds_left_for_am_pm=time.secsTo(QTime(12,0,1)); } secondsLeft_=seconds_left_for_am_pm; } else if(ui->day_week_checkBox->isChecked() || ui->day_month_checkBox->isChecked() || ui->month_checkBox->isChecked()) { float seconds_left_for_next_day=time.secsTo(QTime(23,59,59))+2; secondsLeft_=seconds_left_for_next_day; } totalSeconds_=secondsLeft_; startUpdateSeconds(); setProgressbarsValue(100); } else { QString currentWallpaperClock = Global::wallpaperClockNow(gv.defaultWallpaperClock, ui->minutes_checkBox->isChecked(), ui->hour_checkBox->isChecked(), ui->am_checkBox->isChecked(), ui->day_week_checkBox->isChecked(), ui->day_month_checkBox->isChecked(), ui->month_checkBox->isChecked()); if(gv.setAverageColor){ setAverageColor(currentWallpaperClock); } on_deactivate_clock_clicked(); } } void MainWindow::on_label_9_linkActivated() { Global::openUrl("http://www.vladstudio.com/wallpaperclocks/browse.php"); } void MainWindow::clockCheckboxClicked() { imageTransition("preview_clock"); settings->setValue("month", ui->month_checkBox->isChecked()); settings->setValue("day_of_month", ui->day_month_checkBox->isChecked()); settings->setValue("day_of_week", ui->day_week_checkBox->isChecked()); settings->setValue("am_pm", ui->am_checkBox->isChecked()); settings->setValue("hour", ui->hour_checkBox->isChecked()); settings->setValue("minute", ui->minutes_checkBox->isChecked()); if(gv.wallpaperClocksRunning) { if(wallpaperClockWait_->isActive()){ wallpaperClockWait_->stop(); } wallpaperClockWait_->start(500); } } //Live Website Code void MainWindow::on_activate_website_clicked() { closeEverythingThatsRunning(5); if(!liveWebsitePageLoaded_){ loadLiveWebsitePage(); } if(websiteSnapshot_==NULL || !ui->activate_website->isEnabled() || !websiteConfiguredCorrectly()){ #ifdef ON_LINUX Global::changeIndicatorSelection("none"); #endif return; } gv.websiteWebpageToLoad=gv.onlineLinkForHistory=ui->website->text(); gv.websiteInterval=ui->website_slider->value(); gv.websiteCropEnabled=ui->website_crop_checkbox->isChecked(); on_page_4_web_clicked(); ui->stackedWidget->setCurrentIndex(4); ui->deactivate_website->setEnabled(true); ui->activate_website->setEnabled(false); ui->verticalLayout_11->addWidget(ui->timeout_text_label); ui->verticalLayout_11->addWidget(ui->website_timeout_label); ui->website_timeout_label->setText(QString::number(WEBSITE_TIMEOUT)+" "+tr("seconds")+"..."); ui->timeout_text_label->show(); ui->website_timeout_label->show(); timePassedForLiveWebsiteRequest_=1; ui->live_website_login_widget->setEnabled(false); gv.liveWebsiteRunning=true; Global::updateStartup(); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ dbusmenu_menuitem_property_set_bool(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_VISIBLE, true); } Global::changeIndicatorSelection("website"); #else Q_EMIT signalRecreateTray(); #endif //#ifdef ON_LINUX setProgressbarsValue(100); animateProgressbarOpacity(1); prepareWebsiteSnapshot(); websiteSnapshot_->setCrop(ui->website_crop_checkbox->isChecked(), gv.websiteCropArea); connect(websiteSnapshot_->asQObject(), SIGNAL(resultedImage(QImage*,short)), this, SLOT(liveWebsiteImageCreated(QImage*,short))); startUpdateSeconds(); } void MainWindow::on_deactivate_website_clicked() { if(!ui->deactivate_website->isEnabled()){ return; } gv.liveWebsiteRunning=false; Global::updateStartup(); secondsLeft_=0; if(updateSecondsTimer_->isActive()){ updateSecondsTimer_->stop(); } if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(-1, 2); } ui->live_website_login_widget->setEnabled(true); animateProgressbarOpacity(0); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ dbusmenu_menuitem_property_set_bool(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_VISIBLE, false); } Global::changeIndicatorSelection("none"); #else Q_EMIT signalUncheckRunningFeatureOnTray(); #endif //#ifdef ON_LINUX disconnect(websiteSnapshot_->asQObject(), SIGNAL(resultedImage(QImage*,short)), this, SLOT(liveWebsiteImageCreated(QImage*,short))); ui->deactivate_website->setEnabled(false); ui->activate_website->setEnabled(true); ui->timeout_text_label->hide(); ui->website_timeout_label->hide(); processRequestStop(); websiteSnapshot_->stop(); } void MainWindow::on_website_preview_clicked() { if(gv.liveWebsiteRunning){ QMessageBox::warning(this, tr("Error"), tr("Please stop the current process and try again.")+" ("+tr("Live Website")+")"); return; } if(websitePreviewShown_ || !websiteConfiguredCorrectly()){ return; } if(changedWebPage_!=initialWebPage_ && !(changedWebPage_==initialWebPage_+"/" || changedWebPage_+"/"==initialWebPage_)){ initialWebPage_=changedWebPage_; } QFile::remove(gv.wallchHomePath+LW_PREVIEW_IMAGE); websitePreviewShown_=true; prepareWebsiteSnapshot(); webPreview_ = new WebsitePreview(websiteSnapshot_, false, ui->website_crop_checkbox->isChecked(), gv.websiteCropArea, this); webPreview_->setModal(true); webPreview_->setAttribute(Qt::WA_DeleteOnClose); connect(webPreview_, SIGNAL(destroyed()), this, SLOT(websitePreviewDestroyed())); connect(webPreview_, SIGNAL(previewImageReady(QImage*)), this, SLOT(setWebsitePreviewImage(QImage*))); connect(webPreview_, SIGNAL(sendExtraCoordinates(QRect)), this, SLOT(readCoordinates(const QRect&))); webPreview_->show(); } void MainWindow::liveWebsiteImageCreated(QImage *image, short errorCode){ ui->timeout_text_label->hide(); ui->website_timeout_label->hide(); timePassedForLiveWebsiteRequest_=0; ui->website_timeout_label->setText(QString::number(WEBSITE_TIMEOUT)+" "+tr("seconds")+"..."); processRequestStop(); if(errorCode==0){ //no error! Global::remove(gv.wallchHomePath+LW_IMAGE+"*"); QString filename=gv.wallchHomePath+LW_IMAGE+QString::number(QDateTime::currentMSecsSinceEpoch())+".png"; image->save(filename); delete image; Global::setBackground(filename, true, true, 5); QFile::remove(gv.wallchHomePath+LW_PREVIEW_IMAGE); QFile(filename).link(gv.wallchHomePath+LW_PREVIEW_IMAGE); updateScreenLabel(); } else { switch(errorCode){ case 1: Global::error("Some of the requested pages failed to load successfully."); break; case 2: Global::error("Simple authentication failed. Please check your username and/or password."); break; case 3: Global::error("Username and/or password fields are not found. Please check that you are pointing at the login page."); break; case 4: Global::error("The timeout has been reached and the image has yet to be created!"); break; default: Global::error("Unknown error! Please try with a different web page."); break; } } } void MainWindow::prepareWebsiteSnapshot(){ /* * This does not prepare websiteSnapshot for * the cropping that it has to do (for compatibility * with the crop_image and website_preview dialogs) */ websiteSnapshot_->setParameters(QUrl(ui->website->text()), gv.screenWidth, gv.screenHeight); websiteSnapshot_->setWaitAfterFinish(gv.websiteWaitAfterFinishSeconds); websiteSnapshot_->setJavascriptConfig(gv.websiteJavascriptEnabled, gv.websiteJavascriptCanReadClipboard); websiteSnapshot_->setJavaEnabled(gv.websiteJavaEnabled); websiteSnapshot_->setLoadImagesEnabled(gv.websiteLoadImages); if(ui->add_login_details->isChecked()){ QString final_webpage=ui->final_webpage->text(); if(!ui->redirect_checkBox->isChecked() || final_webpage.isEmpty()){ final_webpage=ui->website->text(); } if(gv.websiteSimpleAuthEnabled){ websiteSnapshot_->setSimpleAuthentication(ui->username->text(), ui->password->text(), final_webpage); } else { if(gv.websiteExtraUsernames.count()>0 || gv.websiteExtraPasswords.count()>0) { websiteSnapshot_->setComplexAuthenticationWithPossibleFields(ui->username->text(), ui->password->text(), final_webpage, gv.websiteExtraUsernames, gv.websiteExtraPasswords, true); } else { websiteSnapshot_->setComplexAuthentication(ui->username->text(), ui->password->text(), final_webpage); } } } else { websiteSnapshot_->disableAuthentication(); } websiteSnapshot_->setTimeout(WEBSITE_TIMEOUT); } void MainWindow::setWebsitePreviewImage(QImage *image){ image->save(gv.wallchHomePath+LW_PREVIEW_IMAGE); delete image; updateScreenLabel(); } void MainWindow::on_edit_crop_clicked() { if(gv.liveWebsiteRunning){ QMessageBox::warning(this, tr("Error"), tr("Please stop the current process and try again.")+" ("+tr("Live Website")+")"); return; } if(changedWebPage_!=initialWebPage_ && !(changedWebPage_==initialWebPage_+"/" || changedWebPage_+"/"==initialWebPage_)){ initialWebPage_=changedWebPage_; } QFile::remove(gv.wallchHomePath+LW_PREVIEW_IMAGE); websitePreviewShown_=true; prepareWebsiteSnapshot(); webPreview_ = new WebsitePreview(websiteSnapshot_, true, false, gv.websiteCropArea, this); webPreview_->setModal(true); webPreview_->setAttribute(Qt::WA_DeleteOnClose); connect(webPreview_, SIGNAL(destroyed()), this, SLOT(websitePreviewDestroyed())); connect(webPreview_, SIGNAL(sendExtraCoordinates(QRect)), this, SLOT(readCoordinates(const QRect&))); webPreview_->show(); } void MainWindow::websitePreviewDestroyed(){ websitePreviewShown_=false; } void MainWindow::on_website_crop_checkbox_clicked(bool checked) { if(gv.liveWebsiteRunning){ ui->website_crop_checkbox->setChecked(!checked); QMessageBox::warning(this, tr("Error"), tr("Please stop the current process and try again.")+" ("+tr("Live Website")+")"); return; } ui->edit_crop->setEnabled(checked); } void MainWindow::readCoordinates(const QRect &cropArea){ gv.websiteCropArea=cropArea; settings->setValue("website_crop_area", gv.websiteCropArea); updateScreenLabel(); } void MainWindow::on_website_textEdited(const QString &arg1) { changedWebPage_=arg1; } bool MainWindow::websiteConfiguredCorrectly(){ if(!ui->website->text().startsWith("h") && !ui->website->text().startsWith("f")){ ui->website->setText("http://"+ui->website->text()); } if(ui->website->text().count()<=4 || !ui->website->text().contains(".")){ QMessageBox::warning(this, tr("Error"), tr("Invalid address specified!")); return false; } if(ui->add_login_details->isChecked()){ if(ui->username->text().isEmpty() || ui->password->text().isEmpty()){ QMessageBox::warning(this, tr("Error"), tr("Invalid username or password specified.")); return false; } } return true; } //Pages code void MainWindow::loadWallpapersPage(){ wallpapersPageLoaded_=true; HideGrayLinesDelegate *delegate = new HideGrayLinesDelegate(ui->listWidget); ui->listWidget->setItemDelegate(delegate); ui->listWidget->setDragDropMode(QAbstractItemView::NoDragDrop); imageLoading_=QIcon::fromTheme("image-loading", QIcon(":icons/Pictures/image-loading.svg")); ui->pictures_location_comboBox->setItemText(0, gv.currentOSName+" "+tr("Desktop Backgrounds")); ui->pictures_location_comboBox->setItemData(0, gv.currentDeDefaultWallpapersPath); ui->pictures_location_comboBox->setItemText(1, tr("My Pictures")); ui->pictures_location_comboBox->setItemData(1, gv.homePath+"/"+gv.defaultPicturesLocation); short size=settings->beginReadArray("pictures_locations"); for(short i=2;isetArrayIndex(i); QString qpath=settings->value("item").toString(); ui->pictures_location_comboBox->addItem(Global::basenameOf(qpath)); ui->pictures_location_comboBox->setItemData(ui->pictures_location_comboBox->count()-1, qpath); } settings->endArray(); short currentFolder = settings->value("currentFolder_index", 0).toInt(); currentFolder_=ui->pictures_location_comboBox->itemData(currentFolder).toString(); if(!QDir(currentFolder_).exists()) { tempForDelayedPicturesLocationChange_=currentFolder; QTimer::singleShot(100, this, SLOT(delayed_pictures_location_change())); } else { if(currentFolder==0){ on_pictures_location_comboBox_currentIndexChanged(0); } else { ui->pictures_location_comboBox->setCurrentIndex(currentFolder); } } refreshIntervals(); short old_value=ui->timerSlider->value(); ui->timerSlider->setValue(settings->value("timeSlider", 7).toInt()); if(old_value==ui->timerSlider->value()){ on_timerSlider_valueChanged(old_value); } launchTimerToUpdateIcons(); openCloseSearch_ = new QPropertyAnimation(ui->search_widget, "maximumHeight"); connect(openCloseSearch_, SIGNAL(finished()), this, SLOT(openCloseSearchAnimationFinished())); openCloseSearch_->setDuration(GENERAL_ANIMATION_SPEED); cacheSizeChecker_->start(CHECK_CACHE_SIZE_TIMEOUT); } void MainWindow::loadPotdPage(){ potdPageLoaded_=true; ui->include_description_checkBox->setChecked(gv.potdIncludeDescription); } void MainWindow::loadWallpaperClocksPage() { HideGrayLinesDelegate *delegate = new HideGrayLinesDelegate(ui->clocksTableWidget); ui->clocksTableWidget->setItemDelegate(delegate); ui->clocksTableWidget->setColumnWidth(0, 20); //add to the listwidget the wallpaper clocks that exist in ~/.wallch/Wallpaper_clocks (AppData/Local/Mellori Studio/Wallch/Wallpaper_clocks for Windows) #ifdef ON_LINUX unzipArchive_=NULL; #endif Q_FOREACH(currentWallpaperClockPath_, Global::listFolders(gv.wallchHomePath+"Wallpaper_clocks", true, false)) { addClockToList(); } short clocksCount=ui->clocksTableWidget->rowCount(); for(short i=0;iclocksTableWidget->item(i,2)->data(32)==gv.defaultWallpaperClock){ ui->clocksTableWidget->selectRow(i); ui->clocksTableWidget->setFocus(); break; } } ui->activate_clock->setEnabled(clocksCount!=0); ui->month_checkBox->setChecked(settings->value("month",true).toBool()); ui->day_month_checkBox->setChecked(settings->value("day_of_month",true).toBool()); ui->day_week_checkBox->setChecked(settings->value("day_of_week",true).toBool()); ui->am_checkBox->setChecked(settings->value("am_pm",true).toBool()); ui->hour_checkBox->setChecked(settings->value("hour",true).toBool()); ui->minutes_checkBox->setChecked(settings->value("minute",true).toBool()); wallpaperClocksPageLoaded_=true; } void MainWindow::loadLiveWebsitePage(){ liveWebsitePageLoaded_=true; //add login details information openCloseAddLogin_ = new QPropertyAnimation(ui->live_website_login_widget, "maximumHeight"); connect(openCloseAddLogin_, SIGNAL(finished()), this, SLOT(openCloseAddLoginAnimationFinished())); openCloseAddLogin_->setDuration(GENERAL_ANIMATION_SPEED); gv.websiteWebpageToLoad=settings->value("website", "http://google.com").toString(); gv.websiteInterval=settings->value("website_interval", 6).toInt(); gv.websiteCropEnabled=settings->value("website_crop", false).toBool(); gv.websiteCropArea=settings->value("website_crop_area", QRect(0, 0, gv.screenWidth, gv.screenHeight)).toRect(); gv.websiteLoginEnabled=settings->value("website_login", false).toBool(); gv.websiteLoginUsername=settings->value("website_username", "").toString(); gv.websiteLoginPasswd=settings->value("website_password", "").toString(); if(!gv.websiteLoginPasswd.isEmpty()){ gv.websiteLoginPasswd=Global::base64Decode(gv.websiteLoginPasswd); } gv.websiteRedirect=settings->value("website_redirect", false).toBool(); gv.websiteFinalPageToLoad=settings->value("website_final_webpage", "").toString(); gv.websiteSimpleAuthEnabled=settings->value("website_simple_auth", false).toBool(); gv.websiteWaitAfterFinishSeconds=settings->value("website_wait_after_finish", 3).toInt(); gv.websiteJavascriptEnabled=settings->value("website_js_enabled", true).toBool(); gv.websiteJavascriptCanReadClipboard=settings->value("website_js_can_read_clipboard", false).toBool(); gv.websiteJavaEnabled=settings->value("website_java_enabled", false).toBool(); gv.websiteLoadImages=settings->value("website_load_images", true).toBool(); gv.websiteExtraUsernames=settings->value("website_extra_usernames", QStringList()).toStringList(); gv.websiteExtraPasswords=settings->value("website_extra_passwords", QStringList()).toStringList(); ui->website->setText(gv.websiteWebpageToLoad); short old_website_slider_value=ui->website_slider->value(); ui->website_slider->setValue(gv.websiteInterval); if(gv.websiteInterval==old_website_slider_value){ on_website_slider_valueChanged(gv.websiteInterval); } ui->website_crop_checkbox->setChecked(gv.websiteCropEnabled); ui->edit_crop->setEnabled(ui->website_crop_checkbox->isEnabled() && gv.websiteCropEnabled); ui->add_login_details->setChecked(gv.websiteLoginEnabled); if(gv.websiteLoginEnabled){ on_add_login_details_clicked(true); } ui->username->setText(gv.websiteLoginUsername); ui->password->setText(gv.websiteLoginPasswd); ui->redirect_checkBox->setChecked(gv.websiteRedirect); ui->final_webpage->setEnabled(gv.websiteRedirect); ui->final_webpage->setText(gv.websiteFinalPageToLoad); ui->timeout_text_label->hide(); ui->website_timeout_label->hide(); changedWebPage_=initialWebPage_=ui->website->text(); if(websiteSnapshot_!=NULL){ return; } websiteSnapshot_ = new WebsiteSnapshot(); } void MainWindow::openCloseAddLoginAnimationFinished(){ if(openCloseAddLogin_->endValue().toInt()==0){ ui->live_website_login_widget->hide(); this->repaint(); } } void MainWindow::disableLiveWebsitePage(){ ui->website_interval_slider_label->setEnabled(false); ui->label_11->setEnabled(false); ui->label_23->setEnabled(false); ui->website->setEnabled(false); ui->website_slider->setEnabled(false); ui->website_crop_checkbox->setEnabled(false); ui->edit_crop->setEnabled(false); ui->activate_website->setEnabled(false); ui->website_preview->setEnabled(false); ui->deactivate_website->setEnabled(false); ui->timeout_text_label->setEnabled(false); ui->website_timeout_label->setEnabled(false); ui->add_login_details->setEnabled(false); ui->live_website_login_widget->setEnabled(false); } void MainWindow::on_add_login_details_clicked(bool checked) { if(gv.liveWebsiteRunning){ ui->add_login_details->setChecked(!checked); QMessageBox::warning(this, tr("Error"), tr("Please stop the current process and try again.")+" ("+tr("Live Website")+")"); return; } openCloseAddLogin_->setStartValue(ui->live_website_login_widget->maximumHeight()); if(!checked){ openCloseAddLogin_->setEndValue(0); } else { ui->live_website_login_widget->show(); openCloseAddLogin_->setEndValue(200); } openCloseAddLogin_->start(); } void MainWindow::on_page_0_wallpapers_clicked() { if(gv.mainwindowLoaded && ui->stackedWidget->currentIndex()==0){ return; } if(!wallpapersPageLoaded_){ loadWallpapersPage(); if(ui->listWidget->count()<=1){ startButtonsSetEnabled(false); } else { startButtonsSetEnabled(true); } if(gv.randomTimeEnabled){ ui->timerSlider->setEnabled(false); ui->wallpapers_slider_time->setEnabled(false); ui->interval_label->setEnabled(false); } else { ui->timerSlider->setEnabled(true); ui->wallpapers_slider_time->setEnabled(true); ui->interval_label->setEnabled(true); } } launchTimerToUpdateIcons(); on_timerSlider_valueChanged(ui->timerSlider->value()); ui->page_0_wallpapers->setChecked(true);//in case it is called via the shortcut ui->stackedWidget->setCurrentIndex(0); ui->page_0_wallpapers->raise(); ui->sep1->raise(); if(gv.previewImagesOnScreen){ updateScreenLabel(); } } void MainWindow::on_page_1_earth_clicked() { if(gv.mainwindowLoaded && ui->stackedWidget->currentIndex()==1){ return; } ui->page_1_earth->setChecked(true); ui->stackedWidget->setCurrentIndex(1); ui->page_1_earth->raise(); ui->sep1->raise(); ui->sep2->raise(); if(gv.previewImagesOnScreen){ QTimer::singleShot(10, this, SLOT(updateScreenLabel())); } } void MainWindow::on_page_2_potd_clicked() { if(gv.mainwindowLoaded && ui->stackedWidget->currentIndex()==2){ return; } ui->page_2_potd->setChecked(true); ui->stackedWidget->setCurrentIndex(2); ui->page_2_potd->raise(); ui->sep2->raise(); ui->sep3->raise(); if(!potdPageLoaded_){ loadPotdPage(); } if(gv.previewImagesOnScreen){ QTimer::singleShot(10, this, SLOT(updateScreenLabel())); } } void MainWindow::on_page_3_clock_clicked() { if(gv.mainwindowLoaded && ui->stackedWidget->currentIndex()==3){ return; } ui->page_3_clock->setChecked(true); ui->stackedWidget->setCurrentIndex(3); ui->page_3_clock->raise(); ui->sep3->raise(); ui->sep4->raise(); if(!wallpaperClocksPageLoaded_){ loadWallpaperClocksPage(); } if(gv.previewImagesOnScreen){ QTimer::singleShot(10, this, SLOT(updateScreenLabel())); } } void MainWindow::on_page_4_web_clicked() { if(gv.mainwindowLoaded && ui->stackedWidget->currentIndex()==4){ return; } ui->page_4_web->setChecked(true); ui->stackedWidget->setCurrentIndex(4); ui->page_4_web->raise(); ui->sep4->raise(); ui->sep5->raise(); if(gv.previewImagesOnScreen){ QTimer::singleShot(10, this, SLOT(updateScreenLabel())); } if(!liveWebsitePageLoaded_){ loadLiveWebsitePage(); } } void MainWindow::on_page_5_other_clicked() { if(gv.mainwindowLoaded && ui->stackedWidget->currentIndex()==5){ return; } ui->page_5_other->setChecked(true); ui->stackedWidget->setCurrentIndex(5); ui->page_5_other->raise(); ui->sep5->raise(); if(gv.previewImagesOnScreen){ updateScreenLabel(); } } void MainWindow::previousPage(){ short currentPage = ui->stackedWidget->currentIndex()-1; if(currentPage<0){ currentPage=5; } switch (currentPage){ case 0: on_page_0_wallpapers_clicked(); break; case 1: on_page_1_earth_clicked(); break; case 2: on_page_2_potd_clicked(); break; case 3: on_page_3_clock_clicked(); break; case 4: on_page_4_web_clicked(); break; case 5: on_page_5_other_clicked(); break; default: on_page_0_wallpapers_clicked(); } } void MainWindow::nextPage(){ short currentPage = ui->stackedWidget->currentIndex()+1; if(currentPage>6){ currentPage=0; } switch (currentPage){ case 0: on_page_0_wallpapers_clicked(); break; case 1: on_page_1_earth_clicked(); break; case 2: on_page_2_potd_clicked(); break; case 3: on_page_3_clock_clicked(); break; case 4: on_page_4_web_clicked(); break; case 5: on_page_5_other_clicked(); break; default: on_page_0_wallpapers_clicked(); } } //Actions code void MainWindow::on_actionCopy_Name_triggered() { QApplication::clipboard()->setText(Global::basenameOf(Global::currentBackgroundImage())); } void MainWindow::on_actionCopy_Path_triggered() { QApplication::clipboard()->setText(Global::currentBackgroundImage()); } void MainWindow::on_actionCopy_Image_triggered() { QApplication::clipboard()->setImage(QImage(Global::currentBackgroundImage()), QClipboard::Clipboard); } void MainWindow::on_actionDelete_triggered() { if(QMessageBox::question(0, tr("Confirm deletion"), tr("Are you sure you want to permanently delete the current image?"))==QMessageBox::Yes) { if(!QFile::remove(Global::currentBackgroundImage())){ QMessageBox::warning(0, tr("Error"), tr("There was a problem deleting the current image. Please make sure you have the permission to delete the image or that the image exists.")); } } } void MainWindow::on_actionProperties_triggered() { if(propertiesShown_){ return; } QString imageFilename=Global::currentBackgroundImage(); if(!QFile::exists(imageFilename) || QImage(imageFilename).isNull()) { QMessageBox::warning(0, tr("Properties"), tr("This file maybe doesn't exist or it's not an image. Please perform a check for the file and try again.")); return; } propertiesShown_=true; properties_ = new Properties(imageFilename, false, 0, 0); properties_->setModal(true); properties_->setAttribute(Qt::WA_DeleteOnClose); connect(properties_, SIGNAL(destroyed()), this, SLOT(propertiesDestroyed())); properties_->show(); } void MainWindow::on_actionOpen_Folder_triggered() { Global::openFolderOf(); } void MainWindow::on_actionQuit_Ctrl_Q_triggered() { actionsOnClose(); Global::debug("See ya next time!"); qApp->exit(0); } void MainWindow::on_actionContents_triggered() { Global::openUrl(HELP_URL); } void MainWindow::on_actionDonate_triggered() { Global::openUrl(DONATE_URL); } void MainWindow::on_actionDownload_triggered() { Global::openUrl("http://melloristudio.com/wallch/1000-HD-Wallpapers"); } void MainWindow::on_actionReport_A_Bug_triggered() { Global::openUrl("https://bugs.launchpad.net/wallpaper-changer/+filebug"); } void MainWindow::on_actionGet_Help_Online_triggered() { Global::openUrl("https://answers.launchpad.net/wallpaper-changer/+addquestion"); } void MainWindow::on_actionWhat_is_my_screen_resolution_triggered() { QMessageBox msgBox;msgBox.setWindowTitle(tr("What is my Screen Resolution")); msgBox.setText(""+tr("Your screen resolution is")+" "+ QString::number(gv.screenWidth)+"x"+ QString::number(gv.screenHeight)+".
"+tr("The number above represents your screen/monitor resolution (In width and height).")); msgBox.setIconPixmap(QIcon(":/icons/Pictures/monitor320x200.png").pixmap(QSize(100,100))); msgBox.setWindowIcon(QIcon(":/icons/Pictures/wallch.png")); msgBox.exec(); } //Dialogs Code void MainWindow::on_actionStatistics_triggered() { if(statisticsShown_){ return; } statisticsShown_=true; statistics_ = new Statistics(this); statistics_->setModal(true); statistics_->setAttribute(Qt::WA_DeleteOnClose); statistics_->setWindowFlags(Qt::Window); connect(statistics_, SIGNAL(destroyed()), this, SLOT(statisticsDestroyed())); statistics_->setWindowFlags(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowCloseButtonHint); statistics_->show(); } void MainWindow::statisticsDestroyed(){ statisticsShown_=false; } void MainWindow::on_actionHistory_triggered() { if(historyShown_){ return; } historyShown_=true; history_ = new History (this); history_->setModal(true); history_->setAttribute(Qt::WA_DeleteOnClose); history_->setWindowFlags(Qt::Window); connect(history_, SIGNAL(destroyed()), this, SLOT(historyDestroyed())); history_->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint | Qt::WindowMaximizeButtonHint); history_->show(); } void MainWindow::historyDestroyed() { historyShown_=false; } void MainWindow::on_action_About_triggered() { if(aboutShown_){ return; } aboutShown_=true; about_ = new About(this); about_->setModal(true); about_->setAttribute(Qt::WA_DeleteOnClose); about_->setWindowFlags(Qt::Window); connect(about_, SIGNAL(destroyed()), this, SLOT(aboutDestroyed())); about_->setWindowFlags(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowCloseButtonHint); about_->show(); } void MainWindow::aboutDestroyed(){ aboutShown_=false; } void MainWindow::on_action_Preferences_triggered() { if(gv.preferencesDialogShown){ return; } gv.preferencesDialogShown=true; preferences_ = new Preferences(this); preferences_->setModal(true); preferences_->setAttribute(Qt::WA_DeleteOnClose); preferences_->setWindowFlags(Qt::Window); connect(preferences_, SIGNAL(destroyed()), this, SLOT(preferencesDestroyed())); connect(preferences_, SIGNAL(changePathsToIcons()), this, SLOT(changePathsToIcons())); connect(preferences_, SIGNAL(changeIconsToPaths()), this, SLOT(changeIconsToPaths())); #ifdef ON_LINUX connect(preferences_, SIGNAL(bindKeySignal(QString)), this, SLOT(bindKey(const QString&))); connect(preferences_, SIGNAL(unbindKeySignal(QString)), this, SLOT(unbindKey(const QString&))); #endif //#ifdef ON_LINUX connect(preferences_, SIGNAL(changeThemeTo(QString)), this, SLOT(changeCurrentThemeTo(const QString&))); connect(preferences_, SIGNAL(changeRandomTime(short)), this, SLOT(random_time_changed(short))); connect(preferences_, SIGNAL(refreshCustomIntervals()), this, SLOT(refreshIntervals())); connect(preferences_, SIGNAL(tvPreviewChanged(bool)), this, SLOT(tvPreview(bool))); #ifdef ON_LINUX connect(preferences_, SIGNAL(unityProgressbarChanged(bool)), this, SLOT(unityProgressbarSetEnabled(bool))); #endif //#ifdef ON_LINUX preferences_->show(); } void MainWindow::preferencesDestroyed(){ gv.preferencesDialogShown=false; } void MainWindow::on_set_desktop_color_clicked() { if(colorsGradientsShown_){ return; } colorsGradientsShown_=true; colorsGradients_ = new ColorsGradients(this); colorsGradients_->setModal(true); colorsGradients_->setAttribute(Qt::WA_DeleteOnClose); colorsGradients_->setWindowFlags(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowCloseButtonHint); connect(colorsGradients_, SIGNAL(destroyed()), this, SLOT(colorsGradientsDestroyed())); connect(colorsGradients_, SIGNAL(updateTv()), this, SLOT(updateScreenLabel())); connect(colorsGradients_, SIGNAL(updateDesktopColor(QString)), this, SLOT(setButtonColor(const QString&))); connect(colorsGradients_, SIGNAL(updateColorButtonSignal(QImage)), this, SLOT(updateColorButton(QImage))); colorsGradients_->show(); } void MainWindow::colorsGradientsDestroyed() { colorsGradientsShown_=false; } void MainWindow::on_potd_viewer_Button_clicked() { if(potdViewerShown_){ return; } potdViewerShown_=true; potdViewer_ = new PotdViewer(this); potdViewer_->setModal(true); potdViewer_->setAttribute(Qt::WA_DeleteOnClose); connect(potdViewer_, SIGNAL(destroyed()), this, SLOT(potdViewerDestroyed())); potdViewer_->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint | Qt::WindowMaximizeButtonHint); potdViewer_->show(); } void MainWindow::potdViewerDestroyed() { potdViewerShown_=false; } void MainWindow::showProperties() { if(propertiesShown_ || !ui->listWidget->currentItem()->isSelected() || ui->stackedWidget->currentIndex()!=0){ return; } QString currentImage; if(gv.iconMode){ if(ui->listWidget->currentItem()->statusTip().isEmpty()){ currentImage=ui->listWidget->currentItem()->toolTip(); } else{ currentImage=ui->listWidget->currentItem()->statusTip(); } } else{ currentImage=ui->listWidget->currentItem()->text(); } if(QImage(currentImage).isNull()) { QMessageBox::warning(this, tr("Properties"), tr("This file maybe doesn't exist or it's not an image. Please perform a check for the file and try again.")); return; } else { propertiesShown_=true; properties_ = new Properties(currentImage, true, ui->listWidget->currentRow(), this); properties_->setModal(true); properties_->setAttribute(Qt::WA_DeleteOnClose); properties_->setWindowFlags(Qt::Window); connect(properties_, SIGNAL(destroyed()), this, SLOT(propertiesDestroyed())); connect(properties_, SIGNAL(requestNext(int)), this, SLOT(sendPropertiesNext(int))); connect(properties_, SIGNAL(requestPrevious(int)), this, SLOT(sendPropertiesPrevious(int))); connect(properties_, SIGNAL(newAverageColor(QString)), this, SLOT(setAverageColor(QString))); connect(this, SIGNAL(givePropertiesRequest(QString, int)), properties_, SLOT(updateEntries(QString, int))); properties_->show(); } } void MainWindow::propertiesDestroyed(){ propertiesShown_=false; } void MainWindow::sendPropertiesNext(int current){ int listCount=ui->listWidget->count(); if(current>=(listCount-1)){ if(listCount){ Q_EMIT givePropertiesRequest(getPathOfListItem(0), 0); } } else { Q_EMIT givePropertiesRequest(getPathOfListItem(current+1), current+1); } } void MainWindow::sendPropertiesPrevious(int current){ int listCount=ui->listWidget->count(); if(current==0){ if(listCount){ Q_EMIT givePropertiesRequest(getPathOfListItem(listCount-1), listCount-1); } } else { Q_EMIT givePropertiesRequest(getPathOfListItem(current-1), current-1); } } void MainWindow::on_include_description_checkBox_clicked(bool checked) { gv.potdIncludeDescription=checked; ui->edit_potd->setEnabled(checked); settings->setValue("potd_include_description", checked); settings->sync(); restartPotdIfRunningAfterSettingChange(); } void MainWindow::on_edit_potd_clicked() { potdPreviewShown_=true; potdPreview_ = new PotdPreview(this); potdPreview_->setModal(true); potdPreview_->setAttribute(Qt::WA_DeleteOnClose); potdPreview_->setWindowFlags(Qt::Window); connect(potdPreview_, SIGNAL(potdPreferencesChanged()), this, SLOT(restartPotdIfRunningAfterSettingChange())); connect(potdPreview_, SIGNAL(destroyed()), this, SLOT(potdPreviewDestroyed())); potdPreview_->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint | Qt::WindowMaximizeButtonHint); potdPreview_->show(); } void MainWindow::potdPreviewDestroyed() { potdPreviewShown_=false; } //functions only to save settings void MainWindow::on_shuffle_images_checkbox_clicked() { settings->setValue("random_images_enabled", ui->shuffle_images_checkbox->isChecked()); } void MainWindow::on_stackedWidget_currentChanged(int page) { settings->setValue("current_page" , page); } void MainWindow::update_website_settings() { gv.websiteWebpageToLoad=ui->website->text(); gv.websiteInterval=ui->website_slider->value(); gv.websiteCropEnabled=ui->website_crop_checkbox->isChecked(); settings->setValue("website", gv.websiteWebpageToLoad); settings->setValue("website_interval", gv.websiteInterval); settings->setValue("website_crop", gv.websiteCropEnabled); settings->setValue("website_login", ui->add_login_details->isChecked()); settings->setValue("website_username", ui->username->text()); settings->setValue("website_password", base64Encode(ui->password->text())); settings->setValue("website_final_webpage", ui->final_webpage->text()); settings->setValue("website_redirect", ui->redirect_checkBox->isChecked()); } void MainWindow::on_donateButton_clicked() { Global::openUrl(DONATE_URL); } void MainWindow::on_melloristudio_link_label_linkActivated(const QString &link) { Global::openUrl(link); } wallch-4.0/src/customwebpage.h0000644000175000017500000000252312301477401015101 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CUSTOMWEBPAGE_H #define CUSTOMWEBPAGE_H #define QT_NO_KEYWORDS #include class CustomWebPage : public QWebPage { protected: virtual QString chooseFile(QWebFrame *, const QString&) { return QString(); } virtual void javaScriptAlert (QWebFrame*, const QString &) {} virtual bool javaScriptConfirm(QWebFrame *, const QString &) { return false; } virtual bool javaScriptPrompt(QWebFrame *, const QString &, const QString &, QString *) { return false; } }; #endif // CUSTOMWEBPAGE_H wallch-4.0/src/history.cpp0000644000175000017500000002741012301477401014272 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #define CUSTOM_ENTRY_COLOR 59, 89, 152 #include "history.h" #include "ui_history.h" #include "glob.h" #include #include #include #include #include #include #include History::History(QWidget *parent) : QDialog(parent), ui(new Ui::history) { propertiesShown_=false; ui->setupUi(this); readHistoryFiles(); (void) new QShortcut(Qt::Key_Return, this, SLOT(on_info_doubleClicked())); } History::~History() { delete ui; } void History::on_closeButton_clicked() { this->close(); } void History::readHistoryFiles(){ QSettings historySettings(HISTORY_SETTINGS); int totalWallpapers=0; QStringList years = historySettings.childGroups(); Q_FOREACH (QString year, years) { historySettings.beginGroup(year); QStringList months = historySettings.childGroups(); Q_FOREACH (QString month, months) { //add top level item, eg. December (2014) QTreeWidgetItem *month_year_item = new QTreeWidgetItem; month_year_item->setText(0, QDate::longMonthName(month.toInt())+" ("+year+")"); month_year_item->setData(0,12, year); month_year_item->setData(1,12, month); ui->treeWidget->addTopLevelItem(month_year_item); historySettings.beginGroup(month); QStringList days = historySettings.childGroups(); int index=0; Q_FOREACH (QString day, days) { //add day of month child (1-31) QTreeWidgetItem *day_item = new QTreeWidgetItem; if(day.toInt()<10){ day_item->setText(0, day.right(1)); } else{ day_item->setText(0, day); } ui->treeWidget->topLevelItem(ui->treeWidget->topLevelItemCount()-1)->insertChild(index, day_item); index++; totalWallpapers+=historySettings.beginReadArray(day); historySettings.endArray(); } historySettings.endGroup(); } historySettings.endGroup(); } ui->treeWidget->setHeaderLabel(tr("History Entries")+" ("+QString::number(totalWallpapers)+")"); } void History::on_treeWidget_itemClicked(QTreeWidgetItem* item) { ui->info->clear(); QSettings historySettings(HISTORY_SETTINGS); if(item->childCount()>0) {//A parent item has been selected, loop through their children and output to the listwidget their input text QFont bold; bold.setBold(true); //this fond will be used to color the days, where below of each, there will be the images of each one historySettings.beginGroup(item->data(0,12).toString()); historySettings.beginGroup(item->data(1,12).toString()); QStringList days = historySettings.childGroups(); Q_FOREACH (QString day, days) { //add days of month(0-31) QListWidgetItem *day_item = new QListWidgetItem; day_item->setFont(bold); day_item->setText(day); ui->info->addItem(day_item); int size=historySettings.beginReadArray(day); for(int i=0; size>i; i++) { historySettings.setArrayIndex(i); addHistoryEntry(historySettings.value("time").toString(), historySettings.value("path").toString(), historySettings.value("type").toInt()); } historySettings.endArray(); } historySettings.endGroup(); historySettings.endGroup(); } else {//a child has been selected... output to the text of this child to the listwidget historySettings.beginGroup(item->parent()->data(0,12).toString()); historySettings.beginGroup(item->parent()->data(1,12).toString()); int size=historySettings.beginReadArray(numberWithLeadingZero(item->text(0))); for(int j=0; size>j; j++) { historySettings.setArrayIndex(j); addHistoryEntry(historySettings.value("time").toString(), historySettings.value("path").toString(), historySettings.value("type").toInt()); } historySettings.endArray(); historySettings.endGroup(); historySettings.endGroup(); } } void History::addHistoryEntry(QString time, QString path, short type){ QListWidgetItem *item = new QListWidgetItem; if(type==1) { item->setData(11, path); item->setData(12, "file"); item->setText(time+" "+path); if(QFile::exists(path)){ item->setToolTip(""); } else { item->setToolTip(tr("This image doesn't seem to exist!")); QFont font; font.setStrikeOut(true); item->setFont(font); } } else if(type!=0) { item->setToolTip(path); item->setForeground(QColor::fromRgb(CUSTOM_ENTRY_COLOR)); if(type==2) { item->setText(time+" "+tr("Live Earth Image")); item->setData(12, "link"); } else if(type==3) { item->setText(time+" "+tr("Picture Of The Day Image")); item->setData(12, "link"); } else if(type==4) { item->setText(time+" "+tr("Wallpaper Clock Image")); item->setData(12, "clock"); } else if(type==5) { item->setText(time+" "+tr("Live Website Image")); item->setData(12, "link"); } } ui->info->addItem(item); } void History::on_info_customContextMenuRequested() { if (ui->info->count() > 0){ if(ui->info->currentIndex().isValid() && ui->info->currentItem()->isSelected() && ui->info->currentItem()->text().count()>2) { infoMenu_ = new QMenu(this); QString data=ui->info->currentItem()->data(12).toString(); if(data=="file") { if(!QFile(ui->info->currentItem()->data(11).toString()).exists()){ return; } infoMenu_->addAction(tr("Open Folder"),this,SLOT(openfolder())); infoMenu_->addAction(tr("Copy path to clipboard"), this, SLOT(copypath())); infoMenu_->addAction(tr("Properties"),this,SLOT(showprop())); } else if(data=="link") { infoMenu_->addAction(tr("Launch in Browser"), this, SLOT(launch_in_browser())); infoMenu_->addAction(tr("Copy link to clipboard"), this, SLOT(copylink())); } else{ return; } infoMenu_->popup(MENU_POPUP_POS); } } } void History::openfolder(){ if(ui->info->currentItem()->isSelected()){ Global::openFolderOf(ui->info->currentItem()->data(11).toString()); } } void History::copypath(){ if(ui->info->currentItem()->isSelected()){ QApplication::clipboard()->setText(ui->info->currentItem()->data(11).toString()); } } void History::showprop(){ if(propertiesShown_ || !ui->info->currentItem()->isSelected()){ return; } QString image_file=ui->info->currentItem()->data(11).toString(); if(!QFile::exists(image_file) || QImage(image_file).isNull()) { QMessageBox::warning(this, tr("Properties"), tr("This file maybe doesn't exist or it's not an image. Please perform a check for the file and try again.")); return; } propertiesShown_=true; historyProperties_ = new Properties(image_file, false, 0, this); historyProperties_->setModal(true); historyProperties_->setAttribute(Qt::WA_DeleteOnClose); connect(historyProperties_, SIGNAL(destroyed()), this, SLOT(historyPropertiesDestroyed())); historyProperties_->show(); } void History::historyPropertiesDestroyed(){ propertiesShown_=false; } void History::launch_in_browser(){ if((ui->info->currentItem()->isSelected() || ui->info->currentItem()->toolTip().isEmpty()) && !QDesktopServices::openUrl(QUrl(ui->info->currentItem()->toolTip()))){ Global::error("I probably could not show the image to your browser!"); } } void History::copylink(){ if(ui->info->currentItem()->isSelected()){ QApplication::clipboard()->setText(ui->info->currentItem()->toolTip()); } } void History::on_info_doubleClicked() { if (ui->info->count() > 0){ if(ui->info->currentIndex().isValid() && ui->info->currentItem()->isSelected() && ui->info->currentItem()->text().count()>2) { QString type=ui->info->currentItem()->data(12).toString(); if(type=="file") { if(!QFile(ui->info->currentItem()->data(11).toString()).exists()){ return; } if(!QDesktopServices::openUrl(QUrl("file:///"+ui->info->currentItem()->data(11).toString()))){ Global::error("I probably could not open "+ui->info->currentItem()->data(12).toString()); } } else if (type=="link"){ launch_in_browser(); } } } } void History::on_remove_history_clicked() { QSettings historySettings(HISTORY_SETTINGS); historySettings.clear(); historySettings.sync(); ui->treeWidget->clear(); ui->info->clear(); ui->treeWidget->setHeaderLabel(tr("History Entries")+" (0)"); } void History::on_treeWidget_customContextMenuRequested() { treeWidgetMenu_ = new QMenu(this); treeWidgetMenu_->addAction(tr("Remove this entry"),this,SLOT(remove_history_entry())); if(!ui->treeWidget->currentIndex().isValid() || !ui->treeWidget->currentItem()->isSelected()) { treeWidgetMenu_->actions().at(0)->setEnabled(false); } treeWidgetMenu_->popup(MENU_POPUP_POS); } void History::remove_history_entry(){ QSettings historySettings(HISTORY_SETTINGS); if(ui->treeWidget->currentItem()->childCount()>=1){ //a parent has been selected for deletion historySettings.remove(ui->treeWidget->currentItem()->data(0,12).toString()+"/"+ui->treeWidget->currentItem()->data(1,12).toString()); } else if(ui->treeWidget->currentItem()->parent()->childCount()==1){ //a child item has been selected for deletion, it is the only child so delete also the parent historySettings.remove(ui->treeWidget->currentItem()->parent()->data(0,12).toString()+"/"+ui->treeWidget->currentItem()->parent()->data(1,12).toString()); } else { //a child item has been selected for deletion historySettings.remove(ui->treeWidget->currentItem()->parent()->data(0,12).toString()+"/"+ui->treeWidget->currentItem()->parent()->data(1,12).toString()+"/"+numberWithLeadingZero(ui->treeWidget->currentItem()->text(0))); } ui->treeWidget->clear(); readHistoryFiles(); ui->info->clear(); } QString History::numberWithLeadingZero(QString number) { if(number.toInt() < 10){ return "0"+number; } else{ return number; } } wallch-4.0/src/Pictures/0000755000175000017500000000000012301477401013657 5ustar alexalexwallch-4.0/src/Pictures/list-add.svg0000644000175000017500000000355012301477401016104 0ustar alexalex wallch-4.0/src/Pictures/ambiance_checked.png0000644000175000017500000000033212301477401017570 0ustar alexalexPNG  IHDRAMbKGD pHYs  tIME `9gIDATe P g)_Ph>yee{k]PkD9suTg5[oF]n̔Zuxr9n>=`kldJ!BzT̊Hٿ?^?tXIENDB`wallch-4.0/src/Pictures/page_1_earth.png0000644000175000017500000011374712301477401016721 0ustar alexalexPNG  IHDRZ= IDATxw|W3[ZlI;F4HB \^̥BB$!'BSn]ZiecVlg?̜9̜yyN8O~pj\, @=PnqH=o %>IX$I \I% ,1GyX6yuAo3K]%B'܌^|%cO"M;'kEQ3;_9^Qk;2::0;v06!ތC#1jUR"W[2 {ڽgDn۰z[OId'~4q/G2Gw&Zgkvm\ FSjL"݄ނC5 >,Oy۩޼J[z$я~+88udΑ=tXa݃cN@_M}2,~zlqzG5Y\zUzuξ=fP*gTfm/5L\wʋنw{y}'$"qՀppcղ #e9-)Sf&*NX]ըWʂh={C:- $fAS@ 둝\tZZӏrtpa7(V! 2p48<dYBF6avve=ޚ\&RR31w>US\9ÔH'A^+W Ӻ{wCCgkLIOR=,u.Ży#:,*)g1}{ Y.S PБ8̓vlz}o$XaJޒg{>[wһA$͗:z$>grUq[8Jό=yKU=k^x>ٚч1`&|ke$: : sbbޒ=њb+{׿ {I:Ы4dy!&o4%e+/W/F_$Bqi{[*k7k:{RQbU/*G1LKRgvɅ<-Ψ#WVT_{w]#'Do?{ dz{-O1A2H W uy˹f/шYq "bʤB$'Af.]P\@+1[5cr2hoP ʯ`v^2*Rr'2΢zMd >^\~]|~rON]zf A:gK&Y+dҏP"q+ ?Sa[3n*CTs?}dzַ7$KNx?">3*>:u Օ|hԕ~>Y98I|}KEY[v\6[EY* S%"gVͩU%i}S!ѡL]FGS t^%yjix_1CT ux,<چw3l9Eoۮ(DGCA,1wYNnQ[aPCqbq2@t+t}Ǽzۚ6s~njsn|F62*.ۮݯeE땞׀5A`n35 N5Vp>=ꢠfi-\>!&u,=5k͎p``-jQO-FՅ)[{?DU3`}_M?L[HŕWRiqz,hi%Gڶ{u_o_¿/c,=OWIsh4}HM"t J3XIL;=-x폼H)grhƳ=C:G8`|!{{G4|qs2yluHfюATXP~Sj/]olW}u{ HHB !PU >\R:jsN`XBocBH⠣((?r9bX9qmk=v-98! +?K:c "61HߖNѵߋѿ-Om+ʪeI(WæwP ZΨ*oQg-y&ĉp\'A{&G #>QРSe3D1ڮ(^i)OSey*j|}g8SDAJP3|K_GoI֩[wuWcQ $ˀ{5%%]=kZp>ņ*Vt!*1~K[$9пV!~$WPnҕL+:M+i8<#hE+Wokߎyw=*SDaj]O1 8 :ZyhTzN"0<Ĉ8kxҏ̙ q%^v>MCZlM P9u_${rxG܍̇=nީ$0BK: ڞ&o>zUC&*0;zUv~ª|wƧVD7k 7^d2}ȴ27ךt:rte|aw,}X3@[4|-pASReHK&~Ƿb7=P=//}ѯpͫșšxewLQϢ+Y{߯~V'(-qztkzRt%SJEYJw.oj-y T'DfIvo;B[eJ {]#;YXK,nΑVt:4xMXGzȤS^9dTUs~M3B* SW鴚um[v\Uy{'-?O-HɱC%Φcuш:_Oy;B_gb޲1yc9ǰ}}rtCzFIV40|o6,Κč.^:idڇwn_I չ[; 7h {zC)_ɠ==4*_y!vt]PWthn|~տl?"GnKz; ;dד⬩x$;Cu(5L&i?`;ʺlHc5>KL*8Пo0H?hkeml~<riq͕w=O>D_zz`bOA7Yg!vt=ѴܲuʻǤp{Ѫ hKq6cjy<33X}jyZf~wuyu,ysv9 y^;GW㉱X&=s7 }̳{nfS~=/f}%M+XAQdw=;G=Dmrڇ+ϙ³D<d/TTb4 FgZTLѴ {>ho7PUQWϒ+zj|8G7_޷OÑd/mCgey/T#R 'uhCףS&%ً <&vu=:o13K.aAu,ӲV't[r.u+8ZRs;+>^c@)-MFw>LMޢ<*MďG"C3ϧż +|7)}o3L˴s}u6LauH)6}yg{~ˏo_&{B}{bX%a㌓"z[jF [Sή~U 9*SG=TZ*s3"zz9>V.򖲼.=}4rK{%7-CWP3oLCl#^Ǽrtk9aWKN&CObR3gV+=o!R!>ÎnK_sk7'>D[^!x,~܎lPXd@WE)dOZh%GxwY+lds&o)m- wG5;Ɉ5F\ W\J" 9=ɤ0fWsd`]tFa>yE#FoDQ?b,Kyt*#1ZXk|hzFR3RF|CvgOw숕 '8e/i#|-Qx.޾h09x1z$}DTn甚/W3T.Pr1}(3+8uP=& CCO +?Oy 4>Ճ B[*be,_W0`=pŬ4 ٚ|q;V)/"I^*sg}fb ҽ\t?p(Q?VZBHx7 -#ˇk="I^j  ߄;سn]R1EkIv#fo3N2#0 zoqUv%{mD3-pܥ%n̿r/2~utY:}9k3p[,((pP&%m I߯at=R;:Hpr"2qjQš;olwy72ux$;-9ҷdkKq=kԺM[͂vSSW~Z@ᔉ2`_`kloml [[QWT$ P3: { cQ?\})V@Isq ^m/j+mNZʸѭYkwq5.Ý , !&8=32>3Go dIt mNXɨ 7.yCĚkv=RnX jBxzu}&g0r@,[3qUs1ڰ#=BtlvҜi3'}{Lw?KW9dVi`}ϛ3.ٴ.xNå%߿ Ipe*9`W?V-up#QP30ԚZ(ʮgaQyg⒬ ֧9.1hpz-ov"A }AL8,^,pN?W6vEw, $e2]vbeK㇎+drqɬ? ].^d=5@V.촲Kvteua.S 8[|DnXϘFy+cGlj#nca͍ <"]]; qzGhYQc'ꧮ,N7Wo@S:f1Ҙ2|OkH:dKf_JMaGrY}̬l}1[SH ڢNbJn~ Uq1s.gA͵,,5|6x~ofх=ši977԰bҗ)ήgkb^".,]!]H\]9i7J4rte4[yޏјq_exqOxћY@stÞ)V d16ߞuenjkފk|6,]1S.Tsv,KT/$?Ch+ t\ڇ6̜$o&xLz#gOgd?CvV۽VvE9|KxSHE\T/n6 _C}̾**Qˠ!{;*QEzm탾Uֺf)WJ˻[3>Q_f(،U9jyZ̝6V_%Y1{,E fШyOQ7e [P:,p{mdiE5ûW3 ZMt+wT߆޿K[9̢PKiC1vSRz6VO{*Oc~Le<P?Jp+gA${&΂(Utl X\4t{-^gkt,io$gzMY|ZMۄa[%2ބXUO1)0rL 6qjkTٜ;!Js:M3290Ff]FeʮYVwG :Q0|I,Ο0#{hx%*ACMg#uG'CO}ydkx9m!8Q("a'$\hHy9얛p-4Ep+/C}68÷0Ѧ$ Ȥ3lE-ZL3LjfrJT]Og'T-'h\QITLQW̊(͝ɬUd(ʞB})5cY֢[ zM>5K‹}iQP3`iP^UytO eYbqMT WW΂U̩7hU}tԢŰ3.G$c^pMwyu>Tcy} ;Z3y~e);=-r-xm1PLEw8;ѕՌXDuy,hZ:B_}/GzދT/*b':N~|#2-#k~ᵡ$7Ofɑ< cE^V‚mhwY޶g0==[DEy E%6P2" F7(|:b |q2:1ΡZo)ہ??qjU_@S {mcn:_Ne"Ȱ:sgH[rț Ck柳zuF}2눂+͊AF 綾~ɪ%StOT\#(],n7g *sb+p!k"F>LI22E w+/ {C/O+Jmp&KK;qxF0Y[V!4v `LDw+S*)c,ChIz+ 7U+),Lw_4,ˬoz8l+I@x:|_ Ҫsx,t3IB2F[=.zuZaw ES *q{FOHcXyEcMDvqlS>xDˆdŨ+GŽBRe<6nO2KoeZ>y]z#vs}#*Lg:(z듐OKOp)v}C=RW|:unPV2P3~K#VF])7=HmtX G` HWN6NGat @-j)ɝMS$u=BIER8S }<}[3i?)X' ? NW?%KCuro^|a{WU_}ݍiCMwQ%0Uq'K" `KC4S\Wj:eϢ(g֘'Q9BJ_,=4ɣhIjٴI]t[ " W; 8(t[i~8üv}/꽹<\^[L9$:_~v 7B o9ߺ쌨ȒDZDDᇙ5t+o))28qI GHw2.m0`k@d,l˜ [~$F4SQ D |v^?huPz&>wMT|[=WW:3$uu=Xwx ZawV|X\]l:#?Flm4ch=Y>HӞnL^InrWߝp7U>zrk^Ir֞:JNHu -H[SZ4'-G&FJ.%{N␉OU@r8o6mv)͸u  kޕ░>@,,7,@P0D눖0L>Lo8E( XoHD%l{iN?y%W.6=CMR>80-qKNƻy`srw~R@JD% {hߋ > o U gؑ\i'ɂ_@Si9k<†Rx>hlrgbbs*Yqy`|. rS4od_+hWvڷqԘt_=YLdwg[O@3LNbDƝUK3 ZQȘ,hWT7#L>y&im`s̝p k}%T j:Խh"UzBP3 kEXg]w$C &$-#]󞌷fKj$[<_M^_1w,Cr#=hوVz0JvٓL(YH~vmvVA =; 4|2N)y"G ks{lk_ەeSATV,8 }NJy8OĤMɒ6UGʉg|&/櫓$WMyPѯK!˾ 7qyt}4wRDҍ@ffaT+Ivɑo?}+90꫑h 5 VF݃;?o<]ȄIhLJfO: e$3[c rPon\"ABs #Zu=Ⱦ!13 Y]G'-/.0VWٺ3c{ڕpO9ޢ哕 (LVu%·ͩOR>#@ɡ8g* }#wM&lB~[L۔A2Ah |Y1!N^zLHr8AdXX![WUNBgG ar%ԖQYX}eEH C嫿4?MwQb&ni D yUy&_@^v^+e$|X">f@Π/R~YqV]$ࡤˊ~хd7B:"`$bFǪSx+"y赅nCetŨ*zM>E+/d0Hxc-TVmdRe4 1b5}q&>d%'Dts~FаnW& C7ۺ2^FV^-W q q!clRCHȼT*Ӫ`˯23f>Au'U^/ǨsڌP_1?IJ Zq-:M~$Yv1h9L߰'9 6 O6̤OuʋpLaG;}2ߌ FDt_vp`?-(t`q jvI~b1 Z+񊢖2FMlh.WT;/~^[ތkcvsY;_Ǩ|8ץiI ꄄ]3sإ2K.uQy3*/ k}vXy{b.kY }=c0n,]hӾtN3CJ?CIjA,mkq䧉k1乴`1}C;+WJ!KcL+Y:1#Q 4[.rϲ.&śY ioyb:b؃ %1{yslcX2FC-g>B]4[vrAՅ0{3o butj6N^%Grd¯ ~͎J.Xvz!L7Ɲ =6] . 䍕t9݃b[qK@bm-W=*=aQYjWuGCVU;Cۤ+pyF$Ɏ3Li'}NCx%'*QNܴ{_!BBd ɝݖ akSW$9[׳x#u7Yv)k+#xGpLXoTҘ+ +{)ʝ,{AT1kQM*)WQR,,§ꝏK.@an_vNڛ~oܬb]ze@3xFG߈iMؘ,Ue䦥e:c7_8ӴCX9mGycxP84\ŦuE2MPL4#F*<2D q^vN3 wVG;G;}ZYr?"ni,M)njƭ(&KXmv-赅,D&st,l:r%{OԔ$_ᩱEYt'q/*3)K3A`Vp{|r88؜Uz4ŤUdiK3:i (/޸dBY)q_Jꏁ z7YF$Ժ di QpBkN j>2ދA sB cNo˟ˮops졭MjJ.u$Ki6&0o=gmA,fLcV_RtTy&R(i·Jbz㔔dž+TRpjGLGB%Krk {IȄ>WBWV47Tn[ We~g ܇+)"٦uA6!4H^wDWG0 ZJB 26&UB|{q :w? q䋼:HHlG#W$2zmb L|޼7ֳḼ^o|zϡÛ|ZڭXp!0NB+M"mE?.H"n׉,h \n jG0/{*g_THf]Cü {/p Ϣ2䯹I|Tg)3 [U3LU5Z]ab7J;*yXxɍ/ŎKYFQ%)_u#rFˎ-] #yvSvcM*ٕgE(B>6gߏ+I,b<* oW[ǴFVV9{*zbάl*r }W ثKD[.ЄIĹLFCkȚ~T a$O,^F&po,] e$~ \ 58 ?o`Әwбۻi~I9I$G\z=uKz7~>dpeCu8.Y BPt|$f$)4oI[xT㹤s@-L,m Z1D̾o~tzŗg>y[hGlJ {* x$(ё&LCȣ"0O_A'3ڔjqG 'yc"Xsg3r ݋*$x>aDf"Jq%tHD^%OR~"zLˎ1O]qbìϲ mYo%Y%ϊ/BxkUH`CoC&ҢAAddQ)4ɥcݓ{S>:nq zc^Fk.qe)dd_sgAG!ςrRU P9%~F̺{œaABYpɇޏ͐ %Z"g]<'_2`ϕ4c/4|[gX}5d)h _3}F0lUa݃yS ϟkӖ$">-M% Xc%UI6 c^IWhTd b7)B _?;,1+cOoژd[p5D$ ~e*A@%D/m|{:F[<'##G`!/wVV%u7DƃIʎ&[n2DLK&F^įP7[ێKqGܪ8q&2|v|ݗ$IEx{ؼ_.UY 8^Ý{{gfdhVTb|!j)ѧė8䩉cb0(0 "yj L@M޾}3]QU{>ӽ N߳kٿZVZi2D,tw'03quT୳ry"`ZzjG,yfUoI=;WqdIޟR .o N3v ,1f31X:M4B"~)}#? Pu?jT>V)6V3qƗ%BȳKhvFP ~a[塜o iǮw\gvެT( aཬ JwopeYhM/<lL`bvV0K5(S*LҌT|2K>/M`#\ T3CyW0|95_]&`C`9r#5o v2evg-H#n&j{6Wb$>.hҲ<cK}$U^cRjs\0Z7LVw[3(TJ x7+v֭S,}Y^kypjʞG狳'zdqR^ $C?}Q3j`@/ $-`!^PFH@u_O\8v!:%†oǖSG^Q;YtPfp}-crHm?.n+B׼9JRu1 -`f^#M)'ʔyNGW.Y,r>@sXcE,,< !஭Cf ew``E*Dss7o8_<{l=5Njɏ L73TOd4j H;X3rP|cȓKn2V29e܌PUKQ(vjBM7+;V?*[gtK%WޏvTP@imT~`O !i!&{`Trqo^8#@n%6ޓQ,=sO<n}[|2YހO"::  (* 'Db?TGWaE3}yz8Ճ޽G+1PB1<BucAӀ#_#Dez,_`M;p։CrO??hż\=]zj9lK,U p+8\=7 C.?w 9jPsظ{- &8;]16J:ٽ02c=Q*DOx.fg4s92ʏ @Z|eՙǬ'.>`Z2/>e);dd {'&5vM} ;t^In*QӆMJv r e"/\Oy?R}a_ϰ]&جbrMp*IG{:;7Fm>B.]0$*l:oaדxgg&I-^:XVyfoݬdKo׿'pQEm*k"ĤJv_flhҞ -ַ뭯r7%}$>Cï܊R)Wd*N*ӈ)G _qU 9(>/< ;9Rݑpc2O/A~3^(-[p%Yڡuyk @* $Zݓ>\*eUtp @9\b px=PX5vxB#2zD)_\0ot/Ðήu^BpLCǽ&l|ӿ+y"iE:I]R;uS(} w5xY6&%*W 52~[OX򝐞z,ax@{cɄx Jy2Pw5X鑶2Ʒ51O߆d ,##V;¼|?::cJ-4'<= [$OXdl]j)`9{B_$?8|==zqDЧlgbݧinѺ I.(x/\w{j2%:odNOO'XŵPҜ))=(`'"o/88xō*<Ξ fU& D.<Эq`O_lWc$ JCEY5IK "HR@4`[Vb/=ZdL cP\c@ gs GZvQ"Xgc%Ҁн4ЎޜFsT5zkRR}f?}HΓ@y)J1G)@.WT;R'EwL4y')3s5WR8~fynnIkҋք2]ǡ@;*&w|e=q|^Yb=\P3C@>4rYA`:I` ߹=;=!x*yx2ˈoq'~]{0;W^Iٶ`/ؓGVX8vݥ::%s먐  IW?~ ^an5iSoϚQ8Vk'th pr<|\%-K~Hl7%;a ~I<(tlb“/;[Y>b@./LR=o *xS;& ~>űm`..s5݂dGv2* H-L6xǔ':o[>͜@3C^ߺCgJ[qaO03`]ٽ / ^>!.,N3ŖQekg#vMI ?n^z{v""V0 &!fjy*?q򅷘ņ,T1_ECYO[:͠Z#{9םO̻Pz xZi <NfS m8xב:#ŤpӤ/5 AcXqhP_Լ,ppm B%U(餖Wy`1s:r6CgFGF1g`[ȩȰP+*Uec`KG丨UDž+sc;Π񧿂 mŲޥʏo>*LՅ \/o䝝 s10tr py {v݉ji_\f1bo|{\_oԔ=L,`5ޔ5_2 ~_gtw,=5Cyi5oLBeb-sViM++P )rp\4(|G(EzBi~5b˕fav.ABg~p`طp{TG$?,nnu3~.tsQ\")#Ƕj|y9_o _cʴ|L잼 s#._PEq@c~g V Hຜ{%,;\}zS(aP_Fv" ato7p^1 ]y'RT<wEk.超(fublpp.,}i<۾ry+V1zN ٖӒ▐"NF~U~KiM-%&WZfҜx9+ls~m{͘&, r`p9`kND֠B<(ere#0qWBY5%6cqz˿2,[avW'C=%ޘ/n2 vc,>euna{00 -`}k޺=$5diO:˴=Snd,tcHo@~n< *,RjB`J˹^N )͹j:mSעW[w럝-)1Ws.P,y=ZO[%V>myxt"PitK2z`ȓ,G85u.Go:N]As#+׉Wvf{ 4ǙT~!EA}ȿ{ރٹgCCT#FtA23PFf( C+O{k_~%6H@+$9\õ\WamIL[%9c"T]"!}]Q?BuTc8F00:]݋ 3{oMzT}>%Vw?|#rĞ0M[A7չt:zLCpql'qo b2,_Z%I9w I&5J4ʪ4%3Yn[pG^ꪃI}5MU\1F³<#.ȏ>F!`RK`])KzZ-9M%5OR'~ fw /xV `ok9xRۛ?SpB ª-7݃+d\ܞdko7OM\Ow9ҙ r4]m`s[yY몵w@#(sF;x?z`d) +8v>TR,VRmIԪPf#W!wzNnD6g^ٶ ́-0ΕOA52m;AvԪ`bNm~ڠA S3ͳqQ%rj><)M+.ugavr( d PF: ?5uVh'/M^AuΝ}3San(-< ;7fk_z;xc&ol̬3oO;?;bl$,TWX/@:.TŵjڌyȰ=?wY칐{@R уDtdNuko9]98}DØw߄҃w=hb= (m04=fyql`oiw|dd\].DGw?؉Xs_?y-?ۼn'`Z}-8u. d2r8..'I5HA9mq82XL:0 xrf=ad>X'VgsH8 {02 _IF85>G c? o7 j}PVRQxe5o|]r]%)mAs-!Gn/u0> Z'T#,ec/< A`*$A%,++,Ӗ`cXyؿ] VhVC;MT{F=0bBkL`Y)Lޤ"R.ͫq9\rT8K+=ʉFfH3a̛&Ư% zn&,(|a-z꓾|I$ ǙlW`ʛdIMҨQ0j7̥$̮3pz_|M/ѡrAcru\\\1hg19ŏ7CRhL t1R.Cެ]^2\U'}=+^S}:NFks]1hI{_Yxmŭ %_4ނEz:@u[p9P "iq=o8WIl%E娨 sqbf 9pi:ܔD|&SKuٹA؏H>F_azXfiTu] jTo_D'q S?N4ùRمT+.Õ/.\MMU^j-u:+tC `j&G8_<PڄM n8 _nԙ 8)A޺Y=pm4/չ:?w.'5ʿJ-@hGY )1_YpUx!F>.|@y;zN'Xe=Y9x}|35 R<Wg4ҕow Nm}BxVwWIwsԶUҞr?GG{絩%/#!*C KʓHg^Ssd"@e7$z4IJ8(4JVG"Vq@tSbQÅjO| PF8knqUCd^EGH %NN\F/O{GW1Z/`,@k G1<9cigLO;B i|KR Css]Twq=urT#y#p$cC\ٖrKysXD$`@Յvr=G[ kB;Clzzώ#MHfQ?8w1c]DGjtC4p]p, xBenzТўgߒ@K3/>@ⱏJƥjhH {(Rsbbs!wWO]i &v i[R,j|V m(-<gn/ 8'g = oo5qf ~̽^ 0i1ߊ};9w! Q(M?dW&p @ՙ 3q鋧{./}huH" ʸ'TWI^r8J[DV`3uS)HFᐒYDz`9ڶg.\j "m=I7w4EuTIg+yNĽ8&̍ܭxu/LckwXT*{{WQ)|&{!jj|qex kv"h%JtG'62R4ʋst8);:L:MpxDm^h44;qq(tn@g 亗B f1r̛lK17;T<_0Ʒ} չEne K5,8-fC  #}γ? t#7w+lIc ` -U zb[J`2T$}pSJ?7%p̀=g͢5<=gca>Ts5eAyz 8*s{|5^jrS:Ә(߃;\G>,~>yԠTHsQO@uUoqhׅ,G9`P6Y ̕~ 1X\6IUDZH_!iI00bxc nx( 5@@CހwW\,z5A8Uk 0%KݠU)jJ˜.Tq"!J4eeL0Uv湱Dr˪C(TܰSS 'J]Tg ص ]}E>@k {kKZbw!p`7@Jg;: kρ LY\WdS\LFUWZ3Ε W  dwCΒ!Pq، \_/@dOY'egɭx& g.~eԀv0w`]:] DO?zٰs10| -+PRzVl.'1ZB cj2Df[ EBѶБЙБљёQP<9un:BJk7ZcTuPuPqpGEjP k.(͇Ju^{;Y'fu)O.vcͱoŠr3YwurVi%HpI _6SpvrC3Uv]]#@F$!5mSԎ6KG\le+=Y!y G_(:>Pu ,XWNi5ۏ6մǻ/D>_ʘ rekBRxjb~X)W*+A^hQN9Bβ%(Z['6^GuEow* x<7.ʺygiWyd +> 7k\&%-r *CPuX*Hbm!o=*  ?´g"kL'YZJ(w{zi"QUh 5_ړ>/qj/B;:LU\9%Eʅ mzYP-i5_例*|D¤}]m'0Ӧg'cۯl PҀP'+7S5ܻ?θdǦ ʭ 4qGcPN3o@miU2\G•s2k(j=?p c-"Ȳe!ŠɇP݅sӰ֤2|[9/10L'0}:RB":);jS3UMГlAJuTK|3r੸NJ_"u?Zgx(Y賍U7+_ @.mЇ(ʳԽ\TrEEr#9o"Uo[i/cy:R9 m0]|T۵'bRͥ B,g/}g7n@;B8@d.kTlGGuj^:PR^wV%=Ü燒f^*NsXNY-{.w51^tjb0rsx_f yi7>h}>:NNc3c]Kš$ջ٠Ҙ}JĺofF@Uue>|Q\8o*{p`1ٹR.y{X_ا~??6p>A`oL*Ï.;Ձ P SdBӘ*7A#:N4ᇡ:szq0.=ȩ#>Tr*xO jkOy)3xۀ"}w*s0;ٽ'p[zk15}وɻw/1?].HCĔkL It8APt ktT;ȗ`5Ї78r܌Gb2]OhL|^ 3Xi]?rRO3OP=RƼu, wa)u s]oއPS.L 󏡫(瘘Ŏ10TDPQa(?rMŒD)I1+@']xTMm/RxJm_Di0RڬB:;!<<ۻncQj}WB 4 1.W@*ZH+q%{3@mAjZ%0m}mJY}hݦK;RM~>(y_s {=-?/pmw .Ⱦ{,A/ckGɬ_l{rwCLEE<\&^d6Y[o֑#H,vso~m 7Uv(JeRj6#^?$ܵ@ҚPiJ͇ۡ'ٞ=/w" wAq&AQPUۗW,?;yCTd<4ʱFKaJxZ1a;xh޲x;{]hTx.Qr]ˌk壔ҷbKxM+ lDocg\ xA)o.EZk1 UJw i CLkB*bA Q>ݿC m`B[פ؄ G_ :/D'N;{>P$:__&&<,ޤ,^XgǓOh-Uo/[cUǔ4$8lZM?xEhO~G- r Mh v W~=:Z t]<$5^v?ʫo2@q!NŇ+W@`[S6I)+UU.22XE Tqup@TL_|@EW[D}YX$@o>Ju_徚^q9*\V%VM{G6[Wաjכ.ZP*ބ߾ٹy u%nURl0 Л|kLTQ[qaq [ 3MٽnZ=Z x½ n\Iڑ,m/`>:U! S}j=P:JvƎJmKImj+S/Z'tgE [ 3nD%;~]<p+_OLIoTy B~#@wwMy S лB­sI_--^,ws?X'E:ʷ WVヒ]>D/sz>^q A{:ux/^Z|"b^q/MzGbѳb:Z) >'3/==mޝN;.-Lt[&$  R;zO Hcq&"}r43+>IovYЛ_tu܊z%tod(têS d"eX +ai%hlTD9 W#mƁch5nN^qO[5:G7|[^+':x2HFejGFHo^>/斷F\$k94> * 88N 34G\ҺcjؓMx$]R[`v!=RMUNX~Q$Y|5`g-D4n'b'"%滷޴dU@UqUוx:*Z*Og$a=wpTv.6 6C҉#8# Fuf0]_\|,FIcp9rv ^qͻnӒe7epBkwyYz](]WBV= 7ogL#Hln^yƀ<Gۮު_ L:d \cx鍷1焋/6Y td _\ˁs!%>u-Z o7y9=r HU:F71+ ^:KlBhxkQu-ZE^yz4-=L γ_u@gJjD z*AvJxc {-exl*~'}^]Q\~XЌZ|yTVG%JJXur[luנΑxet^nCn<돪 z4C^t_e1H(p).] suLvfoi^r8UwVG7S稫&f`:9=OspJ3;.6ֹWch$ﺍ@ﴴ-C ~u%;מ&8ᕨ4__̼”WLjfZo0eah1GenD ^.A8UJq Dgq0;ѣW${-ZA 9goXFW Am߻W&P4xCKv/3`'N zcMr!<)R w>ye9+N(OT)'0(g*ղ\:gେF6_nD_l=uIh;I 5cC|CwZ5* DA>x=5zZ&w|`J@n r;=+NFIB'zѿn :6tp':pu\ yGQ(hg xtn}g G d+S%ZLuŘSp=_W {;紁N]:PVQIN-yo0/m2~Ǣi@]p>JsO*tWVlJK)ͧ׿wk㰷4˾Lg>yv߶oC T].ޅV!\C ~Wg%vZs;x5諳gapK|2|R}) 97I9Vq _Zz萗?jyޚˇ Ŕ.:yG9k'n|A&l"`d ,ByhkF!}Pz@asiNWnm atLu_F/R^̛¤̯vs!pW[ˡw ghWcJZmMcp2ABxi+7cl-Dm8F9 }xXFgn曷ZWatWv_»r85>ۘiOsqy>H" _88sA&HTW+~GC 9X'Cb?}9M/H0vݛBG.1kK9s7rUjz$?:U,FAZ,T; H"~wQjS^|A̬g,K&ztv}MDV NGf<{+r\ݓ/P`֛^@Nj2`h;zJ1pF^N_@㳗 3xs5^uob빻*4eǂE 'f'[.-=x[\7m|6wo]s‘@>2*/j ߻MG(k߻Хy՗(e[tZ&-q{OB 7c ^#<7'.wm>鰗&oĉD:|/Ɨr_/Y$^u̓*'rfxiEASg|<[G?07Dڼ;<2\+{q3 3LS}wIDy!빐.DHW}By}r~R:d;qȭ%ns7P(%[ޭ?n{Qݤ+e q4n^^2#F*f~_ǁ1)P?6cP9l _*k{ "I[?䁼ҕ{33X#}5 e@P)rKchiVϨ8oНtoƆMoj}/^tK[&=7\cAFȓw)#x0D Hq0{#0% Q0zX#Y2O- %ݤ!l Г<=ޚNx#VxfPڶ-3=trk PO[s`H}azx[l%Yu^gȁD}V+LUz mkDx) h"œoxkks)-F[?896v?zϹU@Ţ#@O㯸zZ30 IyJYׁ c޷@Z#@@'};ή>끥^Kп`onDQ^0Xynx5h 휞5W\1.::u=pJx@:UfZy&!إT 8EzT((Z\|D/Ń~ x#\if`_mpj>#z{=C+NŊX=D{LK.96/=6 ˽/p.^=4c7ӃFB;& BP,Ca`]Ck0$<ωGd?^#sG):%_ao=BEg8@qR7]~=Or=oz6ap m~EVfN\?P{[.8YN"$@qR wallch-4.0/src/Pictures/task-due.svg0000644000175000017500000000757012301477401016126 0ustar alexalex wallch-4.0/src/Pictures/radiance_seperator.png0000644000175000017500000000031612301477401020217 0ustar alexalexPNG  IHDR@TssBITOtEXtSoftwareShutterc jIDATE1lK{ZE9+z>+l%!i 3q͹H014s3W3!:?fPjjnYzVaG) IENDB`wallch-4.0/src/Pictures/btn_donate_LG.gif0000644000175000017500000000366012301477401017052 0ustar alexalexGIF89a\2e5f6g6h7i 6c:f 7dfDkBdAiBeAjBkDg%Db Gj(Ge#Il$Jm)Jc+Le,Mf)Nr0Nm1On+SpYm?Zn@[oHZe<\uL[aM\bN]bH^nO^cMcsNdtReoSfpbh^[io[jpXkuZlw\ny]oz`oukn`crxfrsgstvq^st`xs`lupjvvztbkwwnwrix~lxxoxsjyx`y\zbw{{ws}yx|a}bcs^t_{vx^[^_`[x|bxZ|xǞ\͢Z̢`~y٦YԨ`ת[ث\٬]Dz\Ҳ^մ{Ͷa\ϹV׸b\XEZN[O޿⿆]PW^X_Y`Za„ĊĐbƖibǗcŇLJjȈȎkʠlrmʐstʀʌ̒͞|ˍ̈}̓΄ЖϊϑЅВцѓҍӎԐ՗חؘ؞ٙڟ۠ܧݨީ߱̀̀̀̀̀̀̀̀̀̀̀̀̀! ,\ 8ЛuǰÇBHEe#ȱ?rމ )rdHx(Kʔ(c4 K-c|G#l%Ek'hwF*=*RAuJiUWs®زh~5 vYcɖKvm[t۾9u ,X_Ä6XqcŐ3fxC֬/AmCMӨk#hװc˞M۵j#Wwr.|xL8p;'N=oدc߸ӫG@qr0 }47$8 "x h E . v X&)2"8xL6dc#7戣7@ٌ@4z (052]PЁ#=ix#HY" "8@p@VLc7lf (hcxig@g5OڹPR̠]hSq.h # pgxr*]`Y )lz) ( 6('/DMp/LM,`ApeÝ|*Ҭrʷ 6kxzn!M Rn,Obs@ > f{n3"Ĩr 4H.-@ 8@+$#  ܱ:l4*H4PGJPQ LC%P@P@L'@&Lwj0M@P߀5 ıJ)0! 0=Cp23@Mz 90m2!P' 6 ӳG?di4;+dx`);l* D  U@^H t#@/o?{?ؿ6Pw D`HZp3AZ{q  Ѓ.L؋%ta KCia/p<">$""&шJD*Z.z`ܢO!2hLanT0(2ґvL#1Ɓq aRsD IH@Ljd ' IFR&Mz (GIRFr;wallch-4.0/src/Pictures/go-down.svg0000644000175000017500000000713312301477401015756 0ustar alexalex image/svg+xml wallch-4.0/src/Pictures/applications-accessories.svg0000644000175000017500000002014112301477401021365 0ustar alexalex wallch-4.0/src/Pictures/window-close.svg0000644000175000017500000000454012301477401017015 0ustar alexalex wallch-4.0/src/Pictures/radiance_not_checked.png0000644000175000017500000000025312301477401020461 0ustar alexalexPNG  IHDR@TssBITOtEXtSoftwareShutterc GIDAT} 0. A ( ⫓ֳ-BhOw .1H,Wۚyu7s{=IENDB`wallch-4.0/src/Pictures/ambiance_separator.png0000644000175000017500000000041212301477401020201 0ustar alexalexPNG  IHDR>9qsRGBbKGD pHYs  tIME+2!:iTXtCommentCreated with GIMPd.eaIDATe 1 (T}.PRb+|ޯ2 !-> )&hz}gov*$a7v?`=oɺȹP _{^IENDB`wallch-4.0/src/Pictures/mellori-logo.png0000644000175000017500000041350512301477401016776 0ustar alexalexPNG  IHDR%%wbKGD pHYsNN3tIME%,yHi IDATxw}oUu.d"#H0gF3#[J,K,]ݽ^u,˲,+L0 9Eu4!44@sN`DQXa41[q-G1Ww$M>ͺYw24Ms0 C ꎰcru_wxu 8uG(o9*@O~[=?Wg$nDnDDD^=zؐ<觷 I` y@ӖJR\*ʛ1 #U2QFEFϩyNSccGaD_ H(0t p<+ׅE (VM`cQR]5H """ %DDDUP8d v] uCHleYy02@*aIEQ[}_? l<'H GTwa@Eauݍ0 >XV# 8. / (U!""PBDDQƖ!_ j7MT9N72QYQYaQqa3AW76Ԩ1 4M ÈLӬ00 ˾=ۨuarݱR`$IՅG2BDDDO J¡6tVۉr\eY6 f5lxAA 0iFiuEq0 ,ź# /Т{ Q(!""r4‡\ֺС"zhd2tEQ Ð- `xQ.Т8+bXBXzN`M%"" %DDDp\ :zTÇL&s,N0 SaϫtMNhQbfh8;D\]X *ٺ"(("""/iCpreDQI-@V`FdYVRaaY.Êbz$qES """ gW?$mIp:s\eYQe0 Txc}ueYIXQ.牫'bzW[LZ@4BDDJl#oh'n8Տi=@>tvAPX7"4M7 y d⽪ AEEΪqQ}e$H‡tw&錢( #v<3hӲ}q9Pb xR=&,y"P뇈e=~2xf+~`8Y !RTO6N P^<v{%uAEqyu4qxJ4jdiR_; \|>_= ꃆ͂[+2*$|H$Hr\;qO>O}K”RԵ|$!f]H!n&D.UpoPа?/[A" *Jb$HB%x\ ˲j%qkj@񀸒"IQA=DDDT.L t<\~, C@Kގ~3!bj/xH*8~[`Է[ ,X,Y .rUZfZА", `RL|*{CDDR-}C)/#l6;J| :$mc6477BPkH"?-oQ_alllbk[A +g iuy󦪡>q5qG~T7"" %DDɖ #%ⶌ۶0}fEA |ࡥZ IŃً~E}eFHdEVԷ9>Y*>* OB 9Aī:TCQL.6MXuMA ]$IZ "lۮmf!)H֡& RR&묭ʊe^Ŗ*в,EuϟzLQE6""@ O\ qx>İmj+PZ@dY MMM!9j.9aEͤ>X[[c}}6q52%VQW(2P(лDDD؛deg;q[(p,d. [mط[2~Rinn6jU|^SmrŠzNU$AERIT |m -:PEQ.'0$ #nX6 ""ADVv^si4; H'A~ZuE҂Q@N[[͵C'E@!i}6X3̫X__g}}ZUEVlݬvϢHRQcu݉j(qU +f"C!"PBDDv%U3$( 6RqHUA$(ZFRBdgAEpͤcccڱVkp]c? J +ʓ-0e(Y8 \"(jAfgIKFOO===;v6R1DQlll ,//?SE~mŋ('B47b2j@qC"" %DDQg'Xp=_聕u7ڵ-mmmtwwKww7yUCȮKZ=*gii*d^ylEr\~~T )+ ""/a?EsD|8o)/jN2k}}}tuuҢjy*rKKKͱPEu^u'r<8`6CDDnߜM=pն Z^T{F}NrEoo/t:jٗY㰹YmHtkŴZՆVת"ZZZHzDD pdvvvO';`\.&7m`pCDJ4&-/ 0}Tmsy$}߲T 'ެ%"PBD䧇jm_<+8~8 N& @ T*$OͩS$E}"sss<~O@X'֋o QyzeDD0" > |>ϿEQ뺻Fd2ٳ A:֋"""Re癘`bby677wecGN4RM`9@(FXq2GM7vDQU|PBDd۶yjLԤ0BDD*"<{rbzzzWÉt:RRX |8x XҦ@ %DCO& X﹵Mɓ?~"""?pb||N49:~D< m`M&DD:ׁ/l뺩FF qyUF|HD155z÷um0qĿMB M \~tPnv7g%=### *فdDN$ɶ]'a|ּ  %D}n*s#~۶_u]}cˆdHmƨc>|, 'L$JEt\7o⟀ϛ( \.Q܈j*---3220---Z)""KpbqqG1>>,KE '-ɼ$n lhބ( F 2Baqn̍HRp Ο?ӧikkS!""G0qѣGQ,Ο?ٳg Jy0\.3;;8,..R,k:NR(8bGQ9" %Dta} AẮ0²,<===;w"Ei IDATE: !""A@Xdff011r:o"NTjX, q-!rIJыV_>7zg3ř3gp===dY"""Plll099Ƀx 8Coխ r]{ă0WB<(9b}U,E4U#٨f`xx/O>׋ ""r*O |5< îFoH6j244ŋ9y$mDDD IֈCcKK&n #=]"GB7

d]뚍lհ,&x"gΜEs#DDD(py(9pc45۶?n M$Ι3gl6@DDD~c߿ӧOY__o Q4IRQ:.:p9x4fEkY*QqFLV|r%N>MSSq""""|Qy <|1fggk+DwzTqf2 ~[Ӫ9@5 %DE'=爫#>8Ns|ַjr.\cǰ,K/|`aR.7>\, |T]qu5Wr 6:"٪ٳgժ!""" -YAEӎ|߈&<"GP۶?8dF}FssZ5DDDa\eaa1j[:|odDjwMUMg]""}ov׀FuD. .pEԪ!""""199ɽ{x+++8Ӑ-UF j:#Rmmm>}˗/388H.Ӊ]>+++qNYi4551<<̵k8u|^']DDDRNO!Tp`ot:}eQ(䥗^̙3 p>έ[x ;YQ*ֆkG&s ϏU*\lid2z*jT*LOOs-Z %D~'C宺kamۜ:u^zSNfuEDDD,//s=n߾,ryL& yDLly>5!\~7~5~vt$\xk׮۫a""""/PEEyw`cccukC9kmHݵPBD`iO4fqu.^HKKN>8333ܺu︝nDX,-(tEJA֭[ i稛3q;pBs&DP(!Ϗ~x~5qFk3::Q>E#or_ x|n۟Ӳ,8{,/2CCCRDDDD0 Y]]޽{LOOhmhuc[dV7`QyFS(!G_lruN>eK~:Z)"""rDQDXd||7oc6775g2fboě9Lif\9 (&$>ۈL_˗immՉ9:455q9lƶmX]]֜BRmxEκF %(|h~Br@d~ /2Ν#DA\! msΝ͙q2|r\Z?7 NEq9lJȡfqWr岥""""ЇT,mLT*m͙\.w&[`EQQg\3fJȡ|c6NJ6q]w6팎r ͏gϙxX,hD& MӜ/_ .!W0L Xݰ纮@"N͵k׸r mmmĹ{ɜ|>OPLkR۶\,&[a,*@oielFlr8q_~ .P(tEDDD}r9N30މ3.P/ofGw3Z^xQ-EDDD˲hiiŋ+i(`ll~On{3Gu`{fbL~02'mq6\R۰a=.\pl6K&lnn~`""MmX,f,aGQ~PB4Q@KJR)x饗z*mmm:""""u) 9sL<|m ]޶OTwaL+H/Yā+Jn'D&W^yK.a۶Np\!4l{&W(~T* Ø(ٖD[aR(>S.3S\dYxW!$Ⱦd'Nd}WA8BZ]0aL(DKaT*+?_{5Μ9C:IJ[ &}]24*J:Ͽ\.S2 QEζg? b}4fq'@"G>0e$ȾEaؿk ѓ usss8ifr(}PB0Z_T*vߣi'NO900d}}{[o1==MRv0dJr kL T(!hm/5˽8eY0::ʫJooADD䀉v$U{9R&ccc<}r̵AUR`NEδ()!a%i Ε+Wx͋|J{d!JJT* &0u]3^< 0aLȋPBcfm70 ˲ܸqv`@V_\9j gϞ%NJx&2̹ ~}8x7"GgZB y7]of@^zׯҢ,""r4QN>gxxV1677 CQ%)4nLEQEgZB y7of/$HR+pUl 9 |X.chh˲HR`b0&(PB^ԍF@"\r]n N9~8*.]"ȡd,,޽{$f_q &V0!{Ej ;e2QHd2N8kƅ r:""""riN8Q &޽ o78f\ & 0R0!{A쩺@3ŝl^{5FFFd2:""""rtR)jnbyyyD:r_T*= N0zyBbǁɓ'y8wtZ'XDDDDd1M[ny:ϩSx7jDDDDD:4ի͛7YXXQ0f8N{3-':Uk?H9s7x'ObYNHi;vL;o;~(FS(!0N7mo0M|>ٳgyk{EDDDzhNʇwnooʕ+oܶd+G&! i{V@vaǀ_ 88w*$DDDD}3۹<yI[[/_ڵkf?ta/ \0 CkqWمo$f/kn7( я~!LSoYy_ӷ~|ߧw?Gƃi˗~ 4OR$1 C1׻0KV?f/5"xW !"" vA@c}0_ _7kkkܺuzY\% {O& =ϻ_/p?"OgYJ~ $-;܈@7ĉ $DDDP 0 |gssEY^^f}}rLRRyAׂ0 &>C֏ib/__"\N`C(|e. F6erQ !""rLMM1??:R u<`0NosYFFFfߐ~Nkk+.]lg+.T*/gaGQLB yQ_ />@BDDdZ׶]H~}grrZUyT/tH~-}<88lll033ssslnnI6a%9L_ $Hȑ!q2b%>}ʇFeRP"9}4BA/H1MV1_<@HH a @B*8 ӯkiBQSh-Uq@* I”9!!o= ٻw/555Q @c;Ia^FYQB8L<)Hqɐ3f ]t#FABA"DxE(vq\8NZZZ*Ni]vvt:M)..D)z0@FF&Ljv&,v2܊|j pH>; ]$F_ȑ#2 B#N8NN'.fihh\.ie?5U6էFkp88z(#Gh4Rׯ&L۷ڨK~?n_p8܀KQ-:d%BQzUAl63rH."F% n*++)++jjkkVq̇3 *ddd'B&$~N8Uanۯ:)LxE١KFYQB 1d2ON4Q &.Bƌ# 27Dyy9۷o'??ե ~8+MeKK {aСbx)jaL<`0ȁ8q@ R&X֫].֌zd%h$`>p~҅d21l0."RSS1Aw 9qv*F[Vs^rEaZ%Bb/L 0,444D%LiEQfuIkD>eAD bB0l6Oz]$ C /dܸqR)K73kC,f˅ +?_M~~> Q6~ɀN 0^/7\2.=^Orr2YYY~*++ٵkG9<Cw``jǻwfɘf΄^/L 4)S8tMMMQuRU׫3n xCQRUU2ʂ7PF`&j^v$Hl&Nb455ݻwRSSC^^C aΜ9` mx mJ90h42l0~GTse0m6T>)L|ʷ"(!/4: Xlۯv\ƮzDNɓ2ݘ@ " EQX, ͬ^ŋӿ>LNJ߾}eT9SLᮻjۥ 1!F:dg;HRƴgo /~?gȐ!$&& =| f#G|v&b/u8-'/UUu7# S pf~6\cҤIwy$$$vs |I;UUٺu+C aɒ%=xV!;//G2~xDAQQQ֭[9|V-"Aq˃ry'pرc~***xcRSSt2 t BmFYY^S5"l<{/9r8x W A8f#55χ離 D P^ojr(TU(!>A"ܪ((ϧt3Z7lerrr4e[Q-[F]]?lذo_~_***(//n 3TU]vk.jkk;ծS!o |8I" B}!-- ׋狀:*ÊNK@Ia@UՀB$f9vIX,= .!CHC>o@~q:l߾o_W,\@ @0dӦMq2 5 wNCH6  =zk 8q"^={PWWevVz:<6\4o*R.BEzDb.Z n.k_Q͉7;;YcGiӰX,G?"))E}xG2deee>|@ |JUU[l!//OkEmdC]hz딪呚f8Gt$$$ew*c0aZ'\9@FQ&DzSE6m6tE0 2lƌ##bܹtMl6nÇ0`MEEpQǎ㫯qYu  ~WUUQZZJrr\Dff&^<-`05lNg  C,׻nsWZzOZZFQF5hnn%f͚5W_}5 1kkk5#0UUٱc 1***ؼy38N A23F@|Fb0 ɓ'xGt;*d/q8M@(UUu(!v(pjxt^'))iӦ1qDL& l RUUqK/1sL.҈K.~sRUUnPPP )B TVVuVhii9!w iZZZJyy9jy'xB7:[d0:t(SLRPP錪UIajۯp8@(UU7"s`NOjτ&OLff&6M6F8?e]SO=Ŕ)S.bx fϞyLAfڲe [Нk1bqAFbQBU@gwxٚ>+g}kϘ1g}{'~ۭd |MMMرN ! YEEE$kЫhuzx^***6!*d2 K uEQTU 7"Nw[in[ׅj2n8?|cr\]]̀3f m<=SWWǂ (..旿Vs뭷RXX?-.rQ&M$)B;n7{e˖-TWW8T!¹9vcјL&9Gl;˅| ϧZ\.׍@(ґCD !67Nln+6Bgvv6wuuunŋ0`CIu:6l'? Z#Gl2(Wb|7n( ~ JJJ"6!B70 RPP@bb-1an7>:~T9<fMu:MfL|4VĦw-Ed2e]Fjjjuv\uV*++;=zCZZӧOgؽ{7&J?νڵk#.==gy/EQ8tiii?r B/FUUظq#o}tb/YTqq72`9wBMM _5@ @4Olv8usWet{)ѳmeNW:mRC?nj-6nΝ;qD+پ};999$%%qeգkF#.yx衇k[o=ǏO>H{4A477}vmFSSӷfb$BkeGRZZѣGILL앙Yt:'33nz2lNР(~UU}2"J~0 j$NJZZZDwm66lЩ^!)Szd*|:rӇ+V0~x?Z êUx3g"JB/_|cǾ5 !*7撖F~S\?&++ VO2W|ZZ;rB$LfyRx&OLFFV[ǏޣINNSeXHHHZ UUիWcnF ֣qi&2330LӧO_}+DEWD/AbZ>s!A*=QRRBBBp @JJ nCIIN_*fyR_ ġ-:<.vE{t:v;&L`ʔ)ݮCx)((0;"TZYn7&M"''[n1 sϱiӦp/~m z= .;wbeʄ$Blzٳg_x'ٱc7 :Ʉd"'m3&=k 1&ѣGɠA0Qzu6- |HD#nr\Ʈt0͌;;n'H8CiΌ3x饗s֎ׯ_ʕ+Yj,YիWkaݺuTTT0gΜn9UF&ա)]C/,,5&/d޽\o, 7:CA0رc8qC B'l7Ӊ㡦+9vBqUe.cez nZ=-ZP`q3dȐn`3BHJJ&3EQ3g)]].Vbʕ<# >W^y>,yUUٽ{7o;5Л|۷/X[~g^l6c6LC 1V;FJJJH\z3}%==4^?bپHW(#HDY, \ߟܕ2NFVx뭷p8Zp0vX?'xB{]BB%%%Qkii7 -Ҳ!TU婧B/M6d׿jG^; >>ƒDO>8())!//PRRB]]wԨQr! B *MMMlٲ#{Лe^*\.WTe,$&&$???'/|v(K%s{qibLx|k7`|&S/?g 6,@ G}Q-Xp!V0,((wm2 WWWT~鈲}jUU'N)ݘ`0H0r}vVXs=ǡC:$zfZ)Jۛ6555444mɬ vF#Æ c :UK8Y%sH>vwj2~xN:mA>cM<ӤMuX,̚5ǏwGmww?%KxPs /h)r6lȠA"ϖ-[~QxǩxE]Ć "LAOMM .ywp yEFɎkžܠX,=I&1`;r_^ d)bQB8 c"pdxvl63jԨniZ;Ϝ9nIvء=7j(Csss'x[ov~-[??ygUUٴiS X`0DkZqqef͚SQhRyٰaC Ύ gPg^x?l߾N`451BA3oP#F'|wvHOO'!!Ɨ6:*yU f pp30mEaxN sNJKKyꩧ߮kb_]wEQQK.EUU~?k׮%%%۷wwd~}rn"JB!ϧ~JUU7fst: !QPA())o߾+уcUU#gx&NHKK yyy455Em|*zEQD 3gl^:N:EIt:rر\u#6\pSLю_xmRG~cGx^/__̂ :|G=+R{M]]] 6#5h4/Haa!۷/r-D>Es#''z_~cǎu8' f3&IJ4 l UUٺu+`P6={R8RɈ#ZQ |'/uV5  Ȋ(!|G{GUcL1gվ}[:wϿ `ȑ|Z{- IDAT@E7ߤK2|$C={_QsvX +++8..ロ]vg.\u9|07t>+mhA83\.6nȲeXz5Zʎ뛨k'N(!]`00tP2332df9j kZq(VY%EQyVm튏D2++[k.mq+О+//\;kPO?p*xINNvCUUV9N 0n8{1M|19OIIȔ;Xj&MP~޽{cAZZZ裏Xl|MMM(FH A8X/El6kƗ褿f8)LSE DhnZPȑ#6mZ4 r1}tFvꫯFnw}i ,;r;w.gw: 2D;nllfӦM,X;O{4wL&6M;vB2w܈v0ɔ =yy'ڙB\i)mK_'pl6Əτ tZ1XPD z"v2G}qz Ĵi>|x6c:vAQ/^ԩS"pb|رcZ9Ȋ+8p\uu5ƍӎkkkعs'&'|R |IeKElp ?~DAbŊ g:z-x lΜ74׋_ ,Bx<ܹSD A8*!!tƎnb6SkiHQB8S#qGBדHVV2k^g̙s=zT;>}:F\.x]Hp"4=cx^RRRXl6|>HOO^_QQ]wEYY\r f͊1:SXvvqx<|G1o޼Czj>gdUỢ7|+VayG[͛7ǒs#GۮYݠt$''AJJ %javT`6p΅BwKeb6zmGBѧO&NȤImȻ#EEEqqq6׭[EqDlE4`0Ȅ ؽ{wĿy֭[ǜ9sYfflYUUEff&^WDo>^/a&L3RSS1 Fg媫?1;w^7p@z- ѝI!ň׳o߾olwl0cƌaʔ)2+m;b<ڄdX,_~Y{lZ0b*/ #pc4Yb;v젢 6CsQSS]W^yEq_ 555e ĠA(++`|lܸQ{Mbb"\p7|sDV 3 'N`Æ ޽[A,QU?6UUEUUi)**jq|>u63QZpGMSS.Z~TD_" 'EPJD !*AA\jX2<:ӦM 2Q'=yd熆qG?%%JnchllZOuuuĿ|9s5j˗/g|>=?0<ҥK={6شi`Ps3c~oWh4W\qk׮ml*Bcc#_|999x<#!6ⵈlJIII#GZ]8ᠤ;F}}=NiTt:!==]kc„ 455vijj7iC%r]k9D:X6~GBѿNȑ#c D1cի#_]qڱf_~(Q^^μyxg-?07pykY555lܸy믣*,]?O :T6ؿ?gώȌ GߵkPPPٳ8q;QB/+;E+JgcA6l c7U r=`F (((fn7@@s9wطoGaРALt$%%1i$9rNΖKp8劢|G4%SO \rvG".. &Laijj/rg~o`͚5j۽699b?|_3{l-ZĒ%Kp\n6 ''h-A7nK,=Ctѥ Deǎ|g!1Jh#>LCC떂|Ey;WUU8z(Ǐۭ(i![yNƦ^gСdddBYY'Z IrZ%·Of`088ZgEQX,F7 #V÷ӧOf/jZGLTIII?;v!1&;<[f1d/_M㩧x<~{ χlݺ5fD /]vi*kj[o?'|;Bw~>cM1Bb:v0lܸٳgw9nJ&m!Suߏ磹r d;tFt8FСCILLVUEh% nW\.CW}$1bDL'NC\R(=6oތ^pBQbь9R{ vs]wci ;?mF\\'|K.Ӊ<䓼{̝;W34Q"4a&$$_}h裏/R[[f޼y%!Yn01BbPDƇf֭Z"޼ 5񡩩ZJKK)**>AxmNn`РAKLLdҤI455q%Nf7vTU/ -A_x]4iiiiƘdD^^G5k3hd[npDL'Ndeee;~i:eddeeq=hǏg<̟?_k~̓! r.䒘!C͖-[p8(_-DD A@t~zoa{O^^jA͛7s%lL֛uOs8QPPCK-εQe];]cք%^d2z@(&TD ub2Ӂ خX,;̘'|1-O=N׿5>7j=z4ER9RM$55 /u }Ѽ/_΢ECQ~+h3<Çx(..h4jS(\yQYY1ۗ_|d?. |Kؾ}fbѵf4%ZzV<^ײسg N7rqQrrr(**j:U[A"##k;}8 FK\+fyp%P p2cSTVvE~ Ceԩ 0 #\P k֬KIIaڴi|44m]"nkB~hHdʕAя~,]T`0qG:μyڕ477s}kEldC%駟fڵa2 @ڶωִTs---޽_˗Gy_~olܙX\ioA3+ΝMvڀ֌y}o+5;v,}*dPnn)b+Λ2݂D`jx]HJJip1i|W>-&e˖idb޽;b|:91sLFV뉋+VDrJPU/?%--\|3& 2tPnv|MjjjcϞ=yOgM#׿ѣG;q mPCs@mm-&==l"C]R#@jrss9|0\.i :Еs)j;,ĴBy?dm1ټyo>&_f1h JKKرc .駟ċUVӟ3o<^x5>g? 'NN(#FG?|VYDzgӦM޽}#RzQm0h7(TUe @ L&9iSVVƁ(,,AU'&H^g$^ o /LEEET棁@@  imZ D/$ oZ3TSE\\\}FL۶mӎGŐ!Cxp\X^V4pC|!5[bժU@kŏc^|E-'`…/Ń>/M|?8կڥJ~~>^ziL~;廊 6PTTCa6x<5J.h t~?ر۷kQ8: &bo =zt?]n7Wg̷sss)//QK?"4G`( ;L bX=z48:ӦM@(UUu,&DobpsWz Ĕ)SHNN1i!%VEQx<ȍ7ӟ϶mM!O!V1" ̞={:,]R ABZDaa!qI4P,>sw%L466ρp۲Yfƌ1ߟt(**ʴ4z@6ǤM=],KzWZVƍĉϚٜX:Zԯ:yGjD'<"\m~(hd̘1߿;w2bnFx =ʶm۴W^y% رcdɒ%GtȬ Ab7+,,PhR Akz^7ׯ箻 v4D<  PhjjСC߿ $!uwرcuEF#Ç'==f:&dbXƸ\YQ#Y%z2h-۸r飙C>Ç'++]ƞ@>}0 Z`HteI<䓔i;w.#FЎ~6*̙3q g(H^^> o6~`0ȓO>&'<׳fnF^~!9ٺukmˌFjЎdpŽbאzn(...w  $낄hd޼y=jeر8qICCC;ĝl9EQv3HD(v:^ul#))ɓ'3lذyGl6B~ƏСCٻw/ߴ׏%KD$bΎppNy`gygyk>?3V*b崴*O>$/2jD&FȜ)B& r֬YCMMMWJ5A8f:<[駟rm6{@IAA{졬 \!U:~E3Nnj3ׯ_HOOUГd2]z *EQJGrLF@ Uj9azN|P+P_W3&_}qP%nDԶ}jJJ  Ҏs8qRR\sv|aO߿? @2֭[ǟg.]??OiiiF0$@D^ Nϰ vO=a.73p@FcTWt:PJR N$%z)<>R1rH233#L{"jQQVbiiiA;vh?RCp0gΜȑ#zXVwyg#jQ0G#111"ѣrBga5 &IfA:Å%bicW_}ʕ+Yt)o׿qFx<!""$F9sztlfԨQ?z>(QΨ)8{ R:xFzINN&++{Z ܹ"ms`0Xl}mID#?&xӟɓٶm{(⢋.bӦM@IC=G}Č3p> tp]j(;B,A^ᥰ~?x(..f޽Ԥ_Psu1p@ϟ+1~xN8J;C XftST*R,e"Jĺ mt!:No߾L4ǵl6r;Ԛk('|6$$)aK4vo6ӟOn۷seiҥKꪫ|/_͛(q oGޣb)Ă ^,`k|yt^ q򨮮vwɷApvuwد_?n֘4Y :d_b03 Q.%b IDATZm\rŦ( f1c0qKz❜LII NSS7Xb7zjo(:UUeرN`?43cǎq!nL&^UUy饗4QK/%;;-[%$۶m_~.}'|eGHOA&)G^^ >nbCQQMMM \) mâEefwh$%%:5(ڄv{8(JtQ"V7v]aVy6 <ɓ'ӿ^5vSLDa0ߡ"|?~"|4iROs=I\˗3`***ذaC{z=K.e֬YZ#<€4/h3dAGj5:%;B3Ft]{;k 8p\!e-Hl6^'H7:N'])*h-ۘղx2221bDS7yd֬YM& zHK.Dyc;bĈ?cĉO+裏X|9ӧO筷/'33ݻwi&f̘=,Os9>sm& 5B=MȻ!+++;)ݻÇبDzAHFQɆbaѢEvE10a'N0*8Q"ecǒ-Ӈ85Tm5srr (\qs֭ȸuhM9c{Xzu(m۶ES eK̞=`0𷐾ڂpnUUx<n:Ɏl½%TU壏>bȐ! 0SOHhiiСCٳ - f2Ŷ V`7,^ >4NתF%bbѱW .u0 2ɓ'w%ƍ5kD W^&^Q2:ܹs5Qvp81cFQxWxIMMСC(!0H ͛i$5A8[hlldƍ\q$$$hDx[qUUillݻj<O:ɂ=7eFV+p8hjjZL&t{2r)Q :`*p`ݕ222HIIAE]Ė-[ D07 _}Fׯ~NLLd2i!?R\s^ ٱc3g$11* $h䡇b…H|h)™ B餸O?l+^`]'b0zc{!11qƑh{G}}vS$Z"; ʢEDzׯx*bJkG>!"#+Dwf00nOw\h7a„Muo$11tۧ=VXXkwVVVRZZO>]9p8K/[aÆ51d̜9TM9™7o_m~¿z 8H x<jkkٱcw[Ɏ\m³%7of׮]\.<-Aul6.$i{2}„ 466F]zv}jX^UU2Dbg~WWz<[W6233Tj= Y|9]bV( {\qqqM7Nqk\.ZZ V5̎;& |ĉٳիWcǎv^d2 !9:tMgG(KkBX-˜1cdʘ1c3f v=dM_\ȝF%Z&7Yִ@ ժ^1|p O2`n =vak?kkkysVV)pQ"1gm p@k[юICY Y ~jFF M nqqb[B *Eksa„ 2@ޯѯ_?&L!C0Q]C~_1L+bQQퟁ9v2ǣjFZZZ/hY`6.@7|-[*=Q`m4OitVhhhnTU套^$33㵵e w H|>jjjػw/֭#''~>`2n'pDfІ;BDMr^$z=7x#ӦM$4:ٍ`FN;!83(bfW{޾])( /`x2 $ AĬ3̈́` ALtyWի)velp80-8Js'Q"u9vp8,-۰lhkknYPVV /w(eIw<1>4ŷ?_SS۝ZACu `Νxqĉh 8Iȣ !XX,V( Az`ʕ+Q__nw󝤲 &$$zT$v`Fz(ciC$JgwSO=={dLd0d2!bٴ"k3UXt)> 1 288bX PF#JDhpK"y. ̓+u]6^kݛ$\veYfn I}cƤu<?cÆ IN̾ <ؾ};ݛff PA慈x<]g#1"wtĈTAbŸ+ I l<*.D"|@qHDnos klن(>&xޤك/| i-~_ kf%H$֦oڴ)wqE1&{7\uUiA[B!x000V] &Rjp8H$h4x0As1ۢD5ׇX(hjjBGG\. 2,1&8Hȥ p$Im)xh@͛odLb1|??%>C"&~獟y>-]]]ƿ׿fN)!Y 7;pر,SAx"YgB6zBuNFk,`%Q"WTRUUHD0l<UUO`Ӥ7p֭[$L|ŗe躎'Nѣ\s5Y- ~A hllL{Og #0%IRҤFA_Aݻ;vH`AA$$#O+"sȕ(HGGzJ4WA1ϣݨ6UU]1f(&QbnZ`C$qGq$IBSS͛v0+XjUZGO}Smᮻswi|v3[lI:դEf,`޽SNͧ, A1g0sJ&D躞2!X Xf$LsE ߏ-[P̐dYFss3PVVf*["BuV(2-r8 0󨨨Q[[K#9KƍNbAbA,H$"5@[[D4BElذW6TxgM$:Df)`Y -BLc%)$N3$^/nfTVVQЀ\.SX 8(EDYc-0|drH__mۖd*922 wqN>3m6,Y2Xn5sN\߿?gXA+@> ^y啤=tQ|b6D:By|^(kZ$m6x< p8ގ&l"RUnyKr'ш(1#8X/I[.N_|ضmEK4~3رcpkf˧4#?[8s 1O{&NQ<"t!2dX $$Mp0Ad+H *ٰX󨮮FWW<)4!+,/@5^(1e 4'N$IGoooR);***|_|q(~\~ضm&)sܔo$-PKs T,(e>gi]iDQ$(p!""D.ɘ0DT0AL%HoGuu5 ePU\F9AB#15nTU] 3Q^^ޤ"Hhnn?ld0hӟD#UUv)?78S$Q4bV"bx1<x(//A*v;qQd,řuWUo<[b7q8R&^4>@e\[vvvDE,[ wu-ZxXp!:?#$Vq׿oňnOQ G?GAP0NCE1eCdkL}~r-ԑkǃNTUUY(4M8c-BєDptEQSOQQQWWypHZ lݺwƤ% y睇UVaǎF  pWc5 `i JǏɓi%3#bEP h$C:e,VΑin#F$7SD#IҴM/u]G;53 A%6p8,5t\y;Į]OԩSƂA4\r ~?)cpEqI6q%/%JÇ?? Q)[ fYƜ2Y5ݖ>J#1$&K֭[I(ɓ={mBAl@ %8z?x VXDf t:Յ$E7s=䉋IW^!Q(Iގ}QANPdb2>ٔ$hZ 1QqW_M]>H2 L4jpD 17 zHztuufH$aX`t]{g_~o62ɉy̛7(هMp%|0dbـ)1ZyTjB]9 [X|9.rzH,ߏ3gٳY{KΩq:% q <ϯD"Q5554z#?B8|0{=>}peeeFkk+ Qc_!ALM Y a}@'ϔB`UaIsa <㢋.ºu I RPVVf^A-BAF 0HDiQQP(,󡽽& " ͆tttY' IDAT`D 6m®]h!N>ff+d2~f31J毑1{_^ `ƍ uuuhmm4M>r6?::K%k8%pgp(+#h6K=== ,cͩgXMrug@Q{4$$ID"ui3)3R $+$Aq8hkkC}}=Ezϖm6".1,L na,9(A4Fuu5;HbccF1x0'wX:X q aٰeѹ*a[8qlPNZ^qx<)1,k qiTYގ^jC1 Aի!&R pX 1Ϻ6(Yy_Ȳl]K4hVY%ʖ *n̟? 6 ---hllfDñc^/%Ov/hLkl2vJ"&-JjfA!BQc"q_1t&wϦ nG[0%UX`1DҡUUhfjEAww7 2݅ADe,^8iN,D&DHT-"ʼnL?hTt5~ Huu5n6~ " I n6[BPUu>Ʋ%J-[$=%8,VuE … D":u CCC8{,\QnvSw(^x!yX{n]~% >1nPOq"eGb)eneqa6cЀn5554HDv-BCPR) G(QTب`0h*KB$TUU=1a `ӧ &4Ú"v;*++ֆ>x^2*%TTTԩSFp!2ne&t{K:0Ț(tabe l2lڴ 6.EchhgΜy1ϖqoBDImCq'`Ly ͨǡݨmD"xo} wy睌[vTUU%-2***oo(//7wq022bnfCyyyZ-&9r> <4-{ ҿ[ʈȟ8!IRF &J(-6'뒌gcX !I6n܈UVXBcppe-1-=-W{DDYK|((fsvݍrf(v؁_|1m 2dYzx$AUUlٲXO~x'nN8nO?񽖖y|;N9XWu ^޽ EבvW_}5iaڊCaddP(ko M8{XcYt]7%܌f0$c77ވ_hmmESS$ICCC~7@__z){{ošCSO7ҥKaÆ4s#F >dtD-ؽ6abI>1RcppxʴA 2E)xZY 㗿%sA+{/^ IDϟ["˒F$EAKK |>)$#<=˅^Lt~;1VU]w^B!|}SܹGBy|߀(xGF}}=n ??q1|k_3v^r z3 x… >ʥټFcX1vI( ^4&^2$1AnCcc# 12u-/l91%|Y]]]I;w9|MIfN^xs=z p8x7nD(߷zj[ǝwi /zx7144ǏcϞ=r<믿N' 2_lYCʥD;gL1DEQ 2 .Ldj-z L)[|qϟ[odYFKK M;ϖP,D_`1%aDY3'0 QD_LR׭[g|{1'"/w=jg֭lꫯ|>?D ߎǏ۸q#^<t"  XfMPRA0ənIeZx"t]7|"̴5/1q)֭ЄLeDvcq4MK6>믇A"tDkk+nt%:QEi'xI,D",*tuuD5k&=@,X`|ZE477z-<.\>?Yӟ4:{Xdl6D[[/9صk ۍ3g]vek}ȖI7 E~@ o1YЙ*DjH"T@ 2^@Ȳ$K/ŦM 2 1(fO[eK,CfK K%$(Kbڵ+)_zMXYYi|_;Nc//FW{1޿n:477㳟lXp7bٲeOIbŹsp!. >k===EQ/H$FL^Etuu%ԅL0ReY&!lB&2eKd۾8 Á[bicIsyVTTO7[*i'O`)%!eInC`ѢEi >j҂իWC$ _xᇍ666_*oߎ|3yn P[[&k~:|C{v=})A(vmwڵp8'?ַvFFFnDż7Mp\ֆO|$j[. q&nGdxI0!DLUADDBc2^NJIDss3mF{w˖h.l HO<+", ǃ.v{f6MQ*q̙7nz!5χ7 .HCCC{okʼn'&|`]tE8yd *ob׮]G?&8,Y+VKs4,YqC<>qn>?iUW]_I~ضmZ{N7tyK,wߝdv)>.R btcڊ} nZt)Ϡ61 X,V%JX,I\p.䒴׽vq#/4MUU ǽ/)O4`!H6%1Ktvvf! "_zҢoE(p\<֭[+W\.,X_W+++g?Yl۶mBA۶m< 3ϤLYY.,] (aB\tEؿqSD X h4&DPE$g]DS傩%,.a9dYFSSLeKfx(֤cY}ɒhii!/YncŊx1224|W^1^SU/1|ũS.2C|򗿜ԁ# կY7zK⢋.BYYP0`)P0%Q8aBT5TA<%IRZMҼ*r[˱uVENXޭ4-1.JvgKqbȖivʒ]t8`]$>;I"Buu5oӉM6aÆ Iy駓1.]q777/"Eɓ'qwOF< ,]>N'D oV&WgV&"q-qhI,=aMV|P";$-J)h-!NYDnyK%IJڌ)l5*,Z.``~GE8[ cJ8n%Ipɒ9r[АhDJ,K$9N`͚5Xz5n7BFFF׿D"0s?|C`s[7p&+L+ + %n|Y5[lAss3]DA:qٳBYm?c,0qB%8sn/D"$dY,bp㥗^BMM jjjo> _'ԺA(eIH N2sF$JX,`0Aו//Q8Йzp5נ.Z`aZZZpQD"%4Mv`0.H/VqO6'1"(//G{{;uX1k׮ڵkoڴ X3gرcA,(p:EUUdYaFDap8PYYAcM% (+(faFR#78y ʖ$`)9; E +eY^i` Ih*(񠿿 ~ܹ(ۅ.Dd(Dй" Փ/iODQL2bƝ\n.Ò%KhN\xHuHdR?&+Iȼ(hk"Y6 3Vh ո۱l2$f󡺺$e܌b(8 k[ :S82NlT__fK&(*++a Iap`6+BbLkČR5cjg &f^[֝?W_}5GE 󨮮ǓU8UUU۰rJ JQQ__:S1U1_N ,78S,Weia@ IDAT(|zJIQ$_ f6WbD.lq 9!xX#"iZB4%fHhY-w>EQD$I*y ь㸌Y%ǡW]u$>F8*#eKȲDx sC<יY<ۍ6l6 Y*Ν;g,IH1G`E) fđvӊ7g{P;SyQ~z\pF:3gβb,H$ǝT~qh&frgzJ #(p HeX1Y1!2Eə # H(5XYTa5iZUcq3qݸ۱vZ$b9>N35A4 @8Zt^ BUU;,h8CYYt:*'(p-ZE\{GiSwWj id8L!dzisz>L̎Hqw."EQc2rX+T)yjYJ׋gOQttt$[]c.hdeA$SBmD fm IuOu˝?8We R&Qn:^:-{ txACC;6id= cA8 d鿵΋*UUmp8Q^^NW7ADj#U.Hя A3t󡼼|8{,iy;Ds(4xMuHds6%yGc>mۆ:0bۍ&>|8lcA0JpakttԔn bL⛕,B![@W #&_gvx<w}袋K/srY;V@„ua';,hy>iM1rWa4E8DD#L#3H wCUU\.l6\.\Ya4t.,n-a&6sllN4_v\}ոI yUUUn7Sh4X{n`L rM\vjJ1ǂD4i4X g`É' N*!HS/UUEMM n7׿"G5 ȬV jhk-`sW&yfZscԄ~###Y|63 -2A%L7Pef'Mx<477C bDH$P(YI;o<ڵ+鳬ڞ_DZz1eeeEHwu>4JeYTa]-ĒDdysVXv5\~ "('OHV?F!r5E9㖪ylĞ`p٫ih( xh$5ue+A 0y3mWJ%{VH<T= gٳM8V] !VϖHM&:#8C?Zl6:CN'" f~x=c<~ .+ٛ< EQ%6!IҌvgPw:yX8[AHژLy#uh4 ~( $I22~ifs ,I|[;Pq^eGn@[[hG.ӧP7l V2(`py늙6$ڀAb;qNy (5OwΖe`%)FdSOvٴ%&&!ܹsFPU @u" %ϥC„5I͖FyScc"{m+VK/M?RQQY@/Z(19 v{YKUUIW-A-jy-(RU%!xV/"18.֩VBuA8`tt xW\ӟ'PxH5SmUUyf҉%+ʊF߿YuJ07| I%& `9*3 LfpDA9XtLTb&BYpd̋a+~$Fݘ 18w\NJd4M$I$LXJǖi~8ݸkAXlndz678U /-8X^M3MJee%]As5$Zh| H$Py躐vpH9p8'Obtt4cM~$АѶ-ǔn?5((q7[o%A ,hjjZϖ0fx9ejNb2Up\hnn,tAXȗ(ގ'x";R#/YF>+g: ĉPU`0FGGs*1a '(& h2\AHIDQĪUpSg 0 ԩS1\1CV0(ь1Kt .^/.AHHfZJ-h!WR'  044dcb ֘'/Weq$غu+~?];aqXɆ dmx9bZM2%u . `=SAsIf+Ә,%^E(X,MI eXT*jU]]V$@P Zf,c[Bb* 5h4ZfF՗$ 555#K :FGGa٠(ʬQEQOZwv7S-rg_L#~KsŒZ1{yWҾ@FAXQQQzvSh8NaZ.]?GAFTUUnϪqif^1Z{2#oK_D8&b֮)1&b;19qDF8#l' f͆z7Nk@xn/yQ cmf&hAPQQGA9cN<9#K?yCd%#EsAweXD0888$I2%rզLã(c%U\o^>t]W\Jzx< ,\ǡ*1 TbDjDf[XIl=Jb1PGcET_g}<[ZD~XeeeYoA3l]~(X$r뼙w:|lt5AXe- '#:QHM1\B[~IC J|ACeա"v%,mcDi*,EkF s^KAXW`k^SȒ 17d|9+QC\ Ӽt&͕$JDyUUU(f /9IW G^E? |M$36 icAD044GfF(F+%}C#U4#e@8ٳgʟa%̩A= (++3U¡ @)ǞL bFXLSS)3 ژ ֣(^}U?ɓ'gEH R.4yFV%G\2Y7\uSOe5WAAE֢T G4m6c%{` X$ԠvN\ kS{' N϶-VtgNYv#aU4M,XA!)[%$23$Rf͔weG 4aknbI(k~N .\3N}i2Ͼ}G' ;WWWѣYb1NU,Jx,Fltn2  vك۷O*F01 WLm@'ک$A(4M,$L gilbY[D (@X ǁ0::u G,sb,S(ȩ(q6]y?gn(BWAD:^uLcE0K&pLyh - uAHmxz<22h(DQDmm-***Lp[,4:r-`tJ7ziB$(۷oӧ'ѐ)K"q -RL/sպp9͍p陸E6nTWW:s×\x^fK7E1zA#(z-ϋJ5PjQ 6]o-Ϯ<#cttJ7 |ħR)l۶ ob{_ xPSۊs9k̲%R$(,"jpJ~4M.r7xDA- FA Hrvڅ]vP(t>`1%0E"5 A%ĽK7 @ rZTJ8F9T GE z`M\W,$A,A^,ob۶mH]/F,UkNN){ިi-Fʖ8mZʱτC(A](\aJ *RXV OX ###A,ra&9-[ Hίv~yUUiE$I꾳 R b|R aPхP;3<4ME]6DQ :]8Z4M^Ӵk:͢Dm"^nH* X`ݲ,?~7oƕ+W,(VíO qE  B4HR(_c†(BHQ(fQ.I9^uJ`a~m|#E]F 0|%P)8.aw`QQbt:7eы(066UU "X@x饗p̙A:[F,H0@4AI:&:rI aG"@.mluJ12N8[oj(AGu C4veAQQ"q\%%XgUUAt`s^,gr\S1^:~EeDQa}$AQf~[0 1,JH PUT D~⎣nȖ61=dv>w ǭskA:# azzE=t IDAT%&[BA hkeD 7Xiҍp8LAm\.غu+{ĒN8F,,-_QKZ},Xe2,eT*5 X,@ Id2*iv֭b{|ai)asBP0 (JW,׎^j4ͪpR gϞիr%;`0!t n0sfkDIpa`dd@ n?lڴ ^÷7D <;Y[^#Ԏ.VP(@ l6T*մLCE @eLLL[a``X z= 0DT<%n6-Ɲ7뺾K b7wAܤ ڵ ;vp6Ĉ^;G(X ( 8,;7Z]8Q.Q.aYV8J$ITUE"h & y\rM,0%B(cQEQtB/bʕHA 088sΡT*\¡iڊ|>@E0[ z8 4 BA0 o^y啦&1B( XEq'wgHMӜNL`^%ڡ: @.C.ya8$IBPhka\rb&lACQ\.W {qD z{4 CCC4 lQk phWkN4MދD XKADe8{,6n܈K.yuA1uUU$Iʎ$ ;vQ瓉   "!8(N(D2lu0>>N>_KYыs[#Q IAĉyhVDH$-gsMӔ\JF;q"ߒ[9D044D@ Z،cӦM8~x:|z{~,cxx%Ak,EQD0tv컻50T*|>˲ ",rX,M`04111 X8a, ^hv &Jd2\r###TA]FxbK&3,Z`oE - {ɒED"A̲ r9l۶ {m8\׫K7XgJ68C,C4j۩iS2'[YY`0EQP.fQ,L`>R@dryn À(s pRyC, sA.8NLؽ{7x*?,PUU۶9MƲTZfq,%|\.^T]EQ0:: M !h\7|*tS1?K4E8~۱{n },( PU{0D8U$ 'n=88Ν;O,4 !H0 G\4 PdD,C.^|6կ~k֬ヒÇczz KL&nJ~3dZEg}:z(/8L>#AOAAR8nzA-J\ `Vadd$ѓAD_c>-[`zz}E4MC$izA$"B^{-2:'?IxCVPUX D:+M8(b_^rر֭sJpc+IdY]2z&JR)LNNbppJLu k ʲ t umxu}sϦVA3mܹs~ <\kڋ@?23JVfO}Sۿێ ?Sy_q("4gEfK}sUao00S۾y?ϱl-, o09& lV<#J3uYΙNpmۚTaz*9L'~?a/8s0 ww<׾io7&؛a]סzUiZSADQ_rwPhXyDUUB!p8˴ [}omǕ#G8Be(A[ @Q˲@ j `h=&0D/`xx@ R;vp&EY3xg<7FY~KvN$[VfBTUu  /ZƇ6X /^ķmLMM9߻pBlLAl)VR oܢ+p?$a``i 3c;xJ*YWZh 0n7X'O_xC>FC3_ŪT|MŜ724>{wKu|w󝪀ypRPU44dv>e(\R7鋢Hy!f3o&֍CŪF-܂/}K9e˖_rxacAeaAM`0Y⹐$ @AEX~v‰'s[An49^>\ϧL Q" "̴Pv),RnTP(DOA=MX믿zN](dY&h,MJEQ Fڅ>kps{lٲ;ChVYbo!bS^ VYFm:e9A'2KC3H%hAꥄu}*A+ѮoVGQ k , |AlٲbiP_ =Q6v U%o9ߴ창_UU`'`e,E%YGnAP(dh6b[es\ۅcϞ=U( AzYuT:p,Wb?~(טOBujJD299'x099Y)$ ,Ky5jD"s]&[S=O{/FGG}{h~{VQE3ll?˰\.t:=P*JYD·~ ѣNAtZFDϡz5J;oG&QL8}UY n\.cx衇pر@pGn Zxh6>W(xu,Wli<Ϸݥ ?L4&&&faFѠifr2lF\Ή~˨-JӘ;~z Vy49GPɖD;75I!,ӧ /ʕ+ >I\\s<ח㸪6nt]wDIlo|+tUUqLtJNX;RQ!IR7lL&{,r\.\.A%Ϻmێ h}|ń7x_뎻DB*Bb``!˵m4m4^Jܼlm8(i^&IUU1447A6dO=y䑆(|ҥI6|jK:Xw0&pל5 5a,͐eBP~J  bsQ*N;6Q Gg3?ѣGy!59%0@Ǽ}%FrAVzycpp$jLup睮LV IJVd` nwչn:(JzrL&R_ڟsrt*㸪*NW DyD" \1fcB3%x7$6 nĶm\p?3 m$I(TAy!b{ uбv=ywygם?骿ǐ l\2R)r #199t: S!FK뎍| ]$Ek뮻Μ9t` Ի`L^yˁD綠nwށi =1h$|>1'#"J y'X O"A1#G__uֺ >qXXyhְt?B 8UiJ Y&? |q6 .\?)D`Ĉw(6,`e%jYjUO Cd\۶k׮ \NjYn3O!T|%" LdJA~#lF>޽{}vŦ ݷv淶$1׳ i,k$J}bqD *X\xӜwOΌeI>j8m-ku8p e^L.yG8&? |eY0MgϞ/~ \tؤLt(M(AԻzUhTs+ݥp'P覱 N>5kM$.7麎p8iWGrٌP(1s|Eb1 l6_##K²I>( saz))1[[`%nQ-A bu{9xNQbD^&RIN鍱i8y$6n܈W6T77~?F)ǹOw^%,hԅMQ( }pH !"(4MtkEQbbqN(EOB'i8-HA, Nyf>|awʎ 2oh׮s=@Gmf<^8'f}+[3]#H` 8\sm *6q>[E fiˢD0D,7A, i◿%6n܈t:pb)i)b>"Y/ 8qn581ߢG4ͱ'J;DZa (:"DQD\niN2MS F (J x1Q[ |>M6a 7rAEh lm۷o32%4]-p|2hh4 IP(ZsfQ!*JgUPTUuK(=QJD`6{='W7rA(Cǟn 8Z\ޝ>}{;-1Q":۶=*x< y?#<$F(cm1t#ʬϮl4Mʔ13t[xmƞ={ueKEGED"hRQT|%Z*J,K'( bm4M>|pʎ zBh&4Q۶]WPvs=/Q,g4[N,>ԅ8w `6tmrNeX,: ^xG8F hyO=~kdJD:!J\cYV?L.#e66l؀'x#nܠ6 kE (JU]:;[ygt-JQ(荼O_D>rH˟JDAtPuPe_9^0"asF{9IDn²,=z/"RT9:k^7~%X 08J >< IDATrt`6&''F&[1LҥKM%W 3e.5mlt(1==)=l7M|)ChH$IZ2)E bx)U2rUU'!(Qf7KT 6l  ʎ j7rer ˲<j7w{uoذjϬ~T*e^/% p%{uuE,#{2, (-1٥QBBB$b1ȲLw Hwpy?u>01bs[:(4(- 3ocI 4Mky=3kdJe,3MeuL. `b]4M[Gļn&7,,Ѳ,d2YKr鴯ѣ8uTj_hb@ 5v D@} Ǯ]f}6z>h@#JOf3/*%T<)%` bry9P(]nDo( ΐXdO>$u V0 ly5 |UGm<=\.GuJ,l6 0d繲(@% jwP-qѦ8v"iBP˦3Q\(11YGln9 HL.  4a#,dsz<8|pf#~[ti GmeYuoԂ<3l%Q.,hiB :w3q…߂\.WW4ϢUzl|w_3⬝K1g2eoY9 ݳP GyW_mK'AQ('@ 0`* %۶y9x2$@ZA ǹmxw$D yԚ2tl`6rߜ޽{/7 ZjϭT*!9D3rCц1+Ԯ(ɓ'dߘ e{|tT.va-t4L. G ۶|>7իWR);3KRe|>_Fcx駗z-?g,+J4Y$lF&ҍ.|%os0 [n%q |.J躎`0ma.c0uS@A=3[>}4{9mdGsDTB&A4m(X^3o UU!I鯿:t]}ݷ$w^g? B0P(8ףa JQ9@Ah{9~ELOO# %i DQlX^d~P1P[0xT)\a2$h111bAX͛??r eGm z1I& $zXD*ʫ^|Ŧܝ䥗^O~F4ME';bzzz,t:bHrv];X,bΝ$Pep()1&z)!4mՅpL. p8<}Y\x愲# EL&H$RidE0,dYF0tug}Wql6GyǏoU[jºLOO4Mrn @2KaED$&Nڶh4J%cDQD((f-,R4J)|2C^zI6JNhe~P]AMW2l!`&D\h&RTU@3;v;;vwmI`}$"#N4}NW? 7GB>FGЁ$EP - 1۶%/& I}Ε+W3ܹsAt^o+JK.C&A(zTB2D<wٚ\+|G}ݸi$IZs?1.]tS{>e9|^f2 .nn=wץKN2 ~g**vA%"FMlygqB̽{b FAD"]ס(JXK&e{BdX\d7ӖeaϞ=ػw/8֯_Q"ԟܲ,Xcǎgdvp Llg"=Ӻ?pWeg8{.Atj]!rKeY"*8ъ(0dYdrI,/155g}'OSPf.-kTFFFr) Um;> nafzUl߾1661 "C$<۶Q(pI߿SSS9iVFbYcޙdӳ>Bt?i6A/dߏOӴ#*rL ˲xToФ8DW4UPUC_D>>eGK7ܤR)hְE;+]v&"HU6 NvC3 ˗qe>|xAur˲P*N D"11H eY2kK8011C9#D DnўK a/~(%ADD=~:A#tN=zjC϶md2R D|<Q;f a !L:%s @EI4h,GsWB+##Ÿ`0Y]r,Q)h(̵Qq{ H&hgu'At:b۶Q.qUd'NiItT{d\9 lN7H7 |8̳-8Cv`Dnz-lܸaA>ŢR)@DYep~.a4 @i*f;:,B>G&APpl6D"ђ7VZɦ hL(Qc۷(A>{ؾ>bC0 ب\DK:4MF=YL&ظq#~_5TF;X,Dahhns`Y, @4iUcӶmEey ]םefd2E',JF6m9e%Z $J(ѽ~zYdYN7 |,N[PsJ(@kWbm< `0H76LGJoD V0uNLL 7{, bR |,C4Ȳ AUɼ>2rgXNئě( LEg>0 '> CQ" B$/mA9}A`$J|xXUR)Bu #4;={`bb#-FZmCCC E4L&>nj'8L*E(u۶ayQ*`D|>l6RIX`>X{ȗpmc޽?N , c[P<,k`F(*JHAy aضm~_0ϐ%QM"iih5&''CjM~-&(&H1˲ =L( U^w&Dù-L$Qbz1S+Lt8FFFDytE!2| `Ķmdځv9A2.\-[̙3 * 7IR0 ccce+ ($qf^t+-,˂a(N˘=c6A%z'(`ږeaΝL7 |*xoi`6x ҉cUQB0d۶ecFY$JDwnjJN<͛7c||DD_rΟ?19{\F:$Ie@$'3uw(35M!iBFi*$ }:ӟ{//~񋔁M>yhM<m[%lg%By}AtP(زe YޢMT… 088h4:&.bl6눏;P`*rڲv`$l(ApzE|կpM&!rC9)Pm[DiځT +rxװwކiXdfIeM~a&Q(044қF&P,=.z*2 P}RmlD ۶c%‡58x欢L;ynڬ  xꩧ{5\Jx Ta啦i:6"@DRkxyE$IDQ8DQEy$bttDf;Vn :yM$~7$ܩ$GXĥK0>>b\.K.$H4W4{n(1:$Iҁ P)Jh&JHAzYDQ$Q Ht.\I K]V c>HԔ/#˗qd2 F &Zetoƙ3geK0g0yI IDQt60!4Mr 0H bAԾ=p~L XY9WƖZhFo E  VS k B'xG!A*֭[|3q~6X|,BTBTgl6J/ /O8o.AH0sTeD7bj]gD Nx%AXj!BQZ Gq 7T>Kէ_:F>n۷㦛n} A,1$IڂJ*-L9Ӽl6RB7G}'O@h!'B`kŚ5kp=`ʕM 4K/9AB7T= ϟG"@<CK,J Y=e9T.c3 *CE/3 Q !H?Ĺs&D;V;ghԧױc{U=TA$JIΝ;/~. A,!VQ:p98l`,B 2TU7Aƅ H bVQ ڵkq׶i&G h_: bE EQ(C&JDms@A, }/^[iCG7-h$0G> BE,V>[nE"ݔ%A ]6`qDQa|>G; Ijˢ̋-Km.Q"2z Nx NEe2ʈ4 W'> \Y:u oF]@BD##J0}CJK(DˣT8mn$J^6nM 4l4z$˲`oxG0ĺupwcٲem r}YgIDgy(: è+ZCztk_h||/^Ċ+ %%4Mk-L-k T\ew >,#|[ߎǏ.ۇl6l6\.5)*Jκm6|ߠ CKhƭ+mfU;s²,Y?VyBAK H<8u DKBD+Ypvwddow:Ѝ"*bz뭷GC=_~D.\$ĉd2tqbD UU=3{QmF?-3D X W^ѣG6$H^!?u]~XjբY?9yG"ՍqYggعs'$IH( H %R ýK -Jw5Pe9T*¨x\kU @8Ջ*jIh /ܿ?vލڬ&gߢ("`뮻088ώmۘ? zQF 1::X,spF| ѐ /x |ӟk^D ۶!J!qW\7)"ԩSزeK] Gsײ,cŊ뮻n:hd?99 6`jj)U ڏiNl洓q TUE.H&y)3=='NoCK0eY,˞D UN|PDml eY( "rxNG%q[p/`r >addd62A'3h%A (0 G?W:a駟vr A/D Z[mD$IeىEZIs˲x/ 5xٶd2gyu3A"3$ X qw" :SSSxꩧM&E dYv<^y#Jض;wb˖-G:z\.}#JPf,mJA,nI/8PijE|2%H H$Wm KoSGEQ000u;P_K.^|@A,1bLh4MR)d2b\g62o7Zc?s &''188H i N`T%Daz{ (D{( Ot:p%)@,P(+VoիiZ]K4qku-l X9.LB4gfvD BU)AQ"4}v|_ C3ee۶!V*JPY)X"6`Yy?N &l*q-[oʮ$}v |DTիW188I+̠xm='QK|n_ %$Ir7ZqX'Jض-x4JI!|qẅ6`  o166Fek5Xil۶ G%A |8F3 8C$qmݘbd2L&qK8fA(NkXO|.A,(*v7Pܢ2#Jp^'A 8[rkq0 fDZj*vmX|9s- t;wġC ZI T*b]םL( f(˾$J4_w{P۶c| Q8 3\)meyÝASN^ (K1l  dY֬Yd@xq&],vڅ{է A[w  AmۙW~l]wwH&8y$֭[G :WK; L @d/I)$6lPWK_~z ;W^k!T۷vjhGiftIDwįk׮kDop4Jm|D ?T*UF֯_[nXzz.幰kV– DŹ&tzMt ?W\(](!˲'Qb&SBCM@2ٳ7b~SO=˗/ .ZA@8qw`hhQkigxWI X`ߝ=믿tq9Sb&B% cSBiشiNop(HAWmGMصk_7Mkw3eX \s V\H$UUg_G*ev^_,o AĒc4ׯD^OR ;w?y8qa&SB25}AOeJDkXz /r֟~䂝#0躎p Xf  ITuhv}'Z"H xԒ %nQۇ{,!0˙BFѥ*r[/%Ν?_g IftMhSHlh \.cϞ=xWH bI2*ի_;đp|cC%x%2%x*\Q%4|IźqNl" իvZymisչc!A]e++r'b19hQڃn߾wuDX@WNL 6QbH /7P7nիWN6d,úufaz˲m6+$H9_kΖH&8v8с&ח$Ij\ʔ8zJHD!A!۷G?;{`aM6U*H(rJ|XbTUG^R)=UE)KOw?s>acժUxqwxC '&LLL=_`BHuFFFpw28>(tkЊa!mOeF@Jh4%K{5k088 J?/x饗H$ Bir(J?,vލ_ !5͔9 BE J%~m900+V`͚5Xr%h nQ8UVaѢEUifa~wC@aضǏ7߄i !֡N^G)Q݁0[²,ܹ TYG,%B~ߘghhCCCmr3@9o4˲{aϞ=0MpK!]Mŋ-AHG%E50݁S\x^Buصk BHKsUZRإ̶m\巊bR#P(J)DHHM8ՔmtmLL&W^yGeM!I0B[3ia(!UctL B{L$~̙3Bb%̔l;w޲k!sߤ%DLw%!dr3 xp^ BH̳D5._30s. @*%$<7!dGƋ/D" C!`xK޽e18rTTM}BϏ07ZCa˖-Pm_҇8{,CH L O~?!BUUؽ{BZRAzu`m۞Օ2iA,%M !ԑd2^z };lBHAQ7n_|RTepQ8BH~:^x?!!b3EJ%l BJ3%Bcll 6sm)}:99'O20Ty/l *EaU"7!m}~!0 PA0[qٳ28 3%oJABiؽ{7oMӊhB!ESjޟJ'00J@Zpo`n| Ơ( n݊V'p}x(͖8x iy$-x)AVs{frr/">Ya!%C-E$yf8z(CH5=fHb &b )fdd=.]`BFfKe!B)A|DH)V"Biv阜:u oH$(BH\k E\|CH),ߨdH),z^<3i8x ^yָBWT܄l 8r%](A!|)̐1ضmv 4koB!m5_wL0!2>R3oF!_*g /رc6, p,(J, %"00i^SBj}GGn:Mӧ !2K ;\fK00 RXeAQ8p/2BFBIiıcǐH$BnPz%psܶmd2[ؿ?, e74+̖uc`ü<ٌ̄n,kќkO?P !kM\Oiɓ'111Rc%jߌ!۶166x'vBiwx }`&ga`Ϟ= !7ط:UoP pug0! IRQO:194j^eJUR Mo~T*ŀBHt⁜@7 %LĮ]BV2SR / / 2B'5@"ٳe`F0s_9NߔBӮ?*TUe@!T.<$\Ν;QE9!m=Gͷ|L ވ4w^l۶ imx!݅PXxJ%ҥK !ض]0a,M վ)!t$c۶mؿ+RBč~,+̖, ve@JH&-,pPRQU n !Ȳ͛7O>5or%r3y9(͖B0 jO A BHLNN7 N>MB 3%(J4rfKضݻwLDH=QC(aU`B\~/._`BH$ Qkpt<;ʂl qL R .A!5<vFI8\Մt"xJQՙ%;pBIɓoL&ÀBH 4Q4G0>>'O20#JfeJX~a!?cPUh%BnIc)͖p{)Z =3%摞A!miطoo06/+ !vN̒hJ%R>ct,HZ0 E oƄ;v`߾}E B4K~EiÇұߤrYǁ$IlB:EQѣ!:i hnDQ,,>L AlF(!ME BHGJ/>|X`D!7B7ׄ0[=T*[a: !cI$x饗pܹ (" !@QBHIl^{20Rpd0zJmA !+oۋp8 Q84MC6,0 YjD ,(ѼHTtN8˖-cpH`YV5~0SB[aYE BHqE5$ DQAAtwwcXx1XWLH:ecFkQ-a}]>@ LyA @ôRQ7%v̙3~t:]MM($I&4 @$q,[ CCC ҆F.ϟDž QV @+4TfJBH;Oǎ͛!rPM @oo//^ƢEߏ%K B:N(M(c0[¶m|!!J\@Q#Fݍh4H$e UU?\nJeYq@(/K !zB!:BE% לR QjD`rr"m=wm *,(nPDZL|nE B&HQfe>\awBe3P(4O㮻bHcnD%{{ΌP)1|#=VIJ,8q?|Zagtd( t]G&A.C29  B(:ಽDoaeYرcM/I[(Q)(̔ -ϟǛo|>ԟ3" ˂%i,˼ -D, \5y[Vp<?O< o`Pʉ߉4MOoO'lF"aG(`:;"!NC4fIBڒv>3K}d\k Pwߏ~\VG  g> @~&S"\C 0B˲wm9˲,iya,0 hVTJ!H\ڶ]Ti;i-(tM$ `{0;'? 3dHg~7f;@TfR(Ai{gݻwdf;ײ҉A\E>w.JM/O:?ϸDҲh>%ҖA,?i%!Mۻw/vR3BiA^.KO5KM/~mr9T IDAT,3#\%8&JD @@Żv2k !͈eYسg_MdB! 0KLʒpHKi~KmV1-JDec&t]MDi* ;p! Ң(,? 5}.]%AeY(Q)aڶQj-˂B]ױc|L !i7KfIQ8 o ]Rض홯 cR.%94jD jBMӰuV|G$!4pmbDg k{1Ƽߎp3ziKk(aFΏ(a6E%!ᨪm۶ĉޤkҚ].K" rj1|/-8t^ @ pĂHp{JQP<^{"ABEAfLBH neG(RhC9$IB0~ix qʉJ=Uf> *oE BH#Qq"A:!(T@/Τ +W0%cRӥ8eEL:EœlRr^}U9sh B:@ %Ipѿ+-8pFGGD>E Ӣ 3\TDa BYHdYk/rq !a]D ۶gZ^Ǖ▜hm۶A445iV#JXE @ZŊ+J0Ed2l޼gϞUńڴ6:?,-8|0HSc/Qb01G %&u*!dep9Bڐv%l.ڨ v䖇/_øx"I0:ǩq@%4Ip`)R ĹsBxkZ%A $ Pؾ};dYf@Ia64Maml`(aH90Mӄ(%!u͐8{,A!<55ijJsPVEqvͳi1WE1@i,Mӄ,˳L|!V(-[ >Cy\̒,8>Nc4\(,f8#0ioY zMTa!(_N A!mNgU,t2ò,H& 4i,˂u0n`6B,L +m 8lۆ,%!5G4l߾O A!mN;,J+`IRx뭷Njs+&u]qdnۂBjaؾ};N8AAB:V?ܒp>}GepHS`LILʋ t* !0;$!CheQqY{aIXAc",]vadd'M_B$@R,Es Mxe!ƶmٳG A!D+gض=kc,΢^{I k-[ 1褡UU)gseJ$A*Dǁ%!Ʋ,߿[_BHnY`  jsNK)Q(7c|Cq(w"eBȼ8rϹB:V% (lgvg6| N8uUU111l6[]ضR- S(~]4=MBfr;vUBPZ5\$H=iP۶ocll' _7 t###z*4MX1)᩹D @0_Q"ϳ-(!*>3C!E%, M0D ~uVѓc&,FGGq%#z(cYV@jFw^ͯ%R~<%lۆ,AuVҡZmrc޸紑ٳ.ض|>1`ll |C$Ff7`en&G L[Њ ˲y bxx*TUe0!Civ nPw89+V_*Oj6it:)r9 q0|a3B@)P2撥sn Z(8dY뼂~:6oތl6`BH"IRx!`YdAP(䝽,›o%KncȼuLSSSfu}VeY^DDQ0mr/f<Č(Q![L&yfR)B:pJ83e?? ?l۶m˲Jpe`jj 0Ma2 W"J&A0PAQ".L7o[4!˒,ɠ{8dYq -|a۷qr9\z.]EeYe_Q` @Q\(aWEt]G>m-kR_4MÖ-[022`BHjmʒi(p]waڵgxEQH$H$ ˲qk 0M3`rF85:I۶~ۂr9_mA!iرcKfTBiXmHIJ 2XQ(*omٲdLUUŋE68MH+bi`T"JX&E+J!mc޽8v B!YlK , R4F%Jd2غu+YqUU1>> .ʕ+HӾ +ݟ53@n)J̴H̴Fm\8!#GСCM!ݠF4>VBB_ŋq155K.HR, hlRt:7x:˲Nq`||lΈQB0.jd2@2d0!o@[,HĹsp!>8ncA>'Fr뺯[t%@om  448:@t]ǶmpBH$5~. ffāpw`ڵ`mm4 DSSSP 1.iVAMӒΔ0qEQ&%IZRhY4paXw}gΜa0!̢ZGiQ7Mon hmuT D|+xtEJ;o̡ )nR1㈙!'Ͳ! 9rGez !rӦ>;C 2oeP(T/L&}vK0mCQLLL`xxW\,bY^=! 8άJN!ڂ!Ǚ3gk.$H===ꂪLjNgIضM Vx/>yp"N#L"0" ycfژΒȔ]n;pظ)fQdYF>!vnJ坐 b/_իWP]]]D"$ ܹsxwxOp?D+r80fK%ߏ+Wbռx-0t]G&A"@&i~0뺯´eQ"( J޸8R)l޼l I(zuhwu֯_;`pֿ/8Dww7nmd,R p3 B+u[ljR "bDgt @>}*Ȃ D*}c0d(J!֭[q o8#/^˗cʕXt)z{{}?u=0^y+q 1ڬ}$H-iqKXONNbٚ $2 4M^&~ہb B[04mR,Z݉=BuB!*B۶w^={ AEaժUtRDQ/K]O-[xO(Ljf=Gt(~H$R/qi9rO=/\q;Yr9LMM!@QgF%J 00)a%DZA,+*6,StbG!m`BtR7n`y a7AH$ K,ƍ 6UEIi&y;v x(Lgx@,>z녛j|%Lu'nE[*lۮY+Qbf`tCU"J9\ .`ɒ% jJ—_~@RMa$ދ7bŊMmL?ۿ[iֶmHDa/͆m۳\#Aj=$! uW:t[DjGe:2#k۶ UU}uQ-h,$ lcccP *фgϞŁhlI<E-£>~===-wD"xg/ކ+|DZ{7.#!I}$ȼU+ Whj&oߎ!,]w4My/3BZsZL >gJ8p@BEDz.ENۋE!1s"Lb˖-M#VBZ ?8򕯴ߏxdͬ$I4%aR@ eDQP5n6믿@WW/p躎\.T*UQl镛|ea70lܘ1*95MjN,˂(8188X,Ɣ9BZ`bݺu+RAHn7%K47DXt):rPlF%.JkV8(wz*oߎG4ad2HuQ(D,dvv޸Q+Q" $I b_0 |Νc0 $>(֯_X|{oo9io->ĭHɓ'144o}[WnqnSSSru1tnԻLc834GAsq RXW.sE(&I8<<ȃ!s etjƍ166u,LeIGP I/8A|k_.;ˉ\(1j6V]$ 5LwМ9^\(5M3)B e9.# aѢE̜ il߾}fNEA,_O<^#aZq\t6餺,7H-g|900+W2@\.d2L&]k-fF  ;o3Ĝ/T\4m<,4@UUq^Y9ӃH$…Ʋ,ۘb0H pw}7|I\OXՅGL&CQCi, H+5eظtT \FQkQgDT4(/E1 ʌ(aK(qC$4M fAtwwWz)d2q, Ǐ΃MY$ދ'x˗/g=m ꫯCi ˲f= I]֌v>p^{5kEv#R$|2#)*l}5䝛|?VIDQT,J^dvY& dYLNNb``}}}F'#7n;zpqh4O<.]K[/^ѣG)jv(6=z"IiBQ \~Eر>lG.ZeF$ Ȳ=ֳLF̧nWJ &1)qZp?DUQ A]T鮅a󘚚B?FRct]Ƕm 2A:H$O>$-[FѻM6axxׯ_g@:fiXGBEH%$IsƝ[bvZh-.+'ܾ8f}/!5t{= 3$ wy'6mڄ;3w??瞣QnSpJ$BD Ց[|>T*T*EQ`f]3#xe ͚]z?5t' K-Ǚc(X XRRd6E٥queT'(͋/_fOҶEG#.#u7fCJ/KredG<"NOEo] VBŋcaڵ\nYD"m&8AO̙3c\h{T٘MK(JB"MӰeqX従mY2H y ~daxv >mUTPKa $I64BQ|r/j>H&^ǎB!Tp8p׮]c0H[ذa|AbujE4??c76>5--$Hxa\*~cѢE-UU\T l\7/3H NCe9:6nQ0)z+\cv8uf~:L:v_[qA{" bxDZrJaf59X [o1#F@(JԏrBϝ;۷gm3ad2^' W$G' +ChTxm̈Վ3DE7kv96c^Qь}hX,֐q3Hbte&}4= `ѢEظq#֭[VaÆ 8z(694zt3 fIFS$D""aO?EWW~4l6 lT LQ73BEDƀ$ IDATE:t׍ €T3Z&1+a Y100АeYe٫)^iM1I'i6H vZlܸ˖-cVD  o-&F  HP(unsGA,3<`͎/줡iZ" rsQjId YREQ!WUa!s?iHR)foo/ѨCH{iJA }Q<ڬY˗/˗$}?aP >_tz l޽{裏4Mz%_DmCWḧB5AǴɥ\OQBp0(JZ|"%mˢ:$,(z{{ߏ.NdttJTAu]ظq#V\.fE(?!m;6m2]i ibx"Fyiiψ^"AlNYe_"(0 c@J˷(8%e]Grue!-٥0 /d===E<G(N0}vh` #$5\(!Mi+Lvu[nE,]wU{4M/"u@P053krYiApM.8XQ$1MSt )|>5q|>(H$EP ii>c0A,Y<xq>=-b$J}$(df8;:ЈY=ʲ͛7g?n~[BP(F-=뽆W;)(lZ $9a\ #$ +y?L"ö|uL^KQV$H`޽, !`ѢEn:,YeժUXt)FGGysЧi4J)LBݘil޼!_qetL|X`&^3Ӊp@R W*J+4ͦ,낸|*B.Ԕ=XHZfܱcdYf0Ȃ 144{k֬eDxpDQķ-HBD#: Hq;zEHx8^{5g?C,Xw LFܠ(.}32 ԅ%tdY*UOlۆ,M+q+q1 ûYzzzׇx6(v|D!$y.ogE J42LQFl4M+*é@(k:tg70i_ ҟn:OߴeY0 \hx+`KQ t޽HR ) ```_ױn:b1B! m"H,,'kE}$Jk#A=G3\ Q u|Oݍ7" B4O Ƕm(REyLO+EQTAU˲*U٬zˮرcTḮH$x7nŋ',hk\zi jXFNHiVAϿ0>vc#;"Oms,˳ķ[(-(iژ(wWm|]{\cUUJSlذ Rw7O6$I6ռ|$ $ D+=gmLwuLH+p1b6vV{faݺuxꩧxb s8ѤG PfU5"EذaC[gѷYյZ'a`2QB0&DQ\QDTѶmضM$^D<grKDQ|I|k_C$A4 \hB@ BA ЛpI_PAj D8|8YL\ .J8c 0@ @ž,CUUtuuuŷ, B4d2h__0 ۾&yZ ַj*1dmW^Ish6 (HpLQDZNNMM/C=D!^4/L OBk6+(ˁ@14?_8ϣe7T}Su͞p1vC8vFGGRvΊFqBEQp 4!eyLAOOT~:;c4" aݺuxg044Ġ;r}$Q)-EQ^ bѢEF7[6$&&&`=\i  B0,lP(ŋ3H 4k>$cUjAbWbi/ Wp7^,(͞e˞E<GWWò,6wc=7"1 )(|ף{0HkI9DQҥKqwbpp^6;3E,˗JQp8@„>7M'N  -<?)yxk7$I_ $z_%Q=Y- ׈Gud2aq {Pۛs D/Axb<3x7C~a8}4FI328]bn y Hk֬A__\K.yeͶmctt.? ׄqa=3iǏcÆ |Rg\?.Hf3~WܘJP5 cB֡ض\.Mڮo[6Ss3j ꢢ(H&^k^DQNmaصk/ҺsJiʕشi[zBuܸqh@z*M R%K`ոFu>Oy_O3g[.J8c pA`0ܲ,_,mo P]k^d HDNĉ~:!@ k6.]ʠm{MKhlIlc6 ?y +W$IF tQI #Lꝑ4N8GypAYUUUZC?Qb^ֵZ R aJ躎|> K8nkd0994l}dY޽{i>bD8?o~`PHKo8)X%ؒ59/2|衇p.]eYxxh(1 晣RI|x衇Zsc3~+$I$řaW4 ( 1?latUIp!1]]]^'?D:f Xbظq#{1q(A!J#6>ƖRׇh4ZCH2_~{ D,qs,6@˘pv$Iƒ>bRZ"`Sk*T(kJyh8 uò,oBd2D"E;0Zt>7mzh7M<#D" iyq4Bp3$J; 2h{hVx3xwH~gزe ĬCmi6m۳^$[4+W  a͚5&j(J(2#͘zLtӋ%DZAhP(ton K>G<P"Pnj+e J!x)oX p7|r!(@amhhP 5/tɦ[JZZ Y>J$# qկ`۶7~{qw 枷L+/" {aj0G+EQ`YVEL [Q1WM#Jp @ M0|)weY FhqknS7}'Hx۽# qn$>nl77x衇x%ӈ)HJq*%I(Ə+BM#"t]~ Y$Zcpb\Qq={@V2yZV3$.c&%!'B&׉0 M00MӐ099OAj±9ݤIkŰ~z<`RPm̦~!7~?_BPQC- gjB4Ȳ\|Da٣P8s"TۭQӴfA i?+N Z+?@ _J(š&' żH$B!i‰'_\SOG$$I!u>QlI*nBuD"\=dR) &ܒ0w9u -[ Usx4y_ aΔRYGKF$Iz4MA4dYqcޤaJ2D8F<GOO^|ٷo/w\r+ Z DQ(Vڅ4MdYNQ@yPad$ zI41$ybݟ |} gW(5tT3?(Re3v MӠ*<BAg& ׹\ǎ)Ĺ P:*֢(jΒĩb^Tp:_ _TeDQPl)5.J&@ӃX,sfI4qw>nvp R/\9˲DŖݸ5Mo6'G'N?!Μ921:$H6'$LlnnŋxG8?ӥDG,]?2D֠Ӷm4X\\7Hxi'Νmۜ#ļK~Q2&5C^a%IX$Eo!szdEFPy dTt7✇uׯ DV$u~Pa? e˲z4 ÞS8,B{ ?89Xp/'$gl'QMSUaO };)LȲx`(`&,Jj8>㽩C$I|i7}Wz0uQVq1Nyfqjց%sHx`fRD68.TUuhH7 J.ɲcY{UeFQ=9iT*AuV|>I-\Hl8s ~4l!LDQĽ mz1͒-?I?{f'a>$IgB'uCeضSa(bE7\4MSUUUA"=rhBXmPr9VL]ס(XZ+ߍ1Xes=x'p]w11ͤA IDAT?yC_1AEQTd~0!2ᄅ[L(EQ(I'r'R8=JE lA?GVf4Q\/B$*Ei,6ӧOgSX1&e8'HtZ Ð"떮it]F"L?@̻W""w}SkIl ϣ!ܣ\VG${f( a(|[oŁOqh֊rIgΜ3ɸ Ip٩& @VKucע(jh(TU4)j)dXaq4 (MZisssr"Li7>z=ߎg}_9PdYY;=og[bqC|vLq# .}:uV4*! W^&\I{o`,a ɢ@7%S#JDQHA AFᇮhT*Z 0 r/adJ%ܼyhF"a;U[AAwC~Hs[k, |I+Ǥn\hJO.'沖!&oaxEDV,˭B|\/˚4 al1><3[9XLע׳>N5VR N?AzHVIF%DIlo6_Ȳ)z}$)NuXlpe\.z躎{@Q(g$ ǏǏc{(B&MdQ8(ä^"͏Y.DHO>aN\W(`&LLu(Jl6 :Qb7 ~R8=:5H~+ƍ4EM~tE]8̦0~)0?)G&u2{cvR8Q,zWdXZ6 ”]m[s,xgq)NB'NZ ƒqߑa$Щ'eЅ[ 0g}<&I]7.VMpT*=zthhk k׮\祥%G?C=Dc){ūʁ+r([ADa$}ܧg,0 sL0q a|ѫ{n.}u TVm{">.NP & Ùn(JV]o} 'bȉBr B'쐂At tAR'm$ ;$ LHԖ^# e}7MTԩm`'Jbcw\ iTU}׶`a燞%dPJ%83nڞƳ>ok)&K0gb=f%ňn]]L*.&~m<裙H z=uꆪ%XE>QU>SpzC,[2 >䓙#0ܳA.//g>`P(hp0vǣ߽oJ8Hbl lIfQ$R\.㭷£>LWQ8N EQbĩ0bEQ4ȏݠ Ayޞ\$Aжt]=?~a0̐~ZS}9auݎiCmة% 1"NDGL0aFzoffJ5~nDp?8w ;i^MSFpTUdbY]]9j6p?1|2cȲ{7AqɎEblEQaobd ;:: ϳ TUE.kfo6nܸ1K0 Q`fϾH}3n4G>cBI>𑪪_}geu]evm,,BA|g3#F7fI0??~<sM aN$I8<"\zj> {mFZ% meEx?e^CNDJZ<i\ׅiS} r˾Uml66pa*2 @.a皦u LמxsϡT*M|~AB~(JBQbnsO4IH{c>8mkkk :Y_aV4ʹmW1LQ$yއa㿃(˸[HfYYYVUUq⮻:T(ZEm῞A$XՊeMbE PL?n;w/Hv FmCBah k2<$Iju]zq]w $#"MKUU]q>aE8*K%8{P 5 ͓diqQ|_Ќ%u]ضf䫪 ]ۢ* hET ֭ d2rox饗+ґu:9w"dgztD&2}c!#;ՙW^6z衾i9P:`#JD`'Jb}dYi~Ct a۶Q.VT$xz>E4w}8uoÒuݎJ)POB B&Cx~Ο?^E|'!: d0x&2xaB͎rZ߶uV,+m˰l~+J%I$i_}g\.BulllLl)!ôs\[ 4!>\v xqQ;ii \ڤ6>(3 aV nxCQ˲e^GZPs2Y8ӶdbǏX,"Ϸ%p-f&;Q(.<ۗ. \%`AтJR&imًA~# :.a_җpiϣP(`ii ǎv8<-RPQ1[DoӧO+_ :z*o5ogϪ(ax44MV,xI&)Ǐȑ#-1Bl"ߙ ]!q6!YpSQ`/_L 3#ӌ뺙|SH]8DH%XrL^/4Mk{ݺpDQebˉ%v UIeXib{{ <(Jc W4ɤ:A{\$Tt7I"z=BgvMjDYy&f[;f 4[\bO55Y P7PUu]C(r z𦪪uB](( 4"ЩV#* 8s 9JB'vvtuZ݄a_2^2 C8q 2* n=}6˲PZBeY!dA6e8E6ir&=ϻ" !~D6MJ%4&PQTZQhrOP˲>p@y>$o "O<].;Arhy)G {k8AHV)mװ/DXBQbAL$rNu%t]G^GXDX8DP@>oJ#Z:JA#1!Ym@UUǹRۀN(^eeh[[[XXXL͡ɅBgϞѣGԎI-Nq<҄fW^ߪB`D;ps<&Hą m\. P[S(vlv+ҙ7v-IW)" o-˺iZ>JL,'Caeee݉'ǎ]2!6_BJ?Z; Y3mlKBTd.hZ.%A{C?$TUu\p>";SUNcAFؓ٦Z >{,~͵UF*R$o3:91݄^ OyO#%(Lt ES23:ՕXUjj!VX BBzmuo>IyRsj^2MIMӾy^V±c077YOʠZ-,,̙3X\\ldw N~?'MS鹍Ba7{!P?=8Ɏ0L bJu4 ͵"qV( Fg! 6u5hĈn1n Ykƽv1X0`A"eru+LFeA4DD{:B#H=@iW6/JE˲HUz,| ~2DU~#Mp)8q\!=N&CE`E (J) UUaFfyUU?aqaq A!$v#۶x@u><,ikKTUT*"c}}2"/nam-(HBWrh?8)H׋@BHD6W}7E9~pa777Y r,z7$ayyOrt]o+FAB`ǔ>y{ M2/HtC(J2" %!װ1q\9sAӴTRZR'm(M,X^^ƭފbbB%ABv,kh?-κ &a$IjK`1!+i+J.x/"x˲,FKˌ C20c:@Qu=N#Hɬ?OBM?.UUL=WM1e˲4-S}rZ+9|${w:؋"q)?~|B59flIQbXaرۄ*LMe !#e9.8EVVUzێ0 aY677t$ ُf YsI$Es=xHcBzg{-áS[Y$DݨIs+Ap hdUDI|1ɟZD:MӼj*)0 a&677s!4!rBl$ĉ8{,8X2fQu$cxO `O$"" E#DIȲyw;Q&} Di(J }377EQ΋wo|$!ĝÜլ#1:f-h7ABeLFz0DIH]}.x9cNC$I ]}?6Zbkk ^G"< 0ĭފ'O%oq_'u$F+JB{EaS,3˜Cg- a+H|MF;mw i~OUՇ}p][[[8vBH*<;(p-P(@e2 QSDnE<37UUaS7D] !?4ͷmvR7jSq^L -]4Ah4b8렾["#hB` ӌ^(1g8 iS)HL{&)YXi,(kKlmmhpnP@.iuu#GBOpg_V~6v{>]yt]yLE!9dD`eN˘SoxGu?:677ɒIq-X,;! MHQ(1(:9a˄%!I67\{Ï缊hVinEܲH$k)(Y8%IjxI{K$TU ,˺ eiyJ<{ Bfv7'ّ}urfzMQ $DIȲ Ypi$鍔w%!W'ig_L^VI0f&E ^;%Zu K)t9UL(E a!2KzXg$/&V[QKEQg2'h+ҳw("JEI)7#iO򎐽!$˲~7( `D(<Aph u!S(vȘ̈́(15wu%& !{(e v$~qڎ{YqZ}J%eFKB!#X,;q)Jtt> ֕ #"+ Qƣ$J3 ]ݴea}}pB!#$MrJIJO$I[^pq$ًDK|(JS}eJ%nBu0E~5?+AH=0$l۾Y3y'si%(jEKضG!`x%l2auݮ1:ϕu%3$/up)Փ{ /,z_UT%T*FKB!Y4l(Jq 1g˺dD?Q{fvjIgjxou]om0M+BUSt <σ{tú?}֒|߿ eR0N_yQӴT'cVxB!dm'x=npȲ|>Cu%i߃ ,Cuu]%Q3b'M<4M3(QqlllhpB!#@U:kWRUUymOzu%i/nOD;́صmDK4- zT ! '& A9gbaPCjI];;a^NLxϴ(B]մbssJ/!2dr\*Ǘd,f9^XW~O PPU52M^p5QU~:6M-]Sah`}}r$ !!2??Q⅙fPmA0Xrİe@O- Mlox5"kVP$"W$Ii = B!C[n9#6:PRtQ(i#F J%$ iW>S Umu]׃-B-l`B!CdsB&Sg Y{+Afȏ+mCeZp(YG*{w-EeBa}ގg54 C۱ ;#C;mb2A(4͋؉X(Ixt]FK4ME(!2Dm'%ņ+u_t`tDvHN"!!ZBmvE3Xs,z_QT18ARE(!2BǧK&àAP(F`] 2Kģ$ҮM|˲c'JbIQ"9|x0fڃNṾ#B@:ƍNF~|ayg֕ 33TQ(~wQQENlx4 ea^cmm p$ !ӭ-(ɠsu#:uՐ$UȒ;FӴAôuu]mPh `$ +MӪiERBȀ[;Ngu2HՍN. YNc)J)PU5,#m|1{#?7Maډ*ZZő$BȱczrvI6IGFL՘,$Ij&q2"J hfx KQ?@QdQEh\bB!drN*qZ{1UcrI%n} MӼhݾ<8o H"qVq3&B2Uc2u#{'EɅu%ȔðZ-@+iz."L@QbxβiZհL!t$]ҁ;1y^׺,#ϣX,|~%ȴ $Ү`'Jb#dFfKB!d@y:A$3v|߇8]r<_d]dq/ -@_.[vcEyMR) a4M¶m$!2N8&D@[r~*r##d /$sa8뾉Q-@Ix/ESr{{ _#B@l(-[Ff$tiIY M*Y[]׃~^VUB!dcccGa1UCUU (5 ,=gdR~[ʲ UU^nm8=!t]j?*!rھ;~N,n<1O 4M,̭#BRn3LwzUUi#Hۼf2 \}mlx QǎCR zm#I!`{{{HO;k0,#I։M$Iu=0M]Gwxz7YE)z>P6B!$l:z1dI֕ Y<[UU^rEG4=%χͶ+DieYX]]E^HB!y^-":"ySrA0d a_-eYio9(q _aͭ JL BakkkAH~#(H~akPeDDZEUp>" OL|=mK`'cccR4!҅5/:B$r9N1Mھf |+mCu+ <EQ#?%3# >K!L B@Z8gI(JOV~P(@UU d` >'dЂ趑v. L|;ipD!Ķ$I/)AK3 6VWW[7Byc=" hվmX5`'C0 \!'CU[s^E![FQע(r9%uj}a|q#Q(X__n6B! g:gb%r=8(rCVi#K~u q0  yҏ +:;iQY$IoOY(4ES0D͛7Q,A%B={֜gYVFB+=0 r-4 "CӴ6QBDK]EP]_AJryGQæmX q1#JQbmIݲ 'c{{kkkܰ !4(,EIC4;HBx"CQVeYmТ#H)Ⲏ)d١6E"_GQdrD|rG~bY%UU u]asssd !l63yCtN~>G.i-AB mEM\a󼎂x?R cGuNs{kY9<p%Izr4X]G IDAT49,,,И 2sJ6\#!DQK0Z,--;hopU8joC/Jsde] 2lAbiWq>:x)1[ OM|Qu?>2VVV.GḆP̊sO->や(m3t]oEP V_tBHcvU$%Q_EQRԅٶ:@DZB!@Rɦ[2lɲp "n oooځ1F{n$IB.a$)dmx6A|4 •$7i8(jqE,// 238f(f}lmm! C4Mٱgh米h)*9! 8lô Ӳ06%Iig ŸӍR`ee||J!dI:Yr=CE֞r ʾ?Dz,4GAQ`g 2i$pH!_2HQci/b'm.GeY'u]lll`mmanBfRA"N!DkOu{]$ cmm fs_uݎA&pa * mP 4M+5(mXYY6Bzn޼y^[jIلeYmunw#EAEX__ZbaXŏ#A&N) J8dة#n%vԲ jAZ7odB!Je֢j+<8eJ%4=UQVKO?c!OQ;dZa2LQ" GGv۠(1|_,:iZWbPB!NxecQE/m_VU6R 7olkF!L"{ I7=σ{BEAP`:]D~&B{ji,Cu4#N,,;_SӴrZ+&t}}ikSB!Ybuuuj>~3:<"#nsMfoZiZhYe(3fxfkmeYm$"X7ob{{ 3!VA jGte|3:Mp]B:֑vʲyQ?%lY[^iAZƍMB!I!TA󼎑#O|J !uJd-b|2 aM۶_Nl$I' i>P(ZaBȤ`v[$9hTOeA1.hu=dA)l)W0F<(.VWWY_Bđ'1)DF'AB4FGrNFKDdGrE !(Jd4_ ] eƍ/A!dX[[cPfn,%IB.aAHc\ Ð6,D hVl1(JdwE.g۶/hzGZ ׯ_GVN!d"Dʺ#_1KEQBzם"LD#1Mem\eAQ"ۋ+?ey}J%ܸq&!dd=,nT̒> 961p}2UСHX.v(b^{= fgaԗpX]]L!$۰:Au=7wlI$-H8dvԑ}x!"M(JLLaAZ#'"X7obkk'B!dܼys5#YL,fI`Hv1:U_sT EX!mO}0 QquT*B$m_g)@$5X̒;(&HAK}UG #֑Lt<֗a^"=,jsb wK`1KBC2Z-g#q;u$dCQbh OsaXzMq*!~㑅ԍxF$dx$N)Sd :x>G5<>֗/l65΄B2CTj3B]! ,H}.tpHP""%J64m5#{ᇙeaFG[1Dq'%n )h b[]ڵ}9~y3*/7+=q_d,uD_Kp 6J}$C%ӆa\'6sxy\p <&_[M]m bˡzi90M3<> H@6BpRJ9iM{!2loocnna`||+"":PuT[0 "EQ hH~/hCc'*#gu^nV5Msz4Mq5#"":am2Jm3 J_`H}LrcK] ^=|3 % xweYI386$"aFC˕kh۶* _KTe ]R!%5M3gK""G+++ͮn/7]4MN :ȇE 6J=,ӎ>~s}9%s~_ eMӮ{._amm/^wTI\ȗatQh,h R ( LL<{7<[@}`|w໺7Re677@QWօVh 5z)]{via?RJ֡1^5,+h氻` j7tò,k!D]P9R $Zhl)4=Kٻۼw:/zwii3$I.DDD[mYN)\i, a%<-џj6mlifwE^Pb>9]T(o:D'N*\}ư}%YiH4{Px]@x  !0E!]ߝ$#,,,0 ?~Z>""vY[[$(h<ϑ$%D},(Gy<@Ɩ'`x0? ;7(y=N "<GNg&m'RJ֙މÿwMteYmN "i,hWHP~+_CK O,g'm.$yEc;[`{yweYI3r" vvvLQ[[pֲ, SMiUI45irOgYv'o-C^rO7;cmm }ڦeaAnã(,=K8YџiL|߿ Ec3ll9xg B0!0u7+++0 7|3,%"mnnֽn6F2[ $TlpBaDacPbH)=!L8i4M;u7x# %"VOËʚ'Qm\#0B4@4zBBJ )%?=RQx%xPJ.o qi[y0??#"xWa{Sy:"K \,gFV[AbR=^PbywX4T,VZ,--oJt¶mh@h`֊ʶjOH4PN<* g` Eyީf'rBgffDDԔK6ztPkXնѢD{ڇaG9џII#SsÁw[0rV&riM`kkByWq5eF$wEm0 #K8zџ 65Nlt9 G"0 GL|EP%IuhM0::ʍ ]=N6\%fDh6a?@IiUpC įL8騦iމ `uu[n/.]Fu&ɗf7QB@UjX)H6l&Pi&=R $植^H6}ejmm,FQayysssjaaRh@aY !x2%]hDeg3 ^NN %r2Ms͝A`qqu3版qɽ ".IJ|q5S8PY0 _-?|aJY% gPLeYa3`b~~W.{ψӹW "ldIDu_y]ZҺ )}ߖR./T }=ϻQy#hB p:iF4GQl' xu%,@kBi:b04Mq(EQ011tDDClmmnS"jU\[XѶy^-h!| %եZ Еy!ė u]OԐ%I c||7 "!xɆUם'Z{h9LPʃ x7@JKJ3B077yqbk&NBԕR0vy$NK)^]^ %orLAy! D)'8\6SR=^]jC jrW<*syWY " puY"Ni %jp=n=Pi&? RRJP[H)|)I(2iZK9n$8Rw}vi?+~X)&j3K@"wQ}YӴ%DD\O'%j)Pp[ $,'QwTJZPڽ0 j߆hp4N`? "Ɖ|ZM-<|wkMv`(AX jZ+ <%"CrmW|"=45JDەrDP׾0fr*B5X'"$IK7uMCR턄iy:oI)FP:J_mG0QpB݃\Q4pdY6,Q="{)JP'D '&nf] "M.YADx2+IaCJ$I$I;Q@:;(ೞLa%DD}bccg!\Q49Y ޱ!Q͵0 Y $R9ɍ7uC Yy7LjW0`7Q]tuYc Ǡmljj (NG|;n-K(LDQe;w[[[ &zPu5'ADָ b G; ]@关,&8*Ξ=`,//_p@Dm{Ͳ쫫Dai2M| $˸;X@s\,hy\h$X__ٳg>4㞈zNlpIDq 집eY[ UUlA|Fy R)x _9GIy#sLNNvnzB)4MaF?D-Yd AƧ6:U !^Y3۶?h4Ņ ѣGL:DtPP&x(e 7-o V)xg , Z &677e4t_'DDjqq5OJAunDq}.{4MR(y5oI)[B=%X φaEUUu]o:M8/ %WE_(o%R",..ٳjNDDklr "}F>D;JRzK@RUI4[ &( Ξ=[JDDw/븉J?hL_$I$IH躞GQ%*e A4hm!w'0Z6\^^FlIDt%]QG̲mkW'ZV zgr$;hH)}!]v=q](kX^c(0==QDDnqq5OJQk\$iK(y5h EQ(4M3A %h`I)3!v RU xG#C˛fggEN<""um눢)e\64Mˣ(z*I?2;Gh:ʲq?cf7xy#,..7YAD4ʍx&4k$Ire$I:2a#30R !`3 ?q0ԛi 01(±cg6\Q_B@ӴjZxp\ -zZih|hPq@CCJyA6|nu2P雛a &, ~zi8aQNب4r 24TNmQjfm0 qI:tr"l(BTO9#riXo h`% C]J^Õe  -ga A %oaǎ|@1Jj{{q#xe0ADikkncbDԏkxYpD;+ - `IQKzR5m~ӗe<|ulh7DDM.hP^:qIt_ $h "T`ykn$iV9VVV9;˲xh`\pᒍ6Q?jlx)TUmkFߣi4M Rʐ +DCD+>eqgvlh8qFFFq'&D4($I<-.#@? Gа>Dȥ2,J[hcCo`}}YQ_KӔM.h4p+(4(o5D<)A/)KV cu- C !saj9ѣGYAD}kssM.hP~%Pu}:QeK@tٛӮ=[ug"Illl "Ǐs:, >AJ4M$I[i?x2*J]& !p%gZ3\,瘝qa~HD}eccg!U"ǽ^ugem-PadA|K)]O@DWY^B%(qa2*t4LƞB?.htJL<|]JͫN?D~ZB|GQ4R䭙b$BE<'N7D0k&DG{:y^H(PEiX q)eʫNty %&+>i(7&I"Z-<rK:@ ψ?r)P- (5xʼn;뿙%B'GQ4l@Ej+IQamm A`ooǏ8, T2˲k(˲<_|D׎Qs76 oAu%"rH;;;Z111o!mJQېy] .4M<x5rZm!`۶[Qcsy T&D+teeOGQek_mF.Y-(7ZQ6\__60::SDukkkl҉z`ֱQfG_RnQoac) s(9j9P{{{N8#G0 ^x" 6DD=Md$w<DP37!ZΑ9(*|.nJ" Pc>"m{ +DŝQgoCQ1cƿ0M8V9ѡQawwzjBu^x"꘥C ":}VNGiyEwVG):Qq'Af$x boq>Eeabeezjbzz&c^|`oQa `Ar:Q0 SB|uOq`=ڪv]&Ey:vF;GQ2{PxJJ>yS}M0_I۶:"7,y8.;i8FD^5IQ֖iYynRʌWw0 uY! Cu9vR"clnn"jr|(8>IQ[)iy/{w; 0& ?rQb(A4 B;s~qج׊ڒLNNVtS10f]a/ѩB\(NGDODH,X6 LӼ1IT%唎m=zǎPoY^^{`? "ooPji0BMӤayϢ(Ӹ RJQc(A4xm!)q,q]QY#MӺIXDG"j #<.PadixWx2@4D;L".)j8Vq`69cǎq(рBq:q)ēDan 7@EF7o7022Gѣa<>saffqo N@}# #?0[ED_{ φ:I?/~KJ@~I}lllرcC QYYY," #( 4M=bƏFDCm06wx%I'$]u?EۮF@NA8 .رc8ra0 EQ5O: gѩ&@TR8~?xqn a^uqnHog#ڍmۘc0114Ng_mѐ@gXukA<.g !{&a(ADB#~Y )tJׇʬq8Çرc 'z}:L!0BJYw2=+{2H}?Iwx2AD %:6.)0_U8Nln099p^y9sq( CԇF@oēA7M)ew0 |s/&I2$IG֓&Y ':?1p(È˩ib{< "DED{>O8s[zhՆ`8AԼy<זe3E'aDmNyxF<`EJ!3 6aWd$jaֆ###Փ|"j#T]]뮻Es|EQ8/ Qe ѩ|0$MӅ8pERʐ 1 [X)o~u&I2d8Qq8r&''q!p 677V_0xa\׽:j M`6199 X.SN!C뺼0D=FBys(E5M)ID9Nu]>|G `8AC?1>C,N ,hq9I#(0!\l^IDPh@ .6y˲+8$V wKmyG,(w0vY\\ēO>Y}  DDD(]sUU<{iG<ܨC "(FG|=c3˲vnPUUeYp]zbddiBQԒz,ݠa "O<)'u]O<_ UO8E "DDNQv|\}wecI(ݮ+?aYFFF|  DԬ鹦iygDc(J4.H)S{DPhÉ]> iMNt{jGfVСC (gf1,EQ(u=Bl )#=9A"b(ADDA "{kNcV'x`ll],ݠA"jn5"0 g,;D`YJ$"b(ADt-L$y,==E 1T' C{5UUa6/ 1hS(;r%x 9EQ!P6]}A(u166jLNngΜ+R}]% v|A"(OuϢ%!h1 "jFT0QLaivCehW'w\f 4.FGG%mCUU(7rN> OADco 5iZ+ "@Q&- "b(ADiyzfs(NOTeiY3jhmuenoow_,!@]pP;[O+%sy*óeTC "ڰuݷ&Ib'z=۶epe端2DD{DT]iZzg*ē@bOE1 "pB>~˲nUe;j2(FFF=xySN!{8S:ݬ "?DXS^GQL뜠ADP ?guwfY6v2YfR(*5<׺4M^zѫ!jEQdMyyg0ީi i QL&KUDX"*DZTUZ7; A:pL?<D0!PJB!/*,d z&0N?@ Z:9g%<EyݺXpۨ>!J B!{ap ڄ *nCV쪔r`s+Rl| B(%!E@#aEWV9l9/tci BnpJ8IM)IJZ0 nx1phg{&!PJB!jFtnfk_Xv]wYJYl!H.,=HDRJ)O8C/"aj.L<ܛ`ؘl?<ЃNB!B7I38&.bl}?NܞUuYDĈK i "ύmn]IDv& A: wallch-4.0/src/Pictures/ambiance_checked_and_hovered.png0000644000175000017500000000033212301477401022126 0ustar alexalexPNG  IHDRAMbKGD pHYs  tIME ,G[gIDAT] 0D߼$$ h`9`\V/LH@ Lڈ=U-0+`LEc"2tfhWD\0 ϗ*?, 5IENDB`wallch-4.0/src/Pictures/radiance_checked_and_hovered.png0000644000175000017500000000041512301477401022137 0ustar alexalexPNG  IHDR@@bKGD pHYs  tIME tEXtCommentCreated with GIMPWuIDATM_UY"E<.' w ׳`%h $ !X&̍Z^`%Q5 M ZT'>1fݬ&H^kAV IENDB`wallch-4.0/src/Pictures/page_4_website.png0000644000175000017500000003255212301477401017255 0ustar alexalexPNG  IHDRZ= IDATxt$u `~@< <YK\ZIVdIqaQ69$'GI|'|':NN~䬽e["e^-XhY49` 5!G 9~u񪪫 c:]]]]]U]wEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQ'H_Xb811HI^`XVEdn -w7P.>kK|i6PsVϟZTF(gȘ"2'⺅#093,,@51fUbƞ7sdju}.#|p@* 0Q} 2q1 @xRk#[" "!,]ыo"*=D. .#fYp-;BˎВ.DuBTnN׌ s/ׯw))T{*|DHEB״EOoBu}m}r9*=;< ѣȐ ,39]kc4x;C_̟9syN!D>Rn:}7r{ՒGBܬ~s޲WXZvM~D̯1r%}`޷X8}Dt{,<3YOo侻u _+v$Չ\MI ݦy۞.$j|k;5Tmdq||2$?)J"w4aSZ;A%9 ۞m͓vB'%f޵ `FGGŘbe~bgɆ.< nK5)r=#S.U7w5w-RI"L!2]B! [ "z7SV:7.

\-62A-5p]DmD~iW*m"7?D|}[2H :}oͪi>嶣*yy79 ]|o,TMLˋec1Bn1ԊEfy:@Ooj]6*mpR!;F۲Թ.p" ]x啅N܃Sb5ycJّPͬy۞u <߶";~ꛝ Y{" b(n蒌7p߷b! D??~yO'cȣ NSi-Xnˤu, k׾k7cBo׿#:0D E7)}{VpWK΅ R,4w PJ۲ )́˯**&̍G؋@K_ 66~=1{*/93m͓AP b1쑩vw zFG['6Zun#~ޯ>|6 䤿p15QZt!_?<=]]AgKD@ 9n2}J|y 0}< 7n#k&*D^꟞{׮wSOBMx:DC~K{{7'&zVW?&2h5G"g75{ῗ)`ql}CJm̟dָ{  @~Sk.BkG]2XTp"_X"~Chժ̿>03[C}"!#QH bgNpYMVOPlR*s##}[ĺ_{]6eGE<',1esd[Ƙ/OMS;Op͒;13W{9\8{!fV}g]uX>wĆ9;Qg/_]ܸgΙ3}ǓmdDhzam :Pxq.?v쀲|B ZHՏ t-3=!åN_K3BwD1dYIXr ?ioi̮s mq[=z{s!1;;vIq bG^zI45}̈UZKЅ_]&KK_\=]gSp^h#=G/*܁C"YXi>z3\xLO?%s_.B'# {/۞!xZO&s1/E!`Ϝ y1$]]e#+0/vM8|7 ̧C#{ v.<[gcmKOB9 *s׋G8Atk'fDb=YE0Ga-Nd lo~S 0Aq3=m͓6$؁f重IU‡P xa/`1::y"$ MDs4$Ɣu\wϢ 6UVq4Ati\~W_3_9s1וֹgI<5Q*F"fF x} @ ##;A$RvՒ~J>I<#kՍGuJq9qGS9W-;`c.bɭ[c]^~f ,=N䲧yT=/0#O>i=8۩~a!b?À:tw˗=X,Z-m,Ï-~$UpFu_T]\ Oa%D[:|G}vG("G3xg ͉ 7c+Ι3'"2ԻQp.+ebǍY0zDYeOG(nvb[GKUYv.,Ml6i."ֈX?~ի,4::Ed cD\ظٳOhE'4kJ^qܯw[s - 9ש(cJw:i/+ Oa!R z&nSdSc# \8sfxnqL̼s=vfվZltu}bo_|"|ܮFP1861"}ƨ+x2)^#vuHHC@BADRu#!gjDB<єgs{sM9r&Z1&e ;| Y/z{ `y0<2>+IdXDnyd4R-8s#IN^vj_GedoΘT(:!ߏ8Gm|˝>''ܼ!2f8l /2O> D3sTW.&Ds~6%j*իQ=Lty]g`Hd5|{ '" Q H1n'#Dl7wI3n,5[mݭMHEqx/Cƀ1.T 8'c>kcXaT鹹uf76Vb6b-ÖyQf*k>gxhU׷.KK-'E]Z"}E/P2BYqLʇE]r4>8GheDGU`jZ~G\YׄKѳSSm\r… D14BM"e vbL9am͊F_Ƽuϝ5ǢN^Α[v1x~e^gZ gh ʕ P0QK(o ,\x؅@t: A:2; w"#p*T*7 k5M2` Xh `O }O!z<r|៑uD:,w>5wD7|p#87˞ff剩DGff jx)7902rjg:ǯ^][Q۔VLU*gQpPiPL:Rgc8*UAbRzMO>sG=Tm1 I"?>8=OLMl籷BߵkDO;=<T_93wV<4*@ !<؞e_ }R"|ȝOQ3$@Evl`̢Q01;33{<hxݏʓOv9훚gr$rIdc &c JROu+:xy$LJR( { &σA1;ѽD/D"ww0Tb`.'jFi5̥g߉s~%k̷HA|=y,G{}_B_\4\(x:wμt@ q^[]@*Ӄ-95K:uysbjj9(~I,ɶYRˢ1tʪc֚a2f Dg==u2qkpҒمB\'^OݮwD >8 DQlv"kvEՅZf~~W:&o RMpd݊tsdX'퍍XQ0LyDvpE 敕jktHrb<;!rk3@] ."6]W:q3p @$D#P;uɘcv\d.'seiB;q-o4`lc++.=f7"x++H`z!uؒ,bWDThvAg{&pZ!J i7e톮^]1_M^{T֌ð  tPXO<ȹeB|T-~rrrkϜȦLNR+̞eEa$;QG>ՕU*>Y{`/s75" ʾ'9Т6:2|ӥRi=- ]]ݺCҞЏgtu>*Hfd;W*ܑΜ%7ɱ7q9:|=W1b2fxE&'7,WWsO|0Ey:!b&bbB!dr_uq䆇 >/tr 5\KhTs>nLA`d|n߯II Ԉ%w~y7BB X싋}\R~R1\ ENưo H4ʑ1oCf[ ݘX`^Z̀'NM^8~Mb4[KKyռɝ\><:e>7͟ |WAm5Nk~t#|ٳhj`>yo$Lk.QWщܟ(+AmOB~?ng_=t(?` #rSV='6~XC{uVCD?ái^3zRǂGmIk.aRo=&}!rHDRZ\kM4XeUOl`2=f[^[[㜖0áޗq|z첇*Y@FSG֜=Rݞx׻8Z޷"ЁzO:1< )mwc.>ńn1|ȑ\< M۞xưyOǏ3O&L@,v{ׯ_wM @y\6y[ A"xvq1tfqUB!SSvT]xQ2Y_/T]R+XmGD~-\h"ˣ 겼̕^)T14ss\Z\_B![ڤY.A.Yf33Aʗs=(̞g =Y/.؍9kPk*6@p"=jז:wuqw% R3?h1Gy%ll!jDΕ- =ݼGZ\o: MPmw ΕA{ae%7yh!?;8=LWCHR.[.vwW.DF`LM١\R)i{D~owvS#R#۵5hz| LR^kk+c<T>22R<|Soz8~ߵh 7nL?\o>\LZ\Rw}h,#'&'}ܸa uC֚.T*Fp\Ǎ3??xO)|oܽ+Å3E)m}ˑ,{}aֺ| 4;ۉ  '   *VĉVF_h{>LLsw9 פ"o3zr& 7MWﯭۧJŘbTG__\Pj>K}&w#GwyndT*qaCۃs&.l\.P/r2>; y(\fvc*~%y[PwXgWVVlVeXY[\r( p,x *ae0cWVV -T$N9z޷GmlN(٦~@Qg>k=vdekF3TmGaB[ ʊ-Z^^&&fl,6pJ̶WVťK*P.^+__k2 Km ौvS)UW}vjM9`drҗCC7ɔuS52 qxCC%)߉Ve ddb—LLs^kk*H;N曉kPI_NjO}|Kxd&vs_@hB(;vO".MWZ dV| a@vOD(~4yzY[&\eTh]Y>k:zlʷ}7Z~W(JSAPbZu۞(;pulnp5c͖twVEQvi ;6綾EiQd c-|5nr ɊΏ^wQV3h9(-fKjfTN(J D0?oXqm*3>zAV {?72M.x.%6I{)49 =p훹17-:EQ:2 8+Lo {kJtO [~L䟁gar.W(JC~B|.BLZ{V*J)!fVi6VhWt lǰv9?oz~(JZo ~8x(LL#?* h͒2\NǎʔӔXEəOck5? 7@Vǁ 5[(m"}{+? t WBvJuAv& '8h{ (]?Y;z++p#&ǼZQ/p2{lo|R':?|^(*-Ə7\&/"[;]8_^Qm5jn9,+v;NEI5ԋwp<Oى1,EIpف \BoS:aco7|.Aul/!_y.e 6ܓ![?fyi445?7[\k{_kpF-+ʽQ/?𷱵 4\N|xŜ(ַ?'fK 6߇ 58|/ EgI!قzN).5n'dN 2tP+̈́e9zZ!Fˣp.ulCmdOek-F6;:H@"V ?q%@[8U8aN~;-Kh&pMpnfP;x?뚺]pvh$h @f,>F+\-QIc} VY \z;Xr/~YSƾ[YWouf9p3|} 6P]O4>FZ9{zhU[m;mϤR|D[/U #V 4y()uo;y+bC}Wy1"qUEo/͢;^Y<mngieśnQVEl+%.O$ivJgITtbWouwNZp㓟 ONP[DK 2[u5;c)Zg؇&Zkz-~}p?O?]BG'e+@h$?EY(>Y $=赕ITtH6tJ&3}Q=Y"R̢܃ژMQQb_oP z*ӎ7>d[JY5M>:VoFU¥}dG ~lV>B*np>xy,d=O |Z > }k&v3LbfV-v|GtuKm$V<ڼ>vVGרq[y]BL+YSoEz<*a7<d>͎lViSi$O‰d7:?* wallch-4.0/src/Pictures/folder.svg0000644000175000017500000001335212301477401015657 0ustar alexalex wallch-4.0/src/Pictures/media-seek-forward.svg0000644000175000017500000000375512301477401020060 0ustar alexalex wallch-4.0/src/Pictures/ambiance_not_checked.png0000644000175000017500000000027312301477401020454 0ustar alexalexPNG  IHDRAMbKGD pHYs  tIME J"HIDATӥA 0 g&A ~=Q/K!p[/9J7dФA1qj-uv18?s8IENDB`wallch-4.0/src/Pictures/wallch.png0000644000175000017500000002670312301477401015647 0ustar alexalexPNG  IHDR>abKGD pHYsttIME6؏vtEXtCommentCreated with GIMPW IDATxwxgy?=l˒-ےd{$v '&@4-o^mCK % $@ ABJo[^򔇼e˒|#ɒ|$/Is]t;sg`:T^.-O}`@:{][\ < ,fCHvĽ{e1ث8n1 5 pU lby@0V8grm( ]@(^p& 5T#8;d 7^cx!jE=1a^>eFgb` 5  ~Z8y30 gdIo 6\ 4]aGŽ5Q1L|t!}D`TX\Ϳ,' )pd欁k͗lg[ Vihb @7_gu6!5Ab@sM vppGV *7Npnz )vN ?XDdu+͌` qp4bX0 @y-oa! %n0P uwApv}X Q>~8a<: @]= ]> 5+<L2d񼧍go;MS`6ëæP & wM"؁O1 w_Y< ^5u7o Mxxo#v]'  "vn(.Lẃ)#)xX" ̀hX^m7^>; T;f1 ك냓giLoD6:B0tL& jl !!0g >b{BM^b/*dy8vMW?uߴG4FCb,Bd8'~8> ǡT΀s`@ذ>a!0rxPQ &gÃ7AJ"\ [C}yo[ < Aw&nTlIpay|˥m`p Rv1+*\`hY=GdJah cCΜ?3T  'ߡRULK؄xι[km?5Co#p>Gyܐ& pvP|e)|v8v^XE"n xDR^~rWMZDPq_rQm 両"d*[%dCaf., r p|iu`Sg]YeP/8]&۰}ZVؘnʚ66 *P ,{ĥ'td&=G|M|Vr3ۦC? +|>!5]khh{+8+_^%KqTWu?i {I+tYg(qii4i8Lw`m(|uٴQp yh7*WÖ}pX?=(-AGp,|c1@,p'IvXgwKi?=&xG 1a0LϑY; [͒"{wzE}`pi}m=/+M޻\rf濎ʲdmb`Llإ; Q4,^ ƶl`(\s;.f-SaL~O[jq;Ji3 F93b/.,ҹ$E峽>Ļ+m/^߬ab̆٣!# .5p~m3tg c%!雨)p R @vTU+sW-B߽f°F: ⠨DљdDepƽD0pKZ܄ ]hSC(` {P/:x]x}8S%0#W!ޣm#=j| *۰W ޢTA!i%mb %nVm}<:S9&KBsH?q=cB\C'E"]EM(C&Eeh4I9!n@/RXe5X[Z({Tt6yzM)IJ5]KR&_vܱpu0<]e~X NGwX=[mkޯdOH[ K(1 ƕll Ơn\dzRPR/&_}p8,DZv5W)ݛP|8tRĎ[0I$L^ιgoEYVnՙ0 >@Z( v!mnC#Nu3R˚![o0u(5}dmFgqy㐨%s`VH#%׍a*l eZwHd]^u!b,`%"+-IhBC~teQnMp"Ѽs*WkI7*laĹW/_o]\nާ}GQeyJ.$9HZq*F` Ly,Ŧ4Zr3Jۭ&N3?$~ JO 8[| AAW0mdiY?ڒr{AfB')V֢VY% 'Kdd?xNf95\$׬F_+4vtV,~Bp?4ni x_] gfh3K{UAD/ߞ#0%(;N`{$:-!sd䷌N glﵨ0WVRSTLT\v?t5(C7r8m e="˚nCQˏ& Nc:o+zˬ4=G9GJP%*:SbK+ U ՘6f򫓨¾#$@``+^I1M~ 8A9?C=7WJHuo k5Y1, w"2gˀ/K.f?ƫyb.:;UHK+#X(fRH0:*\dL2y/ϣCN3keW@_b*RfqeZl[b@_T&tBjV禀%&gyƄ$Dw Xxj% <-ߢ|yG+?vm -~&PRa Q%!Z3q8?ccy ,.y2ȥZN4qR_OCNf5^CN种o'ΟLkK)sfvkGXoJm>H}>Hk+D](,7Pp'y2j8l:䢪Y:]_79&X~d⵰9TlaI m(bӮ7\X!*^A`' TAnf}:2n}T+UsIݎ- ${E#{\KjUfZeL+hy:6m?e>a ]]\RUJ̟ abr\MqAk|][Y@66NKILקNs{I?{r뾋7XTvFWk;S-M zb HoQ9մQ*wLӥ*NKdfI:n7+ڞx`߽RƫcwQ *qrK 7(.h0V) X(a(p#+ +'pLU&][QUN0mQ(k@Pn"1y(7uLSuLTzWmաG-Ķn5*2Cy/:봑Ef1^A.nΪdjȠhYCEjr \LC J~|3.)c|/2h&S)PDIv7U4E'\נ4oa !bx Kn+ũ./QчϦLtQf*fkwoY-H3W08`R'se%JFYpQ^y "~mgB{چ)ve^a|C«\dxun\1MQZ4-1;Ȯ0^ε>ʨB%]Q^=L}뚺èi=^d|ϡ>H%lC^o W1gI *zY|fV?FfY9! \W)XRQa Ԗ] 2 ײX2]!{0WC d'N_^QVS$3NP y@:b*>Y&o?Hqw!U\ TيP#,O%2tsxQ;c6O? R_I&=O͖+j(>htm$- 3hN}_T`܃޴ qQrx1~;j:Va͆_}#E'e{^n &Q&ʶkRmN2A-@JHFb#uܠ.߾n3s`QXO=j _vgR݋9?(@yw AEZb&|%:w(i!/Wo-d_.ŜFW/,%^ĝLs=?j8:u \W|vcFMS桓[~nѸ׀aZPp#{h?yW/,߅w^fHOއ9sSf]xM8vՊnp=RzWb;28C'Chc$Ijz猅cui 4ZHşyJ80xf|icw9 3,`Q--EOfϺMݚ;zEEhZVA6?i1/N[h{l([޹qb>y>3$p~5 !oލ,΃7p'wNl$b2i$(zJC-SǍե8+~3ANYsG $΍;Wk1vBwl9'#߾ƾ| _ljS.;BjA.* r9w,4Y^Zy,Ћ`4痻54YFe(bP?oWm3 NvPgC7ܐX,Ѻ1 6B4x빃5M:@En}F M( o讃k`FB}̭um&q[^4IrnBC;M7hq+J:feӒ:@%~M=|J F%xܒ'W/"׻v" ? Tiqh) <"~ v-(u+uޡ጑:tOp㣅 Pmv\ 1(0 T T̞7c$ W-ӏWce/FCQZ؍@GUG. zBc\J w!{h_nT>4M6J~q5},juiWsgMPCED#LP @j4]Q8Ӝ!rt)BnĎʛpttjH Bs&I+JB76uT{@r=W8i*n4A*p_$Yg)g fv=^W`o-P5Р~)P xȅ5B ׇiAw{f4;Z} ㄷv%n`WS9?٩c4}mnJ s7x ;tQtC=s oryuXCC4'1F#A^m> ]G q{p`k+Ʈ @*j2Ghό]icaNhFEj˨ư6$:ltKONat֚ҷ`v4C"& fpO`AQr4۸KgгrtϢPnI˫goхICR[^I AwEgݓ;CvAB {T2kت;~ƒ2K tUNC{LB3.`yҬ@qXL&?QE\|\7(m'ÏG:iO-Vnʀ5} J5AdU/`7W3hi!b_JU {Q;[{i^4ƥ %8[npku=LB |C͢FNʼnWzk\=FtKbڿQZ4ʥ)A8/.w~{EThM~A(_e?;لՎJA+thZA[xZ{y*Pi\JJ0_5*mXT՞ A,k+ikb|rzeL{aU-ew|e{C1=&{ @R[Ln'+Rt ܠ,`\.NpNrD;qn&y܈,3k㽂(ߑohJ5<Ow1;?77)h0d"C O9$5ICϟц1Wс6VP2rEtphHTm7T {ໟg)$:J:;# Ål6ĴReϢZ!fF 55IJ}z\ڛ l833Y8gpz^PP{,vw8R\8i3>_d^`ާ /Jd\A?ϕ%8;_!6w]w uqu3J"=F>Cd;;*8 ?L&ΜSo¶'*ˇ@-Z m[(rmZ2\ko4w~Wbk8!~WMWQqgq~8Z4}do,'^05:G|7A-jƸPhJe:0#>g&~6twÓo"VWmMlv,{s٪&81:vL)OϑEشO$҄0l? Eojڌk&a]zMIo/YJQﹴ aE(%"LW>$fXA#o.rѧs?OtMl~y\o߱󣃳0~*_b ˍ<)Aۼ_*WcV4]ZՑ/@#Orif{ N@W|2F6g Q'W7ٰGB)#T s.!/U#>ᆽ*1l-rϟ.7O3V4O, ߸KijT=NQ&2:B9dD|1]XewK)y=w>+_P$ʼnl MMVOTI3r4eJT9Ҝ4<6Мr<a.~Ե`:#׽7 oSɲnQ.a0`T8 x<6K)D|e-5O//*!ױPӒ/ ; cpeIxrXK<'j/K+*ƙ3VϽ4,T݅~6P{ '\™]FEqe o(`AL.ft/TK4_}y UAY//x v.8r Sf(Λ[ʭm'3~LSQ-jn\ !yXulSQc!QB]|xf\Bny b"e?vp%7=G(eK:#U>utA&ݧGyW Jѡ H:h, @Vno)>'8'R,% 3Xe.KR͚%lp* HO|r%@zw4ڜFF636J)赻ԣ5@&͑ק^y_Md&?|eUt2n468ے Q% %JG¡E_^'L+6i)ktዋ<~퉶Q'_I _}tq#T?&q4uxa咖mJ@çYa:Y&iJz5WC@`)p &&1#n&}D mWMAMWb p$ m!~j^Ӂ|qO"!`늼љ /L{jlTPÔm @ l*_J]ڠݖYbبG㚙+w'Ԍ,AUѫ}&Om Ʉ˷ >J4*n~!XYp2soU₅. t5*3[n}nTxr'*WVCap%^ $a{M}mYXڧxUo&#YQɻd{s Bsy֍=F?@ &<OlHh5Kמ##Koa1{׍uX`h}W(OЍ[z$PsQTݓt($c}$?)͢VRynC=`o{(pL[8^LHH´B'L-Ba# 9Ml_Xi\A3;Pa%4챳p?ڬAE3_)/ 룡ƚ:jW3>A0!(D^hvG>8IENDB`wallch-4.0/src/Pictures/application-exit.svg0000644000175000017500000000722212301477401017655 0ustar alexalex wallch-4.0/src/Pictures/preferences-desktop.svg0000644000175000017500000002476412301477401020365 0ustar alexalex wallch-4.0/src/Pictures/media-playback-stop.svg0000644000175000017500000000570212301477401020232 0ustar alexalex wallch-4.0/src/Pictures/monitor320x200.png0000644000175000017500000002331712301477401016721 0ustar alexalexPNG  IHDR^<K pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATx݋$y:3:Zcy^X^)Q,I EBXp Nor;r\%2FC@7"6 L,m$HȑvztjzgS3,;ӯ~SsN^ɫ2m?f;:-"s" *8&??1ޖ?ӿCuw ι Zg ߿6WThzWD'ZֻwJUpF#ZѶF#Ec> s^b0H…1x: YqNrp8t4=~'dY&<}Zx 9{cd4h4}λ~K97(yh0X/ʗ%yAh{orIDxV;$Dq`;SyQJ$sQ"h$:~666駟D'$1%JD)9<?^D)Q$Icw6^_)-ԧؑz=yw9+Y(/_J)!sNvW3B)dq /DF qio0sպ=^*^6#8Q2a2#x vfx8dx x@>/i!C/DF""x 2Z  "x 2.p qD!"j;x/ Z e+\xU//tQD'Bq8:tP2U8IP/ "j;x%G:4/Ĩx@t/^@q8tR2tY2U x vr9'ReD ^*]O)5 _zuΉ&o ^@ ۺ^/ġju' /DxG@d+Pjpt g'th5@C/^ GTe .v^8aV(C/pЃt@\:x/d"D!^8@xC/@%j]6LڴBV>&-c4LBUvm/Tz޴BWݏ=Ǫ9;u!gX6࣪v=}o6M*cfh 1 ^@c:"b,rGZ>o6!:U\݀hڴ>6LkBxz7h7 ;5u+ڶ;W{tjE*g!Dۥ͌J+"T7 U;uH>ܐW6z]f>gf2k54y3]0c,-{%<amxmU*}cz`V,s[ MJWuBھV'VU#'Vo7dH753h3,Zu m6mnKFj%RԢlCܷWհ3BazM{um 7 ޻U:l">AJY>*ʪs~cU] { JNhk鳒?ƁmZ !w6Mz[=h!kY9$䑐tnN*E@v>eӣ|i+{M*XCSyݳ:ڮn)D8E8e[̶;\!FtD*SafDӃ|ˠj]fSNMKg?+^/a蕴|\[en1i~m:ˡ97>WP uν[u&ACHOsσ'|2𬕴I{)d5v\o,{1_#fV>NFdZ/zgm7{ϙ >V]nZզQ%}#L5yӡ{{Pb}jC\!}W٪hR1 enH۝GMO{3ھE\}ެ+Y="cx!kE^hșUBU,|͎>WCU+As-%Фjs1 Wk=$.?muejء. +  y.X+ӼSm3uJ8yXu&CYV{]sTNB7FU6@}PS9Xxʬnus' :.xDQz+VSEW2h}lXŶA]5*'s_-u*ZuӃ:tVNa^W.놺ClZntQl{eҴ['`}Lj}Ui7vZ j;,5mBG<wP7-l&!fgUP1K&\NBU'ws&U+bUoqa|}MO{./z,)IL:]W(]h@٫: 3m󶹲CݯH6tn|7r UXz<%˳1y/+ Yv.F8T%ޤA }`J&}̅m3m8 P˻sey&67Ϧ|531'˨چ:w!F'.cvCI~BCIoiYJflrOAeo~X+TB1Q|^n&k>f)YUﳈ+2~λ~$q4^:ѣr qzjPzܺWC>ȁڴՊYֹmp\ܔׯ_"";t"=~cǎv}geumC*BUB#B^; ,k׮իW/)?_""^~[G#kk$I)誗Q,,E:2>#XCO*fs{F)9-"ew%*OS'4QnV{mmuQg=٬_}>WG?]n2{ g|gzp8MڒQ0ՋJ+E0DJuŋȲL{~ ]79뢂i5ݭ 'O, =+c`?o(zn,V?Je29w7,Y-ΊdeeI>裝HaSx+e$dYvcZJ h̽I=0: ̎Oی%e }ޱgY-0Eˌ!X\tx㍙=$Iy0z+ISN ~/"޾!;/׮]#t;v۟0/H*TEҥKo^ѠՀ%i5G?o[[[73 .뮻Ełki-[]]yg>/ W^y,ikk6F@[Ƙ?%xqyׯ_9^7O]u60c{o#Uhe0o$6Y6b~/Zk✓px5E7Տ-ί:931F$ch9'ysnW/y>Y˷nņX.IL?ϋy.YV,ܮe$ E' Ϙyʧ뼼{U`ӁL g?Ƴl$0/Yya$x+9/x,rκoa,-mFE[Ut "\ˌF6Ye^!N:g ^tk__<䓏zw?~G1f\1 iΥfU/C777ի{wg3J+v7clunrꝻ""ND2RJiڍI"{y-"sşs7sNYkZD䆃( <:3 |U1.{-NףU;s_D$SJֆJEd+++E(ZOVNcz=I)T.MSF7DQLПu6h+ܬ-^cdee,4M]qV*fED~߉SJId^/5(cL9"kkk뉵V CIT< >;s$Qymq`$IikH$`0KT677h4riinZ!x[s"kGzSJeJ)Rι5^ULUʲ,$Ini ^$z;n'$I\Q鎿^ScZ;r1EkK+Z|䜣@e֙hc6ƨ$Ity8d>ok-*RNvוOz$+t2WvI8c-UxYgT/:.Z VkkGJwgﮀUJvRm:f'N󪷨po@ image/svg+xml wallch-4.0/src/Pictures/radiance_checked.png0000644000175000017500000000031612301477401017601 0ustar alexalexPNG  IHDR@TssBITOtEXtSoftwareShutterc jIDATE1lK{ZE9+z>+l%!i 3q͹H014s3W3!:?fPjjnYzVaG) IENDB`wallch-4.0/src/Pictures/page_3_clock.png0000644000175000017500000004421012301477401016677 0ustar alexalexPNG  IHDRx( IDATxy9v{ZnA(HUTz-ި@EU_ZŪT"PP9DXνXvك&dd2dy^$3O<>X0@+ Z@K$ {Rμϛh8Ic+3I?Iİ]ZlArG'`BaŘB7pB`0hMIIIdddмysILL$11$ XV@uu5Z8y$ǚ@ũA`ݙS葥;0Aཕ^O6mro4oޜH*}cǎp8vXl*0^Q`<}tЁΝ;ӹsg:t@ff&'#77BNYC^| |,p&>Bן, r8uF=ҥ ۷n7:Z:DNN999+ /!X~0c ]Z"{}:mڴW^Ջ]&p[zOjjj8p?3{IY} o`s 0x*F` 2n߾= `hB#)Hre׮]ٳ">lJ㻣Oovc4h e˖/\p1oΎ;>,"]Ɔ)tu؁;8p CSNa)@crٹs'uu>> x h=! !`EB:t( ">>Qjkkٶmׯ"f_>h;SN} 'kԻwoFA.]([E(].g/\.CUB B[ jՊ֭[ctܻw/K.OMv/4F>D&{K6mZP3"Myy9yyyr1 դsVVZѮ];h߾=m۶ e˖k.C 6huIV`6,^A/Ç3rHśҨ>pyy9Gqo SNtܙ.]Dòe˨> BFKczhiii\~t9rϾ}طo ݉'11Qn:$$$УGzI#.Of<3սqK' 37gϞL<ȗѣGٽ{7ӚϕNС:t}b:55FJJ9N2(//bݹ "Taҥ }O>ng\.{֬Y#xAWґX,I[b0b."cJu'NsNvڥFI$zE޽ӧzgϞ8Nٻw/ {e޽9r$(GngϞߟ]޼?sm}Ug X:u*ݺu {a֭>gv8!{O-[rWҼy;v?9||HLLdذa9#GFA+lݺ5kȅ`Zٳ'C [f@\.VZ>,AVETkB|W2lMqOII 6l`޽?sGE5\;vUVtRliӦ \p{}D~G/_.7#1[KB=Wdߟqy~z/Mjj*Ǐgĉ ><δpqk.]ʶm~_-Z`'x."[IĊ_;pEEVTTĺu8p :k &ೆCĨXSq(:'|¢E8q222>|FzQQQ~*W}+dhz}:3f30. 0w\K$+Xp!ڴièQ"è>s,$ $l6&MDϞ>SuM6uVAoߞokFq(Uٳwy%K(~W {Xձxb>Sm/љhzfcʔ)c՜:uJx^5k&LP8fV{X,XVzEnn}3gd8N\.N~g544KB}>C}[V=\.L+v8f]~\LB#L1`ۙ2e a-@EEW k׮s=L81#B\\Ź7֭D~;644@]])Z\=)..7d…rIMMK/HerXb;w>T܀n\mBo Bfngԩa9NoΆ dov1{l.Nl͚֬5#>>>!B:ꨭ^;v_߲kwޝѣGv7|#'v'p 1& |> ɻv|rh$?p-ŃnILLt <z IMM{ ϲfc \zKz7Mwu", eP7 [,ƌCvvvvb͚5>7, W]u?[qqq$&&غDb?YmM=zg̛7#G԰tRrrr=zOE3f .ݻw{"d1>b: BOBp/wpԨQKGfŊrtޝ;/XVINNuZ[%pig7ѣG׿7|SR1/3n8:vޯq3f A'W:3# x8ro|G>"㮻bɒ%<..͛EFFF7 hт,tkqd=\ɱSNM6I~k=7Y!aONhQD_~\xav7|Ny{ɓ'rS&&&Azz:qqqdyW%Sd „ "ZJfHNNnBEL> 6o,qQTTDΝrlXѣCvPٕ@ H?0߇:0f0I]]+V~4V+~;.}$2337ХKK߾}>|%Parr28Yoz04hƍc۶m~ڶmzͼ`1J׮]9xwפB2Oޔ;uVYYҥK}b۵k6lXHLL$55pq+kjj y;HZ v1cнϬf]> %J&a/Cs%&&r嗓/|3?f͚-љS`*1|\\\.,KЛnK.a|n+t:jj^jIHH ++}y;|POq_b _iժM6iXHMM%==lG9u8p cʕ.ӧ9z(ٺ;N;uv֟"D\쑸co!|ZL0 4T rXvw"ӦM7P=n'33L1&ZZ+bffĈZʝSÇӥK]Gxv;[f>E[3|Tz s-,GsϕxC Ynn~Zs͝DFFi FP__)ئM6L8իWȑ#dggkIIIf}ȷaO|/rZjň#TY5ٰa?d߽<:Y,#2DV$N&|ZZ'NsS֒س8~\"wz)1>vƏ[-[HZ,}Qc:s,ӬY3l6[L<׻jjjˣK.l6B;t VF{>ȞذatA OǛbᩧot>qTnĬ;A{2e 7nرcgƇҚe*Z!xD99!(Fv<++ /e aɾ{nI0bFBBuuuAۛ5kƤIXf;Fu[w-==JJK}"a{V\8?!@Fi[Nr[oUS)&RZZ{g9rF5SSSѣ{_AA{]mذaJ#>aۢBȟ%[ 0@oeee\Ry5ui&\'xzTTT0tА-- =.11.+Weee8ͱl6222HFȓЭ4.䒐o*/_.8m4yMNII}l_*))k׮-233)(([uBRڄף>tgϞj>l۶ͽf`t,&BO=TXF-ɝwɸqϋغu+N3rqUv)MPn^V:O~BKIgϞɁo<444K 2+2l\baC+Dffb$ bU跡d!j\\\HB߼y{㎠ j}ɣik>3Z}TI6lJ{J?!LGuBg L%&&r8p@2Q} zUm̘1C2e wu]V+6'w ZhAv9Aii.7bktWg*cr EO!vHiٲ擟}pwl6]rfffrA2",@TZ;&&&ҵkW͛%#fҔ1/KtMpH^xhlΝ;)//nO Dh'\ B!@^߿_}{ARL4hyΝ+i裏X"Ԡsiii/qjs:lڴEeVrߊf -MvKʶ:th.WVVa?A֭lrؽ{7s衇$CVF! ~ر#eee0f, VUnfc!b߭[m6I;Ԕ:%%Ŝnjs̑m۶6DR4M(i޽JQkZ춐ۂUBBBFvv:tH~V=4 %$$rXzB{)HJJ :Hrr2?H)tŢdR8Wi-X߅Bǎd$[V+/BСbNp=:ؚNӧ~9Ơ)#B˨Q6myqq@9ʸa=ݺuSm{쑌s^uU'ONN~M$>~I}٨M˥ KunVUi8Y&/pp֭[k^ɓo)))A׸8jjjo~#z:j({1K1LK4&b#q<Ա48 WuD֢[t颹6%; KX,QlJ溟[VyKq`[ر9uTHV=..NrN: BVVYfnZӇ+,,wؑ[n%ABBe7'NK/I]s5 4ȠGf͈ j-!!A2Yt{? ]nȃoUi"۷bNϢ > ArI]G3͓4x' ,Qhi N0&U9b.55Uil~2QAYu5B0}N;jP"={/!VXp!}q\"ߖ5kR4jld~={Hq-p^g{]FF)))ApL_n~[V] 'Gaڴi̜9Ǐsw(x%#hBs6^W1b%]Q-uJd/QvE+>s4iRPFnZʕ+w3#شi_~d?kl6MFûbUmEA0 V='"ĶbXhӦw+j5,NK?٧>,xEG7gɾl hD Z|=^x!\pyiiĪ{{c@l]U"k5o\S$\~~;6Cs&LPS^ b~|fUUULf/`ƍcO=v(M9syNNNHHKKSj A )Ob3A,M{ѹoYS^X{CѳgOɾիWT੯OdСC%2fId[qq1!]0 5O! IDATI,"N:>OZZW_}Jh֬YLyE5k믿SG}T.PT#s!n:#jn ժgee)}3 O1==]SСC\=֚\x>AAeee1᭮d޼y}SNQ! f+%K8oWMBBrz#ŊtB@5iٲe"?y{!;Z_}2 F12si},]ԠcSOXKHHv\9r$3<-ؤ1cH*:N8I䀿Eb[#ݴAĉi xbDujYfqJ޻}v׿bͪ|A=ѣG}2ZZIII>1Q'5ߣEJpB橩Īȃfp;|poHV~:sQA齉`3F:xURRB}}xhОM,pZ4p:J9RhAX{U#f\{?be&#GTrzpX;B)wO~%%%rTBeee>QA40{իWcyI|%&&F}pkӦ }+))ܲHMMUԹHq~~>''',&[,&5!!^{ͧ#H 999{}fҜM1x便~E8P[ݻw(r^ù%k?j˖-={vدh54_,UCCLJԚsǹ fMJ J 2$#GF;ymO>$I3y-Ze˖۸ql8?֤I ;vyܿZLaqa6O?9U4iZ K5bKOOg>ϩSB:.g,{tߌbM-V=99٧Jw?˔uGje0] =,z,0i$~_Kr҃/-[H=17Z}uu5Z]~RRO]|7͚5S-r!Iu"b Lo /!;aMߧ<䓒}Æ lhgwo(ʢt`~Is h`*֭[D\..jjjtx~mIN1&ދ5I_.@ f\>}~'Z"#_=F۷o/b>y$/dߔ)S4MfSJI(^x.^@mh!һwo bW^飽+޽;sϟ?_@cZG⻮jMB?݊ϻ(. +75U%I7$b6C';;G}T[s^MwUm@Bw\bv\CS+o[>S֮]/K/g[jt\XD/1,X?8[DܺYmm[A_8@oJ⬫ ~Tn*?;?H< ~!}鮍W_ /8F_~eC=DJJJ*JɓPE+6?~Zi];Am վ ֭uOdq8 ӓ;x.%-׫DXq&SjZkO[o:Mqg@oӣG~i:FQX22ܖ٦Yv C+7w\\|Œ}{_{c=*@=͏=ܵGPBjrss~7f]*{9ɾ.#Gb`Iu0:M=DyyyǂByB9h>g "waL9e=*Y7;Pnݺ34իW(D%vDMAEGjz'EWwl̛ܸ7I&\;e˖\{EWA&|PQ[v@=ၖx\,zCS&>>3grW G\(YGk2Ѓ}E-sF՜!+v)x(Bs޳)vpDփ͛7֞B?-zHWs!j~Q9B.]6h4MDqy'AH~,QZpG/TenrYr˨´&@jժU&ЏqvB3SKz(03 z>||!gO {Zr5=ʁ3jvZٗ21}?US;fНF5S'jjjXn˨h/^cԘhCZ߫Jt΋/BbtEcVrzZrՎ8ߕ=1t9.\ML%V˖-uhaLctEgҥqBۇr\QQ[uB///P*hLb }=/V:?d 5 4eUm8ŋ;vlש%'}q ֮]zQ*mȏKj.9Wj 4D헵dtͧ.^?D/z[E.q%EǛEתJHhӧOh"Rل7 p ~^'@2~&TzBƙ]<Skբf 0l۶Mu4۷#/pҕ)@K3ycvޭj T=Qn,iEzeh~W>s%U ;5sSYV]r"f_!"V6 P<#UZ>X{*@"B%!P^UAAX0e0CcM!K5an%ڢNJRSS>|xXoZvoa9s&NɮZ x!*Ӣ|g Jm;e}no*J;[ y.爓 }=*e ">䓰дon朗roh.R_]6֟Н/j'FV$%KkLl~Qik-,~J$k׎A: M[o8,a EWy/;h~/*gW1ǣ&Yxnd\E Hee%Z 5LX)r7LiiiخQ`!RKiŪ)ॗ^"l7-v v w,ſ/kx-ʖ,5aL}hHETIUU =:׉Ed=TTTp 7PUph^*uWD?(]86l@nzS썗pq^^Ë5 $ƨ]t*'A}}=s uf|#-א |=7|-YlYدcr-CqM0B#<@eeeدc>>cV^ky _ ښ:g'UAG3NqEf=ȋ먮pMN$cFUJicH^<^Bw^͔qM7nׯg59sR\DK]d0!>bSZZ!7Gaa!ӦMH V`Nlz.w(B!LŽ;ԩeMuuu\s5FAH*py6ExMlݺՈK4rz!6mdĥc5-EB0{&TWWsRPPK4b^~e{=.%‰b MVӄB?())᪫Ɉ3&su[qQ3iշ;~:/(Fg}F|||ך&rlݺɓ'G:ݓ8;S t=,:[B)H(Y?8N3$h5\c7ېZozHB{4.)((`„ MTsANǍ*)Ew)!u>*~'ò:I㣠'm>q([ڃAo!䂿^f֭TUU=IlSPPɓ9|~CFo ùUi&JJJffĉF 0ALNb]z:jm-tl߾\Əժ$_Q4.>͛]믹馛"Hc#^vq11s9ݦ 2رcwf̘ "o@h .xnD)n; e߾}\zFMV01#<< aT;[s˿ RU'|Bff&6(&a뮻O?袈CX awZCCWpfEjHXr#77aP fȐ!,\\-())a̙\q=jxx{br% Bĉvm;4yxW4hQ gЫ(F !{.6mbĈ̚5cǎ]&Ɋ+6ls̡(Y{˽Fh:i|AxgfkTlٲSrWctq!fB.ͼyׯ/b4LhL>ѣGzjy|rs_"MBa3F"̝;s9^z2(شi3f`Ĉ|FG ǀJ"]h:CFB 'N੧O><>|@c].31cưdɒXÿ=/ f5`٘4i7x#cǎVϗʔ)S ,@qq1 .F'X#4׽rpCt -tؑnn;]tzj}.]C%u|DB07hjrEqW2m4Z4,_!\.nʢEϣ!)c(lFhezG!60a,  6K.iӦ1vX:wltBCC6mbٲe,^#G]$=X|uMX:@'+ы={re1vXNbbELnn.VbŊ^1pDXd+䳵z:Cl  X1 zǹ\Znmtdq8ٳ7~z6nHnn 5&TbO 8JQӶm[K9s۷/٤E8]ؽ{7w6rHQ 䁈E\u҅BFF;wstԉL233iٲ%-[$%%$zb>ZPJ8qǢ"9ѣG͍UxlF&p$n#B荰Eo b(p"̨u*p.toW]x؆ xUIS.r=gd:&"%1r54&tAruCgQ^5ŰOzb)aAp1:k1"!S1{>(.pp),'LLDπ/81T1 >a:ae11]}<|E ];<肘)LW ]؟ KE.IDpCpЊ:\|lT45I Bme1 {rpVjD74EtB;ߘ8L_o4}q%A`)`e1 R?c7]ɒ{[FW ]$!qFN9‚KހTJB&)t) k?顏vʁ/~ _|/V ?a:x U Af}3]S -#مD߂Dyb =03<7`FS|m9+dGBo1QvfM4 D_!~'x d"_ ,4{2lB*n'RA;m Dʋ_!4ѴĽ -l5iCzG*|qKB0&Q~DWhM4b =X ] џ(ÉҨY?+ ޴:` =^N!X *}$";ۮav Xny knZ0a Xos * 28$U~f+E\p=NGmJ]N&aztOuN?ˉcM")FNJ2=QU71S豇?kFZ,ؕIa EԈ$3ֵIENDB`wallch-4.0/src/Pictures/image-loading.svg0000644000175000017500000001332312301477401017077 0ustar alexalex wallch-4.0/src/Pictures/page_2_potd.png0000644000175000017500000003050012301477401016546 0ustar alexalexPNG  IHDRZ= IDATxytՕZbmooa1a߉0p $~dEq2LdBf@ C،w0Kbko~H-^UWuWwWsNuJon@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`6 ]\WQQq,WX `<@"C7fc[^۴iPJcNV}O(ζ=k8 g灇zh ~L oFXm[ײ[/=dzm[n|$+iٶp==%=Ps 1!I1jm 16eCIlܸ?۶؁'؁$Iw<77eeezxįK@$A8FGG43jA!f:qGE @\L0())E$S EAADQ̤DePݐehjj$IS+x{u׻8dzB shӃD9~㍍DWGSOqr PUU1ZyA86c$ϛZBIEL]1Je'θVhy_YNG3q9qo}e+~Y pq<ȣ;4{sʛ8=8~<F]])t xzD:ɛg;cXŔɓyU\;Nw%INMM%Gd׮3giFpiCC+5Jceđ7N`Lwڹ=<ɓqA4[ؖ$#2ü9HUVT ??_S,9Mjinn!F:w`C;͛ѣ8ىAp>(,,DQq1P f:B!455M.I7F5I2iݫ~ w$:%̣@\6Fߏ>mh;wasL/ɱ1^Ee{_Pͤ8'ر};vڅ۶fK?oa̙3S (^ t:nF\FS3a!Nz1sMzڹTt%Vy 8=77ƍ_ m 3@\ɌLzM'aw[f򗌊+I7W `(˲:cV]VRR3xsǃrL> -?9guwUg޺^ML\`7=f;ca.?kڵk]I⚮ի. ĩC~nn$I'cɒ%8o",\3f._ {bǶmxg{׮6?͸BnLjK0 U54svJA`b::QI `ҤIx<`~chCpEQ+ˈF!e`'P#@ /^{-Eܜ.^gٳjjܱwq|qRvQmPؽkWRJVDaތWF<^F^uY8tP|}ƮK;cFlH>+++?ޏ>?Dc%x/%ܽ+e 0 o7PPP`$I8Sכ'1UKgżub?>nuغs'y-5&77O=4,t>FGqWy!޻wΚ4ɢ@ )N )oK cqԬYFD\u ĕ& e{Ǔ?o}۸G?T0t~G2ࢋpEaԩ\?}ʳdY,˚#XSn.Bc_KeWn"cLYl?9*]~eO/sE˖ /Ĭٳ!^F7 =x،\I4t(bԩPuyIS+Y q@ۍ60a~x=8 1s4CǃJDsS%obJܮ#8]-t\RشiC+p]qDPAtwu;wn[`rU)=K4k7{.2U?'&LЬ72N'[Eqe߷/)@qI nZJ^>i⢏Lt$ 00cLws8ctQ/;ujZ9''-_y>/"`ٛɍ0 5!P-xsc q,S֮];RY:8qv;qDܸjҒfD2^hknnƴimI7gM׫Ymxī?npX~m bי}hя={/jg’ wᏛ7pI›Hfd$c<{<L:W͑+!nFojqi[.Y$455~;ַP;kn[6(zs))b3Z9</qFsYñBey!Yy.;D"xgq帵^7,{9:eK׬YE+tA\ %F$&jݍo/lْ7;9L8==tRW_͝i$YoMUtle{s7 eX=}ĉ8S__og:c+ ^|_ā?5kh\kVLGrɮ4kտo,^f%tI4MTUU96w1ؾ_|18~c20V$t~ qVHy+~;.s',-'N  ǩ5jja=|w}3A_aÆVLJnjA⪫wvvb`` fhES~d|#et^ޜa8b}$'0 oCo^TTnQ,ej\`ɁL.l &7o|%36zI0on%KY{n?8B%%%1wⲸǃUW_%KLˆ7Gy+2YZfKN+WU,i?@S@zjA\W^{ ?~a:@+Ŀ  ƕl_ ;3s\C95#]]~9xܸj^{-ۓOm dH:BݎkǥmwN6Mzz.]VT 8Eƍ)B?oB3`޽=`%ZnJ|_ǯx{?q3Mez&۝i>3ŰM~E_^^ロ{]2{֮]CzJω'A\qƝ+2Z2*P{vƁ?Fcc#u6A@M0I'c8g|?\L1\R iD ADޜ1۷c64={6v÷eZj[ m&.I%hjj߯Ab۰am/g]k֬{OǺskkʆatdbk`:}A? ׋<Ҳ2픝 T}NQ~C|8JY:횚AțDP:ں=V4Ue2 @IDAT ys 䜓.o>|_/?G܌8^ =ț%K\e x饗Ne /_K A8qf0N8{!onus۱aJ41NKtc==kdMǎ&&9|ԩsɛyd؛a xW8"Iҗ{SV6kj̓1oέns]<͛RgAG:Sf6 񓄞:fқa[ӟ>T~G6u G8HkW[)\ݎY[ubŜs❝زe mff]7nLy"lztm FD5`o&lc#eqÖ-[tTqP?裛S8n cL7UgTnF͙;39vGCߏ_0i؏ݴi|TɖG7FuS#1h&nJآ@>{1m,¾}kWW$H4 KBeYF ( 4B䯱E葄@5f 1+'N;z{{qaܹ|Ѣ\dY90.Mj"tƘfG`0h99i Ԅax'  Ynbԩx]꺺ڍ7~h%2V$IB__:::p1P7lժU'|~#GȸAX+ߺuFb"D}D?]C144B! app0k\!@'7W$  Gz/i!c y/b C|> PXX@ р^W!//qǏG0EUUoK+0kyyyE^^+ORfEEE+ O+dDdTW"0QQ7UAQTTI{F__vUw-T>':c;5 "<^oƉ:툸+ `i=~8O"kf1.[[!BEqIT5A%77- 8r&˖-=Nc~n ɶɿCmQ7AFEQ-DĦ[8qӧO_|U B0_G/++ɓGV8їid[']Mt^S ? ~eh,˚,}mu3hr8i۱0 6'建.-) 7P @3=T"9Ç-O lզFzR^^JJJxu3!t,Te+**43oHiǏל#UH.)t11H}Ye4}ܡfϞ=xWh.A,hiiC4 7L/0Ɩ]pyэ]#'(^ǂ WXRR2U dؽ{7>#̜93.C)Fo21ϴ=fmVڰF+HF3vʲp8SNԗjz%%%|ꡩʔ)˶nݪ̒nb.3 ń~d``{^1D" Cuui֎z%]]e7=}1̀l}Lv&'Ӄ~͞j(#W;3F)zO0xsXLI000@vbL եVWWkWevٲeוeR^W=UWTތ ܩT9Z[[5B͊S /a"^𖴛ݔ(jvN=^s5ގP(,)bQTT_F[[[9N`\L,?Vwߛq{B5w\zyyg1v3(((30cf9p q9< vB'u$iӦ 0Q݈2#.&t/Cy#uE{ee%r#'ݭ)|>M---fU%y矣nDo8pE3 "{YS^PPh4M|XHܦnEFн|>le NEQz{#OKK x MylX\{xVUUaNZ,vǣ2,Dyy9?w~4qL21 Adh4477ւ0!y{ƘK[}/X0NN`άZ bQ58eF\p8 IPZZ.F񝝝4i2A8ǃP(;|>TUU1<,𖢈'rHxTg}5XVN6qD}p'O޲,s`PS~fFݬsՍVߌ+E'O0"70i$zWWWkfe8g޼yIC8<:\@_L_UNA8RL:U7D'OӧO^۔G2F;ֽ띣nH=ZpCoohR= c ~TFbQ!I~l1A@0<_`3m1q[(y(NR7 0 (,,و1A,d``@o߾2wP-bC+O) ̈Dh?ywttVSSiӦ!r"JlrKgg':Vy_x3qGt+0)H(jy_x1Z ,288wY! ceVEE1zHN&F_}5]]]!+a!k0+t mT!+UUU ] 8۶mСCJqkHvP}KKKKcǞ ZƘvq8 "Pw/mGFĭc]U^^`eee.r#3YW۷oh\x-L ]?G~ށI( 11V\ BAbI mmm-S ی>׷7.'TғKf0-Q+J:ǩ+IF(zwDiytX@ЕIO!yQ^J&d="yqe<+IB'E"+բVC Ik:ytYћ"1 2W''hݬLaG0hyޜDN8#) wallch-4.0/src/Pictures/change.png0000644000175000017500000000127012301477401015612 0ustar alexalexPNG  IHDR((mbKGD pHYsu9tIME  (tEXtCommentCreated with GIMPW IDATX=kA{/!~`pIUJDuRR(v*#`G(FbgllQaw, swVEN̙g3QQQQQQ!R=hdcwퟻ lzU`x1~7ھJhgO@.O}M/ ?9 LN;VS; l9 |sPHsLM<* n&8WH.^gPٴf_0&VRaUNeN9+JRjVkeb_4{$I.;޶dyeo?*&&Ippg]Ə yyXFGwbǀBv8ZѐʃĞn\aLs%Wpu Kp8 yCw iZm`$r![rTJOö@ ?$ &iK-NdD>V[ _0***?oũN2IENDB`wallch-4.0/src/Pictures/media-playback-start.svg0000644000175000017500000000254212301477401020401 0ustar alexalex wallch-4.0/src/potd_viewer.cpp0000644000175000017500000003333012301477401015116 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "potd_viewer.h" #include "ui_potd_viewer.h" #include #include PotdViewer::PotdViewer(QWidget *parent) : QDialog(parent), ui(new Ui::potd_viewer) { ui->setupUi(this); selectedDate_=QDate::currentDate(); skipStepsAfterThree_=false; forceStop_=false; ui->previousButton->setIcon(QIcon::fromTheme("media-seek-backward", QIcon(":/icons/Pictures/media-seek-backward.svg"))); ui->nextButton->setIcon(QIcon::fromTheme("media-seek-forward", QIcon(":/icons/Pictures/media-seek-forward.svg"))); ui->save_progressBar->hide(); ui->dateEdit->setDate(selectedDate_); } PotdViewer::~PotdViewer() { if(reply_){ reply_->deleteLater(); } if(originalMovie_){ originalMovie_->deleteLater(); } delete ui; } void PotdViewer::resizeEvent(QResizeEvent *) { if(ui->label->pixmap()) { QSize scaledSize = originalPixmap_.size(); scaledSize.scale(ui->label->size(), Qt::KeepAspectRatio); if (!ui->label->pixmap() || scaledSize != ui->label->pixmap()->size()){ updateLabel(); } } } void PotdViewer::updateLabel() { if(directLinkOfFullImage_.endsWith("gif")) { ui->label->setMovie(originalMovie_); originalMovie_->start(); } else { ui->label->setPixmap(originalPixmap_.scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); } } void PotdViewer::urlQDate() { /* * Step 1 * Find the html link, and download its source */ ui->saveimageButton->setEnabled(false); ui->save_progressBar->hide(); if (Global(true).connectedToInternet()){ htmlSource_=""; if((selectedDate_.year()==2004 && (selectedDate_.month()==11 || selectedDate_.month()==12)) || selectedDate_.year()==2005 || selectedDate_.year()==2006){ url_ = "http://en.wikipedia.org/wiki/Wikipedia:Picture_of_the_day/"+ Global::monthInEnglish(selectedDate_.month()) + selectedDate_.toString("_d,_yyyy"); } else { url_ = "http://en.wikipedia.org/wiki/Template:POTD/"+selectedDate_.toString("yyyy-MM-dd"); } // schedule the request startRequest(url_); } else { enableWidgets(true); QMessageBox::information(this, tr("Error!"),tr("You are not connected to internet.")); } } void PotdViewer::startRequest(QUrl url) { if(reply_){ reply_->deleteLater(); reply_=NULL; } reply_ = qnam_.get(QNetworkRequest(url)); connect(reply_, SIGNAL(finished()), this, SLOT(httpFinished())); connect(reply_, SIGNAL(readyRead()), this, SLOT(httpReadyRead())); } void PotdViewer::movieDestroyed(){ originalMovie_=NULL; } void PotdViewer::httpFinished() { /* * Step 2 * When finished check for errors or redirection page (tough wikipedia has not redirection you never know) */ if(!reply_){ return; } QVariant redirectionTarget = reply_->attribute(QNetworkRequest::RedirectionTargetAttribute); if (reply_->error()) { enableWidgets(true); ui->label->setText(tr("Try another date. Maybe Wikipedia has't\nselected a picture of the day for:")+" "+ui->dateEdit->date().toString()); ui->textBrowser_3->clear(); QMessageBox::information(this, "HTTP",tr("Download failed")+": "+reply_->errorString()+"."); return; } else if (!redirectionTarget.isNull()) { QUrl newUrl = url_.resolved(redirectionTarget.toUrl()); url_ = newUrl; reply_->deleteLater(); startRequest(url_); return; } reply_->deleteLater(); reply_ = NULL; if(!skipStepsAfterThree_) { /* * Step 3 * Get the image's link of the html source downloaded. * The link collected here will still not be a direct link to the image */ QString imageSummix; int imageSummixCount=0; if(htmlSource_.contains("/wiki/File:")) { QRegExp filter(""); int result = filter.indexIn(htmlSource_); if(result != -1){ htmlSource_=filter.cap(1); } while (!imageSummix.contains("\"")) { imageSummixCount++; imageSummix=htmlSource_.left(imageSummixCount); } } else { enableWidgets(true); ui->label->clear(); QMessageBox::information(this, tr("Error!"),tr("Couldn't find image url. Try another date!")); return; } /* * Step 4 * Find the desctription of the current potd */ if(htmlSource_.contains("

") && htmlSource_.contains("")) { QRegExp filter2("

(.+)"); int result2 = filter2.indexIn(htmlSource_); if(result2 != -1){ htmlSource_=filter2.cap(1); } htmlSource_.replace("/wiki", "http://en.wikipedia.org/wiki"); ui->textBrowser_3->setText(htmlSource_); } else if(htmlSource_.contains("

") && htmlSource_.contains("

")){ QRegExp filter2("

(.+)

"); int result2 = filter2.indexIn(htmlSource_); if(result2 != -1){ htmlSource_=filter2.cap(1); } htmlSource_.replace("/wiki", "http://en.wikipedia.org/wiki"); ui->textBrowser_3->setText(htmlSource_); } else { ui->textBrowser_3->setText(tr("We couldn't find the description for this date")+"..."); } /* * Step 5 * We will download the html source of the undirect link to the image * therefore we create a bool to skip steps three-four-five */ skipStepsAfterThree_=true; url_="http://en.wikipedia.org/wiki/File:"+imageSummix.left(imageSummixCount-1); startRequest(url_); } else { skipStepsAfterThree_=false; /* * Step 6 * Find the direct link to the full size image and to the preview image from the second html source we downloaded */ if(htmlSource_.contains("Deleted_photo.png")) { directLinkOfFullImage_=directLinkOfPreviewImage_="http://upload.wikimedia.org/wikipedia/commons/e/e0/Deleted_photo.png"; } else { if(htmlSource_.contains("fullImageLink")) { QRegExp filter("fullImageLink\" id=\"file\">
label->clear(); QMessageBox::information(this, tr("Error!"),tr("Couldn't find image url. Contact us, and include the specific date that shows this error!")); return; } if(htmlSource_.contains("Size of this preview")){ QRegExp filter2("Size of this preview: save_progressBar->setValue(0); ui->save_progressBar->show(); ui->label->clear(); reply_ = qnam_.get(QNetworkRequest(directLinkOfPreviewImage_)); connect(reply_, SIGNAL(finished()),this, SLOT(imageDownloaded())); connect(reply_, SIGNAL(downloadProgress(qint64,qint64)),this, SLOT(updateDataReadProgress(qint64,qint64))); } } void PotdViewer::imageDownloaded() { /* * Step 8 * Set the image to the label */ if(reply_==NULL){ return; } if(directLinkOfFullImage_.endsWith("gif")){ QBuffer *buffer = new QBuffer(this); buffer->open(QIODevice::WriteOnly); buffer->write(reply_->readAll()); buffer->close(); originalMovie_ = new QMovie(buffer, "GIF", this); connect(originalMovie_, SIGNAL(destroyed()), this, SLOT(movieDestroyed())); } else { QImage* image = new QImage(); image->loadFromData(reply_->readAll()); if(image->isNull()){ return; } originalPixmap_=QPixmap::fromImage(*image); delete image; } updateLabel(); ui->save_progressBar->hide(); ui->saveimageButton->setEnabled(true); enableWidgets(true); } void PotdViewer::httpReadyRead() { /* * This slot gets called every time the QNetworkReply has new data. * All of the new data is being read and written into the file. * That way less RAM is used than if the reading was done at the * finished() signal of QNetworkReply */ if(reply_){ htmlSource_+=reply_->readAll(); } } void PotdViewer::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes) { ui->save_progressBar->setMaximum(totalBytes); ui->save_progressBar->setValue(bytesRead); } void PotdViewer::on_quitButton_clicked() { close(); } void PotdViewer::on_saveimageButton_clicked() { //acts as save or cancel. if(QDate::fromString(settings->value("last_day_potd_was_set").toString(),"dd.MM.yyyy")==ui->dateEdit->date()){ QString format=".jpg"; QString savePath = gv.homePath+"/potd_"+settings->value("last_day_potd_was_set", "unkownDate").toString()+format; QString filename = QFileDialog::getSaveFileName(this, tr("Save As"), savePath, format.toUpper()+" "+tr("Files")+" (*."+format+");"+tr("All Files")+" (*)"); if(!filename.isEmpty()){ if(QFile::exists(filename)){ QFile::remove(filename); } if(!QFile::copy(Global::getFilename(gv.wallchHomePath+POTD_IMAGE+"*"), filename)){ QMessageBox::warning(this, tr("Error"), tr("Something went wrong while saving the file!")); } } } else { if(downloadingImage_){ //cancel has been pressed downloadingImage_=false; ui->saveimageButton->setText(tr("Save")); httpRequestAborted_=true; reply_->abort(); ui->save_progressBar->hide(); enableWidgets(true); } else { //save has been pressed downloadingImage_=true; ui->saveimageButton->setText(tr("Cancel")); httpRequestAborted_=false; QFileInfo link(directLinkOfFullImage_); formatOfImage_="."+link.suffix(); ui->save_progressBar->setValue(0); ui->save_progressBar->show(); enableWidgets(false); reply_ = qnam_.get(QNetworkRequest(directLinkOfFullImage_)); connect(reply_, SIGNAL(finished()),this, SLOT(saveImage())); connect(reply_, SIGNAL(downloadProgress(qint64,qint64)),this, SLOT(updateDataReadProgress_save(qint64,qint64))); } } } void PotdViewer::saveImage() { downloadingImage_=false; ui->saveimageButton->setText(tr("Save")); ui->save_progressBar->hide(); enableWidgets(true); ui->saveimageButton->setEnabled(true); QString filename = QFileDialog::getSaveFileName(this, tr("Save As"),gv.homePath+"/potd_"+selectedDate_.toString("dd.MM.yyyy")+formatOfImage_,formatOfImage_.toUpper()+" "+tr("Files")+" (*."+formatOfImage_+");"+tr("All Files")+" (*)"); if(!filename.isEmpty()){ QFile file(filename); if(!file.open(QIODevice::WriteOnly)){ return; } file.write(reply_->readAll()); file.close(); } } void PotdViewer::updateDataReadProgress_save(qint64 bytesRead, qint64 totalBytes) { if(httpRequestAborted_){ return; } ui->save_progressBar->setMaximum(totalBytes); ui->save_progressBar->setValue(bytesRead); } void PotdViewer::enableWidgets(bool state) { ui->dateEdit->setEnabled(state); ui->nextButton->setEnabled(state); ui->previousButton->setEnabled(state); } void PotdViewer::on_dateEdit_dateChanged(const QDate &date_calendar) { if(originalMovie_!=NULL){ originalMovie_->deleteLater(); } enableWidgets(false); selectedDate_=date_calendar; ui->label->setText(tr("Downloading")+"..."); urlQDate(); } void PotdViewer::on_previousButton_clicked() { ui->dateEdit->setDate(selectedDate_.addDays(-1)); } void PotdViewer::on_nextButton_clicked() { ui->dateEdit->setDate(selectedDate_.addDays(+1)); } wallch-4.0/src/glob.h0000644000175000017500000004253012301477401013161 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #ifndef GLOB_H #define GLOB_H #include #include #include #include #include #include #include #include #include #include #include #include "time.h" #ifdef ON_LINUX #include #include "unity/unity/unity.h" #endif //#ifdef ON_LINUX //editing this is enough for everything else (like --version or About dialog) #define APP_VERSION 4.0 #define HELP_URL "http://melloristudio.com/wallch/help" #define DONATE_URL "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Z34FXUH6M4G9S" #ifdef ON_LINUX #define APP_DESKTOP_NAME "wallch-nautilus.desktop" #endif //#ifdef ON_LINUX #define AMBIANCE_THEME_STYLESHEET "QPushButton:checked:!hover {color: white;background-image: url(:/icons/Pictures/ambiance_checked.png);font: 10pt \"Ubuntu\";border: 0px;}QPushButton:checked:hover {color: white;background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png);font: 10pt \"Ubuntu\";border: 0px; }QPushButton {color: white;background-image: url(:/icons/Pictures/ambiance_not_checked.png);font: 10pt \"Ubuntu\";border: 0px;}" #define RADIANCE_THEME_STYLESHEET "QPushButton:checked:!hover {color: #4c4c4c;background-image: url(:/icons/Pictures/radiance_checked.png);font: 10pt \"Ubuntu\";border: 0px;}QPushButton:checked:hover {color: #4c4c4c;background-image: url(:/icons/Pictures/radiance_checked_and_hovered.png);font: 10pt \"Ubuntu\";border: 0px; }QPushButton {color: #4c4c4c;background-image: url(:/icons/Pictures/radiance_not_checked.png);font: 10pt \"Ubuntu\";border: 0px;}" #define AMBIANCE_SEPARATOR QPixmap(":/icons/Pictures/ambiance_separator.png") #define RADIANCE_SEPARATOR QPixmap(":/icons/Pictures/radiance_seperator.png") #ifdef ON_LINUX #define INDICATOR_AMBIANCE_NORMAL QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_ambiance_normal.png")).toLocal8Bit().data() #define INDICATOR_AMBIANCE_LEFT QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_ambiance_left.png")).toLocal8Bit().data() #define INDICATOR_AMBIANCE_RIGHT QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_ambiance_right.png")).toLocal8Bit().data() #define INDICATOR_AMBIANCE_PAUSE QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_ambiance_pause.png")).toLocal8Bit().data() #define INDICATOR_AMBIANCE_EARTH QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_ambiance_earth.png")).toLocal8Bit().data() #define INDICATOR_AMBIANCE_POTD QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_ambiance_potd.png")).toLocal8Bit().data() #define INDICATOR_AMBIANCE_CLOCKS QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_ambiance_clocks.png")).toLocal8Bit().data() #define INDICATOR_AMBIANCE_WEBSITE QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_ambiance_website.png")).toLocal8Bit().data() #define INDICATOR_RADIANCE_NORMAL QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_radiance_normal.png")).toLocal8Bit().data() #define INDICATOR_RADIANCE_LEFT QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_radiance_left.png")).toLocal8Bit().data() #define INDICATOR_RADIANCE_RIGHT QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_radiance_right.png")).toLocal8Bit().data() #define INDICATOR_RADIANCE_PAUSE QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_radiance_pause.png")).toLocal8Bit().data() #define INDICATOR_RADIANCE_EARTH QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_radiance_earth.png")).toLocal8Bit().data() #define INDICATOR_RADIANCE_POTD QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_radiance_potd.png")).toLocal8Bit().data() #define INDICATOR_RADIANCE_CLOCKS QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_radiance_clocks.png")).toLocal8Bit().data() #define INDICATOR_RADIANCE_WEBSITE QString(QString::fromStdString(PREFIX)+QString("/share/wallch/files/indicator_radiance_website.png")).toLocal8Bit().data() #define INDICATOR_SCROLL_INTERVAL 400 #define INDICATOR_DESCRIPTION "Wallch Indicator" #endif //#ifdef ON_LINUX #define POTD_ONLINE_URL "https://dl.dropboxusercontent.com/u/257493884/potd" #define LIVEARTH_ONLINE_URL "http://dl.dropboxusercontent.com/u/257493884/le" #define POTD_ONLINE_URL_B "http://melloristudio.com/wallch/potd" #define LIVEARTH_ONLINE_URL_B "http://melloristudio.com/wallch/le" #define LE_IMAGE "liveEarth" #define POTD_IMAGE "potd" #define WC_IMAGE "wallpaperClock" #define LW_IMAGE "liveWebsite" #define LW_PREVIEW_IMAGE "liveWebsitePreview.png" #define POTD_PREVIEW_IMAGE "previewPotd.jpg" #define NULL_IMAGE "empty.png" #define HISTORY_SETTINGS "wallch", "History" #define DEFAULT_SLIDER_DELAY 900 #define WEBSITE_TIMEOUT 90 #define RESEARCH_FOLDERS_TIMEOUT 1500 #define LEAST_WALLPAPERS_FOR_START 2 #define LIVEARTH_INTERVAL 1800 #define INTERVAL_INDEPENDENCE_DEFAULT_VALUE "p-1.0000:00:00:00:00:00" #define IMAGE_FILTERS QStringList() << "*.png" << "*.PNG" << "*.jpg" << "*.JPG" << "*.jpeg" << "*.JPEG" << "*.gif" << "*.GIF" << "*.bmp" << "*.BMP" << "*.svg" << "*.SVG" #define DEFAULT_INTERVALS_IN_SECONDS QList() << 10 << 30 << 60 << 180 << 300 << 600 << 900 << 1200 << 1800 << 2700 << 3600 << 7200 << 10800 << 14400 << 21600 << 43200 << 86400 #define MENU_POPUP_POS QPoint(QCursor::pos()) + QPoint(2, 0) #define PREVIOUS_PICTURES_LIMIT 30 #define BYTES_PER_MiB 1048576.0 #define BYTES_PER_KiB 1024.0 #define MAX_IMAGE_CACHE 12 // Should be about ~5000 images #define CACHE_IMAGES_PER_MiB 420 //average, tested using 1034 HD images. #define CACHED_IMAGES_SIZE 80, 80 #define AUTOSTART_DIR "/.config/autostart/" #define BOOT_DESKTOP_FILE "wallch.desktop" #ifdef ON_WIN32 #include "notification.h" #endif extern QSettings *settings; #ifdef ON_LINUX typedef enum { //please note that the row of these must match the row of the corresponding combobox in Preferences Dialog. UnityGnome, Gnome, XFCE, LXDE, Mate } DesktopEnvironment; typedef enum { NoneColor, SolidColor, HorizontalColor, VerticalColor } ColoringType; #endif struct GlobalVar { QString homePath; QString wallchHomePath; QString currentTheme; QString currentDeDefaultWallpapersPath; QString currentOSName; int currentRandomImageIndex; bool preferencesDialogShown; bool independentIntervalEnabled; bool useShortcutNext; bool randomTimeEnabled; bool randomImagesEnabled; bool firstTimeout; bool processPaused; #ifdef ON_LINUX bool unityProgressbarEnabled; DesktopEnvironment currentDE; #endif //#ifdef ON_LINUX bool saveHistory; int randomTimeFrom; int randomTimeTo; bool doNotToggleRadiobuttonFallback; bool previewImagesOnScreen; bool amPmEnabled; bool mainwindowLoaded; bool setAverageColor; bool websiteLoginEnabled; bool websiteCropEnabled; int wallpapersChangedCurrentSession; QDateTime timeLaunched; bool showNotification; bool wallpaperClocksRunning; bool liveWebsiteRunning; bool potdRunning; bool liveEarthRunning; bool wallpapersRunning; bool iconMode; bool rotateImages; bool potdIncludeDescription; bool potdDescriptionBottom; short wallpaperClocksHourImages; short refreshhourinterval; short websiteWaitAfterFinishSeconds; bool websiteLoadImages; bool websiteJavaEnabled; bool websiteJavascriptCanReadClipboard; bool websiteJavascriptEnabled; bool websiteSimpleAuthEnabled; int websiteInterval; int screenHeight; int screenWidth; int potdDescriptionLeftMargin; int potdDescriptionRightMargin; int potdDescriptionBottomTopMargin; QString cachePath; QDateTime appStartTime; int currentImageCacheSize; QString websiteWebpageToLoad; QString defaultPicturesLocation; QString potdDescriptionFont; QString potdDescriptionColor; QString potdDescriptionBackgroundColor; QStringList defaultIntervals; QStringList websiteExtraUsernames; QStringList websiteExtraPasswords; QString defaultWallpaperClock; QString nextShortcut; QString potdOnlineUrl; QString potdOnlineUrlB; QString liveEarthOnlineUrl; QString liveEarthOnlineUrlB; QString onlineLinkForHistory; QList randomImages; QList customIntervalsInSeconds; QRect websiteCropArea; QString websiteLoginUsername; QString websiteLoginPasswd; QString websiteFinalPageToLoad; bool websiteRedirect; QDateTime runningTimeOfProcess; QDateTime timeToFinishProcessInterval; #ifdef ON_LINUX //unity launcher shortcuts UnityLauncherEntry *unityLauncherEntry; DbusmenuMenuitem *unityStopAction, *unityPauseAction,*unityNextAction, *unityPreviousAction; //indicator AppIndicator *applicationIndicator; GtkWidget *wallpapersRadiobutton, *liveEarthRadiobutton, *potdRadiobutton, *wallpaperClocksRadiobutton, *liveWebsiteRadiobutton, *iAmNotThere, *wallpapersJustChange, *wallpapersPlayPause, *wallpapersNext, *wallpapersPrevious; #endif //#ifdef ON_LINUX //variable initialization GlobalVar() : homePath(QDir::homePath()), currentTheme("ambiance"), currentRandomImageIndex(0), preferencesDialogShown(false), independentIntervalEnabled(true), useShortcutNext(false), randomTimeEnabled(false), randomImagesEnabled(false), firstTimeout(false), processPaused(false), #ifdef ON_LINUX unityProgressbarEnabled(false), currentDE(UnityGnome), #endif saveHistory(true), randomTimeFrom(300), randomTimeTo(1200), doNotToggleRadiobuttonFallback(false), previewImagesOnScreen(true), amPmEnabled(false), mainwindowLoaded(false), setAverageColor(false), websiteLoginEnabled(false), websiteCropEnabled(false), wallpapersChangedCurrentSession(0), timeLaunched(QDateTime::currentDateTime()), showNotification(false), wallpaperClocksRunning(false), liveWebsiteRunning(false), potdRunning(false), liveEarthRunning(false), wallpapersRunning(false), iconMode(true), rotateImages(false), potdIncludeDescription(true), potdDescriptionBottom(true), wallpaperClocksHourImages(0), refreshhourinterval(0), websiteWaitAfterFinishSeconds(3), websiteLoadImages(true), websiteJavaEnabled(false), websiteJavascriptCanReadClipboard(false), websiteJavascriptEnabled(true), websiteSimpleAuthEnabled(false), websiteInterval(6), screenHeight(0), screenWidth(0), potdDescriptionLeftMargin(100), potdDescriptionRightMargin(0), potdDescriptionBottomTopMargin(0), appStartTime(QDateTime::currentDateTime()), currentImageCacheSize(0), websiteWebpageToLoad("http://google.com"), defaultPicturesLocation(QStandardPaths::displayName(QStandardPaths::PicturesLocation)), potdDescriptionFont("Ubuntu"), defaultIntervals(QStringList() << "10 "+QObject::tr("seconds") << "30 "+QObject::tr("seconds") << "1 "+QObject::tr("minute") << "3 "+QObject::tr("minutes") << "5 "+QObject::tr("minutes") << "10 "+QObject::tr("minutes") << "15 "+QObject::tr("minutes") << "20 "+QObject::tr("minutes") << "30 "+QObject::tr("minutes") << "45 "+QObject::tr("minutes") << "1 "+QObject::tr("hour") << "2 "+QObject::tr("hours") << "3 "+QObject::tr("hours") << "4 "+QObject::tr("hours") << "6 "+QObject::tr("hours") << "12 "+QObject::tr("hours") << "1 "+QObject::tr("day")) {} }; extern struct GlobalVar gv; typedef struct { QStringList images; int imageCount; QList imagesSizeList; int size; } CacheEntry; class Global: public QObject { Q_OBJECT public: Global(bool internetOperation); ~Global(); static void saveHistory(const QString &image, short feature); static void rotateImg(const QString &filename, short rotation_type, bool show_messagebox); static QString wallpaperClockNow(const QString &path, bool minuteCheck, bool hourCheck, bool amPmCheck, bool dayWeekCheck, bool dayMonthCheck, bool monthCheck); static void readClockIni(const QString &path); void desktopNotify(const QString text, bool checkImage, const QString &image); static void setBackground(const QString &image, bool changeAverageColor, bool showNotification, short feature); static QString setAverageColor(const QString &image); static QStringList listFolders(const QString &parentFolder, bool recursively, bool includeParent); static void openFolderOf(QString image = ""); static void generateRandomImages(int imagesNumber, int firstOne); static void generateRandomImage(const QStringList &images); static QString basenameOf(const QString &path); static QString dirnameOf(const QString &path); static QString currentBackgroundImage(); static QString timeNowToString(); static QString secondsToMinutesHoursDays(int seconds); static int websiteSliderValueToSeconds(short value); static bool remove(const QString &files); static QString getFilename(const QString &file); static bool foldersAreSame(QString folder1, QString folder2); static void saveSecondsLeftNow(int secondsLeft, short forType); static QString base64Decode(const QString &string); static void rotateImageBasedOnExif(const QString &image); static short getExifRotation(const QString &filename); static void resetSleepProtection(int timeoutCount); static void addPreviousBackground(QStringList &previous_backgrounds, const QString &image); static void error(const QString &message); static void debug(const QString &message); #ifdef ON_LINUX static void setUnityProgressBarEnabled(bool state); static void setUnityProgressbarValue(float percent); static QString gsettingsGet(const QString &schema, const QString &key); static QString getPrimaryColor(); static QString getSecondaryColor(); static void setPrimaryColor(const QString &colorName); static void setSecondaryColor(const QString &colorName); static ColoringType getColoringType(); static QString getPcManFmValue(const QString &key); static void gsettingsSet(const QString &schema, const QString &key, const QString &value); static void changeIndicatorIcon(const QString &icon); static void changeIndicatorSelection(const QString &status); static void showWallpapersIndicatorControls(bool show, bool pauseText); #endif //#ifdef ON_LINUX static int getSecondsTillHour(const QString &hour); static bool addToCacheSize (qint64 size); static QString originalToCacheName(QString image_path); static QString getOutputOfCommand(QString command, QStringList parameters); static void openUrl(const QString &url); static QString monthInEnglish(short month); static void updateStartup(); static bool createDesktopFile(const QString &path, const QString &command, const QString &comment); void livearth(); void potd(); CacheEntry getCacheStatus(); bool connectedToInternet(); void fixCacheSize(QString curWallpapersFolder); void abortDownload(); private: #ifdef ON_WIN32 Notification *notification_; #endif QNetworkAccessManager *fileDownloader_; QNetworkReply *currentNetworkRequest_; bool internetOperation_; bool internetChecked_; bool connectedToInternet_; bool alreadyTriedAlternativeLinkToDropbox_; QDate potdDescriptionDate_; QString potdDescriptionFilename_; void downloadTextFileContainingImage(const QString &url); void disconnectFileDownloader(); QString cacheToOriginalName(QString cacheName); qint64 cacheGetSizeOfCachedName(const QString &cacheName); bool isSubfolder(QString &subfolder, QString &parentFolder); QString cacheExcludeSize(const QString &cacheName); void downloadOnlineImage(const QString &onlineLink); void tryDownloadingImagesFromAlternativeLink(); void downloadPotdDescription(); void replaceSpecialHtml(QString &html); void writePotdDescription(const QString &description); void onlineRequestComplete(const QString &filename); static QString searchForFileInDir(QString folder, QString file); static void setPcManFmValue(const QString &key, const QString &value); private Q_SLOTS: void readFileContainingImage(QNetworkReply *reply); void saveImage(QNetworkReply *reply); void internetConnectionReplyFinished(QNetworkReply* reply); void getPotdDescription(QNetworkReply* reply); #ifdef ON_WIN32 void notificationDestroyed(); #endif Q_SIGNALS: void onlineRequestFailed(); void onlineImageRequestReady(QString image); void updateNotification(QString message, QString image); }; #endif // GLOB_H wallch-4.0/src/icons.qrc0000644000175000017500000000340312301477401013703 0ustar alexalex Pictures/wallch.png Pictures/monitor320x200.png Pictures/ambiance_checked.png Pictures/ambiance_checked_and_hovered.png Pictures/ambiance_not_checked.png Pictures/ambiance_separator.png Pictures/change.png Pictures/radiance_checked_and_hovered.png Pictures/radiance_checked.png Pictures/radiance_not_checked.png Pictures/radiance_seperator.png Pictures/page_3_clock.png Pictures/page_1_earth.png Pictures/page_4_website.png Pictures/page_2_potd.png Pictures/process_request.gif Pictures/applications-accessories.svg Pictures/go-down.svg Pictures/list-add.svg Pictures/list-remove.svg Pictures/media-playback-start.svg Pictures/media-playback-stop.svg Pictures/media-seek-backward.svg Pictures/media-seek-forward.svg Pictures/image-loading.svg Pictures/media-playback-pause.svg Pictures/window-close.svg Pictures/go-up.svg Pictures/info.svg Pictures/folder.svg Pictures/application-exit.svg Pictures/preferences-desktop.svg Pictures/task-due.svg Pictures/btn_donate_LG.gif Pictures/mellori-logo.png wallch-4.0/src/statistics.h0000644000175000017500000000255512301477401014433 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef STATISTICS_H #define STATISTICS_H #include #include namespace Ui { class statistics; } class Statistics : public QDialog { Q_OBJECT public: explicit Statistics(QWidget *parent = 0); ~Statistics(); private: Ui::statistics *ui; QTimer *updateValuesTimer_; unsigned int totalUptime_, totalLaunchedTimes_; QString secondsToDateSring(unsigned int seconds); private Q_SLOTS: void on_reset_clicked(); void on_ok_clicked(); void updateValues(); }; #endif // STATISTICS_H wallch-4.0/src/properties.cpp0000644000175000017500000001340612301477401014765 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include "properties.h" #include "ui_properties.h" #include "glob.h" #include #include #include #include Properties::Properties(const QString &img, bool showNextPrevious, int currentIndex, QWidget *parent) : QDialog(parent), ui(new Ui::properties) { ui->setupUi(this); //Moving the window to the center of screen! this->move(QApplication::desktop()->availableGeometry().center() - this->rect().center()); nextPreviousTimer_ = new QTimer(this); nextPreviousTimer_->setSingleShot(true); connect(nextPreviousTimer_, SIGNAL(timeout()), this, SLOT(uncheckButtons())); updateEntries(img, currentIndex); if(!showNextPrevious){ ui->previous->hide(); ui->next->hide(); } else { (void) new QShortcut(Qt::Key_Right, this, SLOT(simulateNext())); (void) new QShortcut(Qt::Key_Left, this, SLOT(simulatePrevious())); } ui->previous->setIcon(QIcon::fromTheme("media-seek-backward", QIcon(":/icons/Pictures/media-seek-backward.svg"))); ui->next->setIcon(QIcon::fromTheme("media-seek-forward", QIcon(":/icons/Pictures/media-seek-forward.svg"))); } Properties::~Properties() { if(nextPreviousTimer_->isActive()){ nextPreviousTimer_->stop(); } delete ui; } void Properties::on_close_clicked() { close(); } void Properties::resizeEvent(QResizeEvent *) { QSize scaledSize = currentPixmap_.size(); scaledSize.scale(ui->label->size(), Qt::KeepAspectRatio); if (!ui->label->pixmap() || scaledSize != ui->label->pixmap()->size()){ updateScreenshotLabel(); } } void Properties::updateScreenshotLabel() { ui->label->setPixmap(currentPixmap_.scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); } void Properties::updateEntries(const QString &filename, int currentIndex){ currentFilename_=filename; currentIndex_=currentIndex; QImageReader reader(filename); if(reader.canRead()){ QString originalWidth = QString::number(reader.size().width()); QString originalHeight = QString::number(reader.size().height()); bool resize=false; double scaleFactorX=0, scaleFactorY=0; if(reader.size().width()>gv.screenWidth){ resize=true; scaleFactorX=gv.screenWidth*1.0/reader.size().width(); } if(reader.size().height()>gv.screenHeight){ resize=true; scaleFactorY=gv.screenHeight*1.0/reader.size().height(); } if(resize) { if(scaleFactorX==0 || (scaleFactorYnameLineEdit->setText(Global::basenameOf(filename)); ui->type_label->setText(imageInfo.suffix().toUpper()); ui->dimensionsLabel->setText(originalWidth + " x " + originalHeight); ui->size_label->setText(sizeToNiceString(QFile(filename).size())); ui->location_label->setText(Global::dirnameOf(filename)); ui->created_label->setText(imageInfo.created().toString("ddd, MMM d yyyy hh:mm:ss")); ui->modified_label->setText(imageInfo.lastModified().toString("ddd, MMM d yyyy hh:mm:ss")); currentPixmap_ = QPixmap().fromImage(reader.read()); updateScreenshotLabel(); } else { currentPixmap_ = QPixmap(QIcon::fromTheme("dialog-error").pixmap(100)); updateScreenshotLabel(); } } void Properties::on_next_clicked() { Q_EMIT requestNext(currentIndex_); } void Properties::on_previous_clicked() { Q_EMIT requestPrevious(currentIndex_); } void Properties::simulateNext(){ //simulates the next button to be pressed down for a bit! ui->previous->setDown(false); ui->next->setDown(false); ui->next->setDown(true); on_next_clicked(); if(nextPreviousTimer_->isActive()){ nextPreviousTimer_->stop(); } nextPreviousTimer_->start(200); } void Properties::simulatePrevious(){ ui->previous->setDown(false); ui->next->setDown(false); ui->previous->setDown(true); on_previous_clicked(); if(nextPreviousTimer_->isActive()){ nextPreviousTimer_->stop(); } nextPreviousTimer_->start(200); } void Properties::uncheckButtons(){ ui->next->setDown(false); ui->previous->setDown(false); } void Properties::on_set_as_background_clicked() { Global::setBackground(currentFilename_, true, true, 1); } QString Properties::sizeToNiceString(qint64 fsize){ if(fsize>=BYTES_PER_MiB){ return QString::number(fsize/BYTES_PER_MiB, 'f', 1) + " MiB"; } else{ return QString::number(fsize/BYTES_PER_KiB, 'f', 1) + " KiB"; } } void Properties::on_open_location_button_clicked() { Global::openFolderOf(currentFilename_); } wallch-4.0/src/about.h0000644000175000017500000000253012301477401013344 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ABOUT_H #define ABOUT_H #include namespace Ui { class about; } class About : public QDialog { Q_OBJECT public: About(QWidget *parent = 0); ~About(); protected: void changeEvent(QEvent *e); private: Ui::about *ui; short easterEggCounter_; private Q_SLOTS: void on_website_label_linkActivated(); void on_about_button_clicked(); void on_credits_button_clicked(); void on_license_button_clicked(); void on_closeButton_clicked(); }; #endif // ABOUT_H wallch-4.0/src/glob.cpp0000644000175000017500000021407312301477401013517 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #ifdef ON_LINUX #include #include #include #else #include #endif #include "glob.h" #include "mainwindow.h" const QChar cacheFromChar='/'; //do NOT change const QChar cacheToChar='^'; //change, but it CANNOT be the same as cacheAlreadyIncludedDelimiter const QChar cacheAlreadyIncludedDelimiter='.'; //cannot be the same with the cacheToChar const QChar cache_size_char='='; QSettings *settings = new QSettings("wallch", "Settings"); Global::Global(bool internetOperation){ if(internetOperation){ fileDownloader_ = new QNetworkAccessManager(this); currentNetworkRequest_=NULL; } internetOperation_=internetOperation; #ifdef WIN32 notification_=NULL; #endif } Global::~Global(){ if(internetOperation_){ delete fileDownloader_; } } #ifdef ON_LINUX void Global::setUnityProgressBarEnabled(bool state){ if(!gv.unityLauncherEntry){ gv.unityLauncherEntry = unity_launcher_entry_get_for_desktop_id(APP_DESKTOP_NAME); } unity_launcher_entry_set_progress_visible(gv.unityLauncherEntry, state); setUnityProgressbarValue(0); } void Global::setUnityProgressbarValue(float percent){ if(!gv.unityLauncherEntry){ gv.unityLauncherEntry = unity_launcher_entry_get_for_desktop_id(APP_DESKTOP_NAME); } unity_launcher_entry_set_progress(gv.unityLauncherEntry, percent); } #endif //#ifdef ON_LINUX void Global::potd(){ //searching whether the link for current day is saved at settings settings->beginGroup("potd_links"); potdDescriptionDate_=QDate::currentDate(); QString curOnlineLink=settings->value(potdDescriptionDate_.toString("dd.MM.yyyy"), "").toString(); settings->endGroup(); if(curOnlineLink.isEmpty()){ alreadyTriedAlternativeLinkToDropbox_=false; downloadTextFileContainingImage(gv.potdOnlineUrl); } else { Global::debug("The link is already available"); downloadOnlineImage(curOnlineLink); } } void Global::tryDownloadingImagesFromAlternativeLink(){ alreadyTriedAlternativeLinkToDropbox_=true; if(gv.potdRunning){ downloadTextFileContainingImage(gv.potdOnlineUrlB); } else { downloadTextFileContainingImage(gv.liveEarthOnlineUrlB); } } void Global::readFileContainingImage(QNetworkReply *reply){ currentNetworkRequest_->deleteLater(); currentNetworkRequest_=NULL; if (reply->error()){ if(!alreadyTriedAlternativeLinkToDropbox_){ tryDownloadingImagesFromAlternativeLink(); } else { Q_EMIT onlineRequestFailed(); Global::error("Could not process your request: "+reply->errorString()); reply->deleteLater(); } return; } QString onlineLink(reply->readAll()); reply->deleteLater(); if(gv.potdRunning){ //potd has multiple links in it QStringList linksDates=onlineLink.split(QRegExp("[ \n]"),QString::SkipEmptyParts); if(linksDates.count()!=6){ if(!alreadyTriedAlternativeLinkToDropbox_){ tryDownloadingImagesFromAlternativeLink(); } else { desktopNotify(tr("Today's Picture Of The Day is not available!"), false, "info"); Q_EMIT onlineRequestFailed(); } return; } if(!linksDates.at(1).startsWith("http")){ //something's wrong! if(!alreadyTriedAlternativeLinkToDropbox_){ tryDownloadingImagesFromAlternativeLink(); } else { desktopNotify(tr("Today's Picture Of The Day is not available!"), false, "info"); Q_EMIT onlineRequestFailed(); } return; } settings->remove("potd_links"); settings->beginGroup("potd_links"); bool linkFound=false; QString curDate=QDate::currentDate().toString("dd.MM.yyyy"); for(short i=0;i<6;i+=2){ if(!linkFound){ if(curDate==linksDates.at(i)){ linkFound=true; onlineLink=linksDates.at(i+1); } } settings->setValue(linksDates.at(i), linksDates.at(i+1)); } settings->endGroup(); settings->sync(); if(!linkFound){ if(!alreadyTriedAlternativeLinkToDropbox_){ tryDownloadingImagesFromAlternativeLink(); } else { desktopNotify(tr("Today's Picture Of The Day is not available!"), false, "info"); Q_EMIT onlineRequestFailed(); } return; } } else if(gv.liveEarthRunning) { if(!onlineLink.startsWith("http:")){ if(!alreadyTriedAlternativeLinkToDropbox_){ tryDownloadingImagesFromAlternativeLink(); } else { Global::error("Live Earth image download failed!"); Q_EMIT onlineRequestFailed(); } return; } } onlineLink.replace('\n', ""); gv.onlineLinkForHistory=onlineLink; if(gv.liveEarthRunning){ Global::remove(gv.wallchHomePath+LE_IMAGE+"*"); } else if(gv.potdRunning){ QString previous_img_URL=settings->value("previous_img_url", "").toString(); if(previous_img_URL==onlineLink){ //image has not yet changed, just skip it for the next day :D Global::debug("Wikipedia Picture of the day picture has yet to be updated. Setting the same image..."); QString filename = Global::getFilename(gv.wallchHomePath+POTD_IMAGE+"*"); if(!filename.isEmpty()){ onlineRequestComplete(filename); return; } else { Global::debug("Redownloading the image..."); } } } downloadOnlineImage(onlineLink); } void Global::downloadOnlineImage(const QString &onlineLink){ disconnectFileDownloader(); QObject::connect(fileDownloader_, SIGNAL(finished(QNetworkReply*)), this, SLOT(saveImage(QNetworkReply*))); currentNetworkRequest_=fileDownloader_->get(QNetworkRequest(QUrl(onlineLink))); } void Global::disconnectFileDownloader(){ QObject::disconnect(fileDownloader_, SIGNAL(finished(QNetworkReply*)), this, SLOT(getPotdDescription(QNetworkReply*))); QObject::disconnect(fileDownloader_, SIGNAL(finished(QNetworkReply*)), this, SLOT(saveImage(QNetworkReply*))); QObject::disconnect(fileDownloader_, SIGNAL(finished(QNetworkReply*)), this, SLOT(readFileContainingImage(QNetworkReply*))); QObject::disconnect(fileDownloader_, SIGNAL(finished(QNetworkReply*)), this, SLOT(internetConnectionReplyFinished(QNetworkReply*))); } void Global::getPotdDescription(QNetworkReply *reply){ currentNetworkRequest_->deleteLater(); currentNetworkRequest_=NULL; if(reply->error()){ //set potd without the description Global::error("Could not get picture of the day description. Setting image as is."); onlineRequestComplete(potdDescriptionFilename_); return; } QString potdDescription(reply->readAll()); reply->deleteLater(); if(potdDescription.contains("/wiki/File:")) { QRegExp filter(""); int result = filter.indexIn(potdDescription); if(result != -1){ potdDescription=filter.cap(1); } } else { Global::error("Could not get picture of the day description. Setting image as is."); onlineRequestComplete(potdDescriptionFilename_); return; } if(potdDescription.contains("

") && potdDescription.contains("")) { QRegExp filter2("

(.+)"); int result2 = filter2.indexIn(potdDescription); if(result2 != -1){ potdDescription=filter2.cap(1); } } else { Global::error("Could not get picture of the day description. Setting image as is."); onlineRequestComplete(potdDescriptionFilename_); return; } potdDescription.replace("/wiki", "http://en.wikipedia.org/wiki").remove(QRegExp("<[^>]*>")).replace("\n", " "); replaceSpecialHtml(potdDescription); QtConcurrent::run(this, &Global::writePotdDescription, potdDescription); } void Global::writePotdDescription(const QString &description){ QImage image(potdDescriptionFilename_); QPainter drawer(&image); QFont font; font.setFamily(gv.potdDescriptionFont); font.setPixelSize(image.width()/55); drawer.setFont(font); QRect drawRect; drawRect=drawer.fontMetrics().boundingRect(QRect(0, 0, image.width()-(gv.potdDescriptionLeftMargin+gv.potdDescriptionRightMargin), image.height()), (Qt::TextWordWrap | Qt::AlignCenter), description); drawRect.setX(0); drawRect.setWidth(image.width()); int newY; if(gv.potdDescriptionBottom){ newY=image.height()-drawRect.height()-gv.potdDescriptionBottomTopMargin; } else { newY=gv.potdDescriptionBottomTopMargin; } int oldH=drawRect.height(); drawRect.setY(newY); drawRect.setHeight(oldH); QColor backgroundColor=QColor(gv.potdDescriptionBackgroundColor); backgroundColor.setAlpha(176); drawer.fillRect(drawRect, QBrush(backgroundColor)); drawRect.setX(gv.potdDescriptionLeftMargin); drawRect.setWidth(image.width()-(gv.potdDescriptionLeftMargin+gv.potdDescriptionRightMargin)); drawer.setPen(QColor(gv.potdDescriptionColor)); drawer.drawText(drawRect, (Qt::TextWordWrap | Qt::AlignCenter), description, &drawRect); drawer.end(); image.save(potdDescriptionFilename_, "JPEG", 100); onlineRequestComplete(potdDescriptionFilename_); } void Global::onlineRequestComplete(const QString &filename){ setBackground(filename, true, gv.potdRunning, (gv.potdRunning ? 3 : 2)); if(gv.mainwindowLoaded){ Q_EMIT onlineImageRequestReady(filename); } } void Global::replaceSpecialHtml(QString &html){ QTextDocument textDocument; textDocument.setHtml(html); html=textDocument.toPlainText(); } void Global::downloadTextFileContainingImage(const QString &url){ //downloads the plain text file that contains the direct link to the image disconnectFileDownloader(); QObject::connect(fileDownloader_, SIGNAL(finished(QNetworkReply*)), this, SLOT(readFileContainingImage(QNetworkReply*))); currentNetworkRequest_=fileDownloader_->get(QNetworkRequest(QUrl(url))); } void Global::abortDownload(){ if(currentNetworkRequest_!=NULL && !currentNetworkRequest_->isFinished()){ currentNetworkRequest_->abort(); } } void Global::saveImage(QNetworkReply *reply) { currentNetworkRequest_->deleteLater(); currentNetworkRequest_=NULL; if (reply->error()){ Q_EMIT onlineRequestFailed(); Global::error("Could not process your request: "+reply->errorString()); reply->deleteLater(); return; } QString filename; if(gv.liveEarthRunning){ Global::remove(gv.wallchHomePath+LE_IMAGE+"*"); filename=gv.wallchHomePath+LE_IMAGE+QString::number(QDateTime::currentMSecsSinceEpoch())+".jpg"; } else if(gv.potdRunning){ Global::remove(gv.wallchHomePath+POTD_IMAGE+"*"); filename=gv.wallchHomePath+POTD_IMAGE+QString::number(QDateTime::currentMSecsSinceEpoch())+".jpg"; } else { reply->deleteLater(); return; } QFile file(filename); if (!file.open(QIODevice::WriteOnly)){ Global::error("Could not save image at "+filename+" !"); Q_EMIT onlineRequestFailed(); reply->deleteLater(); return; } file.write(reply->readAll()); file.close(); if(gv.potdRunning){ settings->setValue("previous_img_url", reply->url().toString()); settings->setValue("last_day_potd_was_set", QDateTime::currentDateTime().toString("dd.MM.yyyy")); settings->setValue("potd_preferences_have_changed", false); settings->sync(); } reply->deleteLater(); if(gv.potdRunning && gv.potdIncludeDescription){ potdDescriptionFilename_=filename; downloadPotdDescription(); } else { onlineRequestComplete(filename); } } void Global::downloadPotdDescription(){ disconnectFileDownloader(); connect(fileDownloader_, SIGNAL(finished(QNetworkReply*)), this, SLOT(getPotdDescription(QNetworkReply*))); QString urlToGetDescription; if((potdDescriptionDate_.year()==2004 && (potdDescriptionDate_.month()==11 || potdDescriptionDate_.month()==12)) || potdDescriptionDate_.year()==2005 || potdDescriptionDate_.year()==2006){ urlToGetDescription = "http://en.wikipedia.org/wiki/Wikipedia:Picture_of_the_day/"+ Global::monthInEnglish(potdDescriptionDate_.month()) + potdDescriptionDate_.toString("_d,_yyyy"); } else{ urlToGetDescription = "http://en.wikipedia.org/wiki/Template:POTD/"+potdDescriptionDate_.toString("yyyy-MM-dd"); } currentNetworkRequest_=fileDownloader_->get(QNetworkRequest(QUrl(urlToGetDescription))); } QString Global::monthInEnglish(short month) { /* * Do NOT replace this function with QDate::longMonthName(), * because it is system language independent (but this always * returns english month names). */ switch(month){ case 1: return "January"; break; case 2: return "February"; break; case 3: return "March"; break; case 4: return "April"; break; case 5: return "May"; break; case 6: return "June"; break; case 7: return "July"; break; case 8: return "August"; break; case 9: return "September"; break; case 10: return "October"; break; case 11: return "November"; break; case 12: return "December"; break; default: return "Error"; break; } } void Global::livearth(){ alreadyTriedAlternativeLinkToDropbox_=false; downloadTextFileContainingImage(gv.liveEarthOnlineUrl); } void Global::setBackground(const QString &image, bool changeAverageColor, bool showNotification, short feature){ if(!QFile::exists(image)){ Global::error("Image doesn't exist, background cannot be changed!"); return; } bool result=true; #ifdef ON_LINUX if(gv.rotateImages){ rotateImageBasedOnExif(image); } switch(gv.currentDE){ case Gnome: case UnityGnome: gsettingsSet("org.gnome.desktop.background", "picture-uri", "file://"+image); break; case Mate: gsettingsSet("org.mate.background", "picture-filename", image); break; case LXDE: QProcess::startDetached("pcmanfm", QStringList() << "-w" << image); break; case XFCE: Q_FOREACH(QString entry, getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("image-path") || entry.contains("last-image")){ QProcess::startDetached("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry << "-s" << image); } } break; default: QMessageBox::warning(0, tr("Error"), tr("Failed to change wallpaper. If your Desktop Environment is not listed at \"Preferences->Integration-> Current Desktop Environment\", then it is not supported.")); result=false; break; } #else #ifdef UNICODE result = (bool) SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, (PVOID) image.toLocal8Bit().data(), SPIF_UPDATEINIFILE); #else result = (bool) SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (PVOID) image.toLocal8Bit().data(), SPIF_UPDATEINIFILE); #endif //#ifdef UNICODE if(!result){ QMessageBox::warning(0, tr("Error"), tr("Failed to change wallpaper. Maybe your Windows version is not supported? Usually Windows XP fails to change JPEG images.")); } #endif //#ifdef ON_LINUX if(result && feature!=0){ if(gv.setAverageColor && changeAverageColor){ Global::setAverageColor(image); } if(gv.showNotification && showNotification){ Global(false).desktopNotify(tr("Current wallpaper has been changed!"), true, image); } if(gv.saveHistory){ Global::saveHistory(image, feature); } settings->setValue("images_changed", settings->value("images_changed", 0).toUInt()+1); gv.wallpapersChangedCurrentSession++; } } #ifdef ON_LINUX QString Global::getPrimaryColor(){ QString primaryColor; if(gv.currentDE==UnityGnome || gv.currentDE==Gnome){ primaryColor = Global::gsettingsGet("org.gnome.desktop.background", "primary-color"); } else if(gv.currentDE==Mate){ primaryColor = Global::gsettingsGet("org.mate.background", "primary-color"); } else if(gv.currentDE==XFCE){ Q_FOREACH(QString entry, Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("color1")){ QStringList colors=Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry).split("\n"); QList rgbColors; Q_FOREACH(QString color, colors){ bool ok=false; int currentColor=color.toInt(&ok); if(!ok){ continue; } rgbColors.append(int((256.0*currentColor)/65535.0)); } if(rgbColors.count()!=4){ continue; } QColor finalColor; finalColor.setRgb(rgbColors.at(0), rgbColors.at(1), rgbColors.at(2)); primaryColor = finalColor.name(); break; } } } else if(gv.currentDE==LXDE){ primaryColor=getPcManFmValue("desktop_bg"); } return primaryColor; } QString Global::getSecondaryColor(){ QString secondaryColor; if(gv.currentDE==UnityGnome || gv.currentDE==Gnome){ secondaryColor=Global::gsettingsGet("org.gnome.desktop.background", "secondary-color"); } else if(gv.currentDE==Mate){ secondaryColor=Global::gsettingsGet("org.mate.background", "secondary-color"); } else if(gv.currentDE==XFCE){ Q_FOREACH(QString entry, Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("color2")){ QStringList colors=Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry).split("\n"); QList rgbColors; Q_FOREACH(QString color, colors){ bool ok=false; int currentColor=color.toInt(&ok); if(!ok){ continue; } rgbColors.append(int((256.0*currentColor)/65535.0)); } if(rgbColors.count()!=4){ continue; } QColor finalColor; finalColor.setRgb(rgbColors.at(0), rgbColors.at(1), rgbColors.at(2)); secondaryColor = finalColor.name(); break; } } } return secondaryColor; } void Global::setPrimaryColor(const QString &colorName){ if(gv.currentDE==UnityGnome || gv.currentDE==Gnome){ Global::gsettingsSet("org.gnome.desktop.background", "primary-color", colorName); } else if(gv.currentDE==Mate) { Global::gsettingsSet("org.mate.background", "primary-color", colorName); } else if(gv.currentDE==XFCE){ QStringList colorValues; QColor color=QColor(colorName); colorValues.append(QString::number(int((65535.0/256.0)*color.red()))); colorValues.append(QString::number(int((65535.0/256.0)*color.green()))); colorValues.append(QString::number(int((65535.0/256.0)*color.blue()))); colorValues.append("65535"); Q_FOREACH(QString entry, getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("color1")){ QProcess::startDetached("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry << "-t" << "uint" << "-s" << colorValues.at(0) << "-t" << "uint" << "-s" << colorValues.at(1) << "-t" << "uint" << "-s" << colorValues.at(2) << "-t" << "uint" << "-s" << colorValues.at(3)); } } } else if(gv.currentDE==LXDE){ setPcManFmValue("desktop_bg", colorName); QStringList pids=getOutputOfCommand("pidof", QStringList() << "pcmanfm").replace("\n", "").split(" "); Q_FOREACH(QString pid, pids){ QString output=getOutputOfCommand("ps", QStringList() << "-fp" << pid); if(output.contains("--desktop")){ QProcess::startDetached("kill", QStringList() << "-9" << pid); } } if(QDir(gv.homePath+"/.config/pcmanfm/lubuntu").exists()){ QProcess::startDetached("pcmanfm", QStringList() << "--desktop" << "-p" << "lubuntu"); } else { QProcess::startDetached("pcmanfm", QStringList() << "--desktop"); } } } void Global::setSecondaryColor(const QString &colorName){ if(gv.currentDE==UnityGnome || gv.currentDE==Gnome){ Global::gsettingsSet("org.gnome.desktop.background", "secondary-color", colorName); } else if(gv.currentDE==Mate){ Global::gsettingsSet("org.mate.background", "secondary-color", colorName); } else if(gv.currentDE==XFCE){ QStringList colorValues; QColor color=QColor(colorName); colorValues.append(QString::number(int((65535.0/256.0)*color.red()))); colorValues.append(QString::number(int((65535.0/256.0)*color.green()))); colorValues.append(QString::number(int((65535.0/256.0)*color.blue()))); colorValues.append("65535"); Q_FOREACH(QString entry, getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("color2")){ QProcess::startDetached("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry << "-t" << "uint" << "-s" << colorValues.at(0) << "-t" << "uint" << "-s" << colorValues.at(1) << "-t" << "uint" << "-s" << colorValues.at(2) << "-t" << "uint" << "-s" << colorValues.at(3)); } } } } ColoringType Global::getColoringType(){ ColoringType coloringType=SolidColor; if(gv.currentDE==Gnome || gv.currentDE==UnityGnome){ QString colorStyle=Global::gsettingsGet("org.gnome.desktop.background", "color-shading-type"); if(colorStyle.contains("solid")){ coloringType=SolidColor; } else if(colorStyle.contains("vertical")){ coloringType=VerticalColor; } else if(colorStyle.contains("horizontal")){ coloringType=HorizontalColor; } } else if(gv.currentDE==Mate){ QString colorStyle=Global::gsettingsGet("org.mate.background", "color-shading-type"); if(colorStyle.contains("solid")){ coloringType=SolidColor; } else if(colorStyle.contains("vertical")){ coloringType=VerticalColor; } else if(colorStyle.contains("horizontal")){ coloringType=HorizontalColor; } } else if(gv.currentDE==XFCE){ Q_FOREACH(QString entry, Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("color-style")){ QString colorStyle=Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry).replace("\n", ""); if(colorStyle=="0"){ coloringType=SolidColor; } else if(colorStyle=="1"){ coloringType=HorizontalColor; } else if(colorStyle=="2"){ coloringType=VerticalColor; } else if(colorStyle=="3"){ coloringType=NoneColor; } } } } else if(gv.currentDE==LXDE){ coloringType=SolidColor; } return coloringType; } QString Global::searchForFileInDir(QString folder, QString file){ if(!QDir(folder).exists()){ return QString(); } Q_FOREACH(QString path, Global::listFolders(folder, true, true)){ if(QDir(path, QString(), QDir::Name, QDir::Files).entryList().contains(file)){ return path+'/'+file; } } return QString(); } QString Global::getPcManFmValue(const QString &key){ QString result; if(QDir(gv.homePath+"/.config/pcmanfm/lubuntu").exists()){ QSettings settings("pcmanfm", "lubuntu/pcmanfm"); settings.beginGroup("desktop"); result=settings.value(key, "").toString(); settings.endGroup(); } else { QSettings settings("pcmanfm", "default/pcmanfm"); settings.beginGroup("desktop"); result=settings.value(key, "").toString(); settings.endGroup(); } return result; } void Global::setPcManFmValue(const QString &key, const QString &value){ if(QDir(gv.homePath+"/.config/pcmanfm/lubuntu").exists()){ QSettings settings("pcmanfm", "lubuntu/pcmanfm"); settings.beginGroup("desktop"); settings.setValue(key, value); settings.endGroup(); settings.sync(); } else { QSettings settings("pcmanfm", "default/pcmanfm"); settings.beginGroup("desktop"); settings.setValue(key, value); settings.endGroup(); settings.sync(); } } void Global::rotateImageBasedOnExif(const QString &image) { //getExifRotation() will return 0 if it has no data, in other case it will return 1-8; short currentExifRotation = getExifRotation(image); if(currentExifRotation > 1){ Global::rotateImg(image, currentExifRotation, true); //if currentExifRotation==1, then the rotation is normal } } short Global::getExifRotation(const QString &filename){ ExifData *data = exif_data_new_from_file(filename.toLocal8Bit().data()); ExifByteOrder byte_order = exif_data_get_byte_order(data); ExifEntry *entry; short return_value=0; if(data){ if ((entry = exif_content_get_entry( data->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION))){ return_value = (short) exif_get_short(entry->data, byte_order); } exif_data_unref(data); //no need to exif_entry_unref(entry), there is no memory leak here. } return return_value; } #endif //#ifdef ON_LINUX QString Global::setAverageColor(const QString &image){ //sets the desktop's average color and returns the name of it. QString averageColor = QColor::fromRgb(QImage(image).scaled(1, 1, Qt::IgnoreAspectRatio, Qt::FastTransformation).pixel(0, 0)).name(); #ifdef ON_LINUX Global::setPrimaryColor(averageColor); #endif //#ifdef ON_LINUX return averageColor; } void Global::saveHistory(const QString &image, short feature){ QDateTime dateNow = QDateTime::currentDateTime(); QSettings history_settings(HISTORY_SETTINGS); history_settings.beginGroup(QString::number(dateNow.date().year())); history_settings.beginGroup(QString::number(dateNow.date().month())); int size = history_settings.beginReadArray(dateNow.toString("dd")); history_settings.endArray(); history_settings.beginWriteArray(dateNow.toString("dd")); history_settings.setArrayIndex(size); history_settings.setValue("time", dateNow.toString("hh:mm")); if(feature==1){ history_settings.setValue("path", image); } else if(feature==2 || feature==3 || feature==5){ history_settings.setValue("path", gv.onlineLinkForHistory); } else if(feature==4){ history_settings.setValue("path", ""); } history_settings.setValue("type", feature); history_settings.endArray(); history_settings.endGroup(); history_settings.endGroup(); } void Global::desktopNotify(const QString text, bool checkImage, const QString &image){ if(checkImage && !QFile::exists(image)) { Global::error("Could not display notification"); return; } #ifdef ON_WIN32 if(notification_==NULL) { notification_ = new Notification(text, image, 0); notification_->setAttribute(Qt::WA_DeleteOnClose); connect(notification_, SIGNAL(destroyed()), this, SLOT(notificationDestroyed())); connect(this, SIGNAL(updateNotification(QString,QString)), notification_, SLOT(setupNotification(QString,QString))); notification_->show(); } else { Q_EMIT updateNotification(text, image); } #elif ON_LINUX static NotifyNotification* notification=NULL; if (!notify_init ("update-notifications")){ Global::error("Could not display notification"); return; } gboolean successfullyCreated; GError* error = NULL; if(notification==NULL){ notification = notify_notification_new ( "Wallch", text.toLocal8Bit().data(), image.toLocal8Bit().data()); error = NULL; successfullyCreated = notify_notification_show (notification, &error); if (!successfullyCreated) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } } else { notify_notification_update (notification, "Wallch", text.toLocal8Bit().data(), image.toLocal8Bit().data()); error = NULL; successfullyCreated = notify_notification_show (notification, &error); if (!successfullyCreated) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } } #endif //#ifdef ON_LINUX } #ifdef ON_WIN32 void Global::notificationDestroyed(){ notification_=NULL; } #endif void Global::rotateImg(const QString &filename, short rotation_type, bool show_messagebox){ /* * A function for rotating the image 'filename' based on its 'rotation_type' * Rotation_type is corresponding to the exif values of the image. */ QString ext=filename.right(3); if(ext == "gif" || ext == "GIF"){ if(show_messagebox){ Global::error("Rotation is not supported for GIF files!"); } else { QMessageBox::warning(0, tr("Error!"), tr("Rotation is not supported for GIF files!")); } return; } QString extension; if(ext=="jpg" || ext=="JPG" || ext=="peg" || ext=="PEG"){ extension="JPG"; } else if(ext=="png" || ext=="PNG"){ extension="PNG"; } else if(ext=="bmp" || ext=="BMP"){ extension="BMP"; } /* * 'switching', based on the Exif data "orientation" * 1 2 3 4 5 6 7 8 * * 888888 888888 88 88 8888888888 88 88 8888888888 * 88 88 88 88 88 88 88 88 88 88 88 88 * 8888 8888 8888 8888 88 8888888888 8888888888 88 * 88 88 88 88 * 88 88 888888 888888 * */ switch (rotation_type){ case 2: QImage(filename).mirrored(true, false).save(filename, extension.toLocal8Bit().data(), 100); break; case 3: QImage(filename).mirrored(true, true).save(filename, extension.toLocal8Bit().data(), 100); break; case 4: QImage(filename).mirrored(false, true).save(filename, extension.toLocal8Bit().data(), 100); break; case 5: QImage(filename).transformed(QTransform().rotate(90), Qt::SmoothTransformation).mirrored(true, false).save(filename, extension.toLocal8Bit().data(), 100); break; case 6: QImage(filename).transformed(QTransform().rotate(90), Qt::SmoothTransformation).save(filename, extension.toLocal8Bit().data(), 100); break; case 7: QImage(filename).transformed(QTransform().rotate(-90), Qt::SmoothTransformation).mirrored(true, false).save(filename, extension.toLocal8Bit().data(), 100); break; case 8: QImage(filename).transformed(QTransform().rotate(-90), Qt::SmoothTransformation).save(filename, extension.toLocal8Bit().data(), 100); break; } } QStringList Global::listFolders(const QString &parentFolder, bool recursively, bool includeParent){ QStringList all_dirs; if(recursively){ if(includeParent){ all_dirs << parentFolder; } QDirIterator directories(parentFolder, QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); while(directories.hasNext()){ directories.next(); all_dirs << directories.filePath(); } return all_dirs; } else { //returns only the top level directories QDirIterator directories(parentFolder, QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot); while(directories.hasNext()){ directories.next(); all_dirs << directories.filePath(); } return all_dirs; } } QString Global::currentBackgroundImage(){ //returns the image currently set as desktop background QString currentImage; #ifdef ON_LINUX if(gv.currentDE==UnityGnome || gv.currentDE==Gnome){ currentImage=gsettingsGet("org.gnome.desktop.background", "picture-uri"); if(currentImage.startsWith("file://")){ currentImage=currentImage.right(currentImage.count()-7); } } else if(gv.currentDE==Mate){ currentImage=gsettingsGet("org.mate.background", "picture-filename"); } else if(gv.currentDE==XFCE){ Q_FOREACH(QString entry, Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("image-path") || entry.contains("last-image")){ currentImage=Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry).replace("\n", ""); } } } else if(gv.currentDE==LXDE){ currentImage=Global::getPcManFmValue("wallpaper"); } #else char *current_image = (char*) malloc(MAX_PATH*sizeof(char)); if(current_image==NULL){ return QString(""); } #ifdef UNICODE bool result = (bool) SystemParametersInfoA(SPI_GETDESKWALLPAPER, MAX_PATH, (PVOID) current_image, 0); #else bool result = (bool) SystemParametersInfoW(SPI_GETDESKWALLPAPER, MAX_PATH, (PVOID) current_image, 0); #endif //#ifdef UNICODE if(result){ currentImage = QString(current_image); } free(current_image); #endif //#ifdef ON_LINUX return currentImage; } void Global::openFolderOf(QString image /* = "" */){ /* * Function for opening an image's path. * If 'img' is empty then the current image's (set as background) * path open, but, if img has been specified, * then the specified image's path opens. * To open the background wallpaper's path works * only in GNOME 3. * If nautilus is installed and running then the * image is being selected as well. */ if(image.isEmpty()){ image=Global::currentBackgroundImage(); } if(image==gv.wallchHomePath+NULL_IMAGE){ QMessageBox::information(0, tr("Hey!"), tr("You just won the game.")); } #ifdef ON_WIN32 QProcess::startDetached("explorer", QStringList() << "/select," << QDir::toNativeSeparators(image)); #else if(QFile::exists("/usr/bin/nautilus")){ //opening the current path and selecting the image with nautilus QProcess::startDetached("nautilus", QStringList() << image); } else { //opening the current path with the default files viewer. Global::openUrl("file://"+dirnameOf(image)); } #endif //#ifdef ON_WIN32 } bool Global::connectedToInternet() { internetChecked_=false; disconnectFileDownloader(); connect(fileDownloader_, SIGNAL(finished(QNetworkReply*)), this, SLOT(internetConnectionReplyFinished(QNetworkReply*))); fileDownloader_->get(QNetworkRequest(QUrl("http://google.com"))); while(!internetChecked_){ qApp->processEvents(); } return connectedToInternet_; } void Global::internetConnectionReplyFinished(QNetworkReply *reply) { connectedToInternet_=(reply->error() == QNetworkReply::NoError); internetChecked_=true; reply->deleteLater(); } void Global::readClockIni(const QString &path) { //Reading clock.ini of wallpaper clock to get useful info from there. QFile file(path+"/clock.ini"); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ Global::error("Could not open the clock.ini file ("+path+"/clock.ini) for reading successfully!"); return; } QTextStream in(&file); while(!in.atEnd()) { QString line=in.readLine(); if(line.startsWith("refreshhourinterval=")) { gv.refreshhourinterval=QString(line.right(line.count()-20)).toInt(); } else if(line.startsWith("ampmenabled=")) { gv.amPmEnabled=QString(line.right(line.count()-12)).toInt(); } else if(line.startsWith("ampmenabled=")) { gv.wallpaperClocksHourImages=QString(line.right(line.count()-11)).toInt(); } } file.close(); } QString Global::wallpaperClockNow(const QString &path, bool minuteCheck, bool hourCheck, bool amPmCheck, bool dayWeekCheck, bool dayMonthCheck, bool monthCheck) { //returns where the saved wallpaper clock went //getting system date and time QDate date = QDate::currentDate(); QTime time = QTime::currentTime(); //knowing the current hour, we know if it am or pm //12h format is needed for the analog clocks short hour_12h_format=0; QString am_or_pm; if (time.hour()>=12){ am_or_pm="pm"; } else { am_or_pm="am"; } if(gv.wallpaperClocksHourImages==24 || time.hour()<12 ){ hour_12h_format=time.hour(); } else if(gv.wallpaperClocksHourImages!=24 && time.hour()>=12){ hour_12h_format=time.hour()-12; } //create the image that will be used as desktop background QPixmap merge(path+"/bg.jpg"); QPainter painter(&merge); if(monthCheck){ painter.drawPixmap(0,0, QPixmap(path+"/month"+QString::number(date.month())+".png")); } if(dayWeekCheck){ painter.drawPixmap(0,0, QPixmap(path+"/weekday"+QString::number(date.dayOfWeek())+".png")); } if(dayMonthCheck){ painter.drawPixmap(0,0, QPixmap(path+"/day"+QString::number(date.day())+".png")); } if(hourCheck){ painter.drawPixmap(0,0, QPixmap(path+"/hour"+QString::number(hour_12h_format*(60/gv.refreshhourinterval)+QString::number(time.minute()/gv.refreshhourinterval).toInt())+".png")); } if(minuteCheck){ painter.drawPixmap(0,0, QPixmap(path+"/minute"+QString::number(time.minute())+".png")); } if(gv.amPmEnabled && amPmCheck){ painter.drawPixmap(0,0, QPixmap(path+"/"+am_or_pm+".png")); } painter.end(); Global::remove(gv.wallchHomePath+WC_IMAGE+"*"); QString currentWallpaperClock=gv.wallchHomePath+WC_IMAGE+QString::number(QDateTime::currentMSecsSinceEpoch())+".jpg"; merge.save(currentWallpaperClock); Global::setBackground(currentWallpaperClock, true, false, 4); if(gv.showNotification) { if(settings->value("clocks_notification", true).toBool()){ if(QTime::currentTime().minute()==0) Global(false).desktopNotify(tr("Current wallpaper has been changed!")+"\n"+tr("Time is")+": "+QTime::currentTime().toString("hh:mm"), true, currentWallpaperClock); } else{ Global(false).desktopNotify(tr("Current wallpaper has been changed!")+"\n"+tr("Time is")+": "+QTime::currentTime().toString("hh:mm"), true, currentWallpaperClock); } } return currentWallpaperClock; } QString Global::basenameOf(const QString &path){ /* * Returns the fullname of the file that 'path' points to. E.g.: * path='/home/alex/a.txt' -> basenameOf(path)=='a.txt' * This can be done with the QFileInfo as well, but it is too time&resource consuming */ short pathCount=path.count(); for(short i=pathCount-1; i>=0; i--){ if(path.at(i)=='/' || path.at(i)=='\\' ){ if(i==(pathCount-1)){ continue; //it was a directory } return path.right(pathCount-i-1); } } return QString(""); //it means that '/' or '\' does not exist } QString Global::dirnameOf(const QString &path){ //returns the absolute folder path of the file return path.left(path.count()-(basenameOf(path).count()+1));//the +1 so as to remove the trailing '/' } int Global::websiteSliderValueToSeconds(short value) { switch (value) { case 1: return 120; break; case 2: return 180; break; case 3: return 300; break; case 4: return 600; break; case 5: return 900; break; case 6: return 1200; break; case 7: return 1800; break; case 8: return 2700; break; case 9: return 3600; break; case 10: return 7200; break; case 11: return 10800; break; case 12: return 14400; break; case 13: return 21600; break; case 14: return 43200; break; case 15: return 86400; break; case 16: return 604800; break; default: return DEFAULT_SLIDER_DELAY; break; } } void Global::generateRandomImages(int imagesNumber, int firstOne){ /* * Generates and shuffles the list gv.randomImages. * This way there wouldn't be any occurrence of the * same image while on random mode. */ //initializing... gv.randomImages.clear(); gv.currentRandomImageIndex=0; for(int i=0;i=imagesNumber){ //all images are random, but never set the same image as background. for(int i = 0; i < imagesNumber; i++) { random = rand() % imagesNumber; temp = gv.randomImages[i]; gv.randomImages[i] = gv.randomImages[random]; gv.randomImages[random] = temp; } } else { //explicitly specify the first image temp=gv.randomImages[0]; gv.randomImages[0] = firstOne; gv.randomImages[firstOne]=temp; for(int i = 1; i < imagesNumber; i++) { random = (rand() % (imagesNumber-1))+1; temp = gv.randomImages[i]; gv.randomImages[i] = gv.randomImages[random]; gv.randomImages[random] = temp; } } } void Global::generateRandomImage(const QStringList &images){ /* * This function is being used at the --change * argument. The generate_gv.randomImages function * could be used but it is more time and resource * consuming than it should be. In this case we * just want to randomly change the wallpaper, not * to suffle a list o images_n numbers so as to pick * a random one each time! Also, this function ensures * that the set image isn't already the current background. */ int images_n = images.count(); int index=-1; // the index of the 'images' that will be set as desktop background. if(images_n==1){ index=0; } else { srand(time(0)); QString currentImage=Global::currentBackgroundImage(); do { index=rand()%images_n; } while(images.at(index)==currentImage); } gv.currentRandomImageIndex=0; gv.randomImages << index; } QString Global::timeNowToString(){ return QTime::currentTime().toString("HH:mm"); } bool Global::remove(const QString &files){ /* * Removes one or multiple files (multiple files with * matching). * For removing entire folder, use removeDir() instead. */ if(files.contains("*")){ //more than one files to delete, use RegExp QString parent_dir = dirnameOf(files); if(parent_dir.isEmpty()){ return false; } QDir rmDir(parent_dir); if(!rmDir.exists()){ return false; } rmDir.setFilter(QDir::NoDotAndDotDot | QDir::Files); QRegExp rmValidation; rmValidation.setPatternSyntax(QRegExp::Wildcard); rmValidation.setPattern(basenameOf(files)); bool result=true; Q_FOREACH(QString currentFile, rmDir.entryList()){ if(rmValidation.indexIn(currentFile)!=-1){ //currentFile matches the validation if(!QFile::remove(parent_dir+"/"+currentFile)){ Global::error("Could not remove file '"+parent_dir+"/"+currentFile+"'. Skipping..."); result=false; } } } //result is false if at least one file wasn't deleted properly. return result; } else { return QFile::exists(files) && QFile::remove(files); } } QString Global::getFilename(const QString &file){ if(!file.contains('*')){ return QString(); } QString parentDirectory=dirnameOf(file); if(parentDirectory.isEmpty()){ return QString(); } QDir parentDir(parentDirectory); if(!parentDir.exists()){ return QString(); } parentDir.setFilter(QDir::NoDotAndDotDot | QDir::Files); QRegExp fileValidation; fileValidation.setPatternSyntax(QRegExp::Wildcard); fileValidation.setPattern(basenameOf(file)); Q_FOREACH(QString curFile, parentDir.entryList()){ if(fileValidation.indexIn(curFile)!=-1){ return parentDirectory+'/'+curFile; } } return QString(); } void Global::saveSecondsLeftNow(int secondsLeft, short forType){ /* * for_type: * 0 - Wallpapers * 1 - Live Earth * 2 - Live Website */ if(secondsLeft==-1){ settings->setValue("seconds_left_interval_independence", INTERVAL_INDEPENDENCE_DEFAULT_VALUE); } else { QChar front; switch(forType){ default: case 0: front='p'; break; case 1: front='e'; break; case 2: front='w'; break; } QDateTime currentTime = QDateTime::currentDateTime(); settings->setValue("seconds_left_interval_independence", QString(front)+"."+ QString::number(secondsLeft)+"."+ currentTime.date().toString("yyyy")+":"+ currentTime.date().toString("MM")+":"+ currentTime.date().toString("dd")+":"+ currentTime.time().toString("HH")+":"+ currentTime.time().toString("mm")+":"+ currentTime.time().toString("ss") ); } settings->sync(); } #ifdef ON_LINUX void Global::gsettingsSet(const QString &schema, const QString &key, const QString &value){ GSettings *settings = g_settings_new(schema.toLocal8Bit().data()); g_settings_set_string (settings, key.toLocal8Bit().data(), value.toLocal8Bit().data()); g_settings_sync (); if (settings != NULL){ g_object_unref (settings); } } QString Global::gsettingsGet(const QString &schema, const QString &key){ GSettings *settings = g_settings_new(schema.toLocal8Bit().data()); gchar *printed = g_settings_get_string (settings, key.toLocal8Bit().data()); QString finalSetting = QString(printed); g_free (printed); if (settings != NULL){ g_object_unref (settings); } return finalSetting; } #endif //#ifdef ON_LINUX QString Global::base64Decode(const QString &string){ return QByteArray::fromBase64(QByteArray().append(string)); } void Global::resetSleepProtection(int timeoutCount){ gv.runningTimeOfProcess = QDateTime::currentDateTime(); gv.timeToFinishProcessInterval = gv.runningTimeOfProcess.addSecs(timeoutCount); } void Global::addPreviousBackground(QStringList &previous_backgrounds, const QString &image){ previous_backgrounds << image; if(previous_backgrounds.count()>PREVIOUS_PICTURES_LIMIT){ previous_backgrounds.removeFirst(); } } void Global::error(const QString &message){ cerr << "Error: " << message.toLocal8Bit().data() << endl; } void Global::debug(const QString &message){ cout << message.toLocal8Bit().data() << endl; } QString Global::secondsToMinutesHoursDays(int seconds) { if(seconds%86400==0) { if(seconds/86400==1){ return QString(QString::number(1)+" "+tr("day")); } else{ return QString(QString::number(seconds/86400)+" "+tr("days")); } } else if(seconds%3600==0) { if(seconds/3600==1){ return QString(QString::number(seconds/3600)+" "+tr("hour")); } else{ return QString(QString::number(seconds/3600)+" "+tr("hours")); } } else if(seconds%60==0) { if(seconds/60==1){ return QString(QString::number(seconds/60)+" "+tr("minute")); } else{ return QString(QString::number(seconds/60)+" "+tr("minutes")); } } else if(seconds==1){ return QString(QString::number(1)+" "+tr("second")); } else { return QString(QString::number(seconds)+" "+tr("seconds")); } } bool Global::foldersAreSame(QString folder1, QString folder2){ if(!folder1.endsWith('/')){ folder1+='/'; } if(!folder2.endsWith('/')){ folder2+='/'; } return (folder1==folder2); } #ifdef ON_LINUX void Global::changeIndicatorIcon(const QString &icon) { if(icon=="normal") { if(gv.currentTheme=="ambiance"){ app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_AMBIANCE_NORMAL, INDICATOR_DESCRIPTION); } else { app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_RADIANCE_NORMAL, INDICATOR_DESCRIPTION); } } else if(icon=="right") { if(gv.currentTheme=="ambiance"){ app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_AMBIANCE_RIGHT, INDICATOR_DESCRIPTION); } else { app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_RADIANCE_RIGHT, INDICATOR_DESCRIPTION); } } else if(icon=="left"){ if(gv.currentTheme=="ambiance"){ app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_AMBIANCE_LEFT, INDICATOR_DESCRIPTION); } else { app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_RADIANCE_LEFT, INDICATOR_DESCRIPTION); } } else { gv.doNotToggleRadiobuttonFallback=false; } } void Global::changeIndicatorSelection(const QString &status){ if(status=="wallpapers"){ if(gv.wallpapersRunning){ gv.doNotToggleRadiobuttonFallback=true; if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (gv.wallpapersRadiobutton))){ gv.doNotToggleRadiobuttonFallback=false; } else { gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.wallpapersRadiobutton), TRUE); } showWallpapersIndicatorControls(true, true); } else { if(gv.processPaused){ showWallpapersIndicatorControls(true, false); } else { showWallpapersIndicatorControls(false, true); gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.iAmNotThere), TRUE); gv.doNotToggleRadiobuttonFallback=false; } } } else if(status=="pause"){ showWallpapersIndicatorControls(true, false); } else if(status=="earth"){ gv.doNotToggleRadiobuttonFallback=true; if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gv.liveEarthRadiobutton))){ gv.doNotToggleRadiobuttonFallback=false; } else { gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.liveEarthRadiobutton), TRUE); } } else if(status=="potd"){ gv.doNotToggleRadiobuttonFallback=true; if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gv.potdRadiobutton))){ gv.doNotToggleRadiobuttonFallback=false; } else { gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.potdRadiobutton), TRUE); } } else if(status=="clocks"){ gv.doNotToggleRadiobuttonFallback=true; if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gv.wallpaperClocksRadiobutton))){ gv.doNotToggleRadiobuttonFallback=false; } else { gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.wallpaperClocksRadiobutton), TRUE); } } else if(status=="website"){ gv.doNotToggleRadiobuttonFallback=true; if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gv.liveWebsiteRadiobutton))){ gv.doNotToggleRadiobuttonFallback=false; } else { gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.liveWebsiteRadiobutton), TRUE); } } else { showWallpapersIndicatorControls(false, true); gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.iAmNotThere), TRUE); gv.doNotToggleRadiobuttonFallback=false; } } void Global::showWallpapersIndicatorControls(bool show, bool pauseText){ if(show){ gtk_widget_hide(gv.wallpapersJustChange); gtk_widget_show(gv.wallpapersPlayPause); } else { gtk_widget_show(gv.wallpapersJustChange); gtk_widget_hide(gv.wallpapersPlayPause); gtk_widget_hide(gv.wallpapersNext); gtk_widget_hide(gv.wallpapersPrevious); } if(pauseText){ if(gtk_widget_get_visible(gv.wallpapersPlayPause)){ gtk_widget_show(gv.wallpapersNext); gtk_widget_show(gv.wallpapersPrevious); } gtk_menu_item_set_label((GtkMenuItem*) gv.wallpapersPlayPause, tr(" Pause").toLocal8Bit().data()); } else { gtk_widget_hide(gv.wallpapersNext); gtk_widget_hide(gv.wallpapersPrevious); gtk_menu_item_set_label((GtkMenuItem*) gv.wallpapersPlayPause, tr(" Start").toLocal8Bit().data()); } } #endif //#ifdef ON_LINUX int Global::getSecondsTillHour(const QString &hour){ int secsToPotd=QTime::currentTime().secsTo(QTime::fromString(hour, "hh:mm")); if(secsToPotd<0){ secsToPotd=86400-(secsToPotd*-1);//seconds in one day } else if(secsToPotd==0){ //this is the case where POTD time has come at the exact exact second of the minute change. POTD has come, so the progressbar has to be reset secsToPotd=86400; } return secsToPotd; } void Global::fixCacheSize(QString curWallpapersFolder){ CacheEntry currentCacheEntry=getCacheStatus(); if(currentCacheEntry.size<=MAX_IMAGE_CACHE*BYTES_PER_MiB){ return; } //step 1: Remove all cached images that refer to non-existent images and all cached images that refer to images that have changed (same filename, different image) for(int i=0;iprocessEvents(QEventLoop::AllEvents); } } if(currentCacheEntry.size<=MAX_IMAGE_CACHE*BYTES_PER_MiB){ gv.currentImageCacheSize=currentCacheEntry.size; return; } //step 2: Now all cached images are perfectly valid (pointing to existing images). Remove the images that are not under Wallpapers' current path int max_cache=MAX_IMAGE_CACHE*BYTES_PER_MiB; for(int i=0;imax_cache;i++){ QString cached_image = currentCacheEntry.images.at(i); QString original_image=cacheToOriginalName(cached_image); QString dir_name=Global::dirnameOf(original_image); if(!isSubfolder(dir_name, curWallpapersFolder)){ QFile::remove(gv.cachePath+cached_image); currentCacheEntry.size-=currentCacheEntry.imagesSizeList.at(i); currentCacheEntry.images.removeAt(i); currentCacheEntry.imagesSizeList.removeAt(i); currentCacheEntry.imageCount--; i--; } if(i%1000==0){ qApp->processEvents(QEventLoop::AllEvents); } } if(currentCacheEntry.size<=MAX_IMAGE_CACHE*BYTES_PER_MiB){ gv.currentImageCacheSize=currentCacheEntry.size; return; } //step 3: The only thing left is to delete the images that ARE into the default path. for(int i=currentCacheEntry.imageCount-1;i>=0 && currentCacheEntry.size>max_cache;i--){ QFile::remove(gv.cachePath+currentCacheEntry.images.at(i)); currentCacheEntry.size-=currentCacheEntry.imagesSizeList.at(i); currentCacheEntry.images.removeAt(i); currentCacheEntry.imagesSizeList.removeAt(i); if(i%1000==0){ qApp->processEvents(QEventLoop::AllEvents); } } gv.currentImageCacheSize=currentCacheEntry.size; } bool Global::isSubfolder(QString &subfolder, QString &parentFolder){ //Note that this function returns true even if subfolder==parent_folder if(!subfolder.endsWith('/')){ subfolder+='/'; } if(!parentFolder.endsWith('/')){ parentFolder+='/'; } return subfolder.startsWith(parentFolder); } QString Global::originalToCacheName(QString imagePath){ /* * How the cache works: * 1: All / are converted to ^ (or the cacheToChar) * 2: If ^ is already on the string, the indexes of it are saved at the start of the cached filename * 3: Lastly, the size of the original image is saved at the start of the cached image to prevent * having a different image with the same filename. */ #ifdef ON_WIN32 QString file_size=QString::number(QFile(imagePath).size()); imagePath.remove(1, 1); //removing the ":" from the filename if(imagePath.contains(cacheToChar)){ //imagePath already includes the cacheToChar, so save the index(es) of it QString final_string=imagePath; short currentIndex=0; while((currentIndex=imagePath.indexOf(cacheToChar, currentIndex+1))!=-1) final_string.insert(0, QString::number(currentIndex)+cacheAlreadyIncludedDelimiter); final_string.insert(0, file_size+cache_size_char); return final_string.replace(cacheFromChar, cacheToChar); } else { imagePath.insert(0, file_size+cache_size_char); return imagePath.replace(cacheFromChar, cacheToChar); } #else if(imagePath.contains(cacheToChar)){ //imagePath already includes the cacheToChar, so save the index(es) of it QString final_string=imagePath; short currentIndex=0; while((currentIndex=imagePath.indexOf(cacheToChar, currentIndex+1))!=-1) final_string.insert(0, QString::number(currentIndex)+cacheAlreadyIncludedDelimiter); final_string.insert(0, QString::number(QFile(imagePath).size())+cache_size_char); return final_string.replace(cacheFromChar, cacheToChar); } else { imagePath.insert(0, QString::number(QFile(imagePath).size())+cache_size_char); return imagePath.replace(cacheFromChar, cacheToChar); } #endif //#ifdef ON_WIN32 } QString Global::cacheExcludeSize(const QString &cacheName){ QChar mchar; short i=0, extrasCount=1, cacheNameCount=cacheName.count(); for(mchar=cacheName.at(i);mchar!=cache_size_char && i nums; short oc_count=sNums.count(); short length_to_omit=0, numsCount=0; for(short i=0;iprocessEvents(QEventLoop::AllEvents); } } entry.imageCount=counter; gv.currentImageCacheSize=entry.size=final_size; return entry; } bool Global::addToCacheSize(qint64 size){ gv.currentImageCacheSize+=size; return (gv.currentImageCacheSize>MAX_IMAGE_CACHE*BYTES_PER_MiB); } QString Global::getOutputOfCommand(QString command, QStringList parameters){ QProcess process; process.setProcessChannelMode(QProcess::MergedChannels); process.start(command, parameters,QIODevice::ReadWrite); if(!process.waitForStarted()) return QString(); QByteArray data; while(process.waitForReadyRead()){ data.append(process.readAll()); } return data.data(); } void Global::openUrl(const QString &url){ if(!QDesktopServices::openUrl(QUrl(url))){ Global::error("I probably could not open \""+url+"\""); } } void Global::updateStartup() { if(settings->value("Startup", true).toBool()){ #ifdef ON_WIN32 if(!QFile(settings->value("ProgramFilesPath", "C:\\Program Files (x86)\\Wallch\\wallch.exe").toString()).exists()) { static bool executableNotFoundMessageShown=false; if(!executableNotFoundMessageShown){ executableNotFoundMessageShown=true; QMessageBox::warning(0, tr("Error!"), QString("wallch.exe "+tr("could not be found. Start-up options cannot be enabled."))); } else { Global::error("wallch.exe could not be found. Start-up options cannot be enabled."); } return; } QSettings settings2("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat); if(gv.wallpapersRunning){ if(settings->value("Once", false).toBool()){ settings2.setValue("Wallch", "C:\\Program Files (x86)\\Wallch\\wallch.exe --change"); } else{ settings2.setValue("Wallch", "C:\\Program Files (x86)\\Wallch\\wallch.exe --start"); } } else if(gv.liveEarthRunning){ settings2.setValue("Wallch", "C:\\Program Files (x86)\\Wallch\\wallch.exe --earth"); } else if(gv.potdRunning){ settings2.setValue("Wallch", "C:\\Program Files (x86)\\Wallch\\wallch.exe --potd"); } else if(gv.liveWebsiteRunning){ settings2.setValue("Wallch", "C:\\Program Files (x86)\\Wallch\\wallch.exe --website"); } else if(gv.wallpaperClocksRunning){ settings2.setValue("Wallch", "C:\\Program Files (x86)\\Wallch\\wallch.exe --clock"); } else{ settings2.setValue("Wallch", "C:\\Program Files (x86)\\Wallch\\wallch.exe --none"); } settings2.sync(); #else if(!QDir(gv.homePath+AUTOSTART_DIR).exists()){ if(!QDir().mkpath(gv.homePath+AUTOSTART_DIR)){ Global::error("Failed to create ~"+QString(AUTOSTART_DIR)+" folder. Please check folder existence and permissions."); } } QString desktopFileCommand, desktopFileComment; if(gv.wallpapersRunning){ if(settings->value("Once", false).toBool()){ desktopFileCommand="/usr/bin/wallch --change"; desktopFileComment="Wallch will pick a random picture from the list and set it as background"; } else{ desktopFileCommand="/usr/bin/wallch --start"; desktopFileComment="Start Changing Desktop Background After a Certain Time"; } } else if(gv.liveEarthRunning){ desktopFileCommand="/usr/bin/wallch --earth"; desktopFileComment="Enable Live Earth"; } else if(gv.potdRunning){ desktopFileCommand="/usr/bin/wallch --potd"; desktopFileComment="Enable Picture Of The Day"; } else if(gv.liveWebsiteRunning){ desktopFileCommand="/usr/bin/wallch --website"; desktopFileComment="Enable Live Website"; } else if(gv.wallpaperClocksRunning){ desktopFileCommand="/usr/bin/wallch --clock"; desktopFileComment="Enable Wallpaper Clock"; } else{ desktopFileCommand="/usr/bin/wallch --none"; desktopFileComment="Just show indicator"; } #ifdef ON_LINUX short defaultValue=3; #else short defaultValue=0; #endif if(settings->value("startup_timeout", defaultValue).toInt()!=0){ desktopFileCommand="bash -c 'sleep "+QString::number(settings->value("startup_timeout", defaultValue).toInt())+" && "+desktopFileCommand+"'"; } Global::remove(gv.homePath+AUTOSTART_DIR+"/"+BOOT_DESKTOP_FILE); if(!createDesktopFile(gv.homePath+AUTOSTART_DIR+"/"+BOOT_DESKTOP_FILE, desktopFileCommand, desktopFileComment)){ Global::error("There was probably an error while trying to create the desktop file "+gv.homePath+AUTOSTART_DIR+"/"+BOOT_DESKTOP_FILE); } #endif //#ifdef ON_WIN32 } } bool Global::createDesktopFile(const QString &path, const QString &command, const QString &comment){ QFile desktopFile(path); if(!desktopFile.open(QIODevice::WriteOnly | QIODevice::Text)){ return false; } QTextStream out(&desktopFile); out << "\n[Desktop Entry]\nType=Application\nName=Wallch\nExec="+command+"\nTerminal=false\nIcon=wallch\nComment="+comment+"\nCategories=Utility;Application;\n"; desktopFile.close(); return true; } wallch-4.0/src/website_preview.h0000644000175000017500000000364112301477401015441 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef WEBSITE_PREVIEW_H #define WEBSITE_PREVIEW_H #define QT_NO_KEYWORDS #include #include #include "crop_image.h" #include "websitesnapshot.h" #include "glob.h" namespace Ui { class website_preview; } class WebsitePreview : public QDialog { Q_OBJECT public: explicit WebsitePreview(WebsiteSnapshot *websiteSnapshotP, bool show_crop_dialog, bool crop, QRect cropArea, QWidget *parent = 0); ~WebsitePreview(); private: Ui::website_preview *ui; CropImage *cropImageDialog_; WebsiteSnapshot *websiteSnapshot_; QTimer *countdownTimer_; bool forCropDialog_; QRect curCropArea_; short timeout_; void closeDialog(); void failWithMessage(const QString &further_info); void beginCropDialog(QImage *image); private Q_SLOTS: void on_cancel_or_close_clicked(); void sendCoordinates(const QRect &coords); void imageReady(QImage *image, short errorCode); void reduceTimeoutByOne(); Q_SIGNALS: void sendExtraCoordinates(QRect coords); void previewImageReady(QImage *image); }; #endif // WEBSITE_PREVIEW_H wallch-4.0/src/potd_preview.ui0000644000175000017500000001774512301477401015145 0ustar alexalex PotdPreview 0 0 721 647 Picture Of The Day Desciption Options Getting Picture Of The Day Preview 0 -1 0 0 157 101 false Qt::AlignCenter 10 Qt::Horizontal 40 20 15 Font to use: false Ubuntu 10 true 15 Description position: Qt::NoFocus Bottom Qt::NoFocus Top 15 Qt::NoFocus Text Color Qt::NoFocus Background Color Qt::Horizontal 10 true Margins Left: 200 100 Right: 200 Bottom: 200 Qt::Horizontal 40 20 Qt::Horizontal 40 20 Cancel OK wallch-4.0/src/notification.cpp0000644000175000017500000000473612301477401015265 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include "notification.h" #include "ui_notification.h" #include "glob.h" #include #include Notification::Notification(QString message, QString image, QWidget *parent) : QDialog(parent), ui(new Ui::Notification) { //actions in order for the dialog to look like a popup, to stay on top, and not to take focus Qt::WindowFlags flags = Qt::ToolTip | Qt::WindowStaysOnTopHint; //Qt::X11BypassWindowManagerHint; setWindowFlags(flags); setAttribute(Qt::WA_X11NetWmWindowTypeNotification, true); setAttribute(Qt::WA_ShowWithoutActivating, true); ui->setupUi(this); closeTimer_ = new QTimer(this); connect(closeTimer_, SIGNAL(timeout()), this, SLOT(closeNotification())); closeTimer_->setSingleShot(true); setupNotification(message, image); } Notification::~Notification() { delete ui; } void Notification::setupNotification(QString message, QString image) { if(closeTimer_->isActive()) closeTimer_->stop(); closeTimer_->start(3500); if(this->pos()!=QPoint(20, 20)){ this->move(20,20); } ui->message->setText(message); ui->image->setPixmap(QPixmap(image)); this->resize(this->minimumWidth(), this->minimumHeight()); } void Notification::closeNotification() { close(); } void Notification::enterEvent(QEvent *) { //if (mode_ == Mode_Popup) setWindowOpacity(0.25); } void Notification::leaveEvent(QEvent *) { setWindowOpacity(1.0); } void Notification::mousePressEvent(QMouseEvent* ) { //if (mode_ == Mode_Popup) close(); } wallch-4.0/src/mainwindow.ui0000644000175000017500000027533012301477401014606 0ustar alexalex MainWindow 0 0 898 549 Wallch :/icons/Pictures/wallch.png:/icons/Pictures/wallch.png 1 0 0 0 0 QWidget { background-image: url(:/icons/Pictures/toolbar-default.png); } 0 0 0 0 0 0 65 Ubuntu 10 50 false false Qt::NoFocus QPushButton:checked:!hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton:checked:hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton { color: white; background-image: url(:/icons/Pictures/ambiance_not_selected.png); font: 10pt "Ubuntu"; border: 0px; } Wallpapers :/icons/Pictures/wallch.png:/icons/Pictures/wallch.png 20 20 true true false true tabsButtonGroup 1 1 1 16777215 :/icons/Pictures/ambiance_separator.png 0 65 Ubuntu 10 50 false false Qt::NoFocus QPushButton:checked:!hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton:checked:hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton { color: white; background-image: url(:/icons/Pictures/ambiance_not_checked.png); font: 10pt "Ubuntu"; border: 0px; } Live Earth :/icons/Pictures/page_1_earth.png:/icons/Pictures/page_1_earth.png 20 20 true true tabsButtonGroup 1 0 1 16777215 :/icons/Pictures/ambiance_separator.png 145 65 Ubuntu 10 50 false false Qt::NoFocus QPushButton:checked:!hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton:checked:hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton { color: white; background-image: url(:/icons/Pictures/ambiance_not_checked.png); font: 10pt "Ubuntu"; border: 0px; } Picture Of The Day :/icons/Pictures/page_2_potd.png:/icons/Pictures/page_2_potd.png 20 20 true true tabsButtonGroup 1 0 1 16777215 :/icons/Pictures/ambiance_separator.png 0 0 140 65 Ubuntu 10 50 false false Qt::NoFocus QPushButton:checked:!hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton:checked:hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton { color: white; background-image: url(:/icons/Pictures/ambiance_not_checked.png); font: 10pt "Ubuntu"; border: 0px; } Wallpaper clocks :/icons/Pictures/page_3_clock.png:/icons/Pictures/page_3_clock.png 20 20 true true tabsButtonGroup 1 0 1 16777215 :/icons/Pictures/ambiance_separator.png 0 65 Ubuntu 10 50 false false Qt::NoFocus QPushButton:checked:!hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton:checked:hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton { color: white; background-image: url(:/icons/Pictures/ambiance_not_checked.png); font: 10pt "Ubuntu"; border: 0px; } Live Website :/icons/Pictures/page_4_website.png:/icons/Pictures/page_4_website.png 24 24 true true tabsButtonGroup 1 0 1 16777215 :/icons/Pictures/ambiance_separator.png 0 65 Qt::NoFocus QPushButton:checked:!hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton:checked:hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton { color: white; background-image: url(:/icons/Pictures/ambiance_not_checked.png); font: 10pt "Ubuntu"; border: 0px; } Other :/icons/Pictures/temp_Kozy_Logo.png:/icons/Pictures/temp_Kozy_Logo.png 20 20 true tabsButtonGroup 0 8 0 6 0 0 4 true 0 0 4 0 0 16777215 0 0 0 0 0 Pictures location: 0 0 Desktop Backgrounds My Pictures 0 0 Qt::NoFocus Add monitored folders Browse... 41 16 Qt::Horizontal 40 20 0 0 0 180 true Qt::WheelFocus Qt::CustomContextMenu QAbstractItemView::DragDrop Qt::IgnoreAction false QAbstractItemView::ExtendedSelection QAbstractItemView::ScrollPerItem QAbstractItemView::ScrollPerPixel QListView::Adjust QListView::IconMode false Interval: Qt::NoFocus 1 17 1 7 Qt::Horizontal 120 0 Qt::AlignCenter Qt::NoFocus Shuffle 0 31 75 true Qt::NoFocus Proceed to previous image &Previous 16 16 false false 0 31 75 true Qt::NoFocus Start/Pause the wallpaper changing module &Start 16 16 false false 0 31 75 true Qt::NoFocus Stop the wallpaper changing module St&op 16 16 false false 0 31 75 true Qt::NoFocus Proceed to next image &Next 16 16 false false true false Changes every ½ hour the desktop background to a flat map that shows the sunlight and the clouds. Internet connection is required. Qt::AlignCenter Qt::Horizontal 40 20 Qt::Vertical 20 40 210 61 75 true Activate Live Earth false 210 61 75 true Deactivate Live Earth Qt::Vertical 20 40 Qt::Horizontal 40 20 true Qt::AlignCenter Qt::AlignCenter false Qt::Vertical 20 40 Qt::Horizontal 40 20 0 61 75 true Activate Picture Of The Day false 0 61 75 true Deactivate Picture Of The Day Qt::Horizontal 40 20 Qt::Horizontal 40 20 Qt::NoFocus Include image description on the picture. true 15 100 0 Qt::StrongFocus Edit description settings Qt::Horizontal 40 20 Qt::Vertical 20 40 Qt::Horizontal 40 20 0 40 Picture of they day viewer Qt::Horizontal 40 20 50 false Qt::AlignCenter Qt::Horizontal 40 20 0 30 Qt::NoFocus You can also drag&drop a .wcz file to install a wallpaper clock Install 20 20 Qt::Horizontal 40 20 0 136 16777215 420 Qt::CustomContextMenu QAbstractItemView::SingleSelection QAbstractItemView::SelectRows false true false false true 88 88 false true false 67 67 Default Preview Name Qt::Horizontal 40 20 Qt::NoFocus January,February... Month true Qt::NoFocus 1-31 Day of month true Qt::NoFocus Monday,Tuesday... Day of week true Qt::NoFocus Am/Pm (If available) Am/Pm true Qt::NoFocus 1-24 Hour true Qt::NoFocus 1-60 Minutes true 6 150 61 75 true Activate Wallpaper Clock false 150 61 75 true Deactivate Wallpaper Clock Qt::Horizontal 40 20 0 0 Qt::Horizontal 10 20 true false Live Website is a feature that allows you to have a website as your desktop background. Qt::AlignCenter Qt::Vertical 20 40 208 0 75 true Website: http://google.com 208 0 75 true Interval: Qt::NoFocus 1 16 1 6 Qt::Horizontal 100 0 Qt::AlignCenter 75 true Qt::NoFocus Crop the image Crop Tool false true false 75 true Qt::NoFocus Add Login Details 0 0 16777215 0 75 true Username: Username 75 true Password: QLineEdit::Password Password Qt::NoFocus Redirect to a certain page 50 false Qt::Horizontal 40 20 0 40 151 16777215 50 false Qt::NoFocus Preview 0 61 75 true Qt::NoFocus Activate Live Website false 0 61 75 true Qt::NoFocus Deactivate Live Website Qt::Horizontal 40 20 Qt::Vertical 20 40 75 true Timeout till giving-up: Qt::AlignCenter 90 seconds... Qt::AlignCenter Qt::Horizontal 10 20 Qt::Vertical 20 40 false Qt::AlignCenter false Qt::AlignCenter Qt::Horizontal 40 20 160 160 160 160 :/icons/Pictures/mellori-logo.png true Qt::Horizontal 40 20 9 Wallch is a free application developed in our spare time. You can always ask for new features/bug fixes but we need a good motivation to deliver them fast. By making a donation you support the developers and the open source community in general. Qt::AlignCenter Qt::Horizontal 40 20 Qt::NoFocus :/icons/Pictures/btn_donate_LG.gif:/icons/Pictures/btn_donate_LG.gif 92 26 true Qt::Horizontal 40 20 Qt::Vertical 20 40 Qt::Vertical QLayout::SetDefaultConstraint 9 9 Qt::Vertical 20 40 Qt::Horizontal QSizePolicy::Ignored 1 1 311 281 311 281 0 7 311 271 311 271 311 271 :/icons/Pictures/monitor320x200.png true 13 20 285 172 0 0 true Qt::AlignCenter 10 207 291 20 0 0 true Qt::AlignCenter 270 208 31 21 13 20 285 172 0 0 true Qt::AlignCenter 13 20 285 172 0 0 true Qt::AlignCenter label screen_label_info process_request_label screen_label_transition screen_label screen_label_text Qt::Horizontal QSizePolicy::Ignored 1 1 50 0 65 31 65 31 13 Select the default background color 40 19 Qt::ClickFocus 50 0 Qt::Horizontal QSizePolicy::Ignored 40 13 Qt::Horizontal QSizePolicy::Ignored 40 13 Qt::Vertical 20 40 0 0 898 27 &File Current Image &Edit &Help &Preferences Preferences Ctrl+P true &About Quit Quit Ctrl+Q true Report A Bug Get Help Online How to use Wallch? Contents F1 Statistics &History History Ctrl+H true Donate Download 1000 HD Wallpapers true What is my screen resolution? Copy Name Copy Path Copy Image Delete Properties Open Folder redirect_checkBox clicked(bool) final_webpage setEnabled(bool) 189 309 194 316 wallch-4.0/src/about.ui0000644000175000017500000002771212301477401013543 0ustar alexalex about 0 0 389 294 About Wallch :/icons/Pictures/wallpaper.png:/icons/Pictures/wallpaper.png 0 9 Qt::Vertical 20 40 Qt::Horizontal 40 20 71 71 71 71 :/icons/Pictures/wallch.png true Qt::Horizontal 40 20 15 75 true Wallch 0.0 Qt::AlignCenter Wallch allows your desktop wallpaper to change automatically Qt::AlignCenter 8 Qt::AlignCenter melloristudio.com Qt::AlignCenter Qt::Vertical 20 40 0 Written by 0 0 0 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> true true Translated by 0 0 0 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> true true Wallch (Wallpaper Changer) 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. Wallch (Wallpaper Changer) 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 Wallch (Wallpaper Changer); if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA For further information you can also visit http://www.gnu.org/licenses/gpl.html 1 About true true false buttonGroup Credits true false buttonGroup Licence true false buttonGroup Qt::Horizontal 40 20 Close true false buttonGroup wallch-4.0/src/website_preview.ui0000644000175000017500000001133212301477401015623 0ustar alexalex website_preview 0 0 442 165 442 165 442 165 Preview Live Website with your preferences Qt::Horizontal 138 20 12 75 true Generating Image... Qt::Horizontal 138 20 Qt::Horizontal 138 20 Timeout till giving-up: 15 75 true Qt::Horizontal 138 20 Qt::Horizontal 40 20 Qt::Horizontal 40 20 0 -1 Qt::Horizontal 40 20 Cancel wallch-4.0/src/main.cpp0000644000175000017500000000200612301477401013507 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include "nongui.h" #include "glob.h" struct GlobalVar gv; nonGUI nongui; int main(int argc, char *argv[]) { return nongui.startProgram(argc, argv); } wallch-4.0/src/history.ui0000644000175000017500000000473512301477401014132 0ustar alexalex history 0 0 714 480 History 231 16777215 Qt::StrongFocus Qt::CustomContextMenu QFrame::StyledPanel QFrame::Sunken true 1 Qt::StrongFocus Qt::CustomContextMenu Qt::Horizontal 40 20 &Remove History &Close true wallch-4.0/src/potd_preview.h0000644000175000017500000000615512301477401014750 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef POTD_PREVIEW_H #define POTD_PREVIEW_H #include #include namespace Ui { class PotdPreview; } class PotdPreview : public QDialog { Q_OBJECT protected: void resizeEvent(QResizeEvent *event); public: explicit PotdPreview(QWidget *parent = 0); ~PotdPreview(); private: Ui::PotdPreview *ui; QPixmap currentPixmap_; QTimer *updatePreviewTimer_; QString originalTextColor_; QString originalBackgroundColor_; QString originalTextFont_; bool originalTop_; int originalLeftMargin_; int originalRightMargin_; int originalBottomTopMargin_; QString textColor_; QString backgroundColor_; const QString potdDescription_="The Laughing Kookaburra (Dacelo novaeguineae) is a carnivorous bird in the kingfisher family. Native to eastern Australia, it has also been introduced to parts of New Zealand, Tasmania and Western Australia. Male and female adults are similar in plumage, which is predominantly brown and white. A common and familiar bird, this species of kookaburra is well known for its laughing call. Photo: JJ Harrison"; const QStringList potdPreviewImages_ = QStringList() << "http://i.imgur.com/6rRVaA1.jpg" << "http://oi41.tinypic.com/r06paa.jpg" << "http://i.imgur.com/VLD6HRQ.jpg" << "http://melloristudio.com/wallch/potd_preview.jpg"; QNetworkAccessManager *fileDownloader_; QNetworkReply *currentNetworkRequest_=NULL; QImage *originalImage_=NULL; short currentBackupLinkIndex_=0; bool fetchFailed_=false; bool fetchFinished_=false; void fetchFinished(QImage *img); void getPotdPreviewImage(); void imageFetchfailed(); void writeDescription(); void updateLabel(); private Q_SLOTS: void downloadedImage(QNetworkReply *reply); void on_textColorPotd_clicked(); void on_backgroundColorPotd_clicked(); void on_potdFontComboBox_currentFontChanged(); void on_potd_description_bottom_radioButton_clicked(); void on_potd_description_top_radioButton_clicked(); void on_ok_clicked(); void on_cancel_clicked(); void on_left_margin_spinbox_valueChanged(); void on_right_margin_spinbox_valueChanged(); void on_bottom_top_margin_spinbox_valueChanged(); Q_SIGNALS: void potdPreferencesChanged(); }; #endif // POTD_PREVIEW_H wallch-4.0/src/statistics.ui0000644000175000017500000001260612301477401014617 0ustar alexalex statistics 0 0 299 288 Statistics 0 0 Program's uptime: 0 0 0 Wallpapers changed: 0 0 0 Launched times of program: 0 0 0 Program's uptime: 0 0 0 Wallpapers changed: 0 75 true Total: 75 true Current Session: Qt::Vertical 20 9 Qt::Horizontal 40 20 &Reset &OK true reset ok wallch-4.0/src/crop_image.ui0000644000175000017500000000326612301477401014534 0ustar alexalex crop_image 0 0 517 433 Select an area to crop 310 400 98 27 Cancel 410 400 98 27 &OK 20 20 481 341 true 0 0 479 339 220 400 66 17 wallch-4.0/src/mainwindow.h0000644000175000017500000003606112301477401014414 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #ifndef MAINWINDOW_H #define MAINWINDOW_H #define IMAGE_TRANSITION_SPEED 250 #define GENERAL_ANIMATION_SPEED 150 #define SCREEN_LABEL_SIZE_X 285 #define SCREEN_LABEL_SIZE_Y 172 #define WALLPAPERS_HELP "/usr/share/gnome/help/wallch/C/howto_wallpapers.page"; #define LIVEARTH_HELP "/usr/share/gnome/help/wallch/C/howto_livearth.page"; #define POTD_HELP "/usr/share/gnome/help/wallch/C/howto_potd.page"; #define WALLCLOCKS_HELP "/usr/share/gnome/help/wallch/C/howto_wallclocks.page"; #define LIVEWEBSITE_HELP "/usr/share/gnome/help/wallch/C/howto_livewebsite.page"; #define COLSANDGRADS_HELP "/usr/share/gnome/help/wallch/C/howto_colsandgrads.page"; #define CHECK_CACHE_SIZE_TIMEOUT 5000 #define WALLPAPERS_LIST_ICON_SIZE QSize(60, 60) #define WALLPAPERS_LIST_ITEMS_OFFSET QSize(4, 3) #define WALLPAPER_CLOCKS_LIST_ICON_SIZE QSize(100,75) #define WALLPAPER_CLOCKS_ITEM_ICON_SIZE QSize(82, 82) #include "about.h" #include "ui_mainwindow.h" #include "website_preview.h" #include "properties.h" #include "preferences.h" #include "history.h" #include "statistics.h" #include "glob.h" #include "colors_gradients.h" #include "potd_viewer.h" #include "websitesnapshot.h" #include "notification.h" #include "potd_preview.h" #include "websitesnapshot.h" #ifdef ON_LINUX #include #include #include #include #include #else #include #include #include #endif //#ifdef ON_LINUX #include #include #include #include #include #include #include #include #include #include #include #include #include typedef enum { NoneStyle, Center, Tile, Stretch, Scale, Zoom } DesktopStyle; namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(Global *globalParser, WebsiteSnapshot *websiteSnapshotP, int timeout_count, QStringList previous_pictures_from_main, int last_random_delay, int last_normal_picture, QWidget *parent = 0); ~MainWindow(); void click_shortcut_next(); Ui::MainWindow *ui; protected: void changeEvent(QEvent *e); void closeEvent(QCloseEvent * event); void resizeEvent(QResizeEvent *event); private: void actionsOnClose(); QTimer *updateSecondsTimer_; QTimer *wallpaperClockWait_; QTimer *updateCheckTime_; QTimer *iconUpdater_; QTimer *researchFoldersTimer_; QTimer *hideProgress_; #ifdef ON_LINUX QTimer *indicatorChangeNormalTimer_; #endif //#ifdef ON_LINUX QTimer *cacheSizeChecker_; QFutureWatcher futureWatcherWallClocksPreview_; QFutureWatcher futureWatcherWallpapersPreview_; QMenu *listwidgetMenu_; QMenu *clockwidgetMenu_; QFileSystemWatcher *watchFolders_; QButtonGroup *clocksRadioButtonsGroup; Statistics *statistics_; About *about_; Preferences *preferences_; Properties *properties_; ColorsGradients *colorsGradients_; PotdViewer *potdViewer_; History *history_; Notification *notification_; PotdPreview *potdPreview_; QTranslator *translator_; WebsitePreview *webPreview_; QRegExp *match_; QProgressBar *timeForNext_; QMovie *processingRequestGif_; QPropertyAnimation *openCloseSearch_; QPropertyAnimation *showTvMinimumHeight_; QPropertyAnimation *openCloseAddLogin_; QGraphicsOpacityEffect* opacityEffect_; QGraphicsOpacityEffect* opacityEffect2_; #ifdef ON_LINUX QProcess *unzipArchive_; #endif WebsiteSnapshot *websiteSnapshot_; QIcon imageLoading_; bool appAboutToClose_=false; bool currentlyUpdatingIcons_=false; bool processingOnlineRequest_; Global *globalParser_; qint64 secondsLeft_=0; int initialRandomSeconds_; int totalSeconds_=0; int secondsInWallpapersSlider_; double imagePreviewResizeFactorX_; double imagePreviewResizeFactorY_; int indexOfCurrentImage_; int currentSearchItemIndex; bool currentlyUninstallingWallpaperClock_=false; short timePassedForLiveWebsiteRequest_; short tempForDelayedPicturesLocationChange_; bool addDialogShown_=false; bool historyShown_=false; bool aboutShown_=false; bool propertiesShown_=false; bool statisticsShown_=false; bool websitePreviewShown_=false; bool colorsGradientsShown_=false; bool potdViewerShown_=false; bool potdPreviewShown_=false; bool actAsStart_; bool startWasJustClicked_=false; bool justUpdatedPotd_=false; bool searchIsOn_=false; bool wallpapersPageLoaded_=false; bool potdPageLoaded_=false; bool wallpaperClocksPageLoaded_=false; bool liveWebsitePageLoaded_=false; bool firstRandomImageIsntRandom_=false; bool shuffleWasChecked_=false; QString initialWebPage_; QString changedWebPage_; QString currentWallpaperClockPath_; QString nameOfSelectionPriorFolderChange_; QString currentFolder_; QStringList previousBackgrounds_; QStringList searchList_; QStringList customIntervals_; QStringList monitoredFoldersList_; #ifdef ON_WIN32 void unzip(QString input, const QString &outputDirectory); #else DesktopStyle getDesktopStyle(); ColoringType getColoringType(); QString getPrimaryColor(); QString getSecondaryColor(); #endif QString getPathOfListItem(int index=-1); void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); void changeImage(); void startButtonsSetEnabled(bool enabled); void stopButtonsSetEnabled(bool enabled); void previousAndNextButtonsSetEnabled(bool enabled); void startLivearth(); void stopLivearth(); void startPotd(bool launch_now); void monitor(const QString &path, int &itemCount); void monitor(const QStringList &paths); void setupKeyboardShortcuts(); void setupTimers(); void setupThemeFallbacks(); void connectSignalSlots(); void startUpdateSeconds(); void addFilesToWallpapers(const QString &path, int &itemCount); void searchFor(const QString &term); void continueToNextMatch(); void continueToPreviousMatch(); void animateProgressbarOpacity(bool show); void findSeconds(bool typeCountSeconds); void startPauseWallpaperChangingProcess(); void loadPotdPage(); void loadWallpaperClocksPage(); void loadLiveWebsitePage(); void setPreviewImage(QImage *image); void updatePicturesLocations(); void processRequestStart(); void processRequestStop(); void setThemeToAmbiance(); void setThemeToRadiance(); void doesMatch(); void doesntMatch(); void setProgressbarsValue(short value); void imageTransition(const QString &filename); void hideScreenLabel(); void changeTextOfScreenLabelTo(const QString &text); bool updateIconOf(int row); void closeEverythingThatsRunning(short excludingFeature); bool websiteConfiguredCorrectly(); void updatePotdProgress(); QImage *wallpaperClocksPreview(const QString &wallClockPath, bool minuteCheck, bool hourCheck, bool amPmCheck, bool dayWeekCheck, bool dayMonthCheck, bool monthCheck); QString secondsToMh(int seconds); QString secondsToHms(int seconds); QString secondsToHm(int seconds); QString fixBasenameSize(const QString &basename); void actionsOnWallpaperChange(); void resetWatchFolders(); void strongMinimize(); void processRunningResetPictures(bool fromRandomImagesToNormal); void forceUpdateIconOf(int index); void fixCacheSizeGlobalCallback(); void cacheSizeChanged(const QString &newCacheImage); void prepareWebsiteSnapshot(); QString base64Encode(const QString &string); static void nextKeySignal(const char *, void *); void loadWallpapersPage(); void disableLiveWebsitePage(); bool currentFolderExists(); void setupAnimationsAndChangeImage(QImage *image); QImage *scaleWallpapersPreview(QString filename); private Q_SLOTS: void closeWhatsRunning(); void addFolderForMonitor(const QString &folder); void installWallpaperClock(const QString ¤tPath); void random_time_changed(short index); void folderChanged(); void researchFolders(); void updateTiming(); void sendPropertiesNext(int current); void sendPropertiesPrevious(int current); void changePathsToIcons(); void changeIconsToPaths(); void launchTimerToUpdateIcons(); void updateVisibleIcons(); void removeImageFromDisk(); void removeImagesFromDisk(); void showProperties(); void openImageFolder(); void openImageFolderMassive(); void rotateRight(); void rotateLeft(); void copyImage(); void copyImagePath(); void clockCheckboxClickedWhileRunning(); void readCoordinates(const QRect &cropArea); void setStyle(); void setWebsitePreviewImage(QImage *image); void setButtonColor(); void setButtonColor(const QString &color_name); void enterPressed(); void openCloseAddLoginAnimationFinished(); void updateSeconds(); void liveWebsiteImageCreated(QImage *image, short errorCode); void addClockToList(); void changeCurrentThemeTo(const QString &theme); void showHideSearchBox(); void showHideSearchBoxMenu(); void escapePressed(); void deletePressed(); void previousPage(); void nextPage(); void refreshIntervals(); void openCloseSearchAnimationFinished(); void hideTimeForNext(); void tvPreview(bool show); void hideTv(); void wrongSizeOfWindow(); void startWithThisImage(); void setAverageColor(const QString &image); void updateScreenLabel(); void strongShowApp(); #ifdef ON_LINUX void bindKey(const QString &key); void unbindKey(const QString &key); void unityProgressbarSetEnabled(bool enabled); void indicatorSetNormal(); #endif //#ifdef ON_LINUX void preferencesDestroyed(); void statisticsDestroyed(); void historyDestroyed(); void aboutDestroyed(); void propertiesDestroyed(); void websitePreviewDestroyed(); void colorsGradientsDestroyed(); void potdViewerDestroyed(); void potdPreviewDestroyed(); void updateColorButton(QImage image); void fixCacheSizeThreaded(); void delayed_pictures_location_change(); void clockRadioButton_check_state_changed(); void restartPotdIfRunningAfterSettingChange(); void wallpaperClocksPreviewImageGenerationFinished(); void wallpapersPreviewImageGenerationFinished(); void justChangeWallpaper(); void onlineRequestFailed(); void onlineImageRequestReady(QString image); void on_actionHistory_triggered(); void on_actionStatistics_triggered(); void on_actionContents_triggered(); void on_previous_Button_clicked(); void on_next_Button_clicked(); void on_listWidget_customContextMenuRequested(); void on_listWidget_itemDoubleClicked(); void on_listWidget_itemSelectionChanged(); void on_timerSlider_valueChanged(int value); void on_install_clock_clicked(); void on_label_9_linkActivated(); void on_label_3_linkActivated(); void on_website_preview_clicked(); void on_edit_crop_clicked(); void on_website_crop_checkbox_clicked(bool checked); void on_set_desktop_color_clicked(); void on_image_style_combo_currentIndexChanged(int index); void on_website_textEdited(const QString &arg1); void on_page_5_other_clicked(); void on_browse_folders_clicked(); void on_website_slider_valueChanged(int value); void on_pictures_location_comboBox_currentIndexChanged(int index); void on_search_box_textChanged(const QString &arg1); void on_search_close_clicked(); void on_search_up_clicked(); void on_search_down_clicked(); void on_actionDonate_triggered(); void on_actionDownload_triggered(); void on_actionReport_A_Bug_triggered(); void on_actionGet_Help_Online_triggered(); void on_actionWhat_is_my_screen_resolution_triggered(); void on_actionCopy_Name_triggered(); void on_actionCopy_Path_triggered(); void on_actionCopy_Image_triggered(); void on_actionDelete_triggered(); void on_actionProperties_triggered(); void on_actionOpen_Folder_triggered(); void on_actionQuit_Ctrl_Q_triggered(); void on_potd_viewer_Button_clicked(); void on_add_login_details_clicked(bool checked); void on_action_About_triggered(); void on_action_Preferences_triggered(); void on_stopButton_clicked(); void on_startButton_clicked(); void on_activate_livearth_clicked(); void on_deactivate_livearth_clicked(); void on_activate_potd_clicked(); void on_deactivate_potd_clicked(); void on_activate_clock_clicked(); void on_deactivate_clock_clicked(); void on_activate_website_clicked(); void on_deactivate_website_clicked(); void on_page_0_wallpapers_clicked(); void on_page_1_earth_clicked(); void on_page_2_potd_clicked(); void on_page_3_clock_clicked(); void on_page_4_web_clicked(); void on_clocksTableWidget_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn); void on_include_description_checkBox_clicked(bool checked); void on_edit_potd_clicked(); void clockCheckboxClicked(); void on_clocksTableWidget_customContextMenuRequested(); void uninstall_clock(); void on_shuffle_images_checkbox_clicked(); void on_stackedWidget_currentChanged(int page); void update_website_settings(); void on_donateButton_clicked(); void on_melloristudio_link_label_linkActivated(const QString &link); Q_SIGNALS: void fixLivewebsiteButtons(); void noMatch(); void givePropertiesRequest(QString img, int current_index); void monitorCheck(); #ifdef ON_WIN32 void signalUncheckRunningFeatureOnTray(); void signalRecreateTray(); #endif }; class HideGrayLinesDelegate : public QStyledItemDelegate { public: HideGrayLinesDelegate(QObject *parent = NULL) : QStyledItemDelegate(parent){} void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; opt.state &= ~QStyle::State_HasFocus; QStyledItemDelegate::paint(painter, opt, index); } }; #endif // MAINWINDOW_H wallch-4.0/src/history.h0000644000175000017500000000375512301477401013745 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef HISTORY_H #define HISTORY_H #include "properties.h" #include #include namespace Ui { class history; } class History : public QDialog { Q_OBJECT public: explicit History(QWidget *parent = 0); ~History(); private: Ui::history *ui; QGroupBox *optionsGroupBox_; QGridLayout *optionsGroupBoxLayout_; QVBoxLayout *mainLayout_; QHBoxLayout *buttonsLayout_; QMenu *infoMenu_; QMenu *treeWidgetMenu_; Properties *historyProperties_; bool propertiesShown_; void readHistoryFiles(); void addHistoryEntry(QString time, QString path, short type); QString numberWithLeadingZero(QString number); private Q_SLOTS: void on_treeWidget_itemClicked(QTreeWidgetItem* item); void on_remove_history_clicked(); void on_closeButton_clicked(); void remove_history_entry(); void on_treeWidget_customContextMenuRequested(); void on_info_customContextMenuRequested(); void showprop(); void openfolder(); void copypath(); void copylink(); void launch_in_browser(); void on_info_doubleClicked(); void historyPropertiesDestroyed(); }; #endif // HISTORY_H wallch-4.0/src/statistics.cpp0000644000175000017500000000570712301477401014770 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include "statistics.h" #include "ui_statistics.h" #include "glob.h" #include "QDesktopWidget" #ifdef ON_WIN32 #include #endif #include Statistics::Statistics(QWidget *parent) : QDialog(parent), ui(new Ui::statistics) { ui->setupUi(this); //move dialog to center of the screen this->move(QApplication::desktop()->availableGeometry().center() - this->rect().center()); totalLaunchedTimes_=settings->value("times_launched", 0).toUInt(); totalUptime_=settings->value("seconds_passed", 0).toUInt(); updateValuesTimer_ = new QTimer(this); connect(updateValuesTimer_,SIGNAL(timeout()),this,SLOT(updateValues())); updateValues(); updateValuesTimer_->start(1000); } Statistics::~Statistics() { delete ui; } void Statistics::on_ok_clicked() { updateValuesTimer_->stop(); this->close(); } void Statistics::updateValues(){ unsigned int currentSessionSeconds=gv.timeLaunched.secsTo(QDateTime::currentDateTime()); ui->current_wallpapers_number->setText(QString::number(gv.wallpapersChangedCurrentSession)); ui->current_uptime_number->setText(secondsToDateSring(currentSessionSeconds)); ui->launchedtimes->setText(QString::number(totalLaunchedTimes_)); ui->images_n->setText(QString::number(settings->value("images_changed", 0).toUInt())); ui->uptime->setText(secondsToDateSring(totalUptime_+currentSessionSeconds)); } void Statistics::on_reset_clicked() { totalLaunchedTimes_=totalUptime_=0; gv.appStartTime=QDateTime::currentDateTime(); settings->setValue("seconds_passed", 0); settings->setValue("times_launched", 0); settings->setValue("images_changed", 0); settings->sync(); } QString Statistics::secondsToDateSring(unsigned int seconds) { unsigned int secs=0, minutes=0, hours=0, days=0; days=seconds/86400; hours=seconds/3600; minutes=seconds/60; secs=seconds; hours%=24; minutes%=60; secs%=60; return QString((days ? QString::number(days)+"d ":"") + (hours ? QString::number(hours)+"h ":"") + (minutes ? QString::number(minutes)+"m ":"") + QString::number(secs)+"s"); } wallch-4.0/src/potd_viewer.h0000644000175000017500000000447212301477401014570 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef POTD_VIEWER_H #define POTD_VIEWER_H #define QT_NO_KEYWORDS #include "glob.h" #include #include #include #include #include namespace Ui { class potd_viewer; } class PotdViewer : public QDialog { Q_OBJECT protected: void resizeEvent(QResizeEvent *); public: explicit PotdViewer(QWidget *parent = 0); ~PotdViewer(); private: Ui::potd_viewer *ui; QUrl url_; bool downloadingImage_=false; QNetworkAccessManager qnam_; QNetworkReply *reply_; QPixmap originalPixmap_; QMovie *originalMovie_=NULL; int httpGetId_; bool httpRequestAborted_; QDate selectedDate_; QString directLinkOfFullImage_; QString directLinkOfPreviewImage_; bool skipStepsAfterThree_; bool forceStop_; QString htmlSource_; QString formatOfImage_; void startRequest(QUrl url); void urlQDate(); void updateLabel(); void enableWidgets(bool state); private Q_SLOTS: void movieDestroyed(); void httpFinished(); void httpReadyRead(); void updateDataReadProgress(qint64 bytesRead, qint64 totalBytes); void updateDataReadProgress_save(qint64 bytesRead, qint64 totalBytes); void imageDownloaded(); void saveImage(); void on_quitButton_clicked(); void on_saveimageButton_clicked(); void on_dateEdit_dateChanged(const QDate &date_calendar); void on_previousButton_clicked(); void on_nextButton_clicked(); }; #endif // POTD_VIEWER_H wallch-4.0/src/websitesnapshot.h0000644000175000017500000004157312301477401015466 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef WEBSITESNAPSHOT_H #define WEBSITESNAPSHOT_H #define QT_NO_KEYWORDS #include #include #include #include #include #include "customwebpage.h" /*! * \brief A class for creating image snapshots of websites. * * The WebsiteSnapshot class gives you the ability to * create snapshots of web pages. It also supports * log-in, so as to take a snapshot of a page which needs * special access (cookies). * * WebsiteSnapshot creates a custom QWebPage object which * does not allow prompts created from javascript, for example. * * If no user authentication (log-in) is required, WebsiteSnapshot * loads the specified URL and then renders an image using the main * frame of the custom QWebPage. * * If user authentication is required, WebsiteSnapshot loads through * its custom QWebPage the log-in page, searches for and fills the * username and password fields and calls a QEvent equivalent to * pressing the Return key. This causes a log-in attempt to the website. * After the page has loaded, WebsiteSnapshot loads the final page * that needs to be snapshoted and takes the snapshot of it. If the final * page is equal to the log-in page, then WebsiteSnapshot will use the page * where it is redirected after the log-in, for taking the snapshot. */ class WebsiteSnapshot : public QObject { Q_OBJECT public: /*! * \brief Constructor. * * The constructor does not take arguments because the library is designed as a Qt Plugin. */ WebsiteSnapshot(); /*! * \brief Destructor. * * Destroys the website snapshot. */ ~WebsiteSnapshot(); /*! * \brief Starts the image creation process. * * This function should not be called again, until the resultedImage() * signal has been emitted. Please call @a setParameters() prior to calling this function. * * Returns true if the process has started successfully, otherwise it returns false. If the process * has started successfully (which means that there isn't an already running process and the requested url * is valid), then the @a resultedImage() signal will be emitted when the process has ended. If the process * has not started successfully, then no signal will be emitted. * * \return True if the process has started successfully, otherwise it returns false. * * \sa resultedImage(), setParameters(), setTimeout(), * setJavascriptConfig(), setJavaEnabled(), setLoadImagesEnabled(), setSimpleAuthentication(), * setComplexAuthentication(), setComplexAuthenticationWithPossibleFields(), * setComplexAuthenticationInitialWait(), setWaitAfterFinish() */ bool start(); /*! * \brief Stops the image creation process. * * It does nothing if there isn't any process running. Calling * this function will not call the resultedImage() signal, because it automatically means failure. * \sa start(), resultedImage() */ void stop(); /*! * \brief Sets the necessary parameters for the image creation. * * \param url The url of the page to be snapshotted. If authentication is required, then it should be the url pointing to the login page. * \param width The minimum width that the image should have. * \param height The minimum height that the image should have. * * The corresponding screen dimensions need to be passed as width and height, if a snapshot has to * be produced for a specific monitor. * * If authentication is required and you need to set a different URL for snapshot after the log-in, * then you have to specify here the url of the log-in page, not the page where the snapshot will be * taken. You can set a final URL in the functions where you set the log-in credentials. * * \sa setSimpleAuthentication(), setComplexAuthentication(), setComplexAuthenticationWithPossibleFields() */ void setParameters(QUrl url, const short &width, const short &height); /*! * \brief Crops the final image. * * \param rectCrop The rectangle of the image that will be cropped. * \param enabled If true, then cropping is enabled, if false, then it is disabled. * * Crops the resulted image using @a rectCrop as (x, y, width, height). */ void setCrop(bool enabled, const QRect &rectCrop); /*! * \brief Sets the total timeout. * * \param secondsTimeout The timeout to wait in seconds. * * Sets a timeout for the image creation process. If the timeout passes and the image has yet * to be created, then the @a resultedImage() signal is being emitted with a null QImage pointer and * the image creation process stops. * * By default, the timeout is set to 1 minute. * * \sa resultedImage(), start() */ void setTimeout(unsigned const int &secondsTimeout); /*! * \brief Sets the javascript configuration. * * \param enabled Controls if javascript is generally enabled. * \param canAccessClipboard Controls whether javascript has access to user clipboard. * * Please note that even if javascript is enabled, javascript pop-ups and confirmation * boxes are disabled and they will not be visible at the final image. * * By default, javascript is enabled, but it cannot access the clipboard. */ void setJavascriptConfig(bool enabled, bool canAccessClipboard); /*! * \brief Controls whether java is enabled or not. * * \param enabled If true, then java is enabled, otherwise it is disabled. * * By default, java is disabled. */ void setJavaEnabled(bool enabled); /*! * \brief Controls whether the images inside the webpages are enabled or not. * * \param enabled If true, then images are enabled, otherwise they are disabled. * * By default, they are enabled. */ void setLoadImagesEnabled(bool enabled); /*! * \brief Does a simple pop-up authentication. * * \param username The username to use for the authentication. * \param password The password to use for the authentication. * \param finalUrl The url to navigate to after the authentication is successful. * * After the page has loaded, a simple authentication will be attempted in order * to get to a final url and acquire the final image. If the @a finalUrl is the same * as the @a url specified at @a setParameters(), then the final image will be captured * at the url after the log-in redirection. * * Simple authentication includes authorisation pop-up. A common example * of such authentication is the authorization pop-up for accessing the * settings of most of the routers/modems. * * This function should not be used for all websites, because most of them require * complex authentication. * * \sa setParameters(), setComplexAuthentication() */ void setSimpleAuthentication(const QString &username, const QString &password, const QString &finalUrl); /*! * \brief Does a complex username-password fields authentication. * * \param username The username to use for the authentication. * \param password The password to use for the authentication. * \param finalUrl The url to navigate to after the authentication is successful. * * After the page is loaded, a complex authentication will be attempted in order * to get to a final url and acquire the final image. If the @a finalUrl is the same * as the @a url specified at @a setParameters(), then the final image will be captured * at the url after the log-in redirection. * * Complex authentication includes most of the websites that have common username-password * authentication. WebsiteSnapshot will scan the webpage for common username-password fields * and will fill them with the provided username and password, correspondingly. * * Note that complex authentication will fail in the following cases: * - The website does not use common username-password authentication. * - The log-in page does not use common input username-password ids. * * When searching the log-in page for the appropriate username-password input fields, WebsiteSnapshot * actually searches for the id attribute of tags. * * This is a list with the ids that WebsiteSnapshot uses (listed by the order that they are searched): * - For usernames: * "username", "user", "email", "Email", "User", "Username", "signin-email", "userid", "user-id", * "navbar_username", "login_email", "loginUsername", "id_nickname", "id_email", "session_key-login", * "ap_email", "signup_email". * * - For passwords: * "password", "pass", "passwd", "Password", "Pass", "Passwd", "signin-password", "navbar_password", * "login_password", "navbar_password_hint", "passid", "pass-id", "loginPassword", "id_password", * "pwd", "session_password-login", "ap_password", "signup_password". * * If you want to use specific ids, or if you want to enrich the ids that WebsiteSnapshot uses, * then please refer to @a setComplexAuthenticationWithPossibleFields(). * * For the username field, input tags of type 'text', 'email' and 'username' are searched. * For the password field, input tags of type 'password' are searched. * * \sa setComplexAuthenticationWithPossibleFields() */ void setComplexAuthentication(const QString &username, const QString &password, const QString &finalUrl); /*! * \brief Does a complex username-password fields authentication with custom fields. * * \param username The username to use for the authentication. * \param password The password to use for the authentication. * \param finalUrl The url to navigate to after the authentication is successful. * \param usernameFields The strings to search for the username field. * \param passwordFields The strings to search for the password field. * \param tryUsualFields If true, then aside from @a usernameFields and @a passwordFields, * the library's default search strings will be used. If false, then * only the @a usernameFields and @a passwordFields will be used. * * This function is the same as @a setComplexAuthentication(), but it allows you to set your * own username-password ids for searching, either exclusively or by enriching the current search * values. * *\sa setComplexAuthentication() */ void setComplexAuthenticationWithPossibleFields(const QString &username, const QString &password, const QString &finalUrl, const QStringList &usernameFields, const QStringList &passwordFields, bool tryUsualFields = false); /*! * \brief Disables a previously declared authentication type (either simple or complex). * * This function will disable the previously set authentication attempts. This is usually * useful when you've called start() on a page that requires authentication and then * you need to call start() on a page that does not require authentication using the * same WebsiteSnapshot object. * *\sa start() */ void disableAuthentication(); /*! * \brief Sets a wait timeout prior to complex authentication. * * \param seconds The seconds to wait prior attempting a complex authentication. * * This is done in order to ensure that the log-in page has loaded completely (e.g. Javascript * has finished creating the page) and the username and password fields are available for filling. * * By default, it is set to 1 second. * \sa setComplexAuthentication(), setComplexAuthenticationWithPossibleFields() */ void setComplexAuthenticationInitialWait(unsigned const short &seconds); /*! * \brief Sets a wait timeout after loading the final page. * * \param secondsWait The seconds to wait. * * This is done in order to let the final web page to load completely, because in many * cases there are internal calls that have to be completed in order the web page to * take its final form. * * By default, it is set to 3 seconds. */ void setWaitAfterFinish(unsigned const short &secondsWait); /*! * \brief Returns whether the process is running. * * \return True if start() has been called and the resultedImage() signal is not emitted yet. * In any other case it returns false. * \sa start(), resultedImage() */ bool isLoading(); /*! * \brief Controls debug messages. * * \param enabled If true, then debug messages are enabled, otherwise they are disabled. */ void setDebugEnabled(bool enabled); /*! * \brief Returns the final url. * * \return The url where the website snapshot is to be taken. */ QString url(); /*! * \brief Returns the last error. * * The value of the string is resetted if @a start() is called anew. * * \return The last error that occurred and resulted in a @a resultedImage() signal * with a null QImage pointer. * *\sa resultedImage(), start() */ QString lastErrorString(); /*! * \brief Returns a QObject pointer of the WebsiteSnapshot instance. * * This function is useful when using the instance in a signal-slot mechanism. * * \return Α QObject pointer of the WebsiteSnapshot instance. */ QObject *asQObject(); private: enum AuthenticationLevel { NoAuthentication, SimpleAuthentication, ComplexAuthentication }; AuthenticationLevel authenticationLevel_; bool currentlyLoading_; bool debug_; bool javascriptEnabled_; bool javascriptCanAccessClipboard_; bool javaEnabled_; bool loadImagesEnabled_; bool simpleAuthAlreadyDone_; bool cropImage_; short minWidth_; short minHeight_; short errorCode_; unsigned int timeout_; unsigned short waitAfterFinish_; unsigned short complexAuthInitialWait_; QRect cropRect_; QString authUsername_; QString authPassword_; QUrl requestedUrl_; QUrl urlAfterAuth_; QStringList usernameSearchFields_; QStringList passwordSearchFields_; CustomWebPage *webPage_; QTimer timeoutTimer_; QTimer afterFinishTimer_; QTimer priorComplexTimer_; QString lastError_; void parseUrl(QUrl &url); void disconnectWebPage(); bool searchAndSet(const QWebElement &document, const QString &searchFor, const QString &attribute, const QString &value, const QStringList &searchFields); void sendResultActions(QImage *image); void initializeWebPage(); void decideFinalPage(); void dbg(const QString &string); private Q_SLOTS: void returnResults(bool result); void afterAuthNavigation(bool result); void authenticateSimple(QNetworkReply*, QAuthenticator* authenticator); void complexAuthenticationRequired(bool success); void webPageDestroyed(); void timeoutReached(); void afterFinishTimedOut(); void proceedToComplexAuth(); Q_SIGNALS: /*! * \brief Emitted when the process is complete. * * \param image A pointer of the QImage data containing the final image. Null on unsuccessful attempt. * \param errorCode Indicates the result state. It can take the following values: * - 0 No error. * - 1 Some page required for the image creation could not be loaded for some reason. * - 2 Simple authentication failed * - 3 Username and/or password fields are not found * - 4 The timeout has been reached and the image has yet to be created. * * This signal is always called when the process is complete. */ void resultedImage(QImage *image, short errorCode); }; #endif wallch-4.0/src/preferences.cpp0000644000175000017500000011665612301477401015105 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include "preferences.h" #include "ui_preferences.h" #include "glob.h" #ifdef ON_LINUX #include "keybinder.h" #endif #include "math.h" #include #include #include #include #include #include #include Preferences::Preferences(QWidget *parent) : QDialog(parent), ui(new Ui::preferences) { ui->setupUi(this); ui->stackedWidget->setCurrentIndex(0); setupShortcuts(); //move dialog to center of the screen this->move(QApplication::desktop()->availableGeometry().center() - this->rect().center()); /* * On the constructor all we need to do is to take the saved values from our .conf files (on Linux) * or from registry (on Windows) and put them accordingly to the checkboxes etc */ //'General' Page ui->desktop_notification_checkbox->setChecked(settings->value("notification", false).toBool()); ui->clocksNotifyCheckbox->setChecked(settings->value("clocks_notification", true).toBool()); ui->clocksNotifyCheckbox->setEnabled(ui->desktop_notification_checkbox->isChecked()); ui->history_checkbox->setChecked(settings->value( "history", true ).toBool()); ui->independent_interval_checkbox->setChecked(settings->value("independent_interval_enabled", true).toBool()); ui->preview_images_checkbox->setChecked(settings->value("preview_images_on_screen", true).toBool()); ui->language_combo->setCurrentIndex(settings->value("language", 0).toInt()); ui->startupCheckBox->setChecked(settings->value("Startup", true).toBool()); ui->onceCheckBox->setChecked(settings->value("Once", false).toBool()); on_startupCheckBox_clicked(ui->startupCheckBox->isChecked()); #ifdef ON_LINUX ui->startup_timeout_spinbox->setValue(settings->value("startup_timeout", 3).toInt()); #else ui->startup_timeout_spinbox->setValue(settings->value("startup_timeout", 0).toInt()); #endif //'Wallpapers' Page ui->rotate_checkBox->setChecked(settings->value("rotation", false).toBool()); ui->shortcut_checkbox->setChecked(settings->value("use_shortcut_next", false).toBool()); lineEditShortcut = new LineEditShortCut(this); lineEditShortcut->setPlaceholderText(tr("Press here and give a combination")); lineEditShortcut->setText(settings->value("shortcut", "").toString()); if(!ui->shortcut_checkbox->isChecked()){ lineEditShortcut->setEnabled(false); } buttonsLayout_ = new QHBoxLayout; buttonsLayout_->setContentsMargins(QMargins(0,0,0,0)); buttonsLayout_->addWidget(ui->shortcut_checkbox); buttonsLayout_->addWidget(lineEditShortcut); ui->widget->setLayout(buttonsLayout_); connect(lineEditShortcut, SIGNAL(textChanged(QString)), this, SLOT(shortcutEdited())); shortcutWasCheckedAtFirst_=ui->shortcut_checkbox->isChecked(); textOfShortcutChanged_=false; textOfShortcutInitially_=lineEditShortcut->text(); #ifdef ON_LINUX keybinder_init(); #endif ui->first_timeout_checkbox->setChecked(settings->value("first_timeout", false).toBool()); if(settings->value("icon_style", true).toBool()==false){ ui->paths_radioButton->setChecked(true); } listIsAlreadyIcons_=ui->icons_radioButton->isChecked(); customIntervalsChanged_=false; addNewIntervalIsShown_=false; short size=settings->beginReadArray("custom_intervals_in_seconds"); for (short i=0; isetArrayIndex(i); ui->listWidget->addItem(Global::secondsToMinutesHoursDays(settings->value("item").toInt())); } settings->endArray(); customIntervalsInSeconds_temp=gv.customIntervalsInSeconds; ui->random_time_checkbox->setChecked(gv.randomTimeEnabled); ui->random_time_from_combobox->setCurrentIndex(settings->value("from_combo", 1).toInt()); ui->random_time_to_combobox->setCurrentIndex(settings->value("till_combo", 1).toInt()); on_random_time_checkbox_clicked(gv.randomTimeEnabled); if(ui->random_time_from_combobox->currentIndex()==0){ ui->random_from->setValue(settings->value("random_time_from", 10).toInt()); } else if(ui->random_time_from_combobox->currentIndex()==1){ ui->random_from->setValue(settings->value("random_time_from", 10).toInt()/60); } else { ui->random_from->setValue(settings->value("random_time_from", 10).toInt()/3600); } if(ui->random_time_to_combobox->currentIndex()==0){ ui->random_to->setValue(settings->value("random_time_to", 10).toInt()); } else if(ui->random_time_to_combobox->currentIndex()==1){ ui->random_to->setValue(settings->value("random_time_to", 10).toInt()/60); } else { ui->random_to->setValue(settings->value("random_time_to", 10).toInt()/3600); } on_random_time_from_combobox_currentIndexChanged(ui->random_time_from_combobox->currentIndex()); //'Live Website' Page ui->simple_authentication->setChecked(settings->value("website_simple_auth", false).toBool()); ui->wait_after_finish_spinbox->setValue(settings->value("website_wait_after_finish", 3).toInt()); ui->js_enabled->setChecked(settings->value("website_js_enabled", true).toBool()); ui->js_can_read_clipboard->setEnabled(ui->js_enabled->isChecked()); ui->js_can_read_clipboard->setChecked(settings->value("website_js_can_read_clipboard", false).toBool()); ui->java_enabled->setChecked(settings->value("website_java_enabled", false).toBool()); ui->load_images->setChecked(settings->value("website_load_images", true).toBool()); ui->extra_username_fields->setText(settings->value("website_extra_usernames", QStringList()).toStringList().join(", ")); ui->extra_password_fields->setText(settings->value("website_extra_passwords", QStringList()).toStringList().join(", ")); //'Integration' Page #ifdef ON_LINUX ui->unity_prog_checkbox->setChecked(settings->value("unity_progressbar_enabled", true).toBool()); short curDe = settings->value("de", 0).toInt(); if(curDe>=ui->de_combo->count()){ curDe=0; } ui->de_combo->setCurrentIndex(curDe); on_de_combo_currentIndexChanged(curDe); #else ui->unity_prog_checkbox->hide(); ui->de_combo->hide(); ui->label_16->hide(); #endif QString curTheme = settings->value("theme", "autodetect").toString(); if(curTheme=="ambiance"){ ui->theme_combo->setCurrentIndex(0); } else if(curTheme=="radiance"){ ui->theme_combo->setCurrentIndex(1); } else{ ui->theme_combo->setCurrentIndex(2); } on_theme_combo_currentIndexChanged(ui->theme_combo->currentIndex()); setupThemeFallbacks(); } Preferences::~Preferences() { delete ui; } void Preferences::changeEvent(QEvent *e) { QDialog::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } void Preferences::setupShortcuts(){ (void) new QShortcut(Qt::Key_Escape, this, SLOT(close())); (void) new QShortcut(Qt::ALT + Qt::Key_1, this, SLOT(on_page_0_general_clicked())); (void) new QShortcut(Qt::ALT + Qt::Key_2, this, SLOT(on_page_1_wallpapers_page_clicked())); (void) new QShortcut(Qt::ALT + Qt::Key_3, this, SLOT(on_page_2_live_website_clicked())); (void) new QShortcut(Qt::ALT + Qt::Key_4, this, SLOT(on_page_3_integration_clicked())); (void) new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(previousPage())); (void) new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(nextPage())); } void Preferences::setupThemeFallbacks(){ ui->add_custom_interval->setIcon(QIcon::fromTheme("list-add", QIcon(":/icons/Pictures/list-add.svg"))); ui->remove_custom_interval->setIcon(QIcon::fromTheme("list-remove", QIcon(":/icons/Pictures/list-remove.svg"))); } void Preferences::previousPage(){ short currentPage = ui->stackedWidget->currentIndex()-1; if(currentPage<0){ currentPage=4; } switch(currentPage){ case 0: on_page_0_general_clicked(); break; case 1: on_page_1_wallpapers_page_clicked(); break; case 2: on_page_2_live_website_clicked(); break; case 3: on_page_3_integration_clicked(); break; default: on_page_0_general_clicked(); } } void Preferences::nextPage(){ short currentPage = ui->stackedWidget->currentIndex()+1; if(currentPage>4){ currentPage=0; } switch(currentPage){ case 0: on_page_0_general_clicked(); break; case 1: on_page_1_wallpapers_page_clicked(); break; case 2: on_page_2_live_website_clicked(); break; case 3: on_page_3_integration_clicked(); break; default: on_page_0_general_clicked(); } } void Preferences::on_closeButton_clicked() { this->close(); } void handler (const char *, void *) { } void Preferences::on_saveButton_clicked() { /* * On this function all we need to do is to update the .conf files(on Linux) * or registrys(on Windows) with the values of Preferences checkboxes etc */ //'General' Page gv.saveHistory=ui->history_checkbox->isChecked(); gv.independentIntervalEnabled=ui->independent_interval_checkbox->isChecked(); if(gv.previewImagesOnScreen!=ui->preview_images_checkbox->isChecked()) { gv.previewImagesOnScreen=ui->preview_images_checkbox->isChecked(); Q_EMIT tvPreviewChanged(gv.previewImagesOnScreen); } QString lang_file_string; switch (ui->language_combo->currentIndex()){ default: case 0: lang_file_string="en"; break; case 1: lang_file_string="el"; break; } settings->setValue("history", gv.saveHistory); settings->setValue("independent_interval_enabled", gv.independentIntervalEnabled); settings->setValue("preview_images_on_screen", gv.previewImagesOnScreen); settings->setValue("language", ui->language_combo->currentIndex()); settings->setValue("language_file", lang_file_string); settings->setValue("Startup", ui->startupCheckBox->isChecked()); settings->setValue("startup_timeout", ui->startup_timeout_spinbox->value()); settings->setValue("Once", ui->onceCheckBox->isChecked()); if(ui->startupCheckBox->isChecked()){ Global::updateStartup(); } else{ #ifdef ON_WIN32 QSettings settings2("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat); settings2.remove("Wallch"); settings2.sync(); #else if(QFile::exists(gv.homePath+AUTOSTART_DIR+"/"+BOOT_DESKTOP_FILE)){ Global::remove(gv.homePath+AUTOSTART_DIR+"/"+BOOT_DESKTOP_FILE); } #endif } //'Wallpapers' Page gv.showNotification = ui->desktop_notification_checkbox->isChecked(); gv.rotateImages=ui->rotate_checkBox->isChecked(); if(shortcutWasCheckedAtFirst_){ if(!ui->shortcut_checkbox->isChecked()){ //unbind the current key Q_EMIT unbindKeySignal(gv.nextShortcut); } else { //it was and it is checked, check if text has changed... //if it has, then update with the new button if(textOfShortcutChanged_){ //unbind the old key and bind the new one... Q_EMIT unbindKeySignal(gv.nextShortcut); if(! (lineEditShortcut->text().endsWith(">") || lineEditShortcut->text().isEmpty()) ){ //if the entry is ok, then send command to the mainwindow to bind the key gv.nextShortcut=lineEditShortcut->text(); Q_EMIT bindKeySignal(gv.nextShortcut); } else { gv.useShortcutNext=false; gv.nextShortcut=""; } } } } else { if(ui->shortcut_checkbox->isChecked()){ if(! (lineEditShortcut->text().endsWith(">") || lineEditShortcut->text().isEmpty()) ){ //if the entry is ok, then send command to the mainwindow to bind the key and update the gv.nextShortcut=lineEditShortcut->text(); Q_EMIT bindKeySignal(gv.nextShortcut); } else { gv.useShortcutNext=false; gv.nextShortcut=""; } } } gv.useShortcutNext=ui->shortcut_checkbox->isChecked(); gv.useShortcutNext=ui->shortcut_checkbox->isChecked(); gv.firstTimeout=ui->first_timeout_checkbox->isChecked(); if(ui->icons_radioButton->isChecked() && !listIsAlreadyIcons_){ Q_EMIT changePathsToIcons(); } else if(ui->paths_radioButton->isChecked() && listIsAlreadyIcons_){ Q_EMIT changeIconsToPaths(); } if(customIntervalsChanged_) { gv.customIntervalsInSeconds=customIntervalsInSeconds_temp; if(gv.customIntervalsInSeconds.count()>0) { settings->beginWriteArray("custom_intervals_in_seconds"); short listCount = ui->listWidget->count(); for (short i = 0; i < listCount; ++i) { settings->setArrayIndex(i); settings->setValue("item", gv.customIntervalsInSeconds.at(i)); } settings->endArray(); } Q_EMIT refreshCustomIntervals(); } if(gv.randomTimeEnabled!=ui->random_time_checkbox->isChecked()) { gv.randomTimeEnabled=ui->random_time_checkbox->isChecked(); Q_EMIT changeRandomTime(gv.randomTimeEnabled); } gv.randomTimeFrom=ui->random_from->value() * pow(60, ui->random_time_from_combobox->currentIndex()); if(gv.randomTimeFrom==0){ gv.randomTimeFrom=1; } gv.randomTimeTo=ui->random_to->value() * pow(60, ui->random_time_to_combobox->currentIndex()); settings->setValue("notification", gv.showNotification); settings->setValue("clocks_notification", ui->clocksNotifyCheckbox->isChecked()); settings->setValue("rotation", gv.rotateImages); settings->setValue("use_shortcut_next", gv.useShortcutNext); settings->setValue("shortcut", gv.nextShortcut); settings->setValue("first_timeout", gv.firstTimeout); settings->setValue("icon_style", ui->icons_radioButton->isChecked()); settings->setValue("random_time_from", gv.randomTimeFrom); settings->setValue("random_time_to", gv.randomTimeTo); settings->setValue("random_time_enabled", gv.randomTimeEnabled); settings->setValue("from_combo", ui->random_time_from_combobox->currentIndex()); settings->setValue("till_combo", ui->random_time_to_combobox->currentIndex()); //'Live Website' Page gv.websiteSimpleAuthEnabled=ui->simple_authentication->isChecked(); gv.websiteWaitAfterFinishSeconds=ui->wait_after_finish_spinbox->value(); gv.websiteJavascriptEnabled=ui->js_enabled->isChecked(); gv.websiteJavascriptCanReadClipboard=ui->js_can_read_clipboard->isChecked(); gv.websiteJavaEnabled=ui->java_enabled->isChecked(); gv.websiteLoadImages=ui->load_images->isChecked(); gv.websiteExtraUsernames=ui->extra_username_fields->text().split(',').replaceInStrings(" ", ""); gv.websiteExtraPasswords=ui->extra_password_fields->text().split(',').replaceInStrings(" ", ""); settings->setValue("website_simple_auth", gv.websiteSimpleAuthEnabled); settings->setValue("website_wait_after_finish", gv.websiteWaitAfterFinishSeconds); settings->setValue("website_js_enabled", gv.websiteJavascriptEnabled); settings->setValue("website_js_can_read_clipboard", gv.websiteJavascriptCanReadClipboard); settings->setValue("website_java_enabled", gv.websiteJavaEnabled); settings->setValue("website_load_images", gv.websiteLoadImages); settings->setValue("website_extra_usernames", gv.websiteExtraUsernames); settings->setValue("website_extra_passwords", gv.websiteExtraPasswords); //'Integration' Page #ifdef ON_LINUX if(gv.unityProgressbarEnabled!=ui->unity_prog_checkbox->isChecked()){ gv.unityProgressbarEnabled=ui->unity_prog_checkbox->isChecked(); Q_EMIT unityProgressbarChanged(gv.unityProgressbarEnabled); } settings->setValue("unity_progressbar_enabled", gv.unityProgressbarEnabled); settings->setValue("de", ui->de_combo->currentIndex()); #endif switch(ui->theme_combo->currentIndex()){ case 0: settings->setValue("theme", "ambiance"); break; case 1: settings->setValue("theme", "radiance"); break; case 2: settings->setValue("theme", "autodetect"); break; } settings->sync(); this->close(); } void Preferences::on_reset_clicked() { if (QMessageBox::question(this, tr("Reset Preferences"), tr("Are you sure you want to reset your Wallch\npreferences?")) == QMessageBox::Yes) { //General ui->desktop_notification_checkbox->setChecked(false); ui->clocksNotifyCheckbox->setChecked(false); ui->history_checkbox->setChecked(true); ui->independent_interval_checkbox->setChecked(true); ui->preview_images_checkbox->setChecked(true); ui->language_combo->setCurrentIndex(3); ui->startupCheckBox->setChecked(true); ui->onceCheckBox->setChecked(false); #ifdef ON_LINUX ui->startup_timeout_spinbox->setValue(3); #else ui->startup_timeout_spinbox->setValue(0); #endif //Wallpapers ui->rotate_checkBox->setChecked(false); ui->shortcut_checkbox->setChecked(false); ui->first_timeout_checkbox->setChecked(false); ui->icons_radioButton->setChecked(true); ui->listWidget->clear(); Q_EMIT refreshCustomIntervals(); ui->listWidget->addItems(gv.defaultIntervals); ui->random_time_checkbox->setChecked(false); ui->random_time_from_combobox->setCurrentIndex(1); ui->random_from->setValue(0); ui->random_time_to_combobox->setCurrentIndex(1); ui->random_to->setValue(1); //Live Website ui->simple_authentication->setChecked(false); ui->wait_after_finish_spinbox->setValue(3); ui->js_enabled->setChecked(true); ui->js_can_read_clipboard->setChecked(false); ui->java_enabled->setChecked(false); ui->load_images->setChecked(true); ui->extra_username_fields->clear(); ui->extra_password_fields->clear(); //Integration ui->theme_combo->setCurrentIndex(2); ui->de_combo->setCurrentIndex(0); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ ui->unity_prog_checkbox->setChecked(true); } #endif //applying these settings and closing the dialog... on_saveButton_clicked(); } } //Random time void Preferences::on_random_time_from_combobox_currentIndexChanged(int index) { ui->random_from->setMinimum(0); if(ui->random_time_to_combobox->currentIndex()random_time_to_combobox->setCurrentIndex(index); } on_random_from_valueChanged(ui->random_from->value()); } void Preferences::on_random_time_to_combobox_currentIndexChanged(int index) { if(index==0){ ui->random_time_from_combobox->setCurrentIndex(0); } else if (index==1 && ui->random_time_from_combobox->currentIndex()==2){ ui->random_time_from_combobox->setCurrentIndex(1); } on_random_to_valueChanged(ui->random_to->value()); } void Preferences::on_random_from_valueChanged(int value) { short combo_from=ui->random_time_from_combobox->currentIndex(); short combo_till=ui->random_time_to_combobox->currentIndex(); short value2=ui->random_to->value(); if(combo_from==0 && combo_till==0 && value>=value2-2){ ui->random_to->setValue(value+3); } else if(((combo_from==1 && combo_till==1) || (combo_from==2 && combo_till==2)) && value>=value2){ ui->random_to->setValue(value+1); } } void Preferences::on_random_to_valueChanged(int value2) { short combo_from=ui->random_time_from_combobox->currentIndex(); short combo_till=ui->random_time_to_combobox->currentIndex(); short value=ui->random_from->value(); if(combo_from==0 && combo_till==0 && value>=value2-2){ ui->random_from->setValue(value2-3); } else if(((combo_from==1 && combo_till==1) || (combo_from==2 && combo_till==2)) && value>=value2){ ui->random_from->setValue(value2-1); } } //End of random time void LineEditShortCut::keyPressEvent(QKeyEvent *event) { int modifiers = event->modifiers(); if( !(gotCtrlKey_ || gotAltKey_) ) this->clear(); if(!gotCtrlKey_ && (modifiers & Qt::ControlModifier)){ gotCtrlKey_=true; this->insert(""); } else if(!gotAltKey_ && (modifiers & Qt::AltModifier)){ gotAltKey_=true; this->insert(""); } else { //normal key! if(! (gotAltKey_ || gotCtrlKey_) ){ return; } gotSomeKey_=true; switch(event->key()){ case Qt::Key_A: this->insertAtEnd("A"); break; case Qt::Key_B: this->insertAtEnd("B"); break; case Qt::Key_C: this->insertAtEnd("C"); break; case Qt::Key_D: this->insertAtEnd("D"); break; case Qt::Key_E: this->insertAtEnd("E"); break; case Qt::Key_F: this->insertAtEnd("F"); break; case Qt::Key_G: this->insertAtEnd("G"); break; case Qt::Key_H: this->insertAtEnd("H"); break; case Qt::Key_I: this->insertAtEnd("I"); break; case Qt::Key_J: this->insertAtEnd("J"); break; case Qt::Key_K: this->insertAtEnd("K"); break; case Qt::Key_L: this->insertAtEnd("L"); break; case Qt::Key_M: this->insertAtEnd("M"); break; case Qt::Key_N: this->insertAtEnd("N"); break; case Qt::Key_O: this->insertAtEnd("O"); break; case Qt::Key_P: this->insertAtEnd("P"); break; case Qt::Key_Q: this->insertAtEnd("Q"); break; case Qt::Key_R: this->insertAtEnd("R"); break; case Qt::Key_S: this->insertAtEnd("S"); break; case Qt::Key_T: this->insertAtEnd("T"); break; case Qt::Key_U: this->insertAtEnd("U"); break; case Qt::Key_V: this->insertAtEnd("V"); break; case Qt::Key_W: this->insertAtEnd("W"); break; case Qt::Key_X: this->insertAtEnd("X"); break; case Qt::Key_Y: this->insertAtEnd("Y"); break; case Qt::Key_Z: this->insertAtEnd("Z"); break; case Qt::Key_1: this->insertAtEnd("1"); break; case Qt::Key_2: this->insertAtEnd("2"); break; case Qt::Key_3: this->insertAtEnd("3"); break; case Qt::Key_4: this->insertAtEnd("4"); break; case Qt::Key_5: this->insertAtEnd("5"); break; case Qt::Key_6: this->insertAtEnd("6"); break; case Qt::Key_7: this->insertAtEnd("7"); break; case Qt::Key_8: this->insertAtEnd("8"); break; case Qt::Key_9: this->insertAtEnd("9"); break; case Qt::Key_0: this->insertAtEnd("0"); break; case Qt::Key_Space: this->insertAtEnd("space"); break; case Qt::Key_F1: this->insertAtEnd("F1"); break; case Qt::Key_F2: this->insertAtEnd("F2"); break; case Qt::Key_F3: this->insertAtEnd("F3"); break; case Qt::Key_F4: this->insertAtEnd("F4"); break; case Qt::Key_F5: this->insertAtEnd("F5"); break; case Qt::Key_F6: this->insertAtEnd("F6"); break; case Qt::Key_F7: this->insertAtEnd("F7"); break; case Qt::Key_F8: this->insertAtEnd("F8"); break; case Qt::Key_F9: this->insertAtEnd("F9"); break; case Qt::Key_F10: this->insertAtEnd("F10"); break; case Qt::Key_F11: this->insertAtEnd("F11"); break; case Qt::Key_F12: this->insertAtEnd("F12"); break; case Qt::Key_Agrave: this->insertAtEnd("grave"); break; case Qt::Key_AsciiTilde: this->insertAtEnd("asciitilde"); break; case Qt::Key_Exclam: this->insertAtEnd("exclam"); break; case Qt::Key_At: this->insertAtEnd("at"); break; case Qt::Key_NumberSign: this->insertAtEnd("numbersign"); break; case Qt::Key_Dollar: this->insertAtEnd("dollar"); break; case Qt::Key_Percent: this->insertAtEnd("percent"); break; case Qt::Key_AsciiCircum: this->insertAtEnd("asciicircum"); break; case Qt::Key_Ampersand: this->insertAtEnd("ampersand"); break; case Qt::Key_Asterisk: this->insertAtEnd("asterisk"); break; case Qt::Key_ParenLeft: this->insertAtEnd("parenleft"); break; case Qt::Key_ParenRight: this->insertAtEnd("parenright"); break; case Qt::Key_Minus: this->insertAtEnd("minus"); break; case Qt::Key_Underscore: this->insertAtEnd("underscore"); break; case Qt::Key_Plus: this->insertAtEnd("plus"); break; case Qt::Key_Equal: this->insertAtEnd("equal"); break; case Qt::Key_Backspace: this->insertAtEnd("BackSpace"); break; case Qt::Key_Tab: this->insertAtEnd("Tab"); break; case Qt::Key_BracketLeft: this->insertAtEnd("bracketleft"); break; case Qt::Key_BracketRight: this->insertAtEnd("bracketright"); break; case Qt::Key_BraceLeft: this->insertAtEnd("braceleft"); break; case Qt::Key_BraceRight: this->insertAtEnd("braceright"); break; case Qt::Key_Backslash: this->insertAtEnd("backslash"); break; case Qt::Key_Bar: this->insertAtEnd("bar"); break; case Qt::Key_Colon: this->insertAtEnd("colon"); break; case Qt::Key_Semicolon: this->insertAtEnd("semicolon"); break; case Qt::Key_Apostrophe: this->insertAtEnd("apostrophe"); break; case Qt::Key_QuoteDbl: this->insertAtEnd("quotedbl"); break; case Qt::Key_Return: this->insertAtEnd("Return"); break; case Qt::Key_Comma: this->insertAtEnd("comma"); break; case Qt::Key_Less: this->insertAtEnd("less"); break; case Qt::Key_Period: this->insertAtEnd("period"); break; case Qt::Key_Greater: this->insertAtEnd("greater"); break; case Qt::Key_Slash: this->insertAtEnd("slash"); break; case Qt::Key_Question: this->insertAtEnd("question"); break; case Qt::Key_PageUp: this->insertAtEnd("Page_Up"); break; case Qt::Key_PageDown: this->insertAtEnd("Page_Down"); break; case Qt::Key_Left: this->insertAtEnd("leftarrow"); break; case Qt::Key_Right: this->insertAtEnd("rightarrow"); break; case Qt::Key_Up: this->insertAtEnd("uparrow"); break; case Qt::Key_Down: this->insertAtEnd("downarrow"); break; case Qt::Key_Escape: this->insertAtEnd("Escape"); break; case Qt::Key_Insert: this->insertAtEnd("Insert"); break; case Qt::Key_Delete: this->insertAtEnd("Delete"); break; case Qt::Key_Print: this->insertAtEnd("Print"); break; case Qt::Key_Pause: this->insertAtEnd("Pause"); break; case Qt::Key_ScrollLock: this->insertAtEnd("Scroll_Lock"); break; case Qt::Key_NumLock: this->insertAtEnd("Num_Lock"); break; case Qt::Key_SysReq: this->insertAtEnd("Sys_Req"); break; case Qt::Key_Home: this->insertAtEnd("Home"); break; case Qt::Key_End: this->insertAtEnd("End"); break; default: gotSomeKey_=false; break; } } } void LineEditShortCut::keyReleaseEvent(QKeyEvent *){ this->clearFocus(); #ifdef ON_LINUX gotCtrlKey_=gotAltKey_=false; if(!gotSomeKey_){ this->clear(); } else { gotSomeKey_=false; if(!keybinder_bind(this->text().toLocal8Bit().data(), handler, NULL)){ //key could not be binded! QMessageBox::warning(this, tr("Warning"), tr("The key sequence you chose is not valid or it is taken by another application.")); this->clear(); } else { /* * The key can be binded but the user has yet to click the Save button, so * unbind it for now till then. */ keybinder_unbind(this->text().toLocal8Bit().data(), handler); } } #endif //#ifdef ON_LINUX } void Preferences::on_shortcut_checkbox_clicked(bool checked) { lineEditShortcut->setEnabled(checked); if(checked){ lineEditShortcut->setFocus(); } } void Preferences::shortcutEdited(){ if(shortcutWasCheckedAtFirst_ && !textOfShortcutChanged_){ unbindKeySignal(textOfShortcutInitially_); } textOfShortcutChanged_=true; } void Preferences::on_page_0_general_clicked() { ui->stackedWidget->setCurrentIndex(0); ui->page_0_general->setChecked(true); ui->page_0_general->raise(); ui->sep1->raise(); } void Preferences::on_page_1_wallpapers_page_clicked() { ui->stackedWidget->setCurrentIndex(1); ui->page_1_wallpapers_page->setChecked(true); ui->page_1_wallpapers_page->raise(); ui->sep1->raise(); ui->sep2->raise(); } void Preferences::on_page_2_live_website_clicked() { ui->stackedWidget->setCurrentIndex(2); ui->page_2_live_website->setChecked(true); ui->page_2_live_website->raise(); ui->sep2->raise(); ui->sep3->raise(); } void Preferences::on_page_3_integration_clicked() { ui->stackedWidget->setCurrentIndex(3); ui->page_3_integration->setChecked(true); ui->page_3_integration->raise(); ui->sep3->raise(); } void Preferences::setThemeToAmbiance(){ ui->page_0_general->setStyleSheet(AMBIANCE_THEME_STYLESHEET); ui->page_1_wallpapers_page->setStyleSheet(AMBIANCE_THEME_STYLESHEET); ui->page_2_live_website->setStyleSheet(AMBIANCE_THEME_STYLESHEET); ui->page_3_integration->setStyleSheet(AMBIANCE_THEME_STYLESHEET); ui->sep1->setPixmap(AMBIANCE_SEPARATOR); ui->sep2->setPixmap(AMBIANCE_SEPARATOR); ui->sep3->setPixmap(AMBIANCE_SEPARATOR); ui->widget_2->setStyleSheet("QWidget { background-image: url(:/icons/Pictures/ambiance_not_checked.png); }"); #ifdef ON_LINUX app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_AMBIANCE_NORMAL, INDICATOR_DESCRIPTION); #endif Q_EMIT changeThemeTo("ambiance"); } void Preferences::setThemeToRadiance(){ ui->page_0_general->setStyleSheet(RADIANCE_THEME_STYLESHEET); ui->page_1_wallpapers_page->setStyleSheet(RADIANCE_THEME_STYLESHEET); ui->page_2_live_website->setStyleSheet(RADIANCE_THEME_STYLESHEET); ui->page_3_integration->setStyleSheet(RADIANCE_THEME_STYLESHEET); ui->sep1->setPixmap(RADIANCE_SEPARATOR); ui->sep2->setPixmap(RADIANCE_SEPARATOR); ui->sep3->setPixmap(RADIANCE_SEPARATOR); ui->widget_2->setStyleSheet("QWidget { background-image: url(:/icons/Pictures/radiance_not_checked.png); }"); #ifdef ON_LINUX app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_RADIANCE_NORMAL, INDICATOR_DESCRIPTION); #endif Q_EMIT changeThemeTo("radiance"); } void Preferences::on_theme_combo_currentIndexChanged(int index) { switch(index){ case 0: setThemeToAmbiance(); break; case 1: setThemeToRadiance(); break; default: { //autodetect theme QString curTheme; #ifdef ON_LINUX if(gv.currentDE==Gnome || gv.currentDE==UnityGnome){ curTheme=Global::gsettingsGet("org.gnome.desktop.interface", "gtk-theme"); } else { if(gv.currentTheme=="ambiance"){ curTheme="Ambiance"; } else { curTheme="Radiance"; } } #endif if(curTheme=="Ambiance"){ setThemeToAmbiance(); } else { setThemeToRadiance(); } break; } } } void Preferences::on_random_time_checkbox_clicked(bool checked) { ui->random_time_from_label->setEnabled(checked); ui->random_time_from_combobox->setEnabled(checked); ui->random_time_to_label->setEnabled(checked); ui->random_time_to_combobox->setEnabled(checked); ui->random_from->setEnabled(checked); ui->random_to->setEnabled(checked); ui->listWidget->setEnabled(!checked); ui->custom_intervals_label->setEnabled(!checked); ui->add_custom_interval->setEnabled(!checked); ui->remove_custom_interval->setEnabled(!checked); } void Preferences::on_add_custom_interval_clicked() { QString time_type; int time_in_seconds=0; switch (ui->time_comboBox->currentIndex()) { case 0: time_in_seconds=ui->time_spinBox->value(); if(ui->time_spinBox->value()==1){ time_type=tr("second"); } else{ time_type=tr("seconds"); } break; case 1: time_in_seconds=60*ui->time_spinBox->value(); if(ui->time_spinBox->value()==1){ time_type=tr("minute"); } else{ time_type=tr("minutes"); } break; case 2: time_in_seconds=3600*ui->time_spinBox->value(); if(ui->time_spinBox->value()==1){ time_type=tr("hour"); } else{ time_type=tr("hours"); } break; case 3: time_in_seconds=86400*ui->time_spinBox->value(); if(ui->time_spinBox->value()==1){ time_type=tr("day"); } else{ time_type=tr("days"); } break; } customIntervalsInSeconds_temp << time_in_seconds; for (short i=customIntervalsInSeconds_temp.count()-1; i>0; i--) { if(customIntervalsInSeconds_temp[i]time_spinBox->text()+" "+time_type+"\" "+tr("already exists.")); break; } else { customIntervalsChanged_=true; ui->listWidget->insertItem(i, ui->time_spinBox->text()+" "+time_type); break; } if(i==1) { customIntervalsChanged_=true; ui->listWidget->insertItem(0, ui->time_spinBox->text()+" "+time_type); } } } void Preferences::on_remove_custom_interval_clicked() { if (ui->listWidget->count()==2){ QMessageBox::warning(this, tr("Error"), tr("You need to have at least two intervals")); } else { customIntervalsChanged_=true; customIntervalsInSeconds_temp.removeAt(ui->listWidget->currentRow()); delete ui->listWidget->currentItem(); } } void Preferences::on_rotate_checkBox_clicked(bool checked) { if(checked){ QMessageBox::warning(this, tr("Warning"), tr("This option will alter your images. You can also rotate your images manually via the right click menu.")); } } QString Preferences::getCommandOfDesktopFile(const QString &file){ QFile desktopFile(file); if(!desktopFile.open(QIODevice::ReadOnly | QIODevice::Text)){ return QString(); } QTextStream in(&desktopFile); QString curLine; bool found=false; while(!in.atEnd()){ curLine=in.readLine(); if(curLine.startsWith("Exec=")){ found=true; break; } } if(found){ return curLine.right(curLine.count()-5); } else { return QString(); } } #ifdef ON_LINUX void Preferences::on_de_combo_currentIndexChanged(int index) { DesktopEnvironment curEnv = static_cast(index); if(curEnv!=UnityGnome){ ui->unity_prog_checkbox->hide(); } else { ui->unity_prog_checkbox->show(); } } #endif void Preferences::on_startupCheckBox_clicked(bool checked) { ui->onceCheckBox->setEnabled(checked); ui->label_6->setEnabled(checked); ui->label_7->setEnabled(checked); ui->startup_timeout_spinbox->setEnabled(checked); ui->label->setEnabled(checked); } void Preferences::on_help_clicked() { Global::openUrl(HELP_URL); } wallch-4.0/src/nongui.cpp0000644000175000017500000033437412301477401014102 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "nongui.h" #include #include #include #include #ifdef ON_WIN32 #include #include #else #include #endif //#ifdef ON_WIN32 #define ARG_NOT_REQ 0 #define ARG_REQ 1 #define ARG_OPT 2 #define UPDATE_STATISTICS_SECONDS_INTERVAL 30000 #define CHECK_INTERNET_INTERVAL 10000 bool nonGUI::alreadyRuns(){ alreadyRunsMem_ = new QSharedMemory("Wallch Memory", this); if(alreadyRunsMem_->attach(QSharedMemory::ReadOnly)){ alreadyRunsMem_->detach(); return true; } if(alreadyRunsMem_->create(1)){ return false; } return false; } void nonGUI::getDelay(){ totalSeconds_=settings->value("delay", DEFAULT_SLIDER_DELAY).toInt(); } void nonGUI::dirChanged(){ if(researchFoldersTimerMain_.isActive()){ researchFoldersTimerMain_.stop(); } researchFoldersTimerMain_.start(RESEARCH_FOLDERS_TIMEOUT); } void nonGUI::resetWatchFolders(bool justDelete){ if(watchFoldersMain_){ delete watchFoldersMain_; } if(!justDelete){ watchFoldersMain_ = new QFileSystemWatcher(this); connect(watchFoldersMain_, SIGNAL(directoryChanged(QString)), this, SLOT(dirChanged())); } } void nonGUI::researchDirs(){ if(researchFoldersTimerMain_.isActive()){ researchFoldersTimerMain_.stop(); } resetWatchFolders(false); if(!getPicturesLocation(false)){ return; } if(gv.randomImagesEnabled){ Global::generateRandomImages(allPictures_.count(), -1); } else { currentImageIndex_=0; //start from the beginning of the new folder } } void nonGUI::getFilesFromFolder(const QString &path){ //this function is for adding files of a monitored folder QDir dir_get_all_pictures; dir_get_all_pictures.setPath(path); dir_get_all_pictures.setFilter(QDir::Files); Q_FOREACH(QString pic, dir_get_all_pictures.entryList(IMAGE_FILTERS)){ allPictures_ << path+"/"+pic; } } void nonGUI::potdSetSameImage(){ Global::debug("Picture Of The Day should already be in your hard drive."); QString filename=Global::getFilename(gv.wallchHomePath+POTD_IMAGE+"*"); if(filename.isEmpty()){ Global::error("Wallch will now attemp to download again the Picture Of The Day."); settings->setValue("last_day_potd_was_set", ""); settings->setValue("previous_img_url", "retry"); settings->sync(); globalParser_->potd(); } Global::setBackground(filename, true, true, 3); } void nonGUI::readPictures(const QString &folder){ /* * This function returns a QStringList with all the needed pictures * for the process from a folder(it reads it recursively)... * Used ONLY with --change */ Global::debug("Wallch is reading pictures from your folder: '"+folder+"'"); //getting all the subfolders of the parent 'file' folder QDir dir_get_all_pictures; dir_get_all_pictures.setFilter(QDir::Files); //looping between the folders and adding each of their images. Q_FOREACH(QString currentFolder, Global::listFolders(folder, true, true)){ dir_get_all_pictures.setPath(currentFolder); Q_FOREACH(QString pic, dir_get_all_pictures.entryList(IMAGE_FILTERS)) allPictures_ << currentFolder+"/"+pic; } if(allPictures_.count() == 0){ globalParser_->desktopNotify(tr("There are not enough valid pictures for the process to continue."), false, "info"); Global::error("Wallch has not enough pictures to continue."); doAction("--stop"); } } bool nonGUI::getPicturesLocation(bool init){ /* * Loads the pictures for the main wallpaper changing process * It loads all the pictures. If once is false, it monitors them, as * well. If 'init' is true, then some initializations will be done, like * connecting the research_folders_timer_main timer to its slot. */ if(!startedWithJustChange_ && init){ resetWatchFolders(false); connect(&researchFoldersTimerMain_, SIGNAL(timeout()), this, SLOT(researchDirs())); } QString parentFolder=getCurrentWallpapersFolder(); if(!QDir(parentFolder).exists()){ globalParser_->desktopNotify(tr("Folder doesn't exist for the process to continue."), false, "info"); return false; } allPictures_.clear(); Q_FOREACH(QString curFolder, Global::listFolders(parentFolder, true, true)){ if(!startedWithJustChange_){ //no need to monitor anything if this instance is for changing the picture just once. if(!watchFoldersMain_){ resetWatchFolders(false); } watchFoldersMain_->addPath(curFolder); } getFilesFromFolder(curFolder); } if(startedWithJustChange_){ if(allPictures_.count() == 0){ globalParser_->desktopNotify(tr("There are not enough valid pictures for the process to continue."), false, "info"); Global::error("Wallch has not enough pictures to continue."); doAction("--stop"); return false; } } else { if(allPictures_.count() < LEAST_WALLPAPERS_FOR_START){ globalParser_->desktopNotify(tr("There are not enough valid pictures for the process to continue."), false, "info"); Global::error("Wallch has not enough pictures to continue."); doAction("--stop"); return false; } } return true; } void showUsage(short exitCode){ Global::debug("Wallch " + QString::number(APP_VERSION, 'f', 1) + "\n"\ "Usage: wallch [OPTION]\n\n"\ "Wallch options:\n"\ "-h/--help Show this help.\n"\ "--change Change desktop background once by picking randomly an image from the list\n"\ "--change[=DIRECTORY] Change desktop background once to the wallpaper at [=DIRECTORY]\n"\ "--start Starts changing pictures from the last used list.\n"\ "--earth Starts live earth, updating every 30 minutes.\n"\ "--potd Starts picture of the day, updating once a day.\n"\ "--clock Starts wallpaper clocks.\n"\ "--website Starts live website.\n"\ "--stop Stops the current process, if it is active.\n"\ "--next Proceeds to the next image, if available.\n"\ "--previous Proceeds to the previous image, if available.\n"\ "--pause Pauses the current process, if the wallpaper changing process is active.\n"\ "--cache DIRECTORY Creates the image cache of the specified directory (recursively).\n"\ "--fcache DIRECTORY Same as --cache but without caring about image cache size.\n"\ "--quit Quits any running instance of wallch.\n "\ "--version Shows current version."); exit(exitCode); } #ifdef ON_LINUX static void stop_fake_callback_main(DbusmenuMenuitem *, guint, gpointer){ nongui.doAction("--stop"); } static void pause_fake_callback_main(DbusmenuMenuitem *, guint, gpointer){ nongui.doAction("--pause"); } static void next_fake_callback_main(DbusmenuMenuitem *, guint, gpointer){ nongui.doAction("--next"); } static void previous_fake_callback_main(DbusmenuMenuitem *, guint, gpointer){ nongui.doAction("--previous"); } static void key_action_next(const char *, void *){ nongui.doAction("--next"); } void nonGUI::setupUnityShortcuts(){ unityMenu_ = dbusmenu_menuitem_new(); gv.unityStopAction = dbusmenu_menuitem_new(); gv.unityPauseAction = dbusmenu_menuitem_new(); gv.unityNextAction = dbusmenu_menuitem_new(); gv.unityPreviousAction = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_LABEL, "Stop"); dbusmenu_menuitem_property_set(gv.unityPauseAction, DBUSMENU_MENUITEM_PROP_LABEL, "Pause"); dbusmenu_menuitem_property_set(gv.unityNextAction, DBUSMENU_MENUITEM_PROP_LABEL, "Next"); dbusmenu_menuitem_property_set(gv.unityPreviousAction, DBUSMENU_MENUITEM_PROP_LABEL, "Previous"); dbusmenu_menuitem_child_append (unityMenu_, gv.unityStopAction); dbusmenu_menuitem_child_append (unityMenu_, gv.unityPauseAction); dbusmenu_menuitem_child_append (unityMenu_, gv.unityNextAction); dbusmenu_menuitem_child_append (unityMenu_, gv.unityPreviousAction); g_signal_connect (gv.unityStopAction, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(&stop_fake_callback_main), (gpointer)this); g_signal_connect (gv.unityPauseAction, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(&pause_fake_callback_main), (gpointer)this); g_signal_connect (gv.unityNextAction, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(&next_fake_callback_main), (gpointer)this); g_signal_connect (gv.unityPreviousAction, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(&previous_fake_callback_main), (gpointer)this); if(!gv.unityLauncherEntry){ gv.unityLauncherEntry = unity_launcher_entry_get_for_desktop_id(APP_DESKTOP_NAME); } unity_launcher_entry_set_quicklist(gv.unityLauncherEntry, unityMenu_); dbusmenu_menuitem_property_set_bool(unityMenu_, DBUSMENU_MENUITEM_PROP_VISIBLE, true); } void nonGUI::setUnityShortcutsState(bool stopState, bool pauseState, bool nextState, bool previousState){ if(gv.unityStopAction){ dbusmenu_menuitem_property_set_bool(gv.unityStopAction, DBUSMENU_MENUITEM_PROP_VISIBLE, stopState); dbusmenu_menuitem_property_set_bool(gv.unityPauseAction, DBUSMENU_MENUITEM_PROP_VISIBLE, pauseState); dbusmenu_menuitem_property_set_bool(gv.unityNextAction, DBUSMENU_MENUITEM_PROP_VISIBLE, nextState); dbusmenu_menuitem_property_set_bool(gv.unityPreviousAction, DBUSMENU_MENUITEM_PROP_VISIBLE, previousState); } } #endif //#ifdef ON_LINUX void nonGUI::waitForInternetConnection(){ Global::debug("Checking for internet connection..."); if (globalParser_->connectedToInternet()){ #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ setupUnityShortcuts(); setUnityShortcutsState(true, false, false, false); } #endif if(gv.potdRunning){ continueWithPotd(false); } else if(gv.liveEarthRunning){ secondsLeft_=LIVEARTH_INTERVAL; continueWithLiveEarth(); } else if(gv.liveWebsiteRunning){ continueWithWebsite(); } } else { Global::error("No internet connection, trying again in "+QString::number(CHECK_INTERNET_INTERVAL/1000)+" secs..."); } } void nonGUI::actionsOnWallpaperChange(){ if(gv.wallpapersRunning) { changeWallpaperNow(); if(gv.randomTimeEnabled){ srand(time(0)); totalSeconds_=secondsLeft_=(rand()%(gv.randomTimeTo-gv.randomTimeFrom+1))+gv.randomTimeFrom; } else if(secondsLeft_<=0) { secondsLeft_=totalSeconds_; } if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(secondsLeft_, 0); } } else if(gv.liveEarthRunning) { globalParser_->livearth(); secondsLeft_=totalSeconds_; if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(secondsLeft_, 1); } } else if(gv.liveWebsiteRunning) { websiteSnapshot_->start(); secondsLeft_=totalSeconds_; if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(secondsLeft_, 2); } } else if(gv.wallpaperClocksRunning) { QString currentWallpaperClock = Global::wallpaperClockNow(gv.defaultWallpaperClock, wallpaperClocksMinutesChecked_, wallpaperClocksHourChecked_, wallpaperClocksAmPmChecked_, wallpaperClocksDayOfWeekChecked_, wallpaperClocksDayOfMonthChecked_ , wallpaperClocksMonthChecked_ ); if(gv.setAverageColor){ Global::setAverageColor(currentWallpaperClock); } secondsLeft_=totalSeconds_=wallpaperClocksTotalSeconds_; } } void nonGUI::updateSeconds(){ /* * This function runs once a second and reduces * the timeout_count, which, once 0, will update * the desktop background... */ gv.runningTimeOfProcess = QDateTime::currentDateTime(); if(secondsLeft_<=0){ actionsOnWallpaperChange(); gv.timeToFinishProcessInterval = gv.runningTimeOfProcess.addSecs(secondsLeft_); } else { if(secondsLeft_!=gv.runningTimeOfProcess.secsTo(gv.timeToFinishProcessInterval)) { int secs_to_changing_time = gv.runningTimeOfProcess.secsTo(gv.timeToFinishProcessInterval); if(secs_to_changing_time<0) { actionsOnWallpaperChange(); gv.timeToFinishProcessInterval = gv.runningTimeOfProcess.addSecs(secondsLeft_); } else if (!(gv.wallpaperClocksRunning&& (secondsLeft_-secs_to_changing_time<-1 || secondsLeft_-secs_to_changing_time>1))){ secondsLeft_=secs_to_changing_time; } } } #ifdef ON_LINUX if(gv.unityProgressbarEnabled && gv.currentDE==UnityGnome){ Global::setUnityProgressbarValue((float) secondsLeft_/totalSeconds_); } #endif secondsLeft_--; } void nonGUI::checkPicOfDay(){ if(Global::timeNowToString()=="00:00"){ if(justUpdatedPotd_) { return; } QString lastDaySet=settings->value("last_day_potd_was_set", "").toString(); QString dateTimeNow = QDateTime::currentDateTime().toString("dd.MM.yyyy"); if(settings->value("potd_preferences_have_changed", false).toBool() || dateTimeNow!=lastDaySet){ justUpdatedPotd_=true; globalParser_->potd(); } else { //the day is the same, setting the same image. potdSetSameImage(); } } else { justUpdatedPotd_=false; //time has yet to be reached! if(this->isSingleShot()){ if(this->isActive()){ this->stop(); } //back to normal this->start(59500); } } #ifdef ON_LINUX updatePotdProgressMain(); #endif } #ifdef ON_LINUX void nonGUI::updatePotdProgressMain(){ if(gv.currentDE==UnityGnome && gv.unityProgressbarEnabled){ Global::setUnityProgressbarValue((float) (Global::getSecondsTillHour("00:00")/86400.0)); } } #endif //#ifdef ON_LINUX void nonGUI::connectToUpdateSecondsSlot(){ if(gv.potdRunning){ connect(this, SIGNAL(timeout()), this, SLOT(checkPicOfDay())); } else { connect(this, SIGNAL(timeout()), this, SLOT(updateSeconds())); } #ifdef ON_LINUX if(gv.currentDE==UnityGnome && gv.unityProgressbarEnabled){ Global::setUnityProgressBarEnabled(true); } #endif } void nonGUI::disconnectFromSlot(){ disconnect(this, 0, this, 0); } void nonGUI::connectToCheckInternet(){ connect(this, SIGNAL(timeout()), this, SLOT(waitForInternetConnection())); } void nonGUI::continueWithLiveEarth(){ this->disconnectFromSlot(); this->connectToUpdateSecondsSlot(); this->connectToServer(); totalSeconds_=LIVEARTH_INTERVAL; if(!gv.firstTimeout){ globalParser_->livearth(); } if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(totalSeconds_, 1); } this->start(1000); } void nonGUI::continueWithWebsite(){ this->disconnectFromSlot(); this->connectToUpdateSecondsSlot(); this->connectToServer(); //getting the required values from the settings... QDesktopWidget wid; gv.screenWidth=wid.width(); gv.screenHeight=wid.height(); gv.websiteWebpageToLoad=settings->value("website", "http://google.com").toString(); gv.websiteInterval=settings->value("website_interval", 6).toInt(); gv.websiteCropEnabled=settings->value("website_crop", false).toBool(); gv.websiteCropArea=settings->value("website_crop_area", QRect(0, 0, gv.screenWidth, gv.screenHeight)).toRect(); gv.websiteLoginEnabled=settings->value("website_login", false).toBool(); gv.websiteLoginUsername=settings->value("website_username", "").toString(); gv.websiteLoginPasswd=settings->value("website_password", "").toString(); if(!gv.websiteLoginPasswd.isEmpty()){ gv.websiteLoginPasswd=Global::base64Decode(gv.websiteLoginPasswd); } gv.websiteRedirect=settings->value("website_redirect", false).toBool(); gv.websiteFinalPageToLoad=settings->value("website_final_webpage", "").toString(); gv.websiteSimpleAuthEnabled=settings->value("website_simple_auth", false).toBool(); gv.websiteWaitAfterFinishSeconds=settings->value("website_wait_after_finish", 3).toInt(); gv.websiteJavascriptEnabled=settings->value("website_js_enabled", true).toBool(); gv.websiteJavascriptCanReadClipboard=settings->value("website_js_can_read_clipboard", false).toBool(); gv.websiteJavaEnabled=settings->value("website_java_enabled", false).toBool(); gv.websiteLoadImages=settings->value("website_load_images", true).toBool(); gv.websiteExtraUsernames=settings->value("website_extra_usernames", QStringList()).toStringList(); gv.websiteExtraPasswords=settings->value("website_extra_passwords", QStringList()).toStringList(); websiteSnapshot_->setParameters(QUrl(gv.websiteWebpageToLoad), gv.screenWidth, gv.screenHeight); websiteSnapshot_->setWaitAfterFinish(gv.websiteWaitAfterFinishSeconds); websiteSnapshot_->setJavascriptConfig(gv.websiteJavascriptEnabled, gv.websiteJavascriptCanReadClipboard); websiteSnapshot_->setJavaEnabled(gv.websiteJavaEnabled); websiteSnapshot_->setLoadImagesEnabled(gv.websiteLoadImages); websiteSnapshot_->setCrop(gv.websiteCropEnabled, gv.websiteCropArea); if(gv.websiteLoginEnabled){ if(!gv.websiteRedirect || gv.websiteFinalPageToLoad.isEmpty()){ gv.websiteFinalPageToLoad=gv.websiteWebpageToLoad; } if(gv.websiteSimpleAuthEnabled){ websiteSnapshot_->setSimpleAuthentication(gv.websiteLoginUsername, gv.websiteLoginPasswd, gv.websiteFinalPageToLoad); } else { if(gv.websiteExtraUsernames.count()>0 || gv.websiteExtraPasswords.count()>0) { websiteSnapshot_->setComplexAuthenticationWithPossibleFields(gv.websiteLoginUsername, gv.websiteLoginPasswd, gv.websiteFinalPageToLoad, gv.websiteExtraUsernames, gv.websiteExtraPasswords, true); } else { websiteSnapshot_->setComplexAuthentication(gv.websiteLoginUsername, gv.websiteLoginPasswd, gv.websiteFinalPageToLoad); } } } else { websiteSnapshot_->disableAuthentication(); } websiteSnapshot_->setTimeout(WEBSITE_TIMEOUT); totalSeconds_=Global::websiteSliderValueToSeconds(gv.websiteInterval); if(!gv.firstTimeout){ websiteSnapshot_->start(); } if(!secondsLeft_){ secondsLeft_=totalSeconds_; } Global::resetSleepProtection(secondsLeft_); if(gv.independentIntervalEnabled){ Global::saveSecondsLeftNow(secondsLeft_, 2); } #ifdef ON_LINUX Global::changeIndicatorSelection("website"); #endif //#ifdef ON_LINUX this->start(1000); } bool nonGUI::continueWithClock(){ gv.defaultWallpaperClock=settings->value("default_wallpaper_clock","").toString(); if(gv.defaultWallpaperClock.isEmpty() || gv.defaultWallpaperClock=="None" ) { globalParser_->desktopNotify(tr("No default wallpaper clock has been set."), false, "info"); Global::error("No default wallpaper clock has been set. Make sure that after installing the wallpaper clock you have clicked at set as default."); return false; } else if(!QFile::exists(gv.defaultWallpaperClock)) { globalParser_->desktopNotify(tr("The default wallpaper clock does not exist"), false, "info"); Global::error("Default wallpaper clock does not exist. Make sure the wallpaper clock is installed properly."); return false; } Global::readClockIni(gv.defaultWallpaperClock); wallpaperClocksMonthChecked_=settings->value("month",true).toBool(); wallpaperClocksDayOfMonthChecked_=settings->value("day_of_month",true).toBool(); wallpaperClocksDayOfWeekChecked_=settings->value("day_of_week",true).toBool(); wallpaperClocksAmPmChecked_=settings->value("am_pm",true).toBool(); wallpaperClocksHourChecked_=settings->value("hour",true).toBool(); wallpaperClocksMinutesChecked_=settings->value("minute",true).toBool(); QString wall_clock = Global::wallpaperClockNow(gv.defaultWallpaperClock, wallpaperClocksMinutesChecked_, wallpaperClocksHourChecked_, wallpaperClocksAmPmChecked_, wallpaperClocksDayOfWeekChecked_, wallpaperClocksDayOfMonthChecked_ , wallpaperClocksMonthChecked_ ); if(gv.setAverageColor){ Global::setAverageColor(wall_clock); } QTime time = QTime::currentTime(); float seconds_left_for_min=time.secsTo(QTime(time.hour(),time.minute()+1,1)); if(settings->value("minute",true).toBool()){ wallpaperClocksTotalSeconds_=60; } else if (settings->value("hour",true).toBool()){ wallpaperClocksTotalSeconds_=gv.refreshhourinterval; } else if(settings->value("am_pm",true).toBool() && gv.amPmEnabled){ wallpaperClocksTotalSeconds_=43200; } else if(settings->value("day_of_week",true).toBool() || settings->value("day_of_month",true).toBool() || settings->value("month",true).toBool()){ wallpaperClocksTotalSeconds_=86400; } this->connectToUpdateSecondsSlot(); this->connectToServer(); if(settings->value("minute",true).toBool()) { secondsLeft_=seconds_left_for_min; } else if(settings->value("hour",true).toBool()) { secondsLeft_=(((QString::number(time.minute()/gv.refreshhourinterval).toInt()+1)*gv.refreshhourinterval-time.minute()-1)*60+seconds_left_for_min); } else if(settings->value("am_pm",true).toBool() && gv.amPmEnabled) { float seconds_left_for_am_pm=0; if (time.hour()>=12){ seconds_left_for_am_pm=time.secsTo(QTime(23,59,59))+2; } else{ seconds_left_for_am_pm=time.secsTo(QTime(12,0,1)); } secondsLeft_=seconds_left_for_am_pm; } else if(settings->value("day_of_week",true).toBool() || settings->value("day_of_month",true).toBool()) { float seconds_left_for_next_day=time.secsTo(QTime(23,59,59))+2; secondsLeft_=seconds_left_for_next_day; } else if(settings->value("month",true).toBool()) { float seconds_left_for_next_day=time.secsTo(QTime(23,59,59))+2; secondsLeft_=seconds_left_for_next_day; } else { globalParser_->desktopNotify(tr("At least one option (month, hour etc) must be selected for wallpaper clock to start."), false, "info"); Global::error("At least one option (month, hour etc) must be selected for wallpaper clock to start."); return false; } totalSeconds_=secondsLeft_; gv.runningTimeOfProcess=QDateTime::currentDateTime(); gv.timeToFinishProcessInterval = gv.runningTimeOfProcess.addSecs(secondsLeft_); gv.potdRunning=gv.liveEarthRunning=gv.liveWebsiteRunning=gv.wallpapersRunning=false; gv.wallpaperClocksRunning=true; Global::updateStartup(); if(this->isActive()){ this->stop(); } this->disconnectFromSlot(); this->connectToUpdateSecondsSlot(); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ if(gv.unityProgressbarEnabled){ Global::setUnityProgressBarEnabled(true); } } Global::changeIndicatorSelection("clocks"); #endif //#ifdef ON_LINUX this->start(1000); return true; } void nonGUI::continueWithPotd(bool checkInternetConnection){ if(checkInternetConnection){ Global::debug("Checking for internet connection..."); if (!globalParser_->connectedToInternet()){ //will check every 3 secs if there's internet connection... this->disconnectFromSlot(); this->connectToCheckInternet(); this->start(CHECK_INTERNET_INTERVAL); return; } } this->disconnectFromSlot(); this->connectToUpdateSecondsSlot(); this->connectToServer(); //yearmonthday contains the last time that picture of the day was changed... QString lastDaySet=settings->value("last_day_potd_was_set", "").toString(); QString dateTimeNow = QDateTime::currentDateTime().toString("dd.MM.yyyy"); if(settings->value("potd_preferences_have_changed", false).toBool() || dateTimeNow!=lastDaySet){ //the previous time that potd changes was another day globalParser_->potd(); } else { potdSetSameImage(); } #ifdef ON_LINUX updatePotdProgressMain(); Global::changeIndicatorSelection("potd"); gv.doNotToggleRadiobuttonFallback=false; #endif //#ifdef ON_LINUX this->start(59500); } void nonGUI::connectToServer() { localServer_ = new QLocalServer(this); if(!localServer_->listen(QString(SOCKET_SERVER_NAME))){ #ifdef ON_LINUX //if not in windows, remove the socket and retry... QLocalServer::removeServer(QString(SOCKET_SERVER_NAME)); if(!localServer_->listen(QString(SOCKET_SERVER_NAME))){ Global::error("Could not connect to the local socket server."); return; } #else //if in windows, there doesn't seem to be a solution Global::error("Could not connect to the local socket server."); return; #endif //#ifdef ON_LINUX } connect(localServer_, SIGNAL(newConnection()), this, SLOT(newSocketConnection())); } void nonGUI::newSocketConnection(){ QLocalSocket *clientConnection = localServer_->nextPendingConnection(); while (clientConnection->bytesAvailable() < (int)sizeof(quint32)){ qApp->processEvents(QEventLoop::AllEvents); clientConnection->waitForReadyRead(); } connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater())); QDataStream in(clientConnection); in.setVersion(QDataStream::Qt_5_0); if (clientConnection->bytesAvailable() < (int)sizeof(quint16)) { return; } QString message; in >> message; doAction(message); } void nonGUI::messageServer(const QString &message, bool quitAfterwards){ messageToSendToServer_=message; quitAfterMessage_=quitAfterwards; socket_ = new QLocalSocket(this); socket_->abort(); connect(socket_, SIGNAL(connected()), this, SLOT(socketConnected())); connect(socket_, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(socketError())); socket_->connectToServer(QString(SOCKET_SERVER_NAME)); } void nonGUI::socketError(){ Global::error("The message '"+messageToSendToServer_+"' could not be sent to Wallch."); if(quitAfterMessage_){ Global::debug("Assuming that the previous Wallch instance crashed and starting a new one now. Sorry for this :)"); connectToServer(); #ifdef ON_LINUX setupIndicator(); if(gv.currentDE==UnityGnome){ setupUnityShortcuts(); } #else setupTray(); #endif //#ifdef ON_LINUX mainWindowLaunched_=true; MainWindow *w = new MainWindow(globalParser_, websiteSnapshot_, 0, QStringList(""), 0, 0); connectMainwindowWithExternalActions(w); w->show(); } } void nonGUI::socketConnected(){ QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_0); out << messageToSendToServer_; out.device()->seek(0); socket_->write(block); socket_->flush(); if(quitAfterMessage_){ QTimer::singleShot(100, Qt::CoarseTimer, this, SLOT(quitNow())); } } void nonGUI::quitNow(){ qApp->exit(0); } void nonGUI::changeWallpaperNow(){ int all_count=allPictures_.count(); if(all_count < LEAST_WALLPAPERS_FOR_START && !startedWithJustChange_){ Global::error("Could not get pictures or not enough pictures.\nPlease select pictures from Wallch's main window and try again. The program will now exit."); globalParser_->desktopNotify(tr("There are not enough valid pictures for the process to continue."), false, "info"); return; } if(previousWasClicked_ && previousPictures_.count()>1){ previousWasClicked_=false; QString picture=previousPictures_.at(previousPictures_.count()-2); previousPictures_.removeLast(); if(!QFile::exists(picture) || QImage(picture).isNull()){ Global::error("Previous image not existent or invalid! Skipping..."); return; } Global::setBackground(picture, true, true, 1); } else { if(gv.randomImagesEnabled){ currentImageIndex_=gv.randomImages[gv.currentRandomImageIndex]; gv.currentRandomImageIndex++; if(gv.currentRandomImageIndex>=all_count){ //the loop has ended... Global::generateRandomImages(all_count, -1); } } if(currentImageIndex_ >= all_count){ return;//preventing crash in any case } if(!startedWithJustChange_){ int valid_images_limit=0; while(!QFile::exists(allPictures_.at(currentImageIndex_)) || QImage(allPictures_.at(currentImageIndex_)).isNull()) { if(gv.randomImagesEnabled){ gv.currentRandomImageIndex++; if(gv.currentRandomImageIndex >= all_count){ gv.currentRandomImageIndex=0; } currentImageIndex_=gv.randomImages[gv.currentRandomImageIndex]; } else { currentImageIndex_++; if(currentImageIndex_ >= all_count){ currentImageIndex_=0; } } if(valid_images_limit++ == 30){ //too many invalid images! globalParser_->desktopNotify(tr("There are not enough valid pictures for the process to continue."), false, "info"); QApplication::quit(); } } } QString pic_now=allPictures_.at(currentImageIndex_); Global::setBackground(pic_now, true, true, 1); if(!startedWithJustChange_){ Global::addPreviousBackground(previousPictures_, pic_now); } if(!gv.randomImagesEnabled){ currentImageIndex_++; if(currentImageIndex_>=all_count){ currentImageIndex_=0; } } } } #ifdef ON_LINUX gboolean indicator_is_scrolled(AppIndicator *, gshort *, gushort direction, gpointer *){ if(!gv.wallpapersRunning){ return false; } if(nongui.indicatorScrollTimer_.isActive()){ return false; //you have to wait for the timeout to finish in order to do another change } switch(direction){ case 0: nongui.doAction("--previous"); break; case 1: nongui.doAction("--next"); break; default: break; } nongui.indicatorScrollTimer_.start(INDICATOR_SCROLL_INTERVAL); return false; } void nonGUI::indicatorBackToNormal(){ changeIndicatorIcon(gv.currentTheme); } void nonGUI::changeIndicatorIcon(QString theme){ if(theme=="ambiance"){ app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_AMBIANCE_NORMAL, INDICATOR_DESCRIPTION); } else { app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_RADIANCE_NORMAL, INDICATOR_DESCRIPTION); } } void show_app_callback(guint, gpointer *){ nongui.doAction("--focus"); } void copy_path_current_image_callback(guint, gpointer *){ QApplication::clipboard()->setText(Global::currentBackgroundImage()); } void copy_name_current_image_callback(guint, gpointer *){ QApplication::clipboard()->setText(Global::basenameOf(Global::currentBackgroundImage())); } void open_folder_current_image_callback(guint, gpointer *){ Global::openFolderOf(""); } void delete_current_image_callback(guint, gpointer *){ nongui.doAction("--delete-current"); } void properties_current_image_callback(guint, gpointer *){ nongui.doAction("--properties"); } void wallpapers_pause_callback(guint, gpointer *){ nongui.doAction("--pause"); } void wallpapers_just_change_callback(guint, gpointer *){ nongui.doAction("--change"); } void wallpapers_next_callback(guint, gpointer *){ nongui.doAction("--next"); } void wallpapers_previous_callback(guint, gpointer *){ nongui.doAction("--previous"); } void start_pictures_callback(GtkCheckMenuItem *checkmenuitem, gpointer){ if(gtk_check_menu_item_get_active(checkmenuitem)){ if(gv.doNotToggleRadiobuttonFallback){ gv.doNotToggleRadiobuttonFallback=false; return; } nongui.doAction("--start"); return; } } void stop_everything_callback(GtkCheckMenuItem *checkmenuitem, gpointer){ if(gtk_check_menu_item_get_active(checkmenuitem)){ if(gv.doNotToggleRadiobuttonFallback){ gv.doNotToggleRadiobuttonFallback=false; return; } nongui.doAction("--stop"); return; } } void next_pictures_main(guint, gpointer *){ nongui.doAction("--next"); } void previous_pictures_mainf(guint, gpointer *){ nongui.doAction("--previous"); } void activatelivearth_callback(GtkCheckMenuItem *checkmenuitem, gpointer){ if(gtk_check_menu_item_get_active(checkmenuitem)){ if(gv.doNotToggleRadiobuttonFallback){ gv.doNotToggleRadiobuttonFallback=false; return; } nongui.doAction("--earth"); return; } } void deactivatelivearth_main(guint, gpointer *){ nongui.doAction("--stop"); } void activatephotoofday_callback(GtkCheckMenuItem *checkmenuitem, gpointer){ if(gtk_check_menu_item_get_active(checkmenuitem)){ if(gv.doNotToggleRadiobuttonFallback){ gv.doNotToggleRadiobuttonFallback=false; return; } nongui.doAction("--potd"); return; } } void deactivatephotoofday_main(guint, gpointer *){ nongui.doAction("--stop"); } void activatewallpaperclocks_callback(GtkCheckMenuItem *checkmenuitem, gpointer){ if(gtk_check_menu_item_get_active(checkmenuitem)){ if(gv.doNotToggleRadiobuttonFallback){ gv.doNotToggleRadiobuttonFallback=false; return; } nongui.doAction("--clock"); return; } } void deactivatewallpaperclocks_main(guint, gpointer *){ nongui.doAction("--stop"); } void activatelivewebsite_callback(GtkCheckMenuItem *checkmenuitem, gpointer){ if(gtk_check_menu_item_get_active(checkmenuitem)){ if(gv.doNotToggleRadiobuttonFallback){ gv.doNotToggleRadiobuttonFallback=false; return; } nongui.doAction("--website"); return; } } void deactivatelivewebsite_main(guint, gpointer *){ nongui.doAction("--stop"); } void indicator_quit_app_main(guint, gpointer *){ nongui.doAction("--quit"); } void indicator_preferences_main(guint, gpointer *){ nongui.doAction("--preferences"); } void indicator_about_main(guint, gpointer *){ nongui.doAction("--about"); } void nonGUI::setupIndicator(){ gv.currentTheme=settings->value("theme", "autodetect").toString(); if(gv.currentTheme=="autodetect"){ if(Global::gsettingsGet("org.gnome.desktop.interface", "gtk-theme")=="Ambiance"){ gv.currentTheme="ambiance"; } else { gv.currentTheme="radiance"; } } if(gv.currentTheme=="ambiance"){ gv.applicationIndicator = app_indicator_new(INDICATOR_DESCRIPTION, INDICATOR_AMBIANCE_NORMAL, APP_INDICATOR_CATEGORY_APPLICATION_STATUS); app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_AMBIANCE_NORMAL, INDICATOR_DESCRIPTION); } else { gv.applicationIndicator = app_indicator_new(INDICATOR_DESCRIPTION, INDICATOR_RADIANCE_NORMAL, APP_INDICATOR_CATEGORY_APPLICATION_STATUS); app_indicator_set_icon_full(gv.applicationIndicator, INDICATOR_RADIANCE_NORMAL, INDICATOR_DESCRIPTION); } //main menu GtkWidget* indicatormenu = gtk_menu_new(); //show app option showAppOption_ = gtk_menu_item_new_with_label(tr("Show").toLocal8Bit().data()); g_signal_connect(showAppOption_, "activate", G_CALLBACK(show_app_callback), this); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), showAppOption_); //current image submenu GtkWidget *currentImageSubmenu_main = gtk_menu_new(); GtkWidget *currentImageSubmenuItem_main = gtk_menu_item_new_with_label(tr("Current Image").toLocal8Bit().data()); gtk_menu_item_set_submenu(GTK_MENU_ITEM(currentImageSubmenuItem_main), currentImageSubmenu_main); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), currentImageSubmenuItem_main); copyPathOfCurImageOption_ = gtk_menu_item_new_with_label(tr("Copy Path").toLocal8Bit().data()); g_signal_connect(copyPathOfCurImageOption_, "activate", G_CALLBACK(copy_path_current_image_callback), this); gtk_menu_shell_append(GTK_MENU_SHELL(currentImageSubmenu_main), copyPathOfCurImageOption_); copyNameOfCurImageOption_ = gtk_menu_item_new_with_label(tr("Copy Name").toLocal8Bit().data()); g_signal_connect(copyNameOfCurImageOption_, "activate", G_CALLBACK(copy_name_current_image_callback), this); gtk_menu_shell_append(GTK_MENU_SHELL(currentImageSubmenu_main), copyNameOfCurImageOption_); openPathOfCurImageOption_ = gtk_menu_item_new_with_label(tr("Open Folder").toLocal8Bit().data()); g_signal_connect(openPathOfCurImageOption_, "activate", G_CALLBACK(open_folder_current_image_callback), this); gtk_menu_shell_append(GTK_MENU_SHELL(currentImageSubmenu_main), openPathOfCurImageOption_); deleteCurImageOption_ = gtk_menu_item_new_with_label(tr("Delete").toLocal8Bit().data()); g_signal_connect(deleteCurImageOption_, "activate", G_CALLBACK(delete_current_image_callback), this); gtk_menu_shell_append(GTK_MENU_SHELL(currentImageSubmenu_main), deleteCurImageOption_); propertiesOfCurImageOption_ = gtk_menu_item_new_with_label(tr("Properties").toLocal8Bit().data()); g_signal_connect(propertiesOfCurImageOption_, "activate", G_CALLBACK(properties_current_image_callback), this); gtk_menu_shell_append(GTK_MENU_SHELL(currentImageSubmenu_main), propertiesOfCurImageOption_); //separator gtk_menu_shell_append ( GTK_MENU_SHELL (indicatormenu), gtk_separator_menu_item_new()); GSList *indicatorRadiobuttonsList = NULL; gv.wallpapersRadiobutton = gtk_radio_menu_item_new_with_label(indicatorRadiobuttonsList, tr("Wallpapers").toLocal8Bit().data()); indicatorRadiobuttonsList=gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (gv.wallpapersRadiobutton)); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), gv.wallpapersRadiobutton); gv.wallpapersJustChange = gtk_menu_item_new_with_label(QString(" "+tr("Change wallpaper once")).toLocal8Bit().data()); g_signal_connect(gv.wallpapersJustChange, "activate", G_CALLBACK(wallpapers_just_change_callback), this); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), gv.wallpapersJustChange); gv.wallpapersPlayPause = gtk_menu_item_new_with_label(QString(" "+tr("Pause")).toLocal8Bit().data()); g_signal_connect(gv.wallpapersPlayPause, "activate", G_CALLBACK(wallpapers_pause_callback), this); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), gv.wallpapersPlayPause); gv.wallpapersNext = gtk_menu_item_new_with_label(QString(" "+tr("Next")).toLocal8Bit().data()); g_signal_connect(gv.wallpapersNext, "activate", G_CALLBACK(wallpapers_next_callback), this); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), gv.wallpapersNext); gv.wallpapersPrevious = gtk_menu_item_new_with_label(QString(" "+tr("Previous")).toLocal8Bit().data()); g_signal_connect(gv.wallpapersPrevious, "activate", G_CALLBACK(wallpapers_previous_callback), this); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), gv.wallpapersPrevious); gv.liveEarthRadiobutton = gtk_radio_menu_item_new_with_label(indicatorRadiobuttonsList, tr("Live Earth").toLocal8Bit().data()); indicatorRadiobuttonsList=gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (gv.liveEarthRadiobutton)); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), gv.liveEarthRadiobutton); gv.potdRadiobutton = gtk_radio_menu_item_new_with_label(indicatorRadiobuttonsList, tr("Picture Of The Day").toLocal8Bit().data()); indicatorRadiobuttonsList=gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (gv.potdRadiobutton)); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), gv.potdRadiobutton); gv.wallpaperClocksRadiobutton = gtk_radio_menu_item_new_with_label(indicatorRadiobuttonsList, tr("Wallpaper Clocks").toLocal8Bit().data()); indicatorRadiobuttonsList=gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (gv.wallpaperClocksRadiobutton)); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), gv.wallpaperClocksRadiobutton); gv.liveWebsiteRadiobutton = gtk_radio_menu_item_new_with_label(indicatorRadiobuttonsList, tr("Live Website").toLocal8Bit().data()); indicatorRadiobuttonsList=gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (gv.liveWebsiteRadiobutton)); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), gv.liveWebsiteRadiobutton); gv.iAmNotThere = gtk_radio_menu_item_new_with_label(indicatorRadiobuttonsList, "null"); indicatorRadiobuttonsList=gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (gv.iAmNotThere)); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), gv.iAmNotThere); /* * Decide what will be checked has to be done prior to connecting signals so as * not to emit any because of the set_active process */ if(gv.wallpapersRunning){ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.wallpapersRadiobutton), TRUE); } else if(gv.liveEarthRunning){ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.liveEarthRadiobutton), TRUE); } else if(gv.potdRunning){ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.potdRadiobutton), TRUE); } else if(gv.wallpaperClocksRunning){ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.wallpaperClocksRadiobutton), TRUE); } else if(gv.liveWebsiteRunning){ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.liveWebsiteRadiobutton), TRUE); } else { gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gv.iAmNotThere), TRUE); } //connecting radiobuttons with their functions //this is the only radiobutton that needs the activate signal rather than the toggled one, because we want it to react as "stop" as well g_signal_connect(gv.wallpapersRadiobutton, "activate", G_CALLBACK(start_pictures_callback), this); g_signal_connect(gv.liveEarthRadiobutton, "activate", G_CALLBACK(activatelivearth_callback), this); g_signal_connect(gv.potdRadiobutton, "activate", G_CALLBACK(activatephotoofday_callback), this); g_signal_connect(gv.wallpaperClocksRadiobutton, "activate", G_CALLBACK(activatewallpaperclocks_callback), this); g_signal_connect(gv.liveWebsiteRadiobutton, "activate", G_CALLBACK(activatelivewebsite_callback), this); //separator gtk_menu_shell_append ( GTK_MENU_SHELL (indicatormenu), gtk_separator_menu_item_new()); //preferences option showPreferencesOption_ = gtk_menu_item_new_with_label(tr("Preferences").toLocal8Bit().data()); g_signal_connect(showPreferencesOption_, "activate", G_CALLBACK(indicator_preferences_main), this); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), showPreferencesOption_); //about option showAboutOption_ = gtk_menu_item_new_with_label(tr("About").toLocal8Bit().data()); g_signal_connect(showAboutOption_, "activate", G_CALLBACK(indicator_about_main), this); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), showAboutOption_); //quit option quitAppOption_ = gtk_menu_item_new_with_label(tr("Quit").toLocal8Bit().data()); g_signal_connect(quitAppOption_, "activate", G_CALLBACK(indicator_quit_app_main), this); gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), quitAppOption_); g_signal_connect(G_OBJECT(gv.applicationIndicator), "scroll-event", G_CALLBACK(&indicator_is_scrolled), (gpointer)this); app_indicator_set_status(gv.applicationIndicator, APP_INDICATOR_STATUS_ACTIVE); gtk_widget_show_all(indicatormenu); gtk_widget_hide(gv.iAmNotThere); gtk_widget_hide(gv.wallpapersJustChange); if(!gv.wallpapersRunning){ Global::showWallpapersIndicatorControls(false, true); } app_indicator_set_menu(gv.applicationIndicator, GTK_MENU (indicatormenu)); indicatorScrollTimer_.setSingleShot(true); connect(&indicatorScrollTimer_, SIGNAL(timeout()), this, SLOT(indicatorBackToNormal())); } #ifdef ON_LINUX void nonGUI::unityProgressbarSetEnabled(bool enabled){ if(this->isActive()){ Global::setUnityProgressBarEnabled(enabled); if(enabled){ Global::setUnityProgressbarValue(0); } } } #endif //#ifdef ON_LINUX #else //System tray icon Code void nonGUI::setupTray() { showWindowAction_ = new QAction(tr("Show"), this); connect(showWindowAction_, SIGNAL(triggered()), this, SLOT(trayActionShowWindow())); copyCurrentImagePathAction_ = new QAction(tr("Copy Path"), this); connect(copyCurrentImagePathAction_, SIGNAL(triggered()), this, SLOT(trayActionCopyPath())); copyCurrentImageNameAction_ = new QAction(tr("Copy Name"), this); connect(copyCurrentImageNameAction_, SIGNAL(triggered()), this, SLOT(trayActionCopyName())); copyCurrentImageAction_ = new QAction(tr("Copy Image"), this); connect(copyCurrentImageAction_, SIGNAL(triggered()), this, SLOT(trayActionCopyImage())); openCurrentImageFolderAction_ = new QAction(tr("Show In File Browser"), this); connect(openCurrentImageFolderAction_, SIGNAL(triggered()), this, SLOT(trayActionOpenCurrentImageFolder())); deleteCurrentImageAction_ = new QAction(tr("Delete"), this); connect(deleteCurrentImageAction_, SIGNAL(triggered()), this, SLOT(trayActionDeleteCurrentImage())); openCurrentImagePropertiesAction_ = new QAction(tr("Properties"), this); connect(openCurrentImagePropertiesAction_, SIGNAL(triggered()), this, SLOT(trayActionOpenCurrentImageProperties())); wallpapersAction_ = new QAction(tr("Wallpapers"), this); connect(wallpapersAction_, SIGNAL(triggered()), this, SLOT(trayActionWallpapers())); wallpapersOnceAction_ = new QAction(" "+tr("Change wallpaper once"), this); connect(wallpapersOnceAction_, SIGNAL(triggered()), this, SLOT(trayActionWallpapersOnce())); wallpapersPauseAction_ = new QAction(" "+tr("Pause"), this); connect(wallpapersPauseAction_, SIGNAL(triggered()), this, SLOT(trayActionWallpapersPause())); wallpapersNextAction_ = new QAction(" "+tr("Next"), this); connect(wallpapersNextAction_, SIGNAL(triggered()), this, SLOT(trayActionWallpapersNext())); wallpapersPreviousAction_ = new QAction(" "+tr("Previous"), this); connect(wallpapersPreviousAction_, SIGNAL(triggered()), this, SLOT(trayActionWallpapersPrevious())); liveEarthAction_ = new QAction(tr("Live Earth"), this); connect(liveEarthAction_, SIGNAL(triggered()), this, SLOT(trayActionLiveEarth())); pictureOfTheDayAction_ = new QAction(tr("Picture Of The Day"), this); connect(pictureOfTheDayAction_, SIGNAL(triggered()), this, SLOT(trayActionPictureOfTheDay())); wallpaperClocksAction_ = new QAction(tr("Wallpaper Clocks"), this); connect(wallpaperClocksAction_, SIGNAL(triggered()), this, SLOT(trayActionWallpaperClocks())); liveWebsiteAction_ = new QAction(tr("Live Website"), this); connect(liveWebsiteAction_, SIGNAL(triggered()), this, SLOT(trayActionLiveWebsite())); preferencesAction_ = new QAction(tr("Preferences"), this); connect(preferencesAction_, SIGNAL(triggered()), this, SLOT(trayActionPreferences())); aboutAction_ = new QAction(tr("About"), this); connect(aboutAction_, SIGNAL(triggered()), this, SLOT(trayActionAbout())); quitAction_ = new QAction(tr("Exit"), this); connect(quitAction_, SIGNAL(triggered()), this, SLOT(trayActionQuit())); doubleClick_ = new QTimer(this); connect(doubleClick_, SIGNAL(timeout()), this, SLOT(trayActionWallpapersNext())); doubleClick_->setSingleShot(true); trayIconMenu_ = new QMenu(); createTray(); trayIcon_ = new QSystemTrayIcon(this); trayIcon_->setContextMenu(trayIconMenu_); connect(trayIcon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayActivatedActions(QSystemTrayIcon::ActivationReason))); trayIcon_->setIcon(QIcon(":/icons/Pictures/wallch.png")); trayIcon_->show(); } void nonGUI::trayActivatedActions(QSystemTrayIcon::ActivationReason reason) { if(reason==2) //double-click, show window { doubleClick_->stop(); doAction("--focus"); } else if(reason==3){//single-click, wait to see if user double clicks, else next image int double_click_time = GetDoubleClickTime(); doubleClick_->start(double_click_time); } else if(reason==4) //middle-click, next image { doAction("--next"); } } void nonGUI::createTray() { trayIconMenu_->clear(); trayIconMenu_->addAction(showWindowAction_); currentImageMenu_ = new QMenu("Current Image"); currentImageMenu_->addAction(copyCurrentImagePathAction_); currentImageMenu_->addAction(copyCurrentImageNameAction_); currentImageMenu_->addAction(copyCurrentImageAction_); currentImageMenu_->addAction(openCurrentImageFolderAction_); currentImageMenu_->addAction(deleteCurrentImageAction_); currentImageMenu_->addAction(openCurrentImagePropertiesAction_); trayIconMenu_->addMenu(currentImageMenu_); trayIconMenu_->addSeparator(); trayIconMenu_->addAction(wallpapersAction_); if(!gv.wallpapersRunning) trayIconMenu_->addAction(wallpapersOnceAction_); if(gv.wallpapersRunning) { wallpapersAction_->setCheckable(true); wallpapersAction_->setChecked(true); if(gv.processPaused){ wallpapersPauseAction_->setText(" "+tr("Start")); trayIconMenu_->addAction(wallpapersPauseAction_); } else{ wallpapersPauseAction_->setText(" "+tr("Pause")); trayIconMenu_->addAction(wallpapersPauseAction_); trayIconMenu_->addAction(wallpapersNextAction_); trayIconMenu_->addAction(wallpapersPreviousAction_); } } else if(gv.liveEarthRunning) { liveEarthAction_->setCheckable(true); liveEarthAction_->setChecked(true); } else if(gv.potdRunning) { pictureOfTheDayAction_->setCheckable(true); pictureOfTheDayAction_->setChecked(true); } else if(gv.wallpaperClocksRunning) { wallpaperClocksAction_->setCheckable(true); wallpaperClocksAction_->setChecked(true); } else if(gv.liveWebsiteRunning) { liveWebsiteAction_->setCheckable(true); liveWebsiteAction_->setChecked(true); } else { uncheckRunningFeatureOnTray(); } trayIconMenu_->addAction(liveEarthAction_); trayIconMenu_->addAction(pictureOfTheDayAction_); trayIconMenu_->addAction(wallpaperClocksAction_); trayIconMenu_->addAction(liveWebsiteAction_); QActionGroup* myGroup = new QActionGroup( this ); myGroup->addAction(wallpapersAction_); myGroup->addAction(liveEarthAction_); myGroup->addAction(pictureOfTheDayAction_); myGroup->addAction(wallpaperClocksAction_); myGroup->addAction(liveWebsiteAction_); trayIconMenu_->addSeparator(); trayIconMenu_->addAction(preferencesAction_); trayIconMenu_->addAction(aboutAction_); trayIconMenu_->addAction(quitAction_); } void nonGUI::trayActionShowWindow() { doAction("--focus"); } void nonGUI::trayActionCopyPath() { QApplication::clipboard()->setText(Global::currentBackgroundImage()); } void nonGUI::trayActionCopyName() { QApplication::clipboard()->setText(Global::basenameOf(Global::currentBackgroundImage())); } void nonGUI::trayActionCopyImage() { QApplication::clipboard()->setImage(QImage(Global::currentBackgroundImage()), QClipboard::Clipboard); } void nonGUI::trayActionOpenCurrentImageFolder() { Global::openFolderOf(""); } void nonGUI::trayActionDeleteCurrentImage() { doAction("--delete-current"); } void nonGUI::trayActionOpenCurrentImageProperties() { doAction("--properties"); } void nonGUI::trayActionWallpapers() { if(!gv.wallpapersRunning){ doAction("--start"); } else{ doAction("--stop"); } createTray(); } void nonGUI::trayActionWallpapersOnce() { doAction("--change"); } void nonGUI::trayActionWallpapersPause() { doAction("--pause"); } void nonGUI::trayActionWallpapersNext() { doAction("--next"); } void nonGUI::trayActionWallpapersPrevious() { doAction("--previous"); } void nonGUI::trayActionLiveEarth() { doAction("--earth"); createTray(); } void nonGUI::trayActionPictureOfTheDay() { doAction("--potd"); createTray(); } void nonGUI::trayActionWallpaperClocks() { doAction("--clock"); createTray(); } void nonGUI::trayActionLiveWebsite() { doAction("--website"); createTray(); } void nonGUI::trayActionPreferences() { doAction("--preferences"); } void nonGUI::trayActionAbout() { doAction("--about"); } void nonGUI::trayActionQuit() { doAction("--quit"); } void nonGUI::uncheckRunningFeatureOnTray() { wallpapersAction_->setCheckable(false); liveEarthAction_->setCheckable(false); pictureOfTheDayAction_->setCheckable(false); wallpaperClocksAction_->setCheckable(false); liveWebsiteAction_->setCheckable(false); } //End of System tray icon code #endif //#ifdef ON_LINUX void nonGUI::propertiesDestroyed() { propertiesShown_=false; } void nonGUI::preferencesDestroyed(){ gv.preferencesDialogShown=false; } void nonGUI::doAction(const QString &message){ /* * This function controls messages coming from external sources, * like from the indicator (or tray) and the unity launcher. */ if(message=="--focus"){ if(mainWindowLaunched_){ Global::debug("Focusing to the Wallch window."); Q_EMIT signalFocus(); return; } Global::debug("Loading the Wallch window."); #ifdef ON_LINUX if(gv.useShortcutNext){ keybinder_unbind(gv.nextShortcut.toLocal8Bit().data(), key_action_next); } #endif //stop any process from nonGUI (they will continue to GUI) if(this->isActive()){ this->stop(); } resetWatchFolders(true); Global::debug("Focus was requested! Continuing the process to the Graphical Interface"); if(websiteSnapshot_){ disconnect(websiteSnapshot_->asQObject(), SIGNAL(resultedImage(QImage*,short)), this, SLOT(liveWebsiteImageReady(QImage*,short))); } mainWindowLaunched_=true; MainWindow *w; if(gv.wallpapersRunning){ w = new MainWindow(globalParser_, websiteSnapshot_, secondsLeft_, previousPictures_, totalSeconds_, currentImageIndex_); } else if(gv.liveWebsiteRunning || gv.wallpaperClocksRunning || gv.liveEarthRunning){ w = new MainWindow(globalParser_, websiteSnapshot_, secondsLeft_, previousPictures_, 0, currentImageIndex_); } else { w = new MainWindow(globalParser_, websiteSnapshot_, 0, previousPictures_, 0, currentImageIndex_); } connectMainwindowWithExternalActions(w); w->show(); } else if(message=="--earth"){ if(mainWindowLaunched_){ if(gv.liveEarthRunning){ Global::debug("Stopping the Live Earth process."); Q_EMIT closeWhatsRunning(); } else { Global::debug("Activating the Live Earth process."); Q_EMIT signalActivateLivearth(); } return; } if(gv.liveEarthRunning){ Global::debug("Stopping the Live Earth process."); doAction("--stop"); return; } Global::debug("Checking for internet connection..."); if(!globalParser_->connectedToInternet()){ Global::error("Could not connect to the internet. Live Earth is not enabled."); return; } Global::debug("Switching to Live Earth mode."); if(gv.liveWebsiteRunning){ if(websiteSnapshot_->isLoading()){ websiteSnapshot_->stop(); } } if(gv.potdRunning){ globalParser_->abortDownload(); } #ifdef ON_LINUX Global::showWallpapersIndicatorControls(false, true); #endif gv.liveWebsiteRunning=gv.wallpaperClocksRunning=gv.potdRunning=gv.wallpapersRunning=false; gv.liveEarthRunning=true; Global::updateStartup(); if(this->isActive()){ this->stop(); } this->disconnectFromSlot(); this->connectToUpdateSecondsSlot(); globalParser_->livearth(); secondsLeft_=totalSeconds_=LIVEARTH_INTERVAL; Global::resetSleepProtection(secondsLeft_); this->start(1000); #ifdef ON_LINUX Global::changeIndicatorSelection("earth"); if(gv.currentDE==UnityGnome){ if(gv.unityProgressbarEnabled){ Global::setUnityProgressBarEnabled(true); } setUnityShortcutsState(true, false, false, false); } #endif //#ifdef ON_LINUX } else if(message=="--potd"){ if(mainWindowLaunched_){ if(gv.potdRunning){ Global::debug("Stopping the Picture Of The Day process."); Q_EMIT closeWhatsRunning(); } else { Global::debug("Activating the Picture Of The Day process."); Q_EMIT signalActivatePotd(); } return; } if(gv.potdRunning){ Global::debug("Stopping the Picture Of The Day process."); doAction("--stop"); return; } Global::debug("Checking for internet connection..."); if(!globalParser_->connectedToInternet()){ Global::error("Could not connect to the internet. Picture Of The Day is not enabled."); return; } Global::debug("Switching to Picture Of The Day mode."); if(gv.liveWebsiteRunning){ if(websiteSnapshot_->isLoading()){ websiteSnapshot_->stop(); } } if(gv.liveEarthRunning){ globalParser_->abortDownload(); } #ifdef ON_LINUX Global::showWallpapersIndicatorControls(false, true); #endif gv.liveEarthRunning=gv.liveWebsiteRunning=gv.wallpaperClocksRunning=gv.wallpapersRunning=false; gv.potdRunning=true; Global::updateStartup(); if(this->isActive()){ this->stop(); } this->disconnectFromSlot(); this->continueWithPotd(true); #ifdef ON_LINUX Global::changeIndicatorSelection("potd"); if(gv.currentDE==UnityGnome){ setUnityShortcutsState(true, false, false, false); } #endif //#ifdef ON_LINUX } else if(message=="--clock") { if(mainWindowLaunched_){ if(gv.wallpaperClocksRunning){ Global::debug("Stopping the Wallpaper Clocks process."); Q_EMIT closeWhatsRunning(); } else { Global::debug("Activating the Wallpaper Clocks process."); Q_EMIT signalActivateWallClocks(); } return; } if(gv.wallpaperClocksRunning){ Global::debug("Stopping the Wallpaper Clocks process."); doAction("--stop"); return; } if(!this->continueWithClock()){ Global::error("There was a problem with starting the process. Wallpaper Clocks is not enabled."); doAction("--stop"); return; } #ifdef ON_LINUX Global::showWallpapersIndicatorControls(false, true); #endif gv.liveEarthRunning=gv.liveWebsiteRunning=gv.potdRunning=gv.wallpapersRunning=false; gv.wallpaperClocksRunning=true; Global::updateStartup(); Global::debug("Switching to Wallpaper Clocks mode."); if(gv.liveWebsiteRunning){ if(websiteSnapshot_->isLoading()){ websiteSnapshot_->stop(); } } #ifdef ON_LINUX Global::changeIndicatorSelection("clocks"); if(gv.currentDE==UnityGnome){ setUnityShortcutsState(true, false, false, false); } #endif //#ifdef ON_LINUX } else if(message=="--website"){ if(mainWindowLaunched_){ if(gv.liveWebsiteRunning){ Global::debug("Stopping the Live Website process."); Q_EMIT closeWhatsRunning(); } else { Global::debug("Activating the Live Website process."); Q_EMIT signalActivateLiveWebsite(); } return; } if(gv.liveWebsiteRunning){ Global::debug("Stopping the Live Website process."); doAction("--stop"); return; } if(websiteSnapshot_==NULL){ websiteSnapshot_ = new WebsiteSnapshot(); } Global::debug("Switching to Live Website mode."); if(gv.liveEarthRunning || gv.potdRunning){ globalParser_->abortDownload(); } #ifdef ON_LINUX Global::showWallpapersIndicatorControls(false, true); #endif gv.potdRunning=gv.liveEarthRunning=gv.wallpaperClocksRunning=gv.wallpapersRunning=false; gv.liveWebsiteRunning=true; Global::updateStartup(); if(this->isActive()){ this->stop(); } this->disconnectFromSlot(); secondsLeft_=0; this->continueWithWebsite(); #ifdef ON_LINUX Global::changeIndicatorSelection("website"); if(gv.currentDE==UnityGnome){ if(gv.unityProgressbarEnabled){ Global::setUnityProgressBarEnabled(true); } setUnityShortcutsState(true, false, false, false); } #endif //#ifdef ON_LINUX } else if(message=="--start"){ if(mainWindowLaunched_){ if(!gv.wallpapersRunning || gv.processPaused){ Global::debug("Activating the Wallpapers process."); Q_EMIT signalStart(); } else { Global::debug("Stopping the Wallpapers process."); doAction("--stop"); } return; } if(gv.wallpapersRunning){ Global::debug("Stopping the Wallpapers process."); doAction("--stop"); } else { if(startedWithLiveEarth_ || startedWithWebsite_ || startedWithPotd_ || startedWithClock_){ startedWithLiveEarth_=startedWithWebsite_=startedWithPotd_=startedWithClock_=false; checkSettings(true); if(!getPicturesLocation(true)){ return; } if(gv.randomImagesEnabled){ Global::generateRandomImages(allPictures_.count(), -1); } } Global::debug("Switching to Wallpapers mode."); gv.wallpaperClocksRunning=gv.potdRunning=gv.liveEarthRunning=gv.liveWebsiteRunning=false; gv.wallpapersRunning=true; Global::updateStartup(); if(this->isActive()){ this->stop(); } this->disconnectFromSlot(); this->connectToUpdateSecondsSlot(); getDelay(); secondsLeft_=0; Global::resetSleepProtection(secondsLeft_); this->start(1000); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ if(gv.unityProgressbarEnabled){ Global::setUnityProgressBarEnabled(true); } setUnityShortcutsState(true, true, true, true); } Global::changeIndicatorSelection("wallpapers"); Global::showWallpapersIndicatorControls(true, true); #endif //#ifdef ON_LINUX } } else if(message=="--change"){ if(mainWindowLaunched_){ Q_EMIT signalOnce(); return; } QString parentFolder=getCurrentWallpapersFolder(); if(!QDir(parentFolder).exists()){ globalParser_->desktopNotify(tr("Folder doesn't exist for the process to continue."), false, "info"); return; } allPictures_.clear(); Q_FOREACH(QString curFolder, Global::listFolders(parentFolder, true, true)){ getFilesFromFolder(curFolder); } srand(time(0)); Global::setBackground(allPictures_.at(rand()%allPictures_.count()), true, true, 1); } else if(message=="--pause"){ if(mainWindowLaunched_){ Q_EMIT signalPause(); return; } if(!gv.wallpapersRunning && !gv.processPaused){ Global::error("Cannot pause to any other process rather than Wallpapers!"); return; } if(!gv.processPaused){ Global::debug("Pausing the Wallpapers process."); this->stop(); gv.processPaused=true; #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ setUnityShortcutsState(true, false, false, false); } Global::changeIndicatorSelection("pause"); Global::showWallpapersIndicatorControls(true, false); #endif //#ifdef ON_LINUX } else { Global::resetSleepProtection(secondsLeft_); Global::debug("Continuing from the pause..."); gv.processPaused=false; #ifdef ON_LINUX Global::showWallpapersIndicatorControls(true, true); if(gv.currentDE==UnityGnome){ setUnityShortcutsState(true, true, true, true); } #endif this->start(1000); } } else if(message=="--stop"){ if(mainWindowLaunched_){ #ifdef ON_LINUX if(gv.wallpapersRunning){ Global::showWallpapersIndicatorControls(false, true); } #endif Q_EMIT closeWhatsRunning(); return; } #ifdef ON_LINUX if(gv.currentDE==UnityGnome && gv.unityProgressbarEnabled){ Global::setUnityProgressBarEnabled(false); } #endif if(this->isActive()){ this->stop(); } if(gv.wallpapersRunning) { #ifdef ON_LINUX Global::showWallpapersIndicatorControls(false, true); #endif if(gv.randomTimeEnabled){ srand(time(0)); totalSeconds_=secondsLeft_=(rand()%(gv.randomTimeTo-gv.randomTimeFrom+1))+gv.randomTimeFrom; } else { secondsLeft_=totalSeconds_; } if(gv.independentIntervalEnabled){ //resetting the configuration! Global::saveSecondsLeftNow(-1, 0); } } else if(gv.liveEarthRunning || gv.liveWebsiteRunning){ secondsLeft_=totalSeconds_; } else if(gv.wallpaperClocksRunning){ secondsLeft_=totalSeconds_=wallpaperClocksTotalSeconds_; } if(gv.liveEarthRunning || gv.potdRunning){ globalParser_->abortDownload(); } gv.wallpapersRunning=gv.liveEarthRunning=gv.potdRunning=gv.wallpaperClocksRunning=gv.liveWebsiteRunning=false; Global::updateStartup(); #ifdef ON_LINUX Global::changeIndicatorSelection("none"); if(gv.currentDE==UnityGnome){ setUnityShortcutsState(false, false, false, false); } #endif } else if(message=="--next"){ if(mainWindowLaunched_){ Q_EMIT signalNext(); return; } if(gv.wallpapersRunning){ if(this->isActive()){ this->stop(); secondsLeft_=0; updateSeconds(); this->start(1000); } else { Global::error("Wallpapers mode is not running in order to use 'next'"); } } else { Global::error("Υou can use 'next' only in Wallpapers mode."); } } else if(message=="--previous"){ if(mainWindowLaunched_){ Q_EMIT signalPrevious(); return; } if(gv.wallpapersRunning){ if(this->isActive()){ if(gv.wallpapersRunning){ this->stop(); secondsLeft_=0; previousWasClicked_=true; updateSeconds(); this->start(1000); } } else { Global::error("Wallpapers mode is not running in order to use 'previous'"); } } else { Global::error("Υou can use 'previous' only in Wallpapers mode."); } } else if(message=="--preferences"){ if(mainWindowLaunched_){ Q_EMIT signalShowPreferences(); return; } if(gv.preferencesDialogShown){ return; } gv.preferencesDialogShown=true; preferences_ = new Preferences(); preferences_->setModal(true); preferences_->setAttribute(Qt::WA_DeleteOnClose); connect(preferences_, SIGNAL(destroyed()), this, SLOT(preferencesDestroyed())); #ifdef ON_LINUX connect(preferences_, SIGNAL(unityProgressbarChanged(bool)), this, SLOT(unityProgressbarSetEnabled(bool))); #endif connect(preferences_, SIGNAL(checkCacheSize()), this, SLOT(fixCacheSizeThreaded())); preferences_->show(); } else if(message=="--properties"){ if(propertiesShown_){ return; } QString imageFilename=Global::currentBackgroundImage(); if(!QFile::exists(imageFilename) || QImage(imageFilename).isNull()) { QMessageBox::warning(0, tr("Properties"), tr("This file maybe doesn't exist or it's not an image. Please perform a check for the file and try again.")); return; } propertiesShown_=true; properties_ = new Properties(imageFilename, false, 0, 0); properties_->setModal(true); properties_->setAttribute(Qt::WA_DeleteOnClose); connect(properties_, SIGNAL(destroyed()), this, SLOT(propertiesDestroyed())); properties_->show(); } else if(message=="--about"){ if(mainWindowLaunched_){ Q_EMIT signalShowAbout(); return; } About ab(0); ab.exec(); } else if(message=="--delete-current"){ if(mainWindowLaunched_){ Q_EMIT signalDeleteCurrent(); return; } if(QMessageBox::question(0, QObject::tr("Confirm deletion"), QObject::tr("Are you sure you want to permanently delete the current image?"))==QMessageBox::Yes) { if(!QFile::remove(Global::currentBackgroundImage())){ QMessageBox::warning(0, QObject::tr("Error"), QObject::tr("There was a problem deleting the current image. Please make sure you have the permission to delete the image or that the image exists.")); } } } else if(message=="--quit"){ if(mainWindowLaunched_){ Q_EMIT signalQuit(); return; } Global::debug("See ya next time!"); qApp->exit(0); } else if(message.startsWith("CLOCK:")){ if(mainWindowLaunched_){ Q_EMIT signalInstallWallClock(message.right(message.length()-6)); } else{ Global::error("Wallpapper clock installations only on GUI mode!"); } } else if(message.startsWith("MONITOR:")){ QString folder=message.right(message.length()-8); if(mainWindowLaunched_){ Q_EMIT signalAddFolderForMonitor(folder); return; } //update the configuration to point to the new folder setDefaultFolderInSettings(folder); if(gv.wallpapersRunning){ researchDirs(); } } else{ Global::error("This message is unknown to me."); } } void nonGUI::fixCacheSizeThreaded(){ QtConcurrent::run(this, &nonGUI::fixCacheSizeGlobalCallback); } void nonGUI::fixCacheSizeGlobalCallback(){ Global(false).fixCacheSize(getCurrentWallpapersFolder()); } QString nonGUI::getCurrentWallpapersFolder(){ //read the default folder location short currentFolderIndex=settings->value("currentFolder_index", 0).toInt(); settings->beginReadArray("pictures_locations"); settings->setArrayIndex(currentFolderIndex); QString parent_folder = settings->value("item", gv.currentDeDefaultWallpapersPath).toString(); settings->endArray(); return parent_folder; } void nonGUI::setDefaultFolderInSettings(const QString &folder){ bool already_in_settings=false; short count = settings->beginReadArray("pictures_locations"); if(QDir(folder).exists()){ for(short i=0; isetArrayIndex(i); if(Global::foldersAreSame(folder, settings->value("item").toString())) { settings->endArray(); settings->setValue("currentFolder_index", i); already_in_settings=true; break; } } settings->sync(); } else { settings->endArray(); Global::error("The folder "+folder+" does not exist!"); return; } if(!already_in_settings){ //Add the folder to the index and point to it as default settings->endArray(); settings->beginWriteArray("pictures_locations"); settings->setArrayIndex(count); settings->setValue("item", folder); settings->endArray(); settings->setValue("currentFolder_index", count); settings->sync(); } } void nonGUI::setIndependentInterval(const QString &independentInterval){ if(!independentInterval.contains(".")){ return; } QStringList parts=independentInterval.split("."); if(parts.count()!=3){ return; } if(parts.at(0)=="e"){ //independence was referring to live earth! if(!startedWithLiveEarth_){ return; } } else if(parts.at(0)=="w"){ //independence was referring to live website! if(!startedWithWebsite_){ return; } } else { //independence was referring to wallpapers if(startedWithWebsite_ || startedWithLiveEarth_){ return; } } bool ok; int independence_change_seconds_left = parts.at(1).toInt(&ok); if(!ok){ return; } if(independence_change_seconds_left==-1){ return; } QDateTime time_then = QDateTime::fromString(parts.at(2), "yyyy:MM:dd:HH:mm:ss"); if(time_then.isNull() || !time_then.isValid()){ return; } time_then.addSecs(independence_change_seconds_left); int secs_diff = time_then.secsTo(QDateTime::currentDateTime()); independence_change_seconds_left-=secs_diff; if(independence_change_seconds_left<0){ independence_change_seconds_left=0; } if(independence_change_seconds_left>0){ Global::debug("Interval independence is enabled ("+QString::number(independence_change_seconds_left)+" seconds)"); secondsLeft_=independence_change_seconds_left; } } void nonGUI::checkSettings(bool allSettings){ // The least checks for the --change argument gv.setAverageColor = settings->value("average_color", false).toBool(); gv.showNotification=settings->value("notification", false).toBool(); gv.saveHistory=settings->value("history", true).toBool(); #ifdef ON_LINUX gv.currentDE=static_cast(settings->value("de", 0).toInt()); #endif if(allSettings){ //checks all needed settings gv.useShortcutNext=settings->value("use_shortcut_next", false).toBool(); #ifdef ON_LINUX gv.unityProgressbarEnabled=settings->value("unity_progressbar_enabled", true).toBool(); #endif gv.potdIncludeDescription = settings->value("potd_include_description", true).toBool(); gv.potdDescriptionBottom = settings->value("potd_description_bottom", true).toBool(); gv.potdDescriptionFont = settings->value("potd_description_font", "Ubuntu").toString(); gv.potdDescriptionColor = settings->value("potd_text_color", "#FFFFFF").toString(); gv.potdDescriptionBackgroundColor = settings->value("potd_background_color", "#000000").toString(); #ifdef ON_LINUX gv.potdDescriptionLeftMargin = settings->value("potd_description_left_margin", (gv.currentDE==UnityGnome ? 60 : 0)).toInt(); #else gv.potdDescriptionLeftMargin = settings->value("potd_description_left_margin", (0)).toInt(); #endif gv.potdDescriptionRightMargin = settings->value("potd_description_right_margin", 0).toInt(); gv.potdDescriptionBottomTopMargin = settings->value("potd_description_bottom_top_margin", 0).toInt(); gv.randomTimeEnabled=settings->value("random_time_enabled", false).toBool(); if(startedWithLiveEarth_ || startedWithWebsite_ || (!startedWithClock_ && !startedWithPotd_ && !gv.randomTimeEnabled)){ gv.independentIntervalEnabled = settings->value("independent_interval_enabled", true).toBool(); if(gv.independentIntervalEnabled){ //check if there is an interval to follow setIndependentInterval(settings->value("seconds_left_interval_independence", INTERVAL_INDEPENDENCE_DEFAULT_VALUE).toString()); } } else { gv.independentIntervalEnabled=false; } gv.randomImagesEnabled=settings->value("random_images_enabled", false).toBool(); gv.firstTimeout=settings->value("first_timeout", false).toBool(); if(gv.randomTimeEnabled){ gv.randomTimeFrom=settings->value("random_time_from", 300).toInt(); gv.randomTimeTo=settings->value("random_time_to", 1200).toInt(); if(gv.randomTimeFrom>gv.randomTimeTo-3){ Global::error("The random time is misconfigured, please head to the Preferences dialog to configure it properly!"); gv.randomTimeEnabled=false; } else { totalSeconds_=secondsLeft_=(rand()%(gv.randomTimeTo-gv.randomTimeFrom+1))+gv.randomTimeFrom; } } if(gv.randomImagesEnabled){ srand(QDateTime::currentMSecsSinceEpoch()); } gv.useShortcutNext=settings->value("use_shortcut_next", false).toBool(); #ifdef ON_LINUX if(gv.useShortcutNext){ gv.nextShortcut=settings->value("shortcut", "").toString(); keybinder_init(); if(!keybinder_bind(gv.nextShortcut.toLocal8Bit().data(), key_action_next, NULL)){ //key could not be binded! Global::error("I probably could not bind the key sequence: '"+gv.nextShortcut+"'"); } } #endif gv.potdOnlineUrl=settings->value("potd_online_url", POTD_ONLINE_URL).toString(); gv.potdOnlineUrlB=settings->value("potd_online_urlB", POTD_ONLINE_URL_B).toString(); gv.liveEarthOnlineUrl=settings->value("line_earth_online_url", LIVEARTH_ONLINE_URL).toString(); gv.liveEarthOnlineUrlB=settings->value("live_earth_online_urlB", LIVEARTH_ONLINE_URL_B).toString(); } } void nonGUI::connectMainwindowWithExternalActions(MainWindow *w){ //connects MainWindow with indicator, unity and command line messages. QObject::connect(&nongui, SIGNAL(signalOnce()), w, SLOT(justChangeWallpaper())); QObject::connect(&nongui, SIGNAL(signalPause()), w, SLOT(on_startButton_clicked())); QObject::connect(&nongui, SIGNAL(signalPrevious()), w, SLOT(on_previous_Button_clicked())); QObject::connect(&nongui, SIGNAL(signalNext()), w, SLOT(on_next_Button_clicked())); QObject::connect(&nongui, SIGNAL(signalStart()), w, SLOT(on_startButton_clicked())); QObject::connect(&nongui, SIGNAL(signalActivateLivearth()), w, SLOT(on_activate_livearth_clicked())); QObject::connect(&nongui, SIGNAL(signalActivatePotd()), w, SLOT(on_activate_potd_clicked())); QObject::connect(&nongui, SIGNAL(signalActivateWallClocks()), w, SLOT(on_activate_clock_clicked())); QObject::connect(&nongui, SIGNAL(signalActivateLiveWebsite()), w, SLOT(on_activate_website_clicked())); QObject::connect(&nongui, SIGNAL(closeWhatsRunning()), w, SLOT(closeWhatsRunning())); QObject::connect(&nongui, SIGNAL(signalShowPreferences()), w, SLOT(on_action_Preferences_triggered())); QObject::connect(&nongui, SIGNAL(signalShowAbout()), w, SLOT(on_action_About_triggered())); QObject::connect(&nongui, SIGNAL(signalQuit()), w, SLOT(on_actionQuit_Ctrl_Q_triggered())); QObject::connect(&nongui, SIGNAL(signalDeleteCurrent()), w, SLOT(on_actionDelete_triggered())); QObject::connect(&nongui, SIGNAL(signalAddFolderForMonitor(const QString&)), w, SLOT(addFolderForMonitor(const QString&))); QObject::connect(&nongui, SIGNAL(signalInstallWallClock(QString)), w, SLOT(installWallpaperClock(const QString&))); #ifdef ON_WIN32 QObject::connect(&nongui, SIGNAL(signalFocus()), w, SLOT(strongShowApp())); QObject::connect(w, SIGNAL(signalUncheckRunningFeatureOnTray()), &nongui , SLOT(uncheckRunningFeatureOnTray())); QObject::connect(w, SIGNAL(signalRecreateTray()), &nongui , SLOT(createTray())); #else QObject::connect(&nongui, SIGNAL(signalFocus()), w, SLOT(strongShowApp())); #endif //#ifdef ON_WIN32 } std::string nonGUI::percentToProgressbar(short percentage){ short loop_count=floor((float)(percentage/10.0)); std::string progressbar_string; for(short i=0;isave(filename); delete image; Global::setBackground(filename, true, true, 5); QFile::remove(gv.wallchHomePath+LW_PREVIEW_IMAGE); QFile(filename).link(gv.wallchHomePath+LW_PREVIEW_IMAGE); } else { switch(errorCode){ case 1: Global::error("Some of the requested pages failed to load successfully."); break; case 2: Global::error("Simple authentication failed. Please check your username and/or password."); break; case 3: Global::error("Username and/or password fields are not found. Please check that you are pointing at the login page."); break; case 4: Global::error("The timeout has been reached and the image has yet to be created!"); break; default: Global::error("Unknown error! Please try with a different web page."); break; } } } void nonGUI::updateSecondsPassed() { settings->setValue("seconds_passed", settings->value("seconds_passed", 0).toUInt()+UPDATE_STATISTICS_SECONDS_INTERVAL/1000); } void nonGUI::startStatisticsTimer(){ updateSecondsPassed_ = new QTimer(this); connect(updateSecondsPassed_, SIGNAL(timeout()), this, SLOT(updateSecondsPassed())); updateSecondsPassed_->start(UPDATE_STATISTICS_SECONDS_INTERVAL); } void nonGUI::viralSettingsOperations(){ if(QApplication::instance()){ QTranslator *translator = new QTranslator(this); translator->load(QString::fromStdString(PREFIX)+"/share/wallch/translations/wallch_"+settings->value("language_file", "en").toString()+".qm"); QApplication::installTranslator(translator); } //checking for first run if(settings->value("first-run", true).toBool()){ settings->setValue("first-run", false); #ifdef ON_LINUX if(!QDir(gv.homePath+"/.config/Wallch/").removeRecursively()){ Global::error("I probably could not remove previous Wallch configurations!"); } //doing DE detection DesktopEnvironment setDe; if(QDir("/etc/xdg/lubuntu").exists()){ setDe=LXDE; } else if(QFile::exists("/usr/bin/xfconf-query")){ setDe=XFCE; } else if(QFile::exists("/usr/bin/mate-about")){ setDe=Mate; } else if(QFile::exists("/usr/bin/unity")) { setDe=UnityGnome; } else { setDe=Gnome; } settings->setValue("de", setDe); gv.currentDE=setDe; //doing OS name detection QString osName; QFile osDetectionFile("/etc/os-release"); if(osDetectionFile.exists() && osDetectionFile.open(QIODevice::ReadOnly | QIODevice::Text)){ QTextStream in(&osDetectionFile); QString curLine; QString prettyName, name; while(!in.atEnd()){ curLine=in.readLine(); if(curLine.startsWith("PRETTY_NAME=")){ prettyName=curLine.right(curLine.count()-12); } else if(curLine.startsWith("NAME=")){ name=curLine.right(curLine.count()-5); } } if(!prettyName.isEmpty()){ if(prettyName.contains(" ")){ prettyName=prettyName.split(" ")[0]; } prettyName.replace("\"", ""); osName=prettyName; } else if(!name.isEmpty()){ osName=name; } } else { osDetectionFile.setFileName("/etc/lsb-release"); if(osDetectionFile.exists() && osDetectionFile.open(QIODevice::ReadOnly | QIODevice::Text)){ QTextStream in(&osDetectionFile); QString currentLine; bool found=false; while(!in.atEnd()){ currentLine=in.readLine(); if(currentLine.startsWith("DISTRIB_ID=")){ found=true; currentLine=currentLine.right(currentLine.count()-11); break; } } if(found && !currentLine.isEmpty()){ osName=currentLine; } } } if(!osName.isEmpty()){ osDetectionFile.close(); } settings->setValue("osname", osName); #elif ON_WIN32 OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); settings->setValue("windows_major_version", QString::number(osvi.dwMajorVersion)); settings->setValue("windows_minor_version", QString::number(osvi.dwMinorVersion)); if(!QDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)+"/Mellori Studio/Wallch/").removeRecursively()){ Global::error("I probably could not remove previous Wallch configurations!"); } #endif //#ifdef ON_LINUX } #ifdef ON_LINUX else { //this is not a first-run gv.currentDE=static_cast(settings->value("de", 0).toInt()); } #endif settings->setValue("times_launched", settings->value("times_launched", 0).toUInt()+1); //adding one to times launched settings->sync(); //store the current os name and the current os default wallpapers path so we don't check everytime #ifdef ON_WIN32 gv.currentOSName="Windows"; gv.currentDeDefaultWallpapersPath="C:\\Windows\\Web\\Wallpaper"; #else gv.currentOSName=settings->value("osname", "Ubuntu").toString(); if(gv.currentDE==LXDE && gv.currentOSName=="Ubuntu"){ gv.currentDeDefaultWallpapersPath="/usr/share/lubuntu/wallpapers"; } else { gv.currentDeDefaultWallpapersPath="/usr/share/backgrounds"; } #endif #ifdef ON_LINUX gv.wallchHomePath=gv.homePath+"/.wallch/"; gv.cachePath=gv.homePath+"/.cache/wallch/thumbs/"; #elif ON_WIN32 gv.wallchHomePath=QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)+"/Mellori Studio/Wallch/"; gv.cachePath=gv.wallchHomePath+"/.cache/thumbs/"; #endif if(!QDir(gv.wallchHomePath).exists()){ QDir().mkpath(gv.wallchHomePath); } if(!QDir(gv.cachePath).exists()){ QDir().mkpath(gv.cachePath); } Global::updateStartup(); } int nonGUI::startProgram(int argc, char *argv[]){ if(argc > 1){ const struct option longopts[] = { {"version", ARG_NOT_REQ, 0, 'v'}, {"help", ARG_NOT_REQ, 0, 'h'}, {"change", ARG_OPT, 0, 'c'}, {0,0,0,0}, }; int index; int iarg=0; opterr=0; //turn off getopt error message while(iarg != -1) { iarg = getopt_long(argc, argv, "c:vh", longopts, &index); switch (iarg) { case 'h': showUsage(0); break; case 'v': Global::debug("Wallch - Wallpaper Changer, Version "+QString::number(APP_VERSION, 'f', 1)); return 0; break; case 'c': { viralSettingsOperations(); /* * Just change the current image. This argument always launches when called * correctly (it doesn't matter whether wallch is already running or not! */ startedWithJustChange_=true; if(optarg){ //probably the user has specified a folder for working with --change. if(index!=2 || argc > 3){ showUsage(1); } QString read_from=QString(optarg); if(QDir(read_from).exists()){ //It is a directory. Read its contents instead of the default directory. readPictures(QDir(read_from).absolutePath()); } else { Global::error(read_from+" - No such file or directory."); return 1; } } else { //only --change was specified... Read the pictures of the default folder if(!getPicturesLocation(true)){ return 1; } } checkSettings(false); gv.randomImagesEnabled=true; Global::generateRandomImage(allPictures_); if(gv.setAverageColor){ //QImage::scaled() crashes without QApplication :( QApplication app(argc, argv); changeWallpaperNow(); app.exit(0); } else { changeWallpaperNow(); } return 0; break; } } } //second level argument searching! QApplication app(argc, argv); viralSettingsOperations(); QApplication::setQuitOnLastWindowClosed(false); QStringList arguments=QCoreApplication::arguments(); if(arguments.contains("--start")){ if(alreadyRuns()){ messageServer("--start", true); startStatisticsTimer(); return app.exec(); } bool gotPicLocation=getPicturesLocation(true); checkSettings(true); Global::resetSleepProtection(secondsLeft_); if(gotPicLocation){ if(!gv.randomTimeEnabled){ getDelay(); Global::debug("Your Desktop Background will change every "+QString::number(totalSeconds_)+" seconds."); } else { Global::debug("Your Desktop Background will change every ["+QString::number(gv.randomTimeFrom)+"-"+QString::number(gv.randomTimeTo)+"] seconds."); } if(allPictures_.count()desktopNotify(tr("You cannot change wallpapers if they are less than 2!"), false, "info"); return 1; } if(gv.randomImagesEnabled){ Global::generateRandomImages(allPictures_.count(), -1); } gv.wallpapersRunning=true; Global::updateStartup(); connectToUpdateSecondsSlot(); } connectToServer(); #ifdef ON_LINUX setupIndicator(); if(gv.currentDE==UnityGnome){ setupUnityShortcuts(); if(gotPicLocation){ setUnityShortcutsState(true, true, true, true); } else { setUnityShortcutsState(false, false, false, false); } } #else setupTray(); #endif if(gotPicLocation){ this->start(1000); } startStatisticsTimer(); return app.exec(); } else if(arguments.contains("--earth")){ if(argc > 2){ Global::error("Argument --earth doesn't take any other options!"); showUsage(1); } if(alreadyRuns()){ messageServer("--earth", true); startStatisticsTimer(); return app.exec(); } startedWithLiveEarth_=gv.liveEarthRunning=true; Global::updateStartup(); secondsLeft_=LIVEARTH_INTERVAL; checkSettings(true); Global::resetSleepProtection(secondsLeft_); connectToServer(); #ifdef ON_LINUX setupIndicator(); #else setupTray(); #endif Global::debug("Checking for internet connection..."); if (!globalParser_->connectedToInternet()){ Global::error("No internet connection, trying again in "+QString::number(CHECK_INTERNET_INTERVAL/1000)+" secs..."); disconnectFromSlot(); connectToCheckInternet(); this->start(CHECK_INTERNET_INTERVAL); } else { #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ setupUnityShortcuts(); setUnityShortcutsState(true, false, false, false); } #endif continueWithLiveEarth(); } startStatisticsTimer(); return app.exec(); } else if(arguments.contains("--clock")){ if(argc>2){ Global::error("Argument --clock doesn't take any other options!"); showUsage(1); } if(alreadyRuns()){ messageServer("--clock", true); startStatisticsTimer(); return app.exec(); } startedWithClock_=true; checkSettings(true); connectToServer(); #ifdef ON_LINUX setupIndicator(); if(gv.currentDE==UnityGnome){ setupUnityShortcuts(); setUnityShortcutsState(true, false, false, false); } #else setupTray(); #endif continueWithClock(); startStatisticsTimer(); return app.exec(); } else if(arguments.contains("--potd")){ if(argc>2){ Global::error("Argument --potd doesn't take any other options!"); showUsage(1); } if(alreadyRuns()){ messageServer("--potd", true); return app.exec(); } startedWithPotd_=gv.potdRunning=true; Global::updateStartup(); connectToServer(); #ifdef ON_LINUX setupIndicator(); #else setupTray(); #endif checkSettings(true); Global::debug("Checking for internet connection..."); if (!globalParser_->connectedToInternet()){ //will check every 3 secs if there's internet connection... disconnectFromSlot(); connectToCheckInternet(); this->start(CHECK_INTERNET_INTERVAL); } else { #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ setupUnityShortcuts(); setUnityShortcutsState(true, false, false, false); } #endif continueWithPotd(true); } startStatisticsTimer(); return app.exec(); } else if(arguments.contains("--website")){ if(argc>2){ Global::error("Argument --website doesn't take any other options!"); showUsage(1); } if(alreadyRuns()){ messageServer("--website", true); startStatisticsTimer(); return app.exec(); } gv.liveWebsiteRunning=startedWithWebsite_=true; Global::updateStartup(); secondsLeft_=0; checkSettings(true); Global::resetSleepProtection(secondsLeft_); connectToServer(); #ifdef ON_LINUX setupIndicator(); #else setupTray(); #endif websiteSnapshot_ = new WebsiteSnapshot(); #ifdef ON_LINUX if(gv.currentDE==UnityGnome){ setupUnityShortcuts(); setUnityShortcutsState(true, false, false, false); } #endif //#ifdef ON_LINUX continueWithWebsite(); startStatisticsTimer(); return app.exec(); } else if(arguments.contains("--quit") || arguments.contains("--stop") || arguments.contains("--next") || arguments.contains("--previous") || arguments.contains("--pause")){ if(argc>2){ showUsage(1); } if(alreadyRuns()){ QString message; QStringList all = QStringList() << "--quit" << "--stop" << "--next" << "--previous" << "--pause"; int count=all.count(); for(int i=0;i 2){ Global::error("There is more than a folder in the arguments. Wallch does not know what to do with the extra stuff. See -h/--help for more info"); return 1; } else { QString currentFolder = QDir::cleanPath(QDir().absoluteFilePath(arguments.at(1))); if(alreadyRuns()){ Global::debug("Folder '"+currentFolder+"' has been sent to the already running instance of Wallch for monitoring."); messageServer("MONITOR:"+currentFolder, true); startStatisticsTimer(); return app.exec(); } else { //just set the folder as the default folder for monitoring setDefaultFolderInSettings(currentFolder); Global::debug("Folder '"+currentFolder+"' is now the default folder for Wallch monitoring."); globalParser_->desktopNotify(tr("The default folder has changed."), false, "info"); return 0; } } } else { //wcz files to be sent to the already running instance of Wallch. short returnResult=1; bool runsAlready=alreadyRuns(), settingsChecked=false; for(short i=1; i #include #include #include class LineEditShortCut : public QLineEdit { Q_OBJECT public: explicit LineEditShortCut(QWidget *parent = 0) : QLineEdit(parent){ this->setReadOnly(true); this->setFocusPolicy(Qt::ClickFocus); gotCtrlKey_=gotAltKey_=gotSomeKey_=false; }; private: bool gotCtrlKey_; bool gotAltKey_; bool gotSomeKey_; void insertAtEnd(const QString &text){ this->setCursorPosition(this->text().count()); this->insert(text); } protected: virtual void keyPressEvent(QKeyEvent *ev); virtual void keyReleaseEvent(QKeyEvent *); }; namespace Ui { class preferences; } class Preferences : public QDialog { Q_OBJECT public: LineEditShortCut *lineEditShortcut; Preferences(QWidget *parent = 0); ~Preferences(); protected: void changeEvent(QEvent *e); private: Ui::preferences *ui; QHBoxLayout *buttonsLayout_; bool shortcutWasCheckedAtFirst_; bool textOfShortcutChanged_; bool listIsAlreadyIcons_; bool customIntervalsChanged_; bool addNewIntervalIsShown_; QString textOfShortcutInitially_; QList customIntervalsInSeconds_temp; void setThemeToAmbiance(); void setThemeToRadiance(); void setupShortcuts(); void setupThemeFallbacks(); bool createDesktopFile(const QString &path, const QString &command, const QString &comment); QString getCommandOfDesktopFile(const QString &file); private Q_SLOTS: void shortcutEdited(); void previousPage(); void nextPage(); void on_reset_clicked(); void on_saveButton_clicked(); void on_closeButton_clicked(); void on_shortcut_checkbox_clicked(bool checked); void on_random_time_from_combobox_currentIndexChanged(int index); void on_random_time_to_combobox_currentIndexChanged(int index); void on_page_0_general_clicked(); void on_page_1_wallpapers_page_clicked(); void on_page_3_integration_clicked(); void on_theme_combo_currentIndexChanged(int index); void on_random_time_checkbox_clicked(bool checked); void on_add_custom_interval_clicked(); void on_remove_custom_interval_clicked(); void on_rotate_checkBox_clicked(bool checked); void on_random_from_valueChanged(int value); void on_random_to_valueChanged(int value2); void on_page_2_live_website_clicked(); #ifdef ON_LINUX void on_de_combo_currentIndexChanged(int index); #endif void on_startupCheckBox_clicked(bool checked); void on_help_clicked(); Q_SIGNALS: void changePathsToIcons(); void changeIconsToPaths(); void bindKeySignal(QString key); void unbindKeySignal(QString key); void changeThemeTo(QString theme); void changeRandomTime(short index); void refreshCustomIntervals(); void tvPreviewChanged(bool show); void unityProgressbarChanged(bool show); }; #endif // PREFERENCES_H wallch-4.0/src/crop_image.h0000644000175000017500000000430312301477401014337 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CROP_IMAGE_H #define CROP_IMAGE_H #include #include #include #include class CropLabel : public QLabel { Q_OBJECT public: explicit CropLabel(QWidget *parent = 0); void setSelectionRect(const QRect &selectionRect){ selectionRect_=selectionRect; } QRect &selectionRect(){ return selectionRect_; } private: QRect selectionRect_; protected: void paintEvent(QPaintEvent *e); }; namespace Ui { class crop_image; } class CropImage : public QDialog { Q_OBJECT public: explicit CropImage(QImage *image, const QRect &curCropRect, QWidget *parent = 0); ~CropImage(); CropLabel *image_label; protected: void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void mouseReleaseEvent(); void keyPressEvent ( QKeyEvent * event ); void keyReleaseEvent ( QKeyEvent * event ); private: Ui::crop_image *ui; QVBoxLayout *mainLayout_; QHBoxLayout *buttonsLayout_; QImage *websiteImage_; bool selectionStarted_, shiftKeyDown_; int imageWidth_, imageHeight_, pointX_, pointY_; void createButtonsLayout(); void moveScroll(short direction); void sendNewCoordinates(QRect coords); private Q_SLOTS: void on_cancel_clicked(); void on_ok_clicked(); Q_SIGNALS: void coordinates(QRect coords); }; #endif // CROP_IMAGE_H wallch-4.0/src/websitesnapshot.cpp0000644000175000017500000004121112301477401016006 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include "websitesnapshot.h" #include #include #include #include #include const QStringList USUAL_USERNAME_FIELDS = QStringList() << "username" << "user" << "email" << "Email" << "User" << "Username"\ << "signin-email" << "userid" << "user-id" << "navbar_username" << "login_email" << "loginUsername" << "id_nickname" << "id_email" << "session_key-login"\ << "ap_email" << "signup_email"; const QStringList USUAL_PASSWORD_FIELDS = QStringList() << "password" << "pass" << "passwd" << "Password" << "Pass" << "Passwd"\ << "signin-password" << "navbar_password" << "login_password" << "navbar_password_hint" << "passid" << "pass-id" << "loginPassword" << "id_password" << "pwd"\ << "session_password-login" << "ap_password" << "signup_password"; WebsiteSnapshot::WebsiteSnapshot(){ simpleAuthAlreadyDone_=false; currentlyLoading_=false; debug_=false; javascriptEnabled_=true; javascriptCanAccessClipboard_=false; javaEnabled_=false; loadImagesEnabled_=true; cropImage_=false; webPage_=NULL; minHeight_=minWidth_=600; timeout_=60; waitAfterFinish_=3; complexAuthInitialWait_=1; requestedUrl_=QUrl(""); lastError_="No error."; errorCode_=0; authenticationLevel_=NoAuthentication; timeoutTimer_.setTimerType(Qt::VeryCoarseTimer); timeoutTimer_.setSingleShot(true); connect(&timeoutTimer_, SIGNAL(timeout()), this, SLOT(timeoutReached())); afterFinishTimer_.setTimerType(Qt::VeryCoarseTimer); afterFinishTimer_.setSingleShot(true); connect(&afterFinishTimer_, SIGNAL(timeout()), this, SLOT(afterFinishTimedOut())); priorComplexTimer_.setTimerType(Qt::VeryCoarseTimer); priorComplexTimer_.setSingleShot(true); connect(&priorComplexTimer_, SIGNAL(timeout()), this, SLOT(proceedToComplexAuth())); } WebsiteSnapshot::~WebsiteSnapshot(){ if(debug_) dbg("Destructor."); if(webPage_){ webPage_->settings()->clearMemoryCaches(); webPage_->deleteLater(); } } /*PRIVATE SLOTS/FUNCTIONS*/ void WebsiteSnapshot::returnResults(bool result){ if(!result){ if(debug_) dbg("The page could not be loaded correctly."); lastError_="The page could not be loaded correctly."; errorCode_=1; sendResultActions(NULL); } else { if(!webPage_->mainFrame()){ if(debug_) dbg("Could not get a QWebFrame from the QWebPage."); lastError_="Could not get a QWebFrame from the QWebPage."; errorCode_=1; sendResultActions(NULL); return; } if(webPage_->viewportSize().isNull() || webPage_->viewportSize()==QSize(0, 0)){ if(debug_) dbg("Viewport is null. Waiting for another loadFinished() signal. If no other signal is emitted, then the process will timeout."); return; } disconnectWebPage(); if(debug_) dbg("Starting after finish timeout: "+QString::number(waitAfterFinish_)+" seconds"); afterFinishTimer_.start(waitAfterFinish_*1000); } } void WebsiteSnapshot::afterAuthNavigation(bool result){ if(!result){ if(debug_) dbg("The page could not be loaded correctly."); lastError_="The page could not be loaded correctly."; errorCode_=1; sendResultActions(NULL); } else { disconnectWebPage(); connect(webPage_, SIGNAL(loadFinished(bool)), this, SLOT(returnResults(bool))); webPage_->currentFrame()->load(urlAfterAuth_); } } void WebsiteSnapshot::afterFinishTimedOut(){ timeoutTimer_.stop(); webPage_->setViewportSize(webPage_->mainFrame()->contentsSize()); QImage *image = new QImage(webPage_->viewportSize(), QImage::Format_ARGB32); if(image->isNull()){ if(debug_) dbg("Resulting image is NULL. Waiting for another loadFinished() signal."); return; } QPainter painter(image); webPage_->mainFrame()->render(&painter); painter.end(); if(cropImage_){ *image=image->copy(cropRect_); } if(debug_) dbg("Finished."); sendResultActions(image); } void WebsiteSnapshot::parseUrl(QUrl &url){ QString curUrl=url.url(); if(!curUrl.startsWith("http://") && !curUrl.startsWith("https://")){ curUrl="http://"+curUrl; url=QUrl(curUrl); } } void WebsiteSnapshot::authenticateSimple(QNetworkReply *, QAuthenticator *authenticator){ if(simpleAuthAlreadyDone_){ if(debug_) dbg("Simple authentication failed."); lastError_="Simple Authentication failed."; errorCode_=2; sendResultActions(NULL); return; } if(debug_) dbg("Trying to authenticate using simple authentication..."); authenticator->setUser(authUsername_); authenticator->setPassword(authPassword_); simpleAuthAlreadyDone_=true; } void WebsiteSnapshot::complexAuthenticationRequired(bool success){ if(debug_) dbg("Trying to authenticate using complex authentication..."); if(!success){ //the login page didn't load correctly... if(debug_) dbg("The (login) page could not be loaded correctly."); lastError_="The (login) page could not be loaded correctly."; errorCode_=1; sendResultActions(NULL); return; } if(debug_) dbg("Waiting "+QString::number(complexAuthInitialWait_)+" seconds prior to complex authentication..."); priorComplexTimer_.start(complexAuthInitialWait_*1000); } void WebsiteSnapshot::proceedToComplexAuth(){ //search for username/password fields. QWebElement document = webPage_->mainFrame()->documentElement(); //searching for username... if(!searchAndSet(document, "input[type=text]", "id", authUsername_, usernameSearchFields_) && !searchAndSet(document, "input[type=email]", "id", authUsername_, usernameSearchFields_) && !searchAndSet(document, "input[type=username]", "id", authUsername_, usernameSearchFields_)){ lastError_="The username and/or password fields were not found."; errorCode_=3; if(debug_) dbg("Could not find the username field."); sendResultActions(NULL); return; } //searching for password... if(!searchAndSet(document, "input[type=password]", "id", authPassword_, passwordSearchFields_)){ lastError_="The username and/or password fields were not found."; errorCode_=3; if(debug_) dbg("Could not find the password field."); sendResultActions(NULL); return; } if(debug_) dbg("The username and password fields have been filled."); disconnectWebPage(); webPage_->settings()->setAttribute(QWebSettings::AutoLoadImages, loadImagesEnabled_); decideFinalPage(); if(debug_) dbg("Pressing [Return] to attempt login..."); webPage_->event(new QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier)); } void WebsiteSnapshot::decideFinalPage(){ if(urlAfterAuth_==webPage_->currentFrame()->url()){ if(debug_) dbg("The final url is the same with the log-in page url. The resulted page will be snapshoted."); //stay at the resulted page connect(webPage_, SIGNAL(loadFinished(bool)), this, SLOT(returnResults(bool))); } else { if(debug_) dbg("The final url is "+urlAfterAuth_.url()+". This is the url that will be loaded after logging in."); //have to go to another page connect(webPage_, SIGNAL(loadFinished(bool)), this, SLOT(afterAuthNavigation(bool))); } } void WebsiteSnapshot::dbg(const QString &string){ qDebug() << "WebsiteSnapshot: "+string; } void WebsiteSnapshot::timeoutReached(){ if(debug_) dbg("The timeout has been reached and the page has not finished loading."); lastError_="Timeout has been reached."; errorCode_=4; sendResultActions(NULL); } bool WebsiteSnapshot::searchAndSet(const QWebElement &document, const QString &searchFor, const QString &attribute, const QString &value, const QStringList &searchFields){ if(debug_) dbg("Searching for '"+searchFor+"' with attribute '"+attribute+"'"); QWebElementCollection collection; //searching username... collection = document.findAll(searchFor); short count=collection.count(); QWebElement curElement; for(short i=0;itriggerAction(QWebPage::Stop); webPage_->deleteLater(); Q_EMIT resultedImage(image, errorCode_); currentlyLoading_=false; } void WebsiteSnapshot::webPageDestroyed(){ webPage_=NULL; } void WebsiteSnapshot::initializeWebPage(){ webPage_ = new CustomWebPage(); connect(webPage_, SIGNAL(destroyed()), this, SLOT(webPageDestroyed())); QWebSettings *settings = webPage_->settings(); settings->setAttribute(QWebSettings::JavascriptEnabled, javascriptEnabled_); settings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, javascriptCanAccessClipboard_); settings->setAttribute(QWebSettings::JavaEnabled, javaEnabled_); settings->setAttribute(QWebSettings::AutoLoadImages, loadImagesEnabled_); settings->setAttribute(QWebSettings::JavascriptCanOpenWindows, false); settings->setAttribute(QWebSettings::NotificationsEnabled, false); settings->setAttribute(QWebSettings::PluginsEnabled, false); } void WebsiteSnapshot::disconnectWebPage(){ if(webPage_==NULL) return; disconnect(webPage_, SIGNAL(loadFinished(bool)), this, SLOT(returnResults(bool))); disconnect(webPage_, SIGNAL(loadFinished(bool)), this, SLOT(complexAuthenticationRequired(bool))); disconnect(webPage_, SIGNAL(loadFinished(bool)), this, SLOT(afterAuthNavigation(bool))); disconnect(webPage_->networkAccessManager(), SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticateSimple(QNetworkReply*,QAuthenticator*))); } /*PUBLIC FUNCTIONS*/ bool WebsiteSnapshot::start(){ if(currentlyLoading_ || requestedUrl_==QUrl("") || !requestedUrl_.isValid()){ return false; } else { if(debug_) dbg("Initializing webpage and starting the process..."); lastError_="No error."; errorCode_=0; currentlyLoading_=true; if(webPage_!=NULL){ disconnectWebPage(); webPage_->deleteLater(); } initializeWebPage(); switch(authenticationLevel_){ case NoAuthentication: connect(webPage_, SIGNAL(loadFinished(bool)), this, SLOT(returnResults(bool))); break; case SimpleAuthentication: simpleAuthAlreadyDone_=false; connect(webPage_->networkAccessManager(), SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticateSimple(QNetworkReply*,QAuthenticator*))); decideFinalPage(); break; case ComplexAuthentication: //disable image loading on log-in pages. webPage_->settings()->setAttribute(QWebSettings::AutoLoadImages, false); connect(webPage_, SIGNAL(loadFinished(bool)), this, SLOT(complexAuthenticationRequired(bool))); break; default: break; } if(debug_) dbg("Setting viewport size to QSize("+QString::number(minWidth_)+", "+QString::number(minHeight_)+"), and loading "+requestedUrl_.url()); webPage_->setViewportSize(QSize(minWidth_, minHeight_)); webPage_->setPreferredContentsSize(QSize(minWidth_, minHeight_)); webPage_->currentFrame()->load(requestedUrl_); timeoutTimer_.start(timeout_*1000); return true; } } void WebsiteSnapshot::stop(){ if(timeoutTimer_.isActive()) timeoutTimer_.stop(); if(afterFinishTimer_.isActive()) afterFinishTimer_.stop(); if(priorComplexTimer_.isActive()) priorComplexTimer_.stop(); if(webPage_!=NULL){ disconnectWebPage(); webPage_->triggerAction(QWebPage::Stop); webPage_->deleteLater(); } currentlyLoading_=false; } void WebsiteSnapshot::setParameters(QUrl url, const short &width, const short &height){ if(isLoading()) return; parseUrl(url); requestedUrl_=url; minWidth_=width; minHeight_=height; } void WebsiteSnapshot::setCrop(bool enabled, const QRect &rectCrop){ cropImage_=enabled; cropRect_=rectCrop; } void WebsiteSnapshot::setTimeout(unsigned const int &secondsTimeout){ if(isLoading()) return; timeout_=secondsTimeout; } void WebsiteSnapshot::setJavascriptConfig(bool enabled, bool canAccessClipboard){ javascriptEnabled_=enabled; javascriptCanAccessClipboard_=canAccessClipboard; } void WebsiteSnapshot::setJavaEnabled(bool enabled){ javaEnabled_=enabled; } void WebsiteSnapshot::setLoadImagesEnabled(bool enabled){ loadImagesEnabled_=enabled; } void WebsiteSnapshot::setSimpleAuthentication(const QString &username, const QString &password, const QString &finalUrl){ if(isLoading()) return; authUsername_=username; authPassword_=password; authenticationLevel_=SimpleAuthentication; urlAfterAuth_=QUrl(finalUrl); } void WebsiteSnapshot::setComplexAuthentication(const QString &username, const QString &password, const QString &finalUrl){ if(isLoading()) return; authUsername_=username; authPassword_=password; authenticationLevel_=ComplexAuthentication; urlAfterAuth_=QUrl(finalUrl); usernameSearchFields_=USUAL_USERNAME_FIELDS; passwordSearchFields_=USUAL_PASSWORD_FIELDS; } void WebsiteSnapshot::setComplexAuthenticationWithPossibleFields(const QString &username, const QString &password, const QString &finalUrl, const QStringList &usernameFields, const QStringList &passwordFields, bool tryUsualFields){ if(isLoading()) return; authUsername_=username; authPassword_=password; authenticationLevel_=ComplexAuthentication; urlAfterAuth_=QUrl(finalUrl); usernameSearchFields_ = usernameFields; passwordSearchFields_ = passwordFields; if(tryUsualFields){ usernameSearchFields_ << USUAL_USERNAME_FIELDS; passwordSearchFields_ << USUAL_PASSWORD_FIELDS; } usernameSearchFields_.removeDuplicates(); passwordSearchFields_.removeDuplicates(); } void WebsiteSnapshot::disableAuthentication(){ if(isLoading()) return; authenticationLevel_=NoAuthentication; } void WebsiteSnapshot::setComplexAuthenticationInitialWait(const unsigned short &seconds){ complexAuthInitialWait_=seconds; } void WebsiteSnapshot::setWaitAfterFinish(const unsigned short &secondsWait){ waitAfterFinish_=secondsWait; } bool WebsiteSnapshot::isLoading(){ return currentlyLoading_; } void WebsiteSnapshot::setDebugEnabled(bool enabled){ debug_=enabled; } QString WebsiteSnapshot::url(){ switch(authenticationLevel_){ default: case NoAuthentication: return requestedUrl_.url(); break; case SimpleAuthentication: case ComplexAuthentication: return urlAfterAuth_.url(); break; } } QString WebsiteSnapshot::lastErrorString(){ return lastError_; } QObject *WebsiteSnapshot::asQObject(){ return this; } wallch-4.0/src/crop_image.cpp0000644000175000017500000001712112301477401014674 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include #include #include #include "crop_image.h" #include "ui_crop_image.h" #include "glob.h" #define PEN_COLOR 0, 0, 0, 180 #define BRUSH_COLOR 255, 255, 255, 120 CropImage::CropImage(QImage *image, const QRect &curCropRect, QWidget *parent) : QDialog(parent), ui(new Ui::crop_image) { ui->setupUi(this); selectionStarted_=shiftKeyDown_=false; websiteImage_=image; imageWidth_=websiteImage_->width(); imageHeight_=websiteImage_->height(); createButtonsLayout(); image_label = new CropLabel(this); image_label->setSelectionRect(curCropRect); image_label->setMinimumSize(imageWidth_, imageHeight_); image_label->setPixmap(QPixmap::fromImage(*websiteImage_)); mainLayout_ = new QVBoxLayout; image_label->setToolTip(tr("If you want to select a large area,\njust click on the beggining of it,\nhold the Shift key and click on the end of it.")); ui->scrollArea->setWidget(image_label); mainLayout_->addWidget(ui->scrollArea); mainLayout_->addLayout(buttonsLayout_); setLayout(mainLayout_); ui->scrollArea->setMaximumWidth(imageWidth_); ui->scrollArea->setMaximumHeight(imageHeight_); (void) new QShortcut(Qt::Key_Escape, this, SLOT(close())); } CropLabel::CropLabel(QWidget *parent) : QLabel(parent) { this->setCursor(Qt::CrossCursor); } CropImage::~CropImage() { delete websiteImage_; delete ui; } void CropImage::createButtonsLayout() { buttonsLayout_ = new QHBoxLayout; buttonsLayout_->addStretch(); buttonsLayout_->addWidget(ui->coordinates); buttonsLayout_->addWidget(ui->cancel); buttonsLayout_->addWidget(ui->ok); } void CropLabel::paintEvent(QPaintEvent *e) { QLabel::paintEvent(e); QPainter painter(this); painter.setPen(QPen(QBrush(QColor(PEN_COLOR)), 4, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin)); painter.setBrush(QBrush(QColor(BRUSH_COLOR))); painter.drawRect(selectionRect_); } void CropImage::mousePressEvent(QMouseEvent *e) { selectionStarted_=true; QPoint point=ui->scrollArea->mapFromParent(e->pos()+QPoint(ui->scrollArea->horizontalScrollBar()->value(), ui->scrollArea->verticalScrollBar()->value())); if(shiftKeyDown_){ pointX_=point.x(); pointY_=point.y(); image_label->selectionRect().setBottomRight(point); image_label->update(); int x=image_label->selectionRect().topLeft().x(); int y=image_label->selectionRect().topLeft().y(); int w=pointX_-image_label->selectionRect().topLeft().x(); int h=pointY_-image_label->selectionRect().topLeft().y(); ui->coordinates->setText("("+QString::number(x)+", "+QString::number(y)+", "+QString::number(w)+", "+QString::number(h)+")"); } else { image_label->selectionRect().setTopLeft(point); image_label->selectionRect().setBottomRight(point); } } void CropImage::mouseMoveEvent(QMouseEvent *e) { if (selectionStarted_) { QPoint point=ui->scrollArea->mapFromParent(e->pos()+QPoint(ui->scrollArea->horizontalScrollBar()->value(), ui->scrollArea->verticalScrollBar()->value())); pointX_=point.x(); pointY_=point.y(); if(pointX_>imageWidth_ || pointY_>imageHeight_ || pointX_<0 || pointY_<0){ return; } image_label->selectionRect().setBottomRight(point); repaint(); image_label->update(); int x=image_label->selectionRect().topLeft().x(); int y=image_label->selectionRect().topLeft().y(); int w=pointX_-image_label->selectionRect().topLeft().x(); int h=pointY_-image_label->selectionRect().topLeft().y(); ui->coordinates->setText("("+QString::number(x)+", "+QString::number(y)+", "+QString::number(w)+", "+QString::number(h)+")"); if((y+h-ui->scrollArea->verticalScrollBar()->value())>ui->scrollArea->height()-15){ moveScroll(1); } if(x+w-ui->scrollArea->horizontalScrollBar()->value()>ui->scrollArea->width()-15){ moveScroll(2); } if(y+hscrollArea->verticalScrollBar()->value()+15){ moveScroll(3); } if(x+wscrollArea->horizontalScrollBar()->value()+15){ moveScroll(4); } } } void CropImage::mouseReleaseEvent() { selectionStarted_=false; } void CropImage::moveScroll(short direction){ /* * Moves the scrollbars, depending on the direction. * this is being done when the pointer hits to the edges of the scrollbar * 'direction': * 1 = down, 2 = right, 3 = up, 4 = left */ switch(direction){ case 1: ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->value()+10); break; case 2: ui->scrollArea->horizontalScrollBar()->setValue(ui->scrollArea->horizontalScrollBar()->value()+10); break; case 3: ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->value()-10); break; case 4: ui->scrollArea->horizontalScrollBar()->setValue(ui->scrollArea->horizontalScrollBar()->value()-10); break; default: break; } } void CropImage::on_cancel_clicked() { this->close(); } void CropImage::sendNewCoordinates(QRect coords){ /* * If something is negative, make it like the rectangle started from the (last) top left edge of it * because QImage::copy() doesn't seem to accept negatives as width and height. */ int old_width = coords.width(); int old_height = coords.height(); if(old_width<0){ coords.setX(coords.x()+old_width); coords.setWidth(-1*old_width); } if(old_height<0){ coords.setY(coords.y()+old_height); coords.setHeight(-1*old_height); } websiteImage_->copy(coords).save(gv.wallchHomePath+LW_PREVIEW_IMAGE, "PNG", 100); Q_EMIT coordinates(coords); } void CropImage::on_ok_clicked() { sendNewCoordinates(image_label->selectionRect()); this->close(); } void CropImage::keyPressEvent(QKeyEvent *event){ /* * This is a way to detect if the shift key is down when the * user clicks on the website image. I know that this doesn't * work in the (extremely) rare case that: * User holds shift, clicks on image, Wallch loses focus for some * reason, user releases the Shift key, Wallch gains focus again. * Now Wallch thinks that user holds the Shift key while he does not. * I tried to solve it with focusOutEvent() signal without success. */ if(static_cast(event)->key() == Qt::Key_Shift){ shiftKeyDown_=true; } } void CropImage::keyReleaseEvent(QKeyEvent *event){ if(static_cast(event)->key() == Qt::Key_Shift){ shiftKeyDown_=false; } } wallch-4.0/src/preferences.ui0000644000175000017500000014502212301477401014725 0ustar alexalex preferences 0 0 641 561 false Preferences :/icons/Pictures/wallpaper.png:/icons/Pictures/wallpaper.png 0 0 0 0 64 16777215 64 QWidget { background-image: url(:/icons/Pictures/ambiance_not_checked.png); } 0 0 0 0 0 0 64 Ubuntu 10 50 false false Qt::NoFocus QPushButton:checked:!hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton:checked:hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton { color: white; background-image: url(:/icons/Pictures/ambiance_not_checked.png); font: 10pt "Ubuntu"; border: 0px; } General 25 25 true true true tabsButtonGroup 1 0 1 16777215 :/icons/Pictures/ambiance_separator.png 0 64 Ubuntu 10 50 false false Qt::NoFocus QPushButton:checked:!hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton:checked:hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton { color: white; background-image: url(:/icons/Pictures/ambiance_not_checked.png); font: 10pt "Ubuntu"; border: 0px; } Wallpapers 32 32 true false false true tabsButtonGroup 1 1 1 16777215 :/icons/Pictures/ambiance_separator.png 0 64 Ubuntu 10 50 false false Qt::NoFocus QPushButton:checked:!hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton:checked:hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton { color: white; background-image: url(:/icons/Pictures/ambiance_not_checked.png); font: 10pt "Ubuntu"; border: 0px; } Live Website 30 30 true true true tabsButtonGroup 1 0 1 16777215 :/icons/Pictures/ambiance_separator.png 0 64 Ubuntu 10 50 false false Qt::NoFocus QPushButton:checked:!hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton:checked:hover { color: white; background-image: url(:/icons/Pictures/ambiance_checked_and_hovered.png); font: 10pt "Ubuntu"; border: 0px; } QPushButton { color: white; background-image: url(:/icons/Pictures/ambiance_not_checked.png); font: 10pt "Ubuntu"; border: 0px; } Integration 30 30 true true tabsButtonGroup 0 Qt::NoFocus Notification on Wallpaper change 15 Qt::NoFocus For wallpaper clocks, show notification only when hour changes Qt::NoFocus Keep History of wallpapers changed true Qt::NoFocus Interval independent of application close true Qt::NoFocus Show preview screen true 4 11 50 false Language: 150 0 Qt::NoFocus 0 English (en) Greek (el) 9 true (You will need to restart Wallch) Qt::Horizontal 40 20 Qt::Horizontal Qt::NoFocus Start Wallch on System's startup true 9 true It will continue the feature that was previously running 35 15 Qt::NoFocus If the feature that was previously running was 'Wallpapers', Wallch will pick a random picture and change the desktop background once at System Startup 17 11 Startup timeout: 9999 11 seconds Qt::Horizontal 40 20 9 true Wallch will wait the above time before launching 35 Qt::Vertical 17 91 75 true true Below settings change the behaviour only for the 'Wallpapers' feature Qt::AlignCenter Qt::Horizontal Qt::NoFocus Rotate image on change, based on Exif data (will alter image) 550 30 0 5 341 22 0 0 Qt::NoFocus Use Shortcut for the "Next Wallpaper": Qt::Horizontal 40 20 Qt::NoFocus On clicking 'Start' first timeout then change wallpaper 0 50 false Style of list: Qt::NoFocus Icons true listTypeButtonGroup Qt::NoFocus Paths listTypeButtonGroup Qt::Horizontal 40 20 Qt::Horizontal true Set Up Custom Intervals 1 1000 second(s) minute(s) hour(s) day(s) Qt::Horizontal 40 20 100 27 Qt::NoFocus Add Qt::Horizontal 40 20 Qt::Vertical 20 40 100 27 Qt::NoFocus Remove Qt::Horizontal 40 20 Qt::Horizontal 40 20 Qt::NoFocus Use random time instead of the above intervals: 35 false 0 0 50 false From: Qt::AlignCenter false 0 0 0 86399 1 10 false 0 0 10 0 16777215 16777215 0 QComboBox::AdjustToContents seconds minute(s) hour(s) false 0 0 50 false to: Qt::AlignCenter false 0 0 1 86400 1 20 false 0 QComboBox::AdjustToContents seconds minute(s) hour(s) Qt::Horizontal 40 20 75 true true Below settings change the behaviour only for the 'Live Website' feature Qt::AlignCenter Qt::Horizontal Qt::NoFocus Attempt simple (popup) login authentication After load is finished, prior to taking the snapshot, wait 20 3 seconds Qt::Horizontal 40 20 Qt::NoFocus Javascript is enabled true 15 Qt::NoFocus Javascript can read clipboard Qt::NoFocus Java is enabled Qt::NoFocus Load Images true Add more username fields (comma separated): Username or email Add more password fields (comma separated): Password Qt::Vertical 20 40 14 75 true Ubuntu Qt::AlignCenter 4 11 50 false Theme: 150 0 Ambiance Radiance Autodetect 9 true (Will also change indicator icon) Qt::Horizontal 40 20 Current Desktop Environment Unity-Gnome Gnome XFCE LXDE Mate 9 true (You will need to restart Wallch) Qt::Horizontal 40 20 50 false Qt::NoFocus Enable Unity ProgressBar Qt::Horizontal Qt::Vertical QSizePolicy::Expanding 20 185 10 10 Qt::NoFocus Help true false Qt::Horizontal 40 20 Qt::NoFocus Reset preferences to the default onces Reset Preferences true Qt::TabFocus &Close true true Qt::StrongFocus Save and close the dialog &Save true false stackedWidget widget_2 desktop_notification_checkbox clicked(bool) clocksNotifyCheckbox setEnabled(bool) 151 91 156 121 js_enabled clicked(bool) js_can_read_clipboard setEnabled(bool) 108 182 109 216 wallch-4.0/src/about.cpp0000644000175000017500000000707112301477401013704 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include "about.h" #include "ui_about.h" #include "glob.h" #include #include #include #define PERSON(name, email) name " <" email ">" #define TRANSLATION(translation) translation " Translation:" About::About(QWidget *parent) : QDialog(parent), ui(new Ui::about) { ui->setupUi(this); easterEggCounter_=0; ui->wallch_version_label->setText("Wallch "+QString::number(APP_VERSION, 'f', 1)); ui->website_label->setText(QString("%1").arg(tr("Website"))); ui->label_4->setText(QString::fromUtf8("© 2010-2014 ") + tr("The Wallch (Wallpaper Changer) authors")); ui->about_button->setChecked(true); ui->writtenBy->append(tr("In random order:")); if(rand()%2){ ui->writtenBy->append(PERSON("Leon Vitanos", "leon.vitanos@gmail.com")); ui->writtenBy->append(PERSON("Alex Solanos", "alexsol.developer@gmail.com")); } else { ui->writtenBy->append(PERSON("Alex Solanos", "alexsol.developer@gmail.com")); ui->writtenBy->append(PERSON("Leon Vitanos", "leon.vitanos@gmail.com")); } ui->translatedBy->append(TRANSLATION("Greek")); ui->translatedBy->append(PERSON("Leon Vitanos", "leon.vitanos@gmail.com")); ui->translatedBy->append(PERSON("Alex Solanos", "alexsol.developer@gmail.com")); ui->stackedWidget->setCurrentIndex(0); } About::~About() { delete ui; } void About::changeEvent(QEvent *e) { QDialog::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } void About::on_closeButton_clicked() { close(); } void About::on_about_button_clicked() { easterEggCounter_=0; ui->about_button->setChecked(true); ui->stackedWidget->setCurrentIndex(0); } void About::on_credits_button_clicked() { if((++easterEggCounter_)==5){ QMessageBox::information(this, "Wallch", tr("Don't click it again.")); } else if(easterEggCounter_>5){ easterEggCounter_=0; Global::openUrl("http://www.youtube.com/watch?v=WibmcsEGLKo"); } ui->credits_button->setChecked(true); ui->stackedWidget->setCurrentIndex(1); } void About::on_license_button_clicked() { easterEggCounter_=0; ui->license_button->setChecked(true); ui->stackedWidget->setCurrentIndex(2); } void About::on_website_label_linkActivated() { Global::openUrl("http://melloristudio.com"); } wallch-4.0/src/notification.h0000644000175000017500000000271012301477401014720 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef NOTIFICATION_H #define NOTIFICATION_H #include namespace Ui { class Notification; } class Notification : public QDialog { Q_OBJECT public: explicit Notification(QString message, QString image, QWidget *parent = 0); ~Notification(); private: Ui::Notification *ui; QTimer *closeTimer_; private Q_SLOTS: void setupNotification(QString message, QString image); void closeNotification(); protected: void enterEvent(QEvent *); void leaveEvent(QEvent *); void mousePressEvent(QMouseEvent *); }; #endif // NOTIFICATION_H wallch-4.0/src/properties.h0000644000175000017500000000414712301477401014434 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PROPERTIES_H #define PROPERTIES_H #include #include #include #include #include namespace Ui { class properties; } class Properties : public QDialog { Q_OBJECT public: explicit Properties(const QString &img, bool showNextPrevious, int currentIndex, QWidget *parent = 0); ~Properties(); protected: void resizeEvent(QResizeEvent *event); private: Ui::properties *ui; QGroupBox *optionsGroupBox_; QPixmap currentPixmap_; QGridLayout *optionsGroupBoxLayout_; QVBoxLayout *mainLayout_; QHBoxLayout *buttonsLayout_; QTimer *nextPreviousTimer_; QString currentFilename_; int currentIndex_; void updateScreenshotLabel(); QString sizeToNiceString(qint64 fsize); private Q_SLOTS: void on_close_clicked(); void on_previous_clicked(); void on_next_clicked(); void on_set_as_background_clicked(); void on_open_location_button_clicked(); void simulateNext(); void simulatePrevious(); void uncheckButtons(); void updateEntries(const QString &filename, int currentIndex); Q_SIGNALS: void requestNext(int currentIndex_); void requestPrevious(int currentIndex_); void newAverageColor(QString currentFilename); }; #endif // PROPERTIES_H wallch-4.0/src/colors_gradients.cpp0000644000175000017500000003307412301477401016135 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "colors_gradients.h" #include "ui_colors_gradients.h" #include #include #ifdef ON_WIN32 #include #include #include #endif ColorsGradients::ColorsGradients(QWidget *parent) : QDialog(parent), ui(new Ui::colors_gradients) { ui->setupUi(this); #ifdef ON_LINUX ColoringType coloringType; coloringType=Global::getColoringType(); if(coloringType==SolidColor){ ui->solid_radioButton->setChecked(true); actionForSecondaryButtons(false); } else if(coloringType==VerticalColor){ ui->vertical_radioButton->setChecked(true); actionForSecondaryButtons(true); } else if(coloringType==HorizontalColor){ ui->horizontal_radioButton->setChecked(true); actionForSecondaryButtons(true); } #else QString res = settings->value("ShadingType", "solid").toString(); if(res == "solid"){ ui->solid_radioButton->setChecked(true); actionForSecondaryButtons(false); } else if(res == "vertical" || res=="vertical-gradient"){ ui->vertical_radioButton->setChecked(true); actionForSecondaryButtons(true); } else if(res == "horizontal-gradient"){ ui->horizontal_radioButton->setChecked(true); actionForSecondaryButtons(true); } #endif //#ifdef ON_LINUX //determining current primary color QString res1; #ifdef ON_LINUX res1=Global::getPrimaryColor(); #else int Elements[1] = {COLOR_BACKGROUND}; DWORD currentColors[1]; currentColors[0] = GetSysColor(Elements[0]); res1=QColor(GetRValue(currentColors[0]), GetGValue(currentColors[0]), GetBValue(currentColors[0])).name(); #endif QImage image(60, 60, QImage::Format_ARGB32_Premultiplied); primaryColor_=res1; image.fill(primaryColor_); ui->primary_color_button->setIcon(QIcon(QPixmap::fromImage(image))); //determining secondary color QString res2; #ifdef ON_LINUX res2=Global::getSecondaryColor(); #endif secondaryColor_=res2; QImage image2(60, 60, QImage::Format_ARGB32_Premultiplied); image2.fill(secondaryColor_); ui->secondary_color_button->setIcon(QIcon(QPixmap::fromImage(image2))); updateGradientsOnlyColors(false); if(gv.setAverageColor) { ui->average_color_checkbox->setChecked(true); on_average_color_checkbox_clicked(true); } } ColorsGradients::~ColorsGradients() { delete ui; } void ColorsGradients::on_average_color_checkbox_clicked(bool checked) { ui->primary_color_button->setEnabled(!checked); ui->change_order->setEnabled(!checked); gv.setAverageColor=ui->average_color_checkbox->isChecked(); settings->setValue("average_color", gv.setAverageColor); settings->sync(); if(gv.setAverageColor) { QImage img = QImage(Global::currentBackgroundImage()); if(!img.isNull()){ primaryColor_=QColor::fromRgb(img.scaled(1, 1, Qt::IgnoreAspectRatio, Qt::FastTransformation).pixel(0, 0)).name(); setDesktopColor(primaryColor_); updateGradientsOnlyColors(true); } } if(gv.previewImagesOnScreen){ Q_EMIT updateTv(); } } void ColorsGradients::updateGradientsOnlyColors(bool updateLeftRightSolid){ /* * If updateLeftRightSolid is true then all the buttons are updated, * if it is false, then only the top buttons are updated */ QImage image(70, 70, QImage::Format_RGB32); image.fill(Qt::white); QColor color(primaryColor_); image.fill(color); if(updateLeftRightSolid) { QIcon pri_icon=QIcon(QPixmap::fromImage(image.scaled(60, 60, Qt::IgnoreAspectRatio, Qt::FastTransformation))); ui->primary_color_button->setIcon(pri_icon); } if(ui->solid_radioButton->isChecked()){ Q_EMIT updateColorButtonSignal(image); } /* * We drastically reduce the alpha after the middle * of the image such as the second color not to be * so visible then. */ color.setNamedColor(secondaryColor_); short alpha=255; short softness=0; QPainter paint; paint.begin(&image); //every pixel will be drawn with a different color for(short i=70;i>0;i--){ if(!softness){ alpha-=1; if(alpha<=244){ softness=1; } } else if(softness==1){ alpha-=3; if(alpha<=205){ softness=2; } } else if(softness==2){ alpha-=4; } color.setAlpha(alpha); paint.fillRect(i-1, 0, 1, 70, QColor(color)); } paint.end(); if(ui->horizontal_radioButton->isChecked()) { Q_EMIT updateColorButtonSignal(image); ui->result->setPixmap(QPixmap::fromImage(image)); } if(ui->vertical_radioButton->isChecked()) { QTransform rot;rot.rotate(+90); image = image.transformed(rot, Qt::SmoothTransformation); Q_EMIT updateColorButtonSignal(image); ui->result->setPixmap(QPixmap::fromImage(image)); } if(updateLeftRightSolid){ image.fill(color); ui->secondary_color_button->setIcon(QIcon(QPixmap::fromImage(image.scaled(60, 60, Qt::IgnoreAspectRatio, Qt::FastTransformation)))); } } void ColorsGradients::on_saveButton_clicked() { close(); } void ColorsGradients::on_primary_color_button_clicked() { QColor initial = QColor::fromRgb(ui->primary_color_button->icon().pixmap(QSize(5,5), QIcon::Normal, QIcon::On).toImage().pixel(1,1)); QColorDialog::ColorDialogOptions options = QFlag(0); QColor color = QColorDialog::getColor(initial, this, tr("Select Color"), options); if(!color.isValid()){ return; } primaryColor_=color.name(); setDesktopColor(primaryColor_); Q_EMIT updateDesktopColor(primaryColor_); updateGradientsOnlyColors(true); if(gv.previewImagesOnScreen){ Q_EMIT updateTv(); } } void ColorsGradients::setDesktopColor(const QString &colorName){ #ifdef ON_LINUX Global::setPrimaryColor(colorName); #else QColor color = colorName; QSettings color_setting("HKEY_CURRENT_USER\\Control Panel\\Colors", QSettings::NativeFormat); color_setting.setValue("Background", QString::number(color.red())+' '+QString::number(color.green())+' '+QString::number(color.blue())); int Elements[1] = {COLOR_BACKGROUND}; DWORD NewColors[1]; NewColors[0] = RGB(color.red(), color.green(), color.blue()); SetSysColors(1, Elements, NewColors); #endif } void ColorsGradients::on_secondary_color_button_clicked() { QColor initial = QColor::fromRgb(ui->secondary_color_button->icon().pixmap(QSize(5,5), QIcon::Normal, QIcon::On).toImage().pixel(1,1)); QColorDialog::ColorDialogOptions options = QFlag(0); QColor color = QColorDialog::getColor(initial, this, "Select Color", options); if(!color.isValid()){ return; } #ifdef ON_LINUX secondaryColor_=color.name(); setDesktopSecondaryColor(secondaryColor_); #endif updateGradientsOnlyColors(true); if(gv.previewImagesOnScreen){ Q_EMIT updateTv(); } } #ifdef ON_LINUX void ColorsGradients::setDesktopSecondaryColor(const QString &colorName){ Global::setSecondaryColor(colorName); } #endif void ColorsGradients::on_change_order_clicked() { //this turns the secondary color primary and vice versa... QString temp; temp=primaryColor_; primaryColor_=secondaryColor_; secondaryColor_=temp; setDesktopColor(primaryColor_); #ifdef ON_LINUX setDesktopSecondaryColor(secondaryColor_); #endif updateGradientsOnlyColors(true); if(gv.previewImagesOnScreen){ Q_EMIT updateTv(); } } void ColorsGradients::on_remove_background_clicked() { /* * Setting a 1x1 transparent image as desktop background. On Ubuntu 12.04 and back it would work to set an empty * string as desktop background, but it doesn't anymore (it rolls back to the default desktop background). This * solves any issue :) */ if(!QFile::exists(gv.wallchHomePath+NULL_IMAGE)){ QImage empty(1, 1, QImage::Format_ARGB32); empty.setPixel(0,0, qRgba(0, 0, 0, 0)); empty.save(gv.wallchHomePath+NULL_IMAGE, "PNG", 1); } Global::setBackground(gv.wallchHomePath+NULL_IMAGE, false, false, 0); } void ColorsGradients::actionForSecondaryButtons(bool action) { if(action) { ui->change_order->show(); ui->secondary_color_button->show(); ui->secondary_label->show(); ui->result_label->show(); ui->result->show(); } else { ui->change_order->hide(); ui->secondary_color_button->hide(); ui->secondary_label->hide(); ui->result_label->hide(); ui->result->hide(); } } void ColorsGradients::on_solid_radioButton_clicked() { #ifdef ON_LINUX if(gv.currentDE==Gnome || gv.currentDE==UnityGnome){ Global::gsettingsSet("org.gnome.desktop.background", "color-shading-type", "solid"); } else if(gv.currentDE==Mate){ Global::gsettingsSet("org.mate.background", "color-shading-type", "solid"); } else if(gv.currentDE==XFCE){ Q_FOREACH(QString entry, Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("color-style")){ QProcess::startDetached("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry << "-s" << "0"); } } } #else settings->setValue("ShadingType" , "solid"); #endif //#ifdef ON_LINUX ui->solid_radioButton->setChecked(true); actionForSecondaryButtons(false); if(gv.previewImagesOnScreen){ Q_EMIT updateTv(); } updateGradientsOnlyColors(false); } void ColorsGradients::on_horizontal_radioButton_clicked() { #ifdef ON_LINUX if(gv.currentDE==Gnome || gv.currentDE==UnityGnome){ Global::gsettingsSet("org.gnome.desktop.background", "color-shading-type", "horizontal"); } else if(gv.currentDE==Mate){ Global::gsettingsSet("org.mate.background", "color-shading-type", "horizontal-gradient"); } else if(gv.currentDE==XFCE){ Q_FOREACH(QString entry, Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("color-style")){ QProcess::startDetached("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry << "-s" << "1"); } } } #else settings->setValue("ShadingType" , "horizontal"); #endif //#ifdef ON_LINUX ui->horizontal_radioButton->setChecked(true); actionForSecondaryButtons(true); if(gv.previewImagesOnScreen){ Q_EMIT updateTv(); } updateGradientsOnlyColors(false); createVerticalHorizontalImage("horizontal"); } void ColorsGradients::on_vertical_radioButton_clicked() { #ifdef ON_LINUX if(gv.currentDE==Gnome || gv.currentDE==UnityGnome){ Global::gsettingsSet("org.gnome.desktop.background", "color-shading-type", "vertical"); } else if(gv.currentDE==Mate){ Global::gsettingsSet("org.mate.background", "color-shading-type", "vertical-gradient"); } else if(gv.currentDE==XFCE){ Q_FOREACH(QString entry, Global::getOutputOfCommand("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << "/backdrop" << "-l").split("\n")){ if(entry.contains("color-style")){ QProcess::startDetached("xfconf-query", QStringList() << "-c" << "xfce4-desktop" << "-p" << entry << "-s" << "2"); } } } #else settings->setValue("ShadingType" , "vertical"); #endif //#ifdef ON_LINUX ui->vertical_radioButton->setChecked(true); actionForSecondaryButtons(true); if(gv.previewImagesOnScreen){ Q_EMIT updateTv(); } updateGradientsOnlyColors(false); createVerticalHorizontalImage("vertical"); } QImage ColorsGradients::createVerticalHorizontalImage(const QString &type) { QImage image(gv.screenWidth, gv.screenHeight, QImage::Format_RGB32); image.fill(Qt::white); QPainter p; p.begin(&image); int rec_x1,rec_y1,rec_x2,rec_y2; if(type=="horizontal"){ rec_x1=gv.screenWidth/256+1 , rec_y1=0, rec_x2=gv.screenWidth, rec_y2=0; } else { rec_x1=0 , rec_y1=gv.screenHeight/256+1, rec_x2=0, rec_y2=gv.screenHeight; } QLinearGradient rect_gradient(rec_x1, rec_y1, rec_x2, rec_y2); rect_gradient.setColorAt(0, QColor(primaryColor_)); rect_gradient.setColorAt(1, QColor(secondaryColor_)); p.setBrush(rect_gradient); p.drawRect(0, 0, gv.screenWidth, gv.screenHeight); p.setCompositionMode(QPainter::CompositionMode_DestinationOver); p.setPen(Qt::NoPen); p.setRenderHint(QPainter::SmoothPixmapTransform); p.drawImage(QRect(0,0,gv.screenWidth,gv.screenHeight), image); return image; } wallch-4.0/src/potd_viewer.ui0000644000175000017500000001416212301477401014753 0ustar alexalex potd_viewer 0 0 565 550 Picture of the day viewer Qt::NoFocus Previous day 0 0 Qt::AlignCenter 0 0 0 2014 9 5 2004 11 1 d MMMM yyyy true Qt::NoFocus Next day 0 0 157 101 false Qt::AlignCenter 0 0 Qt::WheelFocus 24 Qt::Horizontal 40 20 100 0 Qt::NoFocus Save Image Qt::Horizontal 40 20 0 0 16777215 150 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> true true Qt::Horizontal 40 20 Close wallch-4.0/src/website_preview.cpp0000644000175000017500000001154712301477401016000 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_KEYWORDS #include "website_preview.h" #include "ui_website_preview.h" #include #include WebsitePreview::WebsitePreview(WebsiteSnapshot *websiteSnapshotP, bool show_crop_dialog, bool crop, QRect cropArea, QWidget *parent) : QDialog(parent), ui(new Ui::website_preview) { //removing the close button (X) to make it clear that you can only cancel the process... this->setWindowFlags(((windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowCloseButtonHint)); ui->setupUi(this); ui->secondary_label->hide(); forCropDialog_=show_crop_dialog; curCropArea_=cropArea; (void) new QShortcut(Qt::Key_Escape, this, SLOT(on_cancel_or_close_clicked())); websiteSnapshot_=websiteSnapshotP; websiteSnapshot_->setCrop(crop, curCropArea_); connect(websiteSnapshot_->asQObject(), SIGNAL(resultedImage(QImage*,short)), this, SLOT(imageReady(QImage*,short))); timeout_=WEBSITE_TIMEOUT; ui->preview_progress->show(); ui->counter_label->show(); ui->counter->show(); ui->counter->setText(QString::number(WEBSITE_TIMEOUT)); countdownTimer_ = new QTimer(this); connect(countdownTimer_, SIGNAL(timeout()), this, SLOT(reduceTimeoutByOne())); countdownTimer_->start(1000); websiteSnapshot_->start(); } WebsitePreview::~WebsitePreview() { disconnect(websiteSnapshot_->asQObject(), SIGNAL(resultedImage(QImage*,short)), this, SLOT(imageReady(QImage*,short))); delete ui; } void WebsitePreview::reduceTimeoutByOne(){ ui->counter->setText(QString::number(--timeout_)); if(timeout_<=0){ if(countdownTimer_->isActive()){ countdownTimer_->stop(); } } } void WebsitePreview::imageReady(QImage *image, short errorCode){ if(countdownTimer_->isActive()){ countdownTimer_->stop(); } if(errorCode==0 && !image->isNull()){ //no error! if(forCropDialog_){ beginCropDialog(image); } else { //just set it as preview Q_EMIT previewImageReady(image); closeDialog(); } } else { QString further_info; switch(errorCode){ case 1: further_info=tr("Some of the requested pages\nfailed to load successfully."); break; case 2: further_info=tr("Simple authentication failed.\nPlease check your username and/or password."); break; case 3: further_info=tr("Username and/or password fields are not found.\nPlease check that you are pointing at the login page."); break; case 4: further_info=tr("The timeout has been reached and the\nimage has yet to be created!"); break; default: further_info=tr("Unknown error! Please try with\na different web page."); break; } failWithMessage(further_info); } } void WebsitePreview::closeDialog(){ ui->main_label->setText(tr("Done!")); QTimer::singleShot(500, this, SLOT(on_cancel_or_close_clicked())); } void WebsitePreview::failWithMessage(const QString &further_info){ ui->preview_progress->hide(); ui->counter_label->hide(); ui->counter->hide(); ui->main_label->setText(tr("Failed!")); ui->secondary_label->show(); ui->secondary_label->setText(further_info); ui->cancel_or_close->setText(tr("Close")); this->adjustSize(); } void WebsitePreview::on_cancel_or_close_clicked() { if(websiteSnapshot_->isLoading()){ websiteSnapshot_->stop(); } this->close(); } void WebsitePreview::beginCropDialog(QImage *image){ cropImageDialog_ = new CropImage(image, curCropArea_, this); connect(cropImageDialog_, SIGNAL(coordinates(QRect)), this, SLOT(sendCoordinates(QRect))); this->close(); cropImageDialog_->exec(); cropImageDialog_->deleteLater(); } void WebsitePreview::sendCoordinates(const QRect &coords){ //sending the coordinates back to mainwindow. Q_EMIT sendExtraCoordinates(coords); } wallch-4.0/src/nongui.h0000644000175000017500000001635512301477401013543 0ustar alexalex/* Wallch - Wallpaper Changer A tool for changing Desktop Wallpapers automatically with lots of features Copyright © 2010-2014 by Alex Solanos and Leon Vitanos This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef NONGUI_H #define NONGUI_H #define QT_NO_KEYWORDS #include #include #include #include #include #include #include #include #include "properties.h" #include "preferences.h" #include "mainwindow.h" #include "about.h" #include "glob.h" #include "websitesnapshot.h" #define SOCKET_SERVER_NAME "Wallch Local Socket Server" class nonGUI : public QTimer { Q_OBJECT public: explicit nonGUI(QObject *parent = 0) : QTimer(parent) {} QTimer indicatorScrollTimer_; int startProgram(int argc, char *argv[]); void doAction(const QString &message); private: QFileSystemWatcher *watchFoldersMain_=NULL; Preferences *preferences_; QTimer researchFoldersTimerMain_; QTimer *updateSecondsPassed_; Properties *properties_; QSharedMemory *alreadyRunsMem_; QLocalServer *localServer_; QLocalSocket *socket_; QString messageToSendToServer_; WebsiteSnapshot *websiteSnapshot_=NULL; bool quitAfterMessage_; Global *globalParser_ = new Global(true); int totalSeconds_; int secondsLeft_; int currentImageIndex_; int wallpaperClocksTotalSeconds_; bool mainWindowLaunched_=false; bool startedWithJustChange_=false; bool startedWithLiveEarth_=false; bool startedWithPotd_=false; bool startedWithClock_=false; bool startedWithWebsite_=false; bool previousWasClicked_=false; bool wallpaperClocksMonthChecked_=false; bool wallpaperClocksDayOfMonthChecked_=false; bool wallpaperClocksDayOfWeekChecked_=false; bool wallpaperClocksAmPmChecked_=false; bool wallpaperClocksHourChecked_=false; bool wallpaperClocksMinutesChecked_=false; bool propertiesShown_=false; bool justUpdatedPotd_=false; QStringList previousPictures_; QStringList allPictures_; #ifdef ON_LINUX DbusmenuMenuitem *unityMenu_; GtkWidget *showAppOption_, *deleteCurrentImageOption_, *showPreferencesOption_, *showAboutOption_, *quitAppOption_, *copyPathOfCurImageOption_, *copyNameOfCurImageOption_, *openPathOfCurImageOption_, *deleteCurImageOption_, *propertiesOfCurImageOption_; #endif //#ifdef ON_LINUX #ifdef ON_WIN32 QSystemTrayIcon *trayIcon_; QMenu *trayIconMenu_; QMenu *currentImageMenu_; QAction *showWindowAction_; QAction *copyCurrentImagePathAction_; QAction *copyCurrentImageNameAction_; QAction *copyCurrentImageAction_; QAction *openCurrentImageFolderAction_; QAction *deleteCurrentImageAction_; QAction *openCurrentImagePropertiesAction_; QAction *wallpapersAction_; QAction *wallpapersOnceAction_; QAction *wallpapersPauseAction_; QAction *wallpapersNextAction_; QAction *wallpapersPreviousAction_; QAction *liveEarthAction_; QAction *pictureOfTheDayAction_; QAction *wallpaperClocksAction_; QAction *liveWebsiteAction_; QAction *preferencesAction_; QAction *aboutAction_; QAction *quitAction_; QTimer *doubleClick_; void setupTray(); #else void setupIndicator(); void updatePotdProgressMain(); void setUnityShortcutsState(bool stopState, bool pauseState, bool nextState, bool previousState); void setupUnityShortcuts(); #endif void viralSettingsOperations(); bool getPicturesLocation(bool init); bool alreadyRuns(); void getFilesFromFolder(const QString &path); void messageServer(const QString &message, bool quitAfterwards); void actionsOnWallpaperChange(); void setIndependentInterval(const QString &independentInterval); void checkSettings(bool allSettings); void connectMainwindowWithExternalActions(MainWindow *w); void resetWatchFolders(bool justDelete); void setDefaultFolderInSettings(const QString &folder); void fixCacheSizeGlobalCallback(); QString getCurrentWallpapersFolder(); std::string percentToProgressbar(short percentage); void clearCurrentLine(short previousOutputCount); bool loadWebsiteSnapshotPlugin(); void connectToServer(); void connectToUpdateSecondsSlot(); void disconnectFromSlot(); void connectToCheckInternet(); void continueWithLiveEarth(); void continueWithWebsite(); bool continueWithClock(); void continueWithPotd(bool checkInternetConnection); void changeWallpaperNow(); void getDelay(); void readPictures(const QString &folder); void potdSetSameImage(); void startStatisticsTimer(); private Q_SLOTS: void newSocketConnection(); void dirChanged(); void researchDirs(); #ifdef ON_LINUX void unityProgressbarSetEnabled(bool enabled); void indicatorBackToNormal(); void changeIndicatorIcon(QString theme); #else void trayActionShowWindow(); void trayActionCopyPath(); void trayActionCopyName(); void trayActionCopyImage(); void trayActionOpenCurrentImageFolder(); void trayActionDeleteCurrentImage(); void trayActionOpenCurrentImageProperties(); void trayActionWallpapers(); void trayActionWallpapersOnce(); void trayActionWallpapersPause(); void trayActionWallpapersNext(); void trayActionWallpapersPrevious(); void trayActionLiveEarth(); void trayActionPictureOfTheDay(); void trayActionWallpaperClocks(); void trayActionLiveWebsite(); void trayActionPreferences(); void trayActionAbout(); void trayActionQuit(); void createTray(); void uncheckRunningFeatureOnTray(); void trayActivatedActions(QSystemTrayIcon::ActivationReason reason); #endif //#ifdef ON_LINUX void socketConnected(); void socketError(); void quitNow(); void waitForInternetConnection(); void updateSeconds(); void checkPicOfDay(); void propertiesDestroyed(); void preferencesDestroyed(); void fixCacheSizeThreaded(); void liveWebsiteImageReady(QImage *image, short errorCode); void updateSecondsPassed(); Q_SIGNALS: void signalOnce(); void signalPause(); void signalNext(); void signalPrevious(); void signalFocus(); void signalStart(); void signalActivateLivearth(); void signalActivatePotd(); void signalActivateWallClocks(); void signalActivateLiveWebsite(); void closeWhatsRunning(); void signalShowPreferences(); void signalShowAbout(); void signalDeleteCurrent(); void signalInstallWallClock(QString wallClock); void signalAddFolderForMonitor(const QString &folder); void signalQuit(); }; extern nonGUI nongui; #endif // NONGUI_H wallch-4.0/uninstall.sh0000755000175000017500000000207012301477401013641 0ustar alexalex#!/bin/bash #Wallch Unonstallation file #Created by Alex Solanos for Wallch v4.0 error_report() { echo -ne "ERROR: $1"; } report_step(){ echo -ne "\n\n" echo "---- $1 ----" echo -ne "\n\n" } uninstall_now() { echo -ne "Uninstalling $1..." if [ -d "$2" ]; then #installing a directory rm -rf "$2" elif [ -f "$2" ]; then #installing a file rm -f "$2" else error_report "\"$2\" - No such file or directory. Skipping..." fi echo -ne "Done.\n" } if [[ $EUID != 0 ]]; then echo "Please run this uninstall script as root: sudo $0" exit 1 fi report_step "Uninstalling Wallch from your system" uninstall_now "wallch binary" "/usr/bin/wallch" uninstall_now "/usr/share files" "/usr/share/wallch" uninstall_now "bash autocompletion" "/etc/bash_completion.d/wallch" uninstall_now "manpage" "/usr/share/man/man1/wallch.1.gz" uninstall_now "program pixmap" "/usr/share/pixmaps/wallch.png" uninstall_now "desktop file" "/usr/share/applications/wallch-nautilus.desktop" report_step "Uninstallation finished. Thank you for using Wallch." wallch-4.0/README0000644000175000017500000000070612301477401012155 0ustar alexalex Wallch (Wallpaper Changer) Version 4.0 by Alex Solanos (alexsol.developer@gmail.com) and Leon Vytanos (leon.vitanos@gmail.com) SEE COPYING FILE FOR LICENSE INFO PLEASE! SEE INSTALL FIRE FOR INSTALLATION INFO PLEASE! You'll find helpful info at Help->Contents at the Menu of Wallch or 'man wallch'. Please report any bug you find (unless a report of it already exists) from the Help Menu of Wallch. Thanks for using Wallch and reading the READMEs. wallch-4.0/install.sh0000755000175000017500000000767112301477401013312 0ustar alexalex#!/bin/bash #Wallch Installation file #Original file made by Devyn Collier Johnson for Wallch v3.xx #Edited by Alex Solanos for Wallch v4.0 set -e error_report() { echo "ERROR: $1"; echo "Please report this at wallch.developers@gmail.com. Somebody will ACTUALLY have a look :)" exit 1 } report_step(){ echo -ne "\n\n" echo "---- $1 ----" echo -ne "\n\n" } install_now() { echo -ne "Installing $1..." if [ -d "$2" ]; then #installing a directory cp -r "$2" "$3" elif [ -f "$2" ]; then #installing a file cp "$2" "$3" else error_report "\"$2\" - No such file or directory." fi echo -ne "Done.\n" } install_tr() { echo -ne "Installing $1..." lrelease -silent "$1" -qm "$2" echo -ne "Done.\n" } if [[ $EUID != 0 ]]; then echo "Please run this install script as root: sudo $0" exit 1 fi report_step "Installing the needed packages" apt-get install debhelper qt5-qmake qttools5-dev-tools libqt5core5 libqt5widgets5 libqt5network5 libqt5dbus5 libnotify-dev libunity-dev libkeybinder-dev libdee-dev libexif-dev libappindicator-dev libglib2.0-dev qtdeclarative5-dev libqt5opengl5-dev libgstreamer-plugins-base0.10-dev libsqlite3-dev libxslt1-dev libqt5webkit5-dev || (error_report "installing build dependencies failed") apt-get install xdg-utils yelp unzip libstdc++6 libappindicator1 libc6 libdbusmenu-glib4 libexif12 libgcc1 libglib2.0-0 libgtk2.0-0 libnotify4 || (error_report "installing dependencies failed") report_step "Building the source code" if [ -f "wallch" ]; then echo "Weird, code seems compiled. Hard recompilation takes place." make clean rm -rf wallch Makefile fi qmake *.pro || (error_report "qmake failed") make || (error_report "make failed") report_step "Compiling translations" install_tr data/translations/wallch_bs.ts data/to_usr_share/wallch/translations/wallch_bs.qm install_tr data/translations/wallch_fr.ts data/to_usr_share/wallch/translations/wallch_fr.qm install_tr data/translations/wallch_nb.ts data/to_usr_share/wallch/translations/wallch_nb.qm install_tr data/translations/wallch_sk.ts data/to_usr_share/wallch/translations/wallch_sk.qm install_tr data/translations/wallch_da.ts data/to_usr_share/wallch/translations/wallch_da.qm install_tr data/translations/wallch_he.ts data/to_usr_share/wallch/translations/wallch_he.qm install_tr data/translations/wallch_pl.ts data/to_usr_share/wallch/translations/wallch_pl.qm install_tr data/translations/wallch_su.ts data/to_usr_share/wallch/translations/wallch_su.qm install_tr data/translations/wallch_el.ts data/to_usr_share/wallch/translations/wallch_el.qm install_tr data/translations/wallch_hr.ts data/to_usr_share/wallch/translations/wallch_hr.qm install_tr data/translations/wallch_pt.ts data/to_usr_share/wallch/translations/wallch_pt.qm install_tr data/translations/wallch_sv.ts data/to_usr_share/wallch/translations/wallch_sv.qm install_tr data/translations/wallch_es.ts data/to_usr_share/wallch/translations/wallch_es.qm install_tr data/translations/wallch_it.ts data/to_usr_share/wallch/translations/wallch_it.qm install_tr data/translations/wallch_ru.ts data/to_usr_share/wallch/translations/wallch_ru.qm install_tr data/translations/wallch_tr.ts data/to_usr_share/wallch/translations/wallch_tr.qm install_tr data/translations/wallch_de.ts data/to_usr_share/wallch/translations/wallch_de.qm install_tr data/translations/wallch_nl.ts data/to_usr_share/wallch/translations/wallch_nl.qm report_step "Installing Wallch to your system" install_now "wallch binary" "wallch" "/usr/bin/" install_now "/usr/share files" "data/to_usr_share/wallch/" "/usr/share/" install_now "bash autocompletion" "data/bash_autocompletion/wallch" "/etc/bash_completion.d/" install_now "manpage" "data/man/wallch.1.gz" "/usr/share/man/man1/" install_now "program pixmap" "data/pixmap/wallch.png" "/usr/share/pixmaps/" install_now "desktop file" "data/wallch-nautilus.desktop" "/usr/share/applications/" report_step "Installation finished. Thank you for using Wallch." wallch-4.0/COPYING0000644000175000017500000007640712301477401012343 0ustar alexalexVersion 3, 29 June 2007 Copyright © 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. “This License” refers to version 3 of the GNU General Public License. “Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. “The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. A “covered work” means either the unmodified Program or a work based on the Program. To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: * a) The work must carry prominent notices stating that you modified it, and giving a relevant date. * b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. * c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. * d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: * a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. * b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. * c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. * d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. * e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. “Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. “Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: * a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or * b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or * c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or * d) Limiting the use for publicity purposes of names of licensors or authors of the material; or * e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or * f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS wallch-4.0/wallch.pro0000644000175000017500000000375312301477401013276 0ustar alexalexTEMPLATE = app TARGET = wallch DEPENDPATH += . data/translations src/ INCLUDEPATH += . CONFIG += c++11 QT += network widgets webkitwidgets win32 { QT += gui-private DEFINES += ON_WIN32 } else { DEFINES += ON_LINUX CONFIG += link_pkgconfig PKGCONFIG += appindicator-0.1 unity libnotify libexif keybinder } isEmpty(PREFIX) { PREFIX = /usr } DEFINES += "PREFIX=\\\"$$PREFIX\\\"" # Input VPATH += ./src HEADERS += about.h \ glob.h \ history.h \ mainwindow.h \ preferences.h \ properties.h \ statistics.h \ website_preview.h \ crop_image.h \ colors_gradients.h \ nongui.h \ potd_viewer.h \ notification.h \ potd_preview.h \ websitesnapshot.h \ customwebpage.h FORMS += about.ui \ history.ui \ mainwindow.ui \ preferences.ui \ properties.ui \ statistics.ui \ website_preview.ui \ crop_image.ui \ colors_gradients.ui \ potd_viewer.ui \ notification.ui \ potd_preview.ui SOURCES += about.cpp \ glob.cpp \ history.cpp \ main.cpp \ mainwindow.cpp \ preferences.cpp \ properties.cpp \ statistics.cpp \ website_preview.cpp \ crop_image.cpp \ colors_gradients.cpp \ nongui.cpp \ potd_viewer.cpp \ notification.cpp \ potd_preview.cpp \ websitesnapshot.cpp RESOURCES += icons.qrc TRANSLATIONS += data/translations/wallch_el.ts configfiles.files += data/to_usr_share/* configfiles.path = $$PREFIX/share shortcutfiles.files += data/wallch-nautilus.desktop shortcutfiles.path = /usr/share/applications/ unix:configfiles.extra = lrelease -silent data/translations/wallch_el.ts -qm data/to_usr_share/wallch/translations/wallch_el.qm INSTALLS += shortcutfiles INSTALLS += configfiles wallch-4.0/debian/0000755000175000017500000000000012301477401012514 5ustar alexalexwallch-4.0/debian/rules0000644000175000017500000000022112301477401013564 0ustar alexalex#!/usr/bin/make -f # -*- makefile -*- # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 export QT_SELECT=qt5 %: dh $@ --parallel wallch-4.0/debian/compat0000644000175000017500000000000212301477401013712 0ustar alexalex8 wallch-4.0/debian/copyright0000644000175000017500000001221112301477401014444 0ustar alexalexFormat: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Wallch Upstream-Contact: Alex Solanos Source: http://melloristudio.com/wallch/ Files: * Copyright: 2010-2014, Alex Solanos 2010-2014, Leon Vytanos License: GPL-3+ This program 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. . This package 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 this program. If not, see . . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". Files: src/Pictures/page_1_earth.png Copyright: 2010, MajinCline License: public-domain The file is at: http://openclipart.org/detail/29188/globe-by-majincline-29188 Files: src/Pictures/page_2_potd.png Copyright: 2010, warszawianka License: public-domain The file is at: http://openclipart.org/detail/35239/tango-office-calendar-by-warszawianka Files: src/Pictures/page_3_clock.png src/Pictures/wallch.png Copyright: 2014, Anonymous License: public-domain The files can be found at the following links: http://openclipart.org/detail/119143/modern-clock-chris-kemps-01-by-anonymous http://openclipart.org/detail/32059/architetto----lucertola-arratolata-by-anonymous Files: src/Pictures/page_4_website.png Copyright: 2012, aseques License: public-domain The file is at: http://openclipart.org/detail/173206/network-wireless-clean-by-aseques-173206 Files: src/Pictures/ambiance_* src/Pictures/radiance_* data/to_usr_share/wallch/files/* src/Pictures/change.png src/Pictures/mellori-logo.png src/Pictures/monitor320x200.png src/Pictures/btn_donate_LG.gif src/Pictures/process_request.gif Copyright: 2014, Alex Solanos License: public-domain The files can be found at the following links: http://openclipart.org/detail/190995/ambiance-checked-button-background-color-by-hakermania-190995 http://openclipart.org/detail/190996/ambiance-checked-and-hovered-button-background-color-by-hakermania-190996 http://openclipart.org/detail/190997/ambiance-not-checked-button-background-color-by-hakermania-190997 http://openclipart.org/detail/190998/ambiance-button-separator-by-hakermania-190998 http://openclipart.org/detail/190999/radiance-button-separator-by-hakermania-190999 http://openclipart.org/detail/191000/radiance-checked-button-background-color-by-hakermania-191000 http://openclipart.org/detail/191001/radiance-checked-and-hovered-button-background-color-by-hakermania-191001 http://openclipart.org/detail/191006/wallch-indicator-ambiance-left-by-hakermania-191006 http://openclipart.org/detail/191007/wallch-indicator-ambiance-by-hakermania-191007 http://openclipart.org/detail/191008/wallch-indicator-ambiance-right-by-hakermania-191008 http://openclipart.org/detail/191009/wallch-indicator-radiance-left-by-hakermania-191009 http://openclipart.org/detail/191010/wallch-indicator-radiance-by-hakermania-191010 http://openclipart.org/detail/191011/wallch-indicator-radiance-right-by-hakermania-191011 http://openclipart.org/detail/191003/changeswitch-by-hakermania-191003 http://openclipart.org/detail/191005/mellori-studio-logo-by-hakermania-191005 http://openclipart.org/detail/191012/monitor-by-hakermania-191012 http://openclipart.org/detail/191013/donate-button-by-hakermania-191013 http://melloristudio.com/wallch/copyright Files: src/Pictures/application-exit.svg src/Pictures/applications-accessories.svg src/Pictures/folder.svg src/Pictures/go-down.svg src/Pictures/go-up.svg src/Pictures/image-loading.svg src/Pictures/info.svg src/Pictures/list-add.svg src/Pictures/list-remove.svg src/Pictures/media-* src/Pictures/preferences-desktop.svg src/Pictures/task-due.svg src/Pictures/window-close.svg Copyright: 2009, Daniel Fore 2009, Jonian Guveli 2009, K.Vishnoo Charan Reddy License: GPL-2 The files can be found in humanity-icon-theme package: http://packages.ubuntu.com/saucy/humanity-icon-theme License: GPL-2 This program 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 2 of the License, or (at your option) any later version. . This package 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 this program. If not, see . . On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". wallch-4.0/debian/install0000644000175000017500000000023612301477401014106 0ustar alexalexwallch /usr/bin/ data/bash_autocompletion/wallch /etc/bash_completion.d/ data/man/wallch.1.gz /usr/share/man/man1/ data/pixmap/wallch.png /usr/share/pixmaps/ wallch-4.0/debian/clean0000644000175000017500000000005312301477401013517 0ustar alexalexdata/to_usr_share/wallch/translations/*.qm wallch-4.0/debian/watch0000644000175000017500000000014012301477401013540 0ustar alexalexversion=3 http://sf.net/wall-changer/wallch_(\d\S*)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) wallch-4.0/debian/source/0000755000175000017500000000000012301477401014014 5ustar alexalexwallch-4.0/debian/source/format0000644000175000017500000000001412301477401015222 0ustar alexalex3.0 (quilt) wallch-4.0/debian/changelog0000644000175000017500000000021612301477401014365 0ustar alexalexwallch (4.01-1trusty) trusty; urgency=low * Beta release. -- Alex Solanos Mon, 10 Jan 2014 15:51:34 +0200 wallch-4.0/debian/control0000644000175000017500000000257512301477401014130 0ustar alexalexSource: wallch Section: utils Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Alex Solanos Build-Depends: debhelper (>= 8), qt5-qmake, libqt5core5, libqt5widgets5, qttools5-dev-tools, libqt5network5, libnotify-dev, libunity-dev, libkeybinder-dev, libdee-dev, libexif-dev, libappindicator-dev, libglib2.0-dev, qtdeclarative5-dev, libqt5opengl5-dev, libsqlite3-dev, libxslt1-dev, libqt5webkit5-dev Standards-Version: 3.9.5 Homepage: http://melloristudio.com/wallch/ Package: wallch Architecture: any Depends: unzip, ${misc:Depends}, ${shlibs:Depends} Description: wallpaper changer Wallch is a wallpaper changer for keeping your desktop fresh and new. It supports the following Desktop Environments: Gnome (with or without Unity integration), LXDE, XFCE and Mate. . Some random features: - Live Website - set as wallpaper any webpage you wish - Live Earth - a live picture of the earth - Picture Of The Day - taken from wikipedia, changing daily - Wallpaper Clocks - wallpapers that tell you the time - Folder Monitoring wallch-4.0/INSTALL0000644000175000017500000000052512301477401012325 0ustar alexalexTo install Wallch 4.0 please run: sudo ./install.sh This will install all the needed dependencies for building and running Wallch, it will compile the source code and it will move every needed file inside your filesystem. If you wish to uninstall Wallch, then run sudo ./uninstall.sh This will completely remove Wallch for your system.