Mercurial > geeqie
annotate src/editors.c @ 1618:552648eff4f2
do not block the files sent to external editors like gimp
author | nadvornik |
---|---|
date | Sun, 31 May 2009 11:08:00 +0000 |
parents | c9c1a16ff8ae |
children | 58a5d1e01e33 |
rev | line source |
---|---|
9 | 1 /* |
196 | 2 * Geeqie |
123
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
3 * (C) 2006 John Ellis |
1284 | 4 * Copyright (C) 2008 - 2009 The Geeqie Team |
9 | 5 * |
6 * Author: John Ellis | |
7 * | |
8 * This software is released under the GNU General Public License (GNU GPL). | |
9 * Please read the included file COPYING for more information. | |
10 * This software comes with no warranty of any kind, use at your own risk! | |
11 */ | |
12 | |
13 | |
281 | 14 #include "main.h" |
9 | 15 #include "editors.h" |
16 | |
669 | 17 #include "filedata.h" |
18 #include "filefilter.h" | |
1022
9962b24b6b43
Move miscellaneous functions to their own files (new misc.[ch]).
zas_
parents:
1000
diff
changeset
|
19 #include "misc.h" |
9 | 20 #include "ui_fileops.h" |
21 #include "ui_spinner.h" | |
22 #include "ui_utildlg.h" | |
1022
9962b24b6b43
Move miscellaneous functions to their own files (new misc.[ch]).
zas_
parents:
1000
diff
changeset
|
23 #include "utilops.h" |
9 | 24 |
25 #include <errno.h> | |
26 | |
27 | |
28 #define EDITOR_WINDOW_WIDTH 500 | |
29 #define EDITOR_WINDOW_HEIGHT 300 | |
30 | |
31 | |
32 | |
33 typedef struct _EditorVerboseData EditorVerboseData; | |
34 struct _EditorVerboseData { | |
35 GenericDialog *gd; | |
36 GtkWidget *button_close; | |
37 GtkWidget *button_stop; | |
38 GtkWidget *text; | |
39 GtkWidget *progress; | |
40 GtkWidget *spinner; | |
140 | 41 }; |
42 | |
43 typedef struct _EditorData EditorData; | |
44 struct _EditorData { | |
1405 | 45 EditorFlags flags; |
140 | 46 GPid pid; |
47 GList *list; | |
9 | 48 gint count; |
49 gint total; | |
140 | 50 gboolean stopping; |
51 EditorVerboseData *vd; | |
52 EditorCallback callback; | |
53 gpointer data; | |
1272 | 54 const EditorDescription *editor; |
9 | 55 }; |
56 | |
57 | |
140 | 58 static void editor_verbose_window_progress(EditorData *ed, const gchar *text); |
1405 | 59 static EditorFlags editor_command_next_start(EditorData *ed); |
60 static EditorFlags editor_command_next_finish(EditorData *ed, gint status); | |
61 static EditorFlags editor_command_done(EditorData *ed); | |
9 | 62 |
63 /* | |
64 *----------------------------------------------------------------------------- | |
65 * external editor routines | |
66 *----------------------------------------------------------------------------- | |
67 */ | |
68 | |
1272 | 69 GHashTable *editors = NULL; |
1479 | 70 GtkListStore *desktop_file_list; |
71 | |
1272 | 72 |
73 #ifdef G_KEY_FILE_DESKTOP_GROUP | |
74 #define DESKTOP_GROUP G_KEY_FILE_DESKTOP_GROUP | |
75 #else | |
76 #define DESKTOP_GROUP "Desktop Entry" | |
77 #endif | |
78 | |
79 void editor_description_free(EditorDescription *editor) | |
768
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
80 { |
1272 | 81 if (!editor) return; |
82 | |
83 g_free(editor->key); | |
84 g_free(editor->name); | |
1278
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
85 g_free(editor->icon); |
1272 | 86 g_free(editor->exec); |
87 g_free(editor->menu_path); | |
88 g_free(editor->hotkey); | |
1468 | 89 g_free(editor->comment); |
1272 | 90 string_list_free(editor->ext_list); |
91 g_free(editor->file); | |
92 g_free(editor); | |
93 } | |
768
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
94 |
1272 | 95 static GList *editor_mime_types_to_extensions(gchar **mime_types) |
96 { | |
97 /* FIXME: this should be rewritten to use the shared mime database, as soon as we switch to gio */ | |
768
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
98 |
1272 | 99 static const gchar *conv_table[][2] = { |
1486 | 100 {"application/x-ufraw", ".ufraw"}, |
1272 | 101 {"image/*", "*"}, |
102 {"image/bmp", ".bmp"}, | |
103 {"image/gif", ".gif"}, | |
104 {"image/jpeg", ".jpeg;.jpg"}, | |
105 {"image/jpg", ".jpg;.jpeg"}, | |
106 {"image/pcx", ".pcx"}, | |
107 {"image/png", ".png"}, | |
108 {"image/svg", ".svg"}, | |
109 {"image/svg+xml", ".svg"}, | |
110 {"image/svg+xml-compressed", ".svg"}, | |
111 {"image/tiff", ".tiff;.tif"}, | |
112 {"image/x-bmp", ".bmp"}, | |
113 {"image/x-canon-crw", ".crw"}, | |
114 {"image/x-cr2", ".cr2"}, | |
115 {"image/x-dcraw", "%raw"}, | |
116 {"image/x-ico", ".ico"}, | |
117 {"image/x-mrw", ".mrw"}, | |
118 {"image/x-MS-bmp", ".bmp"}, | |
119 {"image/x-nef", ".nef"}, | |
120 {"image/x-orf", ".orf"}, | |
121 {"image/x-pcx", ".pcx"}, | |
122 {"image/xpm", ".xpm"}, | |
123 {"image/x-png", ".png"}, | |
124 {"image/x-portable-anymap", ".pam"}, | |
125 {"image/x-portable-bitmap", ".pbm"}, | |
126 {"image/x-portable-graymap", ".pgm"}, | |
127 {"image/x-portable-pixmap", ".ppm"}, | |
128 {"image/x-psd", ".psd"}, | |
129 {"image/x-raf", ".raf"}, | |
130 {"image/x-sgi", ".sgi"}, | |
131 {"image/x-tga", ".tga"}, | |
132 {"image/x-xbitmap", ".xbm"}, | |
133 {"image/x-xcf", ".xcf"}, | |
134 {"image/x-xpixmap", ".xpm"}, | |
135 {"image/x-x3f", ".x3f"}, | |
136 {NULL, NULL}}; | |
137 | |
138 gint i, j; | |
139 GList *list = NULL; | |
140 | |
141 for (i = 0; mime_types[i]; i++) | |
142 for (j = 0; conv_table[j][0]; j++) | |
143 if (strcmp(mime_types[i], conv_table[j][0]) == 0) | |
144 list = g_list_concat(list, filter_to_list(conv_table[j][1])); | |
145 | |
146 return list; | |
768
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
147 } |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
148 |
1272 | 149 static gboolean editor_read_desktop_file(const gchar *path) |
768
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
150 { |
1272 | 151 GKeyFile *key_file; |
152 EditorDescription *editor; | |
153 gchar *extensions; | |
1278
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
154 gchar *type; |
1272 | 155 const gchar *key = filename_from_path(path); |
156 gchar **categories, **only_show_in, **not_show_in; | |
1274 | 157 gchar *try_exec; |
1479 | 158 GtkTreeIter iter; |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
159 gboolean category_geeqie = FALSE; |
1272 | 160 |
161 if (g_hash_table_lookup(editors, key)) return FALSE; /* the file found earlier wins */ | |
162 | |
163 key_file = g_key_file_new(); | |
164 if (!g_key_file_load_from_file(key_file, path, 0, NULL)) | |
165 { | |
166 g_key_file_free(key_file); | |
167 return FALSE; | |
168 } | |
1278
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
169 |
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
170 type = g_key_file_get_string(key_file, DESKTOP_GROUP, "Type", NULL); |
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
171 if (!type || strcmp(type, "Application") != 0) |
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
172 { |
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
173 /* We only consider desktop entries of Application type */ |
1409 | 174 g_key_file_free(key_file); |
1463
25168240a247
added function to reload external editors at any time
nadvornik
parents:
1409
diff
changeset
|
175 g_free(type); |
1278
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
176 return FALSE; |
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
177 } |
1463
25168240a247
added function to reload external editors at any time
nadvornik
parents:
1409
diff
changeset
|
178 g_free(type); |
1272 | 179 |
1407
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
180 editor = g_new0(EditorDescription, 1); |
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
181 |
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
182 editor->key = g_strdup(key); |
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
183 editor->file = g_strdup(path); |
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
184 |
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
185 g_hash_table_insert(editors, editor->key, editor); |
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
186 |
1278
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
187 if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "Hidden", NULL) |
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
188 || g_key_file_get_boolean(key_file, DESKTOP_GROUP, "NoDisplay", NULL)) |
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
189 { |
1407
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
190 editor->hidden = TRUE; |
1278
c5852c543775
Add support for NoDisplay (entry is then hidden) and Type (only Application type is valid here) keys.
zas_
parents:
1276
diff
changeset
|
191 } |
1272 | 192 |
193 categories = g_key_file_get_string_list(key_file, DESKTOP_GROUP, "Categories", NULL, NULL); | |
194 if (categories) | |
195 { | |
196 gboolean found = FALSE; | |
197 gint i; | |
198 for (i = 0; categories[i]; i++) | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
199 { |
1272 | 200 /* IMHO "Graphics" is exactly the category that we are interested in, so this does not have to be configurable */ |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
201 if (strcmp(categories[i], "Graphics") == 0) |
1272 | 202 { |
203 found = TRUE; | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
204 } |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
205 if (strcmp(categories[i], "X-Geeqie") == 0) |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
206 { |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
207 found = TRUE; |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
208 category_geeqie = TRUE; |
1272 | 209 break; |
210 } | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
211 } |
1479 | 212 if (!found) editor->ignored = TRUE; |
1272 | 213 g_strfreev(categories); |
214 } | |
215 else | |
216 { | |
1479 | 217 editor->ignored = TRUE; |
1272 | 218 } |
219 | |
220 only_show_in = g_key_file_get_string_list(key_file, DESKTOP_GROUP, "OnlyShowIn", NULL, NULL); | |
221 if (only_show_in) | |
222 { | |
223 gboolean found = FALSE; | |
224 gint i; | |
225 for (i = 0; only_show_in[i]; i++) | |
226 if (strcmp(only_show_in[i], "X-Geeqie") == 0) | |
227 { | |
228 found = TRUE; | |
229 break; | |
230 } | |
1479 | 231 if (!found) editor->ignored = TRUE; |
1272 | 232 g_strfreev(only_show_in); |
233 } | |
768
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
234 |
1272 | 235 not_show_in = g_key_file_get_string_list(key_file, DESKTOP_GROUP, "NotShowIn", NULL, NULL); |
236 if (not_show_in) | |
237 { | |
238 gboolean found = FALSE; | |
239 gint i; | |
240 for (i = 0; not_show_in[i]; i++) | |
241 if (strcmp(not_show_in[i], "X-Geeqie") == 0) | |
242 { | |
243 found = TRUE; | |
244 break; | |
245 } | |
1479 | 246 if (found) editor->ignored = TRUE; |
1272 | 247 g_strfreev(not_show_in); |
248 } | |
249 | |
1407
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
250 |
1274 | 251 try_exec = g_key_file_get_string(key_file, DESKTOP_GROUP, "TryExec", NULL); |
1479 | 252 if (try_exec && !editor->hidden && !editor->ignored) |
1274 | 253 { |
254 gchar *try_exec_res = g_find_program_in_path(try_exec); | |
1407
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
255 if (!try_exec_res) editor->hidden = TRUE; |
1274 | 256 g_free(try_exec_res); |
257 g_free(try_exec); | |
258 } | |
1479 | 259 |
260 if (editor->ignored) | |
1272 | 261 { |
1479 | 262 /* ignored editors will be deleted, no need to parse the rest */ |
1272 | 263 g_key_file_free(key_file); |
1407
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
264 return TRUE; |
1272 | 265 } |
266 | |
267 editor->name = g_key_file_get_locale_string(key_file, DESKTOP_GROUP, "Name", NULL, NULL); | |
268 editor->icon = g_key_file_get_string(key_file, DESKTOP_GROUP, "Icon", NULL); | |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
269 |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
270 /* Icon key can be either a full path (absolute with file name extension) or an icon name (without extension) */ |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
271 if (editor->icon && !g_path_is_absolute(editor->icon)) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
272 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
273 gchar *ext = strrchr(editor->icon, '.'); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
274 |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
275 if (ext && strlen(ext) == 4 && |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
276 (!strcmp(ext, ".png") || !strcmp(ext, ".xpm") || !strcmp(ext, ".svg"))) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
277 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
278 log_printf(_("Desktop file '%s' should not include extension in Icon key: '%s'\n"), |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
279 editor->file, editor->icon); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
280 |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
281 // drop extension |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
282 *ext = '\0'; |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
283 } |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
284 } |
1272 | 285 |
286 editor->exec = g_key_file_get_string(key_file, DESKTOP_GROUP, "Exec", NULL); | |
287 | |
288 editor->menu_path = g_key_file_get_string(key_file, DESKTOP_GROUP, "X-Geeqie-Menu-Path", NULL); | |
289 if (!editor->menu_path) editor->menu_path = g_strdup("EditMenu/ExternalMenu"); | |
290 | |
291 editor->hotkey = g_key_file_get_string(key_file, DESKTOP_GROUP, "X-Geeqie-Hotkey", NULL); | |
292 | |
1468 | 293 editor->comment = g_key_file_get_string(key_file, DESKTOP_GROUP, "Comment", NULL); |
294 | |
1272 | 295 extensions = g_key_file_get_string(key_file, DESKTOP_GROUP, "X-Geeqie-File-Extensions", NULL); |
296 if (extensions) | |
297 editor->ext_list = filter_to_list(extensions); | |
298 else | |
299 { | |
300 gchar **mime_types = g_key_file_get_string_list(key_file, DESKTOP_GROUP, "MimeType", NULL, NULL); | |
301 if (mime_types) | |
302 { | |
303 editor->ext_list = editor_mime_types_to_extensions(mime_types); | |
304 g_strfreev(mime_types); | |
305 if (!editor->ext_list) editor->hidden = TRUE; | |
306 } | |
307 } | |
308 | |
309 if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "X-Geeqie-Keep-Fullscreen", NULL)) editor->flags |= EDITOR_KEEP_FS; | |
310 if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "X-Geeqie-Verbose", NULL)) editor->flags |= EDITOR_VERBOSE; | |
311 if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "X-Geeqie-Verbose-Multi", NULL)) editor->flags |= EDITOR_VERBOSE_MULTI; | |
312 if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "X-Geeqie-Filter", NULL)) editor->flags |= EDITOR_DEST; | |
313 if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "Terminal", NULL)) editor->flags |= EDITOR_TERMINAL; | |
314 | |
315 editor->flags |= editor_command_parse(editor, NULL, NULL); | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
316 |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
317 if ((editor->flags & EDITOR_NO_PARAM) && !category_geeqie) editor->hidden = TRUE; |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
318 |
1272 | 319 g_key_file_free(key_file); |
1479 | 320 |
321 if (editor->ignored) return TRUE; | |
322 | |
323 gtk_list_store_append(desktop_file_list, &iter); | |
324 gtk_list_store_set(desktop_file_list, &iter, | |
325 DESKTOP_FILE_COLUMN_KEY, key, | |
326 DESKTOP_FILE_COLUMN_NAME, editor->name, | |
327 DESKTOP_FILE_COLUMN_HIDDEN, editor->hidden, | |
328 DESKTOP_FILE_COLUMN_WRITABLE, access_file(path, W_OK), | |
329 DESKTOP_FILE_COLUMN_PATH, path, -1); | |
1272 | 330 |
331 return TRUE; | |
768
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
332 } |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
333 |
1272 | 334 static gboolean editor_remove_desktop_file_cb(gpointer key, gpointer value, gpointer user_data) |
335 { | |
336 EditorDescription *editor = value; | |
1479 | 337 return editor->hidden || editor->ignored; |
1272 | 338 } |
339 | |
340 static void editor_read_desktop_dir(const gchar *path) | |
9 | 341 { |
1272 | 342 DIR *dp; |
343 struct dirent *dir; | |
344 gchar *pathl; | |
345 | |
346 pathl = path_from_utf8(path); | |
347 dp = opendir(pathl); | |
348 g_free(pathl); | |
349 if (!dp) | |
350 { | |
351 /* dir not found */ | |
352 return; | |
353 } | |
354 while ((dir = readdir(dp)) != NULL) | |
355 { | |
356 gchar *namel = dir->d_name; | |
357 | |
1402 | 358 if (g_str_has_suffix(namel, ".desktop")) |
1272 | 359 { |
360 gchar *name = path_to_utf8(namel); | |
361 gchar *dpath = g_build_filename(path, name, NULL); | |
362 editor_read_desktop_file(dpath); | |
363 g_free(dpath); | |
364 g_free(name); | |
365 } | |
366 } | |
367 closedir(dp); | |
368 } | |
369 | |
370 void editor_load_descriptions(void) | |
371 { | |
372 gchar *path; | |
373 gchar *xdg_data_dirs; | |
374 gchar *all_dirs; | |
375 gchar **split_dirs; | |
9 | 376 gint i; |
1272 | 377 |
1479 | 378 if (desktop_file_list) |
379 { | |
380 gtk_list_store_clear(desktop_file_list); | |
381 } | |
382 else | |
383 { | |
384 desktop_file_list = gtk_list_store_new(DESKTOP_FILE_COLUMN_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING); | |
385 } | |
1463
25168240a247
added function to reload external editors at any time
nadvornik
parents:
1409
diff
changeset
|
386 if (editors) |
1272 | 387 { |
1463
25168240a247
added function to reload external editors at any time
nadvornik
parents:
1409
diff
changeset
|
388 g_hash_table_destroy(editors); |
1272 | 389 } |
1463
25168240a247
added function to reload external editors at any time
nadvornik
parents:
1409
diff
changeset
|
390 editors = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)editor_description_free); |
9 | 391 |
1272 | 392 xdg_data_dirs = getenv("XDG_DATA_DIRS"); |
393 if (xdg_data_dirs && xdg_data_dirs[0]) | |
394 xdg_data_dirs = path_to_utf8(xdg_data_dirs); | |
395 else | |
396 xdg_data_dirs = g_strdup("/usr/share"); | |
397 | |
1274 | 398 all_dirs = g_strconcat(get_rc_dir(), ":", GQ_APP_DIR, ":", xdg_data_home_get(), ":", xdg_data_dirs, NULL); |
1272 | 399 |
400 g_free(xdg_data_dirs); | |
401 | |
402 split_dirs = g_strsplit(all_dirs, ":", 0); | |
403 | |
404 g_free(all_dirs); | |
405 | |
406 for (i = 0; split_dirs[i]; i++) | |
9 | 407 { |
1272 | 408 path = g_build_filename(split_dirs[i], "applications", NULL); |
409 editor_read_desktop_dir(path); | |
410 g_free(path); | |
9 | 411 } |
1272 | 412 |
413 g_strfreev(split_dirs); | |
414 | |
415 g_hash_table_foreach_remove(editors, editor_remove_desktop_file_cb, NULL); | |
9 | 416 } |
417 | |
1272 | 418 static void editor_list_add_cb(gpointer key, gpointer value, gpointer data) |
419 { | |
420 GList **listp = data; | |
421 EditorDescription *editor = value; | |
422 | |
1402 | 423 /* do not show the special commands in any list, they are called explicitly */ |
1272 | 424 if (strcmp(editor->key, CMD_COPY) == 0 || |
425 strcmp(editor->key, CMD_MOVE) == 0 || | |
426 strcmp(editor->key, CMD_RENAME) == 0 || | |
427 strcmp(editor->key, CMD_DELETE) == 0 || | |
428 strcmp(editor->key, CMD_FOLDER) == 0) return; | |
429 | |
430 *listp = g_list_prepend(*listp, editor); | |
431 } | |
432 | |
1276
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
433 static gint editor_sort(gconstpointer a, gconstpointer b) |
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
434 { |
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
435 const EditorDescription *ea = a; |
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
436 const EditorDescription *eb = b; |
1402 | 437 gint ret; |
1276
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
438 |
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
439 ret = strcmp(ea->menu_path, eb->menu_path); |
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
440 if (ret != 0) return ret; |
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
441 |
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
442 return g_utf8_collate(ea->name, eb->name); |
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
443 } |
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
444 |
1272 | 445 GList *editor_list_get(void) |
446 { | |
447 GList *editors_list = NULL; | |
448 g_hash_table_foreach(editors, editor_list_add_cb, &editors_list); | |
1276
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
449 editors_list = g_list_sort(editors_list, editor_sort); |
4177057ca11b
editor_list_get() now returns a sorted list, this way items appear in the same order in all menus.
zas_
parents:
1274
diff
changeset
|
450 |
1272 | 451 return editors_list; |
452 } | |
453 | |
454 /* ------------------------------ */ | |
455 | |
456 | |
140 | 457 static void editor_verbose_data_free(EditorData *ed) |
458 { | |
459 if (!ed->vd) return; | |
460 g_free(ed->vd); | |
461 ed->vd = NULL; | |
462 } | |
463 | |
464 static void editor_data_free(EditorData *ed) | |
465 { | |
466 editor_verbose_data_free(ed); | |
467 g_free(ed); | |
468 } | |
469 | |
9 | 470 static void editor_verbose_window_close(GenericDialog *gd, gpointer data) |
471 { | |
140 | 472 EditorData *ed = data; |
9 | 473 |
474 generic_dialog_close(gd); | |
140 | 475 editor_verbose_data_free(ed); |
476 if (ed->pid == -1) editor_data_free(ed); /* the process has already terminated */ | |
9 | 477 } |
478 | |
479 static void editor_verbose_window_stop(GenericDialog *gd, gpointer data) | |
480 { | |
140 | 481 EditorData *ed = data; |
482 ed->stopping = TRUE; | |
483 ed->count = 0; | |
484 editor_verbose_window_progress(ed, _("stopping...")); | |
9 | 485 } |
486 | |
487 static void editor_verbose_window_enable_close(EditorVerboseData *vd) | |
488 { | |
489 vd->gd->cancel_cb = editor_verbose_window_close; | |
490 | |
491 spinner_set_interval(vd->spinner, -1); | |
492 gtk_widget_set_sensitive(vd->button_stop, FALSE); | |
493 gtk_widget_set_sensitive(vd->button_close, TRUE); | |
494 } | |
495 | |
140 | 496 static EditorVerboseData *editor_verbose_window(EditorData *ed, const gchar *text) |
9 | 497 { |
498 EditorVerboseData *vd; | |
499 GtkWidget *scrolled; | |
500 GtkWidget *hbox; | |
501 gchar *buf; | |
502 | |
503 vd = g_new0(EditorVerboseData, 1); | |
504 | |
1174
0bea79d87065
Drop useless wmclass stuff. Gtk will take care of it and as said in the documentation using gtk_window_set_wmclass() is sort of pointless.
zas_
parents:
1055
diff
changeset
|
505 vd->gd = file_util_gen_dlg(_("Edit command results"), "editor_results", |
9 | 506 NULL, FALSE, |
140 | 507 NULL, ed); |
9 | 508 buf = g_strdup_printf(_("Output of %s"), text); |
509 generic_dialog_add_message(vd->gd, NULL, buf, NULL); | |
510 g_free(buf); | |
511 vd->button_stop = generic_dialog_add_button(vd->gd, GTK_STOCK_STOP, NULL, | |
512 editor_verbose_window_stop, FALSE); | |
513 gtk_widget_set_sensitive(vd->button_stop, FALSE); | |
514 vd->button_close = generic_dialog_add_button(vd->gd, GTK_STOCK_CLOSE, NULL, | |
515 editor_verbose_window_close, TRUE); | |
516 gtk_widget_set_sensitive(vd->button_close, FALSE); | |
517 | |
518 scrolled = gtk_scrolled_window_new(NULL, NULL); | |
519 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); | |
520 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), | |
521 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
522 gtk_box_pack_start(GTK_BOX(vd->gd->vbox), scrolled, TRUE, TRUE, 5); | |
523 gtk_widget_show(scrolled); | |
524 | |
525 vd->text = gtk_text_view_new(); | |
526 gtk_text_view_set_editable(GTK_TEXT_VIEW(vd->text), FALSE); | |
527 gtk_widget_set_size_request(vd->text, EDITOR_WINDOW_WIDTH, EDITOR_WINDOW_HEIGHT); | |
528 gtk_container_add(GTK_CONTAINER(scrolled), vd->text); | |
529 gtk_widget_show(vd->text); | |
530 | |
531 hbox = gtk_hbox_new(FALSE, 0); | |
532 gtk_box_pack_start(GTK_BOX(vd->gd->vbox), hbox, FALSE, FALSE, 0); | |
533 gtk_widget_show(hbox); | |
534 | |
535 vd->progress = gtk_progress_bar_new(); | |
536 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(vd->progress), 0.0); | |
537 gtk_box_pack_start(GTK_BOX(hbox), vd->progress, TRUE, TRUE, 0); | |
538 gtk_widget_show(vd->progress); | |
539 | |
540 vd->spinner = spinner_new(NULL, SPINNER_SPEED); | |
541 gtk_box_pack_start(GTK_BOX(hbox), vd->spinner, FALSE, FALSE, 0); | |
542 gtk_widget_show(vd->spinner); | |
442 | 543 |
9 | 544 gtk_widget_show(vd->gd->dialog); |
545 | |
140 | 546 ed->vd = vd; |
9 | 547 return vd; |
548 } | |
549 | |
550 static void editor_verbose_window_fill(EditorVerboseData *vd, gchar *text, gint len) | |
551 { | |
552 GtkTextBuffer *buffer; | |
553 GtkTextIter iter; | |
554 | |
555 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(vd->text)); | |
556 gtk_text_buffer_get_iter_at_offset(buffer, &iter, -1); | |
557 gtk_text_buffer_insert(buffer, &iter, text, len); | |
558 } | |
559 | |
140 | 560 static void editor_verbose_window_progress(EditorData *ed, const gchar *text) |
9 | 561 { |
140 | 562 if (!ed->vd) return; |
563 | |
564 if (ed->total) | |
9 | 565 { |
1000
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
995
diff
changeset
|
566 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ed->vd->progress), (gdouble)ed->count / ed->total); |
9 | 567 } |
568 | |
140 | 569 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ed->vd->progress), (text) ? text : ""); |
9 | 570 } |
571 | |
572 static gboolean editor_verbose_io_cb(GIOChannel *source, GIOCondition condition, gpointer data) | |
573 { | |
140 | 574 EditorData *ed = data; |
9 | 575 gchar buf[512]; |
576 gsize count; | |
577 | |
140 | 578 if (condition & G_IO_IN) |
9 | 579 { |
140 | 580 while (g_io_channel_read_chars(source, buf, sizeof(buf), &count, NULL) == G_IO_STATUS_NORMAL) |
581 { | |
582 if (!g_utf8_validate(buf, count, NULL)) | |
9 | 583 { |
140 | 584 gchar *utf8; |
444 | 585 |
140 | 586 utf8 = g_locale_to_utf8(buf, count, NULL, NULL, NULL); |
587 if (utf8) | |
9 | 588 { |
140 | 589 editor_verbose_window_fill(ed->vd, utf8, -1); |
590 g_free(utf8); | |
9 | 591 } |
592 else | |
593 { | |
288
d1f74154463e
Replace occurences of Geeqie / geeqie by constants defined in main.h.
zas_
parents:
283
diff
changeset
|
594 editor_verbose_window_fill(ed->vd, "Error converting text to valid utf8\n", -1); |
9 | 595 } |
596 } | |
140 | 597 else |
598 { | |
599 editor_verbose_window_fill(ed->vd, buf, count); | |
600 } | |
601 } | |
9 | 602 } |
603 | |
140 | 604 if (condition & (G_IO_ERR | G_IO_HUP)) |
9 | 605 { |
140 | 606 g_io_channel_shutdown(source, TRUE, NULL); |
9 | 607 return FALSE; |
608 } | |
609 | |
610 return TRUE; | |
611 } | |
612 | |
138 | 613 typedef enum { |
614 PATH_FILE, | |
1272 | 615 PATH_FILE_URL, |
140 | 616 PATH_DEST |
138 | 617 } PathType; |
618 | |
619 | |
1272 | 620 static gchar *editor_command_path_parse(const FileData *fd, PathType type, const EditorDescription *editor) |
123
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
621 { |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
622 GString *string; |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
623 gchar *pathl; |
1408 | 624 const gchar *p = NULL; |
123
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
625 |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
626 string = g_string_new(""); |
442 | 627 |
1272 | 628 if (type == PATH_FILE || type == PATH_FILE_URL) |
138 | 629 { |
1272 | 630 GList *work = editor->ext_list; |
442 | 631 |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
632 if (!work) |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
633 p = fd->path; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
634 else |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
635 { |
516 | 636 while (work) |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
637 { |
444 | 638 GList *work2; |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
639 gchar *ext = work->data; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
640 work = work->next; |
442 | 641 |
642 if (strcmp(ext, "*") == 0 || | |
1307 | 643 g_ascii_strcasecmp(ext, fd->extension) == 0) |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
644 { |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
645 p = fd->path; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
646 break; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
647 } |
442 | 648 |
444 | 649 work2 = fd->sidecar_files; |
516 | 650 while (work2) |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
651 { |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
652 FileData *sfd = work2->data; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
653 work2 = work2->next; |
442 | 654 |
1307 | 655 if (g_ascii_strcasecmp(ext, sfd->extension) == 0) |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
656 { |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
657 p = sfd->path; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
658 break; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
659 } |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
660 } |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
661 if (p) break; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
662 } |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
663 if (!p) return NULL; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
664 } |
138 | 665 } |
140 | 666 else if (type == PATH_DEST) |
138 | 667 { |
668 if (fd->change && fd->change->dest) | |
669 p = fd->change->dest; | |
670 else | |
671 p = ""; | |
672 } | |
444 | 673 |
1407
57421a728682
Revert changeset 1502. It brokes the spec: hidden desktop files from user directory should hide files from system directory with the same name.
zas_
parents:
1406
diff
changeset
|
674 g_assert(p); |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
675 string = g_string_append(string, p); |
123
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
676 |
1272 | 677 if (type == PATH_FILE_URL) g_string_prepend(string, "file://"); |
123
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
678 pathl = path_from_utf8(string->str); |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
679 g_string_free(string, TRUE); |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
680 |
1402 | 681 if (pathl && !pathl[0]) /* empty string case */ |
682 { | |
683 g_free(pathl); | |
684 pathl = NULL; | |
685 } | |
686 | |
123
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
687 return pathl; |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
688 } |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
689 |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
690 static GString *append_quoted(GString *str, const char *s, gboolean single_quotes, gboolean double_quotes) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
691 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
692 const char *p; |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
693 |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
694 if (!single_quotes) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
695 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
696 if (!double_quotes) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
697 g_string_append_c(str, '\''); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
698 else |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
699 g_string_append(str, "\"'"); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
700 } |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
701 |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
702 for (p = s; *p != '\0'; p++) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
703 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
704 if (*p == '\'') |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
705 g_string_append(str, "'\\''"); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
706 else |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
707 g_string_append_c(str, *p); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
708 } |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
709 |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
710 if (!single_quotes) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
711 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
712 if (!double_quotes) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
713 g_string_append_c(str, '\''); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
714 else |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
715 g_string_append(str, "'\""); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
716 } |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
717 |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
718 return str; |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
719 } |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
720 |
9 | 721 |
1405 | 722 EditorFlags editor_command_parse(const EditorDescription *editor, GList *list, gchar **output) |
9 | 723 { |
1405 | 724 EditorFlags flags = 0; |
1272 | 725 const gchar *p; |
140 | 726 GString *result = NULL; |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
727 gboolean escape = FALSE; |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
728 gboolean single_quotes = FALSE; |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
729 gboolean double_quotes = FALSE; |
442 | 730 |
140 | 731 if (output) |
732 result = g_string_new(""); | |
733 | |
1272 | 734 if (editor->exec[0] == '\0') |
140 | 735 { |
736 flags |= EDITOR_ERROR_EMPTY; | |
737 goto err; | |
738 } | |
669 | 739 |
1272 | 740 p = editor->exec; |
669 | 741 /* skip leading whitespaces if any */ |
742 while (g_ascii_isspace(*p)) p++; | |
442 | 743 |
140 | 744 /* command */ |
442 | 745 |
140 | 746 while (*p) |
747 { | |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
748 if (escape) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
749 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
750 escape = FALSE; |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
751 if (output) result = g_string_append_c(result, *p); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
752 } |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
753 else if (*p == '\\') |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
754 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
755 if (!single_quotes) escape = TRUE; |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
756 if (output) result = g_string_append_c(result, *p); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
757 } |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
758 else if (*p == '\'') |
140 | 759 { |
760 if (output) result = g_string_append_c(result, *p); | |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
761 if (!single_quotes && !double_quotes) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
762 single_quotes = TRUE; |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
763 else if (single_quotes) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
764 single_quotes = FALSE; |
140 | 765 } |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
766 else if (*p == '"') |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
767 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
768 if (output) result = g_string_append_c(result, *p); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
769 if (!single_quotes && !double_quotes) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
770 double_quotes = TRUE; |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
771 else if (double_quotes) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
772 double_quotes = FALSE; |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
773 } |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
774 else if (*p == '%' && p[1]) |
140 | 775 { |
776 gchar *pathl = NULL; | |
9 | 777 |
140 | 778 p++; |
442 | 779 |
780 switch (*p) | |
140 | 781 { |
1272 | 782 case 'f': /* single file */ |
783 case 'u': /* single url */ | |
140 | 784 flags |= EDITOR_FOR_EACH; |
785 if (flags & EDITOR_SINGLE_COMMAND) | |
786 { | |
787 flags |= EDITOR_ERROR_INCOMPATIBLE; | |
788 goto err; | |
789 } | |
1399 | 790 if (list) |
1397
a0bd58a6535f
In various Edit context menus, only display editors that match the file types in the selection.
zas_
parents:
1367
diff
changeset
|
791 { |
1399 | 792 /* use the first file from the list */ |
793 if (!list->data) | |
794 { | |
795 flags |= EDITOR_ERROR_NO_FILE; | |
796 goto err; | |
797 } | |
798 pathl = editor_command_path_parse((FileData *)list->data, | |
799 (*p == 'f') ? PATH_FILE : PATH_FILE_URL, | |
800 editor); | |
801 if (!pathl) | |
802 { | |
803 flags |= EDITOR_ERROR_NO_FILE; | |
804 goto err; | |
805 } | |
806 if (output) | |
807 { | |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
808 result = append_quoted(result, pathl, single_quotes, double_quotes); |
1399 | 809 } |
810 g_free(pathl); | |
1397
a0bd58a6535f
In various Edit context menus, only display editors that match the file types in the selection.
zas_
parents:
1367
diff
changeset
|
811 } |
442 | 812 break; |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
813 |
1272 | 814 case 'F': |
815 case 'U': | |
140 | 816 flags |= EDITOR_SINGLE_COMMAND; |
817 if (flags & (EDITOR_FOR_EACH | EDITOR_DEST)) | |
818 { | |
819 flags |= EDITOR_ERROR_INCOMPATIBLE; | |
820 goto err; | |
821 } | |
822 | |
1399 | 823 if (list) |
140 | 824 { |
825 /* use whole list */ | |
826 GList *work = list; | |
827 gboolean ok = FALSE; | |
444 | 828 |
140 | 829 while (work) |
830 { | |
831 FileData *fd = work->data; | |
1272 | 832 pathl = editor_command_path_parse(fd, (*p == 'F') ? PATH_FILE : PATH_FILE_URL, editor); |
140 | 833 if (pathl) |
834 { | |
835 ok = TRUE; | |
1397
a0bd58a6535f
In various Edit context menus, only display editors that match the file types in the selection.
zas_
parents:
1367
diff
changeset
|
836 |
a0bd58a6535f
In various Edit context menus, only display editors that match the file types in the selection.
zas_
parents:
1367
diff
changeset
|
837 if (output) |
a0bd58a6535f
In various Edit context menus, only display editors that match the file types in the selection.
zas_
parents:
1367
diff
changeset
|
838 { |
a0bd58a6535f
In various Edit context menus, only display editors that match the file types in the selection.
zas_
parents:
1367
diff
changeset
|
839 ok = TRUE; |
a0bd58a6535f
In various Edit context menus, only display editors that match the file types in the selection.
zas_
parents:
1367
diff
changeset
|
840 if (work != list) g_string_append_c(result, ' '); |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
841 result = append_quoted(result, pathl, single_quotes, double_quotes); |
1397
a0bd58a6535f
In various Edit context menus, only display editors that match the file types in the selection.
zas_
parents:
1367
diff
changeset
|
842 } |
140 | 843 g_free(pathl); |
844 } | |
845 work = work->next; | |
846 } | |
442 | 847 if (!ok) |
140 | 848 { |
849 flags |= EDITOR_ERROR_NO_FILE; | |
850 goto err; | |
851 } | |
852 } | |
442 | 853 break; |
1272 | 854 case 'i': |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
855 if (editor->icon && *editor->icon) |
1272 | 856 { |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
857 if (output) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
858 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
859 result = g_string_append(result, "--icon "); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
860 result = append_quoted(result, editor->icon, single_quotes, double_quotes); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
861 } |
1272 | 862 } |
863 break; | |
864 case 'c': | |
865 if (output) | |
866 { | |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
867 result = append_quoted(result, editor->name, single_quotes, double_quotes); |
1272 | 868 } |
869 break; | |
870 case 'k': | |
871 if (output) | |
872 { | |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
873 result = append_quoted(result, editor->file, single_quotes, double_quotes); |
1272 | 874 } |
875 break; | |
669 | 876 case '%': |
877 /* %% = % escaping */ | |
878 if (output) result = g_string_append_c(result, *p); | |
879 break; | |
1272 | 880 case 'd': |
881 case 'D': | |
882 case 'n': | |
883 case 'N': | |
884 case 'v': | |
885 case 'm': | |
886 /* deprecated according to spec, ignore */ | |
887 break; | |
140 | 888 default: |
889 flags |= EDITOR_ERROR_SYNTAX; | |
890 goto err; | |
891 } | |
892 } | |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
893 else |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
894 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
895 if (output) result = g_string_append_c(result, *p); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
896 } |
140 | 897 p++; |
9 | 898 } |
899 | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
900 if (!(flags & (EDITOR_FOR_EACH | EDITOR_SINGLE_COMMAND))) flags |= EDITOR_NO_PARAM; |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
901 |
1478
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
902 if (output) |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
903 { |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
904 *output = g_string_free(result, FALSE); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
905 DEBUG_3("Editor cmd: %s", *output); |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
906 } |
3cc98d5c6907
Improve editors through .desktop files implementation:
zas_
parents:
1468
diff
changeset
|
907 |
140 | 908 return flags; |
909 | |
442 | 910 |
140 | 911 err: |
442 | 912 if (output) |
9 | 913 { |
140 | 914 g_string_free(result, TRUE); |
915 *output = NULL; | |
916 } | |
917 return flags; | |
918 } | |
919 | |
1272 | 920 |
1397
a0bd58a6535f
In various Edit context menus, only display editors that match the file types in the selection.
zas_
parents:
1367
diff
changeset
|
921 static void editor_child_exit_cb(GPid pid, gint status, gpointer data) |
140 | 922 { |
923 EditorData *ed = data; | |
924 g_spawn_close_pid(pid); | |
925 ed->pid = -1; | |
442 | 926 |
140 | 927 editor_command_next_finish(ed, status); |
928 } | |
929 | |
930 | |
1405 | 931 static EditorFlags editor_command_one(const EditorDescription *editor, GList *list, EditorData *ed) |
140 | 932 { |
933 gchar *command; | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
934 FileData *fd = (ed->flags & EDITOR_NO_PARAM) ? NULL : list->data;; |
140 | 935 GPid pid; |
442 | 936 gint standard_output; |
937 gint standard_error; | |
140 | 938 gboolean ok; |
939 | |
940 ed->pid = -1; | |
1405 | 941 ed->flags = editor->flags; |
942 ed->flags |= editor_command_parse(editor, list, &command); | |
140 | 943 |
1400
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
944 ok = !EDITOR_ERRORS(ed->flags); |
140 | 945 |
946 if (ok) | |
947 { | |
737
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
948 ok = (options->shell.path && *options->shell.path); |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
949 if (!ok) log_printf("ERROR: empty shell command\n"); |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
950 |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
951 if (ok) |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
952 { |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
953 ok = (access(options->shell.path, X_OK) == 0); |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
954 if (!ok) log_printf("ERROR: cannot execute shell command '%s'\n", options->shell.path); |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
955 } |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
956 |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
957 if (!ok) ed->flags |= EDITOR_ERROR_CANT_EXEC; |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
958 } |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
959 |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
960 if (ok) |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
961 { |
443 | 962 gchar *working_directory; |
963 gchar *args[4]; | |
737
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
964 guint n = 0; |
443 | 965 |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
966 working_directory = fd ? remove_level_from_path(fd->path) : NULL; |
737
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
967 args[n++] = options->shell.path; |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
968 if (options->shell.options && *options->shell.options) |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
969 args[n++] = options->shell.options; |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
970 args[n++] = command; |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
971 args[n] = NULL; |
443 | 972 |
1272 | 973 if ((ed->flags & EDITOR_DEST) && fd->change && fd->change->dest) /* FIXME: error handling */ |
974 { | |
1402 | 975 g_setenv("GEEQIE_DESTINATION", fd->change->dest, TRUE); |
1272 | 976 } |
977 else | |
978 { | |
1402 | 979 g_unsetenv("GEEQIE_DESTINATION"); |
1272 | 980 } |
981 | |
442 | 982 ok = g_spawn_async_with_pipes(working_directory, args, NULL, |
140 | 983 G_SPAWN_DO_NOT_REAP_CHILD, /* GSpawnFlags */ |
442 | 984 NULL, NULL, |
985 &pid, | |
986 NULL, | |
987 ed->vd ? &standard_output : NULL, | |
988 ed->vd ? &standard_error : NULL, | |
140 | 989 NULL); |
443 | 990 |
991 g_free(working_directory); | |
442 | 992 |
140 | 993 if (!ok) ed->flags |= EDITOR_ERROR_CANT_EXEC; |
994 } | |
995 | |
442 | 996 if (ok) |
140 | 997 { |
998 g_child_watch_add(pid, editor_child_exit_cb, ed); | |
999 ed->pid = pid; | |
1000 } | |
442 | 1001 |
140 | 1002 if (ed->vd) |
1003 { | |
1004 if (!ok) | |
9 | 1005 { |
140 | 1006 gchar *buf; |
1007 | |
1272 | 1008 buf = g_strdup_printf(_("Failed to run command:\n%s\n"), editor->file); |
140 | 1009 editor_verbose_window_fill(ed->vd, buf, strlen(buf)); |
1010 g_free(buf); | |
1011 | |
1012 } | |
442 | 1013 else |
140 | 1014 { |
1015 GIOChannel *channel_output; | |
1016 GIOChannel *channel_error; | |
444 | 1017 |
140 | 1018 channel_output = g_io_channel_unix_new(standard_output); |
1019 g_io_channel_set_flags(channel_output, G_IO_FLAG_NONBLOCK, NULL); | |
926 | 1020 g_io_channel_set_encoding(channel_output, NULL, NULL); |
140 | 1021 |
1022 g_io_add_watch_full(channel_output, G_PRIORITY_HIGH, G_IO_IN | G_IO_ERR | G_IO_HUP, | |
1023 editor_verbose_io_cb, ed, NULL); | |
1024 g_io_channel_unref(channel_output); | |
1025 | |
1026 channel_error = g_io_channel_unix_new(standard_error); | |
1027 g_io_channel_set_flags(channel_error, G_IO_FLAG_NONBLOCK, NULL); | |
926 | 1028 g_io_channel_set_encoding(channel_error, NULL, NULL); |
140 | 1029 |
1030 g_io_add_watch_full(channel_error, G_PRIORITY_HIGH, G_IO_IN | G_IO_ERR | G_IO_HUP, | |
1031 editor_verbose_io_cb, ed, NULL); | |
1032 g_io_channel_unref(channel_error); | |
1033 } | |
1034 } | |
442 | 1035 |
140 | 1036 g_free(command); |
1037 | |
1400
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1038 return EDITOR_ERRORS(ed->flags); |
140 | 1039 } |
1040 | |
1405 | 1041 static EditorFlags editor_command_next_start(EditorData *ed) |
140 | 1042 { |
1043 if (ed->vd) editor_verbose_window_fill(ed->vd, "\n", 1); | |
1044 | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1045 if ((ed->list || (ed->flags & EDITOR_NO_PARAM)) && ed->count < ed->total) |
140 | 1046 { |
1047 FileData *fd; | |
1405 | 1048 EditorFlags error; |
140 | 1049 |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1050 fd = (ed->flags & EDITOR_NO_PARAM) ? NULL : ed->list->data; |
140 | 1051 |
1052 if (ed->vd) | |
1053 { | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1054 if ((ed->flags & EDITOR_FOR_EACH) && fd) |
1402 | 1055 editor_verbose_window_progress(ed, fd->path); |
1056 else | |
1057 editor_verbose_window_progress(ed, _("running...")); | |
140 | 1058 } |
1059 ed->count++; | |
1060 | |
1272 | 1061 error = editor_command_one(ed->editor, ed->list, ed); |
140 | 1062 if (!error && ed->vd) |
1063 { | |
1064 gtk_widget_set_sensitive(ed->vd->button_stop, (ed->list != NULL) ); | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1065 if ((ed->flags & EDITOR_FOR_EACH) && fd) |
9 | 1066 { |
140 | 1067 editor_verbose_window_fill(ed->vd, fd->path, strlen(fd->path)); |
1068 editor_verbose_window_fill(ed->vd, "\n", 1); | |
9 | 1069 } |
1070 } | |
140 | 1071 |
442 | 1072 if (!error) |
140 | 1073 return 0; |
1402 | 1074 |
1075 /* command was not started, call the finish immediately */ | |
1076 return editor_command_next_finish(ed, 0); | |
140 | 1077 } |
442 | 1078 |
140 | 1079 /* everything is done */ |
237
404629011caa
Add missing return at the end of editor_command_next_start().
zas_
parents:
196
diff
changeset
|
1080 return editor_command_done(ed); |
140 | 1081 } |
1082 | |
1405 | 1083 static EditorFlags editor_command_next_finish(EditorData *ed, gint status) |
140 | 1084 { |
1085 gint cont = ed->stopping ? EDITOR_CB_SKIP : EDITOR_CB_CONTINUE; | |
1086 | |
1087 if (status) | |
1088 ed->flags |= EDITOR_ERROR_STATUS; | |
1089 | |
1090 if (ed->flags & EDITOR_FOR_EACH) | |
1091 { | |
1092 /* handle the first element from the list */ | |
1093 GList *fd_element = ed->list; | |
444 | 1094 |
140 | 1095 ed->list = g_list_remove_link(ed->list, fd_element); |
1096 if (ed->callback) | |
911 | 1097 { |
140 | 1098 cont = ed->callback(ed->list ? ed : NULL, ed->flags, fd_element, ed->data); |
911 | 1099 if (ed->stopping && cont == EDITOR_CB_CONTINUE) cont = EDITOR_CB_SKIP; |
1100 } | |
140 | 1101 filelist_free(fd_element); |
9 | 1102 } |
1103 else | |
1104 { | |
140 | 1105 /* handle whole list */ |
1106 if (ed->callback) | |
1107 cont = ed->callback(NULL, ed->flags, ed->list, ed->data); | |
1108 filelist_free(ed->list); | |
1109 ed->list = NULL; | |
1110 } | |
9 | 1111 |
1400
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1112 switch (cont) |
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1113 { |
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1114 case EDITOR_CB_SUSPEND: |
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1115 return EDITOR_ERRORS(ed->flags); |
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1116 case EDITOR_CB_SKIP: |
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1117 return editor_command_done(ed); |
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1118 } |
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1119 |
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1120 return editor_command_next_start(ed); |
140 | 1121 } |
9 | 1122 |
1405 | 1123 static EditorFlags editor_command_done(EditorData *ed) |
140 | 1124 { |
1405 | 1125 EditorFlags flags; |
9 | 1126 |
140 | 1127 if (ed->vd) |
1128 { | |
1129 if (ed->count == ed->total) | |
9 | 1130 { |
1402 | 1131 editor_verbose_window_progress(ed, _("done")); |
9 | 1132 } |
1133 else | |
1134 { | |
1402 | 1135 editor_verbose_window_progress(ed, _("stopped by user")); |
9 | 1136 } |
140 | 1137 editor_verbose_window_enable_close(ed->vd); |
1138 } | |
1139 | |
1140 /* free the not-handled items */ | |
1141 if (ed->list) | |
1142 { | |
1143 ed->flags |= EDITOR_ERROR_SKIPPED; | |
1144 if (ed->callback) ed->callback(NULL, ed->flags, ed->list, ed->data); | |
1145 filelist_free(ed->list); | |
1146 ed->list = NULL; | |
1147 } | |
9 | 1148 |
140 | 1149 ed->count = 0; |
1150 | |
1400
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1151 flags = EDITOR_ERRORS(ed->flags); |
140 | 1152 |
1153 if (!ed->vd) editor_data_free(ed); | |
1154 | |
1155 return flags; | |
1156 } | |
1157 | |
1158 void editor_resume(gpointer ed) | |
1159 { | |
1160 editor_command_next_start(ed); | |
1161 } | |
443 | 1162 |
140 | 1163 void editor_skip(gpointer ed) |
1164 { | |
442 | 1165 editor_command_done(ed); |
9 | 1166 } |
1167 | |
1405 | 1168 static EditorFlags editor_command_start(const EditorDescription *editor, const gchar *text, GList *list, EditorCallback cb, gpointer data) |
140 | 1169 { |
1170 EditorData *ed; | |
1405 | 1171 EditorFlags flags = editor->flags; |
442 | 1172 |
1400
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1173 if (EDITOR_ERRORS(flags)) return EDITOR_ERRORS(flags); |
140 | 1174 |
1175 ed = g_new0(EditorData, 1); | |
1176 ed->list = filelist_copy(list); | |
1177 ed->flags = flags; | |
1272 | 1178 ed->editor = editor; |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1179 ed->total = (flags & (EDITOR_SINGLE_COMMAND | EDITOR_NO_PARAM)) ? 1 : g_list_length(list); |
140 | 1180 ed->callback = cb; |
1181 ed->data = data; | |
442 | 1182 |
140 | 1183 if ((flags & EDITOR_VERBOSE_MULTI) && list && list->next) |
1184 flags |= EDITOR_VERBOSE; | |
442 | 1185 |
140 | 1186 if (flags & EDITOR_VERBOSE) |
1187 editor_verbose_window(ed, text); | |
442 | 1188 |
1189 editor_command_next_start(ed); | |
140 | 1190 /* errors from editor_command_next_start will be handled via callback */ |
1400
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1191 return EDITOR_ERRORS(flags); |
140 | 1192 } |
1193 | |
1272 | 1194 gboolean is_valid_editor_command(const gchar *key) |
444 | 1195 { |
1272 | 1196 if (!key) return FALSE; |
1197 return g_hash_table_lookup(editors, key) != NULL; | |
444 | 1198 } |
1199 | |
1405 | 1200 EditorFlags start_editor_from_filelist_full(const gchar *key, GList *list, EditorCallback cb, gpointer data) |
9 | 1201 { |
1405 | 1202 EditorFlags error; |
1272 | 1203 EditorDescription *editor; |
1204 if (!key) return FALSE; | |
1205 | |
1206 editor = g_hash_table_lookup(editors, key); | |
9 | 1207 |
1272 | 1208 if (!editor) return FALSE; |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1209 if (!list && !(editor->flags & EDITOR_NO_PARAM)) return FALSE; |
1272 | 1210 |
1211 error = editor_command_start(editor, editor->name, list, cb, data); | |
9 | 1212 |
1400
67573155210c
Add helper macros EDITOR_ERRORS() and EDITOR_ERRORS_BUT_SKIPPED() to clean up the code a bit. Minor tidy up.
zas_
parents:
1399
diff
changeset
|
1213 if (EDITOR_ERRORS(error)) |
669 | 1214 { |
1272 | 1215 gchar *text = g_strdup_printf(_("%s\n\"%s\""), editor_get_error_str(error), editor->file); |
669 | 1216 |
1217 file_util_warning_dialog(_("Invalid editor command"), text, GTK_STOCK_DIALOG_ERROR, NULL); | |
1218 g_free(text); | |
1219 } | |
1220 | |
140 | 1221 return error; |
9 | 1222 } |
1223 | |
1405 | 1224 EditorFlags start_editor_from_filelist(const gchar *key, GList *list) |
140 | 1225 { |
1272 | 1226 return start_editor_from_filelist_full(key, list, NULL, NULL); |
140 | 1227 } |
1228 | |
1405 | 1229 EditorFlags start_editor_from_file_full(const gchar *key, FileData *fd, EditorCallback cb, gpointer data) |
9 | 1230 { |
1231 GList *list; | |
1405 | 1232 EditorFlags error; |
9 | 1233 |
138 | 1234 if (!fd) return FALSE; |
9 | 1235 |
138 | 1236 list = g_list_append(NULL, fd); |
1272 | 1237 error = start_editor_from_filelist_full(key, list, cb, data); |
9 | 1238 g_list_free(list); |
140 | 1239 return error; |
9 | 1240 } |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1241 |
1405 | 1242 EditorFlags start_editor_from_file(const gchar *key, FileData *fd) |
136 | 1243 { |
1272 | 1244 return start_editor_from_file_full(key, fd, NULL, NULL); |
136 | 1245 } |
1246 | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1247 EditorFlags start_editor(const gchar *key) |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1248 { |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1249 return start_editor_from_filelist_full(key, NULL, NULL, NULL); |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1250 } |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1251 |
1405 | 1252 gboolean editor_window_flag_set(const gchar *key) |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1253 { |
1272 | 1254 EditorDescription *editor; |
1255 if (!key) return TRUE; | |
1256 | |
1257 editor = g_hash_table_lookup(editors, key); | |
1258 if (!editor) return TRUE; | |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1259 |
1405 | 1260 return !!(editor->flags & EDITOR_KEEP_FS); |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1261 } |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1262 |
1405 | 1263 gboolean editor_is_filter(const gchar *key) |
753 | 1264 { |
1272 | 1265 EditorDescription *editor; |
1266 if (!key) return TRUE; | |
1267 | |
1268 editor = g_hash_table_lookup(editors, key); | |
1269 if (!editor) return TRUE; | |
753 | 1270 |
1405 | 1271 return !!(editor->flags & EDITOR_DEST); |
753 | 1272 } |
1273 | |
1581
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1274 gboolean editor_no_param(const gchar *key) |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1275 { |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1276 EditorDescription *editor; |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1277 if (!key) return FALSE; |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1278 |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1279 editor = g_hash_table_lookup(editors, key); |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1280 if (!editor) return FALSE; |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1281 |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1282 return !!(editor->flags & EDITOR_NO_PARAM); |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1283 } |
c9c1a16ff8ae
allow external editors without parameters, as long as they are in
nadvornik
parents:
1486
diff
changeset
|
1284 |
1618
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1285 gboolean editor_blocks_file(const gchar *key) |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1286 { |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1287 EditorDescription *editor; |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1288 if (!key) return FALSE; |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1289 |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1290 editor = g_hash_table_lookup(editors, key); |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1291 if (!editor) return FALSE; |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1292 |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1293 /* Decide if the image file should be blocked during editor execution |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1294 Editors like gimp can be used long time after the original file was |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1295 saved, for editing unrelated files. |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1296 %f vs. %F seems to be a good heuristic to detect this kind of editors. |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1297 */ |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1298 |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1299 return !(editor->flags & EDITOR_SINGLE_COMMAND); |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1300 } |
552648eff4f2
do not block the files sent to external editors like gimp
nadvornik
parents:
1581
diff
changeset
|
1301 |
1405 | 1302 const gchar *editor_get_error_str(EditorFlags flags) |
140 | 1303 { |
1304 if (flags & EDITOR_ERROR_EMPTY) return _("Editor template is empty."); | |
1305 if (flags & EDITOR_ERROR_SYNTAX) return _("Editor template has incorrect syntax."); | |
1306 if (flags & EDITOR_ERROR_INCOMPATIBLE) return _("Editor template uses incompatible macros."); | |
1307 if (flags & EDITOR_ERROR_NO_FILE) return _("Can't find matching file type."); | |
1308 if (flags & EDITOR_ERROR_CANT_EXEC) return _("Can't execute external editor."); | |
1309 if (flags & EDITOR_ERROR_STATUS) return _("External editor returned error status."); | |
1310 if (flags & EDITOR_ERROR_SKIPPED) return _("File was skipped."); | |
1311 return _("Unknown error."); | |
1312 } | |
731
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
1313 |
1272 | 1314 const gchar *editor_get_name(const gchar *key) |
731
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
1315 { |
1272 | 1316 EditorDescription *editor = g_hash_table_lookup(editors, key); |
731
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
1317 |
1272 | 1318 if (!editor) return NULL; |
1319 | |
1320 return editor->name; | |
731
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
1321 } |
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
1022
diff
changeset
|
1322 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |