Mercurial > geeqie
comparison src/main.c @ 9:d907d608745f
Sync to GQview 1.5.9 release.
########
DO NOT BASE ENHANCEMENTS OR TRANSLATION UPDATES ON CODE IN THIS CVS!
This CVS is never up to date with current development and is provided
solely for reference purposes, please use the latest official release
package when making any changes or translation updates.
########
author | gqview |
---|---|
date | Sat, 26 Feb 2005 00:13:35 +0000 |
parents | c0e337a01cb7 |
children | 6d50eaba8e4b |
comparison
equal
deleted
inserted
replaced
8:e0d0593d519e | 9:d907d608745f |
---|---|
1 /* | 1 /* |
2 * GQview image viewer | 2 * GQview |
3 * (C)2000 John Ellis | 3 * (C) 2004 John Ellis |
4 * | 4 * |
5 * Author: John Ellis | 5 * Author: John Ellis |
6 * | 6 * |
7 * This software is released under the GNU General Public License (GNU GPL). | |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
7 */ | 10 */ |
8 | 11 |
12 | |
9 #include "gqview.h" | 13 #include "gqview.h" |
14 | |
15 #include "cache.h" | |
16 #include "collect.h" | |
17 #include "collect-io.h" | |
18 #include "dnd.h" | |
19 #include "editors.h" | |
20 #include "filelist.h" | |
21 #include "img-view.h" | |
22 #include "layout.h" | |
23 #include "layout_image.h" | |
24 #include "menu.h" | |
25 #include "preferences.h" | |
26 #include "rcfile.h" | |
27 #include "remote.h" | |
28 #include "similar.h" | |
29 #include "slideshow.h" | |
30 #include "utilops.h" | |
31 #include "ui_bookmark.h" | |
32 #include "ui_help.h" | |
33 #include "ui_fileops.h" | |
34 #include "ui_tabcomp.h" | |
35 #include "ui_utildlg.h" | |
36 | |
10 #include <gdk/gdkkeysyms.h> /* for keyboard values */ | 37 #include <gdk/gdkkeysyms.h> /* for keyboard values */ |
11 | 38 |
12 static void parse_command_line(int argc, char *argv[], gchar **path, gchar **file); | 39 #include "icons/icon.xpm" |
13 static void setup_default_options(); | 40 |
41 | |
42 #include <math.h> | |
43 | |
44 | |
45 static RemoteConnection *gqview_remote = NULL; | |
46 static CollectionData *gqview_command_collection = NULL; | |
47 | |
14 | 48 |
15 /* | 49 /* |
16 *----------------------------------------------------------------------------- | 50 *----------------------------------------------------------------------------- |
17 * path manipulation routines (public) | 51 * misc (public) |
18 *----------------------------------------------------------------------------- | 52 *----------------------------------------------------------------------------- |
19 */ | 53 */ |
20 | 54 |
21 gchar *filename_from_path(char *t) | 55 typedef struct _WindowIconData WindowIconData; |
22 { | 56 struct _WindowIconData |
23 char *p; | 57 { |
24 | 58 const char **icon; |
25 p = t + strlen(t); | 59 gchar *path; |
26 while(p > t && p[0] != '/') p--; | 60 }; |
27 if (p[0] == '/') p++; | 61 |
28 return p; | 62 static void window_set_icon_cb(GtkWidget *widget, gpointer data) |
29 } | 63 { |
30 | 64 WindowIconData *wid = data; |
31 gchar *remove_level_from_path(gchar *path) | 65 GdkPixbuf *pb; |
32 { | 66 GdkPixmap *pixmap; |
33 gchar *new_path; | 67 GdkBitmap *mask; |
34 gchar *ptr = path; | 68 |
35 gint p; | 69 if (wid->icon) |
36 | 70 { |
37 if (!path) return NULL; | 71 pb = gdk_pixbuf_new_from_xpm_data(wid->icon); |
38 | 72 } |
39 p = strlen(path) - 1; | 73 else |
40 if (p < 0) return NULL; | 74 { |
41 while(ptr[p] != '/' && p > 0) p--; | 75 pb = gdk_pixbuf_new_from_file(wid->path, NULL); |
42 if (p == 0 && ptr[p] == '/') p++; | 76 } |
43 new_path = g_strndup(path, (guint)p); | 77 |
44 return new_path; | 78 g_free(wid->path); |
45 } | 79 g_free(wid); |
46 | 80 |
47 void parse_out_relatives(gchar *path) | 81 if (!pb) return; |
48 { | 82 |
49 gint s, t; | 83 gdk_pixbuf_render_pixmap_and_mask(pb, &pixmap, &mask, 128); |
50 | 84 gdk_pixbuf_unref(pb); |
51 if (!path) return; | 85 |
52 | 86 gdk_window_set_icon(widget->window, NULL, pixmap, mask); |
53 s = t = 0; | 87 /* apparently, gdk_window_set_icon does not ref the pixmap and mask, so don't unref it (leak?) */ |
54 | 88 } |
55 while (path[s] != '\0') | 89 |
56 { | 90 void window_set_icon(GtkWidget *window, const char **icon, const gchar *file) |
57 if (path[s] == '/' && path[s+1] == '.' && (path[s+2] == '/' || path[s+2] == '\0') ) | 91 { |
58 { | 92 WindowIconData *wid; |
59 s += 2; | 93 |
60 } | 94 if (!icon && !file) icon = (const char **)icon_xpm; |
61 else if (path[s] == '/' && path[s+1] == '.' && path[s+2] == '.' && (path[s+3] == '/' || path[s+3] == '\0') ) | 95 |
62 { | 96 wid = g_new0(WindowIconData, 1); |
63 s += 3; | 97 wid->icon = icon; |
64 if (t > 0) t--; | 98 wid->path = g_strdup(file); |
65 while (path[t] != '/' && t > 0) t--; | 99 |
66 } | 100 g_signal_connect(G_OBJECT(window), "realize", |
67 else | 101 G_CALLBACK(window_set_icon_cb), wid); |
68 { | 102 } |
69 if (s != t) path[t] = path[s]; | 103 |
70 t++; | 104 gint window_maximized(GtkWidget *window) |
71 s++; | 105 { |
72 } | 106 GdkWindowState state; |
73 } | 107 |
74 if (t == 0 && path[t] == '/') t++; | 108 if (!window || !window->window) return FALSE; |
75 if (t > 1 && path[t-1] == '/') t--; | 109 |
76 path[t] = '\0'; | 110 state = gdk_window_get_state(window->window); |
111 return (state & GDK_WINDOW_STATE_MAXIMIZED); | |
112 } | |
113 | |
114 gdouble get_zoom_increment(void) | |
115 { | |
116 return ((zoom_increment != 0) ? (gdouble)zoom_increment / 10.0 : 1.0); | |
77 } | 117 } |
78 | 118 |
79 /* | 119 /* |
80 *----------------------------------------------------------------------------- | 120 *----------------------------------------------------------------------------- |
81 * external editor start routines (public) | 121 * Open browser with the help Documentation |
122 *----------------------------------------------------------------------------- | |
123 */ | |
124 | |
125 static gchar *command_result(const gchar *binary, const gchar *command) | |
126 { | |
127 gchar *result = NULL; | |
128 FILE *f; | |
129 char buf[2048]; | |
130 int l; | |
131 | |
132 if (!binary) return NULL; | |
133 if (!file_in_path(binary)) return NULL; | |
134 | |
135 if (!command) return g_strdup(binary); | |
136 if (command[0] == '!') return g_strdup(command + 1); | |
137 | |
138 f = popen(command, "r"); | |
139 if (!f) return NULL; | |
140 | |
141 while ((l = fread(buf, sizeof(char), sizeof(buf), f)) > 0) | |
142 { | |
143 if (!result) | |
144 { | |
145 int n = 0; | |
146 | |
147 while (n < l && buf[n] != '\n' && buf[n] != '\r') n++; | |
148 if (n > 0) result = g_strndup(buf, n); | |
149 } | |
150 } | |
151 | |
152 pclose(f); | |
153 | |
154 return result; | |
155 } | |
156 | |
157 static void help_browser_command(const gchar *command, const gchar *path) | |
158 { | |
159 gchar *result; | |
160 gchar *buf; | |
161 gchar *begin; | |
162 gchar *end; | |
163 | |
164 if (!command || !path) return; | |
165 | |
166 if (debug) printf("Help command pre \"%s\", \"%s\"\n", command, path); | |
167 | |
168 buf = g_strdup(command); | |
169 begin = strstr(buf, "%s"); | |
170 if (begin) | |
171 { | |
172 *begin = '\0'; | |
173 end = begin + 2; | |
174 begin = buf; | |
175 | |
176 result = g_strdup_printf("%s%s%s &", begin, path, end); | |
177 } | |
178 else | |
179 { | |
180 result = g_strdup_printf("%s \"%s\" &", command, path); | |
181 } | |
182 g_free(buf); | |
183 | |
184 if (debug) printf("Help command post [%s]\n", result); | |
185 | |
186 system(result); | |
187 | |
188 g_free(result); | |
189 } | |
190 | |
191 /* | |
192 * each set of 2 strings is one browser: | |
193 * the 1st is the binary to look for in the path | |
194 * the 2nd has 3 capabilities: | |
195 * NULL exec binary with html file path as command line | |
196 * string exec string and use results for command line | |
197 * !string use text following ! as command line, replacing optional %s with html file path | |
198 */ | |
199 static gchar *html_browsers[] = | |
200 { | |
201 /* Redhat has a nifty htmlview script to start the user's preferred browser */ | |
202 "htmlview", NULL, | |
203 /* GNOME 2 */ | |
204 "gconftool-2", "gconftool-2 -g /desktop/gnome/url-handlers/http/command", | |
205 /* KDE */ | |
206 "kfmclient", "!kfmclient exec \"%s\"", | |
207 /* use fallbacks */ | |
208 "firefox", NULL, | |
209 "mozilla", NULL, | |
210 "konqueror", NULL, | |
211 "netscape", NULL, | |
212 NULL, NULL | |
213 }; | |
214 | |
215 static void help_browser_run(void) | |
216 { | |
217 gchar *result = NULL; | |
218 gint i; | |
219 | |
220 i = 0; | |
221 while (!result && html_browsers[i]) | |
222 { | |
223 result = command_result(html_browsers[i], html_browsers[i+1]); | |
224 i += 2; | |
225 } | |
226 | |
227 if (!result) | |
228 { | |
229 printf("Unable to detect an installed browser.\n"); | |
230 return; | |
231 } | |
232 | |
233 help_browser_command(result, GQVIEW_HTMLDIR "/index.html"); | |
234 | |
235 g_free(result); | |
236 } | |
237 | |
238 /* | |
239 *----------------------------------------------------------------------------- | |
240 * help window | |
82 *----------------------------------------------------------------------------- | 241 *----------------------------------------------------------------------------- |
83 */ | 242 */ |
84 | 243 |
85 void start_editor_from_file(gint n, gchar *path) | 244 static GtkWidget *help_window = NULL; |
86 { | 245 |
87 gchar *cmd; | 246 static void help_window_destroy_cb(GtkWidget *window, gpointer data) |
88 if (!path) return; | 247 { |
89 cmd = g_strdup_printf("%s \"%s\" &", editor_command[n], path); | 248 help_window = NULL; |
90 printf(_("GQview running: %s\n"),cmd); | 249 } |
91 system(cmd); | 250 |
92 g_free(cmd); | 251 void help_window_show(const gchar *key) |
93 } | 252 { |
94 | 253 if (key && strcmp(key, "html_contents") == 0) |
95 void start_editor_from_image(gint n) | 254 { |
96 { | 255 help_browser_run(); |
97 start_editor_from_file(n, image_get_path()); | 256 return; |
98 } | 257 } |
99 | 258 |
100 void start_editor_from_list(gint n) | 259 if (help_window) |
101 { | 260 { |
102 gchar *cmd; | 261 gtk_window_present(GTK_WINDOW(help_window)); |
103 gchar *buf; | 262 if (key) help_window_set_key(help_window, key); |
104 GList *list = file_get_selected_list(); | 263 return; |
105 GList *work; | 264 } |
106 if (!list) return; | 265 |
107 work = list; | 266 help_window = help_window_new(_("Help - GQview"), "GQview", "help", |
108 cmd = g_strconcat(editor_command[n], " ", NULL); | 267 GQVIEW_HELPDIR "/README", key); |
109 while(work) | 268 g_signal_connect(G_OBJECT(help_window), "destroy", |
110 { | 269 G_CALLBACK(help_window_destroy_cb), NULL); |
111 buf = cmd; | 270 } |
112 cmd = g_strconcat(buf, "\"", work->data, "\" ", NULL); | 271 |
113 g_free(buf); | |
114 work = work->next; | |
115 } | |
116 buf = cmd; | |
117 cmd = g_strconcat(buf, "&", NULL); | |
118 g_free(buf); | |
119 printf(_("GQview running: %s\n"),cmd); | |
120 system(cmd); | |
121 g_free(cmd); | |
122 free_selected_list(list); | |
123 } | |
124 | 272 |
125 /* | 273 /* |
126 *----------------------------------------------------------------------------- | 274 *----------------------------------------------------------------------------- |
127 * keyboard functions | 275 * keyboard functions |
128 *----------------------------------------------------------------------------- | 276 *----------------------------------------------------------------------------- |
132 { | 280 { |
133 static gint delta = 0; | 281 static gint delta = 0; |
134 static guint32 time_old = 0; | 282 static guint32 time_old = 0; |
135 static guint keyval_old = 0; | 283 static guint keyval_old = 0; |
136 | 284 |
285 if (event->state & GDK_CONTROL_MASK) | |
286 { | |
287 if (*x < 0) *x = G_MININT / 2; | |
288 if (*x > 0) *x = G_MAXINT / 2; | |
289 if (*y < 0) *y = G_MININT / 2; | |
290 if (*y > 0) *y = G_MAXINT / 2; | |
291 | |
292 return; | |
293 } | |
294 | |
137 if (progressive_key_scrolling) | 295 if (progressive_key_scrolling) |
138 { | 296 { |
139 guint32 time_diff; | 297 guint32 time_diff; |
140 | 298 |
141 time_diff = event->time - time_old; | 299 time_diff = event->time - time_old; |
155 | 313 |
156 *x = *x * delta; | 314 *x = *x * delta; |
157 *y = *y * delta; | 315 *y = *y * delta; |
158 } | 316 } |
159 | 317 |
160 gint key_press_cb(GtkWidget *widget, GdkEventKey *event) | 318 |
161 { | 319 /* |
162 gint stop_signal = FALSE; | 320 *----------------------------------------------------------------------------- |
163 gint x = 0; | 321 * remote functions |
164 gint y = 0; | 322 *----------------------------------------------------------------------------- |
165 | 323 */ |
166 if (GTK_WIDGET_HAS_FOCUS(path_entry)) | 324 |
167 { | 325 static void gr_image_next(const gchar *text, gpointer data) |
168 if (event->keyval == GDK_Escape) | 326 { |
169 gtk_entry_set_text(GTK_ENTRY(path_entry), current_path); | 327 layout_image_next(NULL); |
170 return stop_signal; | 328 } |
171 } | 329 |
172 | 330 static void gr_image_prev(const gchar *text, gpointer data) |
173 if (full_screen_window || GTK_WIDGET_HAS_FOCUS(main_image->viewport)) | 331 { |
174 { | 332 layout_image_prev(NULL); |
175 switch (event->keyval) | 333 } |
176 { | 334 |
177 case GDK_Left: | 335 static void gr_image_first(const gchar *text, gpointer data) |
178 x -= 1; | 336 { |
179 stop_signal = TRUE; | 337 layout_image_first(NULL); |
180 break; | 338 } |
181 case GDK_Right: | 339 |
182 x += 1; | 340 static void gr_image_last(const gchar *text, gpointer data) |
183 stop_signal = TRUE; | 341 { |
184 break; | 342 layout_image_last(NULL); |
185 case GDK_Up: | 343 } |
186 y -= 1; | 344 |
187 stop_signal = TRUE; | 345 static void gr_fullscreen_toggle(const gchar *text, gpointer data) |
188 break; | 346 { |
189 case GDK_Down: | 347 layout_image_full_screen_toggle(NULL); |
190 y += 1; | 348 } |
191 stop_signal = TRUE; | 349 |
192 break; | 350 static void gr_fullscreen_start(const gchar *text, gpointer data) |
193 case GDK_BackSpace: | 351 { |
194 file_prev_image(); | 352 layout_image_full_screen_start(NULL); |
195 stop_signal = TRUE; | 353 } |
196 break; | 354 |
197 case GDK_space: | 355 static void gr_fullscreen_stop(const gchar *text, gpointer data) |
198 file_next_image(); | 356 { |
199 stop_signal = TRUE; | 357 layout_image_full_screen_stop(NULL); |
200 break; | 358 } |
201 } | 359 |
202 } | 360 static void gr_slideshow_start_rec(const gchar *text, gpointer data) |
203 | 361 { |
204 switch (event->keyval) | 362 GList *list; |
205 { | 363 |
206 case '+': | 364 list = path_list_recursive(text); |
207 image_adjust_zoom(1); | 365 if (!list) return; |
208 break; | 366 printf("length: %d\n", g_list_length(list)); |
209 case GDK_Page_Up: | 367 layout_image_slideshow_stop(NULL); |
210 file_prev_image(); | 368 layout_image_slideshow_start_from_list(NULL, list); |
211 stop_signal = TRUE; | 369 } |
212 break; | 370 |
213 case GDK_Page_Down: | 371 static void gr_slideshow_toggle(const gchar *text, gpointer data) |
214 file_next_image(); | 372 { |
215 stop_signal = TRUE; | 373 layout_image_slideshow_toggle(NULL); |
216 break; | 374 } |
217 case GDK_Home: | 375 |
218 file_first_image(); | 376 static void gr_slideshow_start(const gchar *text, gpointer data) |
219 stop_signal = TRUE; | 377 { |
220 break; | 378 layout_image_slideshow_start(NULL); |
221 case GDK_End: | 379 } |
222 file_last_image(); | 380 |
223 stop_signal = TRUE; | 381 static void gr_slideshow_stop(const gchar *text, gpointer data) |
224 break; | 382 { |
225 case GDK_Delete: | 383 layout_image_slideshow_stop(NULL); |
226 file_util_delete(image_get_path(), NULL); | 384 } |
227 stop_signal = TRUE; | 385 |
228 break; | 386 static void gr_slideshow_delay(const gchar *text, gpointer data) |
229 case GDK_Escape: | 387 { |
230 interrupt_thumbs(); | 388 gdouble n; |
231 stop_signal = TRUE; | 389 |
232 break; | 390 n = strtod(text, NULL); |
233 case 'Q': case 'q': | 391 if (n < SLIDESHOW_MIN_SECONDS || n > SLIDESHOW_MAX_SECONDS) |
234 if (event->state == 0 || (event->state & GDK_MODIFIER_MASK) == GDK_LOCK_MASK) | 392 { |
235 { | 393 gchar *buf; |
236 exit_gqview(); | 394 |
237 return FALSE; | 395 buf = g_strdup_printf("Remote slideshow delay out of range (%.1f to %.1f)\n", |
238 } | 396 SLIDESHOW_MIN_SECONDS, SLIDESHOW_MAX_SECONDS); |
239 break; | 397 print_term(buf); |
240 } | 398 g_free(buf); |
241 | 399 |
242 if (event->state & GDK_SHIFT_MASK) | 400 return; |
243 { | 401 } |
244 x *= 3; | 402 slideshow_delay = (gint)(n * 10.0 + 0.01); |
245 y *= 3; | 403 } |
246 } | 404 |
247 | 405 static void gr_tools_show(const gchar *text, gpointer data) |
248 if (x != 0 || y!= 0) | 406 { |
249 { | 407 gint popped; |
250 keyboard_scroll_calc(&x, &y, event); | 408 gint hidden; |
251 image_scroll(x, y); | 409 |
252 } | 410 if (layout_tools_float_get(NULL, &popped, &hidden) && hidden) |
253 | 411 { |
254 if (stop_signal) gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event"); | 412 layout_tools_float_set(NULL, popped, FALSE); |
255 | 413 } |
256 return stop_signal; | 414 } |
415 | |
416 static void gr_tools_hide(const gchar *text, gpointer data) | |
417 { | |
418 gint popped; | |
419 gint hidden; | |
420 | |
421 if (layout_tools_float_get(NULL, &popped, &hidden) && !hidden) | |
422 { | |
423 layout_tools_float_set(NULL, popped, TRUE); | |
424 } | |
425 } | |
426 | |
427 static gint gr_quit_idle_cb(gpointer data) | |
428 { | |
429 exit_gqview(); | |
430 | |
431 return FALSE; | |
432 } | |
433 | |
434 static void gr_quit(const gchar *text, gpointer data) | |
435 { | |
436 /* schedule exit when idle, if done from within a | |
437 * remote handler remote_close will crash | |
438 */ | |
439 g_idle_add(gr_quit_idle_cb, NULL); | |
440 } | |
441 | |
442 static void gr_file_load(const gchar *text, gpointer data) | |
443 { | |
444 if (isfile(text)) | |
445 { | |
446 if (file_extension_match(text, ".gqv")) | |
447 { | |
448 collection_window_new(text); | |
449 } | |
450 else | |
451 { | |
452 layout_set_path(NULL, text); | |
453 } | |
454 } | |
455 else if (isdir(text)) | |
456 { | |
457 layout_set_path(NULL, text); | |
458 } | |
459 else | |
460 { | |
461 printf("remote sent filename that does not exist:\"%s\"\n", text); | |
462 } | |
463 } | |
464 | |
465 static void gr_file_view(const gchar *text, gpointer data) | |
466 { | |
467 view_window_new(text); | |
468 } | |
469 | |
470 static void gr_list_clear(const gchar *text, gpointer data) | |
471 { | |
472 if (gqview_command_collection) collection_unref(gqview_command_collection); | |
473 gqview_command_collection = NULL; | |
474 } | |
475 | |
476 static void gr_list_add(const gchar *text, gpointer data) | |
477 { | |
478 gint new = TRUE; | |
479 | |
480 if (!gqview_command_collection) | |
481 { | |
482 CollectionData *cd; | |
483 | |
484 cd = collection_new(""); | |
485 | |
486 g_free(cd->path); | |
487 cd->path = NULL; | |
488 g_free(cd->name); | |
489 cd->name = g_strdup(_("Command line")); | |
490 | |
491 gqview_command_collection = cd; | |
492 } | |
493 else | |
494 { | |
495 new = (!collection_get_first(gqview_command_collection)); | |
496 } | |
497 | |
498 if (collection_add(gqview_command_collection, text, FALSE) && new) | |
499 { | |
500 layout_image_set_collection(NULL, gqview_command_collection, | |
501 collection_get_first(gqview_command_collection)); | |
502 } | |
503 } | |
504 | |
505 static void gr_raise(const gchar *text, gpointer data) | |
506 { | |
507 LayoutWindow *lw = NULL; | |
508 | |
509 if (layout_valid(&lw)) | |
510 { | |
511 gtk_window_present(GTK_WINDOW(lw->window)); | |
512 } | |
513 } | |
514 | |
515 typedef struct _RemoteCommandEntry RemoteCommandEntry; | |
516 struct _RemoteCommandEntry { | |
517 gchar *opt_s; | |
518 gchar *opt_l; | |
519 void (*func)(const gchar *text, gpointer data); | |
520 gint needs_extra; | |
521 gint prefer_command_line; | |
522 gchar *description; | |
523 }; | |
524 | |
525 static RemoteCommandEntry remote_commands[] = { | |
526 /* short, long callback, extra, prefer,description */ | |
527 { "-n", "--next", gr_image_next, FALSE, FALSE, N_("next image") }, | |
528 { "-b", "--back", gr_image_prev, FALSE, FALSE, N_("previous image") }, | |
529 { NULL, "--first", gr_image_first, FALSE, FALSE, N_("first image") }, | |
530 { NULL, "--last", gr_image_last, FALSE, FALSE, N_("last image") }, | |
531 { "-f", "--fullscreen", gr_fullscreen_toggle, FALSE, TRUE, N_("toggle full screen") }, | |
532 { "-fs","--fullscreen-start", gr_fullscreen_start, FALSE, FALSE, N_("start full screen") }, | |
533 { "-fS","--fullscreen-stop", gr_fullscreen_stop, FALSE, FALSE, N_("stop full screen") }, | |
534 { "-s", "--slideshow", gr_slideshow_toggle, FALSE, TRUE, N_("toggle slide show") }, | |
535 { "-ss","--slideshow-start", gr_slideshow_start, FALSE, FALSE, N_("start slide show") }, | |
536 { "-sS","--slideshow-stop", gr_slideshow_stop, FALSE, FALSE, N_("stop slide show") }, | |
537 { "-sr","--slideshow-recurse", gr_slideshow_start_rec, TRUE, FALSE, N_("start recursive slide show") }, | |
538 { "-d", "--delay=", gr_slideshow_delay, TRUE, FALSE, N_("set slide show delay in seconds") }, | |
539 { "+t", "--tools-show", gr_tools_show, FALSE, TRUE, N_("show tools") }, | |
540 { "-t", "--tools-hide", gr_tools_hide, FALSE, TRUE, N_("hide tools") }, | |
541 { "-q", "--quit", gr_quit, FALSE, FALSE, N_("quit") }, | |
542 { NULL, "file:", gr_file_load, TRUE, FALSE, N_("open file") }, | |
543 { NULL, "view:", gr_file_view, TRUE, FALSE, N_("open file in new window") }, | |
544 { NULL, "--list-clear", gr_list_clear, FALSE, FALSE, NULL }, | |
545 { NULL, "--list-add:", gr_list_add, TRUE, FALSE, NULL }, | |
546 { NULL, "raise", gr_raise, FALSE, FALSE, NULL }, | |
547 { NULL, NULL, NULL, FALSE, FALSE, NULL } | |
548 }; | |
549 | |
550 static RemoteCommandEntry *gqview_remote_command_find(const gchar *text, const gchar **offset) | |
551 { | |
552 gint match = FALSE; | |
553 gint i; | |
554 | |
555 i = 0; | |
556 while (!match && remote_commands[i].func != NULL) | |
557 { | |
558 if (remote_commands[i].needs_extra) | |
559 { | |
560 if (remote_commands[i].opt_s && | |
561 strncmp(remote_commands[i].opt_s, text, strlen(remote_commands[i].opt_s)) == 0) | |
562 { | |
563 if (offset) *offset = text + strlen(remote_commands[i].opt_s); | |
564 return &remote_commands[i]; | |
565 } | |
566 else if (remote_commands[i].opt_l && | |
567 strncmp(remote_commands[i].opt_l, text, strlen(remote_commands[i].opt_l)) == 0) | |
568 { | |
569 if (offset) *offset = text + strlen(remote_commands[i].opt_l); | |
570 return &remote_commands[i]; | |
571 } | |
572 } | |
573 else | |
574 { | |
575 if ((remote_commands[i].opt_s && strcmp(remote_commands[i].opt_s, text) == 0) || | |
576 (remote_commands[i].opt_l && strcmp(remote_commands[i].opt_l, text) == 0)) | |
577 { | |
578 if (offset) *offset = text; | |
579 return &remote_commands[i]; | |
580 } | |
581 } | |
582 | |
583 i++; | |
584 } | |
585 | |
586 return NULL; | |
587 } | |
588 | |
589 static void gqview_remote_cb(RemoteConnection *rc, const gchar *text, gpointer data) | |
590 { | |
591 RemoteCommandEntry *entry; | |
592 const gchar *offset; | |
593 | |
594 entry = gqview_remote_command_find(text, &offset); | |
595 if (entry && entry->func) | |
596 { | |
597 entry->func(offset, data); | |
598 } | |
599 else | |
600 { | |
601 printf("unknown remote command:%s\n", text); | |
602 } | |
603 } | |
604 | |
605 static void gqview_remote_help(void) | |
606 { | |
607 gint i; | |
608 | |
609 print_term(_("Remote command list:\n")); | |
610 | |
611 i = 0; | |
612 while (remote_commands[i].func != NULL) | |
613 { | |
614 if (remote_commands[i].description) | |
615 { | |
616 gchar *buf; | |
617 | |
618 buf = g_strdup_printf(" %-3s%s %-20s %s\n", | |
619 (remote_commands[i].opt_s) ? remote_commands[i].opt_s : "", | |
620 (remote_commands[i].opt_s && remote_commands[i].opt_l) ? "," : " ", | |
621 (remote_commands[i].opt_l) ? remote_commands[i].opt_l : "", | |
622 _(remote_commands[i].description)); | |
623 | |
624 print_term(buf); | |
625 g_free(buf); | |
626 } | |
627 i++; | |
628 } | |
629 } | |
630 | |
631 static GList *gqview_remote_build_list(GList *list, int argc, char *argv[]) | |
632 { | |
633 gint i; | |
634 | |
635 i = 1; | |
636 while (i < argc) | |
637 { | |
638 RemoteCommandEntry *entry; | |
639 | |
640 entry = gqview_remote_command_find(argv[i], NULL); | |
641 if (entry) | |
642 { | |
643 list = g_list_append(list, argv[i]); | |
644 } | |
645 i++; | |
646 } | |
647 | |
648 return list; | |
649 } | |
650 | |
651 static void gqview_remote_control(const gchar *arg_exec, GList *remote_list, const gchar *path, | |
652 GList *cmd_list, GList *collection_list) | |
653 { | |
654 RemoteConnection *rc; | |
655 gint started = FALSE; | |
656 gchar *buf; | |
657 | |
658 buf = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/.command", NULL); | |
659 rc = remote_client_open(buf); | |
660 if (!rc) | |
661 { | |
662 GString *command; | |
663 GList *work; | |
664 gint retry_count = 12; | |
665 gint blank = FALSE; | |
666 | |
667 print_term(_("Remote GQview not running, starting...")); | |
668 command = g_string_new(arg_exec); | |
669 | |
670 work = remote_list; | |
671 while (work) | |
672 { | |
673 gchar *text; | |
674 RemoteCommandEntry *entry; | |
675 | |
676 text = work->data; | |
677 work = work->next; | |
678 | |
679 entry = gqview_remote_command_find(text, NULL); | |
680 if (entry) | |
681 { | |
682 if (entry->prefer_command_line) | |
683 { | |
684 remote_list = g_list_remove(remote_list, text); | |
685 g_string_append(command, " "); | |
686 g_string_append(command, text); | |
687 } | |
688 if (entry->opt_l && strcmp(entry->opt_l, "file:") == 0) | |
689 { | |
690 blank = TRUE; | |
691 } | |
692 } | |
693 } | |
694 | |
695 if (blank || cmd_list || path) g_string_append(command, " --blank"); | |
696 if (debug) g_string_append(command, " --debug"); | |
697 | |
698 g_string_append(command, " &"); | |
699 system(command->str); | |
700 g_string_free(command, TRUE); | |
701 | |
702 while (!rc && retry_count > 0) | |
703 { | |
704 usleep((retry_count > 10) ? 500000 : 1000000); | |
705 rc = remote_client_open(buf); | |
706 if (!rc) print_term("."); | |
707 retry_count--; | |
708 } | |
709 | |
710 print_term("\n"); | |
711 | |
712 started = TRUE; | |
713 } | |
714 g_free(buf); | |
715 | |
716 if (rc) | |
717 { | |
718 GList *work; | |
719 const gchar *prefix; | |
720 gint use_path = TRUE; | |
721 gint sent = FALSE; | |
722 | |
723 work = remote_list; | |
724 while (work) | |
725 { | |
726 gchar *text; | |
727 RemoteCommandEntry *entry; | |
728 | |
729 text = work->data; | |
730 work = work->next; | |
731 | |
732 entry = gqview_remote_command_find(text, NULL); | |
733 if (entry && | |
734 entry->opt_l && | |
735 strcmp(entry->opt_l, "file:") == 0) use_path = FALSE; | |
736 | |
737 remote_client_send(rc, text); | |
738 | |
739 sent = TRUE; | |
740 } | |
741 | |
742 if (cmd_list && cmd_list->next) | |
743 { | |
744 prefix = "--list-add:"; | |
745 remote_client_send(rc, "--list-clear"); | |
746 } | |
747 else | |
748 { | |
749 prefix = "file:"; | |
750 } | |
751 | |
752 work = cmd_list; | |
753 while (work) | |
754 { | |
755 const gchar *name; | |
756 gchar *text; | |
757 | |
758 name = work->data; | |
759 work = work->next; | |
760 | |
761 text = g_strconcat(prefix, name, NULL); | |
762 remote_client_send(rc, text); | |
763 g_free(text); | |
764 | |
765 sent = TRUE; | |
766 } | |
767 | |
768 if (path && !cmd_list && use_path) | |
769 { | |
770 gchar *text; | |
771 | |
772 text = g_strdup_printf("file:%s", path); | |
773 remote_client_send(rc, text); | |
774 g_free(text); | |
775 | |
776 sent = TRUE; | |
777 } | |
778 | |
779 work = collection_list; | |
780 while (work) | |
781 { | |
782 const gchar *name; | |
783 gchar *text; | |
784 | |
785 name = work->data; | |
786 work = work->next; | |
787 | |
788 text = g_strdup_printf("file:%s", name); | |
789 remote_client_send(rc, text); | |
790 g_free(text); | |
791 | |
792 sent = TRUE; | |
793 } | |
794 | |
795 if (!started && !sent) | |
796 { | |
797 remote_client_send(rc, "raise"); | |
798 } | |
799 } | |
800 else | |
801 { | |
802 print_term(_("Remote not available\n")); | |
803 } | |
804 | |
805 _exit(0); | |
257 } | 806 } |
258 | 807 |
259 /* | 808 /* |
260 *----------------------------------------------------------------------------- | 809 *----------------------------------------------------------------------------- |
261 * command line parser (private) hehe, who needs popt anyway? | 810 * command line parser (private) hehe, who needs popt anyway? |
262 *----------------------------------------------------------------------------- | 811 *----------------------------------------------------------------------------- |
263 */ | 812 */ |
264 | 813 |
814 static gint startup_blank = FALSE; | |
265 static gint startup_full_screen = FALSE; | 815 static gint startup_full_screen = FALSE; |
266 static gint startup_in_slideshow = FALSE; | 816 static gint startup_in_slideshow = FALSE; |
267 | 817 static gint startup_command_line_collection = FALSE; |
268 static void parse_command_line(int argc, char *argv[], gchar **path, gchar **file) | 818 |
269 { | 819 |
820 static void parse_command_line_add_file(const gchar *new_path, gchar **path, gchar **file, | |
821 GList **list, GList **collection_list) | |
822 { | |
823 gchar *path_parsed; | |
824 | |
825 path_parsed = g_strdup(new_path); | |
826 parse_out_relatives(path_parsed); | |
827 | |
828 if (file_extension_match(new_path, ".gqv")) | |
829 { | |
830 *collection_list = g_list_append(*collection_list, path_parsed); | |
831 } | |
832 else | |
833 { | |
834 if (!*path) *path = remove_level_from_path(path_parsed); | |
835 if (!*file) *file = g_strdup(path_parsed); | |
836 *list = g_list_append(*list, path_parsed); | |
837 } | |
838 } | |
839 | |
840 static void parse_command_line(int argc, char *argv[], gchar **path, gchar **file, | |
841 GList **cmd_list, GList **collection_list) | |
842 { | |
843 GList *list = NULL; | |
844 GList *remote_list = NULL; | |
845 gint remote_do = FALSE; | |
846 | |
270 if (argc > 1) | 847 if (argc > 1) |
271 { | 848 { |
272 gint i; | 849 gint i; |
273 gchar *base_dir = get_current_dir(); | 850 gchar *base_dir = get_current_dir(); |
274 i = 1; | 851 i = 1; |
275 while (i < argc) | 852 while (i < argc) |
276 { | 853 { |
277 gchar *cmd_line = argv[i]; | 854 const gchar *cmd_line = argv[i]; |
278 gchar *cmd_all = g_strconcat(base_dir, "/", cmd_line, NULL); | 855 gchar *cmd_all = concat_dir_and_file(base_dir, cmd_line); |
279 | 856 |
280 if (!*path && cmd_line[0] == '/' && isdir(cmd_line)) | 857 if (!*path && cmd_line[0] == '/' && isdir(cmd_line)) |
281 { | 858 { |
282 *path = g_strdup(cmd_line); | 859 *path = g_strdup(cmd_line); |
283 } | 860 } |
284 else if (!*path && isdir(cmd_all)) | 861 else if (!*path && isdir(cmd_all)) |
285 { | 862 { |
286 *path = g_strdup(cmd_all); | 863 *path = g_strdup(cmd_all); |
287 } | 864 } |
288 else if (!*file && cmd_line[0] == '/' && isfile(cmd_line)) | 865 else if (cmd_line[0] == '/' && isfile(cmd_line)) |
289 { | 866 { |
290 g_free(*path); | 867 parse_command_line_add_file(cmd_line, path, file, &list, collection_list); |
291 *path = remove_level_from_path(cmd_line); | 868 } |
292 *file = g_strdup(cmd_line); | 869 else if (isfile(cmd_all)) |
293 } | 870 { |
294 else if (!*file && isfile(cmd_all)) | 871 parse_command_line_add_file(cmd_all, path, file, &list, collection_list); |
295 { | |
296 g_free(*path); | |
297 *path = remove_level_from_path(cmd_all); | |
298 *file = g_strdup(cmd_all); | |
299 } | 872 } |
300 else if (strcmp(cmd_line, "--debug") == 0) | 873 else if (strcmp(cmd_line, "--debug") == 0) |
301 { | 874 { |
302 debug = TRUE; | 875 /* we now increment the debug state for verbosity */ |
303 printf("debugging output enabled\n"); | 876 debug++; |
877 printf("debugging output enabled (level %d)\n", debug); | |
304 } | 878 } |
305 else if (strcmp(cmd_line, "+t") == 0 || | 879 else if (strcmp(cmd_line, "+t") == 0 || |
306 strcmp(cmd_line, "--with-tools") == 0) | 880 strcmp(cmd_line, "--with-tools") == 0) |
307 { | 881 { |
308 tools_float = FALSE; | 882 tools_float = FALSE; |
309 tools_hidden = FALSE; | 883 tools_hidden = FALSE; |
884 | |
885 remote_list = g_list_append(remote_list, "+t"); | |
310 } | 886 } |
311 else if (strcmp(cmd_line, "-t") == 0 || | 887 else if (strcmp(cmd_line, "-t") == 0 || |
312 strcmp(cmd_line, "--without-tools") == 0) | 888 strcmp(cmd_line, "--without-tools") == 0) |
313 { | 889 { |
314 tools_hidden = TRUE; | 890 tools_hidden = TRUE; |
891 | |
892 remote_list = g_list_append(remote_list, "-t"); | |
315 } | 893 } |
316 else if (strcmp(cmd_line, "-f") == 0 || | 894 else if (strcmp(cmd_line, "-f") == 0 || |
317 strcmp(cmd_line, "--fullscreen") == 0) | 895 strcmp(cmd_line, "--fullscreen") == 0) |
318 { | 896 { |
319 startup_full_screen = TRUE; | 897 startup_full_screen = TRUE; |
321 else if (strcmp(cmd_line, "-s") == 0 || | 899 else if (strcmp(cmd_line, "-s") == 0 || |
322 strcmp(cmd_line, "--slideshow") == 0) | 900 strcmp(cmd_line, "--slideshow") == 0) |
323 { | 901 { |
324 startup_in_slideshow = TRUE; | 902 startup_in_slideshow = TRUE; |
325 } | 903 } |
904 else if (strcmp(cmd_line, "-l") == 0 || | |
905 strcmp(cmd_line, "--list") == 0) | |
906 { | |
907 startup_command_line_collection = TRUE; | |
908 } | |
909 else if (strcmp(cmd_line, "-r") == 0 || | |
910 strcmp(cmd_line, "--remote") == 0) | |
911 { | |
912 if (!remote_do) | |
913 { | |
914 remote_do = TRUE; | |
915 remote_list = gqview_remote_build_list(remote_list, argc, argv); | |
916 } | |
917 } | |
918 else if (strcmp(cmd_line, "-rh") == 0 || | |
919 strcmp(cmd_line, "--remote-help") == 0) | |
920 { | |
921 gqview_remote_help(); | |
922 exit (0); | |
923 } | |
924 else if (strcmp(cmd_line, "--blank") == 0) | |
925 { | |
926 startup_blank = TRUE; | |
927 } | |
928 else if (strcmp(cmd_line, "-v") == 0 || | |
929 strcmp(cmd_line, "--version") == 0) | |
930 { | |
931 printf("GQview %s\n", VERSION); | |
932 exit (0); | |
933 } | |
934 else if (strcmp(cmd_line, "--alternate") == 0) | |
935 { | |
936 /* enable faster experimental algorithm */ | |
937 printf("Alternate similarity algorithm enabled\n"); | |
938 image_sim_alternate_set(TRUE); | |
939 } | |
326 else if (strcmp(cmd_line, "-h") == 0 || | 940 else if (strcmp(cmd_line, "-h") == 0 || |
327 strcmp(cmd_line, "--help") == 0) | 941 strcmp(cmd_line, "--help") == 0) |
328 { | 942 { |
329 printf("GQview version %s\n", VERSION); | 943 printf("GQview %s\n", VERSION); |
330 printf(_("Usage: gqview [options] [path]\n\n")); | 944 print_term(_("Usage: gqview [options] [path]\n\n")); |
331 printf(_("valid options are:\n")); | 945 print_term(_("valid options are:\n")); |
332 printf(_(" +t, --with-tools force show of tools\n")); | 946 print_term(_(" +t, --with-tools force show of tools\n")); |
333 printf(_(" -t, --without-tools force hide of tools\n")); | 947 print_term(_(" -t, --without-tools force hide of tools\n")); |
334 printf(_(" -f, --fullscreen start in full screen mode\n")); | 948 print_term(_(" -f, --fullscreen start in full screen mode\n")); |
335 printf(_(" -s, --slideshow start in slideshow mode\n")); | 949 print_term(_(" -s, --slideshow start in slideshow mode\n")); |
336 printf(_(" --debug turn on debug output\n")); | 950 print_term(_(" -l, --list open collection window for command line\n")); |
337 printf(_(" -h, --help show this message\n\n")); | 951 print_term(_(" -r, --remote send following commands to open window\n")); |
952 print_term(_(" -rh,--remote-help print remote command list\n")); | |
953 print_term(_(" --debug turn on debug output\n")); | |
954 print_term(_(" -v, --version print version info\n")); | |
955 print_term(_(" -h, --help show this message\n\n")); | |
956 | |
957 #if 0 | |
958 /* these options are not officially supported! | |
959 * only for testing new features, no need to translate them */ | |
960 print_term( " --alternate use alternate similarity algorithm\n"); | |
961 #endif | |
962 | |
338 exit (0); | 963 exit (0); |
339 } | 964 } |
340 else | 965 else if (!remote_do) |
341 { | 966 { |
342 printf(_("invalid or ignored: %s\nUse -help for options\n"), cmd_line); | 967 gchar *buf; |
343 } | 968 |
969 buf = g_strdup_printf(_("invalid or ignored: %s\nUse --help for options\n"), cmd_line); | |
970 print_term(buf); | |
971 g_free(buf); | |
972 } | |
973 | |
344 g_free(cmd_all); | 974 g_free(cmd_all); |
345 i++; | 975 i++; |
346 } | 976 } |
347 g_free(base_dir); | 977 g_free(base_dir); |
348 parse_out_relatives(*path); | 978 parse_out_relatives(*path); |
349 parse_out_relatives(*file); | 979 parse_out_relatives(*file); |
980 } | |
981 | |
982 if (remote_do) | |
983 { | |
984 gqview_remote_control(argv[0], remote_list, *path, list, *collection_list); | |
985 } | |
986 g_list_free(remote_list); | |
987 | |
988 if (list && list->next) | |
989 { | |
990 *cmd_list = list; | |
991 } | |
992 else | |
993 { | |
994 path_list_free(list); | |
995 *cmd_list = NULL; | |
350 } | 996 } |
351 } | 997 } |
352 | 998 |
353 /* | 999 /* |
354 *----------------------------------------------------------------------------- | 1000 *----------------------------------------------------------------------------- |
355 * startup, init, and exit | 1001 * startup, init, and exit |
356 *----------------------------------------------------------------------------- | 1002 *----------------------------------------------------------------------------- |
357 */ | 1003 */ |
358 | 1004 |
359 static void setup_default_options() | 1005 #define RC_HISTORY_NAME "history" |
360 { | 1006 |
1007 static void keys_load(void) | |
1008 { | |
1009 gchar *path; | |
1010 | |
1011 path = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/", RC_HISTORY_NAME, NULL); | |
1012 history_list_load(path); | |
1013 g_free(path); | |
1014 } | |
1015 | |
1016 static void keys_save(void) | |
1017 { | |
1018 gchar *path; | |
1019 | |
1020 path = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/", RC_HISTORY_NAME, NULL); | |
1021 history_list_save(path); | |
1022 g_free(path); | |
1023 } | |
1024 | |
1025 static void check_for_home_path(gchar *path) | |
1026 { | |
1027 gchar *buf; | |
1028 | |
1029 buf = g_strconcat(homedir(), "/", path, NULL); | |
1030 if (!isdir(buf)) | |
1031 { | |
1032 gchar *tmp; | |
1033 | |
1034 tmp = g_strdup_printf(_("Creating GQview dir:%s\n"), buf); | |
1035 print_term(tmp); | |
1036 g_free(tmp); | |
1037 | |
1038 if (!mkdir_utf8(buf, 0755)) | |
1039 { | |
1040 tmp = g_strdup_printf(_("Could not create dir:%s\n"), buf); | |
1041 print_term(tmp); | |
1042 g_free(tmp); | |
1043 } | |
1044 } | |
1045 g_free(buf); | |
1046 } | |
1047 | |
1048 static void setup_default_options(void) | |
1049 { | |
1050 gchar *path; | |
361 gint i; | 1051 gint i; |
362 | 1052 |
363 for(i=0; i<8; i++) | 1053 for (i = 0; i < GQVIEW_EDITOR_SLOTS; i++) |
364 { | 1054 { |
365 editor_name[i] = NULL; | 1055 editor_name[i] = NULL; |
366 editor_command[i] = NULL; | 1056 editor_command[i] = NULL; |
367 } | 1057 } |
368 | 1058 |
369 editor_name[0] = g_strdup(_("The Gimp")); | 1059 editor_reset_defaults(); |
370 editor_command[0] = g_strdup("gimp"); | 1060 |
371 | 1061 bookmark_add_default(_("Home"), homedir()); |
372 editor_name[1] = g_strdup(_("Electric Eyes")); | 1062 path = concat_dir_and_file(homedir(), "Desktop"); |
373 editor_command[1] = g_strdup("ee"); | 1063 bookmark_add_default(_("Desktop"), path); |
374 | 1064 g_free(path); |
375 editor_name[2] = g_strdup(_("XV")); | 1065 path = concat_dir_and_file(homedir(), GQVIEW_RC_DIR_COLLECTIONS); |
376 editor_command[2] = g_strdup("xv"); | 1066 bookmark_add_default(_("Collections"), path); |
377 | 1067 g_free(path); |
378 editor_name[3] = g_strdup(_("Xpaint")); | 1068 |
379 editor_command[3] = g_strdup("xpaint"); | 1069 g_free(safe_delete_path); |
380 | 1070 safe_delete_path = concat_dir_and_file(homedir(), GQVIEW_RC_DIR_TRASH); |
381 custom_filter = g_strdup(".eim;"); | 1071 } |
382 } | 1072 |
383 | 1073 static void exit_gqview_final(void) |
384 void exit_gqview() | 1074 { |
385 { | 1075 gchar *path; |
386 full_screen_stop(); | 1076 gchar *pathl; |
387 | 1077 LayoutWindow *lw = NULL; |
388 gdk_window_get_position (mainwindow->window, &main_window_x, &main_window_y); | 1078 |
389 gdk_window_get_size(mainwindow->window, &main_window_w, &main_window_h); | 1079 remote_close(gqview_remote); |
390 | 1080 |
391 if (toolwindow) | 1081 collect_manager_flush(); |
392 { | 1082 |
393 gdk_window_get_position (toolwindow->window, &float_window_x, &float_window_y); | 1083 if (layout_valid(&lw)) |
394 gdk_window_get_size(toolwindow->window, &float_window_w, &float_window_h); | 1084 { |
395 } | 1085 main_window_maximized = window_maximized(lw->window); |
1086 if (!main_window_maximized) | |
1087 { | |
1088 layout_geometry_get(NULL, &main_window_x, &main_window_y, | |
1089 &main_window_w, &main_window_h); | |
1090 } | |
1091 } | |
1092 | |
1093 layout_geometry_get_dividers(NULL, &window_hdivider_pos, &window_vdivider_pos); | |
1094 | |
1095 layout_views_get(NULL, &layout_view_tree, &layout_view_icons); | |
1096 | |
1097 thumbnails_enabled = layout_thumb_get(NULL); | |
1098 layout_sort_get(NULL, &file_sort_method, &file_sort_ascending); | |
1099 | |
1100 layout_geometry_get_tools(NULL, &float_window_x, &float_window_y, | |
1101 &float_window_w, &float_window_h, &float_window_divider); | |
1102 layout_tools_float_get(NULL, &tools_float, &tools_hidden); | |
1103 toolbar_hidden = layout_toolbar_hidden(NULL); | |
1104 | |
396 save_options(); | 1105 save_options(); |
1106 keys_save(); | |
1107 | |
1108 path = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/accels", NULL); | |
1109 pathl = path_from_utf8(path); | |
1110 gtk_accel_map_save(pathl); | |
1111 g_free(pathl); | |
1112 g_free(path); | |
397 | 1113 |
398 gtk_main_quit(); | 1114 gtk_main_quit(); |
399 } | 1115 } |
400 | 1116 |
1117 static GenericDialog *exit_dialog = NULL; | |
1118 | |
1119 static void exit_confirm_cancel_cb(GenericDialog *gd, gpointer data) | |
1120 { | |
1121 exit_dialog = NULL; | |
1122 generic_dialog_close(gd); | |
1123 } | |
1124 | |
1125 static void exit_confirm_exit_cb(GenericDialog *gd, gpointer data) | |
1126 { | |
1127 exit_dialog = NULL; | |
1128 generic_dialog_close(gd); | |
1129 exit_gqview_final(); | |
1130 } | |
1131 | |
1132 static gint exit_confirm_dlg(void) | |
1133 { | |
1134 GtkWidget *parent; | |
1135 LayoutWindow *lw; | |
1136 | |
1137 if (exit_dialog) | |
1138 { | |
1139 gtk_window_present(GTK_WINDOW(exit_dialog->dialog)); | |
1140 return TRUE; | |
1141 } | |
1142 | |
1143 if (!collection_window_modified_exists()) return FALSE; | |
1144 | |
1145 parent = NULL; | |
1146 lw = NULL; | |
1147 if (layout_valid(&lw)) | |
1148 { | |
1149 parent = lw->window; | |
1150 } | |
1151 | |
1152 exit_dialog = generic_dialog_new(_("GQview - exit"), | |
1153 "GQview", "exit", parent, FALSE, | |
1154 exit_confirm_cancel_cb, NULL); | |
1155 generic_dialog_add_message(exit_dialog, GTK_STOCK_DIALOG_QUESTION, | |
1156 _("Quit GQview"), _("Collections have been modified. Quit anyway?")); | |
1157 generic_dialog_add_button(exit_dialog, GTK_STOCK_QUIT, NULL, exit_confirm_exit_cb, TRUE); | |
1158 | |
1159 gtk_widget_show(exit_dialog->dialog); | |
1160 | |
1161 return TRUE; | |
1162 } | |
1163 | |
1164 void exit_gqview(void) | |
1165 { | |
1166 layout_image_full_screen_stop(NULL); | |
1167 | |
1168 if (exit_confirm_dlg()) return; | |
1169 | |
1170 exit_gqview_final(); | |
1171 } | |
1172 | |
401 int main (int argc, char *argv[]) | 1173 int main (int argc, char *argv[]) |
402 { | 1174 { |
1175 LayoutWindow *lw; | |
1176 gchar *path = NULL; | |
403 gchar *cmd_path = NULL; | 1177 gchar *cmd_path = NULL; |
404 gchar *cmd_file = NULL; | 1178 gchar *cmd_file = NULL; |
1179 GList *cmd_list = NULL; | |
1180 GList *collection_list = NULL; | |
1181 CollectionData *first_collection = NULL; | |
1182 gchar *buf; | |
1183 gchar *bufl; | |
405 | 1184 |
406 /* setup locale, i18n */ | 1185 /* setup locale, i18n */ |
407 gtk_set_locale(); | 1186 gtk_set_locale(); |
408 bindtextdomain (PACKAGE, LOCALEDIR); | 1187 bindtextdomain (PACKAGE, LOCALEDIR); |
1188 bind_textdomain_codeset (PACKAGE, "UTF-8"); | |
409 textdomain (PACKAGE); | 1189 textdomain (PACKAGE); |
410 | 1190 |
411 /* setup random seed for random slideshow */ | 1191 /* setup random seed for random slideshow */ |
412 srand (time (0)); | 1192 srand(time(NULL)); |
413 | 1193 |
414 gtk_init (&argc, &argv); | 1194 #if 0 |
415 gdk_imlib_init(); | 1195 printf("GQview %s, This is a beta release.\n", VERSION); |
416 | 1196 #endif |
417 /* push the correct color depths to gtk, (for 8-bit psuedo color displays) | 1197 |
418 * they should be popped, too, I guess... | 1198 layout_order = g_strdup("123"); |
419 */ | |
420 gtk_widget_push_visual(gdk_imlib_get_visual()); | |
421 gtk_widget_push_colormap(gdk_imlib_get_colormap()); | |
422 | |
423 setup_default_options(); | 1199 setup_default_options(); |
424 load_options(); | 1200 load_options(); |
425 | 1201 |
426 parse_command_line(argc, argv, &cmd_path, &cmd_file); | 1202 parse_command_line(argc, argv, &cmd_path, &cmd_file, &cmd_list, &collection_list); |
427 | 1203 |
428 if (cmd_path) | 1204 gtk_init (&argc, &argv); |
429 current_path = g_strdup(cmd_path); | 1205 |
1206 if (gtk_major_version < GTK_MAJOR_VERSION || | |
1207 (gtk_major_version == GTK_MAJOR_VERSION && gtk_minor_version < GTK_MINOR_VERSION) ) | |
1208 { | |
1209 gchar *msg; | |
1210 print_term("!!! This is a friendly warning.\n"); | |
1211 print_term("!!! The version of GTK+ in use now is older than when GQview was compiled.\n"); | |
1212 msg = g_strdup_printf("!!! compiled with GTK+-%d.%d\n", GTK_MAJOR_VERSION, GTK_MINOR_VERSION); | |
1213 print_term(msg); | |
1214 g_free(msg); | |
1215 msg = g_strdup_printf("!!! running with GTK+-%d.%d\n", gtk_major_version, gtk_minor_version); | |
1216 print_term(msg); | |
1217 g_free(msg); | |
1218 print_term("!!! GQview may quit unexpectedly with a relocation error.\n"); | |
1219 } | |
1220 | |
1221 check_for_home_path(GQVIEW_RC_DIR); | |
1222 check_for_home_path(GQVIEW_RC_DIR_COLLECTIONS); | |
1223 check_for_home_path(GQVIEW_CACHE_RC_THUMB); | |
1224 check_for_home_path(GQVIEW_CACHE_RC_METADATA); | |
1225 | |
1226 keys_load(); | |
1227 filter_add_defaults(); | |
1228 filter_rebuild(); | |
1229 | |
1230 buf = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/accels", NULL); | |
1231 bufl = path_from_utf8(buf); | |
1232 gtk_accel_map_load(bufl); | |
1233 g_free(bufl); | |
1234 g_free(buf); | |
1235 | |
1236 if (startup_blank) | |
1237 { | |
1238 g_free(cmd_path); | |
1239 cmd_path = NULL; | |
1240 g_free(cmd_file); | |
1241 cmd_file = NULL; | |
1242 path_list_free(cmd_list); | |
1243 cmd_list = NULL; | |
1244 path_list_free(collection_list); | |
1245 collection_list = NULL; | |
1246 | |
1247 path = NULL; | |
1248 } | |
1249 else if (cmd_path) | |
1250 { | |
1251 path = g_strdup(cmd_path); | |
1252 } | |
430 else if (startup_path_enable && startup_path && isdir(startup_path)) | 1253 else if (startup_path_enable && startup_path && isdir(startup_path)) |
431 current_path = g_strdup(startup_path); | 1254 { |
1255 path = g_strdup(startup_path); | |
1256 } | |
432 else | 1257 else |
433 current_path = get_current_dir(); | 1258 { |
434 | 1259 path = get_current_dir(); |
435 create_main_window(); | 1260 } |
436 update_edit_menus(mainwindow_accel_grp); | 1261 |
437 rebuild_file_filter(); | 1262 lw = layout_new(NULL, tools_float, tools_hidden); |
438 filelist_refresh(); | 1263 layout_sort_set(lw, file_sort_method, file_sort_ascending); |
439 | 1264 |
440 init_dnd(); | 1265 if (collection_list && !startup_command_line_collection) |
441 | 1266 { |
442 while(gtk_events_pending()) gtk_main_iteration(); | 1267 GList *work; |
443 image_change_to(cmd_file); | 1268 |
1269 work = collection_list; | |
1270 while (work) | |
1271 { | |
1272 CollectWindow *cw; | |
1273 const gchar *path; | |
1274 | |
1275 path = work->data; | |
1276 work = work->next; | |
1277 | |
1278 cw = collection_window_new(path); | |
1279 if (!first_collection && cw) first_collection = cw->cd; | |
1280 } | |
1281 } | |
1282 | |
1283 if (cmd_list || | |
1284 (startup_command_line_collection && collection_list)) | |
1285 { | |
1286 CollectionData *cd; | |
1287 GList *work; | |
1288 | |
1289 if (startup_command_line_collection) | |
1290 { | |
1291 CollectWindow *cw; | |
1292 | |
1293 cw = collection_window_new(""); | |
1294 cd = cw->cd; | |
1295 } | |
1296 else | |
1297 { | |
1298 cd = collection_new(""); /* if we pass NULL, untitled counter is falsely increm. */ | |
1299 gqview_command_collection = cd; | |
1300 } | |
1301 | |
1302 g_free(cd->path); | |
1303 cd->path = NULL; | |
1304 g_free(cd->name); | |
1305 cd->name = g_strdup(_("Command line")); | |
1306 | |
1307 collection_path_changed(cd); | |
1308 | |
1309 work = cmd_list; | |
1310 while (work) | |
1311 { | |
1312 collection_add(cd, (gchar *)work->data, FALSE); | |
1313 work = work->next; | |
1314 } | |
1315 | |
1316 work = collection_list; | |
1317 while (work) | |
1318 { | |
1319 collection_load(cd, (gchar *)work->data, TRUE); | |
1320 work = work->next; | |
1321 } | |
1322 | |
1323 layout_set_path(lw, path); | |
1324 if (cd->list) layout_image_set_collection(lw, cd, cd->list->data); | |
1325 | |
1326 /* mem leak, we never unref this collection when !startup_command_line_collection | |
1327 * (the image view of the main window does not hold a ref to the collection) | |
1328 * this is sort of unavoidable, for if it did hold a ref, next/back | |
1329 * may not work as expected when closing collection windows. | |
1330 * | |
1331 * collection_unref(cd); | |
1332 */ | |
1333 | |
1334 } | |
1335 else if (cmd_file) | |
1336 { | |
1337 layout_set_path(lw, cmd_file); | |
1338 } | |
1339 else | |
1340 { | |
1341 layout_set_path(lw, path); | |
1342 if (first_collection) | |
1343 { | |
1344 layout_image_set_collection(lw, first_collection, | |
1345 collection_get_first(first_collection)); | |
1346 } | |
1347 } | |
444 | 1348 |
445 g_free(cmd_path); | 1349 g_free(cmd_path); |
446 g_free(cmd_file); | 1350 g_free(cmd_file); |
447 | 1351 path_list_free(cmd_list); |
448 if (startup_full_screen) full_screen_toggle(); | 1352 path_list_free(collection_list); |
449 if (startup_in_slideshow) slideshow_start(); | 1353 g_free(path); |
1354 | |
1355 if (startup_full_screen) layout_image_full_screen_start(lw); | |
1356 if (startup_in_slideshow) layout_image_slideshow_start(lw); | |
1357 | |
1358 buf = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/.command", NULL); | |
1359 gqview_remote = remote_server_open(buf); | |
1360 remote_server_subscribe(gqview_remote, gqview_remote_cb, NULL); | |
1361 g_free(buf); | |
450 | 1362 |
451 gtk_main (); | 1363 gtk_main (); |
452 return 0; | 1364 return 0; |
453 } | 1365 } |
454 | 1366 |
455 |