1 /*
2 * KCemu -- The emulator for the KC85 homecomputer series and much more.
3 * Copyright (C) 1997-2010 Torsten Paul
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 /*
21 * Enable Sound
22 * Joystick Device
23 * Enable V24-Module
24 * Custom ROM Module
25 * Custom ROM Module (Name)
26 * Custom ROM Module (Id)
27 * Custom ROM Module (File)
28 * Custom ROM Module (Size)
29 * V24-Baudrate
30 * V24-Device
31 * Flash Offset
32 * Foreground Saturation
33 * Foreground Brightness
34 * Background Saturation
35 * Background Brightness
36 * Black Value
37 * White Value
38 * Max Auto Skip
39 * DEBUG UI_Gtk Color Add
40 * DEBUG UI_Gtk Frame Delay
41 */
42
43 #include <stdlib.h>
44
45 #include <list>
46 #include <string>
47
48 #include "kc/system.h"
49 #include "kc/prefs/types.h"
50 #include "kc/prefs/prefs.h"
51 #include "kc/prefs/strlist.h"
52
53 #include "kc/kc.h"
54
55 #include "kc/mod_list.h"
56
57 #include "sys/sysdep.h"
58
59 #include "ui/gtk/cmd.h"
60 #include "ui/gtk/dialog.h"
61 #include "ui/gtk/options.h"
62
63 class CMD_options_window_toggle : public CMD {
64 private:
65 OptionsWindow *_w;
66
67 public:
CMD_options_window_toggle(OptionsWindow * w)68 CMD_options_window_toggle(OptionsWindow *w) : CMD("ui-options-window-toggle") {
69 _w = w;
70 register_cmd("ui-options-window-toggle");
71 }
72
execute(CMD_Args * args,CMD_Context context)73 void execute(CMD_Args *args, CMD_Context context) {
74 _w->toggle();
75 }
76 };
77
78 class CMD_options_window_dialog : public CMD {
79 private:
80 OptionsWindow *_w;
81
82 public:
CMD_options_window_dialog(OptionsWindow * w)83 CMD_options_window_dialog(OptionsWindow *w) : CMD("ui-options-window-dialog") {
84 _w = w;
85 register_cmd("ui-options-window-dialog");
86 }
87
execute(CMD_Args * args,CMD_Context context)88 void execute(CMD_Args *args, CMD_Context context) {
89 if (args == NULL)
90 args = new CMD_Args();
91
92 switch (context) {
93 case 0:
94 args->set_string_arg("ui-dialog-title", _("Save profiles?"));
95 args->set_string_arg("ui-dialog-text",
96 _("Some profiles were changed!\n\n"
97 "'Yes' will save changes to disk, 'No' will reject all changes.\n"
98 "'Cancel': will allow to continue editing."));
99 args->set_string_arg("ui-dialog-text-arg", "filename");
100 args->add_callback("ui-dialog-cancel-CB", this, 1);
101 args->add_callback("ui-dialog-yes-no-CB-no", this, 2);
102 args->add_callback("ui-dialog-yes-no-CB-yes", this, 3);
103 CMD_EXEC_ARGS("ui-dialog-yes-no-cancel", args);
104 break;
105 case 1: // cancel
106 break;
107 case 2: // no
108 _w->reject();
109 break;
110 case 3: // yes
111 _w->save();
112 break;
113 }
114 }
115 };
116
117 const char * OptionsWindow::FILE_CHOOSER_BUTTON_KEY = "filechooser_button";
118 const char * OptionsWindow::FILE_CHOOSER_CLEAR_BUTTON_KEY = "filechooser_clear_button";
119 const char * OptionsWindow::DATA_KEY_CHECK_BUTTON = "key_check_button";
120 const char * OptionsWindow::PREFERENCES_KEY = "preferences_key";
121 const char * OptionsWindow::DEFAULT_DIR_KEY = "default_dir_key";
122 const char * OptionsWindow::TARGET_WIDGET1_KEY = "target_widget1_key";
123 const char * OptionsWindow::TARGET_WIDGET2_KEY = "target_widget2_key";
124 const char * OptionsWindow::TARGET_WIDGET3_KEY = "target_widget3_key";
125
OptionsWindow(const char * ui_xml_file)126 OptionsWindow::OptionsWindow(const char *ui_xml_file) : UI_Gtk_Window(ui_xml_file) {
127 _current_profile = NULL;
128 _current_kc_type = KC_TYPE_NONE;
129 _open_rom_last_path = NULL;
130 _w.liststore_modules = NULL;
131
132 _cmd = new CMD_options_window_toggle(this);
133 _cmd_dialog = new CMD_options_window_dialog(this);
134 }
135
~OptionsWindow(void)136 OptionsWindow::~OptionsWindow(void) {
137 delete _cmd;
138 delete _cmd_dialog;
139 }
140
141 void
on_button_up_clicked(GtkButton * button,gpointer user_data)142 OptionsWindow::on_button_up_clicked(GtkButton *button, gpointer user_data) {
143 OptionsWindow *self = (OptionsWindow *)user_data;
144 self->move_row((GtkPathMoveFunc)gtk_tree_path_prev, gtk_tree_store_move_before);
145 }
146
147 void
on_button_down_clicked(GtkButton * button,gpointer user_data)148 OptionsWindow::on_button_down_clicked(GtkButton *button, gpointer user_data) {
149 OptionsWindow *self = (OptionsWindow *)user_data;
150 self->move_row(gtk_tree_path_next, gtk_tree_store_move_after);
151 }
152
153 void
on_button_expand_clicked(GtkButton * button,gpointer user_data)154 OptionsWindow::on_button_expand_clicked(GtkButton *button, gpointer user_data) {
155 OptionsWindow *self = (OptionsWindow *)user_data;
156 self->expand_tree();
157 }
158
159 void
on_button_collapse_clicked(GtkButton * button,gpointer user_data)160 OptionsWindow::on_button_collapse_clicked(GtkButton *button, gpointer user_data) {
161 OptionsWindow *self = (OptionsWindow *)user_data;
162 self->collapse_tree();
163 }
164
165
166 void
expand_tree(void)167 OptionsWindow::expand_tree(void) {
168 gtk_tree_view_expand_all(GTK_TREE_VIEW(_w.treeview));
169 }
170
171 void
collapse_tree(void)172 OptionsWindow::collapse_tree(void) {
173 gtk_tree_view_collapse_all(GTK_TREE_VIEW(_w.treeview));
174
175 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(_w.treeview));
176 GtkTreePath *path = gtk_tree_path_new_first();
177 gtk_tree_view_expand_to_path(GTK_TREE_VIEW(_w.treeview), path);
178 gtk_tree_selection_select_path(select, path);
179 gtk_tree_path_free(path);
180 }
181
182 void
on_button_new_clicked(GtkButton * button,gpointer user_data)183 OptionsWindow::on_button_new_clicked(GtkButton *button, gpointer user_data) {
184 OptionsWindow *self = (OptionsWindow *)user_data;
185 Profile *profile = Preferences::instance()->create_user_profile(self->_current_profile);
186 if (profile == NULL)
187 return;
188
189 GtkTreeIter iter;
190 GtkTreeModel *model = self->get_selected_tree_iter(&iter);
191 if (model == NULL)
192 return;
193
194 GtkTreeIter iter_child;
195 gtk_tree_store_append(GTK_TREE_STORE(model), &iter_child, &iter);
196 gtk_tree_store_set(GTK_TREE_STORE(model), &iter_child,
197 TREE_INT_COLUMN, 2,
198 TREE_TEXT_COLUMN, profile->get_name(),
199 TREE_CONFIG_NAME_COLUMN, profile->get_config_name(),
200 TREE_ICON_COLUMN, self->_w.pixbuf_default,
201 -1);
202
203 self->expand_and_select(GTK_TREE_VIEW(self->_w.treeview), model, &iter_child);
204 gtk_notebook_set_current_page(self->_w.notebook, 0);
205 }
206
207 void
expand_and_select(GtkTreeView * treeview,GtkTreeModel * model,GtkTreeIter * iter)208 OptionsWindow::expand_and_select(GtkTreeView *treeview, GtkTreeModel *model, GtkTreeIter *iter)
209 {
210 GtkTreePath *path = gtk_tree_model_get_path(model, iter);
211 gtk_tree_view_expand_to_path(treeview, path);
212 gtk_tree_path_free(path);
213 gtk_tree_selection_select_iter(gtk_tree_view_get_selection(treeview), iter);
214 }
215
216 void
on_button_copy_clicked(GtkButton * button,gpointer user_data)217 OptionsWindow::on_button_copy_clicked(GtkButton *button, gpointer user_data) {
218 OptionsWindow *self = (OptionsWindow *)user_data;
219 Profile *profile = Preferences::instance()->copy_user_profile(self->_current_profile);
220 if (profile == NULL)
221 return;
222
223 GtkTreeIter iter;
224 GtkTreeModel *model = self->get_selected_tree_iter(&iter);
225 if (model == NULL)
226 return;
227
228 GtkTreeIter parent;
229 if (!gtk_tree_model_iter_parent(model, &parent, &iter))
230 return;
231
232 GtkTreeIter copy;
233 gtk_tree_store_insert_after(GTK_TREE_STORE(model), ©, &parent, &iter);
234 gtk_tree_store_set(GTK_TREE_STORE(model), ©,
235 TREE_INT_COLUMN, 2,
236 TREE_TEXT_COLUMN, profile->get_name(),
237 TREE_CONFIG_NAME_COLUMN, profile->get_config_name(),
238 TREE_ICON_COLUMN, self->_w.pixbuf_default,
239 -1);
240
241 self->expand_and_select(GTK_TREE_VIEW(self->_w.treeview), model, ©);
242 gtk_notebook_set_current_page(self->_w.notebook, 0);
243 }
244
245 void
on_button_delete_clicked(GtkButton * button,gpointer user_data)246 OptionsWindow::on_button_delete_clicked(GtkButton *button, gpointer user_data) {
247 OptionsWindow *self = (OptionsWindow *)user_data;
248 GtkTreeIter iter;
249 GtkTreeModel *model = self->get_selected_tree_iter(&iter);
250 if (model == NULL)
251 return;
252
253 gtk_tree_store_set(GTK_TREE_STORE(model), &iter, TREE_ICON_COLUMN, self->_w.pixbuf_deleted, -1);
254 self->_current_profile->set_deleted(true);
255 }
256
257 gboolean
tree_model_foreach_func_delete(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer user_data)258 OptionsWindow::tree_model_foreach_func_delete(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
259 {
260 OptionsWindow *self = (OptionsWindow *)user_data;
261
262 gchar *config_name;
263 gtk_tree_model_get(model, iter, TREE_CONFIG_NAME_COLUMN, &config_name, -1);
264
265 if (Preferences::instance()->find_profile(config_name) == NULL) {
266 gchar *path_string = gtk_tree_path_to_string(path);
267 self->_delete_path.push_back(path_string);
268 g_free(path_string);
269 }
270
271 g_free(config_name);
272 return FALSE;
273 }
274
275 void
on_button_ok_clicked(GtkButton * button,gpointer user_data)276 OptionsWindow::on_button_ok_clicked(GtkButton *button, gpointer user_data) {
277 OptionsWindow *self = (OptionsWindow *)user_data;
278 self->save();
279 }
280
281 void
on_button_close_clicked(GtkButton * button,gpointer user_data)282 OptionsWindow::on_button_close_clicked(GtkButton *button, gpointer user_data) {
283 OptionsWindow *self = (OptionsWindow *)user_data;
284
285 if (Preferences::instance()->has_changed_profiles()) {
286 CMD_EXEC("ui-options-window-dialog");
287 } else {
288 self->hide();
289 }
290 }
291
292 void
on_tree_selection_changed(GtkTreeSelection * selection,gpointer user_data)293 OptionsWindow::on_tree_selection_changed(GtkTreeSelection *selection, gpointer user_data) {
294 OptionsWindow *self = (OptionsWindow *)user_data;
295
296 GtkTreeIter iter;
297 GtkTreeModel *model;
298
299 if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
300 gchar *key;
301 gtk_tree_model_get(model, &iter, TREE_CONFIG_NAME_COLUMN, &key, -1);
302
303 self->_current_profile = Preferences::instance()->find_profile(key);
304 self->apply_profile();
305 g_free(key);
306
307 profile_level_t level = self->_current_profile->get_level();
308 gtk_widget_set_sensitive(self->_w.b_new, level == PROFILE_LEVEL_SYSTEM_USER);
309 gtk_widget_set_sensitive(self->_w.b_copy, level == PROFILE_LEVEL_USER);
310 gtk_widget_set_sensitive(self->_w.b_delete, level == PROFILE_LEVEL_USER);
311 gtk_widget_set_sensitive(self->_w.b_up, level == PROFILE_LEVEL_USER);
312 gtk_widget_set_sensitive(self->_w.b_down, level == PROFILE_LEVEL_USER);
313 }
314 }
315
316 void
on_media_check_button_toggled(GtkToggleButton * togglebutton,gpointer user_data)317 OptionsWindow::on_media_check_button_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
318 OptionsWindow *self = (OptionsWindow *)user_data;
319
320 GtkWidget *filechooser_button = GTK_WIDGET(g_object_get_data(G_OBJECT(togglebutton), FILE_CHOOSER_BUTTON_KEY));
321 GtkWidget *filechooser_clear_button = GTK_WIDGET(g_object_get_data(G_OBJECT(togglebutton), FILE_CHOOSER_CLEAR_BUTTON_KEY));
322 gtk_widget_set_sensitive(filechooser_button, togglebutton->active);
323 gtk_widget_set_sensitive(filechooser_clear_button, togglebutton->active);
324 if (!togglebutton->active) {
325 const char * key = (const char *)g_object_get_data(G_OBJECT(filechooser_button), PREFERENCES_KEY);
326 self->_current_profile->remove_value(key);
327 self->apply_filechooserbutton(GTK_FILE_CHOOSER(filechooser_button)); // apply parent value
328 }
329 }
330
331 void
on_media_clear_button_clicked(GtkButton * button,gpointer user_data)332 OptionsWindow::on_media_clear_button_clicked(GtkButton *button, gpointer user_data) {
333 OptionsWindow *self = (OptionsWindow *)user_data;
334
335 GtkFileChooser *filechooser = GTK_FILE_CHOOSER(g_object_get_data(G_OBJECT(button), FILE_CHOOSER_BUTTON_KEY));
336 gtk_file_chooser_unselect_all(filechooser);
337 const char * key = (const char *)g_object_get_data(G_OBJECT(filechooser), PREFERENCES_KEY);
338 self->_current_profile->set_null_value(key);
339 }
340
341 void
on_media_filechooser_file_set(GtkFileChooserButton * filechooserbutton,gpointer user_data)342 OptionsWindow::on_media_filechooser_file_set(GtkFileChooserButton *filechooserbutton, gpointer user_data) {
343 OptionsWindow *self = (OptionsWindow *)user_data;
344
345 const char * key = (const char *)g_object_get_data(G_OBJECT(filechooserbutton), PREFERENCES_KEY);
346 gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooserbutton));
347 if (filename == NULL) {
348 self->_current_profile->set_null_value(key);
349 } else {
350 self->_current_profile->set_string_value(key, filename);
351 }
352 g_free(filename);
353 }
354
355 void
set_widget_sensitive_by_key(GObject * object,const gchar * key,bool sensitive)356 OptionsWindow::set_widget_sensitive_by_key(GObject *object, const gchar *key, bool sensitive) {
357 gpointer widget = g_object_get_data(object, key);
358 if (widget == NULL)
359 return;
360
361 gtk_widget_set_sensitive(GTK_WIDGET(widget), sensitive);
362 }
363
364 /**
365 * Returns true if the profile value was removed. In this case the display value
366 * need to be applied again to fetch the now valid parent value.
367 */
368 bool
check_button_toggled(GtkToggleButton * togglebutton)369 OptionsWindow::check_button_toggled(GtkToggleButton *togglebutton) {
370 set_widget_sensitive_by_key(G_OBJECT(togglebutton), TARGET_WIDGET1_KEY, togglebutton->active);
371 set_widget_sensitive_by_key(G_OBJECT(togglebutton), TARGET_WIDGET2_KEY, togglebutton->active);
372 set_widget_sensitive_by_key(G_OBJECT(togglebutton), TARGET_WIDGET3_KEY, togglebutton->active);
373
374 const char * key = (const char *)g_object_get_data(G_OBJECT(togglebutton), PREFERENCES_KEY);
375 if (togglebutton->active) {
376 ProfileValue *value = _current_profile->get_value(key);
377 if (value != NULL)
378 _current_profile->set_value(key, new ProfileValue(value));
379 //_current_profile->set_int_value(key, _current_profile->get_int_value(key, 0));
380 } else {
381 _current_profile->remove_value(key);
382 }
383
384 return !togglebutton->active;
385 }
386
387 void
on_display_check_button_toggled(GtkToggleButton * togglebutton,gpointer user_data)388 OptionsWindow::on_display_check_button_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
389 OptionsWindow *self = (OptionsWindow *)user_data;
390 if (self->check_button_toggled(togglebutton))
391 self->apply_display_settings();
392 }
393
394 void
on_display_scale_value_changed(GtkSpinButton * spin_button,gpointer user_data)395 OptionsWindow::on_display_scale_value_changed(GtkSpinButton *spin_button, gpointer user_data) {
396 OptionsWindow *self = (OptionsWindow *)user_data;
397 int display_scale = gtk_spin_button_get_value_as_int(spin_button);
398 self->_current_profile->set_int_value("display_scale", display_scale);
399 }
400
401 void
on_display_effects_changed(GtkComboBox * combobox,gpointer user_data)402 OptionsWindow::on_display_effects_changed(GtkComboBox *combobox, gpointer user_data) {
403 OptionsWindow *self = (OptionsWindow *)user_data;
404 int display_effects = gtk_combo_box_get_active(combobox);
405 self->_current_profile->set_int_value("display_effects", display_effects);
406 }
407
408 void
on_display_debug_changed(GtkComboBox * combobox,gpointer user_data)409 OptionsWindow::on_display_debug_changed(GtkComboBox *combobox, gpointer user_data) {
410 OptionsWindow *self = (OptionsWindow *)user_data;
411 int display_debug = gtk_combo_box_get_active(combobox);
412 self->_current_profile->set_int_value("display_debug", display_debug);
413 }
414
415 void
on_display_mem_access_changed(GtkComboBox * combobox,gpointer user_data)416 OptionsWindow::on_display_mem_access_changed(GtkComboBox *combobox, gpointer user_data) {
417 OptionsWindow *self = (OptionsWindow *)user_data;
418 int display_mem_access = gtk_combo_box_get_active(combobox);
419 self->_current_profile->set_int_value("display_mem_access", display_mem_access);
420 }
421
422 void
on_profile_name_changed(GtkEditable * editable,gpointer user_data)423 OptionsWindow::on_profile_name_changed(GtkEditable *editable, gpointer user_data) {
424 OptionsWindow *self = (OptionsWindow *)user_data;
425 const char *name = gtk_entry_get_text(GTK_ENTRY(editable));
426
427 GtkTreeIter iter;
428 GtkTreeModel *model;
429 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(self->_w.treeview));
430 if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
431 gtk_tree_store_set(self->_w.treestore, &iter, TREE_TEXT_COLUMN, name, -1);
432 }
433
434 self->_current_profile->set_name(name);
435 self->_current_profile->set_string_value("name", name);
436 }
437
438 void
on_comment_changed(GtkTextBuffer * textbuffer,gpointer user_data)439 OptionsWindow::on_comment_changed(GtkTextBuffer *textbuffer, gpointer user_data) {
440 OptionsWindow *self = (OptionsWindow *)user_data;
441
442 GtkTextIter start, end;
443
444 gtk_text_buffer_get_iter_at_offset(textbuffer, &start, 0);
445 gtk_text_buffer_get_iter_at_offset(textbuffer, &end, 0);
446 gtk_text_iter_forward_to_end(&end);
447
448 gchar *text = gtk_text_buffer_get_text(textbuffer, &start, &end, FALSE);
449
450 const char *key = "comment";
451 if (strlen(text) == 0) {
452 self->_current_profile->remove_value(key);
453 } else {
454 self->_current_profile->set_string_value(key, text);
455 }
456
457 g_free(text);
458 }
459
460 void
on_system_type_changed(GtkComboBox * combobox,gpointer user_data)461 OptionsWindow::on_system_type_changed(GtkComboBox *combobox, gpointer user_data) {
462 OptionsWindow *self = (OptionsWindow *)user_data;
463
464 GtkTreeIter iter;
465 if (!gtk_combo_box_get_active_iter(self->_w.combobox_system_type, &iter))
466 return;
467
468 int kc_type;
469 gtk_tree_model_get(GTK_TREE_MODEL(self->_w.liststore_system), &iter, 1, &kc_type, -1);
470
471 self->_current_profile->set_int_value("system", kc_type);
472 self->apply_system_variant((kc_type_t)kc_type, KC_VARIANT_NONE);
473 self->apply_modules_settings((kc_type_t)kc_type);
474 self->apply_roms_settings((kc_type_t)kc_type, KC_VARIANT_NONE);
475 }
476
477 void
on_system_variant_check_button_toggled(GtkToggleButton * togglebutton,gpointer user_data)478 OptionsWindow::on_system_variant_check_button_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
479 const char *key = "variant";
480 OptionsWindow *self = (OptionsWindow *)user_data;
481
482 gtk_widget_set_sensitive(GTK_WIDGET(self->_w.combobox_system_variant), togglebutton->active);
483
484 if (togglebutton->active) {
485 self->_current_profile->set_int_value(key, self->_current_profile->get_int_value(key, KC_VARIANT_NONE));
486 } else {
487 self->_current_profile->remove_value(key);
488 self->apply_system_variant(self->_current_kc_type, (kc_variant_t)self->_current_profile->get_int_value(key, KC_VARIANT_NONE));
489 }
490 }
491
492 void
on_system_variant_changed(GtkComboBox * combobox,gpointer user_data)493 OptionsWindow::on_system_variant_changed(GtkComboBox *combobox, gpointer user_data) {
494 OptionsWindow *self = (OptionsWindow *)user_data;
495
496 GtkTreeIter iter;
497 if (!gtk_combo_box_get_active_iter(self->_w.combobox_system_variant, &iter))
498 return;
499
500 int kc_variant;
501 GtkTreeModel *model = gtk_combo_box_get_model(self->_w.combobox_system_variant);
502 gtk_tree_model_get(model, &iter, 1, &kc_variant, -1);
503
504 self->_current_profile->set_int_value("variant", kc_variant);
505 self->apply_roms_settings(self->_current_kc_type, (kc_variant_t)kc_variant);
506 }
507
508 void
on_module_changed(GtkComboBox * combobox,gpointer user_data)509 OptionsWindow::on_module_changed(GtkComboBox *combobox, gpointer user_data) {
510 OptionsWindow *self = (OptionsWindow *)user_data;
511
512 string list;
513 const char *ptr = "";
514 for (int a = 0;a < NR_OF_MODULES;a++) {
515 GtkTreeIter iter;
516 if (gtk_combo_box_get_active_iter(self->_w.combobox_module[a], &iter)) {
517 gchar *modif;
518 GtkTreeModel *model = gtk_combo_box_get_model(self->_w.combobox_module[a]);
519 gtk_tree_model_get(model, &iter, MODULES_MODIF_COLUMN, &modif, -1);
520 if (modif != NULL) {
521 list += ptr;
522 list += modif;
523 ptr = ",";
524 g_free(modif);
525 }
526 }
527 }
528 self->_current_profile->set_string_value("modules", list.c_str());
529 }
530
531 void
on_modules_check_button_toggled(GtkToggleButton * togglebutton,gpointer user_data)532 OptionsWindow::on_modules_check_button_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
533 const char *key = "modules";
534 OptionsWindow *self = (OptionsWindow *)user_data;
535
536 for (int a = 0;a < NR_OF_MODULES;a++) {
537 gtk_widget_set_sensitive(GTK_WIDGET(self->_w.combobox_module[a]), togglebutton->active);
538 }
539
540 if (togglebutton->active) {
541 self->_current_profile->set_string_value(key, self->_current_profile->get_string_value(key, ""));
542 } else {
543 self->_current_profile->remove_value(key);
544 self->apply_modules_settings(self->_current_kc_type);
545 }
546 }
547
548 void
on_kc85_settings_check_button_toggled(GtkToggleButton * togglebutton,gpointer user_data)549 OptionsWindow::on_kc85_settings_check_button_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
550 OptionsWindow *self = (OptionsWindow *)user_data;
551 if (self->check_button_toggled(togglebutton))
552 self->apply_kc85_settings();
553 }
554
555 void
on_kc85_d004_changed(GtkComboBox * combobox,gpointer user_data)556 OptionsWindow::on_kc85_d004_changed(GtkComboBox *combobox, gpointer user_data) {
557 OptionsWindow *self = (OptionsWindow *)user_data;
558 int d004 = gtk_combo_box_get_active(combobox);
559 self->_current_profile->set_int_value("d004", d004);
560 }
561
562 void
on_kc85_f8_rom_changed(GtkComboBox * combobox,gpointer user_data)563 OptionsWindow::on_kc85_f8_rom_changed(GtkComboBox *combobox, gpointer user_data) {
564 OptionsWindow *self = (OptionsWindow *)user_data;
565 int d004_f8 = gtk_combo_box_get_active(combobox);
566 self->_current_profile->set_int_value("d004_f8", d004_f8);
567 }
568
569 void
on_kc85_busdrivers_changed(GtkSpinButton * spin_button,gpointer user_data)570 OptionsWindow::on_kc85_busdrivers_changed(GtkSpinButton *spin_button, gpointer user_data) {
571 OptionsWindow *self = (OptionsWindow *)user_data;
572 int busdrivers = gtk_spin_button_get_value_as_int(spin_button);
573 self->_current_profile->set_int_value("busdrivers", busdrivers);
574 }
575
576 void
on_roms_settings_check_button_toggled(GtkToggleButton * togglebutton,gpointer user_data)577 OptionsWindow::on_roms_settings_check_button_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
578 OptionsWindow *self = (OptionsWindow *)user_data;
579 if (self->check_button_toggled(togglebutton))
580 self->apply_system_type();
581 }
582
583 void
on_rom_changed(GtkComboBoxEntry * comboboxentry,gpointer user_data)584 OptionsWindow::on_rom_changed(GtkComboBoxEntry *comboboxentry, gpointer user_data) {
585 OptionsWindow *self = (OptionsWindow *)user_data;
586
587 GtkTreeIter iter;
588 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(comboboxentry), &iter))
589 return;
590
591 gchar *rom;
592 GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(comboboxentry));
593 gtk_tree_model_get(model, &iter, 1, &rom, -1);
594
595 const char *key = self->get_preferences_key(G_OBJECT(g_object_get_data(G_OBJECT(comboboxentry), DATA_KEY_CHECK_BUTTON)));
596 self->_current_profile->set_string_value(key, rom);
597
598 self->apply_system_type(); // let apply_roms_settings change the tooltip text for the combobox!
599 }
600
601 void
on_rom_open_clicked(GtkButton * button,gpointer user_data)602 OptionsWindow::on_rom_open_clicked(GtkButton *button, gpointer user_data) {
603 OptionsWindow *self = (OptionsWindow *)user_data;
604
605 GtkWidget *filechooser = gtk_file_chooser_dialog_new(_("Open ROM Image..."),
606 GTK_WINDOW(self->_window),
607 GTK_FILE_CHOOSER_ACTION_OPEN,
608 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
609 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
610 NULL);
611
612 if (self->_open_rom_last_path == NULL)
613 self->_open_rom_last_path = sys_gethome();
614
615 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), self->_open_rom_last_path);
616 free(self->_open_rom_last_path);
617
618 const char *key = self->get_preferences_key(G_OBJECT(g_object_get_data(G_OBJECT(button), DATA_KEY_CHECK_BUTTON)));
619 if (gtk_dialog_run(GTK_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT)
620 {
621 char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser));
622 self->_current_profile->set_string_value(key, filename);
623 g_free(filename);
624 }
625
626 self->_open_rom_last_path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(filechooser));
627
628 gtk_widget_destroy(filechooser);
629
630 self->apply_system_type(); // let apply_roms_settings add the filename from profile to combobox model!
631 }
632
633 void
apply_entry_value(GtkEntry * entry,gint signal_id)634 OptionsWindow::apply_entry_value(GtkEntry *entry, gint signal_id)
635 {
636 const char * key = get_preferences_key(G_OBJECT(entry));
637 ProfileValue *value = get_current_profile_value(key);
638 g_signal_handler_block(entry, signal_id);
639 gtk_entry_set_text(entry, value == NULL ? "" : value->get_string_value());
640 g_signal_handler_unblock(entry, signal_id);
641
642 GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(entry), DATA_KEY_CHECK_BUTTON));
643 gtk_toggle_button_set_active(toggle_button, _current_profile->contains_key(key));
644 }
645
646 void
apply_network_settings(void)647 OptionsWindow::apply_network_settings(void)
648 {
649 apply_entry_value(_w.entry_network_ip_address, _w.on_network_changed_id[0]);
650 apply_entry_value(_w.entry_network_netmask, _w.on_network_changed_id[1]);
651 apply_entry_value(_w.entry_network_gateway, _w.on_network_changed_id[2]);
652 apply_entry_value(_w.entry_network_dns_server, _w.on_network_changed_id[3]);
653 }
654
655 void
on_network_settings_check_button_toggled(GtkToggleButton * togglebutton,gpointer user_data)656 OptionsWindow::on_network_settings_check_button_toggled(GtkToggleButton *togglebutton, gpointer user_data)
657 {
658 OptionsWindow *self = (OptionsWindow *)user_data;
659 if (self->check_button_toggled(togglebutton))
660 self->apply_network_settings();
661 }
662
663 void
on_network_changed(GtkEntry * entry,gpointer user_data)664 OptionsWindow::on_network_changed(GtkEntry *entry, gpointer user_data)
665 {
666 OptionsWindow *self = (OptionsWindow *)user_data;
667 const char * key = self->get_preferences_key(G_OBJECT(entry));
668 gchar *text = pango_trim_string(gtk_entry_get_text(entry));
669 gtk_entry_set_icon_from_stock(entry, GTK_ENTRY_ICON_PRIMARY, *text && !self->is_ip_address(text) ? GTK_STOCK_DIALOG_WARNING : NULL);
670 gtk_entry_set_icon_activatable(entry, GTK_ENTRY_ICON_PRIMARY, FALSE);
671 self->_current_profile->set_string_value(key, text);
672 g_free(text);
673 }
674
675 GtkTreeModel *
get_selected_tree_iter(GtkTreeIter * iter)676 OptionsWindow::get_selected_tree_iter(GtkTreeIter *iter) {
677 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(_w.treeview));
678
679 GtkTreeModel *model;
680 if (gtk_tree_selection_get_selected(selection, &model, iter))
681 return model;
682
683 return NULL;
684 }
685
686 /**
687 * FreeBSD 8 still uses glib 2.20 as default version. That does
688 * not include g_hostname_is_ip_address() which has the good point
689 * to be available in MinGW environment too.
690 * I'm not going to to create a wrapper just for the GUI check, so
691 * there's no nice warning icon until glib is upgraded to at least 2.22.
692 */
693 bool
is_ip_address(const char * addr)694 OptionsWindow::is_ip_address(const char *addr)
695 {
696 #if GLIB_CHECK_VERSION(2, 22, 0)
697 return g_hostname_is_ip_address(addr);
698 #else
699 return true;
700 #endif
701 }
702
703 ProfileValue *
get_current_profile_value(const char * key)704 OptionsWindow::get_current_profile_value(const char *key) {
705 if (_current_profile == NULL)
706 return NULL;
707
708 return _current_profile->get_value(key);
709 }
710
711 const char *
get_preferences_key(GObject * object)712 OptionsWindow::get_preferences_key(GObject *object) {
713 const char * key = (const char *)g_object_get_data(object, PREFERENCES_KEY);
714 g_assert(key != NULL);
715 return key;
716 }
717
718 void
set_preferences_key(GObject * object,const char * key)719 OptionsWindow::set_preferences_key(GObject *object, const char *key)
720 {
721 g_assert(object != NULL);
722 g_assert(key != NULL);
723 g_object_set_data(object, PREFERENCES_KEY, strdup(key));
724 }
725
726 /**
727 * Apply the profile value to the given spinbutton. The key of the value to apply will
728 * be fetched from the data set on the checkbutton that enables/disables this spinbutton.
729 *
730 * While setting the value the signal handler is blocked to prevent loops with the
731 * handler writing changes back to the profile.
732 */
733 void
apply_spin_button_value(GtkCheckButton * check_button,GtkSpinButton * spin_button,gint signal_id,int default_value)734 OptionsWindow::apply_spin_button_value(GtkCheckButton *check_button, GtkSpinButton *spin_button, gint signal_id, int default_value) {
735 const char *key = get_preferences_key(G_OBJECT(check_button));
736 ProfileValue *value = get_current_profile_value(key);
737 int spin_value = value == NULL ? default_value : value->get_int_value();
738
739 g_signal_handler_block(spin_button, signal_id);
740 gtk_spin_button_set_value(spin_button, spin_value);
741 g_signal_handler_unblock(spin_button, signal_id);
742
743 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), _current_profile->contains_key(key));
744 }
745
746 /**
747 * Apply the profile value to the given combobox. The key of the value to apply will
748 * be fetched from the data set on the checkbutton that enables/disables this combobox.
749 *
750 * While setting the value the signal handler is blocked to prevent loops with the
751 * handler writing changes back to the profile.
752 *
753 * The value for the combobox is currently limited to be 0 or 1.
754 */
755 void
apply_combobox_value(GtkCheckButton * check_button,GtkComboBox * combobox,gint handler_id)756 OptionsWindow::apply_combobox_value(GtkCheckButton *check_button, GtkComboBox *combobox, gint handler_id) {
757 const char *key = get_preferences_key(G_OBJECT(check_button));
758 ProfileValue *value = get_current_profile_value(key);
759 int val = value == NULL ? 0 : value->get_int_value();
760
761 g_signal_handler_block(combobox, handler_id);
762 gtk_combo_box_set_active(combobox, val ? 1 : 0);
763 g_signal_handler_unblock(combobox, handler_id);
764
765 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), _current_profile->contains_key(key));
766 }
767
768 void
apply_profile(void)769 OptionsWindow::apply_profile(void) {
770 g_signal_handler_block(_w.entry_profile_name, _w.on_profile_name_changed_id);
771 gtk_entry_set_text(_w.entry_profile_name, _current_profile->get_name());
772 g_signal_handler_unblock(_w.entry_profile_name, _w.on_profile_name_changed_id);
773 gtk_widget_set_sensitive(GTK_WIDGET(_w.entry_profile_name), _current_profile->get_level() == PROFILE_LEVEL_USER);
774
775 apply_comment();
776 apply_system_type();
777 apply_display_settings();
778 apply_kc85_settings();
779 apply_network_settings();
780
781 apply_filechooserbutton(GTK_FILE_CHOOSER(get_widget("media_filechooserbutton_tape")));
782 apply_filechooserbutton(GTK_FILE_CHOOSER(get_widget("media_filechooserbutton_audio")));
783 apply_filechooserbutton(GTK_FILE_CHOOSER(get_widget("media_filechooserbutton_disk1")));
784 apply_filechooserbutton(GTK_FILE_CHOOSER(get_widget("media_filechooserbutton_disk2")));
785 apply_filechooserbutton(GTK_FILE_CHOOSER(get_widget("media_filechooserbutton_disk3")));
786 apply_filechooserbutton(GTK_FILE_CHOOSER(get_widget("media_filechooserbutton_disk4")));
787 apply_filechooserbutton(GTK_FILE_CHOOSER(get_widget("media_filechooserbutton_hd1")));
788 apply_filechooserbutton(GTK_FILE_CHOOSER(get_widget("media_filechooserbutton_hd2")));
789 }
790
791 void
apply_comment(void)792 OptionsWindow::apply_comment(void) {
793 g_signal_handler_block(_w.textbuffer_comment, _w.on_comment_changed_id);
794 gtk_text_buffer_set_text(_w.textbuffer_comment, _current_profile->get_comment(), -1);
795 g_signal_handler_unblock(_w.textbuffer_comment, _w.on_comment_changed_id);
796
797 gtk_widget_set_sensitive(GTK_WIDGET(_w.textview_comment), _current_profile->get_level() == PROFILE_LEVEL_USER);
798 }
799
800 void
apply_system_type(void)801 OptionsWindow::apply_system_type(void) {
802 gtk_widget_set_sensitive(GTK_WIDGET(_w.combobox_system_type), _current_profile->get_level() == PROFILE_LEVEL_DEFAULT);
803
804 ProfileValue *system = get_current_profile_value("system");
805 ProfileValue *variant = get_current_profile_value("variant");
806
807 g_signal_handler_block(_w.combobox_system_type, _w.on_system_type_changed_id);
808
809 GtkTreeIter iter;
810 bool valid = system != NULL;
811 if (valid)
812 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(_w.liststore_system), &iter);
813 while (valid) {
814 int kc_type;
815 gtk_tree_model_get(GTK_TREE_MODEL(_w.liststore_system), &iter, 1, &kc_type, -1);
816 if (system->get_int_value() == kc_type) {
817 gtk_combo_box_set_active_iter(_w.combobox_system_type, &iter);
818 apply_system_variant((kc_type_t)kc_type, variant == NULL ? KC_VARIANT_NONE : (kc_variant_t)variant->get_int_value());
819 apply_roms_settings((kc_type_t)kc_type, variant == NULL ? KC_VARIANT_NONE : (kc_variant_t)variant->get_int_value());
820 apply_modules_settings((kc_type_t)kc_type);
821 break;
822 }
823 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(_w.liststore_system), &iter);
824 }
825 if (!valid) {
826 gtk_combo_box_set_active(_w.combobox_system_type, -1);
827 apply_system_variant(KC_TYPE_NONE, KC_VARIANT_NONE);
828 apply_roms_settings(KC_TYPE_NONE, KC_VARIANT_NONE);
829 apply_modules_settings(KC_TYPE_NONE);
830 }
831
832 g_signal_handler_unblock(_w.combobox_system_type, _w.on_system_type_changed_id);
833 }
834
835 void
set_roms_liststore(int idx,const char * rom_key,SystemROM * rom)836 OptionsWindow::set_roms_liststore(int idx, const char *rom_key, SystemROM *rom) {
837 ProfileValue *profile_value = get_current_profile_value(rom_key);
838 const char *profile_rom_filename = (profile_value == NULL) ? NULL : profile_value->get_string_value();
839
840 GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(_w.roms_comboboxentry[idx])));
841 gtk_list_store_clear(store);
842
843 int active = -1;
844 int list_entry = 0;
845 ROMEntry *active_entry = NULL;
846 const rom_entry_list_t roms = rom->get_roms();
847 for (rom_entry_list_t::const_iterator it2 = roms.begin();it2 != roms.end();it2++) {
848 ROMEntry *entry = (*it2);
849 GtkTreeIter iter;
850 gtk_list_store_append(store, &iter);
851 gtk_list_store_set(store, &iter,
852 ROMS_DESCRIPTION_COLUMN, entry->get_description().c_str(),
853 ROMS_FILENAME_COLUMN, entry->get_filename().c_str(),
854 ROMS_TYPE_COLUMN, 1,
855 -1);
856
857 if ((profile_rom_filename != NULL) && (entry->get_filename().compare(profile_rom_filename) == 0)) {
858 active = list_entry;
859 active_entry = entry;
860 }
861 list_entry++;
862 }
863
864 if ((active < 0) && (profile_rom_filename != NULL)) {
865 GtkTreeIter iter;
866 gtk_list_store_append(store, &iter);
867 gtk_list_store_set(store, &iter,
868 ROMS_DESCRIPTION_COLUMN, sys_basename(profile_rom_filename),
869 ROMS_FILENAME_COLUMN, profile_rom_filename,
870 ROMS_TYPE_COLUMN, 2,
871 -1);
872 active = list_entry;
873 }
874
875 if (active < 0) {
876 active = 0;
877 active_entry = *roms.begin();
878
879 int idx = 0;
880 for (rom_entry_list_t::const_iterator it = roms.begin();it != roms.end();it++) {
881 ROMEntry *entry = (*it);
882 if (entry->is_default()) {
883 active = idx;
884 active_entry = entry;
885 break;
886 }
887 idx++;
888 }
889 }
890
891 char tooltip[128];
892 snprintf(tooltip, sizeof(tooltip), _("ROM image is '%s'. The ROM size needs to be %04xh (%d) bytes."),
893 active_entry != NULL ? active_entry->get_filename().c_str() : profile_rom_filename,
894 rom->get_size(),
895 rom->get_size());
896 gtk_widget_set_tooltip_text(GTK_WIDGET(_w.roms_comboboxentry[idx]), tooltip);
897
898 g_signal_handler_block(_w.roms_comboboxentry[idx], _w.on_rom_changed_id[idx]);
899 gtk_combo_box_set_model(GTK_COMBO_BOX(_w.roms_comboboxentry[idx]), GTK_TREE_MODEL(store));
900 gtk_combo_box_set_active(GTK_COMBO_BOX(_w.roms_comboboxentry[idx]), active);
901 g_signal_handler_unblock(_w.roms_comboboxentry[idx], _w.on_rom_changed_id[idx]);
902 }
903
904 void
apply_roms_settings(kc_type_t kc_type,kc_variant_t kc_variant)905 OptionsWindow::apply_roms_settings(kc_type_t kc_type, kc_variant_t kc_variant) {
906 const SystemType *type = SystemInformation::instance()->get_system_type(kc_type, kc_variant);
907 if (type == NULL)
908 return;
909
910 system_rom_list_t rom_list = type->get_rom_list();
911 int idx = 0;
912 for (system_rom_list_t::const_iterator it = rom_list.begin();(it != rom_list.end()) && (idx < NR_OF_ROMS);it++) {
913 SystemROM *rom = (*it);
914 const char *rom_key = rom->get_name().c_str();
915
916 set_roms_liststore(idx, rom_key, rom);
917
918 string text = string(gettext(rom_key)) + ":";
919 gtk_label_set_text(_w.roms_label[idx], text.c_str());
920
921 gpointer val = g_object_get_data(G_OBJECT(_w.roms_check_button[idx]), PREFERENCES_KEY);
922 g_object_set_data(G_OBJECT(_w.roms_check_button[idx]), PREFERENCES_KEY, strdup(rom_key));
923 free(val);
924
925 gtk_widget_show(GTK_WIDGET(_w.roms_label[idx]));
926 gtk_widget_show(GTK_WIDGET(_w.roms_comboboxentry[idx]));
927 gtk_widget_show(GTK_WIDGET(_w.roms_open_button[idx]));
928 gtk_widget_show(GTK_WIDGET(_w.roms_check_button[idx]));
929
930 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_w.roms_check_button[idx]), _current_profile->contains_key(rom_key));
931 gtk_widget_set_sensitive(GTK_WIDGET(_w.roms_check_button[idx]), _current_profile->get_level() != PROFILE_LEVEL_DEFAULT);
932
933 idx++;
934 }
935
936 for (;idx < NR_OF_ROMS;idx++) {
937 gtk_widget_hide(GTK_WIDGET(_w.roms_label[idx]));
938 gtk_widget_hide(GTK_WIDGET(_w.roms_comboboxentry[idx]));
939 gtk_widget_hide(GTK_WIDGET(_w.roms_open_button[idx]));
940 gtk_widget_hide(GTK_WIDGET(_w.roms_check_button[idx]));
941 }
942 }
943
944 void
apply_system_variant(kc_type_t kc_type,kc_variant_t kc_variant)945 OptionsWindow::apply_system_variant(kc_type_t kc_type, kc_variant_t kc_variant) {
946 _current_kc_type = kc_type;
947
948 system_type_list_t list = SystemInformation::instance()->get_system_types();
949
950 GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
951 for (system_type_list_t::iterator it = list.begin();it != list.end();it++) {
952 SystemType *type = (*it);
953 if (type->get_kc_type() != kc_type)
954 continue;
955
956 GtkTreeIter iter;
957 gtk_list_store_append(store, &iter);
958 gtk_list_store_set(store, &iter, 0, type->get_display_name(), 1, type->get_kc_variant(), -1);
959 }
960
961 g_signal_handler_block(_w.combobox_system_variant, _w.on_system_variant_changed_id);
962
963 gtk_combo_box_set_model(_w.combobox_system_variant, GTK_TREE_MODEL(store));
964 g_object_unref(store);
965
966 if (kc_variant == KC_VARIANT_NONE) {
967 gtk_combo_box_set_active(_w.combobox_system_variant, 0);
968 } else {
969 GtkTreeIter iter;
970 bool valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
971 while (valid) {
972 int v;
973 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 1, &v, -1);
974 if (kc_variant == v) {
975 gtk_combo_box_set_active_iter(_w.combobox_system_variant, &iter);
976 break;
977 }
978 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
979 }
980 if (!valid) {
981 gtk_combo_box_set_active(_w.combobox_system_variant, 0);
982 }
983 }
984
985 g_signal_handler_unblock(_w.combobox_system_variant, _w.on_system_variant_changed_id);
986
987 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_w.check_button_system_variant), _current_profile->contains_key("variant"));
988 }
989
990 void
apply_display_settings(void)991 OptionsWindow::apply_display_settings(void) {
992 apply_spin_button_value(_w.check_button_display_scale, _w.spin_button_display_scale, _w.on_display_scale_value_changed_id, 1);
993
994 apply_combobox_value(_w.check_button_display_effects, _w.combobox_display_effects, _w.on_display_effects_changed_id);
995 apply_combobox_value(_w.check_button_display_mem_access, _w.combobox_display_mem_access, _w.on_display_mem_access_changed_id);
996 apply_combobox_value(_w.check_button_display_debug, _w.combobox_display_debug, _w.on_display_debug_changed_id);
997 }
998
999 void
apply_kc85_settings(void)1000 OptionsWindow::apply_kc85_settings(void) {
1001 apply_spin_button_value(_w.check_button_busdrivers, _w.spin_button_busdrivers, _w.on_kc85_busdrivers_changed_id, 0);
1002
1003 apply_combobox_value(_w.check_button_d004, _w.combobox_d004, _w.on_kc85_d004_changed_id);
1004 apply_combobox_value(_w.check_button_f8_rom, _w.combobox_f8_rom, _w.on_kc85_f8_rom_changed_id);
1005 }
1006
1007 void
apply_modules_settings(kc_type_t kc_type)1008 OptionsWindow::apply_modules_settings(kc_type_t kc_type) {
1009 const char *key = "modules";
1010 ProfileValue *modules = get_current_profile_value(key);
1011 string modules_list = modules == NULL ? "" : modules->get_string_value();
1012
1013 StringList list(modules == NULL ? "" : modules->get_string_value());
1014
1015 for (int a = 0;a < NR_OF_MODULES;a++) {
1016 g_signal_handler_block(_w.combobox_module[a], _w.on_module_changed_id[a]);
1017 }
1018
1019 if (_w.liststore_modules != NULL) {
1020 gtk_list_store_clear(_w.liststore_modules);
1021 // FIXME: gtk_list_store_free() ???
1022 }
1023 _w.liststore_modules = get_modules_list_model(kc_type);
1024 for (int a = 0;a < NR_OF_MODULES;a++) {
1025 gtk_combo_box_set_model(_w.combobox_module[a], GTK_TREE_MODEL(_w.liststore_modules));
1026 gtk_combo_box_set_active(_w.combobox_module[a], 0);
1027 }
1028
1029 int a = 0;
1030 for (StringList::iterator it = list.begin();(it != list.end()) && (a < NR_OF_MODULES);it++) {
1031 GtkTreeIter iter;
1032 GtkTreeModel *model = gtk_combo_box_get_model(_w.combobox_module[a]);
1033 bool valid = gtk_tree_model_get_iter_first(model, &iter);
1034 while (valid) {
1035 gchar *modif;
1036 gtk_tree_model_get(model, &iter, MODULES_MODIF_COLUMN, &modif, -1);
1037 if ((modif != NULL) && (strcmp((*it).c_str(), modif) == 0)) {
1038 gtk_combo_box_set_active_iter(_w.combobox_module[a], &iter);
1039 break;
1040 }
1041 g_free(modif);
1042 valid = gtk_tree_model_iter_next(model, &iter);
1043 }
1044 a++;
1045 }
1046
1047 for (int a = 0;a < NR_OF_MODULES;a++) {
1048 g_signal_handler_unblock(_w.combobox_module[a], _w.on_module_changed_id[a]);
1049 }
1050
1051 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_w.check_button_modules), _current_profile->contains_key(key));
1052 }
1053
1054 void
apply_filechooserbutton(GtkFileChooser * filechooser)1055 OptionsWindow::apply_filechooserbutton(GtkFileChooser *filechooser) {
1056 const char * key = (const char *)g_object_get_data(G_OBJECT(filechooser), PREFERENCES_KEY);
1057 const char * dir = (const char *)g_object_get_data(G_OBJECT(filechooser), DEFAULT_DIR_KEY);
1058
1059 ProfileValue *value = get_current_profile_value(key);
1060
1061 const char *filename = value == NULL ? NULL : value->get_string_value();
1062
1063 if (filename == NULL) {
1064 gtk_file_chooser_unselect_all(filechooser);
1065 } else {
1066 if (!sys_isabsolutepath(filename) && (dir != NULL)) {
1067 string path = string(kcemu_datadir) + dir + filename;
1068 gtk_file_chooser_select_filename(filechooser, path.c_str());
1069 } else {
1070 gtk_file_chooser_select_filename(filechooser, filename);
1071 }
1072 }
1073
1074 GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(filechooser), DATA_KEY_CHECK_BUTTON));
1075 gtk_toggle_button_set_active(toggle_button, _current_profile->contains_key(key));
1076 }
1077
1078 void
move_row(GtkPathMoveFunc path_func,GtkIterMoveFunc move_func)1079 OptionsWindow::move_row(GtkPathMoveFunc path_func, GtkIterMoveFunc move_func) {
1080 GtkTreeIter iter;
1081 GtkTreeModel *model;
1082
1083 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(_w.treeview));
1084 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
1085 return;
1086
1087 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
1088 path_func(path);
1089
1090 GtkTreeIter position;
1091 if (gtk_tree_model_get_iter(model, &position, path)) {
1092 move_func(_w.treestore, &iter, &position);
1093 }
1094
1095 gtk_tree_path_free(path);
1096 }
1097
1098 void
add_system(GtkTreeStore * store,GtkTreeIter * iter,const char * name,const char * config_name,const char * icon_name)1099 OptionsWindow::add_system(GtkTreeStore *store, GtkTreeIter *iter, const char *name, const char *config_name, const char *icon_name) {
1100 GtkTreeIter iter_system;
1101 GdkPixbuf *pixbuf = get_icon(icon_name);
1102 gtk_tree_store_append(store, &iter_system, iter);
1103 gtk_tree_store_set(store, &iter_system,
1104 TREE_INT_COLUMN, 2,
1105 TREE_TEXT_COLUMN, name,
1106 TREE_CONFIG_NAME_COLUMN, config_name,
1107 TREE_ICON_COLUMN, pixbuf,
1108 -1);
1109
1110 list<Profile *> children = Preferences::instance()->find_child_profiles(config_name);
1111 for (list<Profile *>::iterator it = children.begin();it != children.end();it++) {
1112 GtkTreeIter iter_child;
1113 gtk_tree_store_append(store, &iter_child, &iter_system);
1114 gtk_tree_store_set(store, &iter_child,
1115 TREE_INT_COLUMN, 2,
1116 TREE_TEXT_COLUMN, (*it)->get_name(),
1117 TREE_CONFIG_NAME_COLUMN, (*it)->get_config_name(),
1118 TREE_ICON_COLUMN, _w.pixbuf_default,
1119 -1);
1120 }
1121 }
1122
1123 GtkTreeStore *
get_tree_model(void)1124 OptionsWindow::get_tree_model(void) {
1125 GtkTreeStore *store = gtk_tree_store_new(TREE_N_COLUMNS, G_TYPE_INT, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING);
1126
1127 GtkTreeIter iter_root;
1128 gtk_tree_store_append(store, &iter_root, NULL);
1129 gtk_tree_store_set(store, &iter_root, TREE_INT_COLUMN, 1, TREE_TEXT_COLUMN, "Default", TREE_ICON_COLUMN, _w.pixbuf_root, TREE_CONFIG_NAME_COLUMN, "default", -1);
1130
1131 emulation_type_list_t list = EmulationType::get_emulation_types();
1132 for (emulation_type_list_t::iterator it = list.begin();it != list.end();it++) {
1133 add_system(store, &iter_root, (*it)->get_name(), (*it)->get_config_name(), (*it)->get_icon_name());
1134 }
1135
1136 return store;
1137 }
1138
1139 GtkListStore *
get_system_list_model(void)1140 OptionsWindow::get_system_list_model(void) {
1141 GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
1142
1143 emulation_type_list_t list = EmulationType::get_emulation_types();
1144 for (emulation_type_list_t::iterator it = list.begin();it != list.end();it++) {
1145 GtkTreeIter iter;
1146 gtk_list_store_append(store, &iter);
1147 gtk_list_store_set(store, &iter, 0, (*it)->get_name(), 1, (*it)->get_kc_type(), -1);
1148 }
1149
1150 return store;
1151 }
1152
1153 GtkListStore *
get_variant_list_model(kc_variant_t kc_variant,const char * name,...)1154 OptionsWindow::get_variant_list_model(kc_variant_t kc_variant, const char *name, ...) {
1155 GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
1156
1157 va_list ap;
1158 va_start(ap, name);
1159
1160 while (242) {
1161 GtkTreeIter iter;
1162 gtk_list_store_append(store, &iter);
1163 gtk_list_store_set(store, &iter, 0, name, 1, kc_variant, -1);
1164
1165 kc_variant = (kc_variant_t)va_arg(ap, int);
1166 if (kc_variant < 0)
1167 break;
1168
1169 name = va_arg(ap, const char *);
1170 }
1171
1172 va_end(ap);
1173
1174 return store;
1175 }
1176
1177 GtkListStore *
get_modules_list_model(kc_type_t kc_type)1178 OptionsWindow::get_modules_list_model(kc_type_t kc_type) {
1179 GtkListStore *store = gtk_list_store_new(MODULES_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
1180
1181 for (ModuleList::iterator it = module_list->begin();it != module_list->end();it++) {
1182 kc_type_t mod_kc_type = (*it)->get_kc_type();
1183 if ((mod_kc_type & kc_type) == 0)
1184 continue;
1185
1186 const char *name = (*it)->get_name();
1187 const char *modif_name = (*it)->get_mod() == NULL ? NULL : (*it)->get_mod()->get_name();
1188
1189 GtkTreeIter iter;
1190 gtk_list_store_append(store, &iter);
1191 gtk_list_store_set(store, &iter, MODULES_NAME_COLUMN, name, MODULES_MODIF_COLUMN, modif_name, MODULES_POINTER_COLUMN, (*it), -1);
1192 }
1193
1194 return store;
1195 }
1196
1197 void
wire_check_button(const char * preferences_key,const char * default_dir,const char * check_button_name,const char * filechooser_button_name,const char * button_clear_name)1198 OptionsWindow::wire_check_button(const char *preferences_key, const char *default_dir, const char *check_button_name, const char *filechooser_button_name, const char *button_clear_name) {
1199 GtkWidget *check_button = get_widget(check_button_name);
1200 GtkWidget *filechooser_button = get_widget(filechooser_button_name);
1201 GtkWidget *button_clear = get_widget(button_clear_name);
1202 g_object_set_data(G_OBJECT(check_button), FILE_CHOOSER_BUTTON_KEY, filechooser_button);
1203 g_object_set_data(G_OBJECT(check_button), FILE_CHOOSER_CLEAR_BUTTON_KEY, button_clear);
1204 g_object_set_data(G_OBJECT(button_clear), FILE_CHOOSER_BUTTON_KEY, filechooser_button);
1205 g_object_set_data(G_OBJECT(filechooser_button), DATA_KEY_CHECK_BUTTON, check_button);
1206 g_object_set_data(G_OBJECT(filechooser_button), PREFERENCES_KEY, strdup(preferences_key));
1207 if (default_dir != NULL)
1208 g_object_set_data(G_OBJECT(filechooser_button), DEFAULT_DIR_KEY, strdup(default_dir));
1209 g_signal_connect(check_button, "toggled", G_CALLBACK(on_media_check_button_toggled), this);
1210 g_signal_connect(button_clear, "clicked", G_CALLBACK(on_media_clear_button_clicked), this);
1211 g_signal_connect(filechooser_button, "file-set", G_CALLBACK(on_media_filechooser_file_set), this);
1212 }
1213
1214 void
wire_check_button(const char * preferences_key,GtkCheckButton * check_button,GCallback callback,GtkWidget * target1,GtkWidget * target2,GtkWidget * target3)1215 OptionsWindow::wire_check_button(const char *preferences_key, GtkCheckButton *check_button, GCallback callback, GtkWidget *target1, GtkWidget *target2, GtkWidget *target3) {
1216 g_object_set_data(G_OBJECT(check_button), PREFERENCES_KEY, strdup(preferences_key));
1217 g_object_set_data(G_OBJECT(check_button), TARGET_WIDGET1_KEY, target1);
1218 g_object_set_data(G_OBJECT(target1), DATA_KEY_CHECK_BUTTON, check_button);
1219
1220 if (target2 != NULL) {
1221 g_object_set_data(G_OBJECT(check_button), TARGET_WIDGET2_KEY, target2);
1222 g_object_set_data(G_OBJECT(target2), DATA_KEY_CHECK_BUTTON, check_button);
1223 }
1224 if (target3 != NULL) {
1225 g_object_set_data(G_OBJECT(check_button), TARGET_WIDGET3_KEY, target3);
1226 g_object_set_data(G_OBJECT(target3), DATA_KEY_CHECK_BUTTON, check_button);
1227 }
1228
1229 g_signal_connect(check_button, "toggled", callback, this);
1230 }
1231
1232 void
init(void)1233 OptionsWindow::init(void) {
1234 _window = get_widget("options_window");
1235 gtk_signal_connect(GTK_OBJECT(_window), "delete_event",
1236 GTK_SIGNAL_FUNC(cmd_exec_sft),
1237 (char *)"ui-options-window-toggle"); // FIXME:
1238
1239 _w.pixbuf_root = get_icon("icon-root.png");
1240 _w.pixbuf_default = get_icon("icon-default.png");
1241 _w.pixbuf_deleted = get_icon("icon-deleted.png");
1242
1243 _w.treestore = get_tree_model();
1244 _w.treeview = get_widget("tree_treeview");
1245 gtk_tree_view_set_model(GTK_TREE_VIEW(_w.treeview), GTK_TREE_MODEL(_w.treestore));
1246 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(_w.treeview));
1247
1248 GtkTreeViewColumn *column1 = gtk_tree_view_column_new();
1249 add_icon_renderer(GTK_TREE_VIEW(_w.treeview), column1, "", "pixbuf", TREE_ICON_COLUMN, NULL);
1250 add_text_renderer(GTK_TREE_VIEW(_w.treeview), column1, "Profile", "text", TREE_TEXT_COLUMN, NULL);
1251 gtk_tree_view_append_column(GTK_TREE_VIEW(_w.treeview), column1);
1252 //add_text_column(GTK_TREE_VIEW(_w.treeview), "Comment", "text", TOOLTIP_COLUMN, NULL);
1253
1254 _w.notebook = GTK_NOTEBOOK(get_widget("notebook"));
1255
1256 _w.b_new = get_widget("tree_button_new");
1257 g_signal_connect(_w.b_new, "clicked", G_CALLBACK(on_button_new_clicked), this);
1258
1259 _w.b_copy = get_widget("tree_button_copy");
1260 g_signal_connect(_w.b_copy, "clicked", G_CALLBACK(on_button_copy_clicked), this);
1261
1262 _w.b_delete = get_widget("tree_button_delete");
1263 g_signal_connect(_w.b_delete, "clicked", G_CALLBACK(on_button_delete_clicked), this);
1264
1265 _w.b_up = get_widget("tree_button_up");
1266 g_signal_connect(_w.b_up, "clicked", G_CALLBACK(on_button_up_clicked), this);
1267
1268 _w.b_down = get_widget("tree_button_down");
1269 g_signal_connect(_w.b_down, "clicked", G_CALLBACK(on_button_down_clicked), this);
1270
1271 _w.b_expand = get_widget("tree_button_expand");
1272 g_signal_connect(_w.b_expand, "clicked", G_CALLBACK(on_button_expand_clicked), this);
1273
1274 _w.b_collapse = get_widget("tree_button_collapse");
1275 g_signal_connect(_w.b_collapse, "clicked", G_CALLBACK(on_button_collapse_clicked), this);
1276
1277 _w.b_ok = get_widget("dialog_button_ok");
1278 g_signal_connect(_w.b_ok, "clicked", G_CALLBACK(on_button_ok_clicked), this);
1279
1280 _w.b_close = get_widget("dialog_button_close");
1281 g_signal_connect(_w.b_close, "clicked", G_CALLBACK(on_button_close_clicked), this);
1282
1283 /* setup the selection handler */
1284 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(_w.treeview));
1285 gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
1286 g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(on_tree_selection_changed), this);
1287
1288 _w.entry_profile_name = GTK_ENTRY(get_widget("system_entry_profile_name"));
1289 _w.on_profile_name_changed_id = g_signal_connect(_w.entry_profile_name, "changed", G_CALLBACK(on_profile_name_changed), this);
1290
1291 _w.textview_comment = GTK_TEXT_VIEW(get_widget("system_textview_comment"));
1292 _w.textbuffer_comment = gtk_text_view_get_buffer(_w.textview_comment);
1293 _w.on_comment_changed_id = g_signal_connect(_w.textbuffer_comment, "changed", G_CALLBACK(on_comment_changed), this);
1294
1295 wire_check_button("tape_file", "/tapes/", "media_check_button_tape", "media_filechooserbutton_tape", "media_button_tape_clear");
1296 wire_check_button("audio_file", NULL, "media_check_button_audio", "media_filechooserbutton_audio", "media_button_audio_clear");
1297 wire_check_button("disk_1", "/disks/", "media_check_button_disk1", "media_filechooserbutton_disk1", "media_button_disk1_clear");
1298 wire_check_button("disk_2", "/disks/", "media_check_button_disk2", "media_filechooserbutton_disk2", "media_button_disk2_clear");
1299 wire_check_button("disk_3", "/disks/", "media_check_button_disk3", "media_filechooserbutton_disk3", "media_button_disk3_clear");
1300 wire_check_button("disk_4", "/disks/", "media_check_button_disk4", "media_filechooserbutton_disk4", "media_button_disk4_clear");
1301 wire_check_button("hard_disk_1", NULL, "media_check_button_hd1", "media_filechooserbutton_hd1", "media_button_hd1_clear");
1302 wire_check_button("hard_disk_2", NULL, "media_check_button_hd2", "media_filechooserbutton_hd2", "media_button_hd2_clear");
1303
1304 _w.check_button_display_scale = GTK_CHECK_BUTTON(get_widget("display_check_button_scale"));
1305 _w.check_button_display_effects = GTK_CHECK_BUTTON(get_widget("display_check_button_effects"));
1306 _w.check_button_display_mem_access = GTK_CHECK_BUTTON(get_widget("display_check_button_mem_access"));
1307 _w.check_button_display_debug = GTK_CHECK_BUTTON(get_widget("display_check_button_debug"));
1308 _w.spin_button_display_scale = GTK_SPIN_BUTTON(get_widget("display_spin_button_scale"));
1309 _w.combobox_display_effects = GTK_COMBO_BOX(get_widget("display_combobox_effects"));
1310 _w.combobox_display_mem_access = GTK_COMBO_BOX(get_widget("display_combobox_mem_access"));
1311 _w.combobox_display_debug = GTK_COMBO_BOX(get_widget("display_combobox_debug"));
1312 wire_check_button("display_scale", _w.check_button_display_scale, G_CALLBACK(on_display_check_button_toggled), GTK_WIDGET(_w.spin_button_display_scale));
1313 wire_check_button("display_effects", _w.check_button_display_effects, G_CALLBACK(on_display_check_button_toggled), GTK_WIDGET(_w.combobox_display_effects));
1314 wire_check_button("display_mem_access", _w.check_button_display_mem_access, G_CALLBACK(on_display_check_button_toggled), GTK_WIDGET(_w.combobox_display_mem_access));
1315 wire_check_button("display_debug", _w.check_button_display_debug, G_CALLBACK(on_display_check_button_toggled), GTK_WIDGET(_w.combobox_display_debug));
1316 _w.on_display_scale_value_changed_id = g_signal_connect(_w.spin_button_display_scale, "value-changed", G_CALLBACK(on_display_scale_value_changed), this);
1317 _w.on_display_effects_changed_id = g_signal_connect(_w.combobox_display_effects, "changed", G_CALLBACK(on_display_effects_changed), this);
1318 _w.on_display_mem_access_changed_id = g_signal_connect(_w.combobox_display_mem_access, "changed", G_CALLBACK(on_display_mem_access_changed), this);
1319 _w.on_display_debug_changed_id = g_signal_connect(_w.combobox_display_debug, "changed", G_CALLBACK(on_display_debug_changed), this);
1320
1321 _w.check_button_d004 = GTK_CHECK_BUTTON(get_widget("kc85_checkbutton_d004"));
1322 _w.check_button_f8_rom = GTK_CHECK_BUTTON(get_widget("kc85_checkbutton_f8_rom"));
1323 _w.check_button_busdrivers = GTK_CHECK_BUTTON(get_widget("kc85_checkbutton_busdrivers"));
1324 _w.combobox_d004 = GTK_COMBO_BOX(get_widget("kc85_combobox_d004"));
1325 _w.combobox_f8_rom = GTK_COMBO_BOX(get_widget("kc85_combobox_f8_rom"));
1326 _w.spin_button_busdrivers = GTK_SPIN_BUTTON(get_widget("kc85_spinbutton_busdrivers"));
1327 wire_check_button("d004", _w.check_button_d004, G_CALLBACK(on_kc85_settings_check_button_toggled), GTK_WIDGET(_w.combobox_d004));
1328 wire_check_button("d004_f8", _w.check_button_f8_rom, G_CALLBACK(on_kc85_settings_check_button_toggled), GTK_WIDGET(_w.combobox_f8_rom));
1329 wire_check_button("busdrivers", _w.check_button_busdrivers, G_CALLBACK(on_kc85_settings_check_button_toggled), GTK_WIDGET(_w.spin_button_busdrivers));
1330
1331 _w.on_kc85_d004_changed_id = g_signal_connect(_w.combobox_d004, "changed", G_CALLBACK(on_kc85_d004_changed), this);
1332 _w.on_kc85_f8_rom_changed_id = g_signal_connect(_w.combobox_f8_rom, "changed", G_CALLBACK(on_kc85_f8_rom_changed), this);
1333 _w.on_kc85_busdrivers_changed_id = g_signal_connect(_w.spin_button_busdrivers, "value-changed", G_CALLBACK(on_kc85_busdrivers_changed), this);
1334
1335 for (int a = 0;a < NR_OF_MODULES;a++) {
1336 _w.combobox_module[a] = GTK_COMBO_BOX(get_widget("modules_combobox_module", a + 1));
1337 _w.on_module_changed_id[a] = g_signal_connect(_w.combobox_module[a], "changed", G_CALLBACK(on_module_changed), this);
1338 bind_list_model_column(_w.combobox_module[a], MODULES_NAME_COLUMN, NULL);
1339 }
1340 _w.check_button_modules = GTK_CHECK_BUTTON(get_widget("modules_check_button"));
1341 g_signal_connect(_w.check_button_modules, "toggled", G_CALLBACK(on_modules_check_button_toggled), this);
1342
1343 _w.liststore_system = get_system_list_model();
1344 _w.combobox_system_type = GTK_COMBO_BOX(get_widget("system_combobox_system_type"));
1345 gtk_combo_box_set_model(_w.combobox_system_type, GTK_TREE_MODEL(_w.liststore_system));
1346 bind_list_model_column(_w.combobox_system_type, 0, NULL);
1347 _w.on_system_type_changed_id = g_signal_connect(_w.combobox_system_type, "changed", G_CALLBACK(on_system_type_changed), this);
1348
1349 _w.combobox_system_variant = GTK_COMBO_BOX(get_widget("system_combobox_system_variant"));
1350 bind_list_model_column(_w.combobox_system_variant, 0, NULL);
1351
1352 _w.on_system_variant_changed_id = g_signal_connect(_w.combobox_system_variant, "changed", G_CALLBACK(on_system_variant_changed), this);
1353
1354 _w.check_button_system_variant = GTK_CHECK_BUTTON(get_widget("system_check_button_system_variant"));
1355 g_signal_connect(_w.check_button_system_variant, "toggled", G_CALLBACK(on_system_variant_check_button_toggled), this);
1356
1357 for (int a = 0;a < NR_OF_ROMS;a++) {
1358 _w.roms_label[a] = GTK_LABEL(get_widget("roms_label_rom", a + 1));
1359 _w.roms_comboboxentry[a] = GTK_COMBO_BOX_ENTRY(get_widget("roms_comboboxentry_rom", a + 1));
1360 _w.roms_open_button[a] = GTK_BUTTON(get_widget("roms_open_button_rom", a + 1));
1361 _w.roms_check_button[a] = GTK_CHECK_BUTTON(get_widget("roms_check_button_rom", a + 1));
1362 wire_check_button("rom_dummy",
1363 _w.roms_check_button[a],
1364 G_CALLBACK(on_roms_settings_check_button_toggled),
1365 GTK_WIDGET(_w.roms_comboboxentry[a]),
1366 GTK_WIDGET(_w.roms_open_button[a]));
1367
1368 g_signal_connect(_w.roms_open_button[a], "clicked", G_CALLBACK(on_rom_open_clicked), this);
1369 _w.on_rom_changed_id[a] = g_signal_connect(_w.roms_comboboxentry[a], "changed", G_CALLBACK(on_rom_changed), this);
1370
1371 GtkListStore *store = gtk_list_store_new(ROMS_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
1372 gtk_combo_box_set_model(GTK_COMBO_BOX(_w.roms_comboboxentry[a]), GTK_TREE_MODEL(store));
1373 gtk_combo_box_entry_set_text_column(_w.roms_comboboxentry[a], 0);
1374 g_object_unref(store);
1375 }
1376
1377 _w.entry_network_ip_address = GTK_ENTRY(get_widget("ip_address_entry"));
1378 set_preferences_key(G_OBJECT(_w.entry_network_ip_address), "network_ip_address");
1379 _w.on_network_changed_id[0] = g_signal_connect(_w.entry_network_ip_address, "changed", G_CALLBACK(on_network_changed), this);
1380 wire_check_button("network_ip_address", GTK_CHECK_BUTTON(get_widget("ip_address_checkbutton")), G_CALLBACK(on_network_settings_check_button_toggled), GTK_WIDGET(_w.entry_network_ip_address));
1381
1382 _w.entry_network_netmask = GTK_ENTRY(get_widget("netmask_entry"));
1383 set_preferences_key(G_OBJECT(_w.entry_network_netmask), "network_netmask");
1384 _w.on_network_changed_id[1] = g_signal_connect(_w.entry_network_netmask, "changed", G_CALLBACK(on_network_changed), this);
1385 wire_check_button("network_netmask", GTK_CHECK_BUTTON(get_widget("netmask_checkbutton")), G_CALLBACK(on_network_settings_check_button_toggled), GTK_WIDGET(_w.entry_network_netmask));
1386
1387 _w.entry_network_gateway = GTK_ENTRY(get_widget("gateway_entry"));
1388 set_preferences_key(G_OBJECT(_w.entry_network_gateway), "network_gateway");
1389 _w.on_network_changed_id[2] = g_signal_connect(_w.entry_network_gateway, "changed", G_CALLBACK(on_network_changed), this);
1390 wire_check_button("network_gateway", GTK_CHECK_BUTTON(get_widget("gateway_checkbutton")), G_CALLBACK(on_network_settings_check_button_toggled), GTK_WIDGET(_w.entry_network_gateway));
1391
1392 _w.entry_network_dns_server = GTK_ENTRY(get_widget("dns_server_entry"));
1393 set_preferences_key(G_OBJECT(_w.entry_network_dns_server), "network_dns_server");
1394 _w.on_network_changed_id[3] = g_signal_connect(_w.entry_network_dns_server, "changed", G_CALLBACK(on_network_changed), this);
1395 wire_check_button("network_dns_server", GTK_CHECK_BUTTON(get_widget("dns_server_checkbutton")), G_CALLBACK(on_network_settings_check_button_toggled), GTK_WIDGET(_w.entry_network_dns_server));
1396
1397 collapse_tree();
1398
1399 init_dialog(NULL, NULL);
1400 }
1401
1402 void
save(void)1403 OptionsWindow::save(void) {
1404 string config_name = _current_profile->get_config_name();
1405
1406 Preferences::instance()->save();
1407
1408 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(_w.treeview));
1409 gtk_tree_model_foreach(model, tree_model_foreach_func_delete, this);
1410
1411 /* select parent if we have deleted the currently selected profile */
1412 if (Preferences::instance()->find_profile(config_name.c_str()) == NULL) {
1413 GtkTreeIter iter;
1414 GtkTreeModel *model = get_selected_tree_iter(&iter);
1415 if (model != NULL) {
1416 GtkTreeIter parent;
1417 if (gtk_tree_model_iter_parent(model, &parent, &iter)) {
1418 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(_w.treeview));
1419 gtk_tree_selection_select_iter(selection, &parent);
1420 }
1421 }
1422 }
1423
1424 // delete in reverse order. otherwise we invalidate the collected path strings
1425 for (list<string>::reverse_iterator it = _delete_path.rbegin();it != _delete_path.rend();it++) {
1426 GtkTreeIter iter;
1427 if (gtk_tree_model_get_iter_from_string(model, &iter, (*it).c_str())) {
1428 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
1429 }
1430 }
1431 _delete_path.clear();
1432
1433 hide();
1434 }
1435
1436 void
reject(void)1437 OptionsWindow::reject(void) {
1438 Preferences::instance()->reject();
1439 apply_profile();
1440 hide();
1441 }
1442