1 /*******************************************************************************
2 *                         Goggles Music Manager                                *
3 ********************************************************************************
4 *           Copyright (C) 2006-2021 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 
22 #include "icons.h"
23 
24 #include <FXPNGIcon.h>
25 
26 #include "GMTrack.h"
27 #include "GMApp.h"
28 #include "GMCoverCache.h"
29 #include "GMAudioPlayer.h"
30 #include "GMAlbumList.h"
31 #include "GMTrackList.h"
32 #include "GMList.h"
33 #include "GMSource.h"
34 #include "GMPlayerManager.h"
35 #include "GMWindow.h"
36 #include "GMRemote.h"
37 #include "GMDatabaseSource.h"
38 #include "GMPodcastSource.h"
39 #include "GMTrackView.h"
40 #include "GMSourceView.h"
41 #ifdef HAVE_OPENGL
42 #include "GMImageView.h"
43 #endif
44 #include "GMAudioScrobbler.h"
45 #include "GMIconTheme.h"
46 #include "GMFontDialog.h"
47 #include "GMPreferencesDialog.h"
48 #include "GMTrayIcon.h"
49 
50 
51 #define MINUTES 60000000000LL
52 
53 
54 enum {
55   ALSA_DRIVER   = 0,
56   OSS_DRIVER    = 1,
57   PULSE_DRIVER  = 2,
58   JACK_DRIVER   = 3,
59   OTHER_DRIVER  = 4
60   };
61 
62 
63 
ColorTheme()64 ColorTheme::ColorTheme() {
65   name      = nullptr;
66   base      = FXApp::instance()->getBaseColor();
67   border    = FXApp::instance()->getBorderColor();
68   back      = FXApp::instance()->getBackColor();
69   fore      = FXApp::instance()->getForeColor();
70   selfore	  = FXApp::instance()->getSelforeColor();
71   selback	  = FXApp::instance()->getSelbackColor();
72   tipfore	  = FXApp::instance()->getTipforeColor();
73   tipback	  = FXApp::instance()->getTipbackColor();
74   menufore  = FXApp::instance()->getSelMenuTextColor();
75   menuback  = FXApp::instance()->getSelMenuBackColor();
76   menubase  = GMPlayerManager::instance()->getPreferences().gui_menu_base_color;
77   shadow    = FXApp::instance()->getShadowColor();
78   hilite    = FXApp::instance()->getHiliteColor();
79   playfore  = GMPlayerManager::instance()->getPreferences().gui_playtext_color;
80   playback  = GMPlayerManager::instance()->getPreferences().gui_play_color;
81   altback   = GMPlayerManager::instance()->getPreferences().gui_row_color;
82   trayback  = GMPlayerManager::instance()->getPreferences().gui_tray_color;
83   }
84 
ColorTheme(const FXchar * _name,FXColor _base,FXColor _border,FXColor _back,FXColor _altback,FXColor _fore,FXColor _selback,FXColor _selfore,FXColor _tipback,FXColor _tipfore,FXColor _psback,FXColor _psfore)85 ColorTheme::ColorTheme(const FXchar * _name,FXColor _base,FXColor _border,FXColor _back,FXColor _altback,FXColor _fore,FXColor _selback,FXColor _selfore,FXColor _tipback,FXColor _tipfore,FXColor _psback,FXColor _psfore) :
86   name(_name),
87   base(_base),
88   border(_border),
89   back(_back),
90   altback(_altback),
91   fore(_fore),
92   selback(_selback),
93   selfore(_selfore),
94   tipback(_tipback),
95   tipfore(_tipfore),
96   menuback(_selback),
97   menufore(_selfore),
98   menubase(_back),
99   playfore(_psfore),
100   playback(_psback),
101   hilite(makeHiliteColor(base)),
102   shadow(makeShadowColor(base)),
103   trayback(_base) {
104   }
105 
106 
save() const107 void ColorTheme::save() const {
108   FXApp::instance()->setBaseColor(base);
109   FXApp::instance()->setBorderColor(border);
110   FXApp::instance()->setBackColor(back);
111   FXApp::instance()->setForeColor(fore);
112   FXApp::instance()->setSelbackColor(selback);
113   FXApp::instance()->setSelforeColor(selfore);
114   FXApp::instance()->setTipbackColor(tipback);
115   FXApp::instance()->setTipforeColor(tipfore);
116   FXApp::instance()->setSelMenuBackColor(menuback);
117   FXApp::instance()->setSelMenuTextColor(menufore);
118   FXApp::instance()->setShadowColor(shadow);
119   FXApp::instance()->setHiliteColor(hilite);
120   GMPlayerManager::instance()->getPreferences().gui_playtext_color=playfore;
121   GMPlayerManager::instance()->getPreferences().gui_play_color=playback;
122   GMPlayerManager::instance()->getPreferences().gui_row_color=altback;
123   GMPlayerManager::instance()->getPreferences().gui_menu_base_color=menubase;
124   GMPlayerManager::instance()->getPreferences().gui_tray_color=trayback;
125   }
126 
operator ==(const ColorTheme & t1,const ColorTheme & t2)127 bool operator==(const ColorTheme& t1,const ColorTheme& t2) {
128   return (t1.base==t2.base &&
129       t1.border==t2.border &&
130       t1.back==t2.back &&
131       t1.altback==t2.altback &&
132       t1.fore==t2.fore &&
133       t1.selback==t2.selback &&
134       t1.selfore==t2.selfore &&
135       t1.tipback==t2.tipback &&
136       t1.tipfore==t2.tipfore &&
137       t1.menuback==t2.menuback &&
138       t1.menufore==t2.menufore &&
139       t1.menubase==t2.menubase &&
140       t1.playfore==t2.playfore &&
141       t1.playback==t2.playback &&
142       t1.hilite==t2.hilite &&
143       t1.shadow==t2.shadow &&
144       t1.trayback==t2.trayback);
145   }
146 
147 
148 /// Think you have a great color theme, mail them to s.jansen@gmail.com
149 const ColorTheme ColorThemes[]={
150   ColorTheme("FOX", // name
151              FXRGB(212,208,200), // base
152              FXRGB(  0,  0,  0), // boder
153              FXRGB(255,255,255), // back
154              FXRGB(240,240,240), // alt back
155              FXRGB(  0,  0,  0), // fore
156              FXRGB( 10, 36,106), // selback
157              FXRGB(255,255,255), // selfore
158              FXRGB(255,255,225), // tipback
159              FXRGB(0,0,0)), // tipfore
160 
161   ColorTheme("Clearlooks"     , // name
162              FXRGB(237,236,235), // base
163              FXRGB(  0,  0,  0), // boder
164              FXRGB(255,255,255), // back
165              FXRGB(240,240,240), // alt back
166              FXRGB( 26, 26, 25), // fore
167              FXRGB(134,171,217), // selback
168              FXRGB(255,255,255), // selfore
169              FXRGB(245,245,181), // tipback
170              FXRGB(  0,  0,  0)),   // tipfore
171 
172   ColorTheme("Honeycomb"       , // name
173              FXRGB(213,215,209), // base
174              FXRGB(  0,  0,  0), // boder
175              FXRGB(255,255,255), // back
176              FXRGB(238,238,238), // alt back
177              FXRGB( 0, 0, 0), // fore
178              FXRGB(227,167,  0), // selback
179              FXRGB(255,255,255), // selfore
180              FXRGB(255,242,153), // tipback
181              FXRGB( 64, 48, 0)), // tipfore
182 
183   ColorTheme("Norway"          , // name
184              FXRGB(235,226,210), // base
185              FXRGB(  0,  0,  0), // boder
186              FXRGB(253,252,251), // back
187              FXRGB(238,238,238), // alt back
188              FXRGB(  0,  0,  0), // fore
189              FXRGB( 29,135,205), // selback
190              FXRGB(255,255,255), // selfore
191              FXRGB(253,252,251), // tipback
192              FXRGB(  0,  0,  0)),   // tipfore
193 
194   ColorTheme("Oxygen"          , // name
195              FXRGB(224,223,223), // base
196              FXRGB(  0,  0,  0), // boder
197              FXRGB(255,255,255), // back
198              FXRGB(238,238,238), // alt back
199              FXRGB( 20, 19, 18), // fore
200              FXRGB( 65,141,212), // selback
201              FXRGB(255,255,255), // selfore
202              FXRGB(192,218,255), // tipback
203              FXRGB( 20, 19, 18)), // tipfore
204 
205   ColorTheme("Obsidian Coast" ,  // name
206              FXRGB( 48, 47, 47), // base
207              FXRGB(  0,  0,  0), // boder
208              FXRGB( 32, 31, 31), // back
209              FXRGB( 38, 38, 38), // alt back
210              FXRGB(224,223,220), // fore
211              FXRGB(  24,72,128), // selback
212              FXRGB(255,255,255), // selfore
213              FXRGB( 16, 48, 80), // tipback
214              FXRGB(196,209,224),// tipfore
215              FXRGB(24,128,73), // psback
216              FXRGB(224,223,220)), // psfore
217 
218   ColorTheme("Steel"       , // name
219              FXRGB(224,223,216), // base
220              FXRGB(  0,  0,  0), // boder
221              FXRGB(255,255,255), // back
222              FXRGB(238,238,238), // alt back
223              FXRGB( 0, 0, 0), // fore
224              FXRGB(123,161,173), // selback
225              FXRGB(255,255,255), // selfore
226              FXRGB(220,231,235), // tipback
227              FXRGB( 37, 34, 28)), // tipfore
228 
229   ColorTheme("Wonton Soup"     , // name
230              FXRGB (71, 76, 86), // base
231              FXRGB(  0,  0,  0), // boder
232              FXRGB( 58, 62, 70), // back
233              FXRGB( 62, 66, 75), // alt back
234              FXRGB(182,193,208), // fore
235              FXRGB(117,133,153), // selback
236              FXRGB(209,225,244), // selfore
237              FXRGB(182,193,208), // tipback
238              FXRGB(42,44,48),		 // tipfore
239              FXRGB(134,147,134), // psback
240              FXRGB(209,225,244)),// psfore
241   };
242 
243 
init_default_colortheme()244 void init_default_colortheme() {
245   // Set default to clear looks
246   ColorThemes[1].save();
247   }
248 
249 
250 
251 
252 FXDEFMAP(GMPreferencesDialog) GMPreferencesDialogMap[]={
253   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_LASTFM_SCROBBLE,GMPreferencesDialog::onCmdLastFMScrobble),
254   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_LASTFM_SERVICE,GMPreferencesDialog::onCmdLastFMService),
255   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_LASTFM_USERNAME,GMPreferencesDialog::onCmdLastFMUserName),
256   FXMAPFUNC(SEL_CHANGED,GMPreferencesDialog::ID_LASTFM_USERNAME,GMPreferencesDialog::onCmdLastFMUserName),
257   FXMAPFUNC(SEL_FOCUSIN,GMPreferencesDialog::ID_LASTFM_PASSWORD,GMPreferencesDialog::onFocusLastFMPassWord),
258   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_LASTFM_PASSWORD,GMPreferencesDialog::onCmdLastFMPassWord),
259   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_LASTFM_JOIN,GMPreferencesDialog::onCmdLastFMJoin),
260   FXMAPFUNCS(SEL_COMMAND,GMPreferencesDialog::ID_BASE_COLOR,GMPreferencesDialog::ID_BORDER_COLOR,GMPreferencesDialog::onCmdElementColor),
261   FXMAPFUNCS(SEL_UPDATE,GMPreferencesDialog::ID_BASE_COLOR,GMPreferencesDialog::ID_BORDER_COLOR,GMPreferencesDialog::onUpdElementColor),
262   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_COLOR_THEME,GMPreferencesDialog::onCmdColorTheme),
263   FXMAPFUNC(SEL_UPDATE,GMPreferencesDialog::ID_COLOR_THEME,GMPreferencesDialog::onUpdColorTheme),
264   FXMAPFUNC(SEL_UPDATE,GMPreferencesDialog::ID_FONT,GMPreferencesDialog::onUpdFont),
265   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_CHANGE_FONT,GMPreferencesDialog::onCmdChangeFont),
266   FXMAPFUNC(SEL_COMMAND,FXDialogBox::ID_ACCEPT,GMPreferencesDialog::onCmdAccept),
267   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_AUDIO_DRIVER,GMPreferencesDialog::onCmdAudioDriver),
268   FXMAPFUNC(SEL_CHANGED,GMPreferencesDialog::ID_AUDIO_DRIVER,GMPreferencesDialog::onCmdAudioDriver),
269   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_REPLAY_GAIN,GMPreferencesDialog::onCmdReplayGain),
270   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_CROSS_FADE,GMPreferencesDialog::onCmdCrossFade),
271   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_TITLE_FORMAT,GMPreferencesDialog::onCmdTitleFormat),
272   FXMAPFUNC(SEL_UPDATE,GMPreferencesDialog::ID_TITLE_FORMAT,GMPreferencesDialog::onUpdTitleFormat),
273   FXMAPFUNC(SEL_UPDATE,GMPreferencesDialog::ID_TITLE_FORMAT_LABEL,GMPreferencesDialog::onUpdTitleFormat),
274   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_ICON_THEME,GMPreferencesDialog::onCmdIconTheme),
275   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_DISPLAY_DPI,GMPreferencesDialog::onCmdDisplayDPI),
276   FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_APPLY_AUDIO,GMPreferencesDialog::onCmdApplyAudio)
277   };
278 
FXIMPLEMENT(GMPreferencesDialog,FXDialogBox,GMPreferencesDialogMap,ARRAYNUMBER (GMPreferencesDialogMap))279 FXIMPLEMENT(GMPreferencesDialog,FXDialogBox,GMPreferencesDialogMap,ARRAYNUMBER(GMPreferencesDialogMap))
280 
281 GMPreferencesDialog::GMPreferencesDialog(FXWindow * p) : FXDialogBox(p,FXString::null,DECOR_BORDER|DECOR_TITLE,0,0,0,0,0,0,0,0,0,0),
282   password_set(false) {
283 
284   dpi=getApp()->reg().readIntEntry("SETTINGS","screenres",96);
285 
286   setTitle(tr("Preferences"));
287   target_closeishide.connect(GMPlayerManager::instance()->getPreferences().gui_hide_player_when_close);
288   target_keywords.connect(keywords);
289 
290   target_show_playing_albumcover.connect(GMPlayerManager::instance()->getPreferences().gui_show_playing_albumcover);
291   target_show_playing_lyrics.connect(GMPlayerManager::instance()->getPreferences().gui_show_playing_lyrics);
292 
293 #ifdef HAVE_DBUS
294   target_dbus_notify_daemon.connect(GMPlayerManager::instance()->getPreferences().dbus_notify_daemon);
295   target_dbus_mpris1.connect(GMPlayerManager::instance()->getPreferences().dbus_mpris1);
296 #endif
297   target_gui_tray_icon.connect(GMPlayerManager::instance()->getPreferences().gui_tray_icon);
298   target_replaygain.connect(GMPlayerManager::instance()->getPreferences().play_replaygain,this,ID_REPLAY_GAIN);
299   target_gui_show_playing_titlebar.connect(GMPlayerManager::instance()->getPreferences().gui_show_playing_titlebar);
300   target_gui_format_title.connect(GMPlayerManager::instance()->getPreferences().gui_format_title);
301 
302   target_crossfade.connect(GMPlayerManager::instance()->getPreferences().play_crossfade, this,ID_CROSS_FADE);
303   target_crossfade_duration.connect(GMPlayerManager::instance()->getPreferences().play_crossfade_duration, this,ID_CROSS_FADE);
304 
305   GMPlayerManager::instance()->getPreferences().getKeyWords(keywords);
306 
307   const FXuint labelstyle=LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT;
308   const FXuint textfieldstyle=TEXTFIELD_ENTER_ONLY|LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN;
309 
310   FXGroupBox      * grpbox;
311   FXMatrix        * matrix;
312   FXVerticalFrame * vframe;
313   FXVerticalFrame * vframe2;
314 
315   FXVerticalFrame * main=new FXVerticalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y);
316   GMTabBook * tabbook=new GMTabBook(main,nullptr,0,LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT,0,0,0,0,0,0,0,0);
317 
318 
319   new GMTabItem(tabbook,tr("&General"),nullptr,TAB_TOP_NORMAL,0,0,0,0,5,5);
320   vframe = new GMTabFrame(tabbook);
321 
322   grpbox =  new FXGroupBox(vframe,tr("Sort Options"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20);
323   grpbox->setFont(GMApp::instance()->getThickFont());
324 
325   matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X,0,0,0,0,0,0,0,0);
326   new FXLabel(matrix,tr("Ignore leading words"),nullptr,labelstyle);
327   new GMTextField(matrix,10,&target_keywords,FXDataTarget::ID_VALUE,textfieldstyle);
328 
329   grpbox =  new FXGroupBox(vframe,tr("Additional Track Information"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20);
330   grpbox->setFont(GMApp::instance()->getThickFont());
331 
332   new GMCheckButton(grpbox,tr("Show Album Cover\tShow album cover of playing track"),&target_show_playing_albumcover,FXDataTarget::ID_VALUE);
333   new GMCheckButton(grpbox,tr("Show Lyrics\tShow lyrics of playing track"),&target_show_playing_lyrics,FXDataTarget::ID_VALUE);
334 
335 
336   grpbox =  new FXGroupBox(vframe,tr("System Tray"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20);
337   grpbox->setFont(GMApp::instance()->getThickFont());
338 
339   if (!GMPlayerManager::instance()->getPreferences().gui_tray_icon_disabled)
340     new GMCheckButton(grpbox,tr("Show Tray Icon\tShow tray icon in the system tray."),&target_gui_tray_icon,FXDataTarget::ID_VALUE);
341 #ifdef HAVE_DBUS
342   if (GMPlayerManager::instance()->hasSessionBus()) {
343     new GMCheckButton(grpbox,tr("Show Track Change Notifications\tInform notification daemon of track changes."),&target_dbus_notify_daemon,FXDataTarget::ID_VALUE);
344     new GMCheckButton(grpbox,tr("MPRIS v1 Connectivity\tEnable MPRIS v1 connectivity"),&target_dbus_mpris1,FXDataTarget::ID_VALUE);
345     }
346 #endif
347 
348   grpbox =  new FXGroupBox(vframe,tr("Last.fm"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,23,3,0,0,0,0);
349   grpbox->setFont(GMApp::instance()->getThickFont());
350 
351 
352   if (GMPlayerManager::instance()->getAudioScrobbler()->isBanned()) {
353     new FXLabel(grpbox,tr("This version of Goggles Music Manager is\n"
354                        "not supported by Last-FM. Please upgrade\n"
355                        "to a newer version of GMM."),nullptr,JUSTIFY_LEFT);
356     }
357   else {
358     matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X,0,0,0,0);
359     new FXLabel(matrix,tr("Service:"),nullptr,labelstyle);
360     FXHorizontalFrame * hframe = new FXHorizontalFrame(matrix,FRAME_NONE,0,0,0,0,0,0,0,0);
361     FXuint current_service = GMPlayerManager::instance()->getAudioScrobbler()->getService();
362 
363     lastfm_service = new GMListBox(hframe,this,ID_LASTFM_SERVICE,FRAME_SUNKEN|FRAME_THICK);
364     lastfm_service->appendItem("Last.fm");
365     lastfm_service->appendItem("Libre.fm");
366 
367     if (current_service==SERVICE_CUSTOM) {
368       lastfm_service->appendItem("Custom");
369       lastfm_service->setNumVisible(3);
370       }
371     else {
372       lastfm_service->setNumVisible(2);
373       }
374     lastfm_service->setCurrentItem(current_service);
375 
376     lastfm_join = new FXButton(hframe,tr("&Sign up…"),nullptr,this,ID_LASTFM_JOIN,ICON_AFTER_TEXT|FRAME_RAISED|JUSTIFY_CENTER_Y|JUSTIFY_LEFT|BUTTON_TOOLBAR,0,0,0,0,7);
377     lastfm_join->setTextColor(FXRGB(0,0,255));
378     lastfm_join->setDefaultCursor(GMIconTheme::instance()->cursor_hand);
379     if (current_service==SERVICE_CUSTOM) lastfm_join->hide();
380 
381 
382     lastfm_username_label = new FXLabel(matrix,tr("Username:"),nullptr,labelstyle);
383     lastfm_username = new GMTextField(matrix,20,this,ID_LASTFM_USERNAME,FRAME_SUNKEN|FRAME_THICK);
384     lastfm_password_label = new FXLabel(matrix,tr("Password:"),nullptr,labelstyle);
385     lastfm_password = new GMTextField(matrix,20,this,ID_LASTFM_PASSWORD,FRAME_SUNKEN|FRAME_THICK|TEXTFIELD_PASSWD);
386 
387     new FXFrame(matrix,FRAME_NONE);
388     lastfm_scrobble = new GMCheckButton(grpbox,tr("Scrobble"),this,ID_LASTFM_SCROBBLE,LAYOUT_FIX_X|LAYOUT_FIX_Y|CHECKBUTTON_NORMAL,6,0);
389     lastfm_scrobble->setFont(GMApp::instance()->getThickFont());
390 
391     lastfm_username->setText(GMPlayerManager::instance()->getAudioScrobbler()->getUsername());
392     if (GMPlayerManager::instance()->getAudioScrobbler()->hasPassword())
393       lastfm_password->setText("1234567890");
394 
395     lastfm_scrobble->setCheck(GMPlayerManager::instance()->getAudioScrobbler()->isEnabled());
396 
397     if (current_service==SERVICE_LASTFM){
398       lastfm_username->hide();
399       lastfm_username_label->hide();
400       lastfm_password->hide();
401       lastfm_password_label->hide();
402       }
403     else {
404       lastfm_username->show();
405       lastfm_username_label->show();
406       lastfm_password->show();
407       lastfm_password_label->show();
408       }
409 
410     }
411 
412   new GMTabItem(tabbook,tr("&Window"),nullptr,TAB_TOP_NORMAL,0,0,0,0,5,5);
413   vframe = new GMTabFrame(tabbook);
414 
415   grpbox =  new FXGroupBox(vframe,tr("Window"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20);
416   grpbox->setFont(GMApp::instance()->getThickFont());
417   if (!GMPlayerManager::instance()->getPreferences().gui_tray_icon_disabled)
418     new GMCheckButton(grpbox,tr("Close button minimizes to tray"),&target_closeishide,FXDataTarget::ID_VALUE);
419   statusbarbutton = new GMCheckButton(grpbox,tr("Show Status Bar"),nullptr,0);
420   statusbarbutton->setCheck(GMPlayerManager::instance()->getPreferences().gui_show_status_bar);
421 
422   new GMCheckButton(grpbox,tr("Display playing track in title bar"),&target_gui_show_playing_titlebar,FXDataTarget::ID_VALUE);
423 
424 
425   grpbox =  new FXGroupBox(vframe,tr("Toolbar"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20);
426   grpbox->setFont(GMApp::instance()->getThickFont());
427 
428   matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS);
429   new FXLabel(matrix,tr("Location:"),nullptr,labelstyle);
430   toolbar_docktop = new GMListBox(matrix,nullptr,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X);
431   toolbar_docktop->appendItem(tr("Top"));
432   toolbar_docktop->appendItem(tr("Bottom"));
433   toolbar_docktop->setNumVisible(2);
434 
435   new FXLabel(matrix,tr("Title Format:"),nullptr,labelstyle);
436   new GMTextField(matrix,20,&target_gui_format_title,FXDataTarget::ID_VALUE,LAYOUT_FILL_COLUMN|LAYOUT_FILL_X);
437 
438 
439   /// Create a fixed font, about the same size as the normal font
440   FXint size = FXApp::instance()->getNormalFont()->getSize();
441   font_fixed = new FXFont(FXApp::instance(),"mono",(int)size/10,FXFont::Normal,FXFont::Straight,FONTENCODING_UNICODE,FXFont::NonExpanded,FXFont::Modern|FXFont::Fixed);
442 
443   FXLabel * label = new FXLabel(grpbox,tr("%T - title                   %A - album name\n"
444                                         "%P - album artist name       %p - track artist name\n"
445                                         "%w - composer                %c - conductor\n"
446                                         "%y - year                    %d - disc number\n"
447                                         "%N - track number (2 digits) %n - track number      \n%G - genre"),NULL,FRAME_LINE|JUSTIFY_LEFT,0,0,0,0,30);
448 
449   label->setFont(font_fixed);
450   label->setBackColor(getApp()->getTipbackColor());
451   label->setBorderColor(getApp()->getShadowColor());
452 
453 
454 
455 
456   if (GMPlayerManager::instance()->getPreferences().gui_toolbar_docktop)
457     toolbar_docktop->setCurrentItem(0);
458   else
459     toolbar_docktop->setCurrentItem(1);
460 
461   new GMTabItem(tabbook,tr("A&ppearance"),nullptr,TAB_TOP_NORMAL,0,0,0,0,5,5);
462   vframe = new GMTabFrame(tabbook);
463   grpbox =  new FXGroupBox(vframe,tr("Colors"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,2,2,0,2);
464   grpbox->setFont(GMApp::instance()->getThickFont());
465 
466   matrix = new FXMatrix(grpbox,6,MATRIX_BY_COLUMNS|LAYOUT_SIDE_LEFT,0,0,0,0,0,0,0,0,0,0);
467 
468   new FXFrame(matrix,FRAME_NONE);
469   new FXLabel(matrix,tr("fg\tForeground Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_CENTER_X);
470   new FXLabel(matrix,tr("bg\tBackground Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_CENTER_X);
471   new FXLabel(matrix,tr("alt bg\tAlternative Background Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_CENTER_X);
472   new FXFrame(matrix,FRAME_NONE);
473   new FXFrame(matrix,FRAME_NONE);
474 
475   new FXFrame(matrix,FRAME_NONE);
476   new FXSeparator(matrix,SEPARATOR_LINE|LAYOUT_FILL_X);
477   new FXSeparator(matrix,SEPARATOR_LINE|LAYOUT_FILL_X);
478   new FXSeparator(matrix,SEPARATOR_LINE|LAYOUT_FILL_X);
479   new FXFrame(matrix,FRAME_NONE);
480   new FXFrame(matrix,FRAME_NONE);
481 
482   new FXLabel(matrix,tr("Normal\tNormal Text Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
483   new FXColorWell(matrix,0,this,ID_FORE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
484   new FXColorWell(matrix,0,this,ID_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
485   new FXColorWell(matrix,0,this,ID_ALTERNATIVE_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
486   new FXLabel(matrix,tr("Base\tBase Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
487   new FXColorWell(matrix,0,this,ID_BASE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
488 
489   new FXLabel(matrix,tr("Selected\tSelected Text Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
490   new FXColorWell(matrix,0,this,ID_SEL_FORE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
491   new FXColorWell(matrix,0,this,ID_SEL_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
492   new FXFrame(matrix,FRAME_NONE);
493   new FXLabel(matrix,tr("Menu\tMenu Base Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
494   new FXColorWell(matrix,0,this,ID_MENU_BASE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
495 
496 
497   new FXLabel(matrix,tr("Menu\tMenu Text Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
498   new FXColorWell(matrix,0,this,ID_MENU_FORE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
499   new FXColorWell(matrix,0,this,ID_MENU_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
500   new FXFrame(matrix,FRAME_NONE);
501   new FXLabel(matrix,tr("Border\tBorder Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
502   new FXColorWell(matrix,0,this,ID_BORDER_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
503 
504 
505   new FXLabel(matrix,tr("Tooltip\tTooltip Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
506   new FXColorWell(matrix,0,this,ID_TIP_FORE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
507   new FXColorWell(matrix,0,this,ID_TIP_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
508   new FXFrame(matrix,FRAME_NONE);
509   new FXLabel(matrix,tr("Hilite\tHilite Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
510   new FXColorWell(matrix,0,this,ID_HILITE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
511 
512   new FXFrame(matrix,FRAME_NONE);
513   new FXFrame(matrix,FRAME_NONE);
514   new FXFrame(matrix,FRAME_NONE);
515   new FXFrame(matrix,FRAME_NONE);
516   new FXLabel(matrix,tr("Shadow\tShadow Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
517   new FXColorWell(matrix,0,this,ID_SHADOW_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
518 
519   new FXLabel(matrix,tr("Playing\tPlaying Track Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
520   new FXColorWell(matrix,0,this,ID_PLAY_FORE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
521   new FXColorWell(matrix,0,this,ID_PLAY_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
522   new FXFrame(matrix,FRAME_NONE);
523   new FXLabel(matrix,tr("Tray\tTray Background Color"),nullptr,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT);
524   new FXColorWell(matrix,0,this,ID_TRAY_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24);
525 
526 
527   new FXFrame(matrix,FRAME_NONE);
528   new FXFrame(matrix,FRAME_NONE);
529 
530   new FXSeparator(grpbox,SEPARATOR_GROOVE|LAYOUT_FILL_Y|LAYOUT_SIDE_LEFT);
531 
532   vframe2 = new FXVerticalFrame(grpbox,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0,0,0);
533   new FXLabel(vframe2,tr("Presets:"));
534   GMScrollFrame * sunken = new GMScrollFrame(vframe2);
535   colorpresets = new GMList(sunken,this,ID_COLOR_THEME,LIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
536   colorpresets->setNumVisible(9);
537   colorpresets->setScrollStyle(HSCROLLING_OFF);
538 
539   initColorThemes();
540 
541   grpbox =  new FXGroupBox(vframe,tr("Font & Icons"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0);
542   grpbox->setFont(GMApp::instance()->getThickFont());
543 
544   matrix = new FXMatrix(grpbox,3,MATRIX_BY_COLUMNS|LAYOUT_FILL_X,0,0,0,0,20);
545 
546   new FXLabel(matrix,tr("Default Font"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y);
547   new GMTextField(matrix,20,this,ID_FONT,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|TEXTFIELD_NORMAL|TEXTFIELD_READONLY);
548   new GMButton(matrix,tr("Change…"),nullptr,this,ID_CHANGE_FONT,BUTTON_NORMAL|LAYOUT_CENTER_Y);
549 
550   new FXLabel(matrix,tr("Display DPI"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y);
551   GMSpinner * dpi_spinner = new GMSpinner(matrix,4,this,ID_DISPLAY_DPI,LAYOUT_FILL_COLUMN);
552   dpi_spinner->setValue(dpi);
553   dpi_spinner->setRange(72,200);
554   new FXFrame(matrix,FRAME_NONE);
555 
556 
557   new FXLabel(matrix,tr("Icons"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y);
558 
559   themelist = new GMListBox(matrix,this,ID_ICON_THEME,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X);
560   themelist->appendItem("Standard",nullptr,(void*)(FXival)-1);
561     for (FXint i=0;i<GMIconTheme::instance()->getNumThemes();i++) {
562       themelist->appendItem(GMIconTheme::instance()->getThemeName(i),nullptr,(void*)(FXival)i);
563       }
564   themelist->setSortFunc(FXList::ascending);
565   themelist->sortItems();
566   themelist->setNumVisible(FXMIN(9,themelist->getNumItems()));
567   for (FXint i=0;i<themelist->getNumItems();i++) {
568     if (GMIconTheme::instance()->getCurrentTheme()==(FXint)(FXival)themelist->getItemData(i)) {
569       themelist->setCurrentItem(i);
570       break;
571       }
572     }
573 
574   new FXFrame(matrix,FRAME_NONE);
575 
576   new GMTabItem(tabbook,tr("&Audio"),nullptr,TAB_TOP_NORMAL,0,0,0,0,5,5);
577   vframe = new GMTabFrame(tabbook);
578 
579   grpbox =  new FXGroupBox(vframe,tr("Output"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20);
580   grpbox->setFont(GMApp::instance()->getThickFont());
581 
582   matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X,0,0,0,0,0,0,0,0);
583   new FXLabel(matrix,tr("Driver:"),nullptr,labelstyle);
584 
585   driverlist = new GMListBox(matrix,this,ID_AUDIO_DRIVER,LISTBOX_NORMAL|LAYOUT_FILL_COLUMN);
586 
587   OutputConfig config;
588   GMPlayerManager::instance()->getPlayer()->getOutputConfig(config);
589 
590   FXStringList drivers;
591   FXuint devices=OutputConfig::devices();
592 
593   if (AP_HAS_PLUGIN(devices,DeviceAlsa))
594     driverlist->appendItem("Advanced Linux Sound Architecture",nullptr,(void*)DeviceAlsa);
595 
596   if (AP_HAS_PLUGIN(devices,DeviceOSS))
597     driverlist->appendItem("Open Sound System",nullptr,(void*)DeviceOSS);
598 
599   if (AP_HAS_PLUGIN(devices,DevicePulse))
600     driverlist->appendItem("PulseAudio",nullptr,(void*)DevicePulse);
601 
602   if (AP_HAS_PLUGIN(devices,DeviceJack))
603     driverlist->appendItem("Jack",nullptr,(void*)DeviceJack);
604 
605   if (AP_HAS_PLUGIN(devices,DeviceSndio))
606     driverlist->appendItem("Sndio",nullptr,(void*)DeviceSndio);
607 
608   if (AP_HAS_PLUGIN(devices,DeviceWav))
609     driverlist->appendItem("Wave File Output",nullptr,(void*)DeviceWav);
610 
611   if (driverlist->getNumItems()) {
612     driverlist->setCurrentItem(driverlist->findItemByData((void*)(FXival)config.device));
613     driverlist->setNumVisible(FXMIN(9,driverlist->getNumItems()));
614     }
615   else {
616     driverlist->disable();
617     driverlist->appendItem("No Plugins Found",nullptr,nullptr);
618     }
619   /// Alsa
620   alsa_device_label = new FXLabel(matrix,tr("Device:"),nullptr,labelstyle);
621   alsa_device = new GMTextField(matrix,20,nullptr,0,TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
622   alsa_device->setText(config.alsa.device);
623 
624   //alsa_mixer_label = new FXLabel(matrix,tr("Mixer:"),nullptr,labelstyle);
625  // alsa_mixer = new GMTextField(matrix,20);
626   //alsa_mixer->setText(config.alsa.mixer);
627 
628   alsa_hardware_only_frame = new FXFrame(matrix,FRAME_NONE);
629   alsa_hardware_only = new GMCheckButton(matrix,"No resampling",nullptr,0,CHECKBUTTON_NORMAL|LAYOUT_FILL_COLUMN);
630   alsa_hardware_only->setCheck((config.alsa.flags&AlsaConfig::DeviceNoResample)==AlsaConfig::DeviceNoResample);
631 
632   /// OSS
633   oss_device_label = new FXLabel(matrix,tr("Device:"),nullptr,labelstyle);
634   oss_device = new GMTextField(matrix,20,nullptr,0,TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
635   oss_device->setText(config.oss.device);
636 
637   /// Sndio
638   sndio_device_label = new FXLabel(matrix,tr("Device:"),nullptr,labelstyle);
639   sndio_device = new GMTextField(matrix,20,nullptr,0,TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
640   sndio_device->setText(config.sndio.device);
641 
642   showDriverSettings(config.device);
643 
644   new FXFrame(matrix,FRAME_NONE);
645   new GMButton(matrix,tr("Apply Changes"),nullptr,this,ID_APPLY_AUDIO,BUTTON_NORMAL|LAYOUT_FILL_COLUMN);
646 
647   grpbox =  new FXGroupBox(vframe,tr("Playback"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20);
648   grpbox->setFont(GMApp::instance()->getThickFont());
649 
650   matrix = new FXMatrix(grpbox,4,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP,0,0,0,0,0,0,0,0);
651 
652   new FXLabel(matrix,tr("Replay Gain:"),nullptr,labelstyle);
653 
654   GMListBox * gainlist = new GMListBox(matrix,&target_replaygain,FXDataTarget::ID_VALUE);
655   gainlist->appendItem(tr("Off"));
656   gainlist->appendItem(tr("Track"));
657   gainlist->appendItem(tr("Album"));
658   gainlist->setNumVisible(3);
659   new FXFrame(matrix,FRAME_NONE);
660   new FXFrame(matrix,FRAME_NONE);
661 
662 
663   new FXLabel(matrix,tr("Crossfade:"),nullptr,labelstyle);
664   auto crossfade_list = new GMListBox(matrix,&target_crossfade,FXDataTarget::ID_VALUE,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
665   crossfade_list->appendItem(tr("Off"));
666   crossfade_list->appendItem(tr("On"));
667   crossfade_list->setNumVisible(2);
668   auto crossfade_duration = new GMSpinner(matrix,5,&target_crossfade_duration,FXDataTarget::ID_VALUE,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
669   crossfade_duration->setRange(1,20000);
670   new FXLabel(matrix, tr("ms"), nullptr, labelstyle);
671 
672 
673 
674   // Podcast Settings
675   new GMTabItem(tabbook,tr("&Podcasts"),nullptr,TAB_TOP_NORMAL,0,0,0,0,5,5);
676   vframe = new GMTabFrame(tabbook);
677 
678   grpbox =  new FXGroupBox(vframe,tr("Updates"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20);
679   grpbox->setFont(GMApp::instance()->getThickFont());
680 
681   matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP,0,0,0,0);
682   new FXLabel(matrix,tr("Update Interval"),nullptr,labelstyle);
683   interval  = new GMListBox(matrix);
684   interval->appendItem(tr("Disabled"));
685   interval->appendItem(tr("10 minutes"));
686   interval->appendItem(tr("20 minutes"));
687   interval->appendItem(tr("30 minutes"));
688   interval->appendItem(tr("1 hour"));
689   interval->appendItem(tr("2 hours"));
690   interval->appendItem(tr("6 hours"));
691   interval->appendItem(tr("12 hours"));
692   interval->setNumVisible(FXMIN(interval->getNumItems(),9));
693 
694   FXlong update_interval =  GMPlayerManager::instance()->getPodcastSource()->getUpdateInterval();
695   if (update_interval<=0)
696     interval->setCurrentItem(0);
697   else if (update_interval<=10*MINUTES)
698     interval->setCurrentItem(1);
699   else if (update_interval<=20*MINUTES)
700     interval->setCurrentItem(2);
701   else if (update_interval<=30*MINUTES)
702     interval->setCurrentItem(3);
703   else if (update_interval<=60*MINUTES)
704     interval->setCurrentItem(4);
705   else if (update_interval<=120*MINUTES)
706     interval->setCurrentItem(5);
707   else if (update_interval<=360*MINUTES)
708     interval->setCurrentItem(6);
709   else
710     interval->setCurrentItem(7);
711 
712   FXHorizontalFrame *closebox=new FXHorizontalFrame(main,LAYOUT_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,0,0);
713   new GMButton(closebox,tr("&Close"),nullptr,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 20,20);
714   }
715 
~GMPreferencesDialog()716 GMPreferencesDialog::~GMPreferencesDialog(){
717   }
718 
719 
updateFonts()720 void GMPreferencesDialog::updateFonts() {
721   GMPlayerManager::instance()->getMainWindow()->getTrackView()->updateFont();
722   redraw();
723   FXint nw =getDefaultWidth();
724   FXint nh = getDefaultHeight();
725   resize(nw,nh);
726   }
727 
onCmdDisplayDPI(FXObject *,FXSelector,void * ptr)728 long GMPreferencesDialog::onCmdDisplayDPI(FXObject*,FXSelector,void*ptr){
729   dpi = (FXint)(FXival)ptr;
730   getApp()->reg().writeIntEntry("SETTINGS","screenres",dpi);
731   GMApp::instance()->updateFont();
732   updateFonts();
733   return 1;
734   }
735 
showDriverSettings(FXuchar driver)736 void GMPreferencesDialog::showDriverSettings(FXuchar driver) {
737   switch(driver) {
738     case DeviceAlsa:
739       {
740         alsa_device_label->show();
741         alsa_device->show();
742         alsa_hardware_only->show();
743         alsa_hardware_only_frame->show();
744         oss_device->hide();
745         oss_device_label->hide();
746         sndio_device->hide();
747         sndio_device_label->hide();
748 
749       } break;
750 
751     case DeviceOSS:
752       {
753         alsa_device_label->hide();
754         alsa_device->hide();
755         alsa_hardware_only->hide();
756         alsa_hardware_only_frame->hide();
757         sndio_device->hide();
758         sndio_device_label->hide();
759         oss_device->show();
760         oss_device_label->show();
761       } break;
762 
763     case DevicePulse:
764       {
765         alsa_device_label->hide();
766         alsa_device->hide();
767         alsa_hardware_only->hide();
768         alsa_hardware_only_frame->hide();
769         oss_device->hide();
770         oss_device_label->hide();
771         sndio_device->hide();
772         sndio_device_label->hide();
773       } break;
774 
775     case DeviceSndio:
776       {
777         alsa_device_label->hide();
778         alsa_device->hide();
779         alsa_hardware_only->hide();
780         alsa_hardware_only_frame->hide();
781         oss_device->hide();
782         oss_device_label->hide();
783         sndio_device->show();
784         sndio_device_label->show();
785       } break;
786 
787     default:
788       {
789         alsa_device_label->hide();
790         alsa_device->hide();
791         alsa_hardware_only->hide();
792         alsa_hardware_only_frame->hide();
793         oss_device->hide();
794         oss_device_label->hide();
795         sndio_device->hide();
796         sndio_device_label->hide();
797       } break;
798 
799     }
800 
801   alsa_device_label->getParent()->recalc();
802   }
803 
804 
onCmdApplyAudio(FXObject *,FXSelector,void *)805 long GMPreferencesDialog::onCmdApplyAudio(FXObject*,FXSelector,void*){
806 
807   OutputConfig config;
808   GMPlayerManager::instance()->getPlayer()->getOutputConfig(config);
809 
810   config.device = (FXuchar)(FXival)driverlist->getItemData(driverlist->getCurrentItem());
811 
812   /// Alsa Settings
813   config.alsa.device = alsa_device->getText();
814 
815   if (alsa_hardware_only->getCheck())
816     config.alsa.flags|=AlsaConfig::DeviceNoResample;
817   else
818     config.alsa.flags&=~AlsaConfig::DeviceNoResample;
819 
820   config.oss.device = oss_device->getText();
821   config.sndio.device = sndio_device->getText();
822 
823   GMPlayerManager::instance()->getPlayer()->setOutputConfig(config);
824   return 1;
825   }
826 
onCmdAudioDriver(FXObject *,FXSelector,void *)827 long GMPreferencesDialog::onCmdAudioDriver(FXObject*,FXSelector,void*){
828   FXuchar device=(FXuchar)(FXival)driverlist->getItemData(driverlist->getCurrentItem());
829   showDriverSettings(device);
830 //  layout();
831 //  forceRefresh();
832   return 1;
833   }
834 
onCmdCrossFade(FXObject *,FXSelector,void *)835 long GMPreferencesDialog::onCmdCrossFade(FXObject*,FXSelector,void*){
836   if (GMPlayerManager::instance()->getPreferences().play_crossfade)
837     GMPlayerManager::instance()->getPlayer()->setCrossFade(GMPlayerManager::instance()->getPreferences().play_crossfade_duration);
838   else
839     GMPlayerManager::instance()->getPlayer()->setCrossFade(0);
840   return 1;
841   }
842 
onCmdReplayGain(FXObject *,FXSelector,void *)843 long GMPreferencesDialog::onCmdReplayGain(FXObject*,FXSelector,void*){
844   switch(GMPlayerManager::instance()->getPreferences().play_replaygain){
845     case 0: GMPlayerManager::instance()->getPlayer()->setReplayGain(ReplayGainOff); break;
846     case 1: GMPlayerManager::instance()->getPlayer()->setReplayGain(ReplayGainTrack); break;
847     case 2: GMPlayerManager::instance()->getPlayer()->setReplayGain(ReplayGainAlbum); break;
848     }
849   return 1;
850   }
851 
852 
onCmdAccept(FXObject *,FXSelector,void *)853 long GMPreferencesDialog::onCmdAccept(FXObject*,FXSelector,void*) {
854   getApp()->stopModal(this,true);
855   hide();
856 
857   FXlong update_interval = 0;
858   switch(interval->getCurrentItem()){
859     case 0: update_interval = 0;             break;
860     case 1: update_interval = 10  * MINUTES; break;
861     case 2: update_interval = 20  * MINUTES; break;
862     case 3: update_interval = 30  * MINUTES; break;
863     case 4: update_interval = 60  * MINUTES; break;
864     case 5: update_interval = 120 * MINUTES; break;
865     case 6: update_interval = 360 * MINUTES; break;
866     case 7: update_interval = 720 * MINUTES; break;
867     default: break;
868     }
869   GMPlayerManager::instance()->getPodcastSource()->setUpdateInterval(update_interval);
870 
871   GMWindow * mainwindow = GMPlayerManager::instance()->getMainWindow();
872 
873   if (!GMPlayerManager::instance()->getAudioScrobbler()->isBanned() && password_set) {
874     GMPlayerManager::instance()->getAudioScrobbler()->login(lastfm_username->getText(),lastfm_password->getText());
875     }
876 
877   GMPlayerManager::instance()->getPreferences().setKeyWords(keywords);
878 
879   if (!(selected==current)) {
880     GMIconTheme::instance()->load();
881     redraw();
882     }
883 
884   mainwindow->configureToolbar((toolbar_docktop->getCurrentItem()==0));
885   mainwindow->configureStatusbar(statusbarbutton->getCheck());
886 
887 
888   GMPlayerManager::instance()->update_cover_display();
889 
890   GMPlayerManager::instance()->update_tray_icon();
891 #ifdef HAVE_DBUS
892   GMPlayerManager::instance()->update_mpris();
893 #endif
894 
895   // Key Words may have changed.
896   mainwindow->getTrackView()->resort();
897   mainwindow->getSourceView()->resort();
898   return 1;
899   }
900 
901 
902 
903 
initColorThemes()904 void GMPreferencesDialog::initColorThemes() {
905   for(FXuint i=0;i<ARRAYNUMBER(ColorThemes);i++){
906     colorpresets->appendItem(ColorThemes[i].name,nullptr,(void*)&ColorThemes[i]);
907     }
908 
909   theme=-1;
910   for(FXuint i=0;i<ARRAYNUMBER(ColorThemes);i++){
911     if (current==ColorThemes[i]){
912       theme=i;
913       break;
914       }
915     }
916 
917   if (theme==-1){
918     colorpresets->prependItem(tr("Current"),nullptr,(void*)&current);
919     theme=0;
920     }
921   }
922 
923 
updateColorThemes()924 void GMPreferencesDialog::updateColorThemes() {
925   theme=-1;
926 
927   for (FXint i=0;i<colorpresets->getNumItems();i++){
928     if (selected==*static_cast<ColorTheme*>(colorpresets->getItemData(i))){
929       theme=i;
930       return;
931       }
932     }
933 
934   if (theme==-1) {
935     theme=colorpresets->getNumItems();
936     colorpresets->appendItem(tr("Custom"),nullptr,(void*)&selected);
937     }
938   else if (theme<colorpresets->getNumItems()-1) {
939     if (colorpresets->getItemData(colorpresets->getNumItems()-1)==&selected)
940       colorpresets->removeItem(colorpresets->getNumItems()-1);
941     }
942   }
943 
944 
945 
onCmdIconTheme(FXObject *,FXSelector,void *)946 long GMPreferencesDialog::onCmdIconTheme(FXObject*,FXSelector,void*){
947   GMIconTheme::instance()->setCurrentTheme((FXint)(FXival)themelist->getItemData(themelist->getCurrentItem()));
948   GMIconTheme::instance()->load();
949   redraw();
950   return 1;
951   }
952 
953 
954 
955 
956 
957 
onCmdLastFMScrobble(FXObject *,FXSelector,void *)958 long GMPreferencesDialog::onCmdLastFMScrobble(FXObject*,FXSelector,void*){
959   if (lastfm_scrobble->getCheck())
960     GMPlayerManager::instance()->getAudioScrobbler()->enable();
961   else
962     GMPlayerManager::instance()->getAudioScrobbler()->disable();
963   return 1;
964   }
965 
966 
onCmdLastFMService(FXObject *,FXSelector,void *)967 long GMPreferencesDialog::onCmdLastFMService(FXObject*,FXSelector,void*){
968   if (lastfm_service->getCurrentItem()!=SERVICE_CUSTOM) {
969 
970 
971     GMPlayerManager::instance()->getAudioScrobbler()->service(lastfm_service->getCurrentItem());
972     lastfm_username->setText(FXString::null,false);
973     lastfm_password->setText(FXString::null,false);
974     password_set=false;
975     if (lastfm_service->getNumItems()==3) {
976       lastfm_service->removeItem(2);
977       lastfm_service->setNumVisible(2);
978       }
979     lastfm_join->show();
980     }
981 
982   if (lastfm_service->getCurrentItem()==SERVICE_LASTFM){
983     lastfm_username->hide();
984     lastfm_username_label->hide();
985     lastfm_password->hide();
986     lastfm_password_label->hide();
987     }
988   else {
989     lastfm_username->show();
990     lastfm_username_label->show();
991     lastfm_password->show();
992     lastfm_password_label->show();
993     }
994   return 1;
995   }
996 
997 
onCmdLastFMPassWord(FXObject *,FXSelector,void *)998 long GMPreferencesDialog::onCmdLastFMPassWord(FXObject*,FXSelector,void*){
999   if (!GMPlayerManager::instance()->getAudioScrobbler()->isBanned() && password_set) {
1000     lastfm_scrobble->setCheck(true);
1001     GMPlayerManager::instance()->getAudioScrobbler()->login(lastfm_username->getText(),lastfm_password->getText());
1002     }
1003   return 1;
1004   }
1005 
onFocusLastFMPassWord(FXObject *,FXSelector,void *)1006 long GMPreferencesDialog::onFocusLastFMPassWord(FXObject*,FXSelector,void*){
1007   if (password_set==false) {
1008     password_set=true;
1009     lastfm_password->setText(FXString::null,false);
1010     }
1011   return 0;
1012   }
1013 
onCmdLastFMUserName(FXObject *,FXSelector sel,void *)1014 long GMPreferencesDialog::onCmdLastFMUserName(FXObject*,FXSelector sel,void*){
1015   lastfm_password->setText(FXString::null,false);
1016   password_set=true;
1017   if (FXSELTYPE(sel)==SEL_COMMAND) lastfm_password->setFocus();
1018   return 1;
1019   }
1020 
onCmdLastFMJoin(FXObject *,FXSelector,void *)1021 long GMPreferencesDialog::onCmdLastFMJoin(FXObject*,FXSelector,void*){
1022   FXuint service = GMPlayerManager::instance()->getAudioScrobbler()->getService();
1023   if (service==SERVICE_LASTFM) {
1024     if (!gm_open_browser("https://www.last.fm/join/")){
1025       FXMessageBox::error(this,MBOX_OK,tr("Unable to launch webbrowser"),"Goggles Music Manager was unable to launch a webbrowser.\nPlease visit https://www.last.fm/join/");
1026       }
1027     }
1028   else if (service==SERVICE_LIBREFM) {
1029    if (!gm_open_browser("http://alpha.libre.fm/register.php")){
1030       FXMessageBox::error(this,MBOX_OK,tr("Unable to launch webbrowser"),"Goggles Music Manager was unable to launch a webbrowser.\nPlease visit http://alpha.libre.fm/register.php");
1031       }
1032     }
1033   return 1;
1034   }
1035 
1036 
1037 
onCmdElementColor(FXObject *,FXSelector sel,void * rgba)1038 long GMPreferencesDialog::onCmdElementColor(FXObject*,FXSelector sel,void* rgba) {
1039   FXColor color = (FXColor)(FXuval)rgba;
1040 
1041   switch(FXSELID(sel)){
1042     case ID_BASE_COLOR : selected.base = color;
1043                          selected.shadow = makeShadowColor(selected.base);
1044                          selected.hilite = makeHiliteColor(selected.base);
1045                          break;
1046     case ID_BORDER_COLOR : selected.border = color; break;
1047     case ID_BACK_COLOR   : selected.back = color; break;
1048     case ID_FORE_COLOR  : selected.fore = color; break;
1049     case ID_SHADOW_COLOR : selected.shadow=color; break;
1050     case ID_HILITE_COLOR : selected.hilite=color; break;
1051 
1052 
1053     case ID_SEL_BACK_COLOR: selected.selback=color; break;
1054     case ID_SEL_FORE_COLOR: selected.selfore=color; break;
1055     case ID_MENU_BACK_COLOR: selected.menuback=color; break;
1056     case ID_MENU_FORE_COLOR: selected.menufore=color; break;
1057     case ID_MENU_BASE_COLOR: selected.menubase=color; break;
1058     case ID_TIP_BACK_COLOR: selected.tipback=color; break;
1059     case ID_TIP_FORE_COLOR: selected.tipfore=color; break;
1060     case ID_PLAY_BACK_COLOR: selected.playback=color; break;
1061     case ID_PLAY_FORE_COLOR: selected.playfore=color; break;
1062     case ID_ALTERNATIVE_BACK_COLOR: selected.altback=color; break;
1063     case ID_TRAY_COLOR: selected.trayback=color; break;
1064 
1065      }
1066 
1067   updateColors();
1068 
1069   updateColorThemes();
1070   return 1;
1071   }
1072 
onUpdElementColor(FXObject * sender,FXSelector sel,void *)1073 long GMPreferencesDialog::onUpdElementColor(FXObject*sender,FXSelector sel,void*) {
1074   FXuval rgba = 0;
1075   switch(FXSELID(sel)){
1076     case ID_BASE_COLOR : rgba=selected.base; break;
1077     case ID_BORDER_COLOR : rgba=selected.border; break;
1078     case ID_BACK_COLOR : rgba=selected.back; break;
1079     case ID_FORE_COLOR : rgba=selected.fore; break;
1080     case ID_SHADOW_COLOR : rgba=selected.shadow; break;
1081     case ID_HILITE_COLOR : rgba=selected.hilite; break;
1082 
1083     case ID_SEL_BACK_COLOR: rgba=selected.selback; break;
1084     case ID_SEL_FORE_COLOR: rgba=selected.selfore; break;
1085     case ID_MENU_BACK_COLOR: rgba=selected.menuback; break;
1086     case ID_MENU_FORE_COLOR: rgba=selected.menufore; break;
1087     case ID_MENU_BASE_COLOR: rgba=selected.menubase; break;
1088     case ID_TIP_BACK_COLOR: rgba=selected.tipback; break;
1089     case ID_TIP_FORE_COLOR: rgba=selected.tipfore; break;
1090     case ID_PLAY_BACK_COLOR: rgba=selected.playback; break;
1091     case ID_PLAY_FORE_COLOR: rgba=selected.playfore; break;
1092     case ID_ALTERNATIVE_BACK_COLOR: rgba=selected.altback; break;
1093     case ID_TRAY_COLOR: rgba=selected.trayback; break;
1094     }
1095   sender->tryHandle(this,FXSEL(SEL_COMMAND,FXColorWell::ID_SETINTVALUE),&rgba);
1096   return 1;
1097   }
onCmdColorTheme(FXObject *,FXSelector,void * ptr)1098 long GMPreferencesDialog::onCmdColorTheme(FXObject*,FXSelector,void*ptr) {
1099   theme=(FXint)(FXival)ptr;
1100   ColorTheme *theme_selected=static_cast<ColorTheme*>(colorpresets->getItemData(theme));
1101 
1102   selected.base = theme_selected->base;
1103   selected.border = theme_selected->border;
1104   selected.back = theme_selected->back;
1105   selected.altback = theme_selected->altback;
1106   selected.fore = theme_selected->fore;
1107   selected.selfore	= theme_selected->selfore;
1108   selected.selback	= theme_selected->selback;
1109   selected.tipfore	= theme_selected->tipfore;
1110   selected.tipback	= theme_selected->tipback;
1111   selected.menufore= theme_selected->menufore;
1112   selected.menuback= theme_selected->menuback;
1113   selected.menubase= theme_selected->menubase;
1114   selected.shadow = makeShadowColor(selected.base);
1115   selected.hilite   = makeHiliteColor(selected.base);
1116   selected.playback = theme_selected->playback;
1117   selected.playfore = theme_selected->playfore;
1118   selected.trayback = theme_selected->trayback;
1119 
1120   updateColors();
1121   return 1;
1122   }
1123 
onUpdColorTheme(FXObject * sender,FXSelector,void *)1124 long GMPreferencesDialog::onUpdColorTheme(FXObject*sender,FXSelector,void*) {
1125   sender->tryHandle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SETINTVALUE),&theme);
1126   return 1;
1127   }
1128 
1129 
1130 
updateColors()1131 void GMPreferencesDialog::updateColors(){
1132   FXWindow *w=FXApp::instance()->getRootWindow();
1133 
1134   FX7Segment * sevensegment;
1135   FXTextField * gmtextfield;
1136   FXIconList * iconlist;
1137   FXList * list;
1138   FXListBox * listbox;
1139   FXTreeList * treelist;
1140   FXComboBox * combobox;
1141   FXButton * button;
1142   FXFrame * frame;
1143   FXLabel * label;
1144   FXPopup * popup;
1145   FXMenuTitle * menutitle;
1146   FXMenuCheck * menucheck;
1147   FXMenuRadio * menuradio;
1148   FXMenuCaption * menucaption;
1149   FXMenuSeparator * menuseparator;
1150   FXText * text;
1151   FXFoldingList * foldinglist;
1152   // FXMDIChild * mdichild;
1153   FXTable * table;
1154   // FXDockTitle * docktitle;
1155   FXPacker * packer;
1156   FXHeader * header;
1157   FXGroupBox * groupbox;
1158   FXScrollBar * scrollbar;
1159   FXSlider * slider;
1160   FXStatusLine * statusline;
1161   FXDragCorner * dragcorner;
1162   GMTreeList * gmtreelist;
1163   GMTrackList * gmtracklist;
1164   FXRadioButton * radiobutton;
1165   GMCheckButton * checkbutton;
1166   FXToolTip * tooltip;
1167 
1168   GMList        * gmlist;
1169   GMListBox     * gmlistbox;
1170   GMComboBox     * gmcombobox;
1171   GMScrollFrame * gmscrollframe;
1172   GMTabFrame    * gmtabframe;
1173   GMImageFrame  * gmimageframe;
1174   GMCoverFrame  * gmcoverframe;
1175 #ifdef HAVE_OPENGL
1176   GMImageView   * gmimageview;
1177 #endif
1178   GMMenuPane    * gmmenupane;
1179   GMProgressBar * gmprogressbar;
1180   GMTrackProgressBar * gmtrackprogressbar;
1181   GMSpinner 		* gmspinner;
1182   GMAlbumList   * gmalbumlist;
1183 
1184   while(w){
1185     w->setBackColor(selected.base);
1186     if ((frame=dynamic_cast<FXFrame*>(w))!=nullptr) {
1187 
1188       frame->setBaseColor(selected.base);
1189       frame->setBackColor(selected.base);
1190       frame->setShadowColor(selected.shadow);
1191       frame->setHiliteColor(selected.hilite);
1192       frame->setBorderColor(selected.border);
1193 
1194       if ((label=dynamic_cast<FXLabel*>(w))!=nullptr) {
1195         label->setTextColor(selected.fore);
1196         if ((button=dynamic_cast<FXButton*>(w))!=nullptr) {
1197           if (dynamic_cast<GMListBox*>(button->getParent())){
1198             w->setBackColor(selected.back);
1199             }
1200           else {
1201             w->setBackColor(selected.base);
1202             }
1203           }
1204         else if ((checkbutton=dynamic_cast<GMCheckButton*>(w))!=nullptr) {
1205           checkbutton->setCheckColor(selected.fore);
1206           checkbutton->setBoxColor(selected.back);
1207           }
1208         else if ((radiobutton=dynamic_cast<FXRadioButton*>(w))!=nullptr) {
1209           radiobutton->setRadioColor(selected.fore);
1210           radiobutton->setDiskColor(selected.back);
1211           }
1212         }
1213       else if ((gmtextfield=dynamic_cast<FXTextField*>(w))!=nullptr) {
1214         w->setBackColor(selected.back);
1215         gmtextfield->setTextColor(selected.fore);
1216         gmtextfield->setSelTextColor(selected.selfore);
1217         gmtextfield->setSelBackColor(selected.selback);
1218         gmtextfield->setBorderColor(selected.shadow);
1219         }
1220 /*
1221       else if ((docktitle=dynamic_cast<FXDockTitle*>(w))!=nullptr) {
1222         docktitle->setCaptionColor(selected.selfore);
1223         docktitle->setBackColor(selected.selback);
1224         }
1225 */
1226       else if ((header=dynamic_cast<FXHeader*>(w))!=nullptr) {
1227         header->setTextColor(selected.fore);
1228         }
1229       else if ((statusline=dynamic_cast<FXStatusLine*>(w))!=nullptr) {
1230         statusline->setTextColor(selected.fore);
1231         }
1232       else if ((sevensegment=dynamic_cast<FX7Segment*>(w))!=nullptr) {
1233         sevensegment->setTextColor(selected.fore);
1234         }
1235       else if ((slider=dynamic_cast<FXSlider*>(w))!=nullptr) {
1236         slider->setSlotColor(selected.back);
1237         }
1238      else if ((gmimageframe=dynamic_cast<GMImageFrame*>(w))!=nullptr) {
1239         gmimageframe->setBorderColor(selected.shadow);
1240         gmimageframe->setBackColor(selected.back); /// fixme, only for coverframe in mainwindow
1241         }
1242      else if ((gmprogressbar=dynamic_cast<GMProgressBar*>(w))!=nullptr) {
1243         gmprogressbar->setBarBGColor(selected.back);
1244         gmprogressbar->setBorderColor(selected.shadow);
1245         gmprogressbar->setBarColor(selected.selback);
1246         gmprogressbar->setTextAltColor(selected.selfore);
1247         }
1248      else if ((gmtrackprogressbar=dynamic_cast<GMTrackProgressBar*>(w))!=nullptr) {
1249         gmtrackprogressbar->setBarBGColor(selected.back);
1250         gmtrackprogressbar->setBorderColor(selected.shadow);
1251         gmtrackprogressbar->setBarColor(selected.selback);
1252         gmtrackprogressbar->setTextAltColor(selected.selfore);
1253         }
1254 
1255      }
1256    else if ((packer=dynamic_cast<FXPacker*>(w))!=nullptr) {
1257       packer->setBaseColor(selected.base);
1258       packer->setBackColor(selected.base);
1259       packer->setShadowColor(selected.shadow);
1260       packer->setHiliteColor(selected.hilite);
1261       packer->setBorderColor(selected.border);
1262       if ((gmscrollframe=dynamic_cast<GMScrollFrame*>(w))!=nullptr){
1263         gmscrollframe->setBorderColor(selected.shadow);
1264         }
1265       else if ((gmtabframe=dynamic_cast<GMTabFrame*>(w))!=nullptr){
1266         gmtabframe->setBorderColor(selected.shadow);
1267         }
1268        else if ((gmcoverframe=dynamic_cast<GMCoverFrame*>(w))!=nullptr){
1269         gmcoverframe->setBorderColor(selected.shadow);
1270         gmcoverframe->setBackColor(selected.back);
1271         }
1272       else if ((combobox=dynamic_cast<FXComboBox*>(w))!=nullptr) {
1273         w->setBackColor(selected.back);
1274         }
1275       else if ((listbox=dynamic_cast<FXListBox*>(w))!=nullptr) {
1276         //w->setBackColor(selected.back);
1277         if ((gmlistbox=dynamic_cast<GMListBox*>(w))!=nullptr) {
1278           gmlistbox->setBorderColor(selected.shadow);
1279           }
1280         }
1281       else if ((groupbox=dynamic_cast<FXGroupBox*>(w))!=nullptr) {
1282         groupbox->setTextColor(selected.fore);
1283         }
1284       else if ((gmspinner=dynamic_cast<GMSpinner*>(w))!=nullptr) {
1285         gmspinner->setBorderColor(selected.shadow);
1286         gmspinner->setUpArrowColor(selected.fore);
1287         gmspinner->setDownArrowColor(selected.fore);
1288         }
1289       }
1290     else if ((popup=dynamic_cast<FXPopup*>(w))!=nullptr){
1291       popup->setBaseColor(selected.base);
1292       popup->setShadowColor(selected.shadow);
1293       popup->setHiliteColor(selected.hilite);
1294       popup->setBorderColor(selected.border);
1295       if ((gmmenupane=dynamic_cast<GMMenuPane*>(w))!=nullptr || (gmlistbox=dynamic_cast<GMListBox*>(w->getParent()))!=nullptr ||  (gmcombobox=dynamic_cast<GMComboBox*>(w->getParent()))!=nullptr){
1296         popup->setBorderColor(selected.shadow);
1297         }
1298       }
1299     else if ((menucaption=dynamic_cast<FXMenuCaption*>(w))!=nullptr) {
1300       w->setBackColor(selected.menubase);
1301       menucaption->setTextColor(selected.fore);
1302       menucaption->setSelTextColor(selected.menufore);
1303       menucaption->setSelBackColor(selected.menuback);
1304       menucaption->setShadowColor(makeShadowColor(selected.menubase));
1305       menucaption->setHiliteColor(makeHiliteColor(selected.menubase));
1306 
1307       if ((menucheck=dynamic_cast<FXMenuCheck*>(w))!=nullptr) {
1308         menucheck->setBoxColor(selected.back);
1309         }
1310       else if ((menuradio=dynamic_cast<FXMenuRadio*>(w))!=nullptr) {
1311         menuradio->setRadioColor(selected.back);
1312         }
1313       else if ((menutitle=dynamic_cast<FXMenuTitle*>(w))!=nullptr) {
1314         w->setBackColor(selected.base);
1315         menutitle->setTextColor(selected.fore);
1316         menutitle->setSelTextColor(selected.menufore);
1317         menutitle->setSelBackColor(selected.menuback);
1318         menutitle->setShadowColor(selected.shadow);
1319         menutitle->setHiliteColor(selected.hilite);
1320         }
1321       }
1322     else if ((menuseparator=dynamic_cast<FXMenuSeparator*>(w))!=nullptr) {
1323       menuseparator->setShadowColor(makeShadowColor(selected.menubase));
1324       menuseparator->setHiliteColor(makeHiliteColor(selected.menubase));
1325       }
1326     else if ((scrollbar=dynamic_cast<FXScrollBar*>(w))!=nullptr) {
1327       scrollbar->setShadowColor(selected.shadow);
1328       scrollbar->setHiliteColor(selected.hilite);
1329       scrollbar->setBorderColor(selected.border);
1330       scrollbar->setArrowColor(selected.fore);
1331       }
1332     else if ((dragcorner=dynamic_cast<FXDragCorner*>(w))!=nullptr) {
1333       dragcorner->setShadowColor(selected.shadow);
1334       dragcorner->setHiliteColor(selected.hilite);
1335       }
1336     else if (dynamic_cast<FXScrollArea*>(w)) {
1337       if ((text=dynamic_cast<FXText*>(w))!=nullptr) {
1338         w->setBackColor(selected.back);
1339         text->setTextColor(selected.fore);
1340         text->setSelTextColor(selected.selfore);
1341         text->setSelBackColor(selected.selback);
1342         }
1343       else if ((list=dynamic_cast<FXList*>(w))!=nullptr) {
1344         w->setBackColor(selected.back);
1345         list->setTextColor(selected.fore);
1346         list->setSelTextColor(selected.selfore);
1347         list->setSelBackColor(selected.selback);
1348         if ((gmlist=dynamic_cast<GMList*>(w))!=nullptr) {
1349           gmlist->setRowColor(selected.altback);
1350          ((FXFrame*)gmlist->getParent())->setBorderColor(selected.shadow);
1351           }
1352         }
1353       else if ((treelist=dynamic_cast<FXTreeList*>(w))!=nullptr) {
1354         w->setBackColor(selected.back);
1355         treelist->setTextColor(selected.fore);
1356         treelist->setLineColor(selected.shadow);
1357         treelist->setSelTextColor(selected.selfore);
1358         treelist->setSelBackColor(selected.selback);
1359         if ((gmtreelist=dynamic_cast<GMTreeList*>(w))!=nullptr) {
1360          gmtreelist->setRowColor(selected.altback);
1361          ((FXFrame*)gmtreelist->getParent())->setBorderColor(selected.shadow);
1362           }
1363         else {
1364           treelist->setSelTextColor(selected.selfore);
1365           treelist->setSelBackColor(selected.selback);
1366           }
1367         }
1368       else if ((iconlist=dynamic_cast<FXIconList*>(w))!=nullptr) {
1369         w->setBackColor(selected.back);
1370         iconlist->setTextColor(selected.fore);
1371         iconlist->setSelTextColor(selected.selfore);
1372         iconlist->setSelBackColor(selected.selback);
1373         }
1374       else if ((gmalbumlist=dynamic_cast<GMAlbumList*>(w))!=nullptr) {
1375         w->setBackColor(selected.back);
1376         gmalbumlist->setTextColor(selected.fore);
1377         gmalbumlist->setSelTextColor(selected.selfore);
1378         gmalbumlist->setSelBackColor(selected.selback);
1379         gmalbumlist->setAltBackColor(selected.altback);
1380         }
1381       else if ((gmtracklist=dynamic_cast<GMTrackList*>(w))!=nullptr) {
1382         w->setBackColor(selected.back);
1383         //((FXFrame*)gmtracklist->getParent())->setBorderColor(selected.shadow);
1384         gmtracklist->setTextColor(selected.fore);
1385         gmtracklist->setSelTextColor(selected.selfore);
1386         gmtracklist->setSelBackColor(selected.selback);
1387         gmtracklist->setRowColor(selected.altback);
1388         gmtracklist->setActiveTextColor(selected.playfore);
1389         gmtracklist->setActiveColor(selected.playback);
1390         }
1391       else if ((foldinglist=dynamic_cast<FXFoldingList*>(w))!=nullptr) {
1392         w->setBackColor(selected.back);
1393         foldinglist->setTextColor(selected.fore);
1394         foldinglist->setSelTextColor(selected.selfore);
1395         foldinglist->setSelBackColor(selected.selback);
1396         foldinglist->setLineColor(selected.shadow);
1397         }
1398       else if ((table=dynamic_cast<FXTable*>(w))!=nullptr) {
1399         w->setBackColor(selected.back);
1400         table->setTextColor(selected.fore);
1401         table->setSelTextColor(selected.selfore);
1402         table->setSelBackColor(selected.selback);
1403         }
1404       }
1405 /*
1406     else if ((mdichild=dynamic_cast<FXMDIChild*>(w))!=nullptr) {
1407       mdichild->setBackColor(selected.base);
1408       mdichild->setBaseColor(selected.base);
1409       mdichild->setShadowColor(selected.shadow);
1410       mdichild->setHiliteColor(selected.hilite);
1411       mdichild->setBorderColor(selected.border);
1412       mdichild->setTitleColor(selected.selfore);
1413       mdichild->setTitleBackColor(selected.selback);
1414       }
1415 */
1416     else if ((tooltip=dynamic_cast<FXToolTip*>(w))!=nullptr){
1417       tooltip->setTextColor(selected.tipfore);
1418       tooltip->setBackColor(selected.tipback);
1419       }
1420 #ifdef HAVE_OPENGL
1421     else if ((gmimageview=dynamic_cast<GMImageView*>(w))!=nullptr){
1422       gmimageview->setBackColor(selected.back);
1423       }
1424 #endif
1425     w->update();
1426     if(w->getFirst()){
1427       w=w->getFirst();
1428       continue;
1429       }
1430     while(!w->getNext() && w->getParent()){
1431       w=w->getParent();
1432       }
1433     w=w->getNext();
1434     }
1435   selected.save();
1436 
1437   if (GMPlayerManager::instance()->getTrayIcon())
1438     GMPlayerManager::instance()->getTrayIcon()->updateIcon();
1439   }
1440 
1441 
redraw()1442 void GMPreferencesDialog::redraw(){
1443   FXWindow *w=GMPlayerManager::instance()->getMainWindow();
1444   while(w){
1445     w->recalc();
1446     w->update();
1447     if(w->getFirst()){
1448       w=w->getFirst();
1449       continue;
1450       }
1451     while(!w->getNext() && w->getParent()){
1452       w=w->getParent();
1453       }
1454     w=w->getNext();
1455     }
1456   }
1457 
1458 
1459 
1460 
fancyfontname(FXFont * font,FXString & name)1461 static void fancyfontname(FXFont * font,FXString & name) {
1462   name = font->getActualName().before('[').trimEnd();
1463   const FXchar *wgt=nullptr,*slt=nullptr,*wid=nullptr;
1464   const FXint size=font->getActualSize()/10;
1465 
1466   switch(font->getActualSetWidth()){
1467      case FXFont::UltraCondensed: wid="Ultra Condensed"; break;
1468      case FXFont::ExtraCondensed: wid="Extra Condensed"; break;
1469      case FXFont::Condensed:      wid="Condensed"; break;
1470      case FXFont::SemiCondensed:  wid="Semi Condensed"; break;
1471      case FXFont::NonExpanded:    wid=nullptr; break;
1472      case FXFont::SemiExpanded:   wid="Semi Expanded"; break;
1473      case FXFont::Expanded:       wid="Expanded"; break;
1474      case FXFont::ExtraExpanded:  wid="Extra Expanded"; break;
1475      case FXFont::UltraExpanded:  wid="Ultra Expanded"; break;
1476      default: wid=nullptr; break;
1477      }
1478 
1479   switch(font->getActualWeight()){
1480     case FXFont::Thin      : wgt=fxtr("Thin"); break;
1481     case FXFont::ExtraLight: wgt=fxtr("Extra Light"); break;
1482     case FXFont::Light     : wgt=fxtr("Light"); break;
1483     case FXFont::Normal    : wgt=nullptr; break;
1484     case FXFont::Medium    : wgt=fxtr("Medium"); break;
1485     case FXFont::DemiBold  : wgt=fxtr("Demibold"); break;
1486     case FXFont::Bold      : wgt=fxtr("Bold"); break;
1487     case FXFont::ExtraBold : wgt=fxtr("Extra Bold"); break;
1488     case FXFont::Black     : wgt=fxtr("Heavy"); break;
1489     default: wgt=nullptr; break;
1490     }
1491 
1492   switch(font->getActualSlant()){
1493     case FXFont::ReverseOblique: slt="Reverse Oblique"; break;
1494     case FXFont::ReverseItalic: slt="Reverse Italic"; break;
1495     case FXFont::Straight: slt=nullptr; break;
1496     case FXFont::Italic: slt="Italic"; break;
1497     case FXFont::Oblique: slt="Oblique"; break;
1498     default: slt=nullptr; break;
1499     }
1500 
1501   if (wgt && slt && wid)
1502     name+=FXString::value(", %s %s %s, %d",wgt,wid,slt,size);
1503   else if (wgt && slt)
1504     name+=FXString::value(", %s %s, %d",wgt,slt,size);
1505   else if (wgt && wid)
1506     name+=FXString::value(", %s %s, %d",wgt,wid,size);
1507   else if (wid && slt)
1508     name+=FXString::value(", %s %s, %d",wid,slt,size);
1509   else if (slt)
1510     name+=FXString::value(", %s, %d",slt,size);
1511   else if (wgt)
1512     name+=FXString::value(", %s, %d",wgt,size);
1513   else if (wid)
1514     name+=FXString::value(", %s, %d",wid,size);
1515   else
1516     name+=FXString::value(", %d",size);
1517   }
1518 
1519 
1520 
1521 
1522 
onCmdChangeFont(FXObject *,FXSelector,void *)1523 long GMPreferencesDialog::onCmdChangeFont(FXObject*,FXSelector,void*){
1524   GMFontDialog dialog(this,tr("Select Normal Font"));
1525   FXFont * font = FXApp::instance()->getNormalFont();
1526   FXFontDesc fontdescription;
1527   fontdescription =  font->getActualFontDesc();
1528   fxstrlcpy(fontdescription.face,font->getActualName().text(),sizeof(fontdescription.face));
1529   dialog.setFontDesc(fontdescription);
1530   if(dialog.execute(PLACEMENT_SCREEN)){
1531     GMApp::instance()->setFont(dialog.getFontDesc());
1532     updateFonts();
1533     }
1534   return 1;
1535   }
1536 
onUpdFont(FXObject * sender,FXSelector,void *)1537 long GMPreferencesDialog::onUpdFont(FXObject*sender,FXSelector,void*){
1538   FXString fontname;
1539   FXFont * font = FXApp::instance()->getNormalFont();
1540   fancyfontname(font,fontname);
1541   sender->tryHandle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SETSTRINGVALUE),&fontname);
1542   return 1;
1543   }
1544 
onCmdTitleFormat(FXObject * sender,FXSelector,void *)1545 long GMPreferencesDialog::onCmdTitleFormat(FXObject*sender,FXSelector,void*){
1546   sender->handle(this,FXSEL(SEL_COMMAND,ID_GETSTRINGVALUE),&GMPlayerManager::instance()->getPreferences().gui_format_title);
1547   return 1;
1548   }
1549 
onUpdTitleFormat(FXObject * sender,FXSelector sel,void *)1550 long GMPreferencesDialog::onUpdTitleFormat(FXObject*sender,FXSelector sel,void*){
1551   if (GMPlayerManager::instance()->getPreferences().gui_show_playing_titlebar)
1552     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),nullptr);
1553   else
1554     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),nullptr);
1555 
1556   if (FXSELID(sel)==ID_TITLE_FORMAT)
1557     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),&GMPlayerManager::instance()->getPreferences().gui_format_title);
1558 
1559   return 1;
1560   }
1561 
1562 
1563 
1564 
1565 
1566 
1567