2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <glib/gi18n.h>
21 #include "gtk/gtkui.hpp"
22 #include "framework/thememanager.hpp"
23 #include "gtk/gtkuisettings.hpp"
24 #include "settings.hpp"
25 #include "misc/printf.hpp"
27 #define GDASH_KEYSIM_WHAT_FOR "gdash-keysim-what-for"
28 #define GDASH_RESTAT_BOOL "gdash-restart-bool"
30 gboolean
SettingsWindow::keysim_button_keypress_event(GtkWidget
*widget
, GdkEventKey
*event
, gpointer data
) {
31 g_assert(event
->type
==GDK_KEY_PRESS
); /* must be true. */
32 gtk_dialog_response(GTK_DIALOG(widget
), event
->keyval
);
33 return TRUE
; /* and say that we processed the key. */
36 void SettingsWindow::keysim_button_clicked_cb(GtkWidget
*button
, gpointer data
) {
37 const char *what_for
=(const char *)g_object_get_data(G_OBJECT(button
), GDASH_KEYSIM_WHAT_FOR
);
38 int *keyval
=(int *) data
;
40 /* dialog which has its keypress event connected to the handler above */
41 GtkWidget
*dialog
=gtk_dialog_new_with_buttons(_("Select Key"), GTK_WINDOW(gtk_widget_get_toplevel(button
)),
42 GtkDialogFlags(GTK_DIALOG_MODAL
| GTK_DIALOG_NO_SEPARATOR
),
43 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
, NULL
);
44 GtkWidget
*table
= gtk_table_new(1,1, FALSE
);
45 gtk_table_set_row_spacings(GTK_TABLE(table
), 6);
46 gtk_table_set_col_spacings(GTK_TABLE(table
), 6);
47 gtk_container_set_border_width(GTK_CONTAINER(table
), 6);
48 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog
)->vbox
), table
);
49 gtk_table_attach_defaults(GTK_TABLE(table
), gd_label_new_leftaligned(_("Press key for action:")), 0, 1, 0, 1);
50 gtk_table_attach_defaults(GTK_TABLE(table
), gd_label_new_leftaligned(CPrintf("<b>%s</b>") % what_for
), 0, 1, 1, 2);
51 g_signal_connect(G_OBJECT(dialog
), "key_press_event", G_CALLBACK(keysim_button_keypress_event
), dialog
);
53 gtk_window_set_resizable(GTK_WINDOW(dialog
), FALSE
);
54 gtk_widget_show_all(dialog
);
55 int result
=gtk_dialog_run(GTK_DIALOG(dialog
));
57 /* if positive, it must be a keyval. gtk_response_cancel and gtk_response delete is negative. */
59 gtk_button_set_label(GTK_BUTTON(button
), gdk_keyval_name(*keyval
));
61 gtk_widget_destroy(dialog
);
64 GtkWidget
*SettingsWindow::gd_keysim_button(Setting
*setting
) {
65 char const *what_for
= setting
->name
;
66 int *keyval
= (int *) setting
->var
;
67 g_assert(keyval
!=NULL
);
69 /* the button shows the current value in its name */
70 GtkWidget
*button
= gtk_button_new_with_label(gdk_keyval_name(*keyval
));
71 g_signal_connect(G_OBJECT(button
), "clicked", G_CALLBACK(keysim_button_clicked_cb
), keyval
);
72 g_object_set_data(G_OBJECT(button
), GDASH_KEYSIM_WHAT_FOR
, (gpointer
) what_for
);
73 gtk_widget_set_tooltip_text(button
, CPrintf(_("Click here to set the key for action: %s")) % what_for
);
80 void SettingsWindow::bool_toggle(GtkWidget
*widget
, gpointer data
) {
81 bool *restart_bool
= (bool *)g_object_get_data(G_OBJECT(widget
), GDASH_RESTAT_BOOL
);
82 Setting
*setting
= static_cast<Setting
*>(data
);
83 bool *bl
= (bool *) setting
->var
;
85 *bl
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
));
86 if (setting
->restart
&& restart_bool
)
91 void SettingsWindow::int_change(GtkWidget
*widget
, gpointer data
) {
92 bool *restart_bool
= (bool *)g_object_get_data(G_OBJECT(widget
), GDASH_RESTAT_BOOL
);
93 Setting
*setting
= static_cast<Setting
*>(data
);
94 int *value
= (int *) setting
->var
;
95 *value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget
));
96 if (setting
->restart
&& restart_bool
)
101 void SettingsWindow::stringv_change(GtkWidget
*widget
, gpointer data
) {
102 bool *restart_bool
= (bool *)g_object_get_data(G_OBJECT(widget
), GDASH_RESTAT_BOOL
);
103 Setting
*setting
= static_cast<Setting
*>(data
);
104 int *ptr
= (int *) setting
->var
;
105 *ptr
= gtk_combo_box_get_active(GTK_COMBO_BOX(widget
));
106 /* if nothing selected (for some reason), set to zero. */
109 if (setting
->restart
&& restart_bool
)
110 *restart_bool
= true;
114 void SettingsWindow::theme_change(GtkWidget
*widget
, gpointer data
) {
115 bool *restart_bool
= (bool *)g_object_get_data(G_OBJECT(widget
), GDASH_RESTAT_BOOL
);
116 int *ptr
= (int *) data
;
117 *ptr
= gtk_combo_box_get_active(GTK_COMBO_BOX(widget
));
118 /* if nothing selected (for some reason), set to zero. */
122 *restart_bool
= true;
126 GtkWidget
*SettingsWindow::combo_box_new_from_stringv(const char **str
) {
127 GtkWidget
*combo
= gtk_combo_box_new_text();
128 for (unsigned i
=0; str
[i
]!=NULL
; i
++)
129 gtk_combo_box_append_text(GTK_COMBO_BOX(combo
), _(str
[i
])); // also translate
134 GtkWidget
*SettingsWindow::combo_box_new_from_themelist(std::vector
<std::string
> const &strings
) {
135 GtkWidget
*combo
= gtk_combo_box_new_text();
136 for (unsigned i
=0; i
!= strings
.size(); i
++) {
137 if (strings
[i
] == "")
138 gtk_combo_box_append_text(GTK_COMBO_BOX(combo
), _("[Default]"));
140 char *thm
= g_filename_display_basename(strings
[i
].c_str());
141 if (strrchr(thm
, '.')) /* remove extension */
142 *strrchr(thm
, '.')='\0';
143 gtk_combo_box_append_text(GTK_COMBO_BOX(combo
), thm
);
152 * @return true, if a restart is required by some setting changed
154 bool SettingsWindow::do_settings_dialog(Setting
*settings
, PixbufFactory
&pf
) {
155 bool request_restart
= false;
157 GtkWidget
*dialog
=gtk_dialog_new_with_buttons(_("GDash Preferences"), guess_active_toplevel(),
158 GTK_DIALOG_DESTROY_WITH_PARENT
, GTK_STOCK_CLOSE
, GTK_RESPONSE_ACCEPT
, NULL
);
159 gtk_dialog_set_has_separator(GTK_DIALOG(dialog
), FALSE
);
161 GtkWidget
*notebook
=gtk_notebook_new();
162 gtk_container_set_border_width(GTK_CONTAINER(notebook
), 9);
163 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog
)->vbox
), notebook
);
165 std::vector
<std::string
> themes
;
167 load_themes_list(pf
, themes
, themenum
);
170 GtkWidget
*table
= NULL
;
171 for (unsigned i
=0; settings
[i
].name
!= NULL
; i
++) {
173 GtkWidget
*widget
= NULL
;
175 switch (settings
[i
].type
) {
177 table
= gtk_table_new(1, 1, FALSE
);
178 gtk_container_set_border_width(GTK_CONTAINER(table
), 9);
179 gtk_table_set_row_spacings(GTK_TABLE(table
), 6);
180 gtk_table_set_col_spacings(GTK_TABLE(table
), 12);
181 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), table
, gd_label_new_leftaligned(settings
[i
].name
));
186 widget
= gtk_check_button_new();
187 gtk_widget_set_tooltip_text(widget
, _(settings
[i
].description
));
188 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), *(bool *)settings
[i
].var
);
189 gtk_table_attach(GTK_TABLE(table
), widget
, 1, 2, row
, row
+1, GtkAttachOptions(GTK_EXPAND
|GTK_FILL
), GtkAttachOptions(0), 0, 0);
190 g_signal_connect(G_OBJECT(widget
), "toggled", G_CALLBACK(SettingsWindow::bool_toggle
), &settings
[i
]);
194 widget
= gtk_spin_button_new_with_range(0, 100, 5);
195 gtk_widget_set_tooltip_text(widget
, _(settings
[i
].description
));
196 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget
), *(int *)settings
[i
].var
);
197 g_signal_connect(G_OBJECT(widget
), "value-changed", G_CALLBACK(SettingsWindow::int_change
), &settings
[i
]);
198 gtk_table_attach(GTK_TABLE(table
), widget
, 1, 2, row
, row
+1, GtkAttachOptions(GTK_EXPAND
|GTK_FILL
), GtkAttachOptions(0), 0, 0);
202 widget
=SettingsWindow::combo_box_new_from_stringv(settings
[i
].stringv
);
203 gtk_widget_set_tooltip_text(widget
, _(settings
[i
].description
));
204 gtk_combo_box_set_active(GTK_COMBO_BOX(widget
), *(int *)settings
[i
].var
);
205 g_signal_connect(G_OBJECT(widget
), "changed", G_CALLBACK(SettingsWindow::stringv_change
), &settings
[i
]);
206 gtk_table_attach(GTK_TABLE(table
), widget
, 1, 2, row
, row
+1, GtkAttachOptions(GTK_EXPAND
|GTK_FILL
), GtkAttachOptions(0), 0, 0);
210 widget
=SettingsWindow::combo_box_new_from_themelist(themes
);
211 gtk_widget_set_tooltip_text(widget
, _(settings
[i
].description
));
212 gtk_combo_box_set_active(GTK_COMBO_BOX(widget
), themenum
);
213 g_signal_connect(G_OBJECT(widget
), "changed", G_CALLBACK(SettingsWindow::theme_change
), &themenum
);
214 gtk_table_attach(GTK_TABLE(table
), widget
, 1, 2, row
, row
+1, GtkAttachOptions(GTK_EXPAND
|GTK_FILL
), GtkAttachOptions(0), 0, 0);
218 widget
= gd_keysim_button(&settings
[i
]);
219 gtk_widget_set_tooltip_text(widget
, _(settings
[i
].description
));
220 gtk_table_attach(GTK_TABLE(table
), widget
, 1, 2, row
, row
+1, GtkAttachOptions(GTK_EXPAND
|GTK_FILL
), GtkAttachOptions(0), 0, 0);
225 g_object_set_data(G_OBJECT(widget
), GDASH_RESTAT_BOOL
, &request_restart
);
226 GtkWidget
*label
= gd_label_new_leftaligned(_(settings
[i
].name
));
227 gtk_table_attach(GTK_TABLE(table
), label
, 0, 1, row
, row
+1, GtkAttachOptions(GTK_EXPAND
|GTK_FILL
), GtkAttachOptions(0), 0, 0);
228 gtk_label_set_mnemonic_widget(GTK_LABEL(label
), widget
);
234 gtk_widget_show_all(dialog
);
235 gtk_dialog_run(GTK_DIALOG(dialog
));
237 gtk_widget_destroy(dialog
);
239 gd_theme
= themes
[themenum
];
241 return request_restart
;