1 /*******************************************************************************
2 *                         Goggles Music Manager                                *
3 ********************************************************************************
4 *           Copyright (C) 2006-2010 by Sander Jansen. All Rights Reserved      *
5 *                               ---                                            *
6 * This program is free software: you can redistribute it and/or modify         *
7 * it under the terms of the GNU General Public License as published by         *
8 * the Free Software Foundation, either version 3 of the License, or            *
9 * (at your option) any later version.                                          *
10 *                                                                              *
11 * This program is distributed in the hope that it will be useful,              *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of               *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                *
14 * GNU General Public License for more details.                                 *
15 *                                                                              *
16 * You should have received a copy of the GNU General Public License            *
17 * along with this program.  If not, see http://www.gnu.org/licenses.           *
18 ********************************************************************************/
19 #include "gmdefs.h"
20 #include "gmutils.h"
21 #include "GMIconTheme.h"
22 #include "GMApp.h"
23 #include "icons.h"
24 
25 #include <FXPNGImage.h>
26 #include <FXPNGIcon.h>
27 #include <FXJPGImage.h>
28 #include <FXJPGIcon.h>
29 
30 #define SMALL_SIZE 16
31 #define MEDIUM_SIZE 22
32 #define LARGE_SIZE 128
33 
save(FXStream & store)34 void GMIconSet::save(FXStream & store) {
35   store << name;
36   store << dir;
37   store << small;
38   store << medium;
39   store << large;
40   }
41 
42 
load(FXStream & store)43 void GMIconSet::load(FXStream & store) {
44   store >> name;
45   store >> dir;
46   store >> small;
47   store >> medium;
48   store >> large;
49   }
50 
51 
52 
init_basedirs(FXStringList & basedirs)53 static void init_basedirs(FXStringList & basedirs) {
54   FXString userdir  = FXSystem::getHomeDirectory() + PATHSEPSTRING ".icons";
55   FXString datadirs = FXSystem::getEnvironment("XDG_DATA_DIRS");
56   if (datadirs.empty()) datadirs = "/usr/local/share:/usr/share";
57 
58   FXDictionary pathdict;
59 
60   if (FXStat::exists(userdir)) {
61     pathdict.insert(userdir,(void*)(FXival)1);
62     basedirs.append(userdir);
63     }
64 
65   FXint no = datadirs.contains(":")+1;
66   for (FXint i=0;i<no;i++){
67     FXString dir = FXPath::expand(datadirs.section(':',i));
68     if (dir.empty()) continue;
69     if (dir[dir.length()-1]==PATHSEP)
70       dir += "icons";
71     else
72       dir += PATHSEPSTRING "icons";
73 
74     if (pathdict.has(dir) || !FXStat::exists(dir) ) continue;
75     basedirs.append(dir);
76     pathdict.insert(dir,(void*)(FXival)1);
77     }
78 
79   if (pathdict.has("/usr/share/pixmaps") && FXStat::exists("/usr/share/pixmaps"))
80     basedirs.append("/usr/share/pixmaps");
81 
82 #ifdef DEBUG
83   fxmessage("basedirs:\n");
84   for (FXint i=0;i<basedirs.no();i++){
85     fxmessage("\t%s\n",basedirs[i].text());
86     }
87 #endif
88   }
89 
init_themedict(FXStringList & basedirs,FXStringDictionary & themedict)90 static void init_themedict(FXStringList & basedirs,FXStringDictionary & themedict){
91   FXString * dirs=nullptr;
92   for (FXint i=0;i<basedirs.no();i++) {
93     FXint no = FXDir::listFiles(dirs,basedirs[i],"*",FXDir::AllDirs|FXDir::NoParent|FXDir::NoFiles);
94     if (no) {
95       for (FXint j=0;j<no;j++) {
96         if (!themedict.has(dirs[j]) && !FXStat::isLink(basedirs[i]+PATHSEPSTRING+dirs[j])) {
97           FXString index = basedirs[i]+PATHSEPSTRING+dirs[j]+PATHSEPSTRING+"index.theme";
98           if (FXStat::exists(index)) {
99             themedict.insert(dirs[j],index);
100             }
101           }
102         }
103       delete [] dirs;
104       dirs=nullptr;
105       }
106     }
107 #ifdef DEBUG
108   fxmessage("themes:\n");
109   for (FXint i=0;i<themedict.no();i++){
110     if (!themedict.empty(i))
111       fxmessage("\t%s\n",themedict.key(i).text());
112     }
113 #endif
114   }
115 
gm_set_application_icon(FXWindow * window)116 void gm_set_application_icon(FXWindow * window) {
117   FXPNGImage * image = new FXPNGImage(FXApp::instance(),gogglesmm_32_png,0,0);
118   ewmh_set_window_icon(window,image);
119   delete image;
120   }
121 
122 
123 
124 static const FXuint CACHE_FILE_VERSION = 20101108;
125 static const FXchar CACHE_FILE_NAME[]  = PATHSEPSTRING "icontheme.cache";
126 static const FXchar CACHE_SVG_NAME[] = PATHSEPSTRING "svg";
127 
128 
save_cache()129 void GMIconTheme::save_cache() {
130   const FXuint cache_file_version = CACHE_FILE_VERSION;
131 
132   FXString dirs;
133   for (FXint i=0;i<basedirs.no();i++) {
134     dirs+=basedirs[i] + ":";
135     }
136 
137   FXFileStream store;
138   if (store.open(GMApp::getCacheDirectory(true)+CACHE_FILE_NAME,FXStreamSave)) {
139     store << cache_file_version;
140     store << dirs;
141     store << smallsize;
142     store << mediumsize;
143     store << largesize;
144     FXint n = iconsets.no();
145     store << n;
146     for (FXint i=0;i<iconsets.no();i++) {
147       iconsets[i].save(store);
148       }
149     }
150  }
151 
152 
load_cache()153 FXbool GMIconTheme::load_cache() {
154   FXString cache_file = GMApp::getCacheDirectory()+CACHE_FILE_NAME;
155   FXString cache_dirs,dirs;
156   FXuint   cache_file_version;
157   FXint    cache_size;
158   FXint    n;
159   FXFileStream store;
160   FXTime theme_dir_date=0;
161   FXTime cache_dir_date=FXStat::modified(cache_file);
162 
163   /// Find last modified date for themedirs
164   for (FXint i=0;i<basedirs.no();i++) {
165     FXTime tm = FXStat::modified(basedirs[i]);
166     if (tm>theme_dir_date) theme_dir_date=tm;
167     }
168 
169   /// Any dirs newer, then reload.
170   if (theme_dir_date==0 || cache_dir_date==0 || theme_dir_date>cache_dir_date)
171     goto failed;
172 
173   if (store.open(GMApp::getCacheDirectory()+PATHSEPSTRING+"icontheme.cache",FXStreamLoad)) {
174 
175     store >> cache_file_version;
176     if (cache_file_version!=CACHE_FILE_VERSION)
177       goto failed;
178 
179     for (FXint i=0;i<basedirs.no();i++) {
180       dirs+=basedirs[i] + ":";
181       }
182 
183     store >> cache_dirs;
184     if (dirs!=cache_dirs)
185       goto failed;
186 
187     store >> cache_size;
188     if (cache_size!=smallsize)
189       goto failed;
190 
191     store >> cache_size;
192     if (cache_size!=mediumsize)
193       goto failed;
194 
195     store >> cache_size;
196     if (cache_size!=largesize)
197       goto failed;
198 
199     store >> n;
200     iconsets.no(n);
201     for (FXint i=0;i<iconsets.no();i++){
202       iconsets[i].load(store);
203       }
204 
205     return true;
206     }
207 
208 failed:
209   GM_DEBUG_PRINT("GMIconTheme::load_cache() - failed\n");
210   return false;
211   }
212 
213 
214 
215 
216 #if 0
217 static debug_iconsets(const GMIconSetList & iconsets){
218   for (FXint i=0;i<iconsets.no();i++){
219     fxmessage("----------------------------------------------\n");
220     fxmessage("Set %d\n",i);
221     fxmessage("\tname: %s\n",iconsets[i].name.text());
222     fxmessage("\tdir: %s\n",iconsets[i].dir.text());
223     fxmessage("\tSmall: %d\n",iconsets[i].smallsize);
224     for (FXint j=0;j<iconsets[i].small.no();j++){
225       fxmessage("\t\t%s\n",iconsets[i].small[j].text());
226       }
227     fxmessage("\tMedium: %d\n",iconsets[i].mediumsize);
228     for (FXint j=0;j<iconsets[i].medium.no();j++){
229       fxmessage("\t\t%s\n",iconsets[i].medium[j].text());
230       }
231     fxmessage("\tLarge: %d\n",iconsets[i].largesize);
232     for (FXint j=0;j<iconsets[i].large.no();j++){
233       fxmessage("\t\t%s\n",iconsets[i].large[j].text());
234       }
235     }
236   }
237 #endif
238 
239 
240 GMIconTheme * GMIconTheme::me=nullptr;
241 
GMIconTheme(FXApp * application)242 GMIconTheme::GMIconTheme(FXApp * application) : app(application), set(-1),rsvg(false) {
243   FXASSERT(me==nullptr);
244   me=this;
245 
246   smallsize  = app->reg().readIntEntry("user-interface","icon-theme-small-size",SMALL_SIZE);
247   mediumsize = app->reg().readIntEntry("user-interface","icon-theme-medium-size",MEDIUM_SIZE);
248   largesize  = app->reg().readIntEntry("user-interface","icon-theme-large-size",LARGE_SIZE);
249 
250   if (!FXPath::search(FXSystem::getEnvironment("PATH"),"rsvg-convert").empty()){
251     rsvg=true;
252     }
253 
254   init_basedirs(basedirs);
255   if (!load_cache()) {
256     clear_svg_cache();
257     build();
258     save_cache();
259     }
260 
261 
262   const FXString theme = app->reg().readStringEntry("user-interface","icon-theme","");
263   if (!theme.empty()) {
264 
265     for (FXint i=0;i<iconsets.no();i++){
266       if (compare(iconsets[i].dir,theme)==0) {
267         set=i;
268         break;
269         }
270       }
271     }
272 
273   cursor_hand=new FXGIFCursor(app,cursor_hand_gif,5,0);
274   cursor_hand->create();
275   }
276 
277 
~GMIconTheme()278 GMIconTheme::~GMIconTheme() {
279   }
280 
instance()281 GMIconTheme * GMIconTheme::instance(){
282   return me;
283   }
284 
285 
add_path(const FXStringList & list,const FXString & theme,const FXString & path,FXString & result)286 static void add_path(const FXStringList & list,const FXString & theme,const FXString & path,FXString & result) {
287   for (FXint i=0;i<list.no();i++) {
288     FXString p = list[i] + PATHSEPSTRING + theme + PATHSEPSTRING + path;
289     if (FXStat::exists(p)) result += ":" + p;
290     }
291 
292   }
293 
build()294 void GMIconTheme::build() {
295   FXString parents;
296   FXString themedirs;
297   FXString base;
298   FXString dir;
299 
300   FXStringDictionary themedict;
301   FXDictionary       indexmap;
302   FXint              s,i,j,xx;
303 
304   init_themedict(basedirs,themedict);
305 
306   if (themedict.no()) {
307     FXSettings   * index    = new FXSettings[themedict.used()];
308     FXDictionary * inherits = new FXDictionary[themedict.used()];
309 
310     /// Parse Index Files
311     for (i=0,j=0;i<themedict.no();i++){
312       if (!themedict.empty(i)){
313         index[j++].parseFile(themedict.data(i),true);
314         indexmap.insert(themedict.key(i),(void*)(FXival)(j-1));
315         }
316       }
317 
318     for (i=0;i<themedict.no();i++){
319       if (themedict.empty(i)) continue;
320 
321       const FXString themedir = themedict.key(i);
322       const FXint           x = (FXint)(FXival)indexmap[themedir];
323 
324       if (index[x].readBoolEntry("Icon Theme","Hidden",false))
325         continue;
326 
327       themedirs = index[x].readStringEntry("Icon Theme","Directories",nullptr);
328       if (themedirs.empty())
329         continue;
330 
331       FXString smallpath;
332       FXString mediumpath;
333       FXString largepath;
334 
335 
336       base = themedir;
337       for(xx=x;xx>=0;) {
338         themedirs = index[xx].readStringEntry("Icon Theme","Directories",nullptr);
339         parents   = index[xx].readStringEntry("Icon Theme","Inherits","hicolor");
340 
341         inherits[x].insert(base,(void*)(FXival)1);
342 
343         for (s=0;;s++) {
344 
345           dir = themedirs.section(',',s);
346           if (dir.empty()) break;
347 
348           const FXchar * type   = index[xx].readStringEntry(dir.text(),"Type","Threshold");
349           const FXint size      = index[xx].readIntEntry(dir.text(),"Size",0);
350           const FXint threshold = index[xx].readIntEntry(dir.text(),"Threshold",2);
351           const FXint minsize   = index[xx].readIntEntry(dir.text(),"MinSize",size);
352           const FXint maxsize   = index[xx].readIntEntry(dir.text(),"MaxSize",size);
353 
354           if (comparecase(type,"scalable")==0) {
355             if (smallsize>=minsize && smallsize<=maxsize)
356               add_path(basedirs,base,dir,smallpath);
357             if (mediumsize>=minsize && mediumsize<=maxsize)
358               add_path(basedirs,base,dir,mediumpath);
359             if (largesize>=minsize && largesize<=maxsize)
360               add_path(basedirs,base,dir,largepath);
361             }
362           else if (comparecase(type,"fixed")==0) {
363             if (size==smallsize)
364               add_path(basedirs,base,dir,smallpath);
365             else if (size==mediumsize)
366               add_path(basedirs,base,dir,mediumpath);
367             else if (size==largesize)
368               add_path(basedirs,base,dir,largepath);
369             }
370           else {
371             if (FXABS(smallsize-size)<=threshold)
372               add_path(basedirs,base,dir,smallpath);
373             else if (FXABS(mediumsize-size)<=threshold)
374               add_path(basedirs,base,dir,mediumpath);
375             else if (FXABS(largesize-size)<=threshold)
376               add_path(basedirs,base,dir,largepath);
377             }
378           }
379 
380         /// Find next inherited
381         for (s=0,xx=-1;xx==-1;s++) {
382           base = parents.section(',',s);
383           if (base.empty() || inherits[x].has(base))
384             break;
385           xx = (FXint)(FXival)indexmap[base];
386           }
387         }
388 
389       if (smallpath.empty() && mediumpath.empty() && largepath.empty())
390         continue;
391 
392       /// Finally add the theme
393       const FXint current=iconsets.no();
394       iconsets.no(current+1);
395       iconsets[current].name        = index[x].readStringEntry("Icon Theme","Name",themedir.text());
396       iconsets[current].dir         = themedir;
397       iconsets[current].small.adopt(smallpath);
398       iconsets[current].medium.adopt(mediumpath);
399       iconsets[current].large.adopt(largepath);
400       }
401 
402     delete [] index;
403     delete [] inherits;
404     }
405   }
406 
407 
408 
clear_svg_cache()409 void GMIconTheme::clear_svg_cache() {
410   GM_DEBUG_PRINT("GMIconTheme::clear_svg_cache()\n");
411   FXFile::removeFiles(get_svg_cache(),true);
412   }
413 
get_svg_cache()414 FXString GMIconTheme::get_svg_cache() {
415   return GMApp::getCacheDirectory(false) + CACHE_SVG_NAME;
416   }
417 
loadImage(const FXString & filename)418 FXImage * GMIconTheme::loadImage(const FXString & filename) {
419   FXImage * img=nullptr;
420   const FXString ext = FXPath::extension(filename);
421   FXFileStream store;
422   if(store.open(filename,FXStreamLoad,65536)){
423     if(comparecase(FXPNGImage::fileExt,ext)==0){
424       img=new FXPNGImage(app);
425       }
426     else if(comparecase(FXJPGImage::fileExt,ext)==0 || comparecase("jpeg",ext)==0){
427       img=new FXJPGImage(app);
428       }
429     else if(comparecase(FXBMPIcon::fileExt,ext)==0){
430       img=new FXBMPImage(app);
431       }
432     else if(comparecase(FXGIFIcon::fileExt,ext)==0){
433       img=new FXGIFImage(app);
434       }
435     else {
436       img=nullptr;
437       }
438     if(img){
439       if(img->loadPixels(store)) return img;
440       delete img;
441       img=nullptr;
442       }
443     }
444   return nullptr;
445   }
446 
447 
loadIcon(const FXString & filename)448 FXIcon * GMIconTheme::loadIcon(const FXString & filename) {
449   FXIcon * icon=nullptr;
450   const FXString ext = FXPath::extension(filename);
451   FXFileStream store;
452   if(store.open(filename,FXStreamLoad,65536)){
453     if(comparecase(FXPNGImage::fileExt,ext)==0){
454       icon=new FXPNGIcon(app);
455       }
456     else if(comparecase(FXJPGImage::fileExt,ext)==0 || comparecase("jpeg",ext)==0){
457       icon=new FXJPGIcon(app);
458       }
459     else if(comparecase(FXBMPIcon::fileExt,ext)==0){
460       icon=new FXBMPIcon(app);
461       }
462     else if(comparecase(FXGIFIcon::fileExt,ext)==0){
463       icon=new FXGIFIcon(app);
464       }
465     else if(comparecase(FXICOIcon::fileExt,ext)==0 || comparecase("cur",ext)==0){
466       icon=new FXICOIcon(app);
467       }
468     else {
469       icon=nullptr;
470       }
471     if(icon){
472       icon->setOptions(IMAGE_SHMI|IMAGE_SHMP);
473       if(icon->loadPixels(store)) return icon;
474       delete icon;
475       icon=nullptr;
476       }
477     }
478   return nullptr;
479   }
480 
481 
loadIcon(FXIconPtr & icon,const FXString & pathlist,FXint size,const FXchar * value,const FXColor blendcolor)482 void GMIconTheme::loadIcon(FXIconPtr & icon,const FXString & pathlist,FXint size,const FXchar * value,const FXColor blendcolor) {
483   FXIcon * ic=nullptr;
484   FXString name,path,item;
485   FXint beg,end;
486 
487   FXString file = value;
488   FXString png  = file + ".png";
489   FXString svg  = file + ".svg";
490 
491   ///FIXME: Linux/Unix only
492   for(beg=0; pathlist[beg]; beg=end){
493     while(pathlist[beg]==PATHLISTSEP) beg++;
494     for(end=beg; pathlist[end] && pathlist[end]!=PATHLISTSEP; end++){}
495     if(beg==end) break;
496     item=FXPath::expand(pathlist.mid(beg,end-beg));
497     path=FXPath::absolute(item,png);
498     if(FXStat::exists(path)){
499       name.adopt(path);
500       break;
501       }
502     if (rsvg) {
503       path=FXPath::absolute(item,svg);
504       if(FXStat::exists(path)){
505         FXString dest   = get_svg_cache() + PATHSEPSTRING + FXString::value(size);
506         FXString target = dest + PATHSEPSTRING + svg + ".png";
507         if (!FXStat::exists(target)) {
508           FXDir::createDirectories(dest);
509 
510           GM_DEBUG_PRINT("GMIconTheme::loadIcon() - rsvg-convert %s",target.text());
511 
512           if (system(FXString::value("rsvg-convert --format=png --width=%d --height=%d -o %s %s\n",size,size,target.text(),path.text()).text())==0){
513             name.adopt(target);
514             break;
515             }
516           }
517         else {
518           name.adopt(target);
519           break;
520           }
521         }
522       }
523     }
524 
525   if (!name.empty())
526     ic=loadIcon(name);
527 
528   if (ic) {
529     // Resize icon if necessary
530     gm_scale_crop(ic,size);
531     }
532   else {
533     ic = new FXIcon(app,nullptr,0,IMAGE_OWNED,size,size);
534     ic->fill(blendcolor);
535     }
536 
537   if (icon) {
538     icon->destroy();
539     icon->setData(ic->getData(),ic->getOptions(),ic->getWidth(),ic->getHeight());
540     ic->setOwned(false);
541     delete ic;
542     }
543   else {
544     icon=ic;
545     }
546 
547   icon->blend(blendcolor);
548   icon->create();
549   }
550 
loadSmall(FXIconPtr & icon,const FXchar * value,const FXColor blendcolor)551 void GMIconTheme::loadSmall(FXIconPtr & icon,const FXchar * value,const FXColor blendcolor){
552   if (iconsets.no())
553     loadIcon(icon,iconsets[set].small,smallsize,value,blendcolor);
554   else
555     loadIcon(icon,FXString::null,smallsize,value,blendcolor);
556   }
557 
loadMedium(FXIconPtr & icon,const FXchar * value,const FXColor blendcolor)558 void GMIconTheme::loadMedium(FXIconPtr & icon,const FXchar * value,const FXColor blendcolor){
559   if (iconsets.no())
560     loadIcon(icon,iconsets[set].medium,mediumsize,value,blendcolor);
561   else
562     loadIcon(icon,FXString::null,mediumsize,value,blendcolor);
563   }
564 
loadLarge(FXIconPtr & icon,const FXchar * value,const FXColor blendcolor)565 void GMIconTheme::loadLarge(FXIconPtr & icon,const FXchar * value,const FXColor blendcolor){
566    if (iconsets.no())
567     loadIcon(icon,iconsets[set].large,largesize,value,blendcolor);
568   else
569     loadIcon(icon,FXString::null,largesize,value,blendcolor);
570   }
571 
loadResource(FXIconPtr & icon,const void * data,const FXColor blendcolor,const char * type)572 void GMIconTheme::loadResource(FXIconPtr & icon,const void * data,const FXColor blendcolor,const char * type) {
573   FXIconSource source;
574   FXIcon * newicon = source.loadIconData(app,data,type);
575   FXASSERT(newicon);
576   if (icon) {
577     icon->destroy();
578     icon->setData(newicon->getData(),newicon->getOptions(),newicon->getWidth(),newicon->getHeight());
579     newicon->setOwned(false);
580     delete newicon;
581     }
582   else {
583     icon=newicon;
584     }
585   icon->blend(blendcolor);
586   icon->create();
587   }
588 
loadSmall(const char * value)589 FXImage* GMIconTheme::loadSmall(const char * value) {
590   FXImage * image = nullptr;
591   if (iconsets.no()) {
592     FXString name = FXPath::search(iconsets[set].small,value);
593     if (!name.empty())
594       image = loadImage(name);
595     }
596   return image;
597   }
598 
599 
load()600 void GMIconTheme::load() {
601   if (set>=0)
602     loadExternal();
603   else
604     loadInternal();
605   }
606 
loadInternal()607 void GMIconTheme::loadInternal() {
608   const FXColor basecolor = app->getBaseColor();
609   const FXColor backcolor = app->getBackColor();
610 
611   smallsize  = SMALL_SIZE;
612   mediumsize = MEDIUM_SIZE;
613   largesize  = LARGE_SIZE;
614 
615   loadResource(icon_copy,x16_edit_copy_png,basecolor);
616   loadResource(icon_cut,x16_edit_cut_png,basecolor);
617   loadResource(icon_paste,x16_edit_paste_png,basecolor);
618   loadResource(icon_delete,x16_edit_delete_png,basecolor);
619   loadResource(icon_undo,x16_edit_undo_png,basecolor);
620 
621   loadResource(icon_import,x16_folder_png,basecolor);
622   loadResource(icon_exit,x16_exit_png,basecolor);
623   loadResource(icon_close,x16_window_close_png,basecolor);
624   loadResource(icon_find,x16_edit_find_png,basecolor);
625   loadResource(icon_sync,x16_view_refresh_png,basecolor);
626   loadResource(icon_album,x16_media_optical_png,basecolor);
627   loadResource(icon_artist,x16_system_users_png,basecolor);
628   loadResource(icon_genre,x16_bookmark_new_png,basecolor);
629   loadResource(icon_export,x16_document_save_png,basecolor);
630   loadResource(icon_info,x16_help_browser_png,basecolor);
631 
632   loadResource(icon_file_small,x16_text_x_generic_png,backcolor);
633   loadResource(icon_file_big,x22_text_x_generic_png,backcolor);
634   loadResource(icon_audio_small,x16_audio_x_generic_png,backcolor);
635   loadResource(icon_audio_big,x22_audio_x_generic_png,backcolor);
636   loadResource(icon_image_small,x16_image_x_generic_png,backcolor);
637   loadResource(icon_image_big,x22_image_x_generic_png,backcolor);
638   loadResource(icon_folder_open_small,x16_folder_open_png,backcolor);
639   loadResource(icon_folder_small,x16_folder_png,backcolor);
640   loadResource(icon_folder_big,x22_folder_png,backcolor);
641   loadResource(icon_localcopy,x16_stock_attach_png,backcolor);
642   loadResource(icon_download,x16_go_bottom_png,backcolor);
643   loadResource(icon_error,x16_status_error_png,backcolor);
644   loadResource(icon_podcast,x16_application_rss_xml_png,backcolor);
645 
646   loadResource(icon_home,x16_go_home_png,basecolor);
647   loadResource(icon_playqueue,x16_x_office_presentation_png,basecolor);
648   loadResource(icon_settings,x16_preferences_desktop_png,basecolor);
649   loadResource(icon_edit,x16_accessories_text_editor_png,basecolor);
650   loadResource(icon_sort,x16_view_sort_descending_png,basecolor);
651 
652   loadResource(icon_add,x16_list_add_png,basecolor);
653   loadResource(icon_remove,x16_list_remove_png,basecolor);
654 
655   // Play Back Icons
656   loadResource(icon_play,         x16_media_playback_start_png,basecolor);
657   loadResource(icon_pause,        x16_media_playback_pause_png,basecolor);
658   loadResource(icon_next,         x16_media_skip_forward_png,  basecolor);
659   loadResource(icon_prev,         x16_media_skip_backward_png, basecolor);
660   loadResource(icon_stop,         x16_media_playback_stop_png, basecolor);
661   loadResource(icon_volume_high,  x16_audio_volume_high_png,      basecolor);
662   loadResource(icon_volume_medium,x16_audio_volume_medium_png,    basecolor);
663   loadResource(icon_volume_low,   x16_audio_volume_low_png,       basecolor);
664   loadResource(icon_volume_muted, x16_audio_volume_muted_png,     basecolor);
665 
666   loadResource(icon_play_toolbar,         x22_media_playback_start_png,   basecolor);
667   loadResource(icon_pause_toolbar,        x22_media_playback_pause_png,   basecolor);
668   loadResource(icon_next_toolbar,         x22_media_skip_forward_png,     basecolor);
669   loadResource(icon_prev_toolbar,         x22_media_skip_backward_png,    basecolor);
670   loadResource(icon_stop_toolbar,         x22_media_playback_stop_png,    basecolor);
671   loadResource(icon_volume_high_toolbar,  x22_audio_volume_high_png,      basecolor);
672   loadResource(icon_volume_medium_toolbar,x22_audio_volume_medium_png,    basecolor);
673   loadResource(icon_volume_low_toolbar,   x22_audio_volume_low_png,       basecolor);
674   loadResource(icon_volume_muted_toolbar, x22_audio_volume_muted_png,     basecolor);
675   loadResource(icon_customize,            x22_preferences_system_png,     basecolor);
676   loadResource(icon_document,             x22_document_properties_png,    basecolor);
677   loadResource(icon_create,               x22_document_open_png,          basecolor);
678   loadResource(icon_media,                x22_applications_multimedia_png,basecolor);
679 
680   loadResource(icon_source_library,x22_user_home_png,backcolor);
681   loadResource(icon_source_internetradio,x22_applications_internet_png,backcolor);
682   loadResource(icon_source_playlist,x22_folder_png,backcolor);
683   loadResource(icon_source_playqueue,x22_x_office_presentation_png,backcolor);
684   loadResource(icon_source_local,x22_drive_harddisk_png,backcolor);
685   loadResource(icon_source_podcast,x22_applications_rss_xml_png,backcolor);
686 
687   loadResource(icon_nocover,x128_media_optical_png,basecolor);
688   loadResource(icon_applogo,gogglesmm_32_png,basecolor);
689   loadResource(icon_applogo_small,gogglesmm_16_png,basecolor);
690   loadResource(icon_progress,x16_process_working_png,basecolor);
691   }
692 
693 
loadExternal()694 void GMIconTheme::loadExternal() {
695   const FXColor basecolor = app->getBaseColor();
696   const FXColor backcolor = app->getBackColor();
697 
698   smallsize  = app->reg().readIntEntry("user-interface","icon-theme-small-size",SMALL_SIZE);
699   mediumsize = app->reg().readIntEntry("user-interface","icon-theme-medium-size",MEDIUM_SIZE);
700   largesize  = app->reg().readIntEntry("user-interface","icon-theme-large-size",LARGE_SIZE);
701 
702   loadSmall(icon_copy,"edit-copy",basecolor);
703   loadSmall(icon_cut,"edit-cut",basecolor);
704   loadSmall(icon_paste,"edit-paste",basecolor);
705   loadSmall(icon_delete,"edit-delete",basecolor);
706   loadSmall(icon_undo,"edit-undo",basecolor);
707   loadSmall(icon_play,"media-playback-start",basecolor);
708   loadSmall(icon_pause,"media-playback-pause",basecolor);
709   loadSmall(icon_next,"media-skip-forward",basecolor);
710   loadSmall(icon_prev,"media-skip-backward",basecolor);
711   loadSmall(icon_stop,"media-playback-stop",basecolor);
712 
713   loadSmall(icon_import,"folder",basecolor);
714   //loadSmall(icon_importfile,"document-open",basecolor);
715   loadSmall(icon_exit,"exit",basecolor);
716   loadSmall(icon_close,"window-close",basecolor);
717   loadSmall(icon_find,"edit-find",basecolor);
718   loadSmall(icon_sync,"view-refresh",basecolor);
719   loadSmall(icon_album,"media-optical",basecolor);
720   loadSmall(icon_artist,"system-users",basecolor);
721   loadSmall(icon_genre,"bookmark-new",basecolor);
722   loadSmall(icon_export,"document-save",basecolor);
723   //loadSmall(icon_homepage,"applications-internet",basecolor);
724   loadSmall(icon_info,"help-browser",basecolor);
725 
726   loadSmall(icon_podcast,"application-rss+xml",backcolor);
727 
728   loadSmall(icon_home,"go-home",basecolor);
729   loadSmall(icon_download,"go-bottom",backcolor);
730   loadSmall(icon_error,"error",backcolor);
731   loadSmall(icon_localcopy,"stock_attach",backcolor);
732 
733   loadMedium(icon_source_library,"user-home",backcolor);
734   loadMedium(icon_source_internetradio,"applications-internet",backcolor);
735   loadMedium(icon_source_playlist,"user-bookmarks",backcolor);
736   loadMedium(icon_source_playqueue,"x-office-presentation",backcolor);
737   loadMedium(icon_source_local,"drive-harddisk",backcolor);
738   loadMedium(icon_source_podcast,"application-rss+xml",backcolor);
739 
740   //loadSmall(icon_playlist,"user-bookmarks",basecolor);
741   loadSmall(icon_playqueue,"x-office-presentation",basecolor);
742   loadSmall(icon_settings,"preferences-desktop",basecolor);
743   loadSmall(icon_edit,"accessories-text-editor",basecolor);
744   loadSmall(icon_sort,"view-sort-descending",basecolor);
745 
746   loadResource(icon_applogo,gogglesmm_32_png,basecolor);
747   loadResource(icon_applogo_small,gogglesmm_16_png,basecolor);
748 
749   loadLarge(icon_nocover,"media-optical",basecolor);
750 
751   loadMedium(icon_volume_high_toolbar,"audio-volume-high",basecolor);
752   loadMedium(icon_volume_medium_toolbar,"audio-volume-medium",basecolor);
753   loadMedium(icon_volume_low_toolbar,"audio-volume-low",basecolor);
754   loadMedium(icon_volume_muted_toolbar,"audio-volume-muted",basecolor);
755 
756   loadSmall(icon_volume_high,"audio-volume-high",basecolor);
757   loadSmall(icon_volume_medium,"audio-volume-medium",basecolor);
758   loadSmall(icon_volume_low,"audio-volume-low",basecolor);
759   loadSmall(icon_volume_muted,"audio-volume-muted",basecolor);
760 
761 
762   loadMedium(icon_play_toolbar,"media-playback-start",basecolor);
763   loadMedium(icon_pause_toolbar,"media-playback-pause",basecolor);
764   loadMedium(icon_next_toolbar,"media-skip-forward",basecolor);
765   loadMedium(icon_prev_toolbar,"media-skip-backward",basecolor);
766   loadMedium(icon_stop_toolbar,"media-playback-stop",basecolor);
767 
768   loadMedium(icon_customize,"preferences-system",basecolor);
769   loadMedium(icon_document,"document-properties",basecolor);
770   loadMedium(icon_create,"document-open",basecolor);
771   loadMedium(icon_media,"applications-multimedia",basecolor);
772 
773 
774   loadSmall(icon_file_small,"text-x-generic",backcolor);
775   loadMedium(icon_file_big,"text-x-generic",backcolor);
776   loadSmall(icon_audio_small,"audio-x-generic",backcolor);
777   loadMedium(icon_audio_big,"audio-x-generic",backcolor);
778   loadSmall(icon_image_small,"image-x-generic",backcolor);
779   loadMedium(icon_image_big,"image-x-generic",backcolor);
780   loadSmall(icon_folder_open_small,"folder-open",backcolor);
781   loadSmall(icon_folder_small,"folder",backcolor);
782   loadMedium(icon_folder_big,"folder",backcolor);
783 
784   loadSmall(icon_progress,"process-working",basecolor);
785   }
786 
787 
getNumThemes() const788 FXint GMIconTheme::getNumThemes() const{
789   return iconsets.no();
790   }
791 
setCurrentTheme(FXint s)792 void GMIconTheme::setCurrentTheme(FXint s) {
793   set=s;
794   if (set>=0 && iconsets.no())
795     app->reg().writeStringEntry("user-interface","icon-theme",iconsets[set].dir.text());
796   else
797     app->reg().writeStringEntry("user-interface","icon-theme","");
798 
799   clear_svg_cache();
800   }
801 
getCurrentTheme() const802 FXint GMIconTheme::getCurrentTheme() const {
803   return set;
804   }
805 
getThemeName(FXint i)806 FXString GMIconTheme::getThemeName(FXint i){
807   FXASSERT(i>=0 && i<iconsets.no());
808   return iconsets[i].name;
809   }
810