Mercurial > geeqie
annotate src/editors.c @ 1022:9962b24b6b43
Move miscellaneous functions to their own files (new misc.[ch]).
author | zas_ |
---|---|
date | Sun, 31 Aug 2008 10:51:41 +0000 |
parents | 4fe8f9656107 |
children | 1646720364cf |
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 |
475 | 4 * Copyright (C) 2008 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 { | |
45 gint flags; | |
46 GPid pid; | |
47 gchar *command_template; | |
48 GList *list; | |
9 | 49 gint count; |
50 gint total; | |
140 | 51 gboolean stopping; |
52 EditorVerboseData *vd; | |
53 EditorCallback callback; | |
54 gpointer data; | |
9 | 55 }; |
56 | |
57 | |
730 | 58 static Editor editor_slot_defaults[GQ_EDITOR_SLOTS] = { |
59 { N_("The Gimp"), "gimp-remote %{.cr2;.crw;.nef;.raw;*}f" }, | |
60 { N_("XV"), "xv %f" }, | |
61 { N_("Xpaint"), "xpaint %f" }, | |
62 { N_("UFraw"), "ufraw %{.cr2;.crw;.nef;.raw}p" }, | |
63 { N_("Add XMP sidecar"), "%vFILE=%{.cr2;.crw;.nef;.raw}p;XMP=`echo \"$FILE\"|sed -e 's|\\.[^.]*$|.xmp|'`; exiftool -tagsfromfile \"$FILE\" \"$XMP\"" }, | |
944
e73552743bda
added "Symlink" as an example of "filter" command
nadvornik
parents:
926
diff
changeset
|
64 { N_("Symlink"), "ln -s %p %d"}, |
730 | 65 { NULL, NULL }, |
66 { NULL, NULL }, | |
67 { N_("Rotate jpeg clockwise"), "%vif jpegtran -rotate 90 -copy all -outfile %{.jpg;.jpeg}p_tmp %{.jpg;.jpeg}p; then mv %{.jpg;.jpeg}p_tmp %{.jpg;.jpeg}p;else rm %{.jpg;.jpeg}p_tmp;fi" }, | |
68 { N_("Rotate jpeg counterclockwise"), "%vif jpegtran -rotate 270 -copy all -outfile %{.jpg;.jpeg}p_tmp %{.jpg;.jpeg}p; then mv %{.jpg;.jpeg}p_tmp %{.jpg;.jpeg}p;else rm %{.jpg;.jpeg}p_tmp;fi" }, | |
134
9009856628f7
started implementation of external commands; external Delete should work
nadvornik
parents:
123
diff
changeset
|
69 /* special slots */ |
136 | 70 #if 1 |
71 /* for testing */ | |
730 | 72 { N_("External Copy command"), "%vset -x;cp %p %d" }, |
73 { N_("External Move command"), "%vset -x;mv %p %d" }, | |
74 { N_("External Rename command"), "%vset -x;mv %p %d" }, | |
75 { N_("External Delete command"), NULL }, | |
76 { N_("External New Folder command"), NULL }, | |
136 | 77 #else |
730 | 78 { N_("External Copy command"), NULL }, |
79 { N_("External Move command"), NULL }, | |
80 { N_("External Rename command"), NULL }, | |
81 { N_("External Delete command"), NULL }, | |
82 { N_("External New Folder command"), NULL }, | |
136 | 83 #endif |
9 | 84 }; |
85 | |
140 | 86 static void editor_verbose_window_progress(EditorData *ed, const gchar *text); |
87 static gint editor_command_next_start(EditorData *ed); | |
88 static gint editor_command_next_finish(EditorData *ed, gint status); | |
89 static gint editor_command_done(EditorData *ed); | |
9 | 90 |
91 /* | |
92 *----------------------------------------------------------------------------- | |
93 * external editor routines | |
94 *----------------------------------------------------------------------------- | |
95 */ | |
96 | |
768
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
97 void editor_set_name(gint n, gchar *name) |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
98 { |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
99 if (n < 0 || n >= GQ_EDITOR_SLOTS) return; |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
100 |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
101 g_free(options->editor[n].name); |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
102 |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
103 options->editor[n].name = name ? utf8_validate_or_convert(name) : NULL; |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
104 } |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
105 |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
106 void editor_set_command(gint n, gchar *command) |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
107 { |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
108 if (n < 0 || n >= GQ_EDITOR_SLOTS) return; |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
109 |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
110 g_free(options->editor[n].command); |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
111 options->editor[n].command = command ? utf8_validate_or_convert(command) : NULL; |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
112 } |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
113 |
9 | 114 void editor_reset_defaults(void) |
115 { | |
116 gint i; | |
117 | |
283 | 118 for (i = 0; i < GQ_EDITOR_SLOTS; i++) |
9 | 119 { |
768
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
120 editor_set_name(i, _(editor_slot_defaults[i].name)); |
ff51413f098d
Use functions to set editors name and command and ensure they are
zas_
parents:
766
diff
changeset
|
121 editor_set_command(i, _(editor_slot_defaults[i].command)); |
9 | 122 } |
123 } | |
124 | |
140 | 125 static void editor_verbose_data_free(EditorData *ed) |
126 { | |
127 if (!ed->vd) return; | |
128 g_free(ed->vd); | |
129 ed->vd = NULL; | |
130 } | |
131 | |
132 static void editor_data_free(EditorData *ed) | |
133 { | |
134 editor_verbose_data_free(ed); | |
135 g_free(ed->command_template); | |
136 g_free(ed); | |
137 } | |
138 | |
9 | 139 static void editor_verbose_window_close(GenericDialog *gd, gpointer data) |
140 { | |
140 | 141 EditorData *ed = data; |
9 | 142 |
143 generic_dialog_close(gd); | |
140 | 144 editor_verbose_data_free(ed); |
145 if (ed->pid == -1) editor_data_free(ed); /* the process has already terminated */ | |
9 | 146 } |
147 | |
148 static void editor_verbose_window_stop(GenericDialog *gd, gpointer data) | |
149 { | |
140 | 150 EditorData *ed = data; |
151 ed->stopping = TRUE; | |
152 ed->count = 0; | |
153 editor_verbose_window_progress(ed, _("stopping...")); | |
9 | 154 } |
155 | |
156 static void editor_verbose_window_enable_close(EditorVerboseData *vd) | |
157 { | |
158 vd->gd->cancel_cb = editor_verbose_window_close; | |
159 | |
160 spinner_set_interval(vd->spinner, -1); | |
161 gtk_widget_set_sensitive(vd->button_stop, FALSE); | |
162 gtk_widget_set_sensitive(vd->button_close, TRUE); | |
163 } | |
164 | |
140 | 165 static EditorVerboseData *editor_verbose_window(EditorData *ed, const gchar *text) |
9 | 166 { |
167 EditorVerboseData *vd; | |
168 GtkWidget *scrolled; | |
169 GtkWidget *hbox; | |
170 gchar *buf; | |
171 | |
172 vd = g_new0(EditorVerboseData, 1); | |
173 | |
254
9faf34f047b1
Make the wmclass value unique among the code by defining
zas_
parents:
238
diff
changeset
|
174 vd->gd = file_util_gen_dlg(_("Edit command results"), GQ_WMCLASS, "editor_results", |
9 | 175 NULL, FALSE, |
140 | 176 NULL, ed); |
9 | 177 buf = g_strdup_printf(_("Output of %s"), text); |
178 generic_dialog_add_message(vd->gd, NULL, buf, NULL); | |
179 g_free(buf); | |
180 vd->button_stop = generic_dialog_add_button(vd->gd, GTK_STOCK_STOP, NULL, | |
181 editor_verbose_window_stop, FALSE); | |
182 gtk_widget_set_sensitive(vd->button_stop, FALSE); | |
183 vd->button_close = generic_dialog_add_button(vd->gd, GTK_STOCK_CLOSE, NULL, | |
184 editor_verbose_window_close, TRUE); | |
185 gtk_widget_set_sensitive(vd->button_close, FALSE); | |
186 | |
187 scrolled = gtk_scrolled_window_new(NULL, NULL); | |
188 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); | |
189 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), | |
190 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
191 gtk_box_pack_start(GTK_BOX(vd->gd->vbox), scrolled, TRUE, TRUE, 5); | |
192 gtk_widget_show(scrolled); | |
193 | |
194 vd->text = gtk_text_view_new(); | |
195 gtk_text_view_set_editable(GTK_TEXT_VIEW(vd->text), FALSE); | |
196 gtk_widget_set_size_request(vd->text, EDITOR_WINDOW_WIDTH, EDITOR_WINDOW_HEIGHT); | |
197 gtk_container_add(GTK_CONTAINER(scrolled), vd->text); | |
198 gtk_widget_show(vd->text); | |
199 | |
200 hbox = gtk_hbox_new(FALSE, 0); | |
201 gtk_box_pack_start(GTK_BOX(vd->gd->vbox), hbox, FALSE, FALSE, 0); | |
202 gtk_widget_show(hbox); | |
203 | |
204 vd->progress = gtk_progress_bar_new(); | |
205 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(vd->progress), 0.0); | |
206 gtk_box_pack_start(GTK_BOX(hbox), vd->progress, TRUE, TRUE, 0); | |
207 gtk_widget_show(vd->progress); | |
208 | |
209 vd->spinner = spinner_new(NULL, SPINNER_SPEED); | |
210 gtk_box_pack_start(GTK_BOX(hbox), vd->spinner, FALSE, FALSE, 0); | |
211 gtk_widget_show(vd->spinner); | |
442 | 212 |
9 | 213 gtk_widget_show(vd->gd->dialog); |
214 | |
140 | 215 ed->vd = vd; |
9 | 216 return vd; |
217 } | |
218 | |
219 static void editor_verbose_window_fill(EditorVerboseData *vd, gchar *text, gint len) | |
220 { | |
221 GtkTextBuffer *buffer; | |
222 GtkTextIter iter; | |
223 | |
224 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(vd->text)); | |
225 gtk_text_buffer_get_iter_at_offset(buffer, &iter, -1); | |
226 gtk_text_buffer_insert(buffer, &iter, text, len); | |
227 } | |
228 | |
140 | 229 static void editor_verbose_window_progress(EditorData *ed, const gchar *text) |
9 | 230 { |
140 | 231 if (!ed->vd) return; |
232 | |
233 if (ed->total) | |
9 | 234 { |
1000
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
995
diff
changeset
|
235 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ed->vd->progress), (gdouble)ed->count / ed->total); |
9 | 236 } |
237 | |
140 | 238 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ed->vd->progress), (text) ? text : ""); |
9 | 239 } |
240 | |
241 static gboolean editor_verbose_io_cb(GIOChannel *source, GIOCondition condition, gpointer data) | |
242 { | |
140 | 243 EditorData *ed = data; |
9 | 244 gchar buf[512]; |
245 gsize count; | |
246 | |
140 | 247 if (condition & G_IO_IN) |
9 | 248 { |
140 | 249 while (g_io_channel_read_chars(source, buf, sizeof(buf), &count, NULL) == G_IO_STATUS_NORMAL) |
250 { | |
251 if (!g_utf8_validate(buf, count, NULL)) | |
9 | 252 { |
140 | 253 gchar *utf8; |
444 | 254 |
140 | 255 utf8 = g_locale_to_utf8(buf, count, NULL, NULL, NULL); |
256 if (utf8) | |
9 | 257 { |
140 | 258 editor_verbose_window_fill(ed->vd, utf8, -1); |
259 g_free(utf8); | |
9 | 260 } |
261 else | |
262 { | |
288
d1f74154463e
Replace occurences of Geeqie / geeqie by constants defined in main.h.
zas_
parents:
283
diff
changeset
|
263 editor_verbose_window_fill(ed->vd, "Error converting text to valid utf8\n", -1); |
9 | 264 } |
265 } | |
140 | 266 else |
267 { | |
268 editor_verbose_window_fill(ed->vd, buf, count); | |
269 } | |
270 } | |
9 | 271 } |
272 | |
140 | 273 if (condition & (G_IO_ERR | G_IO_HUP)) |
9 | 274 { |
140 | 275 g_io_channel_shutdown(source, TRUE, NULL); |
9 | 276 return FALSE; |
277 } | |
278 | |
279 return TRUE; | |
280 } | |
281 | |
138 | 282 typedef enum { |
283 PATH_FILE, | |
140 | 284 PATH_DEST |
138 | 285 } PathType; |
286 | |
287 | |
140 | 288 static gchar *editor_command_path_parse(const FileData *fd, PathType type, const gchar *extensions) |
123
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
289 { |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
290 GString *string; |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
291 gchar *pathl; |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
292 const gchar *p = NULL; |
123
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
293 |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
294 string = g_string_new(""); |
442 | 295 |
138 | 296 if (type == PATH_FILE) |
297 { | |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
298 GList *ext_list = filter_to_list(extensions); |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
299 GList *work = ext_list; |
442 | 300 |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
301 if (!work) |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
302 p = fd->path; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
303 else |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
304 { |
516 | 305 while (work) |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
306 { |
444 | 307 GList *work2; |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
308 gchar *ext = work->data; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
309 work = work->next; |
442 | 310 |
311 if (strcmp(ext, "*") == 0 || | |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
312 strcasecmp(ext, fd->extension) == 0) |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
313 { |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
314 p = fd->path; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
315 break; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
316 } |
442 | 317 |
444 | 318 work2 = fd->sidecar_files; |
516 | 319 while (work2) |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
320 { |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
321 FileData *sfd = work2->data; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
322 work2 = work2->next; |
442 | 323 |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
324 if (strcasecmp(ext, sfd->extension) == 0) |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
325 { |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
326 p = sfd->path; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
327 break; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
328 } |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
329 } |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
330 if (p) break; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
331 } |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
332 string_list_free(ext_list); |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
333 if (!p) return NULL; |
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
334 } |
138 | 335 } |
140 | 336 else if (type == PATH_DEST) |
138 | 337 { |
338 if (fd->change && fd->change->dest) | |
339 p = fd->change->dest; | |
340 else | |
341 p = ""; | |
342 } | |
444 | 343 |
123
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
344 while (*p != '\0') |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
345 { |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
346 /* must escape \, ", `, and $ to avoid problems, |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
347 * 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
|
348 */ |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
349 if (strchr("\\\"`$", *p) != NULL) |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
350 { |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
351 string = g_string_append_c(string, '\\'); |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
352 } |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
353 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
|
354 p++; |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
355 } |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
356 |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
357 pathl = path_from_utf8(string->str); |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
358 g_string_free(string, TRUE); |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
359 |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
360 return pathl; |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
361 } |
3602a4aa7c71
Sat Dec 2 20:15:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
60
diff
changeset
|
362 |
9 | 363 |
364 /* | |
365 * The supported macros for editor commands: | |
366 * | |
367 * %f first occurence replaced by quoted sequence of filenames, command is run once. | |
368 * only one occurence of this macro is supported. | |
369 * ([ls %f] results in [ls "file1" "file2" ... "lastfile"]) | |
370 * %p command is run for each filename in turn, each instance replaced with single filename. | |
371 * multiple occurences of this macro is supported for complex shell commands. | |
372 * This macro will BLOCK THE APPLICATION until it completes, since command is run once | |
373 * for every file in syncronous order. To avoid blocking add the %v macro, below. | |
374 * ([ls %p] results in [ls "file1"], [ls "file2"] ... [ls "lastfile"]) | |
375 * none if no macro is supplied, the result is equivalent to "command %f" | |
376 * ([ls] results in [ls "file1" "file2" ... "lastfile"]) | |
377 * | |
378 * Only one of the macros %f or %p may be used in a given commmand. | |
379 * | |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
380 * %v must be the first two characters[1] in a command, causes a window to display |
9 | 381 * showing the output of the command(s). |
382 * %V same as %v except in the case of %p only displays a window for multiple files, | |
383 * operating on a single file is suppresses the output dialog. | |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
384 * |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
385 * %w must be first two characters in a command, presence will disable full screen |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
386 * from exiting upon invocation. |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
387 * |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
388 * |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
389 * [1] Note: %v,%V may also be preceded by "%w". |
9 | 390 */ |
140 | 391 |
392 | |
393 gint editor_command_parse(const gchar *template, GList *list, gchar **output) | |
9 | 394 { |
140 | 395 gint flags = 0; |
396 const gchar *p = template; | |
397 GString *result = NULL; | |
398 gchar *extensions = NULL; | |
442 | 399 |
140 | 400 if (output) |
401 result = g_string_new(""); | |
402 | |
442 | 403 if (!template || template[0] == '\0') |
140 | 404 { |
405 flags |= EDITOR_ERROR_EMPTY; | |
406 goto err; | |
407 } | |
669 | 408 |
409 /* skip leading whitespaces if any */ | |
410 while (g_ascii_isspace(*p)) p++; | |
442 | 411 |
140 | 412 /* global flags */ |
413 while (*p == '%') | |
414 { | |
415 switch (*++p) | |
416 { | |
417 case 'w': | |
418 flags |= EDITOR_KEEP_FS; | |
419 p++; | |
420 break; | |
421 case 'v': | |
422 flags |= EDITOR_VERBOSE; | |
423 p++; | |
424 break; | |
425 case 'V': | |
426 flags |= EDITOR_VERBOSE_MULTI; | |
427 p++; | |
428 break; | |
669 | 429 default: |
430 flags |= EDITOR_ERROR_SYNTAX; | |
431 goto err; | |
140 | 432 } |
433 } | |
442 | 434 |
669 | 435 /* skip whitespaces if any */ |
436 while (g_ascii_isspace(*p)) p++; | |
437 | |
140 | 438 /* command */ |
442 | 439 |
140 | 440 while (*p) |
441 { | |
442 if (*p != '%') | |
443 { | |
444 if (output) result = g_string_append_c(result, *p); | |
445 } | |
446 else /* *p == '%' */ | |
447 { | |
448 extensions = NULL; | |
449 gchar *pathl = NULL; | |
9 | 450 |
140 | 451 p++; |
442 | 452 |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
453 /* for example "%f" or "%{.crw;.raw;.cr2}f" */ |
140 | 454 if (*p == '{') |
455 { | |
444 | 456 gchar *end; |
457 | |
140 | 458 p++; |
444 | 459 end = strchr(p, '}'); |
140 | 460 if (!end) |
461 { | |
462 flags |= EDITOR_ERROR_SYNTAX; | |
463 goto err; | |
464 } | |
442 | 465 |
140 | 466 extensions = g_strndup(p, end - p); |
467 p = end + 1; | |
468 } | |
442 | 469 |
470 switch (*p) | |
140 | 471 { |
472 case 'd': | |
473 flags |= EDITOR_DEST; | |
669 | 474 /* fall through */ |
140 | 475 case 'p': |
476 flags |= EDITOR_FOR_EACH; | |
477 if (flags & EDITOR_SINGLE_COMMAND) | |
478 { | |
479 flags |= EDITOR_ERROR_INCOMPATIBLE; | |
480 goto err; | |
481 } | |
482 if (output) | |
483 { | |
484 /* use the first file from the list */ | |
442 | 485 if (!list || !list->data) |
140 | 486 { |
487 flags |= EDITOR_ERROR_NO_FILE; | |
488 goto err; | |
489 } | |
669 | 490 pathl = editor_command_path_parse((FileData *)list->data, |
491 (flags & EDITOR_DEST) ? PATH_DEST : PATH_FILE, | |
492 extensions); | |
442 | 493 if (!pathl) |
140 | 494 { |
495 flags |= EDITOR_ERROR_NO_FILE; | |
496 goto err; | |
497 } | |
498 result = g_string_append_c(result, '"'); | |
499 result = g_string_append(result, pathl); | |
500 g_free(pathl); | |
501 result = g_string_append_c(result, '"'); | |
502 } | |
442 | 503 break; |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
504 |
140 | 505 case 'f': |
506 flags |= EDITOR_SINGLE_COMMAND; | |
507 if (flags & (EDITOR_FOR_EACH | EDITOR_DEST)) | |
508 { | |
509 flags |= EDITOR_ERROR_INCOMPATIBLE; | |
510 goto err; | |
511 } | |
512 | |
513 if (output) | |
514 { | |
515 /* use whole list */ | |
516 GList *work = list; | |
517 gboolean ok = FALSE; | |
444 | 518 |
140 | 519 while (work) |
520 { | |
521 FileData *fd = work->data; | |
522 pathl = editor_command_path_parse(fd, PATH_FILE, extensions); | |
523 | |
524 if (pathl) | |
525 { | |
526 ok = TRUE; | |
527 if (work != list) g_string_append_c(result, ' '); | |
528 result = g_string_append_c(result, '"'); | |
529 result = g_string_append(result, pathl); | |
530 g_free(pathl); | |
531 result = g_string_append_c(result, '"'); | |
532 } | |
533 work = work->next; | |
534 } | |
442 | 535 if (!ok) |
140 | 536 { |
537 flags |= EDITOR_ERROR_NO_FILE; | |
538 goto err; | |
539 } | |
540 } | |
442 | 541 break; |
669 | 542 case '%': |
543 /* %% = % escaping */ | |
544 if (output) result = g_string_append_c(result, *p); | |
545 break; | |
140 | 546 default: |
547 flags |= EDITOR_ERROR_SYNTAX; | |
548 goto err; | |
549 } | |
550 if (extensions) g_free(extensions); | |
551 extensions = NULL; | |
552 } | |
553 p++; | |
9 | 554 } |
555 | |
140 | 556 if (output) *output = g_string_free(result, FALSE); |
557 return flags; | |
558 | |
442 | 559 |
140 | 560 err: |
442 | 561 if (output) |
9 | 562 { |
140 | 563 g_string_free(result, TRUE); |
564 *output = NULL; | |
565 } | |
566 if (extensions) g_free(extensions); | |
567 return flags; | |
568 } | |
569 | |
570 static void editor_child_exit_cb (GPid pid, gint status, gpointer data) | |
571 { | |
572 EditorData *ed = data; | |
573 g_spawn_close_pid(pid); | |
574 ed->pid = -1; | |
442 | 575 |
140 | 576 editor_command_next_finish(ed, status); |
577 } | |
578 | |
579 | |
580 static gint editor_command_one(const gchar *template, GList *list, EditorData *ed) | |
581 { | |
582 gchar *command; | |
583 FileData *fd = list->data; | |
584 GPid pid; | |
442 | 585 gint standard_output; |
586 gint standard_error; | |
140 | 587 gboolean ok; |
588 | |
589 ed->pid = -1; | |
590 ed->flags = editor_command_parse(template, list, &command); | |
591 | |
592 ok = !(ed->flags & EDITOR_ERROR_MASK); | |
593 | |
594 if (ok) | |
595 { | |
737
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
596 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
|
597 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
|
598 |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
599 if (ok) |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
600 { |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
601 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
|
602 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
|
603 } |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
604 |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
605 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
|
606 } |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
607 |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
608 if (ok) |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
609 { |
443 | 610 gchar *working_directory; |
611 gchar *args[4]; | |
737
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
612 guint n = 0; |
443 | 613 |
614 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
|
615 args[n++] = options->shell.path; |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
616 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
|
617 args[n++] = options->shell.options; |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
618 args[n++] = command; |
8a8873e7a552
Make shell command and its option rc file options instead of hardcoded strings.
zas_
parents:
731
diff
changeset
|
619 args[n] = NULL; |
443 | 620 |
442 | 621 ok = g_spawn_async_with_pipes(working_directory, args, NULL, |
140 | 622 G_SPAWN_DO_NOT_REAP_CHILD, /* GSpawnFlags */ |
442 | 623 NULL, NULL, |
624 &pid, | |
625 NULL, | |
626 ed->vd ? &standard_output : NULL, | |
627 ed->vd ? &standard_error : NULL, | |
140 | 628 NULL); |
443 | 629 |
630 g_free(working_directory); | |
442 | 631 |
140 | 632 if (!ok) ed->flags |= EDITOR_ERROR_CANT_EXEC; |
633 } | |
634 | |
442 | 635 if (ok) |
140 | 636 { |
637 g_child_watch_add(pid, editor_child_exit_cb, ed); | |
638 ed->pid = pid; | |
639 } | |
442 | 640 |
140 | 641 if (ed->vd) |
642 { | |
643 if (!ok) | |
9 | 644 { |
140 | 645 gchar *buf; |
646 | |
147
b2266996fa83
added possibility to specify prefered file type for external commands
nadvornik
parents:
140
diff
changeset
|
647 buf = g_strdup_printf(_("Failed to run command:\n%s\n"), template); |
140 | 648 editor_verbose_window_fill(ed->vd, buf, strlen(buf)); |
649 g_free(buf); | |
650 | |
651 } | |
442 | 652 else |
140 | 653 { |
654 GIOChannel *channel_output; | |
655 GIOChannel *channel_error; | |
444 | 656 |
140 | 657 channel_output = g_io_channel_unix_new(standard_output); |
658 g_io_channel_set_flags(channel_output, G_IO_FLAG_NONBLOCK, NULL); | |
926 | 659 g_io_channel_set_encoding(channel_output, NULL, NULL); |
140 | 660 |
661 g_io_add_watch_full(channel_output, G_PRIORITY_HIGH, G_IO_IN | G_IO_ERR | G_IO_HUP, | |
662 editor_verbose_io_cb, ed, NULL); | |
663 g_io_channel_unref(channel_output); | |
664 | |
665 channel_error = g_io_channel_unix_new(standard_error); | |
666 g_io_channel_set_flags(channel_error, G_IO_FLAG_NONBLOCK, NULL); | |
926 | 667 g_io_channel_set_encoding(channel_error, NULL, NULL); |
140 | 668 |
669 g_io_add_watch_full(channel_error, G_PRIORITY_HIGH, G_IO_IN | G_IO_ERR | G_IO_HUP, | |
670 editor_verbose_io_cb, ed, NULL); | |
671 g_io_channel_unref(channel_error); | |
672 } | |
673 } | |
442 | 674 |
140 | 675 g_free(command); |
676 | |
677 return ed->flags & EDITOR_ERROR_MASK; | |
678 } | |
679 | |
680 static gint editor_command_next_start(EditorData *ed) | |
681 { | |
682 if (ed->vd) editor_verbose_window_fill(ed->vd, "\n", 1); | |
683 | |
684 if (ed->list && ed->count < ed->total) | |
685 { | |
686 FileData *fd; | |
687 gint error; | |
688 | |
689 fd = ed->list->data; | |
690 | |
691 if (ed->vd) | |
692 { | |
693 editor_verbose_window_progress(ed, (ed->flags & EDITOR_FOR_EACH) ? fd->path : _("running...")); | |
694 } | |
695 ed->count++; | |
696 | |
697 error = editor_command_one(ed->command_template, ed->list, ed); | |
698 if (!error && ed->vd) | |
699 { | |
700 gtk_widget_set_sensitive(ed->vd->button_stop, (ed->list != NULL) ); | |
701 if (ed->flags & EDITOR_FOR_EACH) | |
9 | 702 { |
140 | 703 editor_verbose_window_fill(ed->vd, fd->path, strlen(fd->path)); |
704 editor_verbose_window_fill(ed->vd, "\n", 1); | |
9 | 705 } |
706 } | |
140 | 707 |
442 | 708 if (!error) |
140 | 709 return 0; |
710 else | |
711 /* command was not started, call the finish immediately */ | |
712 return editor_command_next_finish(ed, 0); | |
713 } | |
442 | 714 |
140 | 715 /* everything is done */ |
237
404629011caa
Add missing return at the end of editor_command_next_start().
zas_
parents:
196
diff
changeset
|
716 return editor_command_done(ed); |
140 | 717 } |
718 | |
719 static gint editor_command_next_finish(EditorData *ed, gint status) | |
720 { | |
721 gint cont = ed->stopping ? EDITOR_CB_SKIP : EDITOR_CB_CONTINUE; | |
722 | |
723 if (status) | |
724 ed->flags |= EDITOR_ERROR_STATUS; | |
725 | |
726 if (ed->flags & EDITOR_FOR_EACH) | |
727 { | |
728 /* handle the first element from the list */ | |
729 GList *fd_element = ed->list; | |
444 | 730 |
140 | 731 ed->list = g_list_remove_link(ed->list, fd_element); |
732 if (ed->callback) | |
911 | 733 { |
140 | 734 cont = ed->callback(ed->list ? ed : NULL, ed->flags, fd_element, ed->data); |
911 | 735 if (ed->stopping && cont == EDITOR_CB_CONTINUE) cont = EDITOR_CB_SKIP; |
736 } | |
140 | 737 filelist_free(fd_element); |
9 | 738 } |
739 else | |
740 { | |
140 | 741 /* handle whole list */ |
742 if (ed->callback) | |
743 cont = ed->callback(NULL, ed->flags, ed->list, ed->data); | |
744 filelist_free(ed->list); | |
745 ed->list = NULL; | |
746 } | |
9 | 747 |
140 | 748 if (cont == EDITOR_CB_SUSPEND) |
749 return ed->flags & EDITOR_ERROR_MASK; | |
750 else if (cont == EDITOR_CB_SKIP) | |
751 return editor_command_done(ed); | |
752 else | |
753 return editor_command_next_start(ed); | |
754 } | |
9 | 755 |
140 | 756 static gint editor_command_done(EditorData *ed) |
757 { | |
758 gint flags; | |
9 | 759 |
140 | 760 if (ed->vd) |
761 { | |
444 | 762 const gchar *text; |
763 | |
140 | 764 if (ed->count == ed->total) |
9 | 765 { |
140 | 766 text = _("done"); |
9 | 767 } |
768 else | |
769 { | |
140 | 770 text = _("stopped by user"); |
9 | 771 } |
140 | 772 editor_verbose_window_progress(ed, text); |
773 editor_verbose_window_enable_close(ed->vd); | |
774 } | |
775 | |
776 /* free the not-handled items */ | |
777 if (ed->list) | |
778 { | |
779 ed->flags |= EDITOR_ERROR_SKIPPED; | |
780 if (ed->callback) ed->callback(NULL, ed->flags, ed->list, ed->data); | |
781 filelist_free(ed->list); | |
782 ed->list = NULL; | |
783 } | |
9 | 784 |
140 | 785 ed->count = 0; |
786 | |
787 flags = ed->flags & EDITOR_ERROR_MASK; | |
788 | |
789 if (!ed->vd) editor_data_free(ed); | |
790 | |
791 return flags; | |
792 } | |
793 | |
794 void editor_resume(gpointer ed) | |
795 { | |
796 editor_command_next_start(ed); | |
797 } | |
443 | 798 |
140 | 799 void editor_skip(gpointer ed) |
800 { | |
442 | 801 editor_command_done(ed); |
9 | 802 } |
803 | |
140 | 804 static gint editor_command_start(const gchar *template, const gchar *text, GList *list, EditorCallback cb, gpointer data) |
805 { | |
806 EditorData *ed; | |
807 gint flags = editor_command_parse(template, NULL, NULL); | |
442 | 808 |
140 | 809 if (flags & EDITOR_ERROR_MASK) return flags & EDITOR_ERROR_MASK; |
810 | |
811 ed = g_new0(EditorData, 1); | |
812 ed->list = filelist_copy(list); | |
813 ed->flags = flags; | |
814 ed->command_template = g_strdup(template); | |
815 ed->total = (flags & EDITOR_SINGLE_COMMAND) ? 1 : g_list_length(list); | |
816 ed->count = 0; | |
817 ed->stopping = FALSE; | |
818 ed->callback = cb; | |
819 ed->data = data; | |
442 | 820 |
140 | 821 if ((flags & EDITOR_VERBOSE_MULTI) && list && list->next) |
822 flags |= EDITOR_VERBOSE; | |
442 | 823 |
140 | 824 if (flags & EDITOR_VERBOSE) |
825 editor_verbose_window(ed, text); | |
442 | 826 |
827 editor_command_next_start(ed); | |
140 | 828 /* errors from editor_command_next_start will be handled via callback */ |
829 return flags & EDITOR_ERROR_MASK; | |
830 } | |
831 | |
766
7148e125bf23
Check for existing editor command using is_valid_editor_command().
zas_
parents:
753
diff
changeset
|
832 gboolean is_valid_editor_command(gint n) |
444 | 833 { |
834 return (n >= 0 && n < GQ_EDITOR_SLOTS | |
730 | 835 && options->editor[n].command |
995 | 836 && strlen(options->editor[n].command) > 0); |
444 | 837 } |
838 | |
140 | 839 gint start_editor_from_filelist_full(gint n, GList *list, EditorCallback cb, gpointer data) |
9 | 840 { |
841 gchar *command; | |
140 | 842 gint error; |
9 | 843 |
444 | 844 if (!list) return FALSE; |
845 if (!is_valid_editor_command(n)) return FALSE; | |
9 | 846 |
730 | 847 command = g_locale_from_utf8(options->editor[n].command, -1, NULL, NULL, NULL); |
848 error = editor_command_start(command, options->editor[n].name, list, cb, data); | |
9 | 849 g_free(command); |
669 | 850 |
670 | 851 if (n < GQ_EDITOR_GENERIC_SLOTS && (error & EDITOR_ERROR_MASK)) |
669 | 852 { |
670 | 853 gchar *text = g_strdup_printf(_("%s\n#%d \"%s\":\n%s"), editor_get_error_str(error), n+1, |
730 | 854 options->editor[n].name, options->editor[n].command); |
669 | 855 |
856 file_util_warning_dialog(_("Invalid editor command"), text, GTK_STOCK_DIALOG_ERROR, NULL); | |
857 g_free(text); | |
858 } | |
859 | |
140 | 860 return error; |
9 | 861 } |
862 | |
140 | 863 gint start_editor_from_filelist(gint n, GList *list) |
864 { | |
865 return start_editor_from_filelist_full(n, list, NULL, NULL); | |
866 } | |
867 | |
868 gint start_editor_from_file_full(gint n, FileData *fd, EditorCallback cb, gpointer data) | |
9 | 869 { |
870 GList *list; | |
140 | 871 gint error; |
9 | 872 |
138 | 873 if (!fd) return FALSE; |
9 | 874 |
138 | 875 list = g_list_append(NULL, fd); |
140 | 876 error = start_editor_from_filelist_full(n, list, cb, data); |
9 | 877 g_list_free(list); |
140 | 878 return error; |
9 | 879 } |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
880 |
140 | 881 gint start_editor_from_file(gint n, FileData *fd) |
136 | 882 { |
140 | 883 return start_editor_from_file_full(n, fd, NULL, NULL); |
136 | 884 } |
885 | |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
886 gint editor_window_flag_set(gint n) |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
887 { |
444 | 888 if (!is_valid_editor_command(n)) return TRUE; |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
889 |
730 | 890 return (editor_command_parse(options->editor[n].command, NULL, NULL) & EDITOR_KEEP_FS); |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
891 } |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
892 |
753 | 893 gint editor_is_filter(gint n) |
894 { | |
895 if (!is_valid_editor_command(n)) return FALSE; | |
896 | |
897 return (editor_command_parse(options->editor[n].command, NULL, NULL) & EDITOR_DEST); | |
898 } | |
899 | |
140 | 900 const gchar *editor_get_error_str(gint flags) |
901 { | |
902 if (flags & EDITOR_ERROR_EMPTY) return _("Editor template is empty."); | |
903 if (flags & EDITOR_ERROR_SYNTAX) return _("Editor template has incorrect syntax."); | |
904 if (flags & EDITOR_ERROR_INCOMPATIBLE) return _("Editor template uses incompatible macros."); | |
905 if (flags & EDITOR_ERROR_NO_FILE) return _("Can't find matching file type."); | |
906 if (flags & EDITOR_ERROR_CANT_EXEC) return _("Can't execute external editor."); | |
907 if (flags & EDITOR_ERROR_STATUS) return _("External editor returned error status."); | |
908 if (flags & EDITOR_ERROR_SKIPPED) return _("File was skipped."); | |
909 return _("Unknown error."); | |
910 } | |
731
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
911 |
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
912 const gchar *editor_get_name(gint n) |
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
913 { |
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
914 if (!is_valid_editor_command(n)) return NULL; |
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
915 |
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
916 if (options->editor[n].name && strlen(options->editor[n].name) > 0) |
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
917 return options->editor[n].name; |
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
918 |
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
919 return _("(unknown)"); |
fa8f7d7396cf
Introduce an helper function that returns the name of an editor.
zas_
parents:
730
diff
changeset
|
920 } |