1 /*
2 * gsdlg.c - Simple GTK dialog wrapper
3 *
4 * Copyright 2007-2008 Jeff Pohlmeyer <yetanothergeek(at)gmail(dot)com>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 *
22 */
23
24 #ifndef GSDLG_ALL_IN_ONE
25 #include "gsdlg.h"
26 #endif
27
28 #include <stdlib.h>
29
30 #include <geanyplugin.h>
31
32
33 #define TextKey "gsdlg_TextKey_bc4871f4e3478ab5234e28432460a6b8"
34 #define DataKey "gsdlg_DataKey_bc4871f4e3478ab5234e28432460a6b8"
35
36
destroy_slist_and_data(gpointer list)37 static void destroy_slist_and_data(gpointer list)
38 {
39 GSList*p;
40 for (p=list; p ; p=p->next) {
41 if (p->data) g_free(p->data);
42 p->data=NULL;
43 }
44 g_slist_free(list);
45 }
46
47
48
gsdlg_textarea(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr label)49 void gsdlg_textarea(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr label)
50 {
51 GtkWidget*tv;
52 GtkWidget*sw;
53 GtkWidget*frm;
54 g_return_if_fail(dlg);
55 tv=gtk_text_view_new();
56 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(tv),GTK_WRAP_WORD_CHAR);
57 gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(tv),FALSE);
58 if (value) {
59 GtkTextBuffer *tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tv));
60 gtk_text_buffer_set_text (tb, value, -1);
61 }
62 sw=gtk_scrolled_window_new(NULL, NULL);
63 gtk_widget_set_size_request(sw, gdk_screen_get_width(gdk_screen_get_default())/3,
64 gdk_screen_get_height(gdk_screen_get_default())/10);
65 gtk_container_add(GTK_CONTAINER(sw),tv);
66 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
67 frm=gtk_frame_new(label);
68 gtk_frame_set_shadow_type(GTK_FRAME(frm), GTK_SHADOW_ETCHED_IN);
69 gtk_container_add(GTK_CONTAINER(frm),sw);
70 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(dlg)),frm);
71 g_object_set_data_full(G_OBJECT(tv), TextKey, g_strdup(key), g_free);
72 }
73
74
75
make_modal(GtkWidget * w,GtkWidget * p)76 static void make_modal(GtkWidget *w, GtkWidget*p)
77 {
78 gtk_window_set_modal(GTK_WINDOW(w), TRUE);
79 gtk_window_set_transient_for(GTK_WINDOW(w),GTK_WINDOW(p));
80 }
81
82
83
file_dlg_map(GtkWidget * w,gpointer user_data)84 static void file_dlg_map(GtkWidget *w, gpointer user_data)
85 {
86 GtkWidget* entry=gtk_window_get_focus (GTK_WINDOW(w));
87 if (entry && GTK_IS_ENTRY(entry)) {
88 gtk_entry_set_text(GTK_ENTRY(entry), (gchar*)user_data);
89 }
90 }
91
92
93
file_btn_clicked(GtkButton * button,gpointer user_data)94 static void file_btn_clicked(GtkButton *button, gpointer user_data)
95 {
96 GtkWidget*dlg;
97 const gchar *fn=NULL;
98 gchar *bn=NULL;
99 gint resp;
100 dlg=gtk_file_chooser_dialog_new(_("Open file"),
101 gsdlg_toplevel, GTK_FILE_CHOOSER_ACTION_OPEN,
102 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
103 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
104 gtk_window_set_title(GTK_WINDOW(dlg), _("Select file"));
105 make_modal(dlg, gtk_widget_get_toplevel(GTK_WIDGET(user_data)));
106 fn=gtk_entry_get_text(GTK_ENTRY(user_data));
107 if (fn && *fn) {
108 if (g_file_test(fn,G_FILE_TEST_IS_REGULAR)) {
109 gchar *rp=utils_get_real_path(fn);
110 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dlg), rp);
111 if (rp) g_free(rp);
112 } else {
113 if (g_file_test(fn,G_FILE_TEST_IS_DIR)) {
114 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dlg), fn);
115 } else {
116 gchar *dn=g_path_get_dirname(fn);
117 if (g_file_test(dn,G_FILE_TEST_IS_DIR)) {
118 gchar *rp=utils_get_real_path(dn);
119 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dlg), rp);
120 if (rp) g_free(rp);
121 bn=g_path_get_basename(fn);
122 g_signal_connect(G_OBJECT(dlg), "map", G_CALLBACK(file_dlg_map), bn);
123 }
124 g_free(dn);
125 }
126 }
127 }
128 resp=gtk_dialog_run(GTK_DIALOG(dlg));
129 if (resp == GTK_RESPONSE_ACCEPT) {
130 gchar *fcfn=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
131 if (fcfn) {
132 gtk_entry_set_text(GTK_ENTRY(user_data), fcfn);
133 g_free(fcfn);
134 }
135 }
136 gtk_widget_destroy(dlg);
137 if (bn) { g_free(bn); }
138 }
139
140
141
gsdlg_file(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr label)142 void gsdlg_file(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr label)
143 {
144 GtkWidget *hbox;
145 GtkWidget *input;
146 GtkWidget*frm;
147 GtkWidget*btn;
148 g_return_if_fail(dlg);
149 input=gtk_entry_new();
150 if (value) { gtk_entry_set_text(GTK_ENTRY(input),value); }
151 btn=gtk_button_new_with_label(_("Browse..."));
152 g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(file_btn_clicked), input);
153 hbox=gtk_hbox_new(FALSE,FALSE);
154 gtk_box_pack_start(GTK_BOX(hbox), input,TRUE,TRUE,1);
155 gtk_box_pack_start(GTK_BOX(hbox), btn,FALSE,FALSE,1);
156 frm=gtk_frame_new(label);
157 gtk_frame_set_shadow_type(GTK_FRAME(frm), GTK_SHADOW_ETCHED_IN);
158 gtk_container_add(GTK_CONTAINER(frm),hbox);
159 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(dlg)),frm);
160 g_object_set_data_full(G_OBJECT(input), TextKey, g_strdup(key), g_free);
161 }
162
163
164
color_btn_clicked(GtkButton * button,gpointer user_data)165 static void color_btn_clicked(GtkButton *button, gpointer user_data)
166 {
167 GtkWidget*dlg;
168 GtkColorSelectionDialog *csdlg;
169 const gchar *cn=NULL;
170 gint resp;
171 GdkColor rgb;
172
173 dlg=gtk_color_selection_dialog_new (_("Select Color"));
174 csdlg=GTK_COLOR_SELECTION_DIALOG(dlg);
175 make_modal(dlg, gtk_widget_get_toplevel(GTK_WIDGET(user_data)));
176 cn=gtk_entry_get_text(GTK_ENTRY(user_data));
177 if (cn && *cn && gdk_color_parse(cn,&rgb)) {
178 gtk_color_selection_set_current_color(
179 GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(csdlg)), &rgb);
180 }
181 resp=gtk_dialog_run(GTK_DIALOG(dlg));
182 if (resp == GTK_RESPONSE_OK) {
183 gchar *rv=NULL;
184 gtk_color_selection_get_current_color(
185 GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(csdlg)), &rgb);
186 rv=g_strdup_printf("#%2.2X%2.2X%2.2X",rgb.red/256,rgb.green/256,rgb.blue/256);
187 gtk_entry_set_text(GTK_ENTRY(user_data), rv);
188 g_free(rv);
189 }
190 gtk_widget_destroy(dlg);
191 }
192
193
194
gsdlg_color(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr prompt)195 void gsdlg_color(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr prompt)
196 {
197 GtkWidget *hbox;
198 GtkWidget *input;
199 GtkWidget *label;
200 GtkWidget*btn;
201 g_return_if_fail(dlg);
202 input=gtk_entry_new();
203 if (value) { gtk_entry_set_text(GTK_ENTRY(input),value); }
204 btn=gtk_button_new_with_label(_("Choose..."));
205 g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(color_btn_clicked), input);
206 hbox=gtk_hbox_new(FALSE,FALSE);
207 if (prompt) {
208 label=gtk_label_new(prompt);
209 gtk_box_pack_start(GTK_BOX(hbox), label,FALSE,FALSE,1);
210 }
211 gtk_box_pack_start(GTK_BOX(hbox), input,TRUE,TRUE,1);
212 gtk_box_pack_start(GTK_BOX(hbox), btn,FALSE,FALSE,1);
213 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(dlg)),hbox);
214 g_object_set_data_full(G_OBJECT(input), TextKey, g_strdup(key), g_free);
215 }
216
217
218
font_btn_clicked(GtkButton * button,gpointer user_data)219 static void font_btn_clicked(GtkButton *button, gpointer user_data)
220 {
221 GtkWidget*dlg;
222 const gchar *fn=NULL;
223 gint resp;
224 fn=gtk_entry_get_text(GTK_ENTRY(user_data));
225 dlg=gtk_font_selection_dialog_new(_("Select Font"));
226 make_modal(dlg, gtk_widget_get_toplevel(GTK_WIDGET(user_data)));
227 if (fn && *fn) {
228 gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(dlg),fn);
229 }
230 resp=gtk_dialog_run(GTK_DIALOG(dlg));
231 if (resp==GTK_RESPONSE_OK) {
232 gchar *gfn=gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(dlg));
233 if (gfn) {
234 gtk_entry_set_text(GTK_ENTRY(user_data), gfn);
235 g_free(gfn);
236 }
237 }
238 gtk_widget_destroy(dlg);
239 }
240
241
242
gsdlg_font(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr prompt)243 void gsdlg_font(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr prompt)
244 {
245 GtkWidget *hbox;
246 GtkWidget *input;
247 GtkWidget *label;
248 GtkWidget*btn;
249 g_return_if_fail(dlg);
250 input=gtk_entry_new();
251 if (value) { gtk_entry_set_text(GTK_ENTRY(input),value); }
252 btn=gtk_button_new_with_label(_("Select..."));
253 g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(font_btn_clicked), input);
254 hbox=gtk_hbox_new(FALSE,FALSE);
255 if (prompt) {
256 label=gtk_label_new(prompt);
257 gtk_box_pack_start(GTK_BOX(hbox), label,FALSE,FALSE,1);
258 }
259 gtk_box_pack_start(GTK_BOX(hbox), input,TRUE,TRUE,1);
260 gtk_box_pack_start(GTK_BOX(hbox), btn,FALSE,FALSE,1);
261 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(dlg)),hbox);
262 g_object_set_data_full(G_OBJECT(input), TextKey, g_strdup(key), g_free);
263 }
264
265
266
gsdlg_entry(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr prompt,gboolean masked)267 static void gsdlg_entry(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr prompt, gboolean masked)
268 {
269 GtkWidget *hbox;
270 GtkWidget *input;
271 GtkWidget *label;
272 g_return_if_fail(dlg);
273 input=gtk_entry_new();
274 if (value) { gtk_entry_set_text(GTK_ENTRY(input),value); }
275 label=gtk_label_new(prompt);
276 hbox=gtk_hbox_new(FALSE,FALSE);
277 gtk_box_pack_start(GTK_BOX(hbox), label,FALSE,FALSE,1);
278 gtk_box_pack_start(GTK_BOX(hbox), input,TRUE,TRUE,1);
279 gtk_entry_set_visibility(GTK_ENTRY(input), !masked);
280 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(dlg)),hbox);
281 g_object_set_data_full(G_OBJECT(input), TextKey, g_strdup(key), g_free);
282 }
283
284
gsdlg_text(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr label)285 void gsdlg_text(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr label)
286 {
287 gsdlg_entry(dlg, key, value, label, FALSE);
288 }
289
290
291
gsdlg_password(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr label)292 void gsdlg_password(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr label)
293 {
294 gsdlg_entry(dlg, key, value, label, TRUE);
295 }
296
297
gsdlg_checkbox(GtkDialog * dlg,GsDlgStr key,gboolean value,GsDlgStr label)298 void gsdlg_checkbox(GtkDialog *dlg, GsDlgStr key, gboolean value, GsDlgStr label)
299 {
300 GtkWidget *cb=NULL;
301 g_return_if_fail(dlg);
302 cb=gtk_check_button_new_with_label(label);
303 g_object_set_data_full(G_OBJECT(cb),TextKey,g_strdup(key), g_free);
304 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb),value);
305 gtk_container_add(GTK_CONTAINER(GTK_CONTAINER(gtk_dialog_get_content_area(dlg))),cb);
306 }
307
308
309
310 typedef struct _KeySearchData {
311 const gchar *key;
312 GType type;
313 GtkWidget*value;
314 } KeySearchData;
315
316
317
find_widget_by_key_cb(GtkWidget * w,gpointer p)318 static void find_widget_by_key_cb(GtkWidget *w, gpointer p)
319 {
320 KeySearchData*kv=p;
321 if (kv->value) {return;}
322
323 if (G_OBJECT_TYPE(G_OBJECT(w)) == kv->type) {
324 gchar*key=g_object_get_data(G_OBJECT(w), TextKey);
325 if (key && g_str_equal(kv->key,key)) { kv->value=w; }
326 }
327 }
328
329
find_widget_by_key(GtkDialog * dlg,GType type,GsDlgStr key)330 static GtkWidget *find_widget_by_key(GtkDialog *dlg, GType type, GsDlgStr key)
331 {
332 KeySearchData kv={NULL,0,NULL};
333 g_return_val_if_fail(dlg, NULL);
334 kv.key=key;
335 kv.type=type;
336 gtk_container_foreach(GTK_CONTAINER(GTK_CONTAINER(gtk_dialog_get_content_area(dlg))),find_widget_by_key_cb,&kv);
337 return kv.value;
338 }
339
340
select_radio(GtkWidget * parent,GsDlgStr value)341 static void select_radio(GtkWidget*parent, GsDlgStr value)
342 {
343 GList *kids=gtk_container_get_children(GTK_CONTAINER(parent));
344 if (!kids) { return;}
345 if (kids->data && GTK_IS_RADIO_BUTTON(kids->data)) {
346 GList *kid=kids;
347 for (kid=kids; kid; kid=kid->next) {
348 if (kid->data && GTK_IS_RADIO_BUTTON(kid->data)) {
349 gchar*kval=g_object_get_data(G_OBJECT(kid->data),TextKey);
350 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(kid->data),
351 kval && g_str_equal(kval,value));
352 }
353 }
354 }
355 }
356
357
358
gsdlg_group(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr label)359 void gsdlg_group(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr label)
360 {
361 GtkWidget*frm;
362 GtkWidget*vbox;
363
364 g_return_if_fail(dlg);
365 frm=find_widget_by_key(dlg,GTK_TYPE_FRAME,key);
366 if (frm) {
367 vbox=gtk_bin_get_child(GTK_BIN(frm));
368 gtk_frame_set_label(GTK_FRAME(frm), label);
369 } else {
370 frm=gtk_frame_new(label);
371 vbox=gtk_vbox_new(FALSE,FALSE);
372 gtk_container_add(GTK_CONTAINER(frm),vbox);
373 gtk_container_add(GTK_CONTAINER(GTK_CONTAINER(gtk_dialog_get_content_area(dlg))),frm);
374 }
375
376 /* Frame holds keyname, vbox holds default value */
377 g_object_set_data_full(G_OBJECT(frm), TextKey, g_strdup(key), g_free);
378 g_object_set_data_full(G_OBJECT(vbox), TextKey, g_strdup(value), g_free);
379 select_radio(vbox,value);
380 }
381
382
383
384
gsdlg_radio(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr label)385 void gsdlg_radio(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr label)
386 {
387 GtkWidget *frm=NULL;
388 GtkWidget *vbox=NULL;
389 GList *kids=NULL;
390 GtkWidget *rb=NULL;
391 gchar *defval;
392 g_return_if_fail(dlg);
393 frm=find_widget_by_key(dlg,GTK_TYPE_FRAME,key);
394 if (frm) {
395 vbox=gtk_bin_get_child(GTK_BIN(frm));
396 if (vbox) {
397 kids=gtk_container_get_children(GTK_CONTAINER(vbox));
398 }
399 } else {
400 gsdlg_group(dlg,key,value,NULL);
401 frm=find_widget_by_key(dlg,GTK_TYPE_FRAME,key);
402 vbox=gtk_bin_get_child(GTK_BIN(frm));
403 }
404 if (kids) {
405 rb=gtk_radio_button_new_with_label_from_widget (kids->data,label);
406 g_list_free(kids);
407 } else {
408 rb=gtk_radio_button_new_with_label(NULL, label);
409 }
410 g_object_set_data_full(G_OBJECT(rb),TextKey, g_strdup(value), g_free);
411 gtk_container_add(GTK_CONTAINER(vbox), rb);
412 defval=g_object_get_data(G_OBJECT(vbox),TextKey);
413 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb),
414 value && defval && g_str_equal(defval,value));
415 }
416
417
418
419
select_combo(GtkWidget * parent,GsDlgStr value)420 static void select_combo(GtkWidget*parent, GsDlgStr value)
421 {
422 gint n=0;
423 GSList*values=g_object_get_data(G_OBJECT(parent), DataKey);
424 GSList*v;
425 for (v=values; v; v=v->next) {
426 if (v->data && g_str_equal(v->data, value)) {break;}
427 n++;
428 }
429 gtk_combo_box_set_active(GTK_COMBO_BOX(parent), n);
430 }
431
432
433 typedef struct _ComboWidgets {
434 GtkWidget *label;
435 GtkWidget *combo;
436 } ComboWidgets;
437
438
gsdlg_select(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr label)439 void gsdlg_select(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr label)
440 {
441 GtkWidget *hbox=NULL;
442 ComboWidgets*cw=NULL;
443 g_return_if_fail(dlg);
444 hbox=find_widget_by_key(dlg,GTK_TYPE_HBOX, key);
445 if (hbox) {
446 cw=g_object_get_data(G_OBJECT(hbox), DataKey);
447 gtk_label_set_text(GTK_LABEL(cw->label), label);
448 } else {
449 hbox=gtk_hbox_new(FALSE,FALSE);
450 cw=g_malloc0(sizeof(ComboWidgets));
451 g_object_set_data_full(G_OBJECT(hbox),DataKey,cw,g_free);
452 cw->combo=gtk_combo_box_text_new();
453 cw->label=gtk_label_new(label);
454 gtk_box_pack_start(GTK_BOX(hbox), cw->label,FALSE,FALSE,4);
455 gtk_box_pack_start(GTK_BOX(hbox), cw->combo,TRUE,TRUE,1);
456 gtk_container_add(GTK_CONTAINER(GTK_CONTAINER(gtk_dialog_get_content_area(dlg))),hbox);
457 }
458 /* Hbox holds keyname, combo holds default value */
459 g_object_set_data_full(G_OBJECT(hbox), TextKey, g_strdup(key), g_free);
460 g_object_set_data_full(G_OBJECT(cw->combo), TextKey, g_strdup(value), g_free);
461 select_combo(cw->combo,value);
462 }
463
464
465
gsdlg_option(GtkDialog * dlg,GsDlgStr key,GsDlgStr value,GsDlgStr label)466 void gsdlg_option(GtkDialog *dlg, GsDlgStr key, GsDlgStr value, GsDlgStr label)
467 {
468 GtkWidget *hbox=NULL;
469 GSList *values=NULL;
470 ComboWidgets*cw=NULL;
471 gchar*defval=NULL;
472 g_return_if_fail(dlg);
473
474 hbox=find_widget_by_key(dlg,GTK_TYPE_HBOX, key);
475 if (!hbox) {
476 gsdlg_select(dlg,key,value,NULL);
477 hbox=find_widget_by_key(dlg,GTK_TYPE_HBOX, key);
478 }
479 cw=g_object_get_data(G_OBJECT(hbox), DataKey);
480 values=g_object_steal_data(G_OBJECT(cw->combo), DataKey);
481 values=g_slist_append(values, g_strdup(value));
482 g_object_set_data_full(G_OBJECT(cw->combo), DataKey, values, destroy_slist_and_data);
483 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cw->combo), label);
484 defval=g_object_get_data(G_OBJECT(cw->combo), TextKey);
485 if (value && defval && g_str_equal(value,defval)) {
486 select_combo(cw->combo,value);
487 }
488 }
489
490
491
492
gsdlg_label(GtkDialog * dlg,GsDlgStr text)493 void gsdlg_label(GtkDialog *dlg, GsDlgStr text)
494 {
495 GtkWidget *lab=NULL;
496 g_return_if_fail(dlg);
497 lab=gtk_label_new(text);
498 gtk_container_add(GTK_CONTAINER(GTK_CONTAINER(gtk_dialog_get_content_area(dlg))), lab);
499 gtk_misc_set_alignment(GTK_MISC(lab), 0.0f, 0.0f);
500 }
501
502
503
gsdlg_hr(GtkDialog * dlg)504 void gsdlg_hr(GtkDialog *dlg)
505 {
506 g_return_if_fail(dlg);
507 gtk_container_add(GTK_CONTAINER(GTK_CONTAINER(gtk_dialog_get_content_area(dlg))), gtk_hseparator_new());
508 }
509
510
511
gsdlg_heading(GtkDialog * dlg,GsDlgStr text)512 void gsdlg_heading(GtkDialog *dlg, GsDlgStr text)
513 {
514 g_return_if_fail(dlg);
515 gsdlg_hr(dlg);
516 gsdlg_label(dlg,text);
517 }
518
519 GSDLG_API GtkWindow* gsdlg_toplevel=NULL;
520
521
522
gsdlg_new(GsDlgStr title,GsDlgStr * btns)523 GtkDialog *gsdlg_new(GsDlgStr title, GsDlgStr*btns)
524 {
525 gint i;
526 GtkDialog *dlg;
527 dlg=GTK_DIALOG(gtk_dialog_new());
528 if (gsdlg_toplevel) {
529 gtk_window_set_destroy_with_parent(GTK_WINDOW(dlg), TRUE);
530 gtk_window_set_transient_for(GTK_WINDOW(dlg),gsdlg_toplevel);
531 gtk_window_set_modal(GTK_WINDOW(dlg), TRUE);
532 }
533 for (i=0; btns[i]; i++) {
534 gtk_dialog_add_button(GTK_DIALOG(dlg),btns[i],i);
535 }
536 gtk_box_set_spacing(GTK_BOX(GTK_CONTAINER(gtk_dialog_get_content_area(dlg))), 4);
537 gtk_container_set_border_width(GTK_CONTAINER(dlg), 4);
538 gtk_window_set_title(GTK_WINDOW(dlg),title);
539 return dlg;
540 }
541
542
543
widgets_foreach(GtkWidget * w,gpointer p)544 static void widgets_foreach(GtkWidget *w, gpointer p)
545 {
546 gchar*key=g_object_get_data(G_OBJECT(w),TextKey);
547 if (key && *key) {
548 const gchar*value=NULL;
549 if (GTK_IS_ENTRY(w)) {
550 value=gtk_entry_get_text(GTK_ENTRY(w));
551 } else if (GTK_IS_RADIO_BUTTON(w)) {
552 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){
553 value=key;
554 key=g_object_get_data(
555 G_OBJECT(gtk_widget_get_parent(gtk_widget_get_parent(w))), TextKey);
556 }
557 } else if (GTK_IS_CHECK_BUTTON(w)) {
558 value=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))?"1":"0";
559 } else if (GTK_IS_COMBO_BOX(w)) {
560 GSList*values=g_object_get_data(G_OBJECT(w),DataKey);
561 key=g_object_get_data(G_OBJECT(gtk_widget_get_parent(w)), TextKey);
562 if (values) {
563 gint n=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
564 if (n>=0) { value=g_slist_nth_data(values, n); }
565 }
566 } else if (GTK_IS_TEXT_VIEW(w)) {
567 GtkTextBuffer *tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
568 GtkTextIter a,z;
569 gtk_text_buffer_get_start_iter(tb,&a);
570 gtk_text_buffer_get_end_iter(tb,&z);
571 value=gtk_text_buffer_get_text (tb,&a,&z,TRUE);
572 }
573 if (value&&*value) {
574 GHashTable*h=p;
575 g_hash_table_insert(h,g_strdup(key),g_strdup(value));
576 }
577 }
578 if (GTK_IS_CONTAINER(w)) {
579 gtk_container_foreach(GTK_CONTAINER(w),widgets_foreach,p);
580 }
581 }
582
583
584 static GsDlgRunHook gsdlg_run_hook=NULL;
585
586
587 #ifndef DIALOG_LIB
gsdlg_set_run_hook(GsDlgRunHook cb)588 void gsdlg_set_run_hook(GsDlgRunHook cb)
589 {
590 gsdlg_run_hook=cb;
591 }
592 #endif
593
594
gsdlg_run(GtkDialog * dlg,gint * btn,gpointer user_data)595 GHashTable* gsdlg_run(GtkDialog *dlg, gint *btn, gpointer user_data)
596 {
597 GHashTable* results=NULL;
598 gint dummy;
599 g_return_val_if_fail(dlg, NULL);
600 gtk_widget_show_all(GTK_WIDGET(dlg));
601 if (!btn) { btn=&dummy; }
602 if (gsdlg_run_hook) { gsdlg_run_hook(TRUE,user_data); }
603 *btn=gtk_dialog_run(GTK_DIALOG(dlg));
604 if (gsdlg_run_hook) { gsdlg_run_hook(FALSE,user_data); }
605 if (*btn<0) *btn=-1;
606 results=g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
607 gtk_container_foreach(GTK_CONTAINER(GTK_CONTAINER(gtk_dialog_get_content_area(dlg))),widgets_foreach,results);
608 gtk_widget_hide(GTK_WIDGET(dlg));
609 return results;
610 }
611
612
613
614