1 /*
2  * Copyright 2008 Department of Mathematical Sciences, New Mexico State University
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * DEPARTMENT OF MATHEMATICAL SCIENCES OR NEW MEXICO STATE UNIVERSITY BE
18  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "gbdfed.h"
24 #include "grayswatch.h"
25 
26 static GtkWidget *pref_dialog;
27 static GtkWidget *pref_unicode;
28 static GtkWidget *pref_adobe;
29 static GtkWidget *pref_cursor_font;
30 static GtkWidget *pref_apply;
31 
32 static GtkWidget *pref_fsel_dialog;
33 static gboolean pref_fsel_unicode;
34 
35 static GtkWidget *pref_color;
36 static GtkWidget *pref_color_dialog;
37 static GtkWidget *pref_color_win[16];
38 
39 static gbdfed_options_t tmp_opts;
40 
41 static void
pref_toggle(GtkWidget * w,gpointer data)42 pref_toggle(GtkWidget *w, gpointer data)
43 {
44     gint which;
45     gboolean val = FALSE;
46 
47     which = GPOINTER_TO_INT(data);
48     if (which != 10)
49       val = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
50 
51     switch (which) {
52       case 0: tmp_opts.backups = val; break;
53       case 1: tmp_opts.font_opts.correct_metrics = val; break;
54       case 2: tmp_opts.font_opts.pad_cells = val; break;
55       case 3: tmp_opts.font_opts.keep_unencoded = val; break;
56       case 4: tmp_opts.font_opts.keep_comments = val; break;
57       case 5:
58         if (val == TRUE)
59           tmp_opts.font_opts.otf_flags &= ~FT_LOAD_NO_HINTING;
60         else
61           tmp_opts.font_opts.otf_flags |= FT_LOAD_NO_HINTING;
62         break;
63       case 6: tmp_opts.sbit = val; break;
64       case 7:
65         tmp_opts.show_cap_height = val;
66         break;
67       case 8:
68         tmp_opts.show_x_height = val;
69         break;
70       case 9:
71         /*
72          * Toggle the Really Exit dialog.
73          */
74         tmp_opts.really_exit = val;
75         break;
76       case 10:
77         tmp_opts.pixel_size = (unsigned int)
78             gtk_combo_box_get_active(GTK_COMBO_BOX(w)) + 2;
79         break;
80     }
81 
82     /*
83      * Enable the Apply button.
84      */
85     gtk_widget_set_sensitive(pref_apply, TRUE);
86 }
87 
88 static void
pref_eol(GtkWidget * w,gpointer data)89 pref_eol(GtkWidget *w, gpointer data)
90 {
91     tmp_opts.font_opts.eol = gtk_combo_box_get_active(GTK_COMBO_BOX(w)) + 1;
92 
93     /*
94      * Enable the Apply button.
95      */
96     gtk_widget_set_sensitive(pref_apply, TRUE);
97 }
98 
99 static GtkWidget *
pref_make_general_page()100 pref_make_general_page()
101 {
102     GtkWidget *table, *button, *hbox, *tmp, *omenu, *frame, *vbox;
103 
104     vbox = gtk_vbox_new(FALSE, 10);
105 
106     /*
107      * Create the load/save option selection.
108      */
109     frame = gtk_frame_new("Load/Save");
110     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
111 
112     table = gtk_table_new(2, 3, FALSE);
113 
114     button = gtk_check_button_new_with_label("Make Backups");
115     if (tmp_opts.backups)
116       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
117     (void) g_signal_connect(G_OBJECT(button), "toggled",
118                             G_CALLBACK(pref_toggle),
119                             GINT_TO_POINTER(0));
120     gtk_table_attach(GTK_TABLE(table), button, 0, 1, 0, 1,
121                      GTK_FILL|GTK_EXPAND, GTK_FILL, 5, 5);
122 
123     button = gtk_check_button_new_with_label("Correct Metrics");
124     if (tmp_opts.font_opts.correct_metrics)
125       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
126     (void) g_signal_connect(G_OBJECT(button), "toggled",
127                             G_CALLBACK(pref_toggle),
128                             GINT_TO_POINTER(1));
129     gtk_table_attach(GTK_TABLE(table), button, 1, 2, 0, 1,
130                      GTK_FILL|GTK_EXPAND, GTK_FILL, 5, 5);
131 
132     button = gtk_check_button_new_with_label("Pad Character Cells");
133     if (tmp_opts.font_opts.pad_cells)
134       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
135     (void) g_signal_connect(G_OBJECT(button), "toggled",
136                             G_CALLBACK(pref_toggle),
137                             GINT_TO_POINTER(2));
138     gtk_table_attach(GTK_TABLE(table), button, 2, 3, 0, 1,
139                      GTK_FILL|GTK_EXPAND, GTK_FILL, 5, 5);
140 
141     button = gtk_check_button_new_with_label("Keep Unencoded Glyphs");
142     if (tmp_opts.font_opts.keep_unencoded)
143       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
144     (void) g_signal_connect(G_OBJECT(button), "toggled",
145                             G_CALLBACK(pref_toggle),
146                             GINT_TO_POINTER(3));
147     gtk_table_attach(GTK_TABLE(table), button, 0, 1, 1, 2,
148                      GTK_FILL|GTK_EXPAND, GTK_FILL, 5, 5);
149 
150     button = gtk_check_button_new_with_label("Keep Comments");
151     if (tmp_opts.font_opts.keep_comments)
152       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
153     (void) g_signal_connect(G_OBJECT(button), "toggled",
154                             G_CALLBACK(pref_toggle),
155                             GINT_TO_POINTER(4));
156     gtk_table_attach(GTK_TABLE(table), button, 1, 2, 1, 2,
157                      GTK_FILL|GTK_EXPAND, GTK_FILL, 5, 5);
158 
159     hbox = gtk_hbox_new(FALSE, 0);
160     tmp = gtk_label_new("EOL:");
161     gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 0);
162 
163     omenu = gtk_combo_box_new_text();
164     gtk_combo_box_append_text(GTK_COMBO_BOX(omenu), "Unix [LF]");
165     gtk_combo_box_append_text(GTK_COMBO_BOX(omenu), "WIN/DOS [CRLF]");
166     gtk_combo_box_append_text(GTK_COMBO_BOX(omenu), "MAC [CR]");
167     gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), tmp_opts.font_opts.eol - 1);
168     (void) g_signal_connect(G_OBJECT(omenu), "changed",
169                             G_CALLBACK(pref_eol), 0);
170 
171     gtk_box_pack_start(GTK_BOX(hbox), omenu, TRUE, TRUE, 0);
172 
173     gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 1, 2,
174                      GTK_FILL|GTK_EXPAND, GTK_FILL, 5, 5);
175 
176     gtk_container_add(GTK_CONTAINER(frame), table);
177 
178     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
179 
180     frame = gtk_frame_new("OpenType");
181     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
182 
183     button = gtk_check_button_new_with_label("Hint Glyphs");
184     if (!(tmp_opts.font_opts.otf_flags & FT_LOAD_NO_HINTING))
185       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
186 #ifdef HAVE_FREETYPE
187     (void) g_signal_connect(G_OBJECT(button), "toggled",
188                             G_CALLBACK(pref_toggle),
189                             GINT_TO_POINTER(5));
190 #else
191     /*
192      * No Freetype support means no point in being able to toggle this
193      * widget.
194      */
195     gtk_widget_set_sensitive(button, FALSE);
196 #endif
197     gtk_container_add(GTK_CONTAINER(frame), button);
198 
199     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
200 
201     frame = gtk_frame_new("SBIT");
202     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
203 
204     button = gtk_check_button_new_with_label("Generate SBIT Metrics File");
205     if (tmp_opts.sbit)
206       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
207     (void) g_signal_connect(G_OBJECT(button), "toggled",
208                             G_CALLBACK(pref_toggle),
209                             GINT_TO_POINTER(6));
210     gtk_container_add(GTK_CONTAINER(frame), button);
211 
212     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
213 
214     return vbox;
215 }
216 
217 static void
pref_change_size(GtkWidget * w,gpointer data)218 pref_change_size(GtkWidget *w, gpointer data)
219 {
220     gint v, which = GPOINTER_TO_INT(data);
221 
222     v = (gint) gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
223 
224     switch (which) {
225       case 0: tmp_opts.font_opts.point_size = (int) v; break;
226       case 1: tmp_opts.font_opts.resolution_x = (int) v; break;
227       case 2: tmp_opts.font_opts.resolution_y = (int) v; break;
228     }
229 
230     /*
231      * Enable the apply button.
232      */
233     gtk_widget_set_sensitive(pref_apply, TRUE);
234 }
235 
236 /*
237  * Synchronize the vertical resolution with the horizontal resolution.
238  */
239 static void
pref_sync_res(GtkWidget * w,GdkEventFocus * ev,gpointer data)240 pref_sync_res(GtkWidget *w, GdkEventFocus *ev, gpointer data)
241 {
242     gfloat v;
243     GtkSpinButton *b;
244 
245     b = GTK_SPIN_BUTTON(data);
246     v = (gfloat) gtk_spin_button_get_value(b);
247 
248     if (v != (gfloat) gtk_spin_button_get_value(GTK_SPIN_BUTTON(w))) {
249         gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v);
250 
251         /*
252          * Enable the apply button.
253          */
254         gtk_widget_set_sensitive(pref_apply, TRUE);
255     }
256 }
257 
258 static void
pref_set_spacing(GtkWidget * w,gpointer data)259 pref_set_spacing(GtkWidget *w, gpointer data)
260 {
261     tmp_opts.font_opts.font_spacing = GPOINTER_TO_INT(data);
262 
263     /*
264      * Enable the apply button.
265      */
266     gtk_widget_set_sensitive(pref_apply, TRUE);
267 }
268 
269 static void
pref_set_cursor_font(GtkWidget * w,gpointer data)270 pref_set_cursor_font(GtkWidget *w, gpointer data)
271 {
272     tmp_opts.font_opts.cursor_font =
273         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
274 
275     /*
276      * Enable the apply button.
277      */
278     gtk_widget_set_sensitive(pref_apply, TRUE);
279 }
280 
281 static void
pref_color_response(GtkDialog * d,gint response,gpointer data)282 pref_color_response(GtkDialog *d, gint response, gpointer data)
283 {
284     gint i;
285 
286     if (response == GTK_RESPONSE_REJECT) {
287         /*
288          * Replace the colors with those found in the original
289          * options.
290          */
291         memcpy(&tmp_opts.colors, &options.colors,
292                sizeof(unsigned short) * 20);
293 
294         if (tmp_opts.font_opts.bits_per_pixel == 2) {
295             for (i = 0; i < 4; i++)
296               grayswatch_set_gray(GRAYSWATCH(pref_color_win[i]),
297                                   tmp_opts.colors[i]);
298         } else {
299             for (i = 0; i < 16; i++)
300               grayswatch_set_gray(GRAYSWATCH(pref_color_win[i]),
301                                   tmp_opts.colors[i + 4]);
302         }
303     } else if (response == GTK_RESPONSE_CLOSE)
304       gtk_widget_hide(GTK_WIDGET(data));
305 }
306 
307 static void
pref_color_update_color(GtkWidget * w,gint color,gpointer data)308 pref_color_update_color(GtkWidget *w, gint color, gpointer data)
309 {
310     gint which = GPOINTER_TO_INT(data);
311 
312     if (tmp_opts.font_opts.bits_per_pixel == 2)
313       tmp_opts.colors[which] = color;
314     else if (tmp_opts.font_opts.bits_per_pixel == 4)
315       tmp_opts.colors[which + 4] = color;
316 
317     /*
318      * Make sure the Apply button is enabled.
319      */
320     gtk_widget_set_sensitive(pref_apply, TRUE);
321 }
322 
323 static void
pref_select_colors(GtkWidget * w,gpointer data)324 pref_select_colors(GtkWidget *w, gpointer data)
325 {
326     GtkWidget *hbox;
327     gint i;
328 
329     if (pref_color_dialog == 0) {
330 
331         pref_color_dialog = gtk_dialog_new();
332         (void) g_signal_connect(G_OBJECT(pref_color_dialog), "delete_event",
333                                 G_CALLBACK(gtk_widget_hide), 0);
334         (void) g_signal_connect(G_OBJECT(pref_color_dialog), "response",
335                                 G_CALLBACK(pref_color_response),
336                                 (gpointer) pref_color_dialog);
337         gtk_window_set_resizable(GTK_WINDOW(pref_color_dialog), TRUE);
338 
339         hbox = gtk_hbox_new(FALSE, 0);
340 
341         for (i = 0; i < 16; i++) {
342             pref_color_win[i] = grayswatch_new(tmp_opts.colors[i + 4]);
343             g_signal_connect(G_OBJECT(pref_color_win[i]), "value-changed",
344                              G_CALLBACK(pref_color_update_color),
345                              GINT_TO_POINTER(i));
346             gtk_widget_set_size_request(pref_color_win[i], 50, 75);
347             gtk_box_pack_start(GTK_BOX(hbox), pref_color_win[i],
348                                FALSE, FALSE, 0);
349         }
350 
351         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(pref_color_dialog)->vbox),
352                           hbox);
353 
354         /*
355          * Add the buttons.
356          */
357         gtk_dialog_add_buttons(GTK_DIALOG(pref_color_dialog),
358                                GTK_STOCK_REVERT_TO_SAVED,
359                                GTK_RESPONSE_REJECT,
360                                GTK_STOCK_CLOSE,
361                                GTK_RESPONSE_CLOSE, NULL);
362 
363         gtk_dialog_set_default_response(GTK_DIALOG(pref_color_dialog),
364                                         GTK_RESPONSE_CLOSE);
365 
366         gtk_widget_show_all(pref_color_dialog);
367     }
368 
369     /*
370      * If selecting colors for 2 bits-per-pixel, hide all but the first 4.
371      * Set the first 4 colors depending on the bits-per-pixel value.
372      */
373     for (i = 0; i < 16; i++) {
374         /*
375          * We don't want setting the gray values to trigger the signal.
376          * That causes the Apply button to be made sensitive.
377          */
378         grayswatch_block_signal(GRAYSWATCH(pref_color_win[i]), TRUE);
379         if (tmp_opts.font_opts.bits_per_pixel == 2 && i >= 4)
380           gtk_widget_hide(pref_color_win[i]);
381         else {
382             if (i < 4) {
383                 if (tmp_opts.font_opts.bits_per_pixel == 2)
384                   grayswatch_set_gray(GRAYSWATCH(pref_color_win[i]),
385                                       tmp_opts.colors[i]);
386                 else
387                   grayswatch_set_gray(GRAYSWATCH(pref_color_win[i]),
388                                       tmp_opts.colors[i + 4]);
389             } else
390               gtk_widget_show(pref_color_win[i]);
391         }
392         grayswatch_block_signal(GRAYSWATCH(pref_color_win[i]), FALSE);
393     }
394 
395     /*
396      * Center the dialog and show it.
397      */
398     guiutil_show_dialog_centered(pref_color_dialog, pref_dialog);
399 }
400 
401 static void
pref_set_bpp(GtkWidget * w,gpointer data)402 pref_set_bpp(GtkWidget *w, gpointer data)
403 {
404     gboolean on;
405 
406     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)) == FALSE)
407       return;
408 
409     tmp_opts.font_opts.bits_per_pixel = GPOINTER_TO_INT(data);
410     on = (tmp_opts.font_opts.bits_per_pixel == 1 ||
411           tmp_opts.font_opts.bits_per_pixel == 8) ? FALSE : TRUE;
412 
413     if (pref_color_dialog != 0 && GTK_WIDGET_VISIBLE(pref_color_dialog)) {
414         if (tmp_opts.font_opts.bits_per_pixel == 1 ||
415             tmp_opts.font_opts.bits_per_pixel == 8)
416           gtk_widget_hide(pref_color_dialog);
417         else
418           pref_select_colors(w, data);
419     }
420 
421     gtk_widget_set_sensitive(pref_color, on);
422 
423     /*
424      * Enable the apply button.
425      */
426     gtk_widget_set_sensitive(pref_apply, TRUE);
427 }
428 
429 static GtkWidget *
pref_make_newfont_page()430 pref_make_newfont_page()
431 {
432     GtkWidget *label, *table, *button, *hbox, *vbox, *frame, *tmp;
433     GtkAdjustment *adj;
434 
435     vbox = gtk_vbox_new(FALSE, 10);
436 
437     /*
438      * Create the font size selection.
439      */
440     frame = gtk_frame_new("Font Size");
441     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
442 
443     table = gtk_table_new(3, 2, FALSE);
444 
445     label = gtk_label_new("Point Size:");
446     gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
447     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
448                      GTK_FILL, GTK_FILL, 5, 0);
449 
450     label = gtk_label_new("Horizontal Resolution:");
451     gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
452     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
453                      GTK_FILL, GTK_FILL, 5, 5);
454 
455     label = gtk_label_new("Vertical Resolution:");
456     gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
457     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3,
458                      GTK_FILL, GTK_FILL, 5, 5);
459 
460     /*
461      * Make the spinboxes for the point size and resolutions.
462      */
463     adj = (GtkAdjustment *) gtk_adjustment_new(0.0, 4.0, 256.0, 1.0, 2.0, 0.0);
464     button = gtk_spin_button_new(adj, 1.0, 0);
465     gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(button), TRUE);
466     gtk_spin_button_set_value(GTK_SPIN_BUTTON(button),
467                               (gfloat) tmp_opts.font_opts.point_size);
468     gtk_widget_set_size_request(button, 100, -1);
469     (void) g_signal_connect(G_OBJECT(button), "changed",
470                             G_CALLBACK(pref_change_size),
471                             GINT_TO_POINTER(0));
472     gtk_table_attach(GTK_TABLE(table), button, 1, 2, 0, 1,
473                      GTK_FILL, GTK_FILL, 5, 5);
474 
475     adj = (GtkAdjustment *) gtk_adjustment_new(0.0, 20.0, 1200.0,
476                                                1.0, 10.0, 0.0);
477     tmp = button = gtk_spin_button_new(adj, 1.0, 0);
478     gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(button), TRUE);
479     gtk_spin_button_set_value(GTK_SPIN_BUTTON(button),
480                               (gfloat) tmp_opts.font_opts.resolution_x);
481     gtk_widget_set_size_request(button, 100, -1);
482     (void) g_signal_connect(G_OBJECT(button), "changed",
483                             G_CALLBACK(pref_change_size),
484                             GINT_TO_POINTER(1));
485     gtk_table_attach(GTK_TABLE(table), button, 1, 2, 1, 2,
486                      GTK_FILL, GTK_FILL, 5, 5);
487 
488     adj = (GtkAdjustment *) gtk_adjustment_new(0.0, 20.0, 1200.0,
489                                                1.0, 10.0, 0.0);
490     button = gtk_spin_button_new(adj, 1.0, 0);
491     gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(button), TRUE);
492     gtk_spin_button_set_value(GTK_SPIN_BUTTON(button),
493                               (gfloat) tmp_opts.font_opts.resolution_y);
494     gtk_widget_set_size_request(button, 100, -1);
495     (void) g_signal_connect(G_OBJECT(button), "changed",
496                             G_CALLBACK(pref_change_size),
497                             GINT_TO_POINTER(2));
498     (void) g_signal_connect(G_OBJECT(button), "focus-in-event",
499                             G_CALLBACK(pref_sync_res), (gpointer) tmp);
500     gtk_table_attach(GTK_TABLE(table), button, 1, 2, 2, 3,
501                      GTK_FILL, GTK_FILL, 5, 5);
502 
503     gtk_container_add(GTK_CONTAINER(frame), table);
504 
505     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
506 
507     /*
508      * Create the spacing selection.
509      */
510     frame = gtk_frame_new("Spacing");
511     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
512 
513     hbox = gtk_hbox_new(FALSE, 0);
514 
515     button = gtk_radio_button_new_with_label(0, "Proportional");
516     if (tmp_opts.font_opts.font_spacing == BDF_PROPORTIONAL)
517       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
518     else
519       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
520     (void) g_signal_connect(G_OBJECT(button), "toggled",
521                             G_CALLBACK(pref_set_spacing),
522                             GINT_TO_POINTER(BDF_PROPORTIONAL));
523     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
524 
525     button =
526         gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button),
527                                                     "Monowidth");
528     if (tmp_opts.font_opts.font_spacing == BDF_MONOWIDTH)
529       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
530     else
531       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
532     (void) g_signal_connect(G_OBJECT(button), "toggled",
533                             G_CALLBACK(pref_set_spacing),
534                             GINT_TO_POINTER(BDF_MONOWIDTH));
535     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
536 
537     button =
538         gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button),
539                                                     "Character Cell");
540     if (tmp_opts.font_opts.font_spacing == BDF_CHARCELL)
541       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
542     else
543       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
544     (void) g_signal_connect(G_OBJECT(button), "toggled",
545                             G_CALLBACK(pref_set_spacing),
546                             GINT_TO_POINTER(BDF_CHARCELL));
547     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
548 
549     gtk_container_add(GTK_CONTAINER(frame), hbox);
550 
551     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
552 
553     /*
554      * Create the bits-per-pixel selection.
555      */
556     frame = gtk_frame_new("Bits Per Pixel");
557     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
558 
559     hbox = gtk_hbox_new(FALSE, 0);
560 
561     button = gtk_radio_button_new_with_label(0, "1 bpp");
562     if (tmp_opts.font_opts.bits_per_pixel == 1)
563       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
564     else
565       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
566     (void) g_signal_connect(G_OBJECT(button), "toggled",
567                             G_CALLBACK(pref_set_bpp),
568                             GINT_TO_POINTER(1));
569     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
570 
571     button =
572         gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button),
573                                                     "2 bpp");
574     if (tmp_opts.font_opts.bits_per_pixel == 2)
575       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
576     else
577       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
578     (void) g_signal_connect(G_OBJECT(button), "toggled",
579                             G_CALLBACK(pref_set_bpp),
580                             GINT_TO_POINTER(2));
581     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
582 
583     button =
584         gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button),
585                                                     "4 bpp");
586     if (tmp_opts.font_opts.bits_per_pixel == 4)
587       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
588     else
589       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
590     (void) g_signal_connect(G_OBJECT(button), "toggled",
591                             G_CALLBACK(pref_set_bpp),
592                             GINT_TO_POINTER(4));
593     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
594 
595     button =
596         gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button),
597                                                     "8 bpp");
598     if (tmp_opts.font_opts.bits_per_pixel == 8)
599       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
600     else
601       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
602     (void) g_signal_connect(G_OBJECT(button), "toggled",
603                             G_CALLBACK(pref_set_bpp),
604                             GINT_TO_POINTER(8));
605     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
606 
607     pref_color = gtk_button_new_with_label("Select Colors");
608     (void) g_signal_connect(G_OBJECT(pref_color), "clicked",
609                             G_CALLBACK(pref_select_colors), 0);
610     if (tmp_opts.font_opts.bits_per_pixel == 1)
611       gtk_widget_set_sensitive(pref_color, FALSE);
612 
613     gtk_box_pack_start(GTK_BOX(hbox), pref_color, FALSE, FALSE, 0);
614 
615     gtk_container_add(GTK_CONTAINER(frame), hbox);
616 
617     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
618 
619     frame = gtk_frame_new("Cursor Fonts");
620     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
621 
622     pref_cursor_font = gtk_check_button_new_with_label("Cursor Font");
623     if (tmp_opts.font_opts.cursor_font)
624       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pref_cursor_font),
625                                    TRUE);
626     (void) g_signal_connect(G_OBJECT(pref_cursor_font), "toggled",
627                             G_CALLBACK(pref_set_cursor_font), 0);
628     gtk_container_add(GTK_CONTAINER(frame), pref_cursor_font);
629     gtk_widget_set_sensitive(pref_cursor_font, FALSE);
630 
631     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
632 
633     return vbox;
634 }
635 
636 static void
pref_fgrid_mode(GtkWidget * w,gpointer data)637 pref_fgrid_mode(GtkWidget *w, gpointer data)
638 {
639     tmp_opts.overwrite_mode =
640         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
641 
642     /*
643      * Enable the Apply button.
644      */
645     gtk_widget_set_sensitive(pref_apply, TRUE);
646 }
647 
648 static void
pref_set_filename(GtkWidget * w,gpointer data)649 pref_set_filename(GtkWidget *w, gpointer data)
650 {
651     gchar *fname;
652 
653 
654     fname = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(w));
655 
656     if (pref_fsel_unicode)
657       gtk_entry_set_text(GTK_ENTRY(pref_unicode), fname);
658     else
659       gtk_entry_set_text(GTK_ENTRY(pref_adobe), fname);
660 
661     /*
662      * Enable the Apply button.
663      */
664     gtk_widget_set_sensitive(pref_apply, TRUE);
665 
666     /*
667      * Hide the dialog.
668      */
669     gtk_widget_hide(w);
670 }
671 
672 static void
handle_filename_response(GtkDialog * d,gint response,gpointer data)673 handle_filename_response(GtkDialog *d, gint response, gpointer data)
674 {
675     switch (response) {
676       case GTK_RESPONSE_ACCEPT:
677         pref_set_filename(GTK_WIDGET(d), data);
678         break;
679       case GTK_RESPONSE_CANCEL:
680         gtk_widget_hide(GTK_WIDGET(d));
681         break;
682     }
683 }
684 
685 static void
pref_show_fsel_dialog(GtkWidget * w,gpointer data)686 pref_show_fsel_dialog(GtkWidget *w, gpointer data)
687 {
688     pref_fsel_unicode = GPOINTER_TO_INT(data);
689 
690     if (pref_fsel_dialog == 0) {
691         pref_fsel_dialog = gtk_file_chooser_dialog_new("Glyph Name",
692                                                        GTK_WINDOW(pref_dialog),
693                                                        GTK_FILE_CHOOSER_ACTION_OPEN,
694                                                        GTK_STOCK_CANCEL,
695                                                        GTK_RESPONSE_CANCEL,
696                                                        GTK_STOCK_APPLY,
697                                                        GTK_RESPONSE_ACCEPT,
698                                                        NULL);
699         (void) g_signal_connect(G_OBJECT(pref_fsel_dialog), "delete_event",
700                                 G_CALLBACK(gtk_widget_hide), 0);
701 
702         (void) g_signal_connect(G_OBJECT(pref_fsel_dialog), "response",
703                                 G_CALLBACK(handle_filename_response),
704                                 NULL);
705     }
706 
707     /*
708      * Set the title of the dialog.
709      */
710     if (pref_fsel_unicode)
711       strcpy(buffer1, "Unicode Character Database Selection");
712     else
713       strcpy(buffer1, "Adobe Glyph Name File Selection");
714 
715     gtk_window_set_title(GTK_WINDOW(pref_fsel_dialog), buffer1);
716 
717     guiutil_show_dialog_centered(pref_fsel_dialog, pref_dialog);
718 
719     gtk_window_set_modal(GTK_WINDOW(pref_fsel_dialog), TRUE);
720 }
721 
722 static GtkWidget *
pref_make_edit_page()723 pref_make_edit_page()
724 {
725     gint i;
726     GtkWidget *vbox, *hbox, *frame, *button, *label, *omenu;
727     GtkWidget *tmp, *table;
728 
729     vbox = gtk_vbox_new(FALSE, 10);
730 
731     frame = gtk_frame_new("Font Grid Selection Paste");
732     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
733 
734     hbox = gtk_hbox_new(FALSE, 5);
735 
736     button = gtk_radio_button_new_with_label(0, "Overwrites");
737     if (tmp_opts.overwrite_mode)
738       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
739     else
740       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
741     (void) g_signal_connect(G_OBJECT(button), "toggled",
742                             G_CALLBACK(pref_fgrid_mode), 0);
743     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
744 
745     button =
746         gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button),
747                                                     "Inserts");
748     if (tmp_opts.overwrite_mode)
749       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
750     else
751       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
752     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
753 
754     gtk_container_add(GTK_CONTAINER(frame), hbox);
755 
756     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
757 
758     frame = gtk_frame_new("Glyph Editors");
759     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
760 
761     hbox = gtk_hbox_new(FALSE, 5);
762 
763     button = gtk_check_button_new_with_label("Show Cap Height");
764     if (tmp_opts.show_cap_height)
765       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
766     (void) g_signal_connect(G_OBJECT(button), "toggled",
767                             G_CALLBACK(pref_toggle),
768                             GINT_TO_POINTER(7));
769     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
770 
771     button = gtk_check_button_new_with_label("Show X Height");
772     if (tmp_opts.show_cap_height)
773       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
774     (void) g_signal_connect(G_OBJECT(button), "toggled",
775                             G_CALLBACK(pref_toggle),
776                             GINT_TO_POINTER(8));
777     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
778 
779     label = gtk_label_new("Pixel Size:");
780     gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
781     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
782 
783     omenu = gtk_combo_box_new_text();
784     for (i = 2; i < 21; i++) {
785         sprintf(buffer1, "%dx%d", i, i);
786         gtk_combo_box_append_text(GTK_COMBO_BOX(omenu), buffer1);
787     }
788     gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), tmp_opts.pixel_size - 2);
789     g_signal_connect(G_OBJECT(omenu), "changed",
790                      G_CALLBACK(pref_toggle), GINT_TO_POINTER(10));
791 
792     gtk_box_pack_start(GTK_BOX(hbox), omenu, TRUE, TRUE, 0);
793 
794     gtk_container_add(GTK_CONTAINER(frame), hbox);
795 
796     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
797 
798     frame = gtk_frame_new("Glyph Name Lists");
799     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
800 
801     table = gtk_table_new(2, 3, FALSE);
802 
803     label = gtk_label_new("Unicode Character Database:");
804     gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
805     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
806                      GTK_FILL, GTK_FILL, 5, 5);
807 
808     label = gtk_label_new("Adobe Glyph List:");
809     gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
810     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
811                      GTK_FILL, GTK_FILL, 5, 5);
812 
813     /*
814      * Add the entries.
815      */
816     tmp = pref_unicode = gtk_entry_new();
817     gtk_widget_set_size_request(tmp, 250, -1);
818     if (tmp_opts.unicode_name_file)
819       gtk_entry_set_text(GTK_ENTRY(pref_unicode), tmp_opts.unicode_name_file);
820     gtk_table_attach(GTK_TABLE(table), tmp, 1, 2, 0, 1,
821                      GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 5);
822 
823     tmp = pref_adobe = gtk_entry_new();
824     gtk_widget_set_size_request(tmp, 250, -1);
825     if (tmp_opts.adobe_name_file)
826       gtk_entry_set_text(GTK_ENTRY(pref_adobe), tmp_opts.adobe_name_file);
827     gtk_table_attach(GTK_TABLE(table), tmp, 1, 2, 1, 2,
828                      GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 5);
829 
830     /*
831      * Add the browse buttons.
832      */
833     button = gtk_button_new_with_label("Browse");
834     (void) g_signal_connect(G_OBJECT(button), "clicked",
835                             G_CALLBACK(pref_show_fsel_dialog),
836                             GINT_TO_POINTER(TRUE));
837     gtk_table_attach(GTK_TABLE(table), button, 2, 3, 0, 1,
838                      GTK_FILL, 0, 5, 0);
839     button = gtk_button_new_with_label("Browse");
840     (void) g_signal_connect(G_OBJECT(button), "clicked",
841                             G_CALLBACK(pref_show_fsel_dialog),
842                             GINT_TO_POINTER(FALSE));
843     gtk_table_attach(GTK_TABLE(table), button, 2, 3, 1, 2,
844                      GTK_FILL, 0, 5, 0);
845 
846     gtk_container_add(GTK_CONTAINER(frame), table);
847 
848     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
849 
850     return vbox;
851 }
852 
853 static GtkWidget *
pref_make_other_page()854 pref_make_other_page()
855 {
856     GtkWidget *frame, *button, *vbox;
857 
858     frame = gtk_frame_new("Dialogs");
859     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
860 
861     vbox = gtk_vbox_new(FALSE, 0);
862 
863     button = gtk_check_button_new_with_label("Show \"Really Exit\" Dialog");
864     if (tmp_opts.really_exit)
865       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
866     (void) g_signal_connect(G_OBJECT(button), "toggled",
867                             G_CALLBACK(pref_toggle),
868                             GUINT_TO_POINTER(9));
869     gtk_container_add(GTK_CONTAINER(frame), button);
870     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
871 
872     return vbox;
873 }
874 
875 static void
pref_apply_changes(void)876 pref_apply_changes(void)
877 {
878     gchar *fname;
879 
880     /*
881      * Take care of setting the file names for the glyph name lists.
882      */
883     fname = (gchar *) gtk_entry_get_text(GTK_ENTRY(pref_unicode));
884     if (fname != 0 && fname[0] != 0)
885       tmp_opts.unicode_name_file = g_strdup(fname);
886 
887     fname = (gchar *) gtk_entry_get_text(GTK_ENTRY(pref_adobe));
888     if (fname != 0 && fname[0] != 0)
889       tmp_opts.adobe_name_file = g_strdup(fname);
890 
891     /*
892      * If the name files are different, delete the old name files first.
893      */
894     if (options.unicode_name_file != 0 &&
895         options.unicode_name_file != tmp_opts.unicode_name_file)
896       g_free(options.unicode_name_file);
897     if (options.adobe_name_file != 0 &&
898         options.adobe_name_file != tmp_opts.adobe_name_file)
899       g_free(options.adobe_name_file);
900 
901     /*
902      * Copy the updated options over.
903      */
904     (void) memcpy((char *) &options, (char *) &tmp_opts,
905                   sizeof(gbdfed_options_t));
906 
907     /*
908      * Set the glyph edit options.
909      */
910     guigedit_show_cap_height(tmp_opts.show_cap_height);
911     guigedit_show_x_height(tmp_opts.show_x_height);
912     guigedit_set_pixel_size(tmp_opts.pixel_size);
913 
914     /*
915      * Disable the apply button.
916      */
917     gtk_widget_set_sensitive(pref_apply, FALSE);
918 }
919 
920 static void
pref_save(void)921 pref_save(void)
922 {
923     FILE *out;
924     gchar *home;
925     gint i;
926 
927     /*
928      * If any changes were made, do an update before saving.
929      */
930     if (GTK_WIDGET_SENSITIVE(pref_apply))
931       pref_apply_changes();
932 
933     if ((home = getenv("HOME")) == 0) {
934         guiutil_error_message(editors[0].shell,
935                               "Save Preferences: Unable to locate home directory.");
936         return;
937     }
938 
939     sprintf(buffer1, "%s/.gbdfedrc", home);
940     if ((out = fopen(buffer1, "w")) == 0) {
941         sprintf(buffer2, "Save Preferences: Unable to write to %s.", buffer1);
942         guiutil_error_message(editors[0].shell, buffer2);
943         return;
944     }
945 
946     /*
947      * First, write the gbdfed options.
948      */
949     fprintf(out, "#########################\n");
950     fprintf(out, "#\n# gbdfed options.\n#\n");
951     fprintf(out, "#########################\n\n");
952 
953     if (options.no_blanks)
954       fprintf(out, "skip_blank_pages true\n\n");
955     else
956       fprintf(out, "skip_blank_pages false\n\n");
957 
958     if (options.really_exit)
959       fprintf(out, "really_exit true\n\n");
960     else
961       fprintf(out, "really_exit false\n\n");
962     if (options.overwrite_mode)
963       fprintf(out, "grid_overwrite_mode true\n\n");
964     else
965       fprintf(out, "grid_overwrite_mode false\n\n");
966 
967     if (options.accelerator != 0)
968       fprintf(out, "close_accelerator %s\n\n",
969               options.accelerator);
970     if (options.accelerator_text != 0)
971       fprintf(out, "close_accelerator_text %s\n\n",
972               options.accelerator_text);
973 
974     if (options.unicode_name_file != 0)
975       fprintf(out, "name_file %s\n\n", options.unicode_name_file);
976 
977     if (options.adobe_name_file != 0)
978       fprintf(out, "adobe_name_file %s\n\n",
979               options.adobe_name_file);
980 
981     fprintf(out, "pixel_size %d\n\n", options.pixel_size);
982 
983     if (options.show_cap_height)
984       fprintf(out, "show_cap_height true\n\n");
985     else
986       fprintf(out, "show_cap_height false\n\n");
987 
988     if (options.show_x_height)
989       fprintf(out, "show_x_height true\n\n");
990     else
991       fprintf(out, "show_x_height false\n\n");
992 
993     if (options.sbit)
994       fprintf(out, "generate_sbit_metrics true\n\n");
995     else
996       fprintf(out, "generate_sbit_metrics false\n\n");
997 
998     /*
999      * Save the grayscales.
1000      */
1001     fprintf(out, "#\n# Grayscale values. Must be between 0 and 255.\n#\n");
1002     fprintf(out, "2bpp_grays ");
1003     for (i = 0; i < 4; i++) {
1004         fprintf(out, "%d", options.colors[i]);
1005         if (i + 1 < 4)
1006           putc(' ', out);
1007     }
1008     fprintf(out, "\n4bpp_grays ");
1009     for (i = 4; i < 20; i++) {
1010         fprintf(out, "%d", options.colors[i]);
1011         if (i + 1 < 20)
1012           putc(' ', out);
1013     }
1014     fprintf(out, "\n\n");
1015 
1016 #if 0
1017     /*
1018      * Save the colors.
1019      */
1020     fprintf(out, "#\n# Color values for 2 bits per pixel.\n#\n");
1021     for (i = 0; i < 4; i++) {
1022         /*
1023          * Do this to avoid writing negative values.
1024          */
1025         c = options.colors[i];
1026         fprintf(out, "color%d %d\n", i, c);
1027     }
1028 
1029     fprintf(out, "\n#\n# Color values for 4 bits per pixel.\n#\n");
1030     for (i = 4; i < 20; i++) {
1031         /*
1032          * Do this to avoid writing negative values.
1033          */
1034         c = options.colors[i];
1035         fprintf(out, "color%d %d\n", i, c);
1036     }
1037     putc('\n', out);
1038 #endif
1039 
1040     /*
1041      * The save the BDF specific options.
1042      */
1043     fprintf(out, "#########################\n");
1044     fprintf(out, "#\n# BDF font options.\n#\n");
1045     fprintf(out, "#########################\n\n");
1046     bdf_save_options(out, &options.font_opts);
1047     fclose(out);
1048 }
1049 
1050 static void
pref_response(GtkDialog * d,gint response,gpointer data)1051 pref_response(GtkDialog *d, gint response, gpointer data)
1052 {
1053     if (response == GTK_RESPONSE_APPLY)
1054       pref_apply_changes();
1055     else if (response == GTK_RESPONSE_OK)
1056       pref_save();
1057     else {
1058         /*
1059          * Make sure the color chooser dialog is hidden if it
1060          * happens to be up.
1061          */
1062         if (pref_color_dialog != 0 && GTK_WIDGET_VISIBLE(pref_color_dialog))
1063           gtk_widget_hide(pref_color_dialog);
1064 
1065         gtk_widget_hide(GTK_WIDGET(d));
1066     }
1067 }
1068 
1069 void
guiedit_show_preferences(GtkWidget * w,gpointer data)1070 guiedit_show_preferences(GtkWidget *w, gpointer data)
1071 {
1072     GtkWidget *dvbox, *nb, *button, *table, *label;
1073 
1074     if (pref_dialog == 0) {
1075         /*
1076          * Initialize the temporary options.
1077          */
1078         (void) memcpy((char *) &tmp_opts, (char *) &options,
1079                       sizeof(gbdfed_options_t));
1080 
1081         pref_dialog = gtk_dialog_new();
1082         (void) g_signal_connect(G_OBJECT(pref_dialog), "delete_event",
1083                                 G_CALLBACK(gtk_widget_hide), 0);
1084 
1085         sprintf(buffer1, "%s Preferences", g_get_prgname());
1086         gtk_window_set_title(GTK_WINDOW(pref_dialog), buffer1);
1087 
1088         dvbox = GTK_DIALOG(pref_dialog)->vbox;
1089 
1090         /*
1091          * Create the notebook that will contain the Preference tabs.
1092          */
1093         nb = gtk_notebook_new();
1094 
1095         /*
1096          * Create the General Options page.
1097          */
1098         label = gtk_label_new("General Options");
1099         table = pref_make_general_page();
1100         gtk_notebook_append_page(GTK_NOTEBOOK(nb), table, label);
1101 
1102         /*
1103          * Create the New Font Options page.
1104          */
1105         label = gtk_label_new("New Font Options");
1106         table = pref_make_newfont_page();
1107         gtk_notebook_append_page(GTK_NOTEBOOK(nb), table, label);
1108 
1109         /*
1110          * Create the Editing Options page.
1111          */
1112         label = gtk_label_new("Editing Options");
1113         table = pref_make_edit_page();
1114         gtk_notebook_append_page(GTK_NOTEBOOK(nb), table, label);
1115 
1116         /*
1117          * Create the Other Options page.
1118          */
1119         label = gtk_label_new("Other Options");
1120         table = pref_make_other_page();
1121         gtk_notebook_append_page(GTK_NOTEBOOK(nb), table, label);
1122 
1123         /*
1124          * Finally, add the notebook to the dialog's vbox.
1125          */
1126         gtk_container_add(GTK_CONTAINER(dvbox), nb);
1127 
1128         /*
1129          * Add the buttons at the bottom.
1130          */
1131         pref_apply = gtk_dialog_add_button(GTK_DIALOG(pref_dialog),
1132                                            GTK_STOCK_APPLY,
1133                                            GTK_RESPONSE_APPLY);
1134         gtk_widget_set_sensitive(pref_apply, FALSE);
1135 
1136         button = gtk_dialog_add_button(GTK_DIALOG(pref_dialog),
1137                                        GTK_STOCK_SAVE,
1138                                        GTK_RESPONSE_OK);
1139 
1140         button = gtk_dialog_add_button(GTK_DIALOG(pref_dialog),
1141                                        GTK_STOCK_CLOSE,
1142                                        GTK_RESPONSE_CLOSE);
1143         gtk_dialog_set_default_response(GTK_DIALOG(pref_dialog),
1144                                         GTK_RESPONSE_CLOSE);
1145 
1146         g_signal_connect(G_OBJECT(pref_dialog), "response",
1147                          G_CALLBACK(pref_response), 0);
1148 
1149         gtk_widget_show_all(dvbox);
1150     }
1151 
1152     guiutil_show_dialog_centered(pref_dialog, editors[0].shell);
1153 }
1154 
1155 void
guiedit_preference_cleanup()1156 guiedit_preference_cleanup()
1157 {
1158     /*
1159      * Does nothing at the moment.
1160      */
1161 }
1162