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