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_thumb_win.c,v 1.21 2004/12/20 18:18:30 makeinu Exp $
22  */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <gdk/gdkkeysyms.h>
28 
29 #include "gimageview.h"
30 
31 #include "auto_completion.h"
32 #include "charset.h"
33 #include "dirview.h"
34 #include "dnd.h"
35 #include "fileutil.h"
36 #include "gfileutil.h"
37 #include "gimv_comment_view.h"
38 #include "gimv_dupl_finder.h"
39 #include "gimv_hpaned.h"
40 #include "gimv_vpaned.h"
41 #include "gimv_icon_stock.h"
42 #include "gimv_image_win.h"
43 #include "gimv_prefs_win.h"
44 #include "gimv_slideshow.h"
45 #include "gimv_thumb.h"
46 #include "gimv_thumb_view.h"
47 #include "gimv_thumb_win.h"
48 #include "gtk2-compat.h"
49 #include "help.h"
50 #include "menu.h"
51 #include "prefs.h"
52 
53 
54 typedef enum {
55    OPEN_FILE,
56    OPEN_IMAGEWIN,
57    OPEN_THUMBWIN,
58    OPEN_THUMBTAB,
59    OPEN_PREFS,
60    OPEN_GIMV_INFO
61 } OpenItem;
62 
63 
64 typedef enum {
65    CLOSE_FILE,
66    CLOSE_THUMBWIN,
67    CLOSE_THUMBTAB,
68    CLOSE_PREFS,
69    CLOSE_GIMV_INFO,
70    CLOSE_ALL
71 } CloseItem;
72 
73 
74 typedef enum {
75    CURRENT,
76    NEXT,
77    PREV,
78    FIRST,
79    LAST
80 } SwitchPage;
81 
82 
83 typedef enum {
84    DIR_VIEW,
85    THUMBNAIL_VIEW,
86    PREVIEW,
87    LOCATION_ENTRY,
88    THUMBNAIL_SIZE_ENTRY
89 } FocusItem;
90 
91 typedef enum {
92    MENUBAR,
93    TOOLBAR,
94    TAB,
95    STATUSBAR,
96    DIR_TOOLBAR,
97    PREVIEW_TAB
98 } ShowItem;
99 
100 
101 typedef enum {
102    LEFT,
103    RIGHT
104 } MoveTabItem;
105 
106 
107 typedef enum {
108    PERVIEW_NONE,
109    PREVIEW_NEXT,
110    PREVIEW_PREV,
111    PREVIEW_SHAREDWIN,
112    PREVIEW_NEWWIN,
113    PREVIEW_POPUP,
114    PREVIEW_ZOOM_IN,
115    PREVIEW_ZOOM_OUT,
116    PREVIEW_FIT,
117    PREVIEW_ROTATE_CCW,
118    PREVIEW_ROTATE_CW,
119    PREVIEW_NAVWIN,
120    PREVIEW_UP,
121    PREVIEW_DOWN,
122    PREVIEW_LEFT,
123    PREVIEW_RIGHT
124 } PreviewPressType;
125 
126 
127 typedef enum {
128    CLEAR_CACHE_NONE,
129    CLEAR_CACHE_TAB,
130    CLEAR_CACHE_ALL
131 } CacheClearType;
132 
133 
134 typedef enum {
135    SLIDESHOW_START_FROM_FIRST,
136    SLIDESHOW_START_FROM_SELECTED,
137    SLIDESHOW_RANDOM_ORDER,
138 } SlideShowOrder;
139 
140 
141 typedef enum {
142    SLIDESHOW_IMAGES_AND_MOVIES,
143    SLIDESHOW_IMAGES_ONLY,
144    SLIDESHOW_MOVIES_ONLY
145 } SlideShowFileType;
146 
147 
148 struct GimvThumbWinPriv_Tag {
149    SlideShowOrder    slideshow_order;
150    gboolean          slideshow_selected_only;
151    SlideShowFileType slideshow_file_type;
152 };
153 
154 
155 static void       gimv_thumb_win_class_init          (GimvThumbWinClass *klass);
156 static void       gimv_thumb_win_init                (GimvThumbWin      *iw);
157 static void       gimv_thumb_win_destroy             (GtkObject         *object);
158 static void       gimv_thumb_win_realize             (GtkWidget         *widget);
159 static gboolean   gimv_thumb_win_delete_event        (GtkWidget         *widget,
160                                                       GdkEventAny       *event);
161 
162 /* Parts of Thumbnail Window and utilities */
163 static void       create_gimv_thumb_win_menus        (GimvThumbWin   *tw);
164 static void       sync_widget_state_to_menu          (GimvThumbWin   *tw);
165 static GtkWidget *create_toolbar                     (GimvThumbWin   *tw,
166                                                       GtkWidget      *container);
167 static void       gimv_thumb_win_get_layout          (GimvThumbwinComposeType *compose,
168                                                       gint            layout);
169 static void       gimv_thumb_win_pane_set_visible    (GimvThumbWin   *tw,
170                                                       GimvComponentType item);
171 static GtkWidget *thumbnail_window_contents_new      (GimvThumbWin   *tw);
172 static GtkWidget *thumbnail_view_new                 (GimvThumbWin   *tw);
173 static gint       image_preview_action               (GimvImageView  *iv,
174                                                       GdkEventButton *event,
175                                                       gint            num);
176 static gint       cb_image_preview_pressed           (GimvImageView  *iv,
177                                                       GdkEventButton *event,
178                                                       gpointer        data);
179 static gint       cb_image_preview_clicked           (GimvImageView  *iv,
180                                                       GdkEventButton *event,
181                                                       gpointer        data);
182 static GtkWidget *image_preview_new                  (GimvThumbWin   *tw);
183 static void       add_accel_label_to_disp_mode_menu  (GtkWidget      *widget,
184                                                       GtkWidget      *window);
185 static void       location_entry_set_text            (GimvThumbWin   *tw,
186                                                       GimvThumbView  *tv,
187                                                       const gchar    *location);
188 
189 
190 /* Callback Functions for main menu */
191 static void cb_open                 (GimvThumbWin  *tw,
192                                      guint          action,
193                                      GtkWidget     *widget);
194 static void cb_close                (GimvThumbWin  *tw,
195                                      guint          action,
196                                      GtkWidget     *widget);
197 static void cb_select_all           (GimvThumbWin  *tw,
198                                      guint          action,
199                                      GtkWidget     *widget);
200 static void cb_refresh_list         (GimvThumbWin  *tw,
201                                      guint          action,
202                                      GtkWidget     *widget);
203 static void cb_reload               (GimvThumbWin  *tw,
204                                      ThumbLoadType  type,
205                                      GtkWidget     *widget);
206 static void cb_clear_cache          (GimvThumbWin  *tw,
207                                      CacheClearType type,
208                                      GtkWidget     *widget);
209 static void cb_file_operate         (GimvThumbWin  *tw,
210                                      guint          action,
211                                      GtkWidget     *menuitem);
212 static void cb_find_similar         (GimvThumbWin  *tw,
213                                      guint          action,
214                                      GtkWidget     *widget);
215 static void cb_move_tab             (GimvThumbWin  *tw,
216                                      MoveTabItem    sortitem,
217                                      GtkWidget     *widget);
218 static void cb_cut_out_tab          (GimvThumbWin  *tw,
219                                      guint          action,
220                                      GtkWidget     *widget);
221 static void cb_switch_layout        (GimvThumbWin  *tw,
222                                      gint          action,
223                                      GtkWidget     *widget);
224 static void cb_switch_tab_pos       (GimvThumbWin  *tw,
225                                      GtkPositionType pos,
226                                      GtkWidget     *widget);
227 static void cb_slideshow            (GimvThumbWin  *tw,
228                                      guint          action,
229                                      GtkWidget     *widget);
230 static void cb_slideshow_order      (GimvThumbWin  *tw,
231                                      SlideShowOrder action,
232                                      GtkWidget     *widget);
233 static void cb_slideshow_selected   (GimvThumbWin  *tw,
234                                      guint          action,
235                                      GtkWidget     *widget);
236 static void cb_slideshow_file_type  (GimvThumbWin  *tw,
237                                      SlideShowFileType action,
238                                      GtkWidget     *widget);
239 static void cb_switch_page          (GimvThumbWin  *tw,
240                                      SwitchPage     action,
241                                      GtkWidget     *widget);
242 static void cb_focus                (GimvThumbWin  *tw,
243                                      FocusItem      item,
244                                      GtkWidget     *widget);
245 static void cb_toggle_view          (GimvThumbWin  *tw,
246                                      GimvComponentType item,
247                                      GtkWidget     *widget);
248 static void cb_toggle_show          (GimvThumbWin  *tw,
249                                      guint          action,
250                                      GtkWidget     *widget);
251 static void cb_switch_player        (GimvThumbWin  *tw,
252                                      GimvImageViewPlayerVisibleType visible,
253                                      GtkWidget     *widget);
254 static void cb_toggle_maximize      (GimvThumbWin  *tw,
255                                      guint          action,
256                                      GtkWidget     *widget);
257 /*
258   static void cb_toggle_fullscreen    (GimvThumbWin   *tw,
259   guint          action,
260   GtkWidget     *widget);
261 */
262 static void cb_sort_item            (GimvThumbWin  *tw,
263                                      GimvSortItem   sortitem,
264                                      GtkWidget     *widget);
265 static void cb_sort_flag            (GimvThumbWin  *tw,
266                                      GimvSortFlag   sortflag,
267                                      GtkWidget     *widget);
268 static void cb_win_composition_menu (GtkMenuItem   *item,
269                                      gpointer       data);
270 
271 static void cb_file_submenu_show    (GtkWidget     *widget,
272                                      GimvThumbWin  *tw);
273 static void cb_file_submenu_hide    (GtkWidget     *widget,
274                                      GimvThumbWin  *tw);
275 static void cb_edit_submenu_show    (GtkWidget     *widget,
276                                      GimvThumbWin  *tw);
277 static void cb_edit_submenu_hide    (GtkWidget     *widget,
278                                      GimvThumbWin  *tw);
279 static void cb_view_submenu_show    (GtkWidget     *widget,
280                                      GimvThumbWin  *tw);
281 static void cb_view_submenu_hide    (GtkWidget     *widget,
282                                      GimvThumbWin  *tw);
283 static void cb_tab_submenu_show     (GtkWidget     *widget,
284                                      GimvThumbWin  *tw);
285 static void cb_tab_submenu_hide     (GtkWidget     *widget,
286                                      GimvThumbWin  *tw);
287 
288 /* callback function for toolbar buttons */
289 #ifdef USE_GTK2
290 static void cb_location_entry_enter              (GtkEditable  *entry,
291                                                   GimvThumbWin *tw);
292 #endif /* USE_GTK2 */
293 static void cb_location_entry_drag_data_received (GtkWidget *widget,
294                                                   GdkDragContext  *context,
295                                                   gint x, gint y,
296                                                   GtkSelectionData *seldata,
297                                                   guint     info,
298                                                   guint     time,
299                                                   gpointer  data);
300 static gboolean cb_location_entry_key_press (GtkWidget    *widget,
301                                              GdkEventKey  *event,
302                                              GimvThumbWin *tw);
303 static void cb_open_button                  (GtkWidget    *widget,
304                                              GimvThumbWin *tw);
305 static void cb_prefs_button                 (GtkWidget    *widget,
306                                              GimvThumbWin *tw);
307 static void cb_previous_button              (GtkWidget    *widget,
308                                              GimvThumbWin *tw);
309 static void cb_next_button                  (GtkWidget    *widget,
310                                              GimvThumbWin *tw);
311 static void cb_refresh_button               (GtkWidget    *widget,
312                                              GimvThumbWin *tw);
313 static void cb_skip_button                  (GtkWidget    *widget,
314                                              GimvThumbWin *tw);
315 static void cb_stop_button                  (GtkWidget    *widget,
316                                              GimvThumbWin *tw);
317 static gboolean cb_size_spinner_key_press   (GtkWidget    *widget,
318                                              GdkEventKey  *event,
319                                              GimvThumbWin *tw);
320 static void cb_quit_button                  (GtkWidget    *widget,
321                                              GimvThumbWin *tw);
322 static void cb_display_mode_menu            (GtkWidget    *widget,
323                                              GimvThumbWin *tw);
324 
325 /* other callback functions */
326 static void cb_thumb_notebook_switch_page (GtkNotebook      *notebook,
327                                            GtkNotebookPage  *page,
328                                            gint              pagenum,
329                                            GimvThumbWin     *tw);
330 static void cb_tab_close_button_clicked   (GtkWidget        *button,
331                                            GimvThumbWin     *tw);
332 static void cb_com_drag_begin             (GtkWidget        *widget,
333                                            GdkDragContext   *context,
334                                            gpointer          data);
335 static void cb_com_drag_data_get          (GtkWidget        *widget,
336                                            GdkDragContext   *context,
337                                            GtkSelectionData *seldata,
338                                            guint             info,
339                                            guint             time,
340                                            gpointer          data);
341 static void cb_notebook_drag_data_received(GtkWidget        *widget,
342                                            GdkDragContext   *context,
343                                            gint x, gint y,
344                                            GtkSelectionData *seldata,
345                                            guint             info,
346                                            guint             time,
347                                            gpointer          data);
348 static void cb_tab_drag_data_received     (GtkWidget        *widget,
349                                            GdkDragContext   *context,
350                                            gint x, gint y,
351                                            GtkSelectionData *seldata,
352                                            guint             info,
353                                            guint             time,
354                                            gpointer          data);
355 static void cb_com_swap_drag_data_received(GtkWidget        *widget,
356                                            GdkDragContext   *context,
357                                            gint x, gint y,
358                                            GtkSelectionData *seldata,
359                                            guint             info,
360                                            guint             time,
361                                            gpointer          data);
362 #ifdef USE_GTK2   /* FIXME */
363 static gboolean cb_focus_in               (GtkWidget        *widget,
364                                            GdkEventFocus    *event,
365                                            GimvThumbWin     *tw);
366 static gboolean cb_focus_out              (GtkWidget        *widget,
367                                            GdkEventFocus    *event,
368                                            GimvThumbWin     *tw);
369 #endif /* USE_GTK2 */
370 
371 
372 /******************************************************************************
373  *
374  *   Parts of thumbnail window.
375  *
376  ******************************************************************************/
377 /* for main manu */
378 GtkItemFactoryEntry gimv_thumb_win_menu_items[] =
379 {
380    {N_("/_File"),                       NULL,         NULL,     0,               "<Branch>"},
381    {N_("/_File/_Open..."),              "<control>F", cb_open,  OPEN_FILE,       NULL},
382    {N_("/_File/New _Image Window"),     "<control>I", cb_open,  OPEN_IMAGEWIN,   NULL},
383    {N_("/_File/New _Window"),           "<control>W", cb_open,  OPEN_THUMBWIN,   NULL},
384    {N_("/_File/New _Tab"),              "<control>T", cb_open,  OPEN_THUMBTAB,   NULL},
385    {N_("/_File/---"),                   NULL,         NULL,     0,               "<Separator>"},
386    {N_("/_File/Close Ta_b"),            "Q",          cb_close, CLOSE_THUMBTAB,  NULL},
387    {N_("/_File/_Close Window"),         "<control>Q", cb_close, CLOSE_THUMBWIN,  NULL},
388    {N_("/_File/_Quit"),                 "<control>C", cb_close, CLOSE_ALL,       NULL},
389 
390    {N_("/_Edit"),                       NULL,         NULL,             0,            "<Branch>"},
391    {N_("/_Edit/_Select All"),           "<control>A", cb_select_all,    TRUE,         NULL},
392    {N_("/_Edit/U_nselect All"),         "<control>N", cb_select_all,    FALSE,        NULL},
393    {N_("/_Edit/---"),                   NULL,         NULL,             0,            "<Separator>"},
394    {N_("/_Edit/_Refresh List"),         "<shift><control>R", cb_refresh_list,   0,    NULL},
395    {N_("/_Edit/Reload _Cache"),         "<shift>R",   cb_reload,        LOAD_CACHE,   NULL},
396    {N_("/_Edit/_Update All Thumbnail"), "<control>R", cb_reload,        CREATE_THUMB, NULL},
397    {N_("/_Edit/---"),                   NULL,         NULL,             0,            "<Separator>"},
398    /*
399    {N_("/_Edit/Clear cache for _this tab"), NULL,     cb_clear_cache,   CLEAR_CACHE_TAB, NULL},
400    */
401    {N_("/_Edit/R_ename..."),            "<shift>E",   cb_file_operate,  FILE_RENAME, NULL},
402    {N_("/_Edit/Co_py Files To..."),     "<shift>C",   cb_file_operate,  FILE_COPY,   NULL},
403    {N_("/_Edit/_Move Files To..."),     "<shift>M",   cb_file_operate,  FILE_MOVE,   NULL},
404    {N_("/_Edit/_Link Files To..."),     "<shift>L",   cb_file_operate,  FILE_LINK,   NULL},
405    {N_("/_Edit/Remo_ve file..."),       "<del>",      cb_file_operate,  FILE_REMOVE, NULL},
406    {N_("/_Edit/---"),                   NULL,         NULL,             0,            "<Separator>"},
407    {N_("/_Edit/_Options..."),           "<control>O", cb_open,          OPEN_PREFS,   NULL},
408 
409    {N_("/_View"), NULL, NULL, 0, "<Branch>"},
410 
411    {N_("/_Tab"),                       NULL,         NULL,              0,              "<Branch>"},
412    {N_("/_Tab/_Tab Position"),         NULL,         NULL,              0,              "<Branch>"},
413    {N_("/_Tab/_Tab Position/_Top"),    NULL,         cb_switch_tab_pos, GTK_POS_TOP,    "<RadioItem>"},
414    {N_("/_Tab/_Tab Position/_Bottom"), NULL,         cb_switch_tab_pos, GTK_POS_BOTTOM, "/Tab/Tab Position/Top"},
415    {N_("/_Tab/_Tab Position/_Left"),   NULL,         cb_switch_tab_pos, GTK_POS_LEFT,   "/Tab/Tab Position/Bottom"},
416    {N_("/_Tab/_Tab Position/_Right"),  NULL,         cb_switch_tab_pos, GTK_POS_RIGHT,  "/Tab/Tab Position/Left"},
417    {N_("/_Tab/---"),                   NULL,         NULL,              0,              "<Separator>"},
418    {N_("/_Tab/_First Page"),           "k",          cb_switch_page,    FIRST,          NULL},
419    {N_("/_Tab/_Last Page"),            "J",          cb_switch_page,    LAST,           NULL},
420    {N_("/_Tab/_Next Page"),            "L",          cb_switch_page,    NEXT,           NULL},
421    {N_("/_Tab/_Previous Page"),        "H",          cb_switch_page,    PREV,           NULL},
422    {N_("/_Tab/---"),                   NULL,         NULL,              0,              "<Separator>"},
423    {N_("/_Tab/Move tab for_ward"),     "<shift>F",   cb_move_tab,       LEFT,           NULL},
424    {N_("/_Tab/Move tab _backward"),    "<shift>B",   cb_move_tab,       RIGHT,          NULL},
425    {N_("/_Tab/_Detach tab"),           "<control>D", cb_cut_out_tab,    0,              NULL},
426 
427    {N_("/_Action"),                        NULL,            NULL,     0,              "<Branch>"},
428    {N_("/_Action/_Focus"),                 NULL,            NULL,     0,              "<Branch>"},
429    {N_("/_Action/_Focus/_Directory View"), "<shift><alt>D", cb_focus, DIR_VIEW,       NULL},
430    {N_("/_Action/_Focus/_Thumbnail View"), "<shift><alt>T", cb_focus, THUMBNAIL_VIEW, NULL},
431    {N_("/_Action/_Focus/_Preview"),        "<shift><alt>P", cb_focus, PREVIEW,        NULL},
432    {N_("/_Action/_Focus/_Location Entry"), "<shift><alt>L", cb_focus, LOCATION_ENTRY, NULL},
433 #if 0
434    {N_("/_Action/_Directory View"),        NULL,            NULL,     0,              "<Branch>"},
435    {N_("/_Action/_Thumbnail View"),        NULL,            NULL,     0,              "<Branch>"},
436    {N_("/_Action/_Preview"),               NULL,            NULL,     0,              "<Branch>"},
437    {N_("/_Action/_Preview/_Next"),         NULL,            cb_preview_move,     0,   NULL},
438    {N_("/_Action/_Preview/_Previous"),     NULL,            cb_preview_move,     0,   NULL},
439 #endif
440 
441    {N_("/Too_l"),                      NULL,         NULL,              0,              "<Branch>"},
442    {N_("/Too_l/_Clear all cache"),     NULL,         cb_clear_cache,    CLEAR_CACHE_ALL, NULL},
443    {N_("/Too_l/---"),                  NULL,         NULL,              0,              "<Separator>"},
444    {N_("/Too_l/_Find duplicates"),     NULL,         NULL,              0,              "<Branch>"},
445    {N_("/Too_l/---"),                  NULL,         NULL,              0,              "<Separator>"},
446    {N_("/Too_l/_Wallpaper setting"),   NULL,         NULL,              0,               "<Branch>"},
447 
448    {N_("/_Help"), NULL, NULL, 0, "<LastBranch>"},
449    {NULL, NULL, NULL, 0, NULL},
450 };
451 
452 
453 /* for "View" sub menu */
454 GtkItemFactoryEntry gimv_thumb_win_view_items [] =
455 {
456    {N_("/_Sort File List"),        NULL,         NULL,                 0,              "<Branch>"},
457    {N_("/_Layout"),                NULL,         NULL,                 0,              "<Branch>"},
458    {N_("/_Layout/Layout_0"),       "<control>0", cb_switch_layout,     0,              "<RadioItem>"},
459    {N_("/_Layout/Layout_1"),       "<control>1", cb_switch_layout,     1,              "/Layout/Layout0"},
460    {N_("/_Layout/Layout_2"),       "<control>2", cb_switch_layout,     2,              "/Layout/Layout1"},
461    {N_("/_Layout/Layout_3"),       "<control>3", cb_switch_layout,     3,              "/Layout/Layout2"},
462    {N_("/_Layout/Layout_4"),       "<control>4", cb_switch_layout,     4,              "/Layout/Layout3"},
463    {N_("/_Layout/_Custom"),        NULL,         cb_switch_layout,     -1,             "/Layout/Layout4"},
464    {N_("/_Layout/---"),            NULL,         NULL,                 0,              "<Separator>"},
465    {N_("/_Layout/Window _Composition"), NULL,    NULL,                 0,              "<Branch>"},
466 
467    {N_("/---"),                    NULL,         NULL,                 0,              "<Separator>"},
468 
469    {N_("/S_lideshow"),            "<control>S",  cb_slideshow,         0,              NULL},
470    {N_("/Slideshow Opt_ions"),    NULL,          NULL,                 0,                       "<Branch>"},
471    {N_("/Slideshow Opt_ions/Start from the _first"),   NULL, cb_slideshow_order,     SLIDESHOW_START_FROM_FIRST,    "<RadioItem>"},
472    {N_("/Slideshow Opt_ions/Start from the se_lected"),NULL, cb_slideshow_order,     SLIDESHOW_START_FROM_SELECTED, "/Slideshow Options/Start from the first"},
473 #ifdef USE_GTK2
474    {N_("/Slideshow Opt_ions/_Random order"),           NULL, cb_slideshow_order,     SLIDESHOW_RANDOM_ORDER,        "/Slideshow Options/Start from the selected"},
475 #endif /* USE_GTK2 */
476    {N_("/Slideshow Opt_ions/---"),                     NULL, NULL,                   0,                             "<Separator>"},
477    {N_("/Slideshow Opt_ions/_Selected only"),          NULL, cb_slideshow_selected,  0,                             "<CheckItem>"},
478    {N_("/Slideshow Opt_ions/---"),                     NULL, NULL,                   0,                             "<Separator>"},
479    {N_("/Slideshow Opt_ions/Images _and movies"),      NULL, cb_slideshow_file_type, SLIDESHOW_IMAGES_AND_MOVIES,   "<RadioItem>"},
480    {N_("/Slideshow Opt_ions/_Images only"),            NULL, cb_slideshow_file_type, SLIDESHOW_IMAGES_ONLY,         "/Slideshow Options/Images and movies"},
481    {N_("/Slideshow Opt_ions/_Movies only"),            NULL, cb_slideshow_file_type, SLIDESHOW_MOVIES_ONLY,         "/Slideshow Options/Images only"},
482 
483    {N_("/---"),                    NULL,         NULL,                 0,              "<Separator>"},
484 
485    {N_("/_Directory View"),        "<shift>D",   cb_toggle_view,       GIMV_COM_DIR_VIEW,   "<ToggleItem>"},
486    {N_("/_Preview"),               "<shift>P",   cb_toggle_view,       GIMV_COM_IMAGE_VIEW, "<ToggleItem>"},
487    {N_("/_Menu Bar"),              "M",          cb_toggle_show,       MENUBAR,        "<ToggleItem>"},
488    {N_("/T_ool Bar"),              "N",          cb_toggle_show,       TOOLBAR,        "<CheckItem>"},
489    {N_("/Dir_View Tool Bar"),      "<shift>N",   cb_toggle_show,       DIR_TOOLBAR,    "<CheckItem>"},
490    {N_("/St_atus Bar"),            "V",          cb_toggle_show,       STATUSBAR,      "<CheckItem>"},
491    {N_("/_Tab"),                   "B",          cb_toggle_show,       TAB,            "<CheckItem>"},
492    {N_("/Ta_b (Preview)"),         "<shift>Z",   cb_toggle_show,       PREVIEW_TAB,    "<CheckItem>"},
493    {N_("/_Player"),                NULL,         NULL,                 0,              "<Branch>"},
494    {N_("/_Player/_Show"),          NULL,         cb_switch_player,     GimvImageViewPlayerVisibleShow, "<RadioItem>"},
495    {N_("/_Player/_Hide"),          NULL,         cb_switch_player,     GimvImageViewPlayerVisibleHide, "/Player/Show"},
496    {N_("/_Player/_Auto"),          NULL,         cb_switch_player,     GimvImageViewPlayerVisibleAuto, "/Player/Hide"},
497 
498    {N_("/---"),                    NULL,         NULL,                 0,              "<Separator>"},
499 
500    {N_("/Ma_ximize"),              "F",          cb_toggle_maximize,   0,              "<ToggleItem>"},
501    /* {N_("/_Full Screen"),        "F",          cb_toggle_fullscreen, 0,              "<ToggleItem>"}, */
502    {NULL, NULL, NULL, 0, NULL},
503 };
504 
505 
506 /* for "Sort File List" sub menu */
507 GtkItemFactoryEntry gimv_thumb_win_sort_items [] =
508 {
509    {N_("/by _Name"),               NULL, cb_sort_item,      GIMV_SORT_NAME,   "<RadioItem>"},
510    {N_("/by _Access Time"),        NULL, cb_sort_item,      GIMV_SORT_ATIME,  "/by Name"},
511    {N_("/by _Modification Time"),  NULL, cb_sort_item,      GIMV_SORT_MTIME,  "/by Access Time"},
512    {N_("/by _Change Time"),        NULL, cb_sort_item,      GIMV_SORT_CTIME,  "/by Modification Time"},
513    {N_("/by _Size"),               NULL, cb_sort_item,      GIMV_SORT_SIZE,   "/by Change Time"},
514    {N_("/by _Type"),               NULL, cb_sort_item,      GIMV_SORT_TYPE,   "/by Size"},
515    {N_("/by Image _Width"),        NULL, cb_sort_item,      GIMV_SORT_WIDTH,  "/by Type"},
516    {N_("/by Image _Height"),       NULL, cb_sort_item,      GIMV_SORT_HEIGHT, "/by Image Width"},
517    {N_("/by Image Ar_ea"),         NULL, cb_sort_item,      GIMV_SORT_AREA,   "/by Image Height"},
518    {N_("/---"),                    NULL, NULL,              0,                "<Separator>"},
519    {N_("/_Reverse Order"),         NULL, cb_sort_flag,      GIMV_SORT_REVERSE,"<CheckItem>"},
520    {N_("/---"),                    NULL, NULL,              0,                "<Separator>"},
521    {N_("/Case _insensitive"),      NULL, cb_sort_flag,      GIMV_SORT_CASE_INSENSITIVE, "<CheckItem>"},
522    {N_("/_Directory insensitive"), NULL, cb_sort_flag,      GIMV_SORT_DIR_INSENSITIVE,  "<CheckItem>"},
523    {NULL, NULL, NULL, 0, NULL},
524 };
525 
526 
527 /* for layout */
528 GimvThumbwinComposeType compose_type[] =
529 {
530    {TRUE,  FALSE, FALSE, {GIMV_COM_DIR_VIEW,   GIMV_COM_THUMB_VIEW, GIMV_COM_IMAGE_VIEW}},
531    {TRUE,  FALSE, TRUE,  {GIMV_COM_IMAGE_VIEW, GIMV_COM_DIR_VIEW,   GIMV_COM_THUMB_VIEW}},
532    {FALSE, TRUE,  TRUE,  {GIMV_COM_IMAGE_VIEW, GIMV_COM_DIR_VIEW,   GIMV_COM_THUMB_VIEW}},
533    {TRUE,  FALSE, TRUE,  {GIMV_COM_THUMB_VIEW, GIMV_COM_DIR_VIEW,   GIMV_COM_IMAGE_VIEW}},
534    {FALSE, TRUE,  TRUE,  {GIMV_COM_THUMB_VIEW, GIMV_COM_DIR_VIEW,   GIMV_COM_IMAGE_VIEW}},
535 };
536 gint compose_type_num = sizeof (compose_type) / sizeof (compose_type[0]);
537 
538 
539 static gboolean win_comp[][3] = {
540    {TRUE,  FALSE, FALSE},
541    {FALSE, TRUE,  FALSE},
542    {TRUE,  FALSE, TRUE},
543    {FALSE, TRUE,  TRUE},
544    {FALSE, FALSE, FALSE},
545    {TRUE,  TRUE,  FALSE},
546 };
547 
548 
549 static gint win_comp_icon[][12] = {
550    {0, 1, 0, 2, 1, 2, 0, 1, 1, 2, 1, 2},
551    {0, 2, 0, 1, 0, 1, 1, 2, 1, 2, 1, 2},
552    {0, 1, 0, 1, 1, 2, 0, 2, 0, 1, 1, 2},
553    {0, 1, 0, 1, 1, 2, 0, 1, 0, 2, 1, 2},
554    {0, 1, 0, 1, 0, 1, 1, 2, 0, 1, 2, 3},
555    {0, 1, 0, 1, 1, 2, 0, 1, 2, 3, 0, 1},
556 };
557 
558 
559 static GtkWindowClass *parent_class = NULL;
560 static GList *ThumbWinList = NULL;
561 
562 
563 GtkType
gimv_thumb_win_get_type(void)564 gimv_thumb_win_get_type (void)
565 {
566    static GtkType gimv_thumb_win_type = 0;
567 
568    if (!gimv_thumb_win_type) {
569       static const GtkTypeInfo gimv_thumb_win_info = {
570          "GimvThumbWin",
571          sizeof (GimvThumbWin),
572          sizeof (GimvThumbWinClass),
573          (GtkClassInitFunc) gimv_thumb_win_class_init,
574          (GtkObjectInitFunc) gimv_thumb_win_init,
575          NULL,
576          NULL,
577          (GtkClassInitFunc) NULL,
578       };
579 
580       gimv_thumb_win_type = gtk_type_unique (GTK_TYPE_WINDOW,
581                                              &gimv_thumb_win_info);
582    }
583 
584    return gimv_thumb_win_type;
585 }
586 
587 
588 static void
gimv_thumb_win_class_init(GimvThumbWinClass * klass)589 gimv_thumb_win_class_init (GimvThumbWinClass *klass)
590 {
591    GtkObjectClass *object_class;
592    GtkWidgetClass *widget_class;
593 
594    object_class = (GtkObjectClass *) klass;
595    widget_class = (GtkWidgetClass *) klass;
596    parent_class = gtk_type_class (GTK_TYPE_WINDOW);
597 
598    object_class->destroy = gimv_thumb_win_destroy;
599 
600    widget_class->realize         = gimv_thumb_win_realize;
601    widget_class->delete_event    = gimv_thumb_win_delete_event;
602 }
603 
604 
605 static void
gimv_thumb_win_init(GimvThumbWin * tw)606 gimv_thumb_win_init (GimvThumbWin *tw)
607 {
608    GtkWidget *vbox, *hbox;
609    GtkWidget *separator;
610    GtkWidget *entry;
611    gint num, summary_mode;
612    gboolean loading;
613    gchar **summary_mode_labels = NULL;
614 
615    tw->dv            = NULL;
616    tw->iv            = NULL;
617    tw->cv            = NULL;
618    tw->filenum       = 0;
619    tw->pagenum       = 0;
620    tw->filesize      = 0;
621    tw->newpage_count = 0;
622    tw->open_dialog   = NULL;
623    tw->pane_size1    = conf.thumbwin_pane_size1;
624    tw->pane_size2    = conf.thumbwin_pane_size2;
625    tw->show_dirview  = conf.thumbwin_show_dir_view;
626    tw->show_preview  = conf.thumbwin_show_preview;
627    tw->player_visible= conf.preview_player_visible;
628    tw->layout_type   = conf.thumbwin_layout_type;
629    tw->tab_pos       = conf.thumbwin_tab_pos;
630    tw->sortitem      = conf.thumbwin_sort_type;
631    tw->sortflags     = 0;
632    if (conf.thumbwin_sort_reverse)
633       tw->sortflags |= GIMV_SORT_REVERSE;
634    if (conf.thumbwin_sort_ignore_case)
635       tw->sortflags |= GIMV_SORT_CASE_INSENSITIVE;
636    if (conf.thumbwin_sort_ignore_dir)
637       tw->sortflags |= GIMV_SORT_DIR_INSENSITIVE;
638    tw->changing_layout = FALSE;
639 
640    tw->priv = g_new0 (GimvThumbWinPriv, 1);
641    tw->priv->slideshow_order         = SLIDESHOW_START_FROM_FIRST;
642    tw->priv->slideshow_selected_only = FALSE;
643    tw->priv->slideshow_file_type     = SLIDESHOW_IMAGES_AND_MOVIES;
644 
645    ThumbWinList = g_list_append (ThumbWinList, tw);
646 
647 #ifdef USE_GTK2
648    tw->accel_group_list = NULL;
649 #endif /* USE_GTK2 */
650 
651    /* window */
652    gtk_widget_set_name (GTK_WIDGET (tw), "ThumbWin");
653    gtk_window_set_title (GTK_WINDOW (tw),
654                          _(GIMV_PROG_NAME" -Thumbnail Window-"));
655    gtk_window_set_wmclass(GTK_WINDOW(tw), "thumbwin", "GImageView");
656    gtk_window_set_default_size (GTK_WINDOW(tw),
657                                 conf.thumbwin_width, conf.thumbwin_height);
658    gtk_window_set_policy(GTK_WINDOW(tw), TRUE, TRUE, FALSE);
659 
660    /* Main vbox */
661    vbox = gtk_vbox_new (FALSE, 0);
662    tw->main_vbox = vbox;
663    gtk_container_add (GTK_CONTAINER (tw), vbox);
664    gtk_widget_show (vbox);
665 
666    /* Menu Bar */
667    tw->menubar_handle = gtk_handle_box_new();
668    gtk_widget_set_name (tw->menubar_handle, "MenuBarContainer");
669    gtk_container_set_border_width (GTK_CONTAINER(tw->menubar_handle), 2);
670    gtk_box_pack_start(GTK_BOX(vbox), tw->menubar_handle, FALSE, FALSE, 0);
671    gtk_widget_show (tw->menubar_handle);
672 
673    /* toolbar */
674    tw->toolbar_handle = gtk_handle_box_new();
675    gtk_widget_set_name (tw->toolbar_handle, "ToolBarContainer");
676    gtk_container_set_border_width (GTK_CONTAINER(tw->toolbar_handle), 2);
677    gtk_box_pack_start(GTK_BOX(vbox), tw->toolbar_handle, FALSE, FALSE, 0);
678    gtk_widget_show (tw->toolbar_handle);
679 
680    hbox = gtk_hbox_new (FALSE, 0);
681    gtk_container_add(GTK_CONTAINER(tw->toolbar_handle), hbox);
682    gtk_widget_show (hbox);
683 
684    tw->toolbar = create_toolbar (tw, tw->toolbar_handle);
685    gtk_box_pack_start (GTK_BOX (hbox), tw->toolbar, FALSE, FALSE, 0);
686    gtk_widget_show (tw->toolbar);
687    gtk_toolbar_set_style (GTK_TOOLBAR(tw->toolbar), conf.thumbwin_toolbar_style);
688 
689    /* location entry */
690    tw->location_entry = entry = gtk_entry_new ();
691    gtk_widget_set_name (tw->location_entry, "LocationEntry");
692    gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
693    gtk_signal_connect_after (GTK_OBJECT(entry), "key-press-event",
694                              GTK_SIGNAL_FUNC(cb_location_entry_key_press), tw);
695    dnd_dest_set (tw->location_entry, dnd_types_uri, dnd_types_uri_num);
696    gtk_signal_connect(GTK_OBJECT (tw->location_entry), "drag_data_received",
697                       GTK_SIGNAL_FUNC (cb_location_entry_drag_data_received), tw);
698 #ifdef USE_GTK2
699    gtk_signal_connect(GTK_OBJECT (tw->location_entry), "activate",
700                       GTK_SIGNAL_FUNC (cb_location_entry_enter), tw);
701 #endif /* USE_GTK2 */
702 #ifdef USE_GTK2 /* FIXME */
703    gtk_signal_connect(GTK_OBJECT (tw->location_entry), "focus_in_event",
704                       GTK_SIGNAL_FUNC (cb_focus_in), tw);
705    gtk_signal_connect(GTK_OBJECT (tw->location_entry), "focus_out_event",
706                       GTK_SIGNAL_FUNC (cb_focus_out), tw);
707 #endif /* USE_GTK2 */
708    gtk_widget_show (entry);
709 
710    /* option menu for display mode */
711    if (!summary_mode_labels)
712       summary_mode_labels = gimv_thumb_view_get_summary_mode_labels (&num);
713 
714    summary_mode = gimv_thumb_view_label_to_num (conf.thumbwin_disp_mode);
715    tw->thumbview_summary_mode = gimv_thumb_view_num_to_label (summary_mode);
716    if (summary_mode < 0)
717       summary_mode = gimv_thumb_view_label_to_num (GIMV_THUMB_VIEW_DEFAULT_SUMMARY_MODE);
718 
719    tw->summary_mode_menu = create_option_menu ((const gchar **)summary_mode_labels,
720                                                summary_mode,
721                                                cb_display_mode_menu, tw);
722    gtk_widget_set_name (tw->summary_mode_menu, "DispModeOptionMenu");
723    add_accel_label_to_disp_mode_menu (tw->summary_mode_menu, GTK_WIDGET (tw));
724    gtk_box_pack_end (GTK_BOX (hbox), tw->summary_mode_menu, FALSE, FALSE, 0);
725    gtk_widget_show (tw->summary_mode_menu);
726 
727    /* separator */
728    separator = gtk_hseparator_new ();
729    gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
730    gtk_widget_show (separator);
731 
732    /* main contents */
733    tw->main_contents = thumbnail_window_contents_new (tw);
734    gtk_widget_set_name (tw->main_contents, "MainArea");
735    gtk_container_add (GTK_CONTAINER (vbox), tw->main_contents);
736    gtk_widget_show (tw->main_contents);
737 
738    /* status bar */
739    hbox = gtk_hbox_new (FALSE, 0);
740    gtk_widget_set_name (hbox, "StatusBarContainer");
741    tw->status_bar_container = hbox;
742    gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
743    gtk_widget_show (hbox);
744 
745    tw->status_bar1 = gtk_statusbar_new ();
746    gtk_widget_set_name (tw->status_bar1, "StatusBar1");
747    gtk_container_border_width (GTK_CONTAINER (tw->status_bar1), 1);
748    gtk_widget_set_usize(tw->status_bar1, 150, -1);
749    gtk_box_pack_start (GTK_BOX (hbox), tw->status_bar1, TRUE, TRUE, 0);
750    gtk_widget_show (tw->status_bar1);
751    gtk_statusbar_push(GTK_STATUSBAR (tw->status_bar1), 1, _("New Window"));
752 
753    tw->status_bar2 = gtk_statusbar_new ();
754    gtk_widget_set_name (tw->status_bar2, "StatusBar2");
755    gtk_container_border_width (GTK_CONTAINER (tw->status_bar2), 1);
756    gtk_widget_set_usize(tw->status_bar2, 150, -1);
757    gtk_box_pack_start (GTK_BOX (hbox), tw->status_bar2, TRUE, TRUE, 0);
758    gtk_widget_show (tw->status_bar2);
759 
760    tw->progressbar = gtk_progress_bar_new();
761    gtk_widget_set_name (tw->progressbar, "ProgressBar");
762    gtk_box_pack_end (GTK_BOX (hbox), tw->progressbar, FALSE, FALSE, 0);
763    gtk_widget_show (tw->progressbar);
764 
765    /* create menus */
766    create_gimv_thumb_win_menus (tw);
767    sync_widget_state_to_menu (tw);
768 
769    /* create new tab */
770    /* gimv_thumb_win_create_new_tab (tw); */
771 
772    loading = files_loader_query_loading ();
773    if (loading) gimv_thumb_win_set_sensitive (tw, GIMV_THUMB_WIN_STATUS_LOADING);
774 
775 #ifdef USE_GTK2   /* FIXME */
776    if (tw->accel_group_list)
777       g_slist_free (tw->accel_group_list);
778    tw->accel_group_list
779       = g_slist_copy (gtk_accel_groups_from_object (G_OBJECT (tw)));
780    tw->accel_group_list = g_slist_reverse (tw->accel_group_list);
781 #endif /* USE_GTK2 */
782 }
783 
784 
785 GtkWidget *
gimv_thumb_win_new(void)786 gimv_thumb_win_new (void)
787 {
788    GimvThumbWin *tw = gtk_type_new (GIMV_TYPE_THUMB_WIN);
789 
790    return GTK_WIDGET (tw);
791 }
792 
793 
794 GimvThumbWin *
gimv_thumb_win_open_window(void)795 gimv_thumb_win_open_window (void)
796 {
797    GimvThumbWin *tw = GIMV_THUMB_WIN (gimv_thumb_win_new());
798 
799    gtk_widget_show (GTK_WIDGET (tw));
800 
801    return tw;
802 }
803 
804 
805 static void
gimv_thumb_win_destroy(GtkObject * object)806 gimv_thumb_win_destroy (GtkObject *object)
807 {
808    GimvThumbWin *tw = GIMV_THUMB_WIN (object);
809    GimvThumbView *tv;
810    GList *node;
811 
812    /* for inhibiting Gtk-WARNING */
813    tw->location_entry = NULL;
814    tw->button.size_spin = NULL;
815    tw->summary_mode_menu = NULL;
816 
817    node = g_list_first (gimv_thumb_view_get_list());
818    while (node) {
819       tv = node->data;
820       node = g_list_next (node);
821 
822       if (tv->tw == tw) {
823          if (tv->progress) {
824             tv->progress->status = WINDOW_DESTROYED;
825          } else {
826             gtk_object_unref (GTK_OBJECT (tv));
827          }
828       }
829 
830    }
831 
832    ThumbWinList = g_list_remove (ThumbWinList, tw);
833 
834    if (tw->priv) {
835       g_free(tw->priv);
836       tw->priv = NULL;
837    }
838 
839    if (GTK_OBJECT_CLASS (parent_class)->destroy)
840       GTK_OBJECT_CLASS (parent_class)->destroy (object);
841 
842    /* quit when last window */
843    if (!gimv_image_win_get_list() && !gimv_thumb_win_get_list()) {
844       gimv_quit();
845    }
846 }
847 
848 
849 static void
gimv_thumb_win_realize(GtkWidget * widget)850 gimv_thumb_win_realize (GtkWidget *widget)
851 {
852    GimvThumbWin *tw = GIMV_THUMB_WIN (widget);
853 
854    if (GTK_WIDGET_CLASS (parent_class)->realize)
855       GTK_WIDGET_CLASS (parent_class)->realize (widget);
856 
857    gimv_icon_stock_set_window_icon (GTK_WIDGET(tw)->window, "gimv_icon");
858    gtk_widget_grab_focus (tw->dv->dirtree);
859 }
860 
861 
862 static gboolean
gimv_thumb_win_delete_event(GtkWidget * widget,GdkEventAny * event)863 gimv_thumb_win_delete_event (GtkWidget *widget, GdkEventAny *event)
864 {
865    GimvThumbWin *tw = GIMV_THUMB_WIN (widget);
866    GimvThumbView *tv;
867    GList *node;
868 
869    if (GTK_WIDGET_CLASS (parent_class)->delete_event)
870       if (GTK_WIDGET_CLASS (parent_class)->delete_event (widget, event))
871          return TRUE;
872 
873    if (tw->status == GIMV_THUMB_WIN_STATUS_CHECKING_DUPLICATE) return TRUE;
874 
875    node = g_list_first (gimv_thumb_view_get_list());
876    while (node) {
877       tv = node->data;
878       node = g_list_next (node);
879 
880       if (tv->tw == tw) {
881          /* do not destroy this window while loading */
882          if (tv->progress) {
883             return TRUE;
884          }
885       }
886    }
887 
888    if (g_list_length (ThumbWinList) == 1 && conf.thumbwin_save_win_state)
889       gimv_thumb_win_save_state (tw);
890 
891    return FALSE;
892 }
893 
894 
895 static GtkWidget *
create_composition_icon(gint type)896 create_composition_icon (gint type)
897 {
898    GtkWidget *hbox, *table, *button, *label;
899    gint i, comp[4], n_types;
900    gchar buf[128];
901 
902    n_types = sizeof (win_comp_icon) / sizeof (gint) / 12;
903    if (type > n_types || type < 0)
904       return NULL;
905 
906    if (type < 4)
907       table = gtk_table_new (2, 2, FALSE);
908    else if (type == 4)
909       table = gtk_table_new (3, 1, FALSE);
910    else if (type == 5)
911       table = gtk_table_new (1, 3, FALSE);
912    else
913       return NULL;
914 
915    gtk_widget_set_usize (table, 24, 24);
916    gtk_widget_show (table);
917 
918    hbox = gtk_hbox_new (FALSE, 0);
919    gtk_widget_show (hbox);
920    gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, FALSE, 2);
921 
922    for (i = 0; i < 3; i++) {
923       comp[0] = win_comp_icon[type][i * 4];
924       comp[1] = win_comp_icon[type][i * 4 + 1];
925       comp[2] = win_comp_icon[type][i * 4 + 2];
926       comp[3] = win_comp_icon[type][i * 4 + 3];
927       button = gtk_button_new ();
928       gtk_widget_set_sensitive (button, FALSE);
929       GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
930       gtk_table_attach_defaults (GTK_TABLE (table), button,
931                                  comp[0], comp[1], comp[2], comp[3]);
932       gtk_widget_show (button);
933    }
934 
935    g_snprintf (buf, 128, _("Composition %d"), type);
936    label = gtk_label_new (buf);
937    gtk_widget_show (label);
938    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);
939 
940    return hbox;
941 }
942 
943 
944 static GtkWidget *
create_wincomp_sub_menu(GimvThumbWin * tw)945 create_wincomp_sub_menu (GimvThumbWin *tw)
946 {
947    GtkWidget *menu, *item, *icon;
948    /* GSList *group = NULL; */
949    gint i;
950 
951    menu = gtk_menu_new();
952    gtk_widget_show (menu);
953 
954    for (i = 0; i < 6; i++) {
955       /* item = gtk_menu_item_new (group); */
956       item = gtk_menu_item_new ();
957       gtk_object_set_data (GTK_OBJECT (item), "num", GINT_TO_POINTER (i));
958       icon = create_composition_icon (i);
959       gtk_container_add (GTK_CONTAINER (item), icon);
960       gtk_signal_connect (GTK_OBJECT (item), "activate",
961                           GTK_SIGNAL_FUNC (cb_win_composition_menu),
962                           tw);
963       /* group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (item)); */
964       gtk_menu_append (GTK_MENU (menu), item);
965       gtk_widget_show (item);
966    }
967 
968    return menu;
969 }
970 
971 
972 static void
cb_file_submenu_show(GtkWidget * widget,GimvThumbWin * tw)973 cb_file_submenu_show (GtkWidget *widget, GimvThumbWin *tw)
974 {
975    GtkItemFactory *ifactory;
976    GtkWidget *menuitem;
977 
978    g_return_if_fail (tw);
979 
980    if (tw->pagenum < 1) {
981       ifactory = gtk_item_factory_from_widget (tw->menubar);
982       menuitem = gtk_item_factory_get_item (ifactory, "/File/Close Tab");
983       gtk_widget_set_sensitive (menuitem, FALSE);
984    }
985 }
986 
987 
988 static void
cb_file_submenu_hide(GtkWidget * widget,GimvThumbWin * tw)989 cb_file_submenu_hide (GtkWidget *widget, GimvThumbWin *tw)
990 {
991    GtkItemFactory *ifactory;
992    GtkWidget *menuitem;
993 
994    g_return_if_fail (tw);
995 
996    ifactory = gtk_item_factory_from_widget (tw->menubar);
997    menuitem = gtk_item_factory_get_item (ifactory, "/File/Close Tab");
998    gtk_widget_set_sensitive (menuitem, TRUE);
999 }
1000 
1001 
1002 static void
cb_edit_submenu_show(GtkWidget * widget,GimvThumbWin * tw)1003 cb_edit_submenu_show (GtkWidget *widget, GimvThumbWin *tw)
1004 {
1005    GimvThumbView *tv;
1006    GList *list = NULL;
1007    gint len;
1008 
1009    g_return_if_fail (tw);
1010    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
1011    if (!tv || tv->mode == GIMV_THUMB_VIEW_MODE_ARCHIVE) {
1012       if (!tv) {
1013          gtk_widget_set_sensitive (tw->menuitem.select,   FALSE);
1014          gtk_widget_set_sensitive (tw->menuitem.unselect, FALSE);
1015          gtk_widget_set_sensitive (tw->menuitem.refresh,  FALSE);
1016          gtk_widget_set_sensitive (tw->menuitem.reload,   FALSE);
1017          gtk_widget_set_sensitive (tw->menuitem.recreate, FALSE);
1018       }
1019       gtk_widget_set_sensitive (tw->menuitem.rename,   FALSE);
1020       gtk_widget_set_sensitive (tw->menuitem.copy,     FALSE);
1021       gtk_widget_set_sensitive (tw->menuitem.move,     FALSE);
1022       gtk_widget_set_sensitive (tw->menuitem.link,     FALSE);
1023       gtk_widget_set_sensitive (tw->menuitem.delete,   FALSE);
1024    }
1025 
1026    if (!tv) return;
1027 
1028    list = gimv_thumb_view_get_selection_list (tv);
1029 
1030    if (list) {
1031       len = g_list_length (list);
1032       if (len > 1) {
1033          gtk_widget_set_sensitive (tw->menuitem.rename,   FALSE);
1034       }
1035       if (tv->mode == GIMV_THUMB_VIEW_MODE_DIR) {
1036          const gchar *dirname = gimv_thumb_view_get_path (tv);
1037          if (!iswritable (dirname)) {
1038             gtk_widget_set_sensitive (tw->menuitem.rename,   FALSE);
1039             gtk_widget_set_sensitive (tw->menuitem.move,     FALSE);
1040             gtk_widget_set_sensitive (tw->menuitem.delete,   FALSE);
1041          } else if (tv->mode == GIMV_THUMB_VIEW_MODE_COLLECTION) {
1042             /* FIXME */
1043          }
1044       }
1045    } else {
1046       gtk_widget_set_sensitive (tw->menuitem.rename,   FALSE);
1047       gtk_widget_set_sensitive (tw->menuitem.copy,     FALSE);
1048       gtk_widget_set_sensitive (tw->menuitem.move,     FALSE);
1049       gtk_widget_set_sensitive (tw->menuitem.link,     FALSE);
1050       gtk_widget_set_sensitive (tw->menuitem.delete,   FALSE);
1051    }
1052 
1053    if (list)
1054       g_list_free (list);
1055 }
1056 
1057 
1058 static void
cb_edit_submenu_hide(GtkWidget * widget,GimvThumbWin * tw)1059 cb_edit_submenu_hide (GtkWidget *widget, GimvThumbWin *tw)
1060 {
1061    g_return_if_fail (tw);
1062 
1063    gtk_widget_set_sensitive (tw->menuitem.select,   TRUE);
1064    gtk_widget_set_sensitive (tw->menuitem.unselect, TRUE);
1065    gtk_widget_set_sensitive (tw->menuitem.refresh,  TRUE);
1066    gtk_widget_set_sensitive (tw->menuitem.reload,   TRUE);
1067    gtk_widget_set_sensitive (tw->menuitem.recreate, TRUE);
1068    gtk_widget_set_sensitive (tw->menuitem.rename,   TRUE);
1069    gtk_widget_set_sensitive (tw->menuitem.copy,     TRUE);
1070    gtk_widget_set_sensitive (tw->menuitem.move,     TRUE);
1071    gtk_widget_set_sensitive (tw->menuitem.link,     TRUE);
1072    gtk_widget_set_sensitive (tw->menuitem.delete,   TRUE);
1073 }
1074 
1075 
1076 static void
cb_tool_submenu_show(GtkWidget * widget,GimvThumbWin * tw)1077 cb_tool_submenu_show (GtkWidget *widget, GimvThumbWin *tw)
1078 {
1079    GimvThumbView *tv;
1080    GtkItemFactory *ifactory;
1081    GtkWidget /* *menuitem1, */ *menuitem2;
1082 
1083    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
1084    if (!tv) {
1085       /* gtk_widget_set_sensitive (tw->menuitem.find_sim, FALSE); */
1086    }
1087 
1088    ifactory = gtk_item_factory_from_widget (tw->menubar);
1089    /* menuitem1 = gtk_item_factory_get_item (ifactory, "/Tool/Clear cache for this tab"); */
1090    menuitem2 = gtk_item_factory_get_item (ifactory, "/Tool/Clear all cache");
1091 
1092    if (!gimv_thumb_cache_can_clear (NULL, conf.cache_write_type))
1093        gtk_widget_set_sensitive (menuitem2, FALSE);
1094 
1095    /*
1096    if (tw->pagenum < 1 || !tv) {
1097       gtk_widget_set_sensitive (menuitem1, FALSE);
1098    } else {
1099       const gchar *path = thumbview_get_path (tv);
1100 
1101       if (path && *path && !thumbsupport_can_clear_cache (path, conf.cache_write_type))
1102           gtk_widget_set_sensitive (menuitem1, FALSE);
1103    }
1104    */
1105 }
1106 
1107 
1108 static void
cb_tool_submenu_hide(GtkWidget * widget,GimvThumbWin * tw)1109 cb_tool_submenu_hide (GtkWidget *widget, GimvThumbWin *tw)
1110 {
1111    GtkItemFactory *ifactory;
1112    GtkWidget *menuitem;
1113 
1114    g_return_if_fail (tw);
1115 
1116    /* gtk_widget_set_sensitive (tw->menuitem.find_sim, TRUE); */
1117 
1118    ifactory = gtk_item_factory_from_widget (tw->menubar);
1119    /*
1120    menuitem = gtk_item_factory_get_item (ifactory, "/Edit/Clear cache for this tab");
1121    gtk_widget_set_sensitive (menuitem,     TRUE);
1122    */
1123    menuitem = gtk_item_factory_get_item (ifactory, "/Tool/Clear all cache");
1124    gtk_widget_set_sensitive (menuitem, TRUE);
1125 }
1126 
1127 
1128 static void
cb_view_submenu_show(GtkWidget * widget,GimvThumbWin * tw)1129 cb_view_submenu_show (GtkWidget *widget, GimvThumbWin *tw)
1130 {
1131    GimvThumbView *tv;
1132    /*
1133      GtkItemFactory *ifactory;
1134      GtkWidget *menuitem;
1135    */
1136 
1137    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
1138 
1139    /*
1140      if (!tv || tv->mode == THUMB_VIEW_MODE_ARCHIVE) {
1141      ifactory = gtk_item_factory_from_widget (tw->view_menu);
1142      menuitem = gtk_item_factory_get_item (ifactory, "/Slideshow");
1143      gtk_widget_set_sensitive (menuitem, FALSE);
1144      }
1145    */
1146 }
1147 
1148 
1149 static void
cb_view_submenu_hide(GtkWidget * widget,GimvThumbWin * tw)1150 cb_view_submenu_hide (GtkWidget *widget, GimvThumbWin *tw)
1151 {
1152    /*
1153      GtkItemFactory *ifactory;
1154      GtkWidget *menuitem;
1155 
1156      ifactory = gtk_item_factory_from_widget (tw->view_menu);
1157      menuitem = gtk_item_factory_get_item (ifactory, "/Slideshow");
1158      gtk_widget_set_sensitive (menuitem, TRUE);
1159    */
1160 }
1161 
1162 
1163 static void
cb_tab_submenu_show(GtkWidget * widget,GimvThumbWin * tw)1164 cb_tab_submenu_show (GtkWidget *widget, GimvThumbWin *tw)
1165 {
1166    GtkItemFactory *ifactory;
1167    GtkWidget *menuitem;
1168 
1169    g_return_if_fail (tw);
1170 
1171    ifactory = gtk_item_factory_from_widget (tw->menubar);
1172 
1173    if (tw->pagenum < 1 || !gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE)) {
1174       menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Detach tab");
1175       gtk_widget_set_sensitive (menuitem, FALSE);
1176    }
1177 
1178    if (tw->pagenum < 2) {
1179       menuitem = gtk_item_factory_get_item (ifactory, "/Tab/First Page");
1180       gtk_widget_set_sensitive (menuitem, FALSE);
1181       menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Last Page");
1182       gtk_widget_set_sensitive (menuitem, FALSE);
1183       menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Next Page");
1184       gtk_widget_set_sensitive (menuitem, FALSE);
1185       menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Previous Page");
1186       gtk_widget_set_sensitive (menuitem, FALSE);
1187       menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Move tab forward");
1188       gtk_widget_set_sensitive (menuitem, FALSE);
1189       menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Move tab backward");
1190       gtk_widget_set_sensitive (menuitem, FALSE);
1191    }
1192 }
1193 
1194 
1195 static void
cb_tab_submenu_hide(GtkWidget * widget,GimvThumbWin * tw)1196 cb_tab_submenu_hide (GtkWidget *widget, GimvThumbWin *tw)
1197 {
1198    GtkItemFactory *ifactory;
1199    GtkWidget *menuitem;
1200 
1201    g_return_if_fail (tw);
1202 
1203    ifactory = gtk_item_factory_from_widget (tw->menubar);
1204 
1205    menuitem = gtk_item_factory_get_item (ifactory, "/Tab/First Page");
1206    gtk_widget_set_sensitive (menuitem, TRUE);
1207    menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Last Page");
1208    gtk_widget_set_sensitive (menuitem, TRUE);
1209    menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Next Page");
1210    gtk_widget_set_sensitive (menuitem, TRUE);
1211    menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Previous Page");
1212    gtk_widget_set_sensitive (menuitem, TRUE);
1213    menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Move tab forward");
1214    gtk_widget_set_sensitive (menuitem, TRUE);
1215    menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Move tab backward");
1216    gtk_widget_set_sensitive (menuitem, TRUE);
1217    menuitem = gtk_item_factory_get_item (ifactory, "/Tab/Detach tab");
1218    gtk_widget_set_sensitive (menuitem, TRUE);
1219 }
1220 
1221 
1222 #if 0
1223 #warning should be implemented as customizable launcher.
1224 #endif
1225 static void
cb_wallpaper_setting(GtkWidget * menuitem,GimvThumbWin * tw)1226 cb_wallpaper_setting (GtkWidget *menuitem, GimvThumbWin *tw)
1227 {
1228    const gchar *str;
1229    gchar *cmd;
1230 
1231    str = gtk_object_get_data (GTK_OBJECT (menuitem), "command");
1232    if (!str) return;
1233 
1234    cmd = g_strconcat (str, " &", NULL);
1235    system (cmd);
1236 
1237    g_free (cmd);
1238 }
1239 
1240 
1241 static GtkWidget *
create_wallpaper_submenu(GimvThumbWin * tw)1242 create_wallpaper_submenu (GimvThumbWin *tw)
1243 {
1244    GtkWidget *menu;
1245    GtkWidget *menu_item;
1246    gint i;
1247    gchar **menus, **pair;
1248 
1249    menus = g_strsplit (conf.wallpaper_menu, ";", -1);
1250    if (!menus) return NULL;
1251 
1252    menu = gtk_menu_new();
1253 
1254    /* count items num */
1255    for (i = 0; menus[i]; i++) {
1256       if (!menus[i] || !*menus[i]) continue;
1257 
1258       pair = g_strsplit (menus[i], ",", 2);
1259 
1260       if (pair && pair[0] && pair[1]) {
1261          menu_item = gtk_menu_item_new_with_label (pair[0]);
1262          gtk_object_set_data_full (GTK_OBJECT (menu_item), "command",
1263                                    g_strdup (pair[1]),
1264                                    (GtkDestroyNotify) g_free);
1265          gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
1266                              GTK_SIGNAL_FUNC (cb_wallpaper_setting), tw);
1267          gtk_menu_append (GTK_MENU (menu), menu_item);
1268          gtk_widget_show (menu_item);
1269       }
1270 
1271       g_strfreev (pair);
1272    }
1273 
1274    g_strfreev (menus);
1275 
1276    return menu;
1277 }
1278 
1279 
1280 static void
create_gimv_thumb_win_menus(GimvThumbWin * tw)1281 create_gimv_thumb_win_menus (GimvThumbWin *tw)
1282 {
1283    static GtkItemFactoryEntry *entries = NULL;
1284    GtkWidget *item, *dupmenu;
1285    GtkItemFactory *ifactory;
1286    guint n_menu_items, layout;
1287    GtkWidget *submenu, *help;
1288    const gchar **labels;
1289    gint i = 0;
1290 
1291    /* main menu */
1292    n_menu_items = sizeof (gimv_thumb_win_menu_items)
1293       / sizeof (gimv_thumb_win_menu_items[0]) - 1;
1294    tw->menubar = menubar_create (GTK_WIDGET (tw), gimv_thumb_win_menu_items,
1295                                  n_menu_items, "<ThumbWinMainMenu>", tw);
1296 
1297    gtk_container_add(GTK_CONTAINER(tw->menubar_handle), tw->menubar);
1298 #ifndef USE_GTK2
1299    gtk_menu_bar_set_shadow_type(GTK_MENU_BAR(tw->menubar), GTK_SHADOW_NONE);
1300 #endif /* USE_GTK2 */
1301    gtk_widget_show (tw->menubar);
1302 
1303    /* sub menu */
1304    n_menu_items = sizeof(gimv_thumb_win_view_items)
1305       / sizeof(gimv_thumb_win_view_items[0]) - 1;
1306    tw->view_menu = menu_create_items(GTK_WIDGET (tw), gimv_thumb_win_view_items,
1307                                      n_menu_items, "<ThumbWinViewSubMenu>", tw);
1308    n_menu_items = sizeof(gimv_thumb_win_sort_items)
1309       / sizeof(gimv_thumb_win_sort_items[0]) - 1;
1310    tw->sort_menu = menu_create_items(GTK_WIDGET (tw), gimv_thumb_win_sort_items,
1311                                      n_menu_items, "<ThumbWinSortSubMenu>", tw);
1312    tw->comp_menu = create_wincomp_sub_menu (tw);
1313    help = gimvhelp_create_menu (GTK_WIDGET (tw));
1314 
1315    /* duplicates finder sub menu */
1316    labels = gimv_dupl_finder_get_algol_types ();
1317    for (i = 0; labels && labels[i]; i++) ;
1318    if (!entries && i > 0) {
1319       entries = g_new0 (GtkItemFactoryEntry, i);
1320       for (i = 0; labels[i]; i++) {
1321          gchar tempstr[BUF_SIZE];
1322 
1323          g_snprintf (tempstr, BUF_SIZE, "/%s", _(labels[i]));
1324          entries[i].path            = g_strdup (tempstr);
1325          entries[i].accelerator     = NULL;
1326          entries[i].callback        = cb_find_similar;
1327          entries[i].callback_action = i;
1328          entries[i].item_type       = NULL;
1329       }
1330    }
1331    if (entries) {
1332       dupmenu = menu_create_items (GTK_WIDGET (tw), entries,
1333                                    i, "<ThumbWinDuplicatesFinderSubMenu>", tw);
1334       menu_set_submenu (tw->menubar, "/Tool/Find duplicates", dupmenu);
1335    }
1336 
1337    /* attach sub menus to parent menu */
1338    menu_set_submenu (tw->menubar,   "/View", tw->view_menu);
1339    menu_set_submenu (tw->menubar,   "/Help", help);
1340    menu_set_submenu (tw->view_menu, "/Sort File List", tw->sort_menu);
1341    menu_set_submenu (tw->view_menu, "/Layout/Window Composition", tw->comp_menu);
1342    submenu = create_wallpaper_submenu (tw);
1343    if (submenu)
1344       menu_set_submenu (tw->menubar, "/Tool/Wallpaper setting", submenu);
1345 
1346    ifactory = gtk_item_factory_from_widget (tw->menubar);
1347    tw->menuitem.file = gtk_item_factory_get_item (ifactory, "/File");
1348    tw->menuitem.edit = gtk_item_factory_get_item (ifactory, "/Edit");
1349    tw->menuitem.view = gtk_item_factory_get_item (ifactory, "/View");
1350    tw->menuitem.tool = gtk_item_factory_get_item (ifactory, "/Tool");
1351 
1352    tw->menuitem.select     = gtk_item_factory_get_item (ifactory, "/Edit/Select All");
1353    tw->menuitem.unselect   = gtk_item_factory_get_item (ifactory, "/Edit/Unselect All");
1354    tw->menuitem.refresh    = gtk_item_factory_get_item (ifactory, "/Edit/Refresh List");
1355    tw->menuitem.reload     = gtk_item_factory_get_item (ifactory, "/Edit/Reload Cache");
1356    tw->menuitem.recreate   = gtk_item_factory_get_item (ifactory, "/Edit/Update All Thumbnail");
1357 
1358    tw->menuitem.rename     = gtk_item_factory_get_item (ifactory, "/Edit/Rename...");
1359    tw->menuitem.copy       = gtk_item_factory_get_item (ifactory, "/Edit/Copy Files To...");
1360    tw->menuitem.move       = gtk_item_factory_get_item (ifactory, "/Edit/Move Files To...");
1361    tw->menuitem.link       = gtk_item_factory_get_item (ifactory, "/Edit/Link Files To...");
1362    tw->menuitem.delete     = gtk_item_factory_get_item (ifactory, "/Edit/Remove file...");
1363 
1364    tw->menuitem.find_sim   = gtk_item_factory_get_item (ifactory, "/Tool/Find duplicates");
1365 
1366    item =  gtk_item_factory_get_item (ifactory, "/Tab");
1367 
1368    ifactory = gtk_item_factory_from_widget (tw->view_menu);
1369    tw->menuitem.layout[0]   = gtk_item_factory_get_item (ifactory, "/Layout/Layout0");
1370    tw->menuitem.layout[1]   = gtk_item_factory_get_item (ifactory, "/Layout/Layout1");
1371    tw->menuitem.layout[2]   = gtk_item_factory_get_item (ifactory, "/Layout/Layout2");
1372    tw->menuitem.layout[3]   = gtk_item_factory_get_item (ifactory, "/Layout/Layout3");
1373    tw->menuitem.layout[4]   = gtk_item_factory_get_item (ifactory, "/Layout/Layout4");
1374    tw->menuitem.layout[5]   = gtk_item_factory_get_item (ifactory, "/Layout/Custom");
1375    tw->menuitem.dirview     = gtk_item_factory_get_item (ifactory, "/Directory View");
1376    tw->menuitem.preview     = gtk_item_factory_get_item (ifactory, "/Preview");
1377    tw->menuitem.menubar     = gtk_item_factory_get_item (ifactory, "/Menu Bar");
1378    tw->menuitem.toolbar     = gtk_item_factory_get_item (ifactory, "/Tool Bar");
1379    tw->menuitem.dir_toolbar = gtk_item_factory_get_item (ifactory, "/DirView Tool Bar");
1380    tw->menuitem.statusbar   = gtk_item_factory_get_item (ifactory, "/Status Bar");
1381    tw->menuitem.tab         = gtk_item_factory_get_item (ifactory, "/Tab");
1382    tw->menuitem.preview_tab = gtk_item_factory_get_item (ifactory, "/Tab (Preview)");
1383    tw->menuitem.fullscr     = gtk_item_factory_get_item (ifactory, "/Full Screen");
1384 
1385    ifactory = gtk_item_factory_from_widget (tw->sort_menu);
1386    tw->menuitem.sort_name   = gtk_item_factory_get_item (ifactory, "/by Name");
1387    tw->menuitem.sort_access = gtk_item_factory_get_item (ifactory, "/by Access Time");
1388    tw->menuitem.sort_time   = gtk_item_factory_get_item (ifactory, "/by Modification Time");
1389    tw->menuitem.sort_change = gtk_item_factory_get_item (ifactory, "/by Change Time");
1390    tw->menuitem.sort_size   = gtk_item_factory_get_item (ifactory, "/by Size");
1391    tw->menuitem.sort_type   = gtk_item_factory_get_item (ifactory, "/by Type");
1392    tw->menuitem.sort_width  = gtk_item_factory_get_item (ifactory, "/by Image Width");
1393    tw->menuitem.sort_height = gtk_item_factory_get_item (ifactory, "/by Image Height");
1394    tw->menuitem.sort_area   = gtk_item_factory_get_item (ifactory, "/by Image Area");
1395    tw->menuitem.sort_rev    = gtk_item_factory_get_item (ifactory, "/Reverse Order");
1396    tw->menuitem.sort_case   = gtk_item_factory_get_item (ifactory, "/Case insensitive");
1397    tw->menuitem.sort_dir    = gtk_item_factory_get_item (ifactory, "/Directory insensitive");
1398 
1399    gtk_signal_connect (GTK_OBJECT (GTK_MENU_ITEM (tw->menuitem.file)->submenu),
1400                        "show", GTK_SIGNAL_FUNC (cb_file_submenu_show), tw);
1401    gtk_signal_connect (GTK_OBJECT (GTK_MENU_ITEM (tw->menuitem.file)->submenu),
1402                        "hide", GTK_SIGNAL_FUNC (cb_file_submenu_hide), tw);
1403    gtk_signal_connect (GTK_OBJECT (GTK_MENU_ITEM (tw->menuitem.edit)->submenu),
1404                        "show", GTK_SIGNAL_FUNC (cb_edit_submenu_show), tw);
1405    gtk_signal_connect (GTK_OBJECT (GTK_MENU_ITEM (tw->menuitem.edit)->submenu),
1406                        "hide", GTK_SIGNAL_FUNC (cb_edit_submenu_hide), tw);
1407    gtk_signal_connect (GTK_OBJECT (tw->view_menu),
1408                        "show", GTK_SIGNAL_FUNC (cb_view_submenu_show), tw);
1409    gtk_signal_connect (GTK_OBJECT (tw->view_menu),
1410                        "hide", GTK_SIGNAL_FUNC (cb_view_submenu_hide), tw);
1411    gtk_signal_connect (GTK_OBJECT (GTK_MENU_ITEM (item)->submenu),
1412                        "show", GTK_SIGNAL_FUNC (cb_tab_submenu_show), tw);
1413    gtk_signal_connect (GTK_OBJECT (GTK_MENU_ITEM (item)->submenu),
1414                        "hide", GTK_SIGNAL_FUNC (cb_tab_submenu_hide), tw);
1415    gtk_signal_connect (GTK_OBJECT (GTK_MENU_ITEM (tw->menuitem.tool)->submenu),
1416                        "show", GTK_SIGNAL_FUNC (cb_tool_submenu_show), tw);
1417    gtk_signal_connect (GTK_OBJECT (GTK_MENU_ITEM (tw->menuitem.tool)->submenu),
1418                        "hide", GTK_SIGNAL_FUNC (cb_tool_submenu_hide), tw);
1419 
1420    /* initialize check menu items */
1421    if (tw->layout_type < 0)
1422       layout = compose_type_num;
1423    else if (tw->layout_type >compose_type_num)
1424       layout = 0;
1425    else
1426       layout = tw->layout_type;
1427    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM
1428                                    (tw->menuitem.layout[layout]),
1429                                    TRUE);
1430    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.dirview),
1431                                    conf.thumbwin_show_dir_view);
1432    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.preview),
1433                                    conf.thumbwin_show_preview);
1434    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.menubar),
1435                                    conf.thumbwin_show_menubar);
1436    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.toolbar),
1437                                    conf.thumbwin_show_toolbar);
1438    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.dir_toolbar),
1439                                    conf.dirview_show_toolbar);
1440    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.statusbar),
1441                                    conf.thumbwin_show_statusbar);
1442    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.tab),
1443                                    conf.thumbwin_show_tab);
1444    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.preview_tab),
1445                                    conf.thumbwin_show_preview_tab);
1446 
1447    switch (tw->player_visible) {
1448    case GimvImageViewPlayerVisibleShow:
1449       menu_check_item_set_active (tw->view_menu, "/Player/Show", TRUE);
1450       break;
1451    case GimvImageViewPlayerVisibleHide:
1452       menu_check_item_set_active (tw->view_menu, "/Player/Hide", TRUE);
1453       break;
1454    case GimvImageViewPlayerVisibleAuto:
1455    default:
1456       menu_check_item_set_active (tw->view_menu, "/Player/Auto", TRUE);
1457       break;
1458    }
1459 
1460    switch (tw->tab_pos) {
1461    case GTK_POS_LEFT:
1462       menu_check_item_set_active (tw->menubar, "/Tab/Tab Position/Left", TRUE);
1463       break;
1464    case GTK_POS_RIGHT:
1465       menu_check_item_set_active (tw->menubar, "/Tab/Tab Position/Right", TRUE);
1466       break;
1467    case GTK_POS_BOTTOM:
1468       menu_check_item_set_active (tw->menubar, "/Tab/Tab Position/Bottom", TRUE);
1469       break;
1470    case GTK_POS_TOP:
1471    default:
1472       menu_check_item_set_active (tw->menubar, "/Tab/Tab Position/Top", TRUE);
1473       break;
1474    }
1475 
1476    switch (tw->sortitem) {
1477    case GIMV_SORT_NAME:
1478       item = tw->menuitem.sort_name;
1479       break;
1480    case GIMV_SORT_ATIME:
1481       item = tw->menuitem.sort_access;
1482       break;
1483    case GIMV_SORT_MTIME:
1484       item = tw->menuitem.sort_time;
1485       break;
1486    case GIMV_SORT_CTIME:
1487       item = tw->menuitem.sort_change;
1488       break;
1489    case GIMV_SORT_SIZE:
1490       item = tw->menuitem.sort_size;
1491       break;
1492    case GIMV_SORT_TYPE:
1493       item = tw->menuitem.sort_type;
1494       break;
1495    case GIMV_SORT_WIDTH:
1496       item = tw->menuitem.sort_width;
1497       break;
1498    case GIMV_SORT_HEIGHT:
1499       item = tw->menuitem.sort_height;
1500       break;
1501    case GIMV_SORT_AREA:
1502       item = tw->menuitem.sort_area;
1503       break;
1504    default:
1505       item = tw->menuitem.sort_name;
1506       break;
1507    }
1508    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
1509    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.sort_rev),
1510                                    tw->sortflags & GIMV_SORT_REVERSE);
1511    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.sort_case),
1512                                    tw->sortflags & GIMV_SORT_CASE_INSENSITIVE);
1513    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tw->menuitem.sort_dir),
1514                                    tw->sortflags & GIMV_SORT_DIR_INSENSITIVE);
1515 }
1516 
1517 
1518 static void
sync_widget_state_to_menu(GimvThumbWin * tw)1519 sync_widget_state_to_menu (GimvThumbWin *tw)
1520 {
1521    gimv_thumb_win_pane_set_visible (tw, GIMV_COM_DIR_VIEW);
1522    gimv_thumb_win_pane_set_visible (tw, GIMV_COM_IMAGE_VIEW);
1523 
1524    if (!GTK_CHECK_MENU_ITEM (tw->menuitem.menubar)->active)
1525       gtk_widget_hide (tw->menubar_handle);
1526    if (!GTK_CHECK_MENU_ITEM (tw->menuitem.toolbar)->active)
1527       gtk_widget_hide (tw->toolbar_handle);
1528    if (!GTK_CHECK_MENU_ITEM (tw->menuitem.statusbar)->active)
1529       gtk_widget_hide (tw->status_bar_container);
1530    gtk_notebook_set_show_tabs (GTK_NOTEBOOK (tw->notebook),
1531                                GTK_CHECK_MENU_ITEM (tw->menuitem.tab)->active);
1532    if (tw->cv)
1533       gtk_notebook_set_show_tabs (GTK_NOTEBOOK (tw->cv->notebook),
1534                                   GTK_CHECK_MENU_ITEM (tw->menuitem.preview_tab)->active);
1535 }
1536 
1537 
1538 static GtkWidget *
create_toolbar(GimvThumbWin * tw,GtkWidget * container)1539 create_toolbar (GimvThumbWin *tw, GtkWidget *container)
1540 {
1541    GtkWidget *toolbar;
1542    GtkWidget *button;
1543    GtkWidget *iconw;
1544    GtkAdjustment *adj;
1545    GtkWidget *spinner;
1546 
1547    toolbar = gtkutil_create_toolbar ();
1548 
1549    /* file open button */
1550    iconw = gimv_icon_stock_get_widget ("nfolder");
1551    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
1552                                     _("Open"),
1553                                     _("File Open"),
1554                                     _("File Open"),
1555                                     iconw,
1556                                     GTK_SIGNAL_FUNC (cb_open_button),
1557                                     tw);
1558    tw->button.fileopen = button;
1559 
1560    /* preference button */
1561    iconw = gimv_icon_stock_get_widget ("prefs");
1562    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
1563                                     _("Prefs"),
1564                                     _("Preference"),
1565                                     _("Preference"),
1566                                     iconw,
1567                                     GTK_SIGNAL_FUNC (cb_prefs_button),
1568                                     tw);
1569    tw->button.prefs = button;
1570 
1571    gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1572 
1573    /* previous button */
1574    iconw = gimv_icon_stock_get_widget ("leftarrow");
1575    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
1576                                     _("Prev"),
1577                                     _("Go to previous page"),
1578                                     _("Go to previous page"),
1579                                     iconw,
1580                                     GTK_SIGNAL_FUNC (cb_previous_button),
1581                                     tw);
1582    tw->button.prev = button;
1583 
1584    /* next button */
1585    iconw = gimv_icon_stock_get_widget ("rightarrow");
1586    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
1587                                     _("Next"),
1588                                     _("Go to next page"),
1589                                     _("Go to next page"),
1590                                     iconw,
1591                                     GTK_SIGNAL_FUNC (cb_next_button),
1592                                     tw);
1593    tw->button.next = button;
1594 
1595    gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1596 
1597    /* refresh button */
1598    iconw = gimv_icon_stock_get_widget ("refresh");
1599    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
1600                                     _("Reload"),
1601                                     _("Reload Cache"),
1602                                     _("Reload Cache"),
1603                                     iconw,
1604                                     GTK_SIGNAL_FUNC (cb_refresh_button),
1605                                     tw);
1606    tw->button.refresh = button;
1607 
1608    /* skip button */
1609    iconw = gimv_icon_stock_get_widget ("skip");
1610    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
1611                                     _("Skip"),
1612                                     _("Skip creating current thumbnail table"),
1613                                     _("Skip creating current thumbnail table"),
1614                                     iconw,
1615                                     GTK_SIGNAL_FUNC (cb_skip_button),
1616                                     tw);
1617    gtk_widget_set_sensitive (button, FALSE);
1618    tw->button.skip = button;
1619 
1620    /* stop button */
1621    iconw = gimv_icon_stock_get_widget ("stop");
1622    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
1623                                     _("Stop"),
1624                                     _("Stop creating thumbnails"),
1625                                     _("Stop creating thumbnails"),
1626                                     iconw,
1627                                     GTK_SIGNAL_FUNC (cb_stop_button),
1628                                     tw);
1629    gtk_widget_set_sensitive (button, FALSE);
1630    tw->button.stop = button;
1631 
1632    /* thumbnail size spinner */
1633    adj = (GtkAdjustment *) gtk_adjustment_new (conf.thumbwin_thumb_size,
1634                                                GIMV_THUMB_WIN_MIN_THUMB_SIZE,
1635                                                GIMV_THUMB_WIN_MAX_THUMB_SIZE,
1636                                                1.0, 4.0, 0.0);
1637    spinner = gtkutil_create_spin_button (adj);
1638    gtk_widget_set_name (tw->menubar_handle, "ThumbnailSizeSpinner");
1639    tw->button.size_spin = spinner;
1640    gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), spinner,
1641                               _("Thumbnail Size"), _("Thumbnail Size"));
1642    gtk_signal_connect (GTK_OBJECT(spinner), "key-press-event",
1643                        GTK_SIGNAL_FUNC(cb_size_spinner_key_press), tw);
1644    gtk_widget_show (spinner);
1645 
1646    gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1647 
1648    /* quit button */
1649    iconw = gimv_icon_stock_get_widget ("close");
1650    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
1651                                     _("Quit"),
1652                                     _("Exit this program"),
1653                                     _("Exit this program"),
1654                                     iconw,
1655                                     GTK_SIGNAL_FUNC (cb_quit_button),
1656                                     NULL);
1657    tw->button.quit = button;
1658    gtk_widget_hide (tw->button.quit);
1659 
1660    return toolbar;
1661 }
1662 
1663 
1664 static void
gimv_thumb_win_get_layout(GimvThumbwinComposeType * compose,gint layout)1665 gimv_thumb_win_get_layout (GimvThumbwinComposeType *compose, gint layout)
1666 {
1667    gint i;
1668 
1669    if (layout >= compose_type_num)
1670       layout = 0;
1671 
1672    if (layout > -1) {
1673       *compose = compose_type[layout];
1674    } else {
1675       compose->pane1_horizontal = conf.thumbwin_pane1_horizontal;
1676       compose->pane2_horizontal = conf.thumbwin_pane2_horizontal;
1677       compose->pane2_attach_to_child1 = conf.thumbwin_pane2_attach_1;
1678       for (i = 0; i < 3; i++)
1679          compose->widget_type[i] = conf.thumbwin_widget[i];
1680    }
1681 }
1682 
1683 
1684 static void
gimv_thumb_win_pane_set_visible(GimvThumbWin * tw,GimvComponentType item)1685 gimv_thumb_win_pane_set_visible (GimvThumbWin *tw,  GimvComponentType item)
1686 {
1687    GimvThumbwinComposeType compose;
1688    GimvComponentType type;
1689    GtkWidget *gpane;
1690    gint i, val = -1, *size, pane, child;
1691    gboolean show, *current_state;
1692 
1693    g_return_if_fail (tw);
1694 
1695    if (tw->layout_type >= compose_type_num) return;
1696    gimv_thumb_win_get_layout (&compose, tw->layout_type);
1697 
1698    if (item == GIMV_COM_DIR_VIEW) {
1699       type = GIMV_COM_DIR_VIEW;
1700       current_state = &tw->show_dirview;
1701       show = GTK_CHECK_MENU_ITEM(tw->menuitem.dirview)->active;
1702    } else if (item == GIMV_COM_IMAGE_VIEW) {
1703       type = GIMV_COM_IMAGE_VIEW;
1704       current_state = &tw->show_preview;
1705       show = GTK_CHECK_MENU_ITEM(tw->menuitem.preview)->active;
1706    } else {
1707       return;
1708    }
1709 
1710    /* find attached pane and child */
1711    for (i = 0; i < 3; i++) {
1712       if (compose.widget_type[i] == type)
1713          val = i;
1714    }
1715    if (val < 0) return;
1716 
1717    if (val == 0) {
1718       pane = 1;
1719       if (compose.pane2_attach_to_child1)
1720          child = 2;
1721       else
1722          child = 1;
1723    } else if (val == 1) {
1724       pane = 2;
1725       child = 1;
1726    } else if (val == 2) {
1727       pane = 2;
1728       child = 2;
1729    } else {
1730       goto FUNC_END;
1731    }
1732 
1733    if (pane == 1) {
1734       gpane = tw->pane1;
1735       size = &tw->pane_size1;
1736    } else {
1737       gint pane1_hide_item = gimv_paned_which_hidden (GIMV_PANED(tw->pane1));
1738       gint pane2_hide_item = gimv_paned_which_hidden (GIMV_PANED(tw->pane2));
1739 
1740       /*
1741        *  directory view and preview are attach to same pane,
1742        *  and one of them is hidden.
1743        */
1744       if (compose.widget_type[0] == GIMV_COM_THUMB_VIEW
1745           && gimv_paned_which_hidden (GIMV_PANED(tw->pane2)) != 0
1746           && ((pane1_hide_item == 0 && !show) || (pane1_hide_item != 0 && show)))
1747          {
1748             gpane = tw->pane1;
1749             size = &tw->pane_size1;
1750             if (GIMV_PANED(tw->pane1)->child1 == tw->pane2) {
1751                child = 1;
1752             } else if (GIMV_PANED(tw->pane1)->child2 == tw->pane2) {
1753                child = 2;
1754             } else {
1755                goto FUNC_END;
1756             }
1757 
1758             if (show && (val == pane2_hide_item)) {
1759                gimv_paned_split (GIMV_PANED(tw->pane2));
1760                if (pane2_hide_item == 1)
1761                   gimv_paned_hide_child2 (GIMV_PANED (tw->pane2));
1762                else if (pane2_hide_item == 2)
1763                   gimv_paned_hide_child1 (GIMV_PANED (tw->pane2));
1764             }
1765 
1766          } else {
1767             gpane = tw->pane2;
1768             size = &tw->pane_size2;
1769          }
1770    }
1771 
1772    if (show) {
1773       gimv_paned_split (GIMV_PANED (gpane));
1774       gimv_paned_set_position (GIMV_PANED (gpane), *size);
1775    } else {
1776       *size = gimv_paned_get_position (GIMV_PANED (gpane));
1777       if (child == 1)
1778          gimv_paned_hide_child1 (GIMV_PANED (gpane));
1779       else
1780          gimv_paned_hide_child2 (GIMV_PANED (gpane));
1781    }
1782 
1783  FUNC_END:
1784    *current_state = show;
1785 }
1786 
1787 
1788 static GtkWidget *
thumbnail_window_contents_new(GimvThumbWin * tw)1789 thumbnail_window_contents_new (GimvThumbWin *tw)
1790 {
1791    GtkWidget *widget[3], *thumbview;
1792    GimvThumbwinComposeType compose;
1793    gchar *dirname;
1794    gint i;
1795 
1796    if (tw->layout_type >= compose_type_num)
1797       tw->layout_type = 0;
1798 
1799    gimv_thumb_win_get_layout (&compose, tw->layout_type);
1800 
1801    /* create each widget */
1802    dirname = g_get_current_dir ();
1803    tw->dv = dirview_create (dirname, GTK_WIDGET (tw), tw);
1804    tw->dirview = tw->dv->container;
1805    thumbview = thumbnail_view_new (tw);
1806    tw->preview = image_preview_new (tw);
1807    g_free (dirname);
1808 
1809    for (i = 0; i < 3; i++) {
1810       switch (compose.widget_type[i]) {
1811       case GIMV_COM_DIR_VIEW:
1812          widget[i] = tw->dirview;
1813          break;
1814       case GIMV_COM_THUMB_VIEW:
1815          widget[i] = thumbview;
1816          break;
1817       case GIMV_COM_IMAGE_VIEW:
1818          widget[i] = tw->preview;
1819          break;
1820       default:
1821          break;
1822       }
1823    }
1824 
1825    /* compose */
1826    if (compose.pane2_horizontal)
1827       tw->pane2 = gimv_hpaned_new ();
1828    else
1829       tw->pane2 = gimv_vpaned_new ();
1830    if (compose.pane1_horizontal)
1831       tw->pane1 = gimv_hpaned_new ();
1832    else
1833       tw->pane1 = gimv_vpaned_new ();
1834 
1835    if (compose.pane2_attach_to_child1) {
1836       gimv_paned_add1 (GIMV_PANED (tw->pane1), tw->pane2);
1837       gimv_paned_add2 (GIMV_PANED (tw->pane1), widget[0]);
1838    } else {
1839       gimv_paned_add1 (GIMV_PANED (tw->pane1), widget[0]);
1840       gimv_paned_add2 (GIMV_PANED (tw->pane1), tw->pane2);
1841    }
1842    gimv_paned_add1 (GIMV_PANED (tw->pane2), widget[1]);
1843    gimv_paned_add2 (GIMV_PANED (tw->pane2), widget[2]);
1844 
1845    gimv_paned_set_position (GIMV_PANED (tw->pane1),
1846                             tw->pane_size1);
1847    gimv_paned_set_position (GIMV_PANED (tw->pane2),
1848                             tw->pane_size2);
1849 
1850    /* show widget */
1851    gtk_widget_show (widget[0]);
1852    gtk_widget_show (widget[1]);
1853    gtk_widget_show (widget[2]);
1854    gtk_widget_show (tw->pane2);
1855 
1856    return tw->pane1;
1857 }
1858 
1859 
1860 static GtkWidget *
thumbnail_view_new(GimvThumbWin * tw)1861 thumbnail_view_new (GimvThumbWin *tw)
1862 {
1863    GtkWidget *notebook, *vbox;
1864 
1865    vbox = gtk_vbox_new (FALSE, 0);
1866 
1867    notebook = gtk_notebook_new ();
1868    gtk_widget_set_name (notebook, "ThumbViewNoteBook");
1869    gtk_widget_show (notebook);
1870    gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
1871    gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
1872 
1873    gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook),
1874                              tw->tab_pos);
1875    gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
1876    gtk_notebook_popup_enable (GTK_NOTEBOOK (notebook));
1877    gtk_notebook_set_tab_hborder (GTK_NOTEBOOK (notebook), 0);
1878    gtk_notebook_set_tab_vborder (GTK_NOTEBOOK (notebook), 0);
1879    gtk_signal_connect (GTK_OBJECT(notebook), "switch-page",
1880                        GTK_SIGNAL_FUNC(cb_thumb_notebook_switch_page), tw);
1881 
1882    gtk_object_set_data (GTK_OBJECT (notebook), "thumbwin", tw);
1883    dnd_src_set  (notebook, dnd_types_tab_component, dnd_types_tab_component_num);
1884    gtk_signal_connect (GTK_OBJECT (notebook), "drag_begin",
1885                        GTK_SIGNAL_FUNC (cb_com_drag_begin), tw);
1886    gtk_signal_connect (GTK_OBJECT (notebook), "drag_data_get",
1887                        GTK_SIGNAL_FUNC (cb_com_drag_data_get), tw);
1888 
1889    dnd_dest_set (notebook, dnd_types_all, dnd_types_all_num);
1890    gtk_object_set_data (GTK_OBJECT (notebook),
1891                         "gimv-component",
1892                         GINT_TO_POINTER (GIMV_COM_THUMB_VIEW));
1893    gtk_signal_connect (GTK_OBJECT (notebook), "drag_data_received",
1894                        GTK_SIGNAL_FUNC (cb_notebook_drag_data_received), tw);
1895 
1896    dnd_dest_set (vbox, dnd_types_all, dnd_types_all_num);
1897    gtk_object_set_data (GTK_OBJECT (vbox),
1898                         "gimv-component",
1899                         GINT_TO_POINTER (GIMV_COM_THUMB_VIEW));
1900    gtk_signal_connect (GTK_OBJECT (vbox), "drag_data_received",
1901                        GTK_SIGNAL_FUNC (cb_notebook_drag_data_received), tw);
1902 
1903    tw->notebook = notebook;
1904 
1905    return vbox;
1906 }
1907 
1908 
1909 static gint
image_preview_action(GimvImageView * iv,GdkEventButton * event,gint num)1910 image_preview_action (GimvImageView *iv, GdkEventButton *event, gint num)
1911 {
1912    gint mx, my;
1913 
1914    gimv_image_view_get_view_position (iv, &mx, &my);
1915 
1916    switch (abs (num)) {
1917    case PREVIEW_NEXT:
1918       gimv_image_view_next (iv);
1919       break;
1920    case PREVIEW_PREV:
1921       gimv_image_view_prev (iv);
1922       break;
1923    case PREVIEW_SHAREDWIN:
1924       gimv_image_win_open_shared_window (iv->info);
1925       break;
1926    case PREVIEW_NEWWIN:
1927       if (iv->info)
1928          gimv_image_win_open_window (iv->info);
1929       break;
1930    case PREVIEW_POPUP:
1931       gimv_image_view_popup_menu (iv, event);
1932       break;
1933    case PREVIEW_ZOOM_IN:
1934       gimv_image_view_zoom_image (iv, GIMV_IMAGE_VIEW_ZOOM_IN, 0, 0);
1935       break;
1936    case PREVIEW_ZOOM_OUT:
1937       gimv_image_view_zoom_image (iv, GIMV_IMAGE_VIEW_ZOOM_OUT, 0, 0);
1938       break;
1939    case PREVIEW_FIT:
1940       gimv_image_view_zoom_image (iv, GIMV_IMAGE_VIEW_ZOOM_FIT, 0, 0);
1941       break;
1942    case PREVIEW_ROTATE_CCW:
1943       gimv_image_view_rotate_ccw (iv);
1944       break;
1945    case PREVIEW_ROTATE_CW:
1946       gimv_image_view_rotate_cw (iv);
1947       break;
1948    case PREVIEW_NAVWIN:
1949       gimv_image_view_open_navwin (iv, event->x_root, event->y_root);
1950       break;
1951    case PREVIEW_UP:
1952       my += 20;
1953       gimv_image_view_moveto (iv, mx, my);
1954       break;
1955    case PREVIEW_DOWN:
1956       my -= 20;
1957       gimv_image_view_moveto (iv, mx, my);
1958       break;
1959    case PREVIEW_LEFT:
1960       mx += 20;
1961       gimv_image_view_moveto (iv, mx, my);
1962       break;
1963    case PREVIEW_RIGHT:
1964       mx -= 20;
1965       gimv_image_view_moveto (iv, mx, my);
1966       break;
1967    default:
1968       break;
1969    }
1970 
1971    return TRUE;
1972 }
1973 
1974 
1975 static gint
cb_image_preview_pressed(GimvImageView * iv,GdkEventButton * event,gpointer data)1976 cb_image_preview_pressed (GimvImageView *iv, GdkEventButton *event, gpointer data)
1977 {
1978    gint num;
1979 
1980    g_return_val_if_fail (iv, TRUE);
1981    g_return_val_if_fail (event, TRUE);
1982 
1983    num = prefs_mouse_get_num_from_event (event, conf.preview_mouse_button);
1984    if (num > 0)
1985       return image_preview_action (iv, event, num);
1986 
1987    return TRUE;
1988 }
1989 
1990 
1991 static gint
cb_image_preview_clicked(GimvImageView * iv,GdkEventButton * event,gpointer data)1992 cb_image_preview_clicked (GimvImageView *iv, GdkEventButton *event, gpointer data)
1993 {
1994    gint num;
1995 
1996    g_return_val_if_fail (iv, TRUE);
1997    g_return_val_if_fail (event, TRUE);
1998 
1999    num = prefs_mouse_get_num_from_event (event, conf.preview_mouse_button);
2000    if (num < 0)
2001       return image_preview_action (iv, event, num);
2002 
2003    return TRUE;
2004 }
2005 
2006 
2007 static gboolean
cb_unset_com_dnd(GtkWidget * widget,GdkEventButton * event,GimvThumbWin * tw)2008 cb_unset_com_dnd (GtkWidget *widget,
2009                   GdkEventButton *event,
2010                   GimvThumbWin *tw)
2011 {
2012    g_return_val_if_fail (tw, FALSE);
2013    g_return_val_if_fail (tw->cv, FALSE);
2014    gtk_drag_source_unset (tw->cv->notebook);
2015 
2016    return FALSE;
2017 }
2018 
2019 
2020 static gboolean
cb_reset_com_dnd(GtkWidget * widget,GdkEventButton * event,GimvThumbWin * tw)2021 cb_reset_com_dnd (GtkWidget *widget,
2022                   GdkEventButton *event,
2023                   GimvThumbWin *tw)
2024 {
2025    g_return_val_if_fail (tw, FALSE);
2026    g_return_val_if_fail (tw->cv, FALSE);
2027    dnd_src_set  (tw->cv->notebook,
2028                  dnd_types_component,
2029                  dnd_types_component_num);
2030    return FALSE;
2031 }
2032 
2033 
2034 static gboolean
cb_comment_view_delete(GtkWidget * widget,GdkEventAny * event,GimvThumbWin * tw)2035 cb_comment_view_delete (GtkWidget *widget, GdkEventAny *event, GimvThumbWin *tw)
2036 {
2037    if (tw->cv) {
2038 #ifdef USE_GTK2
2039       if (g_slist_find (tw->accel_group_list, tw->cv->accel_group))
2040          tw->accel_group_list
2041             = g_slist_remove (tw->accel_group_list, tw->cv->accel_group);
2042       else
2043          gtk_window_remove_accel_group (GTK_WINDOW (tw),
2044                                         tw->cv->accel_group);
2045 #else /* USE_GTK2 */
2046       gtk_window_remove_accel_group (GTK_WINDOW (tw),
2047                                      tw->cv->accel_group);
2048 #endif /* USE_GTK2 */
2049    }
2050    return FALSE;
2051 }
2052 
2053 
2054 static GtkWidget *
image_preview_new(GimvThumbWin * tw)2055 image_preview_new (GimvThumbWin *tw)
2056 {
2057    GimvCommentView *cv;
2058    GtkWidget *label;
2059    gboolean show_scrollbar;
2060 
2061    cv = tw->cv = gimv_comment_view_create ();
2062    if (cv->accel_group) {
2063       gtk_accel_group_ref (cv->accel_group);
2064       gtk_window_add_accel_group (GTK_WINDOW (tw), cv->accel_group);
2065    }
2066    gtk_signal_connect (GTK_OBJECT (cv->main_vbox), "delete_event",
2067                        GTK_SIGNAL_FUNC (cb_comment_view_delete), tw);
2068 #ifdef USE_GTK2   /* FIXME */
2069    gtk_signal_connect(GTK_OBJECT (cv->value_entry), "focus_in_event",
2070                       GTK_SIGNAL_FUNC (cb_focus_in), tw);
2071    gtk_signal_connect(GTK_OBJECT (cv->value_entry), "focus_out_event",
2072                       GTK_SIGNAL_FUNC (cb_focus_out), tw);
2073    gtk_signal_connect(GTK_OBJECT (cv->note_box), "focus_in_event",
2074                       GTK_SIGNAL_FUNC (cb_focus_in), tw);
2075    gtk_signal_connect(GTK_OBJECT (cv->note_box), "focus_out_event",
2076                       GTK_SIGNAL_FUNC (cb_focus_out), tw);
2077 #endif /* USE_GTK2 */
2078 
2079    /* create image view and attach to comment view notebook */
2080    label = gtk_label_new (_("Preview"));
2081    gtk_widget_set_name (label, "TabLabel");
2082 
2083    tw->iv = GIMV_IMAGE_VIEW (gimv_image_view_new (NULL));
2084 
2085    gtk_signal_connect (GTK_OBJECT (tw->iv), "image_pressed",
2086                        GTK_SIGNAL_FUNC (cb_image_preview_pressed), tw);
2087    gtk_signal_connect (GTK_OBJECT (tw->iv), "image_clicked",
2088                        GTK_SIGNAL_FUNC (cb_image_preview_clicked), tw);
2089 
2090    /* override prefs */
2091    gimv_image_view_set_player_visible (tw->iv, tw->player_visible);
2092    gtk_object_set(GTK_OBJECT(tw->iv),
2093                   "x_scale",           conf.preview_scale,
2094                   "y_scale",           conf.preview_scale,
2095                   "default_zoom",      conf.preview_zoom,
2096                   "default_rotation",  conf.preview_rotation,
2097                   "keep_aspect",       conf.preview_keep_aspect,
2098                   "keep_buffer",       conf.preview_buffer,
2099                   "show_scrollbar",    conf.preview_scrollbar,
2100                   NULL);
2101 
2102    gimv_image_view_create_popup_menu (GTK_WIDGET (tw),
2103                                       tw->iv, "<ThumbWinPreviewPop>");
2104 
2105    /* set component DnD */
2106    /* FIXME!! image view and comment view shuold be seperated */
2107    dnd_src_set  (cv->notebook, dnd_types_component, dnd_types_component_num);
2108    gtk_object_set_data (GTK_OBJECT (cv->notebook),
2109                         "gimv-component",
2110                         GINT_TO_POINTER (GIMV_COM_IMAGE_VIEW));
2111    gtk_signal_connect (GTK_OBJECT (cv->notebook), "drag_begin",
2112                        GTK_SIGNAL_FUNC (cb_com_drag_begin), tw);
2113    gtk_signal_connect (GTK_OBJECT (cv->notebook), "drag_data_get",
2114                        GTK_SIGNAL_FUNC (cb_com_drag_data_get), tw);
2115 
2116    dnd_dest_set (cv->main_vbox, dnd_types_component, dnd_types_component_num);
2117    gtk_object_set_data (GTK_OBJECT (cv->main_vbox),
2118                         "gimv-component",
2119                         GINT_TO_POINTER (GIMV_COM_IMAGE_VIEW));
2120    gtk_signal_connect (GTK_OBJECT (cv->main_vbox), "drag_data_received",
2121                        GTK_SIGNAL_FUNC (cb_com_swap_drag_data_received), tw);
2122    /* END FIXME!! */
2123 
2124    /* FIXME!! */
2125    /* for avoiding gtk's bug */
2126    gtk_signal_connect (GTK_OBJECT (tw->iv), "button_press_event",
2127                        GTK_SIGNAL_FUNC (cb_unset_com_dnd), tw);
2128    gtk_signal_connect (GTK_OBJECT (tw->iv), "button_release_event",
2129                        GTK_SIGNAL_FUNC (cb_reset_com_dnd), tw);
2130    gtk_signal_connect (GTK_OBJECT (tw->cv->comment_clist->parent),
2131                        "button_press_event",
2132                        GTK_SIGNAL_FUNC (cb_unset_com_dnd), tw);
2133    gtk_signal_connect (GTK_OBJECT (tw->cv->comment_clist->parent),
2134                        "button_release_event",
2135                        GTK_SIGNAL_FUNC (cb_reset_com_dnd), tw);
2136    gtk_signal_connect (GTK_OBJECT (tw->cv->note_box->parent),
2137                        "button_press_event",
2138                        GTK_SIGNAL_FUNC (cb_unset_com_dnd), tw);
2139    gtk_signal_connect (GTK_OBJECT (tw->cv->note_box->parent),
2140                        "button_release_event",
2141                        GTK_SIGNAL_FUNC (cb_reset_com_dnd), tw);
2142    /* END FIXME!! */
2143 
2144    gtk_widget_show (GTK_WIDGET (tw->iv));
2145    gtk_object_get (GTK_OBJECT (tw->iv),
2146                    "show_scrollbar", &show_scrollbar,
2147                    NULL);
2148    if (!show_scrollbar)
2149       gimv_image_view_hide_scrollbar (tw->iv);
2150    gtk_notebook_prepend_page (GTK_NOTEBOOK(cv->notebook), GTK_WIDGET (tw->iv), label);
2151    gtk_notebook_set_page (GTK_NOTEBOOK(cv->notebook), 0);
2152 
2153    return cv->main_vbox;
2154 }
2155 
2156 
2157 static void
add_accel_label_to_disp_mode_menu(GtkWidget * widget,GtkWidget * window)2158 add_accel_label_to_disp_mode_menu (GtkWidget *widget, GtkWidget *window)
2159 {
2160    GtkAccelGroup *accel_group;
2161    GtkWidget *menu;
2162    GList *list, *node;
2163    gint i, num = sizeof (akey.thumbwin_disp_mode) / sizeof (gchar *);
2164 
2165    g_return_if_fail (widget);
2166 
2167    menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (widget));
2168    if (!menu) return;
2169 
2170    accel_group = gtk_accel_group_new ();
2171    gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
2172    gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
2173 
2174    list = gtk_container_children (GTK_CONTAINER (menu));
2175    if (!list) return;
2176 
2177    for (node = list, i = 0; node && i < num; node = g_list_next (node), i++) {
2178       GtkWidget *item = node->data;
2179       guint keyval = 0;
2180       GdkModifierType mod = 0;
2181 
2182       if (!item) continue;
2183 
2184       if (akey.thumbwin_disp_mode[i] && *akey.thumbwin_disp_mode[i]) {
2185          gtk_accelerator_parse (akey.thumbwin_disp_mode[i], &keyval, &mod);
2186          gtk_widget_add_accelerator (item, "activate",
2187                                      accel_group,
2188                                      keyval, mod, 0);
2189       }
2190    }
2191 }
2192 
2193 
2194 
2195 /******************************************************************************
2196  *
2197  *   Callback functions for menubar.
2198  *
2199  ******************************************************************************/
2200 static void
cb_open(GimvThumbWin * tw,guint action,GtkWidget * widget)2201 cb_open (GimvThumbWin *tw, guint action, GtkWidget *widget)
2202 {
2203    switch (action) {
2204    case OPEN_FILE:
2205       if (tw->open_dialog)
2206          gdk_window_raise (tw->open_dialog->window);
2207       else
2208          tw->open_dialog = (GtkWidget *) create_filebrowser (tw);
2209       break;
2210    case OPEN_IMAGEWIN:
2211       gimv_image_win_open_window (NULL);
2212       break;
2213    case OPEN_THUMBWIN:
2214       gimv_thumb_win_open_window();
2215       break;
2216    case OPEN_THUMBTAB:
2217       gimv_thumb_win_create_new_tab (tw);
2218       break;
2219    case OPEN_PREFS:
2220       gimv_prefs_win_open_idle ("/Thumbnail Window", GTK_WINDOW (tw));
2221       break;
2222    case OPEN_GIMV_INFO:
2223       gimvhelp_open_info_window ();
2224       break;
2225    default:
2226       break;
2227    }
2228 }
2229 
2230 
2231 static void
cb_close(GimvThumbWin * tw,guint action,GtkWidget * widget)2232 cb_close (GimvThumbWin *tw, guint action, GtkWidget *widget)
2233 {
2234    switch (action) {
2235    case CLOSE_THUMBWIN:
2236       if (g_list_length (ThumbWinList) == 1 && conf.thumbwin_save_win_state)
2237          gimv_thumb_win_save_state (tw);
2238       gtk_widget_destroy (GTK_WIDGET (tw));
2239       break;
2240    case CLOSE_THUMBTAB:
2241       gimv_thumb_win_close_tab (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2242       break;
2243    case CLOSE_ALL:
2244       gimv_quit ();
2245       break;
2246    default:
2247       break;
2248    }
2249 }
2250 
2251 
2252 static void
cb_select_all(GimvThumbWin * tw,guint action,GtkWidget * widget)2253 cb_select_all (GimvThumbWin *tw, guint action, GtkWidget *widget)
2254 {
2255    GimvThumbView *tv;
2256 
2257    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2258    if (!tv) return;
2259 
2260    gimv_thumb_view_set_selection_all (tv, action);
2261 }
2262 
2263 
2264 static void
cb_refresh_list(GimvThumbWin * tw,guint action,GtkWidget * widget)2265 cb_refresh_list (GimvThumbWin *tw, guint action, GtkWidget *widget)
2266 {
2267    GimvThumbView *tv;
2268 
2269    if (!tw) return;
2270 
2271    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2272    if (!tv) return;
2273 
2274    gimv_thumb_view_refresh_list (tv);
2275 }
2276 
2277 static void
cb_reload(GimvThumbWin * tw,ThumbLoadType type,GtkWidget * widget)2278 cb_reload (GimvThumbWin *tw, ThumbLoadType type, GtkWidget *widget)
2279 {
2280    gimv_thumb_win_reload_thumbnail (tw, type);
2281 }
2282 
2283 
2284 static void
cb_clear_cache(GimvThumbWin * tw,CacheClearType type,GtkWidget * widget)2285 cb_clear_cache (GimvThumbWin *tw, CacheClearType type, GtkWidget *widget)
2286 {
2287    const gchar *path;
2288 
2289    switch (type) {
2290    case CLEAR_CACHE_TAB:
2291    {
2292       GimvThumbView *tv;
2293 
2294       tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2295       if (!tv) return;
2296 
2297       path = gimv_thumb_view_get_path (tv);
2298       gimv_thumb_cache_clear (path, conf.cache_write_type, 0, NULL);
2299       break;
2300    }
2301    case CLEAR_CACHE_ALL:
2302       gimv_thumb_cache_clear (NULL, conf.cache_write_type, 0, NULL);
2303       break;
2304    default:
2305       break;
2306    }
2307 }
2308 
2309 
2310 static void
cb_file_operate(GimvThumbWin * tw,guint action,GtkWidget * menuitem)2311 cb_file_operate (GimvThumbWin *tw, guint action, GtkWidget *menuitem)
2312 {
2313    GimvThumbView  *tv;
2314 
2315    g_return_if_fail (tw);
2316    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2317    if (!tv) return;
2318 
2319    switch (action) {
2320    case FILE_COPY:
2321       gimv_thumb_view_file_operate (tv, FILE_COPY);
2322       break;
2323    case FILE_MOVE:
2324       gimv_thumb_view_file_operate (tv, FILE_MOVE);
2325       break;
2326    case FILE_LINK:
2327       gimv_thumb_view_file_operate (tv, FILE_LINK);
2328       break;
2329    case FILE_RENAME:
2330       gimv_thumb_view_rename_file (tv);
2331       break;
2332    case FILE_REMOVE:
2333       gimv_thumb_view_delete_files (tv);
2334       break;
2335    default:
2336       break;
2337    }
2338 }
2339 
2340 
2341 static void
cb_find_similar(GimvThumbWin * tw,guint action,GtkWidget * widget)2342 cb_find_similar (GimvThumbWin *tw, guint action, GtkWidget *widget)
2343 {
2344    GimvThumbView *tv;
2345    const gchar **types;
2346 
2347    g_return_if_fail (tw);
2348 
2349    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2350    if (!tv) return;
2351 
2352    types = gimv_dupl_finder_get_algol_types();
2353    gimv_thumb_view_find_duplicates (tv, NULL, types[action]);
2354 }
2355 
2356 
2357 static void
cb_move_tab(GimvThumbWin * tw,MoveTabItem item,GtkWidget * widget)2358 cb_move_tab (GimvThumbWin *tw, MoveTabItem item, GtkWidget *widget)
2359 {
2360    GtkWidget *page_container;
2361    gint current_page;
2362 
2363    current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (tw->notebook));
2364    if (current_page < 0) return;
2365 
2366    page_container = gtk_notebook_get_nth_page (GTK_NOTEBOOK (tw->notebook),
2367                                                current_page);
2368 
2369    switch (item) {
2370    case LEFT:
2371       gtk_notebook_reorder_child (GTK_NOTEBOOK (tw->notebook),
2372                                   page_container, current_page - 1);
2373       break;
2374    case RIGHT:
2375       gtk_notebook_reorder_child (GTK_NOTEBOOK (tw->notebook),
2376                                   page_container, current_page + 1);
2377       break;
2378    default:
2379       break;
2380    }
2381 }
2382 
2383 
2384 static void
cb_cut_out_tab(GimvThumbWin * tw,guint action,GtkWidget * widget)2385 cb_cut_out_tab (GimvThumbWin *tw, guint action, GtkWidget *widget)
2386 {
2387    GimvThumbWin *tw_new;
2388    GimvThumbView  *tv;
2389 
2390    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2391    if (!tv) return;
2392 
2393    /* open new window */
2394    tw_new = gimv_thumb_win_open_window ();
2395 
2396    gimv_thumb_win_detach_tab (tw_new, tw, tv);
2397 }
2398 
2399 
2400 static void
cb_sort_item(GimvThumbWin * tw,GimvSortItem sortitem,GtkWidget * widget)2401 cb_sort_item (GimvThumbWin *tw, GimvSortItem sortitem, GtkWidget *widget)
2402 {
2403    GimvThumbView  *tv;
2404 
2405    tw->sortitem = sortitem;
2406 
2407    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2408    if (!tv) return;
2409 
2410    gimv_thumb_view_set_widget (tv, tv->tw, tv->container, tv->summary_mode);
2411 }
2412 
2413 
2414 static void
cb_sort_flag(GimvThumbWin * tw,GimvSortFlag sortflag,GtkWidget * widget)2415 cb_sort_flag (GimvThumbWin *tw, GimvSortFlag sortflag, GtkWidget *widget)
2416 {
2417    GimvThumbView  *tv;
2418 
2419    if (GTK_CHECK_MENU_ITEM (widget)->active) {
2420       tw->sortflags |= sortflag;
2421    } else {
2422       tw->sortflags &= ~sortflag;
2423    }
2424 
2425    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2426    if (!tv) return;
2427 
2428    gimv_thumb_view_set_widget (tv, tv->tw, tv->container, tv->summary_mode);
2429 }
2430 
2431 
2432 static void
cb_switch_layout(GimvThumbWin * tw,gint action,GtkWidget * widget)2433 cb_switch_layout (GimvThumbWin *tw, gint action, GtkWidget *widget)
2434 {
2435    gimv_thumb_win_change_layout (tw, action);
2436 }
2437 
2438 
2439 static void
cb_switch_tab_pos(GimvThumbWin * tw,GtkPositionType pos,GtkWidget * widget)2440 cb_switch_tab_pos (GimvThumbWin *tw, GtkPositionType pos, GtkWidget *widget)
2441 {
2442    g_return_if_fail (tw);
2443 
2444    tw->tab_pos = pos;
2445    gtk_notebook_set_tab_pos (GTK_NOTEBOOK (tw->notebook),
2446                              tw->tab_pos);
2447 }
2448 
2449 
2450 #ifdef USE_GTK2
2451 static void
g_list_randomize(GList ** lix)2452 g_list_randomize (GList **lix)
2453 {
2454    GList *newlist = NULL;
2455 
2456    gint num_elements;
2457    while ((num_elements = g_list_length(*lix)) > 0) {
2458         GList *element = g_list_nth(*lix, g_random_int_range(0, num_elements));
2459 
2460         newlist = g_list_append(newlist, element->data);
2461         *lix = g_list_remove_link(*lix, element);
2462    }
2463 
2464    *lix = newlist;
2465 }
2466 #endif /* USE_GTK2 */
2467 
2468 
2469 static void
cb_slideshow(GimvThumbWin * tw,guint action,GtkWidget * widget)2470 cb_slideshow (GimvThumbWin *tw, guint action, GtkWidget *widget)
2471 {
2472    GimvThumbView *tv;
2473    GimvThumb *thumb;
2474    GimvSlideShow *slideshow;
2475    GList *filelist = NULL, *list, *selection, *node, *start = NULL;
2476 
2477    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2478    if (!tv) return;
2479    if (!tv->priv) return;
2480 
2481    selection = gimv_thumb_view_get_selection_list (tv);
2482 
2483    if (tw->priv->slideshow_selected_only)
2484       list = selection;
2485    else
2486       list = tv->thumblist;
2487 
2488    for (node = list; node; node = g_list_next (node)) {
2489       thumb = node->data;
2490 
2491       if (gimv_image_info_is_dir (thumb->info)
2492           || gimv_image_info_is_archive (thumb->info))
2493       {
2494          continue;
2495       }
2496 
2497       if (gimv_image_info_is_movie (thumb->info)) {
2498          if (tw->priv->slideshow_file_type == SLIDESHOW_IMAGES_ONLY)
2499             continue;
2500       } else {
2501          if (tw->priv->slideshow_file_type == SLIDESHOW_MOVIES_ONLY)
2502             continue;
2503       }
2504 
2505       filelist = g_list_append (filelist, gimv_image_info_ref (thumb->info));
2506 
2507       if (!start) {
2508          if (tw->priv->slideshow_order == SLIDESHOW_START_FROM_SELECTED) {
2509             if (g_list_find (selection, thumb))
2510                start = g_list_find (filelist, thumb->info);
2511          } else {
2512             start = filelist;
2513          }
2514       }
2515    }
2516 
2517    if (filelist) {
2518 #ifdef USE_GTK2
2519       if (tw->priv->slideshow_order == SLIDESHOW_RANDOM_ORDER) {
2520          g_list_randomize(&filelist);
2521          start = filelist;
2522       }
2523 #endif /* USE_GTK2 */
2524 
2525       slideshow = gimv_slideshow_new_with_filelist (filelist, start);
2526       if (slideshow)
2527          gimv_slideshow_play (slideshow);
2528    }
2529 
2530    g_list_free (selection);
2531 }
2532 
2533 
2534 static void
cb_slideshow_order(GimvThumbWin * tw,SlideShowOrder action,GtkWidget * widget)2535 cb_slideshow_order (GimvThumbWin  *tw, SlideShowOrder action, GtkWidget *widget)
2536 {
2537    if (tw && tw->priv)
2538       tw->priv->slideshow_order = action;
2539 }
2540 
2541 
2542 static void
cb_slideshow_selected(GimvThumbWin * tw,guint action,GtkWidget * widget)2543 cb_slideshow_selected (GimvThumbWin *tw, guint action, GtkWidget *widget)
2544 {
2545    if (tw && tw->priv)
2546       tw->priv->slideshow_selected_only
2547 #ifdef USE_GTK2
2548          = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
2549 #else /* USE_GTK2 */
2550          = GTK_CHECK_MENU_ITEM (widget)->active;
2551 #endif /* USE_GTK2 */
2552 }
2553 
2554 static void
cb_slideshow_file_type(GimvThumbWin * tw,SlideShowFileType action,GtkWidget * widget)2555 cb_slideshow_file_type (GimvThumbWin *tw, SlideShowFileType action,
2556                         GtkWidget *widget)
2557 {
2558    if (tw && tw->priv)
2559       tw->priv->slideshow_file_type = action;
2560 }
2561 
2562 
2563 static void
cb_switch_page(GimvThumbWin * tw,SwitchPage action,GtkWidget * widget)2564 cb_switch_page (GimvThumbWin *tw, SwitchPage action, GtkWidget *widget)
2565 {
2566    switch (action) {
2567    case FIRST:
2568       gtk_notebook_set_page (GTK_NOTEBOOK (tw->notebook), 0);
2569       break;
2570    case LAST:
2571       gtk_notebook_set_page (GTK_NOTEBOOK (tw->notebook), -1);
2572       break;
2573    case NEXT:
2574       gtk_notebook_next_page (GTK_NOTEBOOK (tw->notebook));
2575       break;
2576    case PREV:
2577       gtk_notebook_prev_page (GTK_NOTEBOOK (tw->notebook));
2578       break;
2579    default:
2580       break;
2581    }
2582 }
2583 
2584 
2585 static void
cb_focus(GimvThumbWin * tw,FocusItem item,GtkWidget * menuitem)2586 cb_focus (GimvThumbWin *tw, FocusItem item, GtkWidget *menuitem)
2587 {
2588    GtkWidget *widget;
2589 
2590    switch (item) {
2591    case DIR_VIEW:
2592       widget = tw->dv->dirtree;
2593       break;
2594    case THUMBNAIL_VIEW:
2595    {
2596       GimvThumbView *tv;
2597 
2598       tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2599       if (tv)
2600          gimv_thumb_view_grab_focus (tv);
2601       return;
2602    }
2603    case PREVIEW:
2604       widget = tw->iv->draw_area;
2605       break;
2606    case LOCATION_ENTRY:
2607       widget = tw->location_entry;
2608       break;
2609    default:
2610       return;
2611    }
2612 
2613    if (GTK_IS_WIDGET (widget))
2614       gtk_widget_grab_focus (widget);
2615 }
2616 
2617 
2618 static void
cb_toggle_view(GimvThumbWin * tw,GimvComponentType item,GtkWidget * widget)2619 cb_toggle_view (GimvThumbWin *tw, GimvComponentType item, GtkWidget *widget)
2620 {
2621    g_return_if_fail (tw && (tw->layout_type < compose_type_num));
2622    gimv_thumb_win_pane_set_visible (tw, item);
2623 }
2624 
2625 
2626 static void
cb_toggle_show(GimvThumbWin * tw,ShowItem sitem,GtkWidget * widget)2627 cb_toggle_show (GimvThumbWin *tw, ShowItem sitem, GtkWidget *widget)
2628 {
2629    GtkWidget *item = NULL;
2630 
2631    switch (sitem) {
2632    case MENUBAR:
2633       item = tw->menubar_handle;
2634       break;
2635    case TOOLBAR:
2636       item = tw->toolbar_handle;
2637       break;
2638    case TAB:
2639       gtk_notebook_set_show_tabs (GTK_NOTEBOOK(tw->notebook),
2640                                   GTK_CHECK_MENU_ITEM(widget)->active);
2641       break;
2642    case STATUSBAR:
2643       item = tw->status_bar_container;
2644       break;
2645    case DIR_TOOLBAR:
2646       if (!tw->dv) return;
2647       if (GTK_CHECK_MENU_ITEM(widget)->active) {
2648          dirview_show_toolbar (tw->dv);
2649       } else {
2650          dirview_hide_toolbar (tw->dv);
2651       }
2652       return;
2653    case PREVIEW_TAB:
2654       if (tw->cv)
2655          gtk_notebook_set_show_tabs (GTK_NOTEBOOK(tw->cv->notebook),
2656                                      GTK_CHECK_MENU_ITEM(widget)->active);
2657       break;
2658    default:
2659       return;
2660       break;
2661    }
2662 
2663    if (sitem == TAB || sitem == PREVIEW_TAB)
2664       return;
2665 
2666    if (GTK_CHECK_MENU_ITEM(widget)->active) {
2667       gtk_widget_show (item);
2668    } else {
2669       gtk_widget_hide (item);
2670    }
2671 }
2672 
2673 
2674 static void
cb_switch_player(GimvThumbWin * tw,GimvImageViewPlayerVisibleType visible,GtkWidget * widget)2675 cb_switch_player (GimvThumbWin *tw, GimvImageViewPlayerVisibleType visible, GtkWidget *widget)
2676 {
2677    g_return_if_fail (tw);
2678    g_return_if_fail (GIMV_IS_IMAGE_VIEW (tw->iv));
2679 
2680    gimv_image_view_set_player_visible (tw->iv, visible);
2681    tw->player_visible = gimv_image_view_get_player_visible (tw->iv);
2682 }
2683 
2684 
2685 static void
cb_toggle_maximize(GimvThumbWin * tw,guint action,GtkWidget * widget)2686 cb_toggle_maximize (GimvThumbWin *tw, guint action, GtkWidget *widget)
2687 {
2688    GdkWindow *gdk_window = GTK_WIDGET (tw)->window;
2689    gint client_x, client_y, root_x, root_y;
2690    gint width, height;
2691 
2692    if (GTK_CHECK_MENU_ITEM(widget)->active) {
2693       gdk_window_get_origin (gdk_window, &root_x, &root_y);
2694       gdk_window_get_geometry (gdk_window, &client_x, &client_y,
2695                                &width, &height, NULL);
2696 
2697       gdk_window_move_resize (gdk_window, -client_x, -client_y,
2698                               gdk_screen_width (), gdk_screen_height ());
2699 
2700       tw->fullscreen = TRUE;
2701       tw->win_x = root_x - client_x;
2702       tw->win_y = root_y - client_y;
2703       tw->win_width  = width;
2704       tw->win_height = height;
2705 
2706    } else {
2707       gdk_window_move_resize (gdk_window, tw->win_x, tw->win_y,
2708                               tw->win_width, tw->win_height);
2709       tw->fullscreen = FALSE;
2710    }
2711 }
2712 
2713 
2714 static void
cb_win_composition_menu(GtkMenuItem * item,gpointer data)2715 cb_win_composition_menu (GtkMenuItem *item, gpointer data)
2716 {
2717    GimvThumbWin *tw = data;
2718    GtkCheckMenuItem *menuitem;
2719    gpointer p;
2720    gint num, n_win_comps;
2721    gboolean active;
2722 
2723    g_return_if_fail (tw);
2724 
2725    p = gtk_object_get_data (GTK_OBJECT (item), "num");
2726    num = GPOINTER_TO_INT (p);
2727    n_win_comps = sizeof (win_comp) / sizeof (gboolean) / 3;
2728    if (num < 0 || num > n_win_comps) return;
2729 
2730    conf.thumbwin_pane1_horizontal = win_comp[num][0];
2731    conf.thumbwin_pane2_horizontal = win_comp[num][1];
2732    conf.thumbwin_pane2_attach_1   = win_comp[num][2];
2733 
2734    menuitem = GTK_CHECK_MENU_ITEM(tw->menuitem.layout[5]);
2735    active = menuitem->active;
2736    gtk_check_menu_item_set_active (menuitem, TRUE);
2737    if (active)
2738       gtk_signal_emit_by_name (GTK_OBJECT (menuitem), "activate");
2739 }
2740 
2741 
2742 
2743 /******************************************************************************
2744  *
2745  *  Callback functions for toolbar buttons.
2746  *
2747  ******************************************************************************/
2748 #ifdef USE_GTK2
2749 static void
cb_location_entry_enter(GtkEditable * entry,GimvThumbWin * tw)2750 cb_location_entry_enter (GtkEditable *entry, GimvThumbWin *tw)
2751 {
2752    const gchar *path_internal;
2753    gchar *path, *dir;
2754 
2755    g_return_if_fail (tw);
2756 
2757    path_internal = gtk_entry_get_text (GTK_ENTRY (entry));
2758    path = charset_internal_to_locale (path_internal);
2759 
2760    if (isdir (path)) {
2761       dir = add_slash (path);
2762       open_dir_images (dir, tw, NULL, LOAD_CACHE, conf.scan_dir_recursive);
2763       g_free (dir);
2764    } else if (file_exists (path)) {
2765       if (fr_archive_utils_get_file_name_ext (path)) {
2766          open_archive_images (path, tw, NULL, LOAD_CACHE);
2767       } else {
2768          GimvImageInfo *info = gimv_image_info_get (path);
2769          if (info)
2770             gimv_image_view_change_image (tw->iv, info);
2771       }
2772    }
2773 
2774    g_free (path);
2775 }
2776 #endif /* USE_GTK2 */
2777 
2778 
2779 static gboolean
cb_location_entry_key_press(GtkWidget * widget,GdkEventKey * event,GimvThumbWin * tw)2780 cb_location_entry_key_press (GtkWidget *widget,
2781                              GdkEventKey *event,
2782                              GimvThumbWin *tw)
2783 {
2784    const gchar *path_internal;
2785    guint comp_key1 = 0, comp_key2 = 0;
2786    GdkModifierType comp_mods1 = 0, comp_mods2 = 0;
2787 
2788    g_return_val_if_fail (tw, FALSE);
2789 
2790    if (akey.common_auto_completion1)
2791       gtk_accelerator_parse (akey.common_auto_completion1,
2792                              &comp_key1, &comp_mods1);
2793    if (akey.common_auto_completion2)
2794       gtk_accelerator_parse (akey.common_auto_completion2,
2795                              &comp_key2, &comp_mods2);
2796 
2797    if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter) {
2798       gchar *path;
2799 
2800       path_internal = gtk_entry_get_text (GTK_ENTRY (widget));
2801       path = charset_internal_to_locale (path_internal);
2802 
2803       if (isdir (path)) {
2804          gchar *dir = add_slash (path);
2805          open_dir_images (dir, tw, NULL, LOAD_CACHE, conf.scan_dir_recursive);
2806          g_free (dir);
2807       } else if (file_exists (path)) {
2808          if (fr_archive_utils_get_file_name_ext (path)) {
2809             open_archive_images (path, tw, NULL, LOAD_CACHE);
2810          } else {
2811             GimvImageInfo *info = gimv_image_info_get (path);
2812             if (info)
2813                gimv_image_view_change_image (tw->iv, info);
2814          }
2815       }
2816 
2817       g_free (path);
2818 
2819       return TRUE;
2820 
2821    } else if (event->keyval == GDK_Tab
2822               || (event->keyval == comp_key1 && (!comp_mods1 || (event->state & comp_mods1)))
2823               || (event->keyval == comp_key2 && (!comp_mods2 || (event->state & comp_mods2))))
2824       {
2825          gchar *text, *dirname;
2826          gint n;
2827 
2828          path_internal = gtk_entry_get_text (GTK_ENTRY (widget));
2829          n = auto_compl_get_n_alternatives (path_internal);
2830 
2831          if (n < 1) return TRUE;
2832 
2833          text = auto_compl_get_common_prefix ();
2834 
2835          if (n == 1) {
2836             auto_compl_hide_alternatives ();
2837             gtk_entry_set_text (GTK_ENTRY (widget), text);
2838             if (text[strlen(text) - 1] != '/')
2839                gtk_entry_append_text (GTK_ENTRY (widget), "/");
2840             dirview_change_dir (tw->dv, text);
2841          } else {
2842             gtk_entry_set_text (GTK_ENTRY (widget), text);
2843             dirname = g_dirname (text);
2844             if (tw->show_dirview)
2845                dirview_change_dir (tw->dv, dirname);
2846             g_free (dirname);
2847             auto_compl_show_alternatives (widget);
2848          }
2849 
2850 #ifdef USE_GTK2
2851          gtk_editable_set_position (GTK_EDITABLE (widget), -1);
2852 #endif /* USE_GTK2 */
2853 
2854          g_free (text);
2855 
2856          return TRUE;
2857 
2858       } else if (event->keyval == GDK_Escape) {
2859          gtk_window_set_focus (GTK_WINDOW (tw), NULL);
2860          return TRUE;
2861 
2862       } else if (event->keyval == GDK_Right || event->keyval == GDK_Left
2863                  || event->keyval == GDK_Up || event->keyval == GDK_Down)
2864          {
2865             return TRUE;
2866          }
2867 
2868    return TRUE;
2869 }
2870 
2871 
2872 static void
cb_location_entry_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * seldata,guint info,guint time,gpointer data)2873 cb_location_entry_drag_data_received (GtkWidget *widget,
2874                                       GdkDragContext *context,
2875                                       gint x, gint y,
2876                                       GtkSelectionData *seldata,
2877                                       guint info,
2878                                       guint time,
2879                                       gpointer data)
2880 {
2881    GimvThumbWin *tw = data;
2882    GList *list;
2883 
2884    switch (info) {
2885    case TARGET_URI_LIST:
2886       list = dnd_get_file_list (seldata->data, seldata->length);
2887       gimv_thumb_win_location_entry_set_text (tw, list->data);
2888       g_list_foreach (list, (GFunc) g_free, NULL);
2889       g_list_free (list);
2890       break;
2891 
2892    default:
2893       break;
2894    }
2895 }
2896 
2897 
2898 static void
cb_open_button(GtkWidget * widget,GimvThumbWin * tw)2899 cb_open_button (GtkWidget *widget, GimvThumbWin *tw)
2900 {
2901    if (tw->open_dialog)
2902       gdk_window_raise (tw->open_dialog->window);
2903    else
2904       tw->open_dialog = (GtkWidget *) create_filebrowser (tw);
2905 }
2906 
2907 
2908 static void
cb_refresh_button(GtkWidget * widget,GimvThumbWin * tw)2909 cb_refresh_button (GtkWidget *widget, GimvThumbWin *tw)
2910 {
2911    /* ThumbView *tv; */
2912 
2913    if (!tw) return;
2914 
2915    gtk_signal_handler_block_by_func (GTK_OBJECT (widget),
2916                                      GTK_SIGNAL_FUNC (cb_refresh_button),
2917                                      tw);
2918 
2919    gimv_thumb_win_reload_thumbnail (tw, LOAD_CACHE);
2920 
2921    gtk_signal_handler_unblock_by_func (GTK_OBJECT (widget),
2922                                        GTK_SIGNAL_FUNC (cb_refresh_button),
2923                                        tw);
2924 }
2925 
2926 
2927 static void
cb_previous_button(GtkWidget * widget,GimvThumbWin * tw)2928 cb_previous_button (GtkWidget *widget, GimvThumbWin *tw)
2929 {
2930    gtk_notebook_prev_page (GTK_NOTEBOOK (tw->notebook));
2931 }
2932 
2933 
2934 
2935 static void
cb_next_button(GtkWidget * widget,GimvThumbWin * tw)2936 cb_next_button (GtkWidget *widget, GimvThumbWin *tw)
2937 {
2938    gtk_notebook_next_page (GTK_NOTEBOOK (tw->notebook));
2939 }
2940 
2941 
2942 static void
cb_skip_button(GtkWidget * widget,GimvThumbWin * tw)2943 cb_skip_button (GtkWidget *widget, GimvThumbWin *tw)
2944 {
2945    GimvThumbView *tv;
2946 
2947    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
2948 
2949    if (tv && tv->progress) {
2950       tv->progress->status = CANCEL;
2951    }
2952 }
2953 
2954 
2955 static gboolean
cb_size_spinner_key_press(GtkWidget * widget,GdkEventKey * event,GimvThumbWin * tw)2956 cb_size_spinner_key_press (GtkWidget *widget,
2957                            GdkEventKey *event,
2958                            GimvThumbWin *tw)
2959 {
2960    g_return_val_if_fail (tw, FALSE);
2961 
2962    switch (event->keyval) {
2963    case GDK_Escape:
2964       gtk_window_set_focus (GTK_WINDOW (tw), NULL);
2965       return TRUE;
2966    }
2967 
2968    return TRUE;
2969 }
2970 
2971 
2972 static void
cb_stop_button(GtkWidget * widget,GimvThumbWin * tw)2973 cb_stop_button (GtkWidget *widget, GimvThumbWin *tw)
2974 {
2975    g_return_if_fail (tw);
2976 
2977    /*
2978    for (i = 0; i < tw->pagenum; i++) {
2979       tv = gimv_thumb_win_find_thumbtable (tw, i);
2980 
2981       if (tv && tv->thumb_window == tw && tv->progress) {
2982          tv->progress->status = STOP;
2983       }
2984    }
2985    */
2986 
2987    files_loader_stop ();
2988 }
2989 
2990 
2991 static void
cb_prefs_button(GtkWidget * widget,GimvThumbWin * tw)2992 cb_prefs_button (GtkWidget *widget, GimvThumbWin *tw)
2993 {
2994    gimv_prefs_win_open_idle ("/Thumbnail Window", GTK_WINDOW (tw));
2995 }
2996 
2997 
2998 static void
cb_quit_button(GtkWidget * widget,GimvThumbWin * tw)2999 cb_quit_button (GtkWidget *widget, GimvThumbWin *tw)
3000 {
3001    gimv_quit ();
3002 }
3003 
3004 
3005 static void
cb_display_mode_menu(GtkWidget * widget,GimvThumbWin * tw)3006 cb_display_mode_menu (GtkWidget *widget, GimvThumbWin *tw)
3007 {
3008    GimvThumbView *tv;
3009    gint summary_mode;
3010 
3011    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
3012    if (!tv) return;
3013 
3014    summary_mode = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "num"));
3015    tw->thumbview_summary_mode = gimv_thumb_view_num_to_label (summary_mode);
3016 
3017    gtk_signal_handler_block_by_func (GTK_OBJECT (widget),
3018                                      GTK_SIGNAL_FUNC (cb_display_mode_menu),
3019                                      tw);
3020 
3021    gimv_thumb_view_change_summary_mode (
3022       tv, gimv_thumb_view_num_to_label (summary_mode));
3023    gtk_option_menu_set_history (GTK_OPTION_MENU (tw->summary_mode_menu),
3024                                 summary_mode);
3025 
3026    gtk_signal_handler_unblock_by_func (GTK_OBJECT (widget),
3027                                        GTK_SIGNAL_FUNC(cb_display_mode_menu),
3028                                        tw);
3029 }
3030 
3031 
3032 
3033 /******************************************************************************
3034  *
3035  *   other collback functions for thumbnail window.
3036  *
3037  ******************************************************************************/
3038 static void
cb_thumb_notebook_switch_page(GtkNotebook * notebook,GtkNotebookPage * page,gint pagenum,GimvThumbWin * tw)3039 cb_thumb_notebook_switch_page (GtkNotebook *notebook, GtkNotebookPage *page,
3040                                gint pagenum, GimvThumbWin *tw)
3041 {
3042    GimvThumbView *tv = NULL;
3043    gint summary_mode
3044       = gimv_thumb_view_label_to_num (GIMV_THUMB_VIEW_DEFAULT_SUMMARY_MODE);
3045    GList *node;
3046 
3047    g_return_if_fail (notebook && tw);
3048    node = g_list_find (ThumbWinList, tw);
3049    if (!node) return;
3050 
3051    tv = gimv_thumb_win_find_thumbtable (tw, pagenum);
3052 
3053    if (files_loader_query_loading ()) {
3054       gimv_thumb_win_set_sensitive (tw, GIMV_THUMB_WIN_STATUS_LOADING);
3055       /*
3056       if (tv && tv->progress)
3057          tw->status = THUMB_WIN_STATUS_LOADING;
3058       else
3059          tw->status = THUMB_WIN_STATUS_LOADING_BG;
3060       */
3061    }
3062 
3063    gimv_thumb_win_set_statusbar_page_info (tw, pagenum);
3064 
3065    if (tv) {
3066       location_entry_set_text (tw, tv, NULL);
3067 
3068       gtk_spin_button_set_value (GTK_SPIN_BUTTON (tw->button.size_spin),
3069                                  tv->thumb_size);
3070       gtk_option_menu_set_history (GTK_OPTION_MENU (tw->summary_mode_menu),
3071                                    gimv_thumb_view_label_to_num (tv->summary_mode));
3072       summary_mode = gimv_thumb_view_label_to_num (tv->summary_mode);
3073 
3074       if (tw->status == GIMV_THUMB_WIN_STATUS_LOADING
3075           || tw->status == GIMV_THUMB_WIN_STATUS_LOADING_BG
3076           || files_loader_query_loading ())
3077          {
3078             if (tv->progress)
3079                gimv_thumb_win_set_sensitive (tw, GIMV_THUMB_WIN_STATUS_LOADING);
3080             else
3081                gimv_thumb_win_set_sensitive (tw, GIMV_THUMB_WIN_STATUS_LOADING_BG);
3082          }
3083 
3084       if (tw->show_dirview) {
3085          const gchar *path;
3086 
3087          path = gimv_thumb_view_get_path (tv);
3088          if (path && isdir (path)) {
3089             dirview_change_dir (tw->dv, path);
3090          } else if (path && isfile (path)) {
3091             gchar *dirname = g_dirname (path);
3092             dirview_change_dir (tw->dv, dirname);
3093             g_free(dirname);
3094          }
3095       }
3096 
3097    } else {   /* if empty page */
3098       if (tw->location_entry)
3099          gimv_thumb_win_location_entry_set_text (tw, g_getenv("HOME"));
3100 
3101       if (tw->button.size_spin)
3102          gtk_spin_button_set_value (GTK_SPIN_BUTTON (tw->button.size_spin),
3103                                     conf.thumbwin_thumb_size);
3104       if (tw->summary_mode_menu) {
3105          summary_mode = gimv_thumb_view_label_to_num (tw->thumbview_summary_mode);
3106          if (summary_mode < 0)
3107             summary_mode
3108                = gimv_thumb_view_label_to_num (
3109                      GIMV_THUMB_VIEW_DEFAULT_SUMMARY_MODE);
3110          gtk_option_menu_set_history (GTK_OPTION_MENU (tw->summary_mode_menu),
3111                                       summary_mode);
3112       }
3113 
3114       if (tw->status == GIMV_THUMB_WIN_STATUS_LOADING
3115           || tw->status == GIMV_THUMB_WIN_STATUS_LOADING_BG)
3116          {
3117             gimv_thumb_win_set_sensitive (tw, GIMV_THUMB_WIN_STATUS_LOADING_BG);
3118          }
3119    }
3120 
3121    tw->thumbview_summary_mode = gimv_thumb_view_num_to_label (summary_mode);
3122 }
3123 
3124 
3125 static void
cb_tab_close_button_clicked(GtkWidget * button,GimvThumbWin * tw)3126 cb_tab_close_button_clicked (GtkWidget *button, GimvThumbWin *tw)
3127 {
3128    GtkWidget *container;
3129    gint num;
3130 
3131    container = gtk_object_get_data (GTK_OBJECT (button), "page-container");
3132    num = gtk_notebook_page_num (GTK_NOTEBOOK (tw->notebook), container);
3133 
3134    gimv_thumb_win_close_tab (tw, num);
3135    gimv_thumb_win_set_statusbar_page_info (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
3136 }
3137 
3138 
3139 static void
cb_com_drag_begin(GtkWidget * widget,GdkDragContext * context,gpointer data)3140 cb_com_drag_begin (GtkWidget *widget,
3141                    GdkDragContext *context,
3142                    gpointer data)
3143 {
3144    GdkColormap *colormap;
3145    GimvIcon *icon;
3146 
3147    icon = gimv_icon_stock_get_icon ("paper");
3148    colormap = gdk_colormap_get_system ();
3149    gtk_drag_set_icon_pixmap (context, colormap,
3150                              icon->pixmap, icon->mask,
3151                              0, 0);
3152 }
3153 
3154 
3155 static void
cb_com_drag_data_get(GtkWidget * widget,GdkDragContext * context,GtkSelectionData * seldata,guint info,guint time,gpointer data)3156 cb_com_drag_data_get (GtkWidget *widget,
3157                       GdkDragContext *context,
3158                       GtkSelectionData *seldata,
3159                       guint info,
3160                       guint time,
3161                       gpointer data)
3162 {
3163    switch (info) {
3164    case TARGET_GIMV_TAB:
3165    case TARGET_GIMV_COMPONENT:
3166       gtk_selection_data_set(seldata, seldata->target,
3167                              8, "dummy", strlen("dummy"));
3168       break;
3169    }
3170 }
3171 
3172 
3173 typedef struct SwapCom_Tag
3174 {
3175    GimvThumbWin *tw;
3176    gint src;
3177    gint dest;
3178 } SwapCom;
3179 
3180 
3181 static gint
idle_gimv_thumb_win_swap_component(gpointer data)3182 idle_gimv_thumb_win_swap_component (gpointer data)
3183 {
3184    SwapCom *swap = data;
3185    gimv_thumb_win_swap_component (swap->tw, swap->src, swap->dest);
3186    return FALSE;
3187 }
3188 
3189 
3190 static void
cb_notebook_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * seldata,guint info,guint time,gpointer data)3191 cb_notebook_drag_data_received (GtkWidget *widget,
3192                                 GdkDragContext *context,
3193                                 gint x, gint y,
3194                                 GtkSelectionData *seldata,
3195                                 guint info,
3196                                 guint time,
3197                                 gpointer data)
3198 {
3199    GimvThumbWin *tw = data;
3200    GimvThumbView *tv;
3201    GtkWidget *src_widget;
3202    GList *list;
3203    gpointer p;
3204    gint src, dest;
3205 
3206    switch (info) {
3207    case TARGET_URI_LIST:
3208       list = dnd_get_file_list (seldata->data, seldata->length);
3209       open_images_dirs (list, tw, LOAD_CACHE, FALSE);
3210       g_list_foreach (list, (GFunc) g_free, NULL);
3211       g_list_free (list);
3212       break;
3213 
3214    case TARGET_GIMV_TAB:
3215       src_widget = gtk_drag_get_source_widget (context);
3216       if (src_widget && GTK_IS_NOTEBOOK (src_widget)) {
3217          GimvThumbWin *tw_src, *tw_dest = tw;
3218 
3219          tw_src = gtk_object_get_data (GTK_OBJECT (src_widget), "thumbwin");
3220          if (!tw_src) return;
3221 
3222          /* if deferent window, detach tab */
3223          if (tw_src != tw_dest) {
3224             tv = gimv_thumb_win_find_thumbtable (tw_src, GIMV_THUMB_WIN_CURRENT_PAGE);
3225             if (!tv) return;
3226 
3227             gimv_thumb_win_detach_tab (tw_dest, tw_src, tv);
3228          }
3229       }
3230       break;
3231 
3232    case TARGET_GIMV_COMPONENT:
3233       src_widget = gtk_drag_get_source_widget (context);
3234       if (!src_widget) return;
3235       if (gdk_window_get_toplevel (src_widget->window)
3236           != gdk_window_get_toplevel (widget->window))
3237          {
3238             return;
3239          }
3240 
3241       p = gtk_object_get_data (GTK_OBJECT (src_widget), "gimv-component");
3242       src = GPOINTER_TO_INT (p);
3243       if (!src) return;
3244 
3245       p = gtk_object_get_data (GTK_OBJECT (widget), "gimv-component");
3246       dest = GPOINTER_TO_INT (p);
3247       if (!dest) return;
3248 
3249       /* to avoid gtk's bug, exec redraw after exit this callback function */
3250       {
3251          SwapCom *swap = g_new0 (SwapCom, 1);
3252          swap->tw = tw;
3253          swap->src = src;
3254          swap->dest = dest;
3255          gtk_idle_add_full (GTK_PRIORITY_REDRAW,
3256                             idle_gimv_thumb_win_swap_component, NULL, swap,
3257                             (GtkDestroyNotify) g_free);
3258       }
3259 
3260       break;
3261    }
3262 }
3263 
3264 
3265 static void
cb_tab_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * seldata,guint info,guint time,gpointer data)3266 cb_tab_drag_data_received (GtkWidget *widget,
3267                            GdkDragContext *context,
3268                            gint x, gint y,
3269                            GtkSelectionData *seldata,
3270                            guint info,
3271                            guint time,
3272                            gpointer data)
3273 {
3274    GimvThumbWin *tw = data;
3275    GimvThumbView *tv;
3276    GtkWidget *page_container;
3277    GtkWidget *src_widget;
3278    gint pagenum;
3279    gpointer p;
3280    gint src, dest;
3281 
3282    g_return_if_fail (widget && tw);
3283 
3284    page_container = gtk_object_get_data (GTK_OBJECT (widget), "page-container");
3285    if (!page_container) return;
3286 
3287    switch (info) {
3288    case TARGET_URI_LIST:
3289       pagenum = gtk_notebook_page_num (GTK_NOTEBOOK (tw->notebook),
3290                                        page_container);
3291 
3292       tv = gimv_thumb_win_find_thumbtable (tw, pagenum);
3293       if (!tv) return;
3294 
3295       gimv_thumb_view_drag_data_received_cb (widget, context, x, y,
3296                                              seldata, info, time, tv);
3297       break;
3298 
3299    case TARGET_GIMV_TAB:
3300       src_widget = gtk_drag_get_source_widget (context);
3301       if (src_widget && GTK_IS_NOTEBOOK (src_widget)) {
3302          GtkNotebook *notebook = GTK_NOTEBOOK (src_widget);
3303          GtkWidget *src_page, *newtab;
3304          GimvThumbWin *tw_src, *tw_dest = tw;
3305          gint src_pagenum, dest_pagenum;
3306 
3307          tw_src = gtk_object_get_data (GTK_OBJECT (src_widget), "thumbwin");
3308          if (!tw_src) return;
3309 
3310          dest_pagenum = gtk_notebook_page_num (GTK_NOTEBOOK (tw_dest->notebook),
3311                                                page_container);
3312 
3313          /* if same window, reorder pages */
3314          if (tw_src == tw_dest) {
3315             src_pagenum = gtk_notebook_get_current_page (notebook);
3316             if (src_pagenum < 0) return;
3317 
3318             src_page = gtk_notebook_get_nth_page (notebook, src_pagenum);
3319             if (!src_page) return;
3320 
3321             gtk_notebook_reorder_child (notebook, src_page, dest_pagenum);
3322 
3323             /* if deferent window, detach tab */
3324          } else {
3325             tv = gimv_thumb_win_find_thumbtable (tw_src, GIMV_THUMB_WIN_CURRENT_PAGE);
3326             if (!tv) return;
3327 
3328             if (dest_pagenum < 0) return;
3329 
3330             newtab = gimv_thumb_win_detach_tab (tw_dest, tw_src, tv);
3331             gtk_notebook_reorder_child (GTK_NOTEBOOK (tw_dest->notebook),
3332                                         newtab, dest_pagenum);
3333          }
3334       }
3335       break;
3336 
3337    case TARGET_GIMV_COMPONENT:
3338       src_widget = gtk_drag_get_source_widget (context);
3339       if (!src_widget) return;
3340       if (gdk_window_get_toplevel (src_widget->window)
3341           != gdk_window_get_toplevel (widget->window))
3342          {
3343             return;
3344          }
3345 
3346       p = gtk_object_get_data (GTK_OBJECT (src_widget), "gimv-component");
3347       src = GPOINTER_TO_INT (p);
3348       if (!src) return;
3349 
3350       p = gtk_object_get_data (GTK_OBJECT (widget), "gimv-component");
3351       dest = GPOINTER_TO_INT (p);
3352       if (!dest) return;
3353 
3354       {
3355          SwapCom *swap = g_new0 (SwapCom, 1);
3356          swap->tw = tw;
3357          swap->src = src;
3358          swap->dest = dest;
3359          gtk_idle_add_full (GTK_PRIORITY_REDRAW,
3360                             idle_gimv_thumb_win_swap_component, NULL, swap,
3361                             (GtkDestroyNotify) g_free);
3362       }
3363 
3364       break;
3365    }
3366 }
3367 
3368 
3369 static void
cb_com_swap_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * seldata,guint info,guint time,gpointer data)3370 cb_com_swap_drag_data_received (GtkWidget *widget,
3371                                 GdkDragContext *context,
3372                                 gint x, gint y,
3373                                 GtkSelectionData *seldata,
3374                                 guint info,
3375                                 guint time,
3376                                 gpointer data)
3377 {
3378    GimvThumbWin *tw = data;
3379    GtkWidget *src_widget;
3380    gpointer p;
3381    gint src, dest;
3382 
3383    switch (info) {
3384    case TARGET_GIMV_COMPONENT:
3385       src_widget = gtk_drag_get_source_widget (context);
3386       if (!src_widget) return;
3387       if (gdk_window_get_toplevel (src_widget->window)
3388           != gdk_window_get_toplevel (widget->window))
3389          {
3390             return;
3391          }
3392 
3393       p = gtk_object_get_data (GTK_OBJECT (src_widget), "gimv-component");
3394       src = GPOINTER_TO_INT (p);
3395       if (!src) return;
3396 
3397       p = gtk_object_get_data (GTK_OBJECT (widget), "gimv-component");
3398       dest = GPOINTER_TO_INT (p);
3399       if (!dest) return;
3400 
3401       {
3402          SwapCom *swap = g_new0 (SwapCom, 1);
3403          swap->tw = tw;
3404          swap->src = src;
3405          swap->dest = dest;
3406          gtk_idle_add_full (GTK_PRIORITY_REDRAW,
3407                             idle_gimv_thumb_win_swap_component, NULL, swap,
3408                             (GtkDestroyNotify) g_free);
3409       }
3410 
3411       break;
3412 
3413    default:
3414       break;
3415    }
3416 }
3417 
3418 
3419 #ifdef USE_GTK2   /* FIXME */
3420 void
gimv_thumb_win_remove_key_accel(GimvThumbWin * tw)3421 gimv_thumb_win_remove_key_accel (GimvThumbWin *tw)
3422 {
3423    GSList *node;
3424 
3425    for (node = tw->accel_group_list; node; node = g_slist_next (node)) {
3426       GtkAccelGroup *accel_group = node->data;
3427       gtk_window_remove_accel_group (GTK_WINDOW (tw), accel_group);
3428    }
3429 }
3430 
3431 
3432 void
gimv_thumb_win_reset_key_accel(GimvThumbWin * tw)3433 gimv_thumb_win_reset_key_accel (GimvThumbWin *tw)
3434 {
3435    GSList *node;
3436 
3437    for (node = tw->accel_group_list; node; node = g_slist_next (node)) {
3438       GtkAccelGroup *accel_group = node->data;
3439       gtk_window_add_accel_group (GTK_WINDOW (tw), accel_group);
3440    }
3441 }
3442 
3443 
3444 static gboolean
cb_focus_in(GtkWidget * widget,GdkEventFocus * event,GimvThumbWin * tw)3445 cb_focus_in (GtkWidget *widget, GdkEventFocus *event, GimvThumbWin *tw)
3446 {
3447    gimv_thumb_win_remove_key_accel (tw);
3448    return FALSE;
3449 }
3450 
3451 
3452 static gboolean
cb_focus_out(GtkWidget * widget,GdkEventFocus * event,GimvThumbWin * tw)3453 cb_focus_out (GtkWidget *widget, GdkEventFocus *event, GimvThumbWin *tw)
3454 {
3455    gimv_thumb_win_reset_key_accel (tw);
3456    return FALSE;
3457 }
3458 #endif /* USE_GTK2 */
3459 
3460 
3461 
3462 /******************************************************************************
3463  *
3464  *   Utility.
3465  *
3466  ******************************************************************************/
3467 GList *
gimv_thumb_win_get_list(void)3468 gimv_thumb_win_get_list (void)
3469 {
3470    return ThumbWinList;
3471 }
3472 
3473 
3474 GimvThumbView *
gimv_thumb_win_find_thumbtable(GimvThumbWin * tw,gint pagenum)3475 gimv_thumb_win_find_thumbtable (GimvThumbWin *tw, gint pagenum)
3476 {
3477    GimvThumbView *tv;
3478    GtkWidget *tab;
3479    GList *node;
3480    gint i, num;
3481 
3482    g_return_val_if_fail (tw, NULL);
3483    node = g_list_find (ThumbWinList, tw);
3484    if (!node) return NULL;
3485 
3486    if (pagenum == GIMV_THUMB_WIN_CURRENT_PAGE)
3487       pagenum = gtk_notebook_get_current_page (GTK_NOTEBOOK(tw->notebook));
3488    tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK(tw->notebook), pagenum);
3489    node = gimv_thumb_view_get_list();
3490    num = g_list_length (gimv_thumb_view_get_list());
3491    for (i = 0; i < num; i++) {
3492       tv = node->data;
3493       if (tv->container == tab) {
3494          return tv;
3495       }
3496       node = g_list_next (node);
3497    }
3498    return NULL;
3499 }
3500 
3501 
3502 void
gimv_thumb_win_set_statusbar_page_info(GimvThumbWin * tw,gint pagenum)3503 gimv_thumb_win_set_statusbar_page_info (GimvThumbWin *tw, gint pagenum)
3504 {
3505    GimvThumbView *tv;
3506    gint page, tv_filenum;
3507    gulong tv_filesize;
3508    gchar buf[BUF_SIZE];
3509    gfloat progress = 0.0;
3510    GList *node;
3511    gboolean update_statusbar1 = FALSE;
3512 
3513    g_return_if_fail (tw);
3514    node = g_list_find (ThumbWinList, tw);
3515    if (!node) return;
3516 
3517    if (pagenum == GIMV_THUMB_WIN_CURRENT_PAGE)
3518       page = gtk_notebook_get_current_page (GTK_NOTEBOOK(tw->notebook));
3519    else
3520       page = pagenum;
3521 
3522    tv = gimv_thumb_win_find_thumbtable (tw, page);
3523 
3524    if (!tv) {
3525       gtk_progress_set_show_text(GTK_PROGRESS(tw->progressbar), FALSE);
3526       g_snprintf (buf, BUF_SIZE, _("Empty"));
3527       tv_filenum = 0;
3528       tv_filesize = 0;
3529       progress = 0.0;
3530    } else if (tv->progress){
3531       if (conf.thumbwin_show_progress_detail) {
3532          gtk_progress_set_show_text(GTK_PROGRESS(tw->progressbar), TRUE);
3533          g_snprintf (buf, BUF_SIZE, _("%d/%d files"),
3534                      tv->progress->pos, tv->progress->num);
3535 
3536          gtk_progress_set_format_string(GTK_PROGRESS(tw->progressbar), buf);
3537          if (tv->progress->now_file) {
3538             gchar *tmpstr;
3539 
3540             tmpstr = charset_to_internal (tv->progress->now_file,
3541                                           conf.charset_filename,
3542                                           conf.charset_auto_detect_fn,
3543                                           conf.charset_filename_mode);
3544             g_snprintf (buf, BUF_SIZE, "%s", tmpstr);
3545             g_free (tmpstr);
3546             update_statusbar1 = TRUE;
3547          } else {
3548             gtk_progress_set_show_text(GTK_PROGRESS(tw->progressbar), FALSE);
3549          }
3550       }
3551       progress = (gfloat) tv->progress->pos / (gfloat) tv->progress->num;
3552       tv_filenum = tv->filenum;
3553       tv_filesize = tv->filesize;
3554    } else {
3555       const gchar *real_path;
3556 
3557       gtk_progress_set_show_text(GTK_PROGRESS(tw->progressbar), FALSE);
3558       tv_filenum = tv->filenum;
3559       tv_filesize = tv->filesize;
3560 
3561       real_path = gimv_thumb_view_get_path (tv);
3562       if (real_path) {
3563          const gchar *format_str = NULL;
3564          gchar *path, *tmpstr;
3565 
3566          if (tv->mode == GIMV_THUMB_VIEW_MODE_DIR)
3567             format_str = _("Dir View: %s");
3568          else if (tv->mode == GIMV_THUMB_VIEW_MODE_ARCHIVE)
3569             format_str = _("Archive View: %s");
3570 
3571          if (format_str) {
3572             path = fileutil_home2tilde (real_path);
3573             tmpstr = charset_to_internal (path,
3574                                           conf.charset_filename,
3575                                           conf.charset_auto_detect_fn,
3576                                           conf.charset_filename_mode);
3577 
3578             g_snprintf (buf, BUF_SIZE, format_str, tmpstr);
3579 
3580             g_free (tmpstr);
3581             g_free (path);
3582          }
3583       } else {
3584          g_snprintf (buf, BUF_SIZE, _("Collection View"));
3585       }
3586 
3587       progress = 0.0;
3588       update_statusbar1 = TRUE;
3589    }
3590 
3591    if ((!tv || !tv->progress) && tw->status == GIMV_THUMB_WIN_STATUS_LOADING_BG) {
3592       gtk_progress_set_show_text(GTK_PROGRESS(tw->progressbar), TRUE);
3593       gtk_progress_set_format_string(GTK_PROGRESS(tw->progressbar),
3594                                      _("Loading in another tab..."));
3595    }
3596 
3597    /* update status bar */
3598    if (update_statusbar1) {
3599       gtk_statusbar_pop (GTK_STATUSBAR (tw->status_bar1), 1);
3600       gtk_statusbar_push (GTK_STATUSBAR (tw->status_bar1), 1, buf);
3601    }
3602    g_snprintf (buf, BUF_SIZE, _("%d/%d page  %d/%d files  %ld/%ld kB"),
3603                page + 1, tw->pagenum, tv_filenum, tw->filenum,
3604                tv_filesize / 1024, tw->filesize / 1024);
3605    gtk_statusbar_pop (GTK_STATUSBAR (tw->status_bar2), 1);
3606    gtk_statusbar_push (GTK_STATUSBAR (tw->status_bar2), 1, buf);
3607    /* update progress bar */
3608    gtk_progress_bar_update (GTK_PROGRESS_BAR(tw->progressbar), progress);
3609 }
3610 
3611 
3612 void
gimv_thumb_win_loading_update_progress(GimvThumbWin * tw,gint pagenum)3613 gimv_thumb_win_loading_update_progress (GimvThumbWin *tw, gint pagenum)
3614 {
3615    GimvThumbView *tv;
3616    gint page;
3617    gchar buf[BUF_SIZE], *tmpstr;
3618    gfloat progress = 0.0;
3619    GList *node;
3620 
3621    g_return_if_fail (tw);
3622    node = g_list_find (ThumbWinList, tw);
3623    if (!node) return;
3624 
3625    if (pagenum == GIMV_THUMB_WIN_CURRENT_PAGE)
3626       page = gtk_notebook_get_current_page (GTK_NOTEBOOK(tw->notebook));
3627    else
3628       page = pagenum;
3629 
3630    tv = gimv_thumb_win_find_thumbtable (tw, page);
3631    if (!tv) return;
3632    if (!tv->progress) return;
3633 
3634    if (conf.thumbwin_show_progress_detail) {
3635       gtk_progress_set_show_text(GTK_PROGRESS(tw->progressbar), TRUE);
3636       g_snprintf (buf, BUF_SIZE, _("%d/%d files"),
3637                   tv->progress->pos, tv->progress->num);
3638       gtk_progress_set_format_string(GTK_PROGRESS(tw->progressbar), buf);
3639       tmpstr = charset_to_internal (tv->progress->now_file,
3640                                     conf.charset_filename,
3641                                     conf.charset_auto_detect_fn,
3642                                     conf.charset_filename_mode);
3643       g_snprintf (buf, BUF_SIZE, "%s", tmpstr);
3644       g_free (tmpstr);
3645       gtk_statusbar_pop (GTK_STATUSBAR (tw->status_bar1), 1);
3646       gtk_statusbar_push (GTK_STATUSBAR (tw->status_bar1), 1, buf);
3647    }
3648    progress = (gfloat) tv->progress->pos / (gfloat) tv->progress->num;
3649 
3650    /* update progress bar */
3651    gtk_progress_bar_update (GTK_PROGRESS_BAR(tw->progressbar), progress);
3652 }
3653 
3654 
3655 #define SET_SENSITIVE_WIDGETS_NUM 23
3656 
3657 void
gimv_thumb_win_set_sensitive(GimvThumbWin * tw,GimvThumbwinStatus status)3658 gimv_thumb_win_set_sensitive (GimvThumbWin *tw, GimvThumbwinStatus status)
3659 {
3660    gboolean gimv_thumb_win_status [][SET_SENSITIVE_WIDGETS_NUM] =
3661       {
3662          /* status: normal */
3663          {TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,
3664           TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  FALSE, FALSE,
3665           TRUE,  TRUE,  TRUE},
3666          /* status: loading */
3667          {TRUE,  FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
3668           FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,  TRUE,
3669           FALSE, FALSE, FALSE},
3670          /* status: loading on BG */
3671          {TRUE,  FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
3672           FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,  TRUE,
3673           FALSE, FALSE, TRUE},
3674          /* status: checking duplicate images */
3675          {TRUE,  FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
3676           FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,
3677           FALSE, FALSE, TRUE},
3678          /* status: take all sensitive */
3679          {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
3680           FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
3681           FALSE, FALSE, FALSE},
3682       };
3683    GtkWidget *widget[SET_SENSITIVE_WIDGETS_NUM], *menu;
3684    GList *list, *node;
3685    guint i, num, summary_mode_menu_num;
3686 
3687    num = sizeof (gimv_thumb_win_status) / sizeof (gimv_thumb_win_status[0]);
3688    if (status > num - 1 || status < 0)
3689       status = 0;
3690 
3691    widget[0] = tw->menubar;
3692    widget[1] = tw->menuitem.file;
3693    widget[2] = tw->menuitem.edit;
3694    widget[3] = tw->view_menu;
3695    widget[4] = tw->menuitem.sort_name;
3696    widget[5] = tw->menuitem.sort_access;
3697    widget[6] = tw->menuitem.sort_time;
3698    widget[7] = tw->menuitem.sort_change;
3699    widget[8] = tw->menuitem.sort_size;
3700    widget[9] = tw->menuitem.sort_type;
3701 
3702    widget[10] = tw->menuitem.sort_width;
3703    widget[11] = tw->menuitem.sort_height;
3704    widget[12] = tw->menuitem.sort_area;
3705    widget[13] = tw->menuitem.sort_rev;
3706    widget[14] = tw->menuitem.sort_case;
3707    widget[15] = tw->menuitem.sort_dir;
3708    widget[16] = tw->button.fileopen;
3709    widget[17] = tw->button.refresh;
3710    widget[18] = tw->button.skip;
3711    widget[19] = tw->button.stop;
3712 
3713    widget[20] = tw->button.prefs;
3714    widget[21] = tw->button.quit;
3715 
3716    summary_mode_menu_num = 22;
3717    widget[summary_mode_menu_num] = tw->summary_mode_menu;
3718 
3719    for (i = 0; i < SET_SENSITIVE_WIDGETS_NUM; i++) {
3720       gtk_widget_set_sensitive (widget[i], gimv_thumb_win_status[status][i]);
3721    }
3722 
3723    /* set sensitivity of option menu items */
3724    menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (tw->summary_mode_menu));
3725    if (!menu) return;
3726 
3727    list = gtk_container_children (GTK_CONTAINER (menu));
3728    if (!list) return;
3729 
3730    for (node = list; node; node = g_list_next (node)) {
3731       GtkWidget *item = node->data;
3732       if (!item) continue;
3733       gtk_widget_set_sensitive (item, gimv_thumb_win_status[status][summary_mode_menu_num]);
3734    }
3735 
3736    tw->status = status;
3737 }
3738 
3739 #undef SET_SENSITIVE_WIDGETS_NUM
3740 
3741 
3742 void
gimv_thumb_win_set_tab_label_text(GtkWidget * page_container,const gchar * title)3743 gimv_thumb_win_set_tab_label_text (GtkWidget *page_container,
3744                                    const gchar *title)
3745 {
3746    GtkWidget *tablabel, *button;
3747 
3748    tablabel = gtk_object_get_data (GTK_OBJECT (page_container), "tab-label");
3749 
3750    if (tablabel) {
3751       button =   gtk_object_get_data (GTK_OBJECT (tablabel), "close-button");
3752       gtk_label_set_text (GTK_LABEL (tablabel), title);
3753 
3754       if (conf.thumbwin_show_tab_close) {
3755          gtk_widget_show (button);
3756       } else {
3757          gtk_widget_hide (button);
3758       }
3759    }
3760 
3761    gtk_notebook_set_menu_label_text (GTK_NOTEBOOK (page_container->parent),
3762                                      page_container, title);
3763 }
3764 
3765 
3766 void
gimv_thumb_win_set_tab_label_state(GtkWidget * page_container,GtkStateType state)3767 gimv_thumb_win_set_tab_label_state (GtkWidget *page_container,
3768                                     GtkStateType state)
3769 {
3770    GtkWidget *tablabel;
3771 
3772    tablabel = gtk_object_get_data (GTK_OBJECT (page_container), "tab-label");
3773 
3774    if (tablabel) {
3775       gtk_widget_set_state (tablabel, state);
3776    }
3777 }
3778 
3779 
3780 static void
cb_pagecontainer_button_press(GtkWidget * widget,GdkEventButton * event,GimvThumbWin * tw)3781 cb_pagecontainer_button_press (GtkWidget *widget,
3782                                GdkEventButton *event,
3783                                GimvThumbWin *tw)
3784 {
3785    g_return_if_fail (tw);
3786 
3787    gimv_thumb_win_notebook_drag_src_unset (tw);   /* FIXMEEEEEEEE!! */
3788 }
3789 
3790 
3791 static void
cb_pagecontainer_thumb_button_release(GtkWidget * widget,GdkEventButton * event,GimvThumbWin * tw)3792 cb_pagecontainer_thumb_button_release (GtkWidget *widget,
3793                                        GdkEventButton *event,
3794                                        GimvThumbWin *tw)
3795 {
3796    g_return_if_fail (tw);
3797 
3798    gimv_thumb_win_notebook_drag_src_reset (tw);   /* FIXMEEEEEEEEE!!! */
3799 }
3800 
3801 
3802 static GtkWidget *
gimv_thumb_win_create_tab_container(GimvThumbWin * tw)3803 gimv_thumb_win_create_tab_container (GimvThumbWin *tw)
3804 {
3805    GtkWidget *hbox, *pixmap, *button;
3806    GtkWidget *tablabel;
3807    GtkWidget *scrolled_window;
3808    GtkScrolledWindow *scrollwin;
3809    gint pagenum;
3810    gchar buf[BUF_SIZE];
3811 
3812    /* page container */
3813    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
3814    scrollwin = GTK_SCROLLED_WINDOW (scrolled_window);
3815    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolled_window),
3816                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3817    gtk_widget_show (scrolled_window);
3818    gtk_signal_connect_after (GTK_OBJECT(scrolled_window), "button_press_event",
3819                              GTK_SIGNAL_FUNC(cb_pagecontainer_button_press), tw);
3820    gtk_signal_connect_after (GTK_OBJECT(scrolled_window), "button_release_event",
3821                              GTK_SIGNAL_FUNC(cb_pagecontainer_thumb_button_release), tw);
3822    gtk_signal_connect_after (GTK_OBJECT(scrollwin->hscrollbar), "button_press_event",
3823                              GTK_SIGNAL_FUNC(cb_pagecontainer_button_press), tw);
3824    gtk_signal_connect_after (GTK_OBJECT(scrollwin->hscrollbar), "button_release_event",
3825                              GTK_SIGNAL_FUNC(cb_pagecontainer_thumb_button_release), tw);
3826    gtk_signal_connect_after (GTK_OBJECT(scrollwin->vscrollbar), "button_press_event",
3827                              GTK_SIGNAL_FUNC(cb_pagecontainer_button_press), tw);
3828    gtk_signal_connect_after (GTK_OBJECT(scrollwin->vscrollbar), "button_release_event",
3829                              GTK_SIGNAL_FUNC(cb_pagecontainer_thumb_button_release), tw);
3830 
3831    /* page label widget */
3832    hbox = gtk_hbox_new (FALSE, 0);
3833    gtk_object_set_data (GTK_OBJECT (hbox), "page-container", scrolled_window);
3834 
3835    tablabel = gtk_label_new (_("New Tab"));
3836    gtk_widget_set_name (tablabel, "TabLabel");
3837    gtk_misc_set_alignment (GTK_MISC (tablabel), 0.00, 0.5);
3838    gtk_misc_set_padding (GTK_MISC (tablabel), 4, 0);
3839    gtk_box_pack_start(GTK_BOX(hbox), tablabel, TRUE, TRUE, 0);
3840 
3841    button = gtk_button_new();
3842    gtk_container_set_border_width (GTK_CONTAINER (button), 1);
3843    gtk_widget_set_usize (button, 16, 16);
3844    gtk_button_set_relief((GtkButton *) button, GTK_RELIEF_NONE);
3845    pixmap = gimv_icon_stock_get_widget ("small_close");
3846    gtk_object_set_data (GTK_OBJECT (button), "page-container", scrolled_window);
3847    gtk_object_set_data (GTK_OBJECT (tablabel), "close-button", button);
3848    gtk_signal_connect (GTK_OBJECT (button), "clicked",
3849                        GTK_SIGNAL_FUNC (cb_tab_close_button_clicked), tw);
3850 
3851    gtk_container_add(GTK_CONTAINER(button), pixmap);
3852    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3853 
3854    gtk_widget_show_all (hbox);
3855 
3856    if (conf.thumbwin_show_tab_close) {
3857       gtk_widget_show (button);
3858    } else {
3859       gtk_widget_hide (button);
3860    }
3861 
3862    dnd_dest_set (hbox, dnd_types_all, dnd_types_all_num);
3863    gtk_object_set_data (GTK_OBJECT (hbox),
3864                         "gimv-component",
3865                         GINT_TO_POINTER (GIMV_COM_THUMB_VIEW));
3866    gtk_signal_connect (GTK_OBJECT (hbox), "drag_data_received",
3867                        GTK_SIGNAL_FUNC (cb_tab_drag_data_received), tw);
3868 
3869    /* create page */
3870    gtk_notebook_append_page (GTK_NOTEBOOK(tw->notebook), scrolled_window, hbox);
3871    gtk_object_set_data (GTK_OBJECT (scrolled_window), "tab-label", tablabel);
3872 
3873    tw->pagenum++;
3874 
3875    /* set label text */
3876    pagenum = gtk_notebook_page_num (GTK_NOTEBOOK (tw->notebook), scrolled_window);
3877    g_snprintf (buf, BUF_SIZE, _("NewTab %d"), tw->newpage_count++);
3878    gtk_label_set_text (GTK_LABEL (tablabel), buf);
3879    gtk_notebook_set_menu_label_text (GTK_NOTEBOOK (tw->notebook),
3880                                      scrolled_window, buf);
3881 
3882    /* switch to this page */
3883    if (conf.thumbwin_move_to_newtab || tw->pagenum == 1)
3884       gtk_notebook_set_page (GTK_NOTEBOOK(tw->notebook), pagenum);
3885 
3886    return scrolled_window;
3887 }
3888 
3889 
3890 GimvThumbView *
gimv_thumb_win_create_new_tab(GimvThumbWin * tw)3891 gimv_thumb_win_create_new_tab (GimvThumbWin *tw)
3892 {
3893    GtkWidget *scrolled_window;
3894    GimvThumbView *tv;
3895    FilesLoader *files;
3896 
3897    scrolled_window = gimv_thumb_win_create_tab_container (tw);
3898 
3899    /* create new collection */
3900    files = files_loader_new ();
3901    tv = gimv_thumb_view_new ();
3902    gimv_thumb_view_set_widget (tv, tw, scrolled_window,
3903                                tw->thumbview_summary_mode);
3904    gimv_thumb_win_set_statusbar_page_info (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
3905    files_loader_delete (files);
3906 
3907    return tv;
3908 }
3909 
3910 
3911 GtkWidget *
gimv_thumb_win_detach_tab(GimvThumbWin * tw_dest,GimvThumbWin * tw_src,GimvThumbView * tv)3912 gimv_thumb_win_detach_tab (GimvThumbWin *tw_dest, GimvThumbWin *tw_src,
3913                            GimvThumbView *tv)
3914 {
3915    GtkWidget *newtab;
3916    const gchar *path;
3917 
3918    g_return_val_if_fail (tw_dest && tw_src && tv, FALSE);
3919    g_return_val_if_fail (tw_dest != tw_src, FALSE);
3920    g_return_val_if_fail (tw_src == tv->tw, FALSE);
3921 
3922    newtab = gimv_thumb_win_create_tab_container (tw_dest);
3923    gimv_thumb_win_set_tab_label_text (newtab, tv->tabtitle);
3924 
3925    /* move the table to new window */
3926    gimv_thumb_view_set_widget (tv, tw_dest, newtab, tv->summary_mode);
3927 
3928    /* reset widget */
3929    gtk_spin_button_set_value (GTK_SPIN_BUTTON (tw_dest->button.size_spin),
3930                               tv->thumb_size);
3931    gtk_option_menu_set_history (GTK_OPTION_MENU (tw_dest->summary_mode_menu),
3932                                 gimv_thumb_view_label_to_num (tv->summary_mode));
3933 
3934    /* update struct data */
3935    tw_src->filenum -= tv->filenum;
3936    tw_src->filesize -= tv->filesize;
3937    tw_dest->filenum += tv->filenum;
3938    tw_dest->filesize += tv->filesize;
3939 
3940    gimv_thumb_win_close_tab (tw_src, GIMV_THUMB_WIN_CURRENT_PAGE);
3941 
3942    gimv_thumb_win_set_statusbar_page_info (tw_dest, GIMV_THUMB_WIN_CURRENT_PAGE);
3943 
3944    /* change current directory of dirview */
3945    path = gimv_thumb_view_get_path (tv);
3946    if (tv && tw_dest->show_dirview && path)
3947    {
3948       if (isdir(path)) {
3949          dirview_change_dir (tw_dest->dv, path);
3950       } else if (isfile(path)) {
3951          gchar *dirname = g_dirname (path);
3952          dirview_change_dir (tw_dest->dv, dirname);
3953          g_free(dirname);
3954       }
3955    }
3956 
3957    return newtab;
3958 }
3959 
3960 
3961 void
gimv_thumb_win_close_tab(GimvThumbWin * tw,gint page)3962 gimv_thumb_win_close_tab (GimvThumbWin *tw, gint page)
3963 {
3964    gint page_tmp;
3965    GimvThumbView *tv;
3966 
3967    tv = gimv_thumb_win_find_thumbtable (tw, page);
3968 
3969    if (tv && tv->progress) return;
3970    if (tv && (tv->status == GIMV_THUMB_VIEW_STATUS_LOADING)) return;
3971    if (tv && (tv->status == GIMV_THUMB_VIEW_STATUS_CHECK_DUPLICATE)) return;
3972 
3973    if (tv)
3974       gtk_object_unref (GTK_OBJECT (tv));
3975 
3976    if (page == GIMV_THUMB_WIN_CURRENT_PAGE)
3977       page_tmp = gtk_notebook_get_current_page (GTK_NOTEBOOK(tw->notebook));
3978    else
3979       page_tmp = page;
3980 
3981    gtk_notebook_remove_page (GTK_NOTEBOOK(tw->notebook), page_tmp);
3982 
3983    if (tw->pagenum > 0)
3984       tw->pagenum--;
3985 
3986    gimv_thumb_win_set_statusbar_page_info (tw, page);
3987 }
3988 
3989 
3990 void
gimv_thumb_win_reload_thumbnail(GimvThumbWin * tw,ThumbLoadType type)3991 gimv_thumb_win_reload_thumbnail (GimvThumbWin *tw, ThumbLoadType type)
3992 {
3993    GimvThumbView *tv;
3994    gchar *path = NULL;
3995 
3996    tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
3997    if (!tv) return;
3998 
3999    path = g_strdup (gimv_thumb_view_get_path (tv));
4000 
4001    if (tv->mode == GIMV_THUMB_VIEW_MODE_DIR) {
4002       open_dir_images (path, tw, tv, type, conf.scan_dir_recursive);
4003 
4004    } else if (tv->mode == GIMV_THUMB_VIEW_MODE_ARCHIVE) {
4005       open_archive_images (path, tw, tv, type);
4006 
4007    } else if (tv->mode == GIMV_THUMB_VIEW_MODE_COLLECTION) {
4008       FilesLoader *files = files_loader_new ();
4009       GList *node;
4010 
4011       for (node = tv->thumblist; node; node = g_list_next (node)) {
4012          GimvThumb  *thumb;
4013          gchar *filename;
4014 
4015          thumb = GIMV_THUMB (node->data);
4016          filename = g_strdup (gimv_image_info_get_path (thumb->info));
4017          files->filelist = g_list_append (files->filelist, filename);
4018       }
4019       files->status = END;
4020       files->thumb_load_type = type;
4021 
4022       open_image_files_in_thumbnail_view (files, tw, tv);
4023       files_loader_delete (files);
4024    }
4025 
4026    g_free (path);
4027 }
4028 
4029 void
gimv_thumb_win_open_dirview(GimvThumbWin * tw)4030 gimv_thumb_win_open_dirview (GimvThumbWin *tw)
4031 {
4032    g_return_if_fail (tw);
4033 
4034    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(tw->menuitem.dirview),
4035                                    TRUE);
4036 }
4037 
4038 
4039 void
gimv_thumb_win_close_dirview(GimvThumbWin * tw)4040 gimv_thumb_win_close_dirview (GimvThumbWin *tw)
4041 {
4042    g_return_if_fail (tw);
4043 
4044    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(tw->menuitem.dirview),
4045                                    FALSE);
4046 }
4047 
4048 
4049 void
gimv_thumb_win_open_preview(GimvThumbWin * tw)4050 gimv_thumb_win_open_preview (GimvThumbWin *tw)
4051 {
4052    g_return_if_fail (tw);
4053 
4054    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(tw->menuitem.preview),
4055                                    TRUE);
4056 }
4057 
4058 
4059 void
gimv_thumb_win_close_preview(GimvThumbWin * tw)4060 gimv_thumb_win_close_preview (GimvThumbWin *tw)
4061 {
4062    g_return_if_fail (tw);
4063 
4064    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(tw->menuitem.preview),
4065                                    FALSE);
4066 }
4067 
4068 
4069 static void
location_entry_set_text(GimvThumbWin * tw,GimvThumbView * tv,const gchar * location)4070 location_entry_set_text (GimvThumbWin  *tw,
4071                          GimvThumbView *tv,
4072                          const gchar   *location)
4073 {
4074    gchar *text;
4075    gchar *internal_str;
4076 
4077    g_return_if_fail (tw);
4078 
4079    if (!location) {
4080       if (tv) {
4081          const gchar *path = gimv_thumb_view_get_path (tv);
4082          if (path && isdir (path))
4083             text = g_strdup (path);
4084          else if (path && isfile (path))
4085             text = g_dirname (path);
4086          else
4087             text = g_strdup (g_getenv ("HOME"));
4088       } else {
4089          text = g_strdup (g_getenv ("HOME"));
4090       }
4091    } else {
4092       text = g_strdup (location);
4093    }
4094 
4095    internal_str = charset_to_internal (text,
4096                                        conf.charset_filename,
4097                                        conf.charset_auto_detect_fn,
4098                                        conf.charset_filename_mode);
4099 
4100    gtk_entry_set_text (GTK_ENTRY (tw->location_entry), internal_str);
4101 
4102    g_free (internal_str);
4103 
4104 #ifdef USE_GTK2
4105    gtk_editable_set_position (GTK_EDITABLE (tw->location_entry), -1);
4106 #endif /* USE_GTK2 */
4107 
4108    g_free (text);
4109 }
4110 
4111 
4112 void
gimv_thumb_win_location_entry_set_text(GimvThumbWin * tw,const gchar * location)4113 gimv_thumb_win_location_entry_set_text (GimvThumbWin *tw, const gchar *location)
4114 {
4115    GimvThumbView *tv;
4116 
4117    g_return_if_fail (tw);
4118 
4119    if (!location) {
4120       tv = gimv_thumb_win_find_thumbtable (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
4121    } else {
4122       tv = NULL;
4123    }
4124 
4125    location_entry_set_text (tw, tv, location);
4126 }
4127 
4128 
4129 GimvSortItem
gimv_thumb_win_get_sort_type(GimvThumbWin * tw,GimvSortFlag * flags_ret)4130 gimv_thumb_win_get_sort_type (GimvThumbWin *tw, GimvSortFlag *flags_ret)
4131 {
4132    g_return_val_if_fail (tw, GIMV_SORT_NONE);
4133    if (flags_ret)
4134       *flags_ret = tw->sortflags;
4135    return tw->sortitem;
4136 }
4137 
4138 
4139 void
gimv_thumb_win_sort_thumbnail(GimvThumbWin * tw,GimvSortItem item,GimvSortFlag flags,gint page)4140 gimv_thumb_win_sort_thumbnail (GimvThumbWin *tw,
4141                                GimvSortItem item, GimvSortFlag flags,
4142                                gint page)
4143 {
4144    GtkWidget *sort_item = NULL;
4145    GtkCheckMenuItem *toggle;
4146    gboolean bool1, bool2;
4147 
4148    g_return_if_fail (tw);
4149 
4150    switch (item) {
4151    case GIMV_SORT_NAME:
4152       sort_item = tw->menuitem.sort_name;
4153       break;
4154    case GIMV_SORT_ATIME:
4155       sort_item = tw->menuitem.sort_access;
4156       break;
4157    case GIMV_SORT_MTIME:
4158       sort_item = tw->menuitem.sort_time;
4159       break;
4160    case GIMV_SORT_CTIME:
4161       sort_item = tw->menuitem.sort_change;
4162       break;
4163    case GIMV_SORT_SIZE:
4164       sort_item = tw->menuitem.sort_size;
4165       break;
4166    case GIMV_SORT_WIDTH:
4167       sort_item = tw->menuitem.sort_width;
4168       break;
4169    case GIMV_SORT_HEIGHT:
4170       sort_item = tw->menuitem.sort_height;
4171       break;
4172    case GIMV_SORT_AREA:
4173       sort_item = tw->menuitem.sort_area;
4174       break;
4175    case GIMV_SORT_TYPE:
4176       sort_item = tw->menuitem.sort_type;
4177       break;
4178    default:
4179       return;
4180    }
4181 
4182    if (!sort_item) return;
4183 
4184    if (!GTK_CHECK_MENU_ITEM(sort_item)->active)
4185       gtk_check_menu_item_set_active
4186          (GTK_CHECK_MENU_ITEM(sort_item), TRUE);
4187 
4188    toggle = GTK_CHECK_MENU_ITEM(tw->menuitem.sort_rev);
4189    bool1 = flags & GIMV_SORT_REVERSE;
4190    bool2 = tw->sortflags & GIMV_SORT_REVERSE;
4191    if (bool1 != bool2)
4192       gtk_check_menu_item_set_active (toggle, flags & GIMV_SORT_REVERSE);
4193 
4194    toggle = GTK_CHECK_MENU_ITEM(tw->menuitem.sort_case);
4195    bool1 = flags & GIMV_SORT_CASE_INSENSITIVE;
4196    bool2 = tw->sortflags & GIMV_SORT_CASE_INSENSITIVE;
4197    if (bool1 != bool2)
4198       gtk_check_menu_item_set_active (toggle, flags & GIMV_SORT_REVERSE);
4199 
4200    toggle = GTK_CHECK_MENU_ITEM(tw->menuitem.sort_dir);
4201    bool1 = flags & GIMV_SORT_DIR_INSENSITIVE;
4202    bool2 = tw->sortflags & GIMV_SORT_DIR_INSENSITIVE;
4203    if (bool1 != bool2)
4204       gtk_check_menu_item_set_active (toggle, flags & GIMV_SORT_REVERSE);
4205 }
4206 
4207 
4208 void
gimv_thumb_win_change_layout(GimvThumbWin * tw,gint layout)4209 gimv_thumb_win_change_layout (GimvThumbWin *tw, gint layout)
4210 {
4211    GimvThumbView *tv;
4212    GimvImageInfo *info = NULL;
4213    GtkWidget *tab, *new_main_contents;
4214    GList *pages_list = NULL, *node;
4215    gint i, pagenum, current_page;
4216    gfloat progress;
4217 
4218    if (tw->layout_type > -1 && tw->layout_type == layout) return;
4219 
4220    if (tw->changing_layout) return;
4221    tw->changing_layout = TRUE;
4222 
4223    gimv_thumb_win_set_sensitive (tw, GIMV_THUMB_WIN_STATUS_NO_SENSITIVE);
4224 
4225    if (tw->iv->info)
4226       info = gimv_image_info_ref (tw->iv->info);
4227 
4228    if (layout >= compose_type_num)
4229       tw->layout_type = 0;
4230    else
4231       tw->layout_type = layout;
4232 
4233    /* get pages list in this window */
4234    for (i = 0; i < tw->pagenum; i++) {
4235       tv = gimv_thumb_win_find_thumbtable (tw, i);
4236       pages_list = g_list_append (pages_list, tv);
4237    }
4238 
4239    current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK(tw->notebook));
4240    pagenum = tw->pagenum;
4241 
4242    /* create new main contents */
4243    if (tw->iv) {
4244       tw->iv = NULL;
4245       tw->preview = NULL;
4246    }
4247    if (tw->dv) {
4248       tw->dv = NULL;
4249       tw->dirview = NULL;
4250    }
4251    new_main_contents = thumbnail_window_contents_new (tw);
4252 
4253    /* move pages */
4254    if (pages_list) {
4255       node = g_list_first (pages_list);
4256 
4257       for (i = 0; i < pagenum; i++) {
4258          tv = node->data;
4259          tab = gimv_thumb_win_create_tab_container (tw);
4260          if (tv && tab) {
4261             /* move to new tab */
4262             gimv_thumb_view_set_widget (tv, tv->tw, tab, tv->summary_mode);
4263             gimv_thumb_win_set_tab_label_text (tv->container, tv->tabtitle);
4264          }
4265          node = g_list_next (node);
4266          if (pagenum > 4) {
4267             progress = (gfloat) i / (gfloat) pagenum;
4268             gtk_progress_bar_update (GTK_PROGRESS_BAR(tw->progressbar),
4269                                      progress);
4270             while (gtk_events_pending()) gtk_main_iteration();
4271          }
4272       }
4273       gtk_progress_bar_update (GTK_PROGRESS_BAR(tw->progressbar), 0.0);
4274    }
4275 
4276    gtk_widget_destroy (tw->main_contents);
4277 
4278    /* attach new main contents */
4279    gtk_container_add (GTK_CONTAINER (tw->main_vbox), new_main_contents);
4280    sync_widget_state_to_menu (tw);  /* reset widget state */
4281    gtk_widget_show (new_main_contents);
4282    tw->main_contents = new_main_contents;
4283    tw->pagenum = pagenum;
4284 
4285    gtk_notebook_set_page (GTK_NOTEBOOK (tw->notebook), current_page);
4286    gimv_thumb_win_set_statusbar_page_info (tw, GIMV_THUMB_WIN_CURRENT_PAGE);
4287 
4288    tv = gimv_thumb_win_find_thumbtable (tw, current_page);
4289    if (tv) {
4290       tw->thumbview_summary_mode = tv->summary_mode;
4291       gtk_option_menu_set_history (GTK_OPTION_MENU (tw->summary_mode_menu),
4292                                    gimv_thumb_view_label_to_num (tw->thumbview_summary_mode));
4293    }
4294 
4295    /* reset preview image */
4296    if (tw->show_preview && info)
4297       gimv_image_view_change_image (tw->iv, info);
4298 
4299    if (info) {
4300       gimv_image_info_unref (info);
4301       info = NULL;
4302    }
4303 
4304    while (gtk_events_pending()) gtk_main_iteration();
4305 
4306    if (!GIMV_IS_THUMB_WIN (tw)) return;
4307 
4308    if (GIMV_IS_THUMB_VIEW (tv)) {
4309       const gchar *path = gimv_thumb_view_get_path (tv);
4310 
4311       /* adjust dirview */
4312       if (tw->show_dirview && path) {
4313          if (path && isdir (path)) {
4314             dirview_change_dir (tw->dv, path);
4315          } else if (path && isfile (path)) {
4316             gchar *dirname = g_dirname (path);
4317             dirview_change_dir (tw->dv, dirname);
4318             g_free (dirname);
4319          }
4320       }
4321    }
4322 
4323    gimv_thumb_win_set_sensitive (tw, GIMV_THUMB_WIN_STATUS_NORMAL);
4324 
4325 #ifdef USE_GTK2   /* FIXME */
4326    if (tw->accel_group_list)
4327       g_slist_free (tw->accel_group_list);
4328    tw->accel_group_list
4329       = g_slist_copy (gtk_accel_groups_from_object (G_OBJECT (tw)));
4330    tw->accel_group_list = g_slist_reverse (tw->accel_group_list);
4331 #endif /* USE_GTK2 */
4332 
4333    tw->changing_layout = FALSE;
4334 }
4335 
4336 
4337 void
gimv_thumb_win_swap_component(GimvThumbWin * tw,GimvComponentType com1,GimvComponentType com2)4338 gimv_thumb_win_swap_component (GimvThumbWin *tw,
4339                                GimvComponentType com1,
4340                                GimvComponentType com2)
4341 {
4342    GimvThumbwinComposeType compose;
4343    GtkCheckMenuItem *menuitem;
4344    gboolean active;
4345    gint tmp = 0, *p1 = NULL, *p2 = NULL, i;
4346 
4347    g_return_if_fail (tw);
4348    g_return_if_fail (com1 > 0 && com1 < 4);
4349    g_return_if_fail (com2 > 0 && com2 < 4);
4350 
4351    if (com1 == com2) return;
4352 
4353    gimv_thumb_win_get_layout (&compose, tw->layout_type);
4354 
4355    for (i = 0; i < 3; i++) {
4356       if (compose.widget_type[i] == com1) {
4357          tmp = compose.widget_type[i];
4358          p1 = &conf.thumbwin_widget[i];
4359       } else if (compose.widget_type[i] == com2) {
4360          p2 = &conf.thumbwin_widget[i];
4361       }
4362    }
4363 
4364    g_return_if_fail (p1 && p2 && p1 != p2);
4365 
4366    conf.thumbwin_pane1_horizontal = compose.pane1_horizontal;
4367    conf.thumbwin_pane2_horizontal = compose.pane2_horizontal;
4368    conf.thumbwin_pane2_attach_1 = compose.pane2_attach_to_child1;
4369    for (i = 0; i < 3; i++)
4370       conf.thumbwin_widget[i] = compose.widget_type[i];
4371 
4372    *p1 = *p2;
4373    *p2 = tmp;
4374 
4375    menuitem = GTK_CHECK_MENU_ITEM(tw->menuitem.layout[5]);
4376    active = menuitem->active;
4377    gtk_check_menu_item_set_active (menuitem, TRUE);
4378    if (active)
4379       gtk_signal_emit_by_name (GTK_OBJECT (menuitem), "activate");
4380 }
4381 
4382 
4383 void
gimv_thumb_win_save_state(GimvThumbWin * tw)4384 gimv_thumb_win_save_state (GimvThumbWin *tw)
4385 {
4386    g_return_if_fail (GIMV_IS_THUMB_WIN (tw));
4387 
4388    if (!tw->fullscreen) {
4389       conf.thumbwin_width  = GTK_WIDGET (tw)->allocation.width;
4390       conf.thumbwin_height = GTK_WIDGET (tw)->allocation.height;
4391    } else {
4392       conf.thumbwin_width  = tw->win_width;
4393       conf.thumbwin_height = tw->win_height;
4394    }
4395 
4396    if (tw->show_preview)
4397       conf.thumbwin_pane_size2
4398          = gimv_paned_get_position (GIMV_PANED (tw->pane2));
4399    if (tw->show_dirview)
4400       conf.thumbwin_pane_size1
4401          = gimv_paned_get_position (GIMV_PANED (tw->pane1));
4402 
4403    conf.thumbwin_show_preview  = tw->show_preview;
4404    conf.thumbwin_show_dir_view = tw->show_dirview;
4405 
4406    conf.thumbwin_show_menubar
4407       = GTK_CHECK_MENU_ITEM (tw->menuitem.menubar)->active;
4408    conf.thumbwin_show_toolbar
4409       = GTK_CHECK_MENU_ITEM (tw->menuitem.toolbar)->active;
4410    conf.thumbwin_show_statusbar
4411       = GTK_CHECK_MENU_ITEM (tw->menuitem.statusbar)->active;
4412    conf.thumbwin_show_tab
4413       = GTK_CHECK_MENU_ITEM (tw->menuitem.tab)->active;
4414    conf.thumbwin_show_preview_tab
4415       = GTK_CHECK_MENU_ITEM (tw->menuitem.preview_tab)->active;
4416 
4417    gtk_object_get (GTK_OBJECT (tw->iv),
4418                    "show_scrollbar",   &conf.preview_scrollbar,
4419                    "continuance_play", &conf.imgview_movie_continuance,
4420                    NULL);
4421    conf.preview_player_visible = tw->player_visible;
4422 
4423    conf.thumbwin_layout_type = tw->layout_type;
4424    conf.thumbwin_tab_pos = tw->tab_pos;
4425 
4426    conf.thumbwin_thumb_size =
4427       gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(tw->button.size_spin));
4428 
4429    conf.thumbwin_sort_type        = tw->sortitem;
4430    conf.thumbwin_sort_reverse     = tw->sortflags & GIMV_SORT_REVERSE;
4431    conf.thumbwin_sort_ignore_case = tw->sortflags & GIMV_SORT_CASE_INSENSITIVE;
4432    conf.thumbwin_sort_ignore_dir  = tw->sortflags & GIMV_SORT_DIR_INSENSITIVE;
4433 
4434    if (!gimv_prefs_win_is_opened ())
4435       g_free (conf.thumbwin_disp_mode);
4436    conf.thumbwin_disp_mode = g_strdup (tw->thumbview_summary_mode);
4437 }
4438 
4439 
4440 /* FIXMEEEEEEEEEEE!!! (TOT */
4441 void
gimv_thumb_win_notebook_drag_src_unset(GimvThumbWin * tw)4442 gimv_thumb_win_notebook_drag_src_unset (GimvThumbWin *tw)
4443 {
4444    g_return_if_fail (tw);
4445 
4446    gtk_drag_source_unset (tw->notebook);
4447 }
4448 
4449 
4450 void
gimv_thumb_win_notebook_drag_src_reset(GimvThumbWin * tw)4451 gimv_thumb_win_notebook_drag_src_reset (GimvThumbWin *tw)
4452 {
4453    g_return_if_fail (tw);
4454 
4455    dnd_src_set  (tw->notebook,
4456                  dnd_types_tab_component,
4457                  dnd_types_tab_component_num);
4458 }
4459 /* END FIXMEEEEEEEEEEE!!! (TOT */
4460