1 // PreferencesDialog.cc --- Preferences dialog
2 //
3 // Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Raymond Penners <raymond@dotsphinx.com>
4 // 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
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "preinclude.h"
25
26 #include "nls.h"
27 #include "debug.hh"
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #include <assert.h>
33
34 #include <gtkmm/notebook.h>
35 #include <gtkmm/stock.h>
36 #include <gtkmm/menu.h>
37 #include <gtkmm/combobox.h>
38 #include <gtkmm/cellrenderer.h>
39 #include <gtkmm/scale.h>
40 #include <gtkmm/scrolledwindow.h>
41 #include <gtkmm/filechooserbutton.h>
42
43 #include "StringUtil.hh"
44 #include "Locale.hh"
45
46 #include "GtkUtil.hh"
47 #include "Hig.hh"
48 #include "PreferencesDialog.hh"
49 #include "TimeEntry.hh"
50 #include "TimerBoxPreferencePage.hh"
51 #include "TimerPreferencesPanel.hh"
52 #include "Util.hh"
53 #include "GUI.hh"
54 #include "GUIConfig.hh"
55 #include "DataConnector.hh"
56
57 #include "CoreFactory.hh"
58 #include "CoreConfig.hh"
59 #include "IConfigurator.hh"
60
61 #ifdef HAVE_DISTRIBUTION
62 #include "NetworkPreferencePage.hh"
63 #endif
64
65 #ifndef WR_CHECK_VERSION
66 #define WR_CHECK_VERSION(comp,major,minor,micro) \
67 (comp##_MAJOR_VERSION > (major) || \
68 (comp##_MAJOR_VERSION == (major) && comp##_MINOR_VERSION > (minor)) || \
69 (comp##_MAJOR_VERSION == (major) && comp##_MINOR_VERSION == (minor) && \
70 comp##_MICRO_VERSION >= (micro)))
71 #endif
72
73
74 #define RUNKEY "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
75
76 using namespace std;
77
PreferencesDialog()78 PreferencesDialog::PreferencesDialog()
79 : HigDialog(_("Preferences"), false, false),
80 sound_button(NULL),
81 block_button(NULL),
82 sound_theme_button(NULL),
83 connector(NULL),
84 sound_volume_scale(NULL),
85 sound_play_button(NULL),
86 fsbutton(NULL),
87 filefilter(NULL)
88 #ifdef PLATFORM_OS_WIN32
89 ,
90 sensitivity_adjustment(3, 0, 100),
91 sensitivity_box(NULL)
92 #endif
93 {
94 TRACE_ENTER("PreferencesDialog::PreferencesDialog");
95
96 connector = new DataConnector();
97 inhibit_events = 0;
98
99 // Pages
100 Gtk::Widget *timer_page = Gtk::manage(create_timer_page());
101 Gtk::Notebook *gui_page = Gtk::manage(new Gtk::Notebook());
102
103 #if !defined(PLATFORM_OS_OSX)
104 Gtk::Widget *gui_general_page = Gtk::manage(create_gui_page());
105 gui_page->append_page(*gui_general_page, _("General"));
106 #endif
107
108 #if 1
109 Gtk::Widget *gui_sounds_page = Gtk::manage(create_sounds_page());
110 gui_page->append_page(*gui_sounds_page, _("Sounds"));
111 #endif
112
113 Gtk::Widget *gui_mainwindow_page = Gtk::manage(create_mainwindow_page());
114 gui_page->append_page(*gui_mainwindow_page, _("Status Window"));
115
116 #if !defined(PLATFORM_OS_OSX)
117 Gtk::Widget *gui_applet_page = Gtk::manage(create_applet_page());
118 gui_page->append_page(*gui_applet_page, _("Applet"));
119 #endif
120
121 #ifdef HAVE_DISTRIBUTION
122 Gtk::Widget *network_page = Gtk::manage(create_network_page());
123 #endif
124
125 // Notebook
126 add_page(_("Timers"), "time.png", *timer_page);
127 add_page(_("User interface"), "display.png", *gui_page);
128 #ifdef HAVE_DISTRIBUTION
129 add_page(_("Network"), "network.png", *network_page);
130 #endif
131
132 // Gtk::Widget *plugins_page = Gtk::manage( new PluginsPreferencePage() );
133 // add_page( _("Plugins"), "workrave-icon-huge.png", *plugins_page );
134
135 // Dialog
136 get_vbox()->pack_start(notebook, true, true, 0);
137 add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
138
139 show_all();
140
141 TRACE_EXIT();
142 }
143
144
145 //! Destructor.
~PreferencesDialog()146 PreferencesDialog::~PreferencesDialog()
147 {
148 TRACE_ENTER("PreferencesDialog::~PreferencesDialog");
149
150 #if defined(HAVE_LANGUAGE_SELECTION)
151 const Gtk::TreeModel::iterator& iter = languages_combo.get_active();
152 const Gtk::TreeModel::Row row = *iter;
153 const Glib::ustring code = row[languages_columns.code];
154
155 GUIConfig::set_locale(code);
156 #endif
157
158 ICore *core = CoreFactory::get_core();
159 core->remove_operation_mode_override( "preferences" );
160
161 delete connector;
162 #ifndef HAVE_GTK3
163 delete filefilter;
164 #endif
165 TRACE_EXIT();
166 }
167
168
169
170 Gtk::Widget *
create_gui_page()171 PreferencesDialog::create_gui_page()
172 {
173 // Block types
174 block_button = Gtk::manage(new Gtk::ComboBoxText());
175 #if GTKMM_CHECK_VERSION(2, 24, 0)
176 block_button->append(_("No blocking"));
177 block_button->append(_("Block input"));
178 block_button->append(_("Block input and screen"));
179 #else
180 block_button->append_text(_("No blocking"));
181 block_button->append_text(_("Block input"));
182 block_button->append_text(_("Block input and screen"));
183 #endif
184
185 int block_idx;
186 switch (GUIConfig::get_block_mode())
187 {
188 case GUIConfig::BLOCK_MODE_NONE:
189 block_idx = 0;
190 break;
191 case GUIConfig::BLOCK_MODE_INPUT:
192 block_idx = 1;
193 break;
194 default:
195 block_idx = 2;
196 }
197 block_button->set_active(block_idx);
198 block_button->signal_changed()
199 .connect(sigc::mem_fun(*this, &PreferencesDialog::on_block_changed));
200
201 // Options
202 HigCategoryPanel *panel = Gtk::manage(new HigCategoryPanel(_("Options")));
203
204 panel->add_label(_("Block mode:"), *block_button);
205
206 #if defined(HAVE_LANGUAGE_SELECTION)
207 string current_locale = GUIConfig::get_locale();
208
209 languages_model = Gtk::ListStore::create(languages_columns);
210 languages_combo.set_model(languages_model);
211
212 std::vector<std::string> all_linguas;
213 StringUtil::split(string(ALL_LINGUAS), ' ', all_linguas);
214 all_linguas.push_back("en");
215
216 Locale::LanguageMap languages_current_locale;
217 Locale::LanguageMap languages_native_locale;
218
219 Locale::get_all_languages_in_current_locale(languages_current_locale);
220 Locale::get_all_languages_in_native_locale(languages_native_locale);
221
222 Gtk::TreeModel::iterator iter = languages_model->append();
223 Gtk::TreeModel::Row row = *iter;
224 row[languages_columns.current] = _("System default");
225 row[languages_columns.native] = "";
226 row[languages_columns.code] = "";
227 row[languages_columns.enabled] = true;
228
229 Gtk::TreeModel::iterator selected = iter;
230
231 for (vector<std::string>::iterator i = all_linguas.begin(); i != all_linguas.end(); i++)
232 {
233 string code = *i;
234
235 iter = languages_model->append();
236 row = *iter;
237 row[languages_columns.code] = code;
238 row[languages_columns.enabled] = true;
239
240 if (current_locale == code)
241 {
242 selected = iter;
243 }
244
245 string txt = languages_current_locale[code].language_name;
246 if( txt.empty() )
247 {
248 txt = "Unrecognized language: (" + code + ")";
249 }
250 else if (languages_current_locale[code].country_name != "")
251 {
252 txt += " (" + languages_current_locale[code].country_name + ")";
253 }
254 row[languages_columns.current] = txt;
255
256 if (languages_current_locale[code].language_name !=
257 languages_native_locale[code].language_name)
258 {
259 txt = languages_native_locale[code].language_name;
260 if (languages_native_locale[code].country_name != "")
261 {
262 txt += " (" + languages_native_locale[code].country_name + ")";
263 }
264
265 Glib::RefPtr<Pango::Layout> pl = create_pango_layout(txt);
266 if (pl->get_unknown_glyphs_count() > 0)
267 {
268 txt = _("(font not available)");
269 row[languages_columns.enabled] = false;
270 }
271
272 row[languages_columns.native] = txt;
273 }
274 }
275
276 languages_model->set_sort_column(languages_columns.current, Gtk::SORT_ASCENDING);
277 languages_model->set_sort_func (languages_columns.current,
278 sigc::mem_fun(*this,
279 &PreferencesDialog::on_cell_data_compare));
280
281 languages_combo.pack_start(current_cellrenderer, true);
282 languages_combo.pack_start(native_cellrenderer, false);
283
284 languages_combo.set_cell_data_func(native_cellrenderer,
285 sigc::mem_fun(*this,
286 &PreferencesDialog::on_native_cell_data));
287 languages_combo.set_cell_data_func(current_cellrenderer,
288 sigc::mem_fun(*this,
289 &PreferencesDialog::on_current_cell_data));
290
291 languages_combo.set_active(selected);
292
293 panel->add_label(_("Language:"), languages_combo);
294 #endif
295
296 bool show_autostart = false;
297
298 #if defined(PLATFORM_OS_WIN32)
299 show_autostart = true;
300 #elif defined(PLATFORM_OS_UNIX)
301 const char *desktop = g_getenv("XDG_CURRENT_DESKTOP");
302 show_autostart = (g_strcmp0(desktop, "Unity") == 0);
303 #endif
304
305 if (show_autostart)
306 {
307 Gtk::Label *autostart_lab = Gtk::manage(GtkUtil::create_label(_("Start Workrave on logon"), false));
308 autostart_cb = Gtk::manage(new Gtk::CheckButton());
309 autostart_cb->add(*autostart_lab);
310 autostart_cb->signal_toggled().connect(sigc::mem_fun(*this, &PreferencesDialog::on_autostart_toggled));
311 panel->add_widget(*autostart_cb);
312
313 connector->connect(GUIConfig::CFG_KEY_AUTOSTART, dc::wrap(autostart_cb));
314
315 #if defined(PLATFORM_OS_WIN32)
316 char value[MAX_PATH];
317 bool rc = Util::registry_get_value(RUNKEY, "Workrave", value);
318 autostart_cb->set_active(rc);
319 #endif
320 }
321
322 Gtk::Label *trayicon_lab = Gtk::manage(GtkUtil::create_label(_("Show system tray icon"), false));
323 trayicon_cb = Gtk::manage(new Gtk::CheckButton());
324 trayicon_cb->add(*trayicon_lab);
325 connector->connect(GUIConfig::CFG_KEY_TRAYICON_ENABLED, dc::wrap(trayicon_cb));
326
327 panel->add_widget(*trayicon_cb, false, false);
328
329 panel->set_border_width(12);
330 return panel;
331 }
332
333
334 Gtk::Widget *
create_sounds_page()335 PreferencesDialog::create_sounds_page()
336 {
337 Gtk::VBox *panel = Gtk::manage(new Gtk::VBox(false, 6));
338
339 // Options
340 HigCategoryPanel *hig = Gtk::manage(new HigCategoryPanel(_("Sound Options")));
341 panel->pack_start(*hig, false, false, 0);
342
343 // Sound types
344 sound_button = Gtk::manage(new Gtk::ComboBoxText());
345 #if GTKMM_CHECK_VERSION(2, 24, 0)
346 sound_button->append(_("No sounds"));
347 sound_button->append(_("Play sounds using sound card"));
348 sound_button->append(_("Play sounds using built-in speaker"));
349 #else
350 sound_button->append_text(_("No sounds"));
351 sound_button->append_text(_("Play sounds using sound card"));
352 sound_button->append_text(_("Play sounds using built-in speaker"));
353 #endif
354 int idx;
355 if (! SoundPlayer::is_enabled())
356 idx = 0;
357 else
358 {
359 if (SoundPlayer::DEVICE_SPEAKER == SoundPlayer::get_device())
360 idx = 2;
361 else
362 idx = 1;
363 }
364 sound_button->set_active(idx);
365 sound_button->signal_changed().connect(sigc::mem_fun(*this, &PreferencesDialog::on_sound_changed));
366
367 IGUI *gui = GUI::get_instance();
368 SoundPlayer *snd = gui->get_sound_player();
369
370 if (snd->capability(SOUND_CAP_VOLUME))
371 {
372 // Volume
373 sound_volume_scale = Gtk::manage(new Gtk:: HScale(0.0, 100.0, 0.0));
374 sound_volume_scale->set_increments(1.0, 5.0);
375 connector->connect(SoundPlayer::CFG_KEY_SOUND_VOLUME, dc::wrap(sound_volume_scale->get_adjustment()));
376
377 hig->add_label(_("Volume:"), *sound_volume_scale, true, true);
378 }
379
380 hig->add_label(_("Sound:"), *sound_button);
381
382 if (snd->capability(SOUND_CAP_MUTE))
383 {
384 // Volume
385 mute_cb = Gtk::manage(new Gtk::CheckButton
386 (_("Mute sounds during rest break and daily limit")));
387
388 connector->connect(SoundPlayer::CFG_KEY_SOUND_MUTE, dc::wrap(mute_cb));
389
390 hig->add_widget(*mute_cb, true, true);
391 }
392
393 if (snd->capability(SOUND_CAP_EDIT))
394 {
395 // Sound themes
396 hig = Gtk::manage(new HigCategoryPanel(_("Sound Events"), true));
397 panel->pack_start(*hig, true, true, 0);
398
399 sound_theme_button = Gtk::manage(new Gtk::ComboBoxText());
400
401 update_theme_selection();
402
403 sound_theme_button->signal_changed().connect(sigc::mem_fun(*this, &PreferencesDialog::on_sound_theme_changed));
404 hig->add_label(_("Sound Theme:"), *sound_theme_button);
405
406 sound_store = Gtk::ListStore::create(sound_model);
407 sound_treeview.set_model(sound_store);
408
409 for (unsigned int i = 0; i < SOUND_MAX; i++)
410 {
411 Gtk::TreeModel::iterator iter = sound_store->append();
412 Gtk::TreeModel::Row row = *iter;
413
414 bool sound_enabled = false;
415 snd->get_sound_enabled((SoundEvent)i, sound_enabled);
416
417 row[sound_model.enabled] = sound_enabled;
418 row[sound_model.selectable] = true;
419 row[sound_model.description] = _(SoundPlayer::sound_registry[i].friendly_name);
420 row[sound_model.label] = SoundPlayer::sound_registry[i].id;
421 row[sound_model.event] = i;
422 }
423
424 sound_treeview.set_rules_hint();
425 sound_treeview.set_search_column(sound_model.description.index());
426
427 int cols_count = sound_treeview.append_column_editable(_("Play"), sound_model.enabled);
428 Gtk::TreeViewColumn *column = sound_treeview.get_column(cols_count - 1);
429
430 Gtk::CellRendererToggle *cell = dynamic_cast<Gtk::CellRendererToggle*>(sound_treeview.get_column_cell_renderer(cols_count - 1));
431
432 cols_count = sound_treeview.append_column(_("Event"), sound_model.description);
433 column = sound_treeview.get_column(cols_count - 1);
434 column->set_fixed_width(40);
435
436 Gtk::ScrolledWindow *sound_scroll = Gtk::manage(new Gtk::ScrolledWindow());
437 sound_scroll->add(sound_treeview);
438 sound_scroll->set_size_request(-1, 200);
439 sound_treeview.set_size_request(-1, 200);
440
441 hig->add_widget(*sound_scroll, true, true);
442
443 Gtk::HBox *hbox = Gtk::manage(new Gtk::HBox(false, 6));
444
445 sound_play_button = Gtk::manage(new Gtk::Button(_("Play")));
446 hbox->pack_start(*sound_play_button, false, false, 0);
447
448 fsbutton = Gtk::manage(new Gtk::FileChooserButton(_("Choose a sound"),
449 Gtk::FILE_CHOOSER_ACTION_OPEN
450 ));
451
452 hbox->pack_start(*fsbutton, true, true, 0);
453
454 #ifdef HAVE_GTK3
455 filefilter = Gtk::FileFilter::create();
456 #else
457 filefilter = new Gtk::FileFilter();
458 #endif
459
460 filefilter->set_name(_("Wavefiles"));
461 #ifdef PLATFORM_OS_WIN32
462 filefilter->add_pattern("*.wav");
463 #else
464 filefilter->add_mime_type("audio/x-wav");
465 #endif
466 #ifdef HAVE_GTK3
467 fsbutton->add_filter(filefilter);
468 #else
469 fsbutton->add_filter(*filefilter);
470 #endif
471
472 hig->add_widget(*hbox);
473
474 Gtk::HBox *selector_hbox = Gtk::manage(new Gtk::HBox(false, 0));
475 Gtk::Button *selector_playbutton = Gtk::manage(new Gtk::Button(_("Play")));
476
477 selector_hbox->pack_end(*selector_playbutton, false, false, 0);
478 selector_playbutton->show();
479 fsbutton->set_extra_widget(*selector_hbox);
480
481 cell->signal_toggled().connect(sigc::mem_fun(*this,
482 &PreferencesDialog::on_sound_enabled));
483
484 sound_play_button->signal_clicked().connect(sigc::mem_fun(*this,
485 &PreferencesDialog::on_sound_play));
486
487 selector_playbutton->signal_clicked().connect(sigc::mem_fun(*this,
488 &PreferencesDialog::on_sound_filechooser_play));
489
490 #if WR_CHECK_VERSION(GTKMM,2,22,0)
491 fsbutton->signal_file_set().connect(sigc::mem_fun(*this,
492 &PreferencesDialog::on_sound_filechooser_select));
493 #else
494 fsbutton->signal_selection_changed().connect(sigc::mem_fun(*this,
495 &PreferencesDialog::on_sound_filechooser_select));
496 #endif
497
498 Glib::RefPtr<Gtk::TreeSelection> selection = sound_treeview.get_selection();
499 selection->signal_changed().connect(sigc::mem_fun(*this,
500 &PreferencesDialog::on_sound_events_changed));
501
502 Gtk::TreeModel::iterator iter = sound_store->children().begin();
503 if (iter)
504 {
505 selection->select(iter);
506 }
507
508 update_senstives();
509 }
510
511 panel->set_border_width(12);
512 return panel;
513 }
514
515
516 Gtk::Widget *
create_timer_page()517 PreferencesDialog::create_timer_page()
518 {
519 // Timers page
520 Gtk::Notebook *tnotebook = Gtk::manage(new Gtk::Notebook());
521 tnotebook->set_tab_pos (Gtk::POS_TOP);
522 Glib::RefPtr<Gtk::SizeGroup> hsize_group
523 = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
524 Glib::RefPtr<Gtk::SizeGroup> vsize_group
525 = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_VERTICAL);
526 for (int i = 0; i < BREAK_ID_SIZEOF; i++)
527 {
528 // Label
529 Gtk::Widget *box = Gtk::manage(GtkUtil::create_label_for_break
530 ((BreakId) i));
531 TimerPreferencesPanel *tp = Gtk::manage(new TimerPreferencesPanel(BreakId(i), hsize_group, vsize_group));
532 box->show_all();
533 #ifdef HAVE_GTK3
534 tnotebook->append_page(*tp, *box);
535 #else
536 tnotebook->pages().push_back(Gtk::Notebook_Helpers::TabElem(*tp, *box));
537 #endif
538 }
539
540 #if defined(PLATFORM_OS_WIN32)
541 Gtk::Widget *box = Gtk::manage(GtkUtil::create_label("Monitoring", false));
542 Gtk::Widget *monitoring_page = create_monitoring_page();
543
544 #ifdef HAVE_GTK3
545 tnotebook->append_page(*monitoring_page , *box);
546 #else
547 tnotebook->pages().push_back(Gtk::Notebook_Helpers::TabElem(*monitoring_page, *box));
548 #endif
549 #endif
550
551 return tnotebook;
552 }
553
554 #if defined(PLATFORM_OS_WIN32)
555 Gtk::Widget *
create_monitoring_page()556 PreferencesDialog::create_monitoring_page()
557 {
558 Gtk::VBox *panel = Gtk::manage(new Gtk::VBox(false, 6));
559 panel->set_border_width(12);
560
561 Gtk::Label *monitor_type_lab = Gtk::manage(GtkUtil::create_label(_("Use alternate monitor"), false));
562 monitor_type_cb = Gtk::manage(new Gtk::CheckButton());
563 monitor_type_cb->add(*monitor_type_lab);
564 monitor_type_cb->signal_toggled().connect(sigc::mem_fun(*this, &PreferencesDialog::on_monitor_type_toggled));
565 panel->pack_start(*monitor_type_cb, false, false, 0);
566
567 Gtk::Label *monitor_type_help = Gtk::manage(GtkUtil::create_label(_("Enable this option if Workrave fails to detect when you are using your computer"), false));
568 panel->pack_start(*monitor_type_help, false, false, 0);
569
570 sensitivity_box = Gtk::manage(new Gtk::HBox());
571 Gtk::Widget *sensitivity_lab = Gtk::manage(GtkUtil::create_label_with_tooltip(_("Mouse sensitivity:"), _("Number of pixels the mouse should move before it is considered activity.")));
572 Gtk::SpinButton *sensitivity_spin = Gtk::manage(new Gtk::SpinButton(sensitivity_adjustment));
573 sensitivity_box->pack_start(*sensitivity_lab, false, false, 0);
574 sensitivity_box->pack_start(*sensitivity_spin, false, false, 0);
575 panel->pack_start(*sensitivity_box, false, false, 0);
576
577 connector->connect(CoreConfig::CFG_KEY_MONITOR_SENSITIVITY, dc::wrap(&sensitivity_adjustment));
578
579 string monitor_type;
580 CoreFactory::get_configurator()->get_value_with_default("advanced/monitor",
581 monitor_type,
582 "default");
583
584 monitor_type_cb->set_active(monitor_type != "default");
585
586 sensitivity_box->set_sensitive(monitor_type != "default");
587
588 return panel;
589 }
590
591 #endif
592
593 Gtk::Widget *
create_mainwindow_page()594 PreferencesDialog::create_mainwindow_page()
595 {
596 // Timers page
597 return new TimerBoxPreferencePage("main_window");
598 }
599
600
601 Gtk::Widget *
create_applet_page()602 PreferencesDialog::create_applet_page()
603 {
604 // Timers page
605 return new TimerBoxPreferencePage("applet");
606 }
607
608
609 #ifdef HAVE_DISTRIBUTION
610 Gtk::Widget *
create_network_page()611 PreferencesDialog::create_network_page()
612 {
613 return new NetworkPreferencePage();
614 }
615 #endif
616
617 void
add_page(const char * label,const char * image,Gtk::Widget & widget)618 PreferencesDialog::add_page(const char *label, const char *image,
619 Gtk::Widget &widget)
620 {
621 string icon = Util::complete_directory(image, Util::SEARCH_PATH_IMAGES);
622 Glib::RefPtr<Gdk::Pixbuf> pixbuf = Gdk::Pixbuf::create_from_file(icon);
623 notebook.add_page(label, pixbuf, widget);
624 }
625
626 void
on_sound_changed()627 PreferencesDialog::on_sound_changed()
628 {
629 int idx = sound_button->get_active_row_number();
630 SoundPlayer::set_enabled(idx > 0);
631 if (idx > 0)
632 {
633 SoundPlayer::Device dev = idx == 1
634 ? SoundPlayer::DEVICE_SOUNDCARD
635 : SoundPlayer::DEVICE_SPEAKER;
636 SoundPlayer::set_device(dev);
637 }
638
639 update_senstives();
640 }
641
642 void
update_senstives()643 PreferencesDialog::update_senstives()
644 {
645 int idx = sound_button->get_active_row_number();
646 if (idx > 0)
647 {
648 SoundPlayer::Device dev = idx == 1
649 ? SoundPlayer::DEVICE_SOUNDCARD
650 : SoundPlayer::DEVICE_SPEAKER;
651
652 sound_treeview.set_sensitive(dev == SoundPlayer::DEVICE_SOUNDCARD);
653 if (sound_theme_button != NULL)
654 {
655 sound_theme_button->set_sensitive(dev == SoundPlayer::DEVICE_SOUNDCARD);
656 }
657 if (sound_volume_scale != NULL)
658 {
659 sound_volume_scale->set_sensitive(dev == SoundPlayer::DEVICE_SOUNDCARD);
660 }
661 if (sound_play_button != NULL)
662 {
663 sound_play_button->set_sensitive(dev == SoundPlayer::DEVICE_SOUNDCARD);
664 }
665 if (fsbutton != NULL)
666 {
667 fsbutton->set_sensitive(dev == SoundPlayer::DEVICE_SOUNDCARD);
668 }
669 }
670 }
671
672 void
on_block_changed()673 PreferencesDialog::on_block_changed()
674 {
675 int idx = block_button->get_active_row_number();
676 GUIConfig::BlockMode m;
677 switch (idx)
678 {
679 case 0:
680 m = GUIConfig::BLOCK_MODE_NONE;
681 break;
682 case 1:
683 m = GUIConfig::BLOCK_MODE_INPUT;
684 break;
685 default:
686 m = GUIConfig::BLOCK_MODE_ALL;
687 }
688 GUIConfig::set_block_mode(m);
689 }
690
691
692 int
run()693 PreferencesDialog::run()
694 {
695 show_all();
696 return 0;
697 }
698
699
700 bool
on_focus_in_event(GdkEventFocus * event)701 PreferencesDialog::on_focus_in_event(GdkEventFocus *event)
702 {
703 TRACE_ENTER("PreferencesDialog::focus_in");
704
705 GUIConfig::BlockMode block_mode = GUIConfig::get_block_mode();
706 if (block_mode != GUIConfig::BLOCK_MODE_NONE)
707 {
708 ICore *core = CoreFactory::get_core();
709
710 OperationMode mode = core->get_operation_mode();
711 if (mode == OPERATION_MODE_NORMAL)
712 {
713 core->set_operation_mode_override( OPERATION_MODE_QUIET, "preferences" );
714 }
715 }
716 TRACE_EXIT();
717 return HigDialog::on_focus_in_event(event);
718 }
719
720
721 bool
on_focus_out_event(GdkEventFocus * event)722 PreferencesDialog::on_focus_out_event(GdkEventFocus *event)
723 {
724 TRACE_ENTER("PreferencesDialog::focus_out");
725 ICore *core = CoreFactory::get_core();
726
727 core->remove_operation_mode_override( "preferences" );
728 TRACE_EXIT();
729 return HigDialog::on_focus_out_event(event);
730 }
731
732
733 #if defined(HAVE_LANGUAGE_SELECTION)
734 void
on_current_cell_data(const Gtk::TreeModel::const_iterator & iter)735 PreferencesDialog::on_current_cell_data(const Gtk::TreeModel::const_iterator& iter)
736 {
737 if (iter)
738 {
739 Gtk::TreeModel::Row row = *iter;
740 Glib::ustring name = row[languages_columns.current];
741 bool enabled = row[languages_columns.enabled];
742
743 current_cellrenderer.set_property("text", name);
744 current_cellrenderer.set_property("sensitive", enabled);
745 }
746 }
747
748 void
on_native_cell_data(const Gtk::TreeModel::const_iterator & iter)749 PreferencesDialog::on_native_cell_data(const Gtk::TreeModel::const_iterator& iter)
750 {
751 if (iter)
752 {
753 Gtk::TreeModel::Row row = *iter;
754 Glib::ustring name = row[languages_columns.native];
755 bool enabled = row[languages_columns.enabled];
756
757 native_cellrenderer.set_property("text", name);
758 native_cellrenderer.set_property("sensitive", enabled);
759 }
760 }
761
762 int
on_cell_data_compare(const Gtk::TreeModel::iterator & iter1,const Gtk::TreeModel::iterator & iter2)763 PreferencesDialog::on_cell_data_compare(const Gtk::TreeModel::iterator& iter1,
764 const Gtk::TreeModel::iterator& iter2)
765 {
766 Gtk::TreeModel::Row row1 = *iter1;
767 Gtk::TreeModel::Row row2 = *iter2;
768 Glib::ustring name1 = row1[languages_columns.current];
769 Glib::ustring name2 = row2[languages_columns.current];
770 Glib::ustring code1 = row1[languages_columns.code];
771 Glib::ustring code2 = row2[languages_columns.code];
772
773 if (code1 == "")
774 {
775 return -1;
776 }
777 else if (code2 == "")
778 {
779 return 1;
780 }
781 else
782 {
783 return g_utf8_collate(name1.c_str(), name2.c_str());
784 }
785 }
786 #endif
787
788 void
on_autostart_toggled()789 PreferencesDialog::on_autostart_toggled()
790 {
791 #if defined(PLATFORM_OS_WIN32)
792 bool on = autostart_cb->get_active();
793
794 gchar *value = NULL;
795
796 if (on)
797 {
798 string appdir = Util::get_application_directory();
799 value = g_strdup_printf("%s" G_DIR_SEPARATOR_S "lib" G_DIR_SEPARATOR_S "workrave.exe", appdir.c_str());
800 }
801
802 Util::registry_set_value(RUNKEY, "Workrave", value);
803 #endif
804 }
805
806 #if defined(PLATFORM_OS_WIN32)
807 void
on_monitor_type_toggled()808 PreferencesDialog::on_monitor_type_toggled()
809 {
810 bool on = monitor_type_cb->get_active();
811 CoreFactory::get_configurator()->set_value("advanced/monitor", on ? "lowlevel" : "default");
812 sensitivity_box->set_sensitive(on);
813 }
814 #endif
815
816 void
on_sound_enabled(const Glib::ustring & path_string)817 PreferencesDialog::on_sound_enabled(const Glib::ustring &path_string)
818 {
819 Gtk::TreePath path(path_string);
820 const Gtk::TreeModel::iterator iter = sound_store->get_iter(path);
821
822 if (iter)
823 {
824 Gtk::TreeRow row = *iter;
825
826 IGUI *gui = GUI::get_instance();
827 SoundPlayer *snd = gui->get_sound_player();
828
829 snd->set_sound_enabled((SoundEvent)(int)row[sound_model.event],
830 row[sound_model.enabled]);
831 }
832 }
833
834
835 void
on_sound_play()836 PreferencesDialog::on_sound_play()
837 {
838 Glib::RefPtr<Gtk::TreeSelection> selection = sound_treeview.get_selection();
839 Gtk::TreeModel::iterator iter = selection->get_selected();
840
841 if (iter)
842 {
843 Gtk::TreeModel::Row row = *iter;
844
845 string filename;
846 bool valid = CoreFactory::get_configurator()->get_value(string(SoundPlayer::CFG_KEY_SOUND_EVENTS) +
847 row[sound_model.label],
848 filename);
849
850 if (valid && filename != "")
851 {
852 IGUI *gui = GUI::get_instance();
853 SoundPlayer *snd = gui->get_sound_player();
854 snd->play_sound(filename);
855 }
856 }
857 }
858
859 void
on_sound_filechooser_play()860 PreferencesDialog::on_sound_filechooser_play()
861 {
862 string filename = fsbutton->get_filename();
863
864 IGUI *gui = GUI::get_instance();
865 SoundPlayer *snd = gui->get_sound_player();
866 snd->play_sound(filename);
867 }
868
869
870 void
on_sound_filechooser_select()871 PreferencesDialog::on_sound_filechooser_select()
872 {
873 TRACE_ENTER("PreferencesDialog::on_sound_filechooser_select");
874 string filename = fsbutton->get_filename();
875
876 TRACE_MSG(filename << " " << fsbutton_filename << " " << inhibit_events);
877
878 if (inhibit_events == 0 && filename != "" && fsbutton_filename != filename)
879 {
880 TRACE_MSG("ok");
881
882 Glib::RefPtr<Gtk::TreeSelection> selection = sound_treeview.get_selection();
883 Gtk::TreeModel::iterator iter = selection->get_selected();
884
885 if (iter) {
886 Gtk::TreeModel::Row row = *iter;
887
888 TRACE_MSG(row[sound_model.label]);
889
890 IGUI *gui = GUI::get_instance();
891 SoundPlayer *snd = gui->get_sound_player();
892 snd->set_sound_wav_file( (SoundEvent)(int)row[sound_model.event], filename);
893 TRACE_MSG(filename);
894 update_theme_selection();
895 }
896
897 fsbutton_filename = filename;
898 TRACE_EXIT();
899 }
900 }
901
902
903 void
on_sound_events_changed()904 PreferencesDialog::on_sound_events_changed()
905 {
906 TRACE_ENTER("PreferencesDialog::on_sound_events_changed");
907 Glib::RefPtr<Gtk::TreeSelection> selection = sound_treeview.get_selection();
908 Gtk::TreeModel::iterator iter = selection->get_selected();
909
910 if (iter)
911 {
912 Gtk::TreeModel::Row row = *iter;
913
914 string event = (Glib::ustring) row[sound_model.label];
915 string filename;
916 bool valid = CoreFactory::get_configurator()->get_value(string(SoundPlayer::CFG_KEY_SOUND_EVENTS) +
917 row[sound_model.label],
918 filename);
919
920 TRACE_MSG(filename);
921
922 if (valid && filename != "")
923 {
924 inhibit_events++;
925 fsbutton_filename = filename;
926 fsbutton->set_filename(filename);
927 inhibit_events--;
928 }
929 }
930 TRACE_EXIT();
931 }
932
933
934 void
on_sound_theme_changed()935 PreferencesDialog::on_sound_theme_changed()
936 {
937 TRACE_ENTER("PreferencesDialog::on_sound_theme_changed");
938 int idx = sound_theme_button->get_active_row_number();
939
940 if (idx >= 0 && idx < (int)sound_themes.size())
941 {
942 SoundPlayer::Theme &theme = sound_themes[idx];
943
944 IGUI *gui = GUI::get_instance();
945 SoundPlayer *snd = gui->get_sound_player();
946 snd->activate_theme(theme);
947
948 Glib::RefPtr<Gtk::TreeSelection> selection = sound_treeview.get_selection();
949 Gtk::TreeModel::iterator iter = selection->get_selected();
950
951 if (iter)
952 {
953 Gtk::TreeModel::Row row = *iter;
954 string event = (Glib::ustring) row[sound_model.label];
955 string filename;
956
957 bool valid = CoreFactory::get_configurator()->get_value(string(SoundPlayer::CFG_KEY_SOUND_EVENTS) +
958 row[sound_model.label],
959 filename);
960
961 if (valid && filename != "")
962 {
963 TRACE_MSG(filename << " " <<row[sound_model.label]);
964 inhibit_events++;
965 fsbutton_filename = filename;
966 fsbutton->set_filename(filename);
967 inhibit_events--;
968 }
969 }
970 }
971 TRACE_EXIT();
972 }
973
974
975 void
update_theme_selection()976 PreferencesDialog::update_theme_selection()
977 {
978 TRACE_ENTER("PreferencesDialog::update_theme_selection");
979 sound_themes.erase(sound_themes.begin(), sound_themes.end());
980
981 IGUI *gui = GUI::get_instance();
982 SoundPlayer *snd = gui->get_sound_player();
983 snd->get_sound_themes(sound_themes);
984
985 #if GTKMM_CHECK_VERSION(2, 24, 0)
986 sound_theme_button->remove_all();
987 #else
988 sound_theme_button->clear_items();
989 #endif
990
991 int idx = 0;
992 for (vector<SoundPlayer::Theme>::iterator it = sound_themes.begin(); it != sound_themes.end(); it++)
993 {
994 #if GTKMM_CHECK_VERSION(2, 24, 0)
995 sound_theme_button->append(it->description);
996 #else
997 sound_theme_button->append_text(it->description);
998 #endif
999
1000 if (it->active)
1001 {
1002 sound_theme_button->set_active(idx);
1003 }
1004 idx++;
1005 }
1006 TRACE_EXIT();
1007 }
1008