1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2
3 /*
4 * GImageView
5 * Copyright (C) 2001 Takuro Ashie
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 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * $Id: gimv_prefs_win.c,v 1.8 2004/09/22 15:37:11 makeinu Exp $
22 */
23
24 #include "gimv_prefs_win.h"
25
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "gimageview.h"
30
31 #include "gimv_hpaned.h"
32 #include "gtk2-compat.h"
33 #include "gimv_cell_pixmap.h"
34 #include "gimv_icon_stock.h"
35 #include "help.h"
36 #include "prefs.h"
37 #include "prefs_ui/prefs_ui_common.h"
38 #include "prefs_ui/prefs_ui_etc.h"
39 #include "prefs_ui/prefs_ui_movie.h"
40 #include "prefs_ui/prefs_ui_plugin.h"
41 #include "prefs_ui/prefs_ui_progs.h"
42 #include "prefs_ui/prefs_ui_imagewin.h"
43 #include "prefs_ui/prefs_ui_thumbalbum.h"
44 #include "prefs_ui/prefs_ui_thumbwin.h"
45
46
47 typedef struct PrefsWin_Tag {
48 GtkWidget *notebook;
49 GtkWidget *tree;
50 gboolean ok_pressed;
51 } PrefsWin;
52
53
54 typedef struct GimvPrefsWinPagePrivate_Tag
55 {
56 GimvPrefsWinPage *page;
57 GtkWidget *widget;
58 #ifndef ENABLE_TREEVIEW
59 GtkCTreeNode *node;
60 #endif /* ENABLE_TREEVIEW */
61 } GimvPrefsWinPagePrivate;
62
63
64 static GimvPrefsWinPage prefs_pages[] = {
65 {N_("/Infomation"), 0, NULL, NULL, gimvhelp_create_info_widget, NULL},
66 {N_("/Common"), 0, NULL, NULL, prefs_common_page, NULL},
67 {N_("/Common/Filtering"), 0, NULL, NULL, prefs_filter_page, prefs_filter_apply},
68 {N_("/Common/Character set"), 0, NULL, NULL, prefs_charset_page, prefs_charset_apply},
69
70 {N_("/Image Window"), 0, NULL, NULL, prefs_imagewin_page, NULL},
71 {N_("/Image Window/Image"), 0, NULL, NULL, prefs_imagewin_image_page, prefs_ui_imagewin_image_apply},
72 {N_("/Image Window/Mouse Buttton"), 0, NULL, NULL, prefs_imagewin_mouse_page, NULL},
73
74 {N_("/Thumbnail Window"), 0, NULL, NULL, prefs_thumbwin_page, prefs_ui_thumbwin_apply},
75 /*
76 {N_("/Thumbnail Window/Toolbar"), 0, NULL, NULL, prefs_thumbview_toolbar_page, NULL},
77 */
78 {N_("/Thumbnail Window/Tab"), 0, NULL, NULL, prefs_thumbwin_tab_page, prefs_ui_thumbwin_tab_apply},
79 {N_("/Thumbnail Window/Thumbnail View"), 0, NULL, NULL, prefs_thumbview_page, NULL},
80 {N_("/Thumbnail Window/Thumbnail View/Mouse Buttton"), 0, NULL, NULL, prefs_thumbview_mouse_page, NULL},
81 {N_("/Thumbnail Window/Thumbnail View/Album"), 0, NULL, NULL, prefs_ui_thumbalbum, NULL},
82
83 {N_("/Thumbnail Window/Directory View"), 0, NULL, NULL, prefs_dirview_page, prefs_ui_dirview_apply},
84 {N_("/Thumbnail Window/Directory View/Mouse Buttton"), 0, NULL, NULL, prefs_dirview_mouse_page, NULL},
85 {N_("/Thumbnail Window/Preview"), 0, NULL, NULL, prefs_preview_page, prefs_ui_preview_apply},
86 {N_("/Thumbnail Window/Preview/Mouse Buttton"), 0, NULL, NULL, prefs_preview_mouse_page, NULL},
87
88 {N_("/Movie and Audio"), 0, NULL, NULL, prefs_movie_page, NULL},
89
90 {N_("/Slide Show"), 0, NULL, NULL, prefs_slideshow_page, NULL},
91 {N_("/Thumbnail Cache"), 0, NULL, NULL, prefs_cache_page, NULL},
92 {N_("/Comment"), 0, NULL, NULL, prefs_comment_page, prefs_comment_apply},
93 {N_("/Search"), 0, NULL, NULL, prefs_search_page, NULL},
94 {N_("/Drag and Drop"), 0, NULL, NULL, prefs_dnd_page, NULL},
95 {N_("/External Program"), 0, NULL, NULL, prefs_progs_page, NULL},
96 {N_("/External Program/Scripts"), 0, NULL, NULL, prefs_scripts_page, NULL},
97
98 {N_("/Plugin"), 0, NULL, NULL, prefs_ui_plugin, prefs_ui_plugin_apply},
99 {N_("/Plugin/Image Loader"), 0, NULL, NULL, prefs_ui_plugin_image_loader, NULL},
100 {N_("/Plugin/Image Saver"), 0, NULL, NULL, prefs_ui_plugin_image_saver, NULL},
101 {N_("/Plugin/IO Stream"), 0, NULL, NULL, prefs_ui_plugin_io_stream, NULL},
102 {N_("/Plugin/Archiver"), 0, NULL, NULL, prefs_ui_plugin_archiver, NULL},
103 {N_("/Plugin/Thumbnail"), 0, NULL, NULL, prefs_ui_plugin_thumbnail, NULL},
104 {N_("/Plugin/Image View"), 0, NULL, NULL, prefs_ui_plugin_imageview, NULL},
105 {N_("/Plugin/Thumbnail View"), 0, NULL, NULL, prefs_ui_plugin_thumbview, NULL},
106 };
107 static gint prefs_pages_num = sizeof (prefs_pages) / sizeof (prefs_pages[0]);
108
109 GList *prefs_pages_list = NULL;
110
111 Config *config_changed = NULL;
112 Config *config_prechanged = NULL;
113
114
115 static GtkWidget *prefs_window;
116 static PrefsWin prefs_win = {
117 notebook: NULL,
118 tree: NULL,
119 ok_pressed: FALSE,
120 };
121 static GList *priv_page_list = NULL;
122
123
124 static GList *
get_page_entries_list(void)125 get_page_entries_list (void)
126 {
127 if (!prefs_pages_list) {
128 gint i;
129
130 for (i = 0; i < prefs_pages_num; i++)
131 prefs_pages_list = g_list_append (prefs_pages_list, &prefs_pages[i]);
132 }
133
134 return prefs_pages_list;
135 }
136
137
138 gboolean
gimv_prefs_win_add_page_entry(GimvPrefsWinPage * page)139 gimv_prefs_win_add_page_entry (GimvPrefsWinPage *page)
140 {
141 g_return_val_if_fail (page, FALSE);
142
143 get_page_entries_list ();
144 #warning FIXME: check path
145 prefs_pages_list = g_list_append (prefs_pages_list, page);
146 return TRUE;
147 }
148
149
150 /*******************************************************************************
151 *
152 * Private functions
153 *
154 *******************************************************************************/
155 static void
prefs_win_apply_config(GimvPrefsWinAction action)156 prefs_win_apply_config (GimvPrefsWinAction action)
157 {
158 GList *node;
159
160 for (node = priv_page_list; node; node = g_list_next (node)) {
161 GimvPrefsWinPagePrivate *priv = node->data;
162 if (priv && priv->widget && priv->page && priv->page->apply_fn)
163 priv->page->apply_fn (action);
164 }
165 }
166
167
168 /* FIXME!! too stupid ;-( */
169 /* Damn Damn Damn XD */
170 static void
prefs_win_free_strings(gboolean value_changed)171 prefs_win_free_strings (gboolean value_changed)
172 {
173 gint i;
174 gchar **strings[] = {
175 &conf.text_viewer,
176 &conf.web_browser,
177 &conf.plugin_search_dir_list,
178 &conf.scripts_search_dir_list,
179 &conf.imgview_mouse_button,
180 &conf.preview_mouse_button,
181 &conf.imgtype_disables,
182 &conf.imgtype_user_defs,
183 &conf.comment_key_list,
184 &conf.charset_locale,
185 &conf.charset_internal,
186 };
187 gint num1 = sizeof (strings) / sizeof (gchar **);
188 gint num2 = sizeof (conf.progs) / sizeof (gchar *);
189
190 for (i = 0; i < num1 + num2; i++) {
191 gchar **src, **dest, **member;
192 gulong offset;
193
194 if (i < num1)
195 member = strings[i];
196 else if (i < num1 + num2)
197 member = &conf.progs[i - num1];
198 else
199 break;
200
201 offset = (gchar *) member - (gchar *) &conf;
202 src = G_STRUCT_MEMBER_P (config_prechanged, offset);
203 dest = G_STRUCT_MEMBER_P (config_changed, offset);
204
205 if (*src == *dest) continue;
206
207 if (value_changed) {
208 g_free (*src);
209 } else {
210 g_free (*dest);
211 }
212 }
213 }
214 /* END FIXME!! */
215
216
217 static void
prefs_win_create_page(GimvPrefsWinPagePrivate * priv)218 prefs_win_create_page (GimvPrefsWinPagePrivate *priv)
219 {
220 const gchar *title = NULL;
221 GtkWidget *vbox, *label;
222
223 if (!priv || !priv->page) return;
224 if (priv->widget) return;
225
226 /* translate page title */
227 if (priv->page->path)
228 title = g_basename (_(priv->page->path));
229
230 /* create page */
231 if (priv->page->create_page_fn) {
232 vbox = priv->page->create_page_fn ();
233 label = gtk_label_new (title);
234 gtk_notebook_append_page (GTK_NOTEBOOK(prefs_win.notebook),
235 vbox, label);
236 priv->widget = vbox;
237 }
238 }
239
240
241 static void
prefs_win_set_page(const gchar * path)242 prefs_win_set_page (const gchar *path)
243 {
244 GimvPrefsWinPagePrivate *priv = NULL;
245 GList *node;
246 gint num;
247
248 if (!path || !*path) {
249 if (!priv_page_list) return;
250 priv = priv_page_list->data;
251 } else {
252 for (node = priv_page_list; node; node = g_list_next (node)) {
253 priv = node->data;
254 if (priv->page && !strcmp (path, priv->page->path))
255 break;
256 priv = NULL;
257 }
258 }
259
260 if (!priv) {
261 if (!priv_page_list) return;
262 priv = priv_page_list->data;
263 }
264
265 if (!priv->widget) {
266 prefs_win_create_page (priv);
267 }
268 if (priv->widget)
269 gtk_widget_show (priv->widget);
270 else
271 return;
272
273 num = gtk_notebook_page_num (GTK_NOTEBOOK (prefs_win.notebook),
274 priv->widget);
275 if (num >= 0)
276 gtk_notebook_set_page (GTK_NOTEBOOK (prefs_win.notebook), num);
277
278 #ifdef ENABLE_TREEVIEW
279 #else /* ENABLE_TREEVIEW */
280 /* gtk_ctree_select (GTK_CTREE (prefs_win.tree), priv->node); */
281 #endif /* ENABLE_TREEVIEW */
282 }
283
284
285
286 /*******************************************************************************
287 *
288 * functions for creating navigate tree
289 *
290 *******************************************************************************/
291 static void
get_icon(const gchar * name,GdkPixmap ** pixmap,GdkBitmap ** mask)292 get_icon (const gchar *name, GdkPixmap **pixmap, GdkBitmap **mask)
293 {
294 GimvIcon *icon;
295
296 if (!name || !*name) return;
297
298 icon = gimv_icon_stock_get_icon (name);
299 if (icon) {
300 if (pixmap)
301 *pixmap = icon->pixmap;
302 if (mask)
303 *mask = icon->mask;
304 } else {
305 if (pixmap)
306 *pixmap = NULL;
307 if (mask)
308 *mask = NULL;
309 }
310 }
311
312
313 #ifdef ENABLE_TREEVIEW
314
315 typedef enum {
316 COLUMN_TERMINATOR = -1,
317 COLUMN_ICON_OPEN,
318 COLUMN_ICON_OPEN_MASK,
319 COLUMN_ICON_CLOSE,
320 COLUMN_ICON_CLOSE_MASK,
321 COLUMN_NAME,
322 COLUMN_PRIV_DATA,
323 N_COLUMN
324 } TreeStoreColumn;
325
326
327 struct FindNode {
328 gchar *path;
329 GimvPrefsWinPagePrivate *priv;
330 GtkTreeIter iter;
331 };
332
333
334 static gboolean
find_node_by_path(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer data)335 find_node_by_path (GtkTreeModel *model,
336 GtkTreePath *path, GtkTreeIter *iter,
337 gpointer data)
338 {
339 struct FindNode *node = data;
340 GimvPrefsWinPagePrivate *priv;
341
342 gtk_tree_model_get (model, iter,
343 COLUMN_PRIV_DATA, &priv,
344 COLUMN_TERMINATOR);
345 if (priv && !strcmp (priv->page->path, node->path)) {
346 node->priv = priv;
347 node->iter = *iter;
348 return TRUE;
349 }
350
351 return FALSE;
352 }
353
354
355 static gboolean
prefs_win_navtree_get_parent(GimvPrefsWinPagePrivate * priv,GtkTreeIter * iter)356 prefs_win_navtree_get_parent (GimvPrefsWinPagePrivate *priv, GtkTreeIter *iter)
357 {
358 GtkTreeModel *model;
359 struct FindNode node;
360
361 g_return_val_if_fail (priv, FALSE);
362 g_return_val_if_fail (priv->page, FALSE);
363 g_return_val_if_fail (priv->page->path, FALSE);
364
365 node.path = g_dirname (priv->page->path);
366 node.priv = NULL;
367
368 model = gtk_tree_view_get_model (GTK_TREE_VIEW (prefs_win.tree));
369 gtk_tree_model_foreach (model, find_node_by_path, &node);
370
371 g_free (node.path);
372
373 if (node.priv) {
374 *iter = node.iter;
375 return TRUE;
376 }
377
378 return FALSE;
379 }
380
381
382 static gboolean
cb_tree_key_press(GtkWidget * widget,GdkEventKey * event,gpointer data)383 cb_tree_key_press (GtkWidget *widget, GdkEventKey *event, gpointer data)
384 {
385 GtkTreeSelection *selection;
386 GtkTreeModel *model;
387 GtkTreeIter iter;
388 GtkTreePath *treepath;
389 gboolean success, retval = FALSE;
390
391 g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
392
393 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
394 if (!selection) return FALSE;
395 success = gtk_tree_selection_get_selected (selection, &model, &iter);
396 if (!success) return FALSE;
397 treepath = gtk_tree_model_get_path (model, &iter);
398 if (!treepath) return FALSE;
399
400 switch (event->keyval) {
401 case GDK_KP_Enter:
402 case GDK_Return:
403 case GDK_ISO_Enter:
404 case GDK_space:
405 if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (widget), treepath))
406 gtk_tree_view_collapse_row (GTK_TREE_VIEW (widget), treepath);
407 else
408 gtk_tree_view_expand_row (GTK_TREE_VIEW (widget), treepath, FALSE);
409 retval = TRUE;
410 break;
411 case GDK_Right:
412 gtk_tree_view_expand_row (GTK_TREE_VIEW (widget), treepath, FALSE);
413 retval = TRUE;
414 break;
415 case GDK_Left:
416 gtk_tree_view_collapse_row (GTK_TREE_VIEW (widget), treepath);
417 retval = TRUE;
418 break;
419 default:
420 break;
421 }
422
423 gtk_tree_path_free(treepath);
424
425 return retval;
426 }
427
428
429 static void
cb_tree_cursor_changed(GtkTreeView * treeview,gpointer data)430 cb_tree_cursor_changed (GtkTreeView *treeview, gpointer data)
431 {
432 GtkTreeSelection *selection;
433 GtkTreeModel *model;
434 GtkTreeIter iter;
435 GimvPrefsWinPagePrivate *priv;
436
437 g_return_if_fail (treeview);
438
439 selection = gtk_tree_view_get_selection (treeview);
440 gtk_tree_selection_get_selected (selection, &model, &iter);
441 gtk_tree_model_get (model, &iter,
442 COLUMN_PRIV_DATA, &priv,
443 COLUMN_TERMINATOR);
444
445 g_return_if_fail (priv);
446 g_return_if_fail (priv->page);
447
448 prefs_win_set_page (priv->page->path);
449 }
450
451
452 static GtkWidget *
prefs_win_create_navtree(void)453 prefs_win_create_navtree (void)
454 {
455 GtkTreeStore *store;
456 GtkTreeViewColumn *col;
457 GtkCellRenderer *render;
458 GtkWidget *tree;
459 GList *node;
460
461 store = gtk_tree_store_new (N_COLUMN,
462 GDK_TYPE_PIXMAP,
463 GDK_TYPE_PIXMAP,
464 GDK_TYPE_PIXMAP,
465 GDK_TYPE_PIXMAP,
466 G_TYPE_STRING,
467 G_TYPE_POINTER);
468 tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
469 prefs_win.tree = tree;
470 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree), TRUE);
471 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree), FALSE);
472
473 g_signal_connect (G_OBJECT (tree), "key_press_event",
474 G_CALLBACK (cb_tree_key_press), NULL);
475 g_signal_connect (G_OBJECT (tree), "cursor_changed",
476 G_CALLBACK (cb_tree_cursor_changed), NULL);
477
478 /* name column */
479 col = gtk_tree_view_column_new();
480
481 render = gimv_cell_renderer_pixmap_new ();
482 gtk_tree_view_column_pack_start (col, render, FALSE);
483 gtk_tree_view_column_add_attribute (col, render, "pixmap",
484 COLUMN_ICON_CLOSE);
485 gtk_tree_view_column_add_attribute (col, render, "mask",
486 COLUMN_ICON_CLOSE_MASK);
487 gtk_tree_view_column_add_attribute (col, render, "pixmap_expander_open",
488 COLUMN_ICON_OPEN);
489 gtk_tree_view_column_add_attribute (col, render, "mask_expander_open",
490 COLUMN_ICON_OPEN_MASK);
491 gtk_tree_view_column_add_attribute (col, render, "pixmap_expander_closed",
492 COLUMN_ICON_CLOSE);
493 gtk_tree_view_column_add_attribute (col, render, "mask_expander_closed",
494 COLUMN_ICON_CLOSE_MASK);
495
496 render = gtk_cell_renderer_text_new ();
497 gtk_tree_view_column_pack_start (col, render, TRUE);
498 gtk_tree_view_column_add_attribute (col, render, "text", COLUMN_NAME);
499
500 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), col);
501 gtk_tree_view_set_expander_column (GTK_TREE_VIEW (tree), col);
502
503 /* create pages */
504 for (node = get_page_entries_list(); node; node = g_list_next (node)) {
505 GimvPrefsWinPage *page = node->data;
506 const gchar *title;
507 GdkPixmap *pixmap = NULL, *opixmap = NULL;
508 GdkBitmap *mask = NULL, *omask = NULL;
509 GimvPrefsWinPagePrivate *priv;
510 GtkTreeIter iter, parent_iter;
511
512 if (!page || !page->path) continue;
513
514 /* translate page title */
515 title = g_basename (_(page->path));
516
517 /* get node icon */
518 get_icon (page->icon, &pixmap, &mask);
519 get_icon (page->icon_open, &opixmap, &omask);
520
521 /* set private data */
522 priv = g_new0 (GimvPrefsWinPagePrivate, 1);
523 priv->page = page;
524 priv->widget = NULL;
525
526 priv_page_list = g_list_append (priv_page_list, priv);
527
528 if (prefs_win_navtree_get_parent (priv, &parent_iter)) {
529 gtk_tree_store_append (store, &iter, &parent_iter);
530 } else {
531 gtk_tree_store_append (store, &iter, NULL);
532 }
533 gtk_tree_store_set (store, &iter,
534 COLUMN_ICON_CLOSE, pixmap,
535 COLUMN_ICON_CLOSE_MASK, mask,
536 COLUMN_ICON_OPEN, opixmap,
537 COLUMN_ICON_OPEN_MASK, omask,
538 COLUMN_NAME, title,
539 COLUMN_PRIV_DATA, priv,
540 COLUMN_TERMINATOR);
541 }
542
543 return tree;
544 }
545
546 #else /* ENABLE_TREEVIEW */
547
548 static gboolean
cb_ctree_key_press(GtkWidget * widget,GdkEventKey * event,gpointer data)549 cb_ctree_key_press (GtkWidget *widget, GdkEventKey *event, gpointer data)
550 {
551 GList *sel;
552 GtkCTreeNode *node;
553
554 g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
555
556 sel = GTK_CLIST (widget)->selection;
557 if (!sel) return FALSE;
558 node = sel->data;
559
560 switch (event->keyval) {
561 case GDK_KP_Enter:
562 case GDK_Return:
563 case GDK_ISO_Enter:
564 case GDK_space:
565 gtk_ctree_toggle_expansion (GTK_CTREE (widget), node);
566 break;
567 case GDK_Right:
568 gtk_ctree_expand (GTK_CTREE (widget), node);
569 return TRUE;
570 break;
571 case GDK_Left:
572 gtk_ctree_collapse (GTK_CTREE (widget), node);
573 return TRUE;
574 break;
575 default:
576 break;
577 }
578
579 return FALSE;
580 }
581
582
583 static void
cb_ctree_select_row(GtkWidget * widget,gint row,gint column,GdkEventButton * event,gpointer data)584 cb_ctree_select_row (GtkWidget *widget, gint row, gint column,
585 GdkEventButton *event, gpointer data)
586 {
587 GtkCTreeNode *node;
588 GimvPrefsWinPagePrivate *priv;
589
590 node = gtk_ctree_node_nth (GTK_CTREE (widget), row);
591 if (!node) return;
592
593 priv = gtk_ctree_node_get_row_data (GTK_CTREE (widget), node);
594 if (priv->page)
595 prefs_win_set_page (priv->page->path);
596 }
597
598
599 static GtkCTreeNode *
prefs_win_navtree_get_parent(GimvPrefsWinPage * page)600 prefs_win_navtree_get_parent (GimvPrefsWinPage *page)
601 {
602 GList *node = NULL;
603 gchar *parent;
604
605 g_return_val_if_fail (page, NULL);
606 g_return_val_if_fail (page->path, NULL);
607
608 if (!page->path) return NULL;
609 parent = g_dirname (page->path);
610
611 for (node = priv_page_list; node; node = g_list_next (node)) {
612 GimvPrefsWinPagePrivate *priv = node->data;
613 if (priv && priv->page && !strcmp (parent, priv->page->path)) {
614 g_free (parent);
615 return priv->node;
616 }
617 }
618
619 g_free (parent);
620
621 return NULL;
622 }
623
624
625 static GtkWidget *
prefs_win_create_navtree(void)626 prefs_win_create_navtree (void)
627 {
628 GtkWidget *ctree;
629 GtkCTreeNode *node, *parent = NULL;
630 GList *lnode;
631
632 /* create tree */
633 ctree = prefs_win.tree = gtk_ctree_new (1,0);
634 prefs_win.tree = ctree;
635 gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 0, TRUE);
636 gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_BROWSE);
637 gtk_ctree_set_line_style (GTK_CTREE (ctree), conf.dirview_line_style);
638 gtk_ctree_set_expander_style (GTK_CTREE (ctree), conf.dirview_expander_style);
639 gtk_clist_set_row_height (GTK_CLIST (ctree), 18);
640
641 gtk_signal_connect (GTK_OBJECT (ctree), "key_press_event",
642 GTK_SIGNAL_FUNC (cb_ctree_key_press), NULL);
643 gtk_signal_connect (GTK_OBJECT (ctree), "select-row",
644 GTK_SIGNAL_FUNC (cb_ctree_select_row), NULL);
645
646 /* create pages */
647 for (lnode = get_page_entries_list(); lnode; lnode = g_list_next (lnode)) {
648 GimvPrefsWinPage *page = lnode->data;
649 const gchar *title;
650 GdkPixmap *pixmap = NULL, *opixmap = NULL;
651 GdkBitmap *mask = NULL, *omask = NULL;
652 GimvPrefsWinPagePrivate *priv;
653
654 if (!page || !page->path) continue;
655
656 /* translate page title */
657 title = g_basename (_(page->path));
658
659 /* get node icon */
660 get_icon (page->icon, &pixmap, &mask);
661 get_icon (page->icon_open, &opixmap, &omask);
662
663 /* insert node */
664 parent = prefs_win_navtree_get_parent (page);
665 node = gtk_ctree_insert_node (GTK_CTREE (ctree), parent, NULL,
666 (gchar **) &title, 4,
667 pixmap, mask,
668 opixmap, omask,
669 FALSE, FALSE);
670
671 /* set private data */
672 priv = g_new0 (GimvPrefsWinPagePrivate, 1);
673 priv->page = page;
674 priv->widget = NULL;
675 priv->node = node;
676
677 priv_page_list = g_list_append (priv_page_list, priv);
678
679 gtk_ctree_node_set_row_data (GTK_CTREE(ctree), node, priv);
680 }
681
682 return ctree;
683 }
684
685 #endif /* ENABLE_TREEVIEW */
686
687
688
689 /*******************************************************************************
690 *
691 * Callback functions for preference window.
692 *
693 *******************************************************************************/
694 static void
cb_prefs_win_destroy()695 cb_prefs_win_destroy ()
696 {
697 if (prefs_win.ok_pressed) {
698 prefs_win_free_strings (TRUE);
699 conf = *config_changed;
700 prefs_win_apply_config (GIMV_PREFS_WIN_ACTION_OK);
701 } else {
702 prefs_win_free_strings (FALSE);
703 conf = *config_prechanged;
704 prefs_win_apply_config (GIMV_PREFS_WIN_ACTION_CANCEL);
705 }
706
707 g_free (config_changed);
708 g_free (config_prechanged);
709 config_changed = NULL;
710 config_prechanged = NULL;
711
712 prefs_window = NULL;
713 prefs_win.notebook = NULL;
714 prefs_win.tree = NULL;
715 prefs_win.ok_pressed = FALSE;
716
717 g_list_foreach (priv_page_list, (GFunc) g_free, NULL);
718 g_list_free (priv_page_list);
719 priv_page_list = NULL;
720
721 prefs_save_config ();
722 }
723
724
725 #ifdef USE_GTK2
726
727 static void
cb_dialog_response(GtkDialog * dialog,gint arg,gpointer data)728 cb_dialog_response (GtkDialog *dialog, gint arg, gpointer data)
729 {
730 switch (arg) {
731 case GTK_RESPONSE_ACCEPT:
732 prefs_win.ok_pressed = TRUE;
733 gtk_widget_destroy (prefs_window);
734 break;
735 case GTK_RESPONSE_APPLY:
736 memcpy (&conf, config_changed, sizeof(Config));
737 prefs_win_apply_config (GIMV_PREFS_WIN_ACTION_APPLY);
738 break;
739 case GTK_RESPONSE_REJECT:
740 gtk_widget_destroy (prefs_window);
741 break;
742 default:
743 break;
744 }
745 }
746
747 #else
748
749 static void
cb_prefs_ok_button()750 cb_prefs_ok_button ()
751 {
752 prefs_win.ok_pressed = TRUE;
753 gtk_widget_destroy (prefs_window);
754 }
755
756
757 static void
cb_prefs_apply_button()758 cb_prefs_apply_button ()
759 {
760 memcpy (&conf, config_changed, sizeof(Config));
761 prefs_win_apply_config (GIMV_PREFS_WIN_ACTION_APPLY);
762 }
763
764
765 static void
cb_prefs_cancel_button()766 cb_prefs_cancel_button ()
767 {
768 gtk_widget_destroy (prefs_window);
769 }
770
771 #endif
772
773
774
775 /*******************************************************************************
776 *
777 * prefs_open_window:
778 * @ Create preference window. If already opened, raise it and return.
779 *
780 * GtkWidget *prefs_window (global variable):
781 * Pointer to preference window.
782 *
783 * Static PrefsWin prefs_win (local variable):
784 * store pointer to eache widget;
785 *
786 *******************************************************************************/
787 GtkWidget *
gimv_prefs_win_open(const gchar * path,GtkWindow * parent)788 gimv_prefs_win_open (const gchar *path, GtkWindow *parent)
789 {
790 GtkWidget *notebook, *pane, *scrolledwin, *navtree;
791
792 /* if preference window is alredy opend, raise it and return */
793 if (prefs_window) {
794 gdk_window_raise (prefs_window->window);
795 return prefs_window;
796 }
797
798 prefs_win.ok_pressed = FALSE;
799
800 /* allocate buffer for new config */
801 config_prechanged = g_memdup (&conf, sizeof(Config));
802 config_changed = g_memdup (&conf, sizeof(Config));
803
804 /* create config window */
805 prefs_window = gtk_dialog_new ();
806 if (parent)
807 gtk_window_set_transient_for (GTK_WINDOW (prefs_window), parent);
808 gtk_window_set_wmclass(GTK_WINDOW(prefs_window), "prefs", GIMV_PROG_NAME);
809 gtk_window_set_default_size (GTK_WINDOW(prefs_window), 600, 450);
810 gtk_window_set_title (GTK_WINDOW (prefs_window), _("Preference"));
811 gtk_signal_connect (GTK_OBJECT(prefs_window), "destroy",
812 GTK_SIGNAL_FUNC(cb_prefs_win_destroy), NULL);
813
814 /* pane */
815 pane = gimv_hpaned_new ();
816 gtk_container_set_border_width (GTK_CONTAINER (pane), 5);
817 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (prefs_window)->vbox),
818 pane, TRUE, TRUE, 0);
819 gtk_widget_show (pane);
820
821 notebook = prefs_win.notebook = gtk_notebook_new ();
822 gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
823 gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
824 /* gtk_notebook_popup_enable (GTK_NOTEBOOK (notebook)); */
825 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
826 gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
827 gtk_widget_show (notebook);
828
829 /* scrolled window */
830 scrolledwin = gtk_scrolled_window_new (NULL, NULL);
831 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolledwin),
832 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
833 #ifdef USE_GTK2
834 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin),
835 GTK_SHADOW_IN);
836 #endif /* USE_GTK2 */
837 gtk_widget_set_usize (scrolledwin, 170, -1);
838 gtk_widget_show (scrolledwin);
839
840 /* navigation tree */
841 navtree = prefs_win_create_navtree ();
842 gtk_container_add (GTK_CONTAINER (scrolledwin), navtree);
843 gtk_widget_show (navtree);
844
845 gimv_paned_add1 (GIMV_PANED (pane), scrolledwin);
846 gimv_paned_add2 (GIMV_PANED (pane), notebook);
847
848 /* button */
849 #ifdef USE_GTK2
850 gtk_dialog_add_buttons (GTK_DIALOG (prefs_window),
851 GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
852 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
853 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
854 NULL);
855 gtk_signal_connect_object (GTK_OBJECT (prefs_window), "response",
856 GTK_SIGNAL_FUNC (cb_dialog_response),
857 NULL);
858 #else
859 {
860 GtkWidget *button;
861
862 /* dialog buttons */
863 button = gtk_button_new_with_label (_("OK"));
864 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (prefs_window)->action_area),
865 button, TRUE, TRUE, 0);
866 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
867 GTK_SIGNAL_FUNC (cb_prefs_ok_button),
868 GTK_OBJECT (prefs_window));
869 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
870 gtk_widget_show (button);
871
872 gtk_widget_grab_focus (button);
873
874 button = gtk_button_new_with_label (_("Apply"));
875 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (prefs_window)->action_area),
876 button, FALSE, TRUE, 0);
877 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
878 GTK_SIGNAL_FUNC (cb_prefs_apply_button),
879 GTK_OBJECT (prefs_window));
880 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
881 gtk_widget_show (button);
882
883 button = gtk_button_new_with_label (_("Cancel"));
884 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (prefs_window)->action_area),
885 button, FALSE, TRUE, 0);
886 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
887 GTK_SIGNAL_FUNC (cb_prefs_cancel_button),
888 GTK_OBJECT (prefs_window));
889 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
890 gtk_widget_show (button);
891 }
892 #endif
893
894 gtk_window_set_position (GTK_WINDOW (prefs_window), GTK_WIN_POS_CENTER);
895 gtk_widget_show (prefs_window);
896 gimv_icon_stock_set_window_icon (prefs_window->window, "prefs");
897
898 prefs_win_set_page (NULL);
899
900 return prefs_window;
901 }
902
903
904 static GtkWindow *auauauau_window = NULL;
905
906 static gboolean
idle_prefs_win_open(gpointer data)907 idle_prefs_win_open (gpointer data)
908 {
909 gchar *path = data;
910 gimv_prefs_win_open (path, auauauau_window);
911 auauauau_window = NULL;
912 g_free (path);
913 return FALSE;
914 }
915
916
917 void
gimv_prefs_win_open_idle(const gchar * path,GtkWindow * parent)918 gimv_prefs_win_open_idle (const gchar *path, GtkWindow *parent)
919 {
920 gchar *str = NULL;
921
922 if (path)
923 str = g_strdup (path);
924
925 auauauau_window = parent;
926
927 gtk_idle_add (idle_prefs_win_open, str);
928 }
929
930
931 gboolean
gimv_prefs_win_is_opened(void)932 gimv_prefs_win_is_opened (void)
933 {
934 if (prefs_window)
935 return TRUE;
936 else
937 return FALSE;
938 }
939
940
941 GtkWidget *
gimv_prefs_win_get(void)942 gimv_prefs_win_get (void)
943 {
944 return prefs_window;
945 }
946