This source file includes following definitions.
- edit_save_mode_callback
- edit_save_file
- edit_check_newline
- edit_get_save_file_as
- edit_save_cmd
- edit_delete_column_of_text
- edit_block_delete
- edit_get_block
- edit_save_block_to_clip_file
- pipe_mail
- edit_insert_column_of_text
- edit_syntax_onoff_cb
- editcmd_dialog_raw_key_query_cb
- edit_refresh_cmd
- edit_syntax_onoff_cmd
- edit_show_tabs_tws_cmd
- edit_show_margin_cmd
- edit_show_numbers_cmd
- edit_save_mode_cmd
- edit_set_filename
- edit_save_as_cmd
- edit_save_confirm_cmd
- edit_load_cmd
- edit_load_file_from_filename
- edit_load_file_from_history
- edit_load_syntax_file
- edit_load_menu_file
- edit_close_cmd
- edit_block_copy_cmd
- edit_block_move_cmd
- edit_block_delete_cmd
- edit_ok_to_exit
- edit_save_block
- edit_paste_from_history
- edit_copy_to_X_buf_cmd
- edit_cut_to_X_buf_cmd
- edit_paste_from_X_buf_cmd
- edit_goto_cmd
- edit_save_block_cmd
- edit_insert_file_cmd
- edit_sort_cmd
- edit_ext_cmd
- edit_block_process_cmd
- edit_mail_dialog
- edit_select_codepage_cmd
- edit_insert_literal_cmd
- edit_load_forward_cmd
- edit_load_back_cmd
- editcmd_dialog_raw_key_query
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <config.h>
37
38 #include <ctype.h>
39 #include <stdio.h>
40 #include <stdarg.h>
41 #include <sys/types.h>
42 #include <unistd.h>
43 #include <string.h>
44 #include <sys/stat.h>
45 #include <stdlib.h>
46
47 #include "lib/global.h"
48 #include "lib/tty/tty.h"
49 #include "lib/tty/key.h"
50 #include "lib/strutil.h"
51 #include "lib/fileloc.h"
52 #include "lib/lock.h"
53 #include "lib/util.h"
54 #include "lib/vfs/vfs.h"
55 #include "lib/widget.h"
56 #include "lib/event.h"
57 #ifdef HAVE_CHARSET
58 #include "lib/charsets.h"
59 #endif
60
61 #include "src/history.h"
62 #include "src/file_history.h"
63 #ifdef HAVE_CHARSET
64 #include "src/selcodepage.h"
65 #endif
66 #include "src/util.h"
67
68 #include "edit-impl.h"
69 #include "editwidget.h"
70 #include "editsearch.h"
71 #include "etags.h"
72
73
74
75
76 int search_create_bookmark = FALSE;
77
78
79
80 #define space_width 1
81
82 #define TEMP_BUF_LEN 1024
83
84
85
86
87
88
89
90 static unsigned long edit_save_mode_radio_id, edit_save_mode_input_id;
91
92
93
94
95
96 static cb_ret_t
97 edit_save_mode_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
98 {
99 switch (msg)
100 {
101 case MSG_CHANGED_FOCUS:
102 if (sender != NULL && sender->id == edit_save_mode_radio_id)
103 {
104 Widget *ww;
105
106 ww = widget_find_by_id (w, edit_save_mode_input_id);
107 widget_disable (ww, RADIO (sender)->sel != 2);
108 return MSG_HANDLED;
109 }
110 return MSG_NOT_HANDLED;
111
112 default:
113 return dlg_default_callback (w, sender, msg, parm, data);
114 }
115 }
116
117
118
119
120
121
122
123
124
125
126
127
128
129 static int
130 edit_save_file (WEdit * edit, const vfs_path_t * filename_vpath)
131 {
132 char *p;
133 gchar *tmp;
134 off_t filelen = 0;
135 int this_save_mode, rv, fd = -1;
136 vfs_path_t *real_filename_vpath;
137 vfs_path_t *savename_vpath = NULL;
138 const char *start_filename;
139 const vfs_path_element_t *vpath_element;
140 struct stat sb;
141
142 vpath_element = vfs_path_get_by_index (filename_vpath, 0);
143 if (vpath_element == NULL)
144 return 0;
145
146 start_filename = vpath_element->path;
147 if (*start_filename == '\0')
148 return 0;
149
150 if (!IS_PATH_SEP (*start_filename) && edit->dir_vpath != NULL)
151 real_filename_vpath = vfs_path_append_vpath_new (edit->dir_vpath, filename_vpath, NULL);
152 else
153 real_filename_vpath = vfs_path_clone (filename_vpath);
154
155 this_save_mode = edit_options.save_mode;
156 if (this_save_mode != EDIT_QUICK_SAVE)
157 {
158 if (!vfs_file_is_local (real_filename_vpath))
159
160 this_save_mode = EDIT_QUICK_SAVE;
161 else
162 {
163 fd = mc_open (real_filename_vpath, O_RDONLY | O_BINARY);
164 if (fd == -1)
165
166 this_save_mode = EDIT_QUICK_SAVE;
167 }
168
169 if (fd != -1)
170 mc_close (fd);
171 }
172
173 rv = mc_stat (real_filename_vpath, &sb);
174 if (rv == 0)
175 {
176 if (this_save_mode == EDIT_QUICK_SAVE && !edit->skip_detach_prompt && sb.st_nlink > 1)
177 {
178 rv = edit_query_dialog3 (_("Warning"),
179 _("File has hard-links. Detach before saving?"),
180 _("&Yes"), _("&No"), _("&Cancel"));
181 switch (rv)
182 {
183 case 0:
184 this_save_mode = EDIT_SAFE_SAVE;
185 MC_FALLTHROUGH;
186 case 1:
187 edit->skip_detach_prompt = 1;
188 break;
189 default:
190 vfs_path_free (real_filename_vpath, TRUE);
191 return -1;
192 }
193 }
194
195
196 if (edit->stat1.st_mtime != 0 && edit->stat1.st_mtime != sb.st_mtime)
197 {
198
199 query_set_sel (1);
200
201 rv = edit_query_dialog2 (_("Warning"),
202 _("The file has been modified in the meantime. Save anyway?"),
203 _("&Yes"), _("&Cancel"));
204 if (rv != 0)
205 {
206 vfs_path_free (real_filename_vpath, TRUE);
207 return -1;
208 }
209 }
210 }
211
212 if (this_save_mode == EDIT_QUICK_SAVE)
213 savename_vpath = vfs_path_clone (real_filename_vpath);
214 else
215 {
216 char *savedir, *saveprefix;
217
218 savedir = vfs_path_tokens_get (real_filename_vpath, 0, -1);
219 if (savedir == NULL)
220 savedir = g_strdup (".");
221
222
223 saveprefix = mc_build_filename (PATH_SEP_STR, savedir, "cooledit", (char *) NULL);
224 g_free (savedir);
225 fd = mc_mkstemps (&savename_vpath, saveprefix, NULL);
226 g_free (saveprefix);
227 if (savename_vpath == NULL)
228 {
229 vfs_path_free (real_filename_vpath, TRUE);
230 return 0;
231 }
232
233
234
235
236
237 close (fd);
238 }
239
240 (void) mc_chown (savename_vpath, edit->stat1.st_uid, edit->stat1.st_gid);
241 (void) mc_chmod (savename_vpath, edit->stat1.st_mode);
242
243 fd = mc_open (savename_vpath, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, edit->stat1.st_mode);
244 if (fd == -1)
245 goto error_save;
246
247
248 p = edit_get_write_filter (savename_vpath, real_filename_vpath);
249 if (p != NULL)
250 {
251 FILE *file;
252
253 mc_close (fd);
254 file = (FILE *) popen (p, "w");
255
256 if (file != NULL)
257 {
258 filelen = edit_write_stream (edit, file);
259 #if 1
260 pclose (file);
261 #else
262 if (pclose (file) != 0)
263 {
264 tmp = g_strdup_printf (_("Error writing to pipe: %s"), p);
265 edit_error_dialog (_("Error"), tmp);
266 g_free (tmp);
267 g_free (p);
268 goto error_save;
269 }
270 #endif
271 }
272 else
273 {
274 tmp = g_strdup_printf (_("Cannot open pipe for writing: %s"), p);
275 edit_error_dialog (_("Error"), get_sys_error (tmp));
276 g_free (p);
277 g_free (tmp);
278 goto error_save;
279 }
280 g_free (p);
281 }
282 else if (edit->lb == LB_ASIS)
283 {
284 filelen = edit_buffer_write_file (&edit->buffer, fd);
285
286 if (filelen != edit->buffer.size)
287 {
288 mc_close (fd);
289 goto error_save;
290 }
291
292 if (mc_close (fd) != 0)
293 goto error_save;
294
295
296 if (mc_stat (savename_vpath, &edit->stat1) == -1)
297 goto error_save;
298 }
299 else
300 {
301 FILE *file;
302 const char *savename;
303
304 mc_close (fd);
305
306 savename = vfs_path_get_last_path_str (savename_vpath);
307 file = (FILE *) fopen (savename, "w");
308 if (file != NULL)
309 {
310 filelen = edit_write_stream (edit, file);
311 fclose (file);
312 }
313 else
314 {
315 char *msg;
316
317 msg = g_strdup_printf (_("Cannot open file for writing: %s"), savename);
318 edit_error_dialog (_("Error"), msg);
319 g_free (msg);
320 goto error_save;
321 }
322 }
323
324 if (filelen != edit->buffer.size)
325 goto error_save;
326
327 if (this_save_mode == EDIT_DO_BACKUP)
328 {
329 char *tmp_store_filename;
330 vfs_path_element_t *last_vpath_element;
331 vfs_path_t *tmp_vpath;
332 gboolean ok;
333
334 g_assert (edit_options.backup_ext != NULL);
335
336
337 tmp_vpath = vfs_path_clone (real_filename_vpath);
338 last_vpath_element = (vfs_path_element_t *) vfs_path_get_by_index (tmp_vpath, -1);
339 tmp_store_filename = last_vpath_element->path;
340 last_vpath_element->path =
341 g_strdup_printf ("%s%s", tmp_store_filename, edit_options.backup_ext);
342 g_free (tmp_store_filename);
343
344 ok = (mc_rename (real_filename_vpath, tmp_vpath) != -1);
345 vfs_path_free (tmp_vpath, TRUE);
346 if (!ok)
347 goto error_save;
348 }
349
350 if (this_save_mode != EDIT_QUICK_SAVE && mc_rename (savename_vpath, real_filename_vpath) == -1)
351 goto error_save;
352
353 vfs_path_free (real_filename_vpath, TRUE);
354 vfs_path_free (savename_vpath, TRUE);
355 return 1;
356 error_save:
357
358
359
360
361 vfs_path_free (real_filename_vpath, TRUE);
362 vfs_path_free (savename_vpath, TRUE);
363 return 0;
364 }
365
366
367
368 static gboolean
369 edit_check_newline (const edit_buffer_t * buf)
370 {
371 return !(edit_options.check_nl_at_eof && buf->size > 0
372 && edit_buffer_get_byte (buf, buf->size - 1) != '\n'
373 && edit_query_dialog2 (_("Warning"),
374 _("The file you are saving does not end with a newline."),
375 _("C&ontinue"), _("&Cancel")) != 0);
376 }
377
378
379
380 static vfs_path_t *
381 edit_get_save_file_as (WEdit * edit)
382 {
383 static LineBreaks cur_lb = LB_ASIS;
384 char *filename_res;
385 vfs_path_t *ret_vpath = NULL;
386
387 const char *lb_names[LB_NAMES] = {
388 N_("&Do not change"),
389 N_("&Unix format (LF)"),
390 N_("&Windows/DOS format (CR LF)"),
391 N_("&Macintosh format (CR)")
392 };
393
394 quick_widget_t quick_widgets[] = {
395
396 QUICK_LABELED_INPUT (N_("Enter file name:"), input_label_above,
397 vfs_path_as_str (edit->filename_vpath), "save-as",
398 &filename_res, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
399 QUICK_SEPARATOR (TRUE),
400 QUICK_LABEL (N_("Change line breaks to:"), NULL),
401 QUICK_RADIO (LB_NAMES, lb_names, (int *) &cur_lb, NULL),
402 QUICK_BUTTONS_OK_CANCEL,
403 QUICK_END
404
405 };
406
407 WRect r = { -1, -1, 0, 64 };
408
409 quick_dialog_t qdlg = {
410 r, N_("Save As"), "[Save File As]",
411 quick_widgets, NULL, NULL
412 };
413
414 if (quick_dialog (&qdlg) != B_CANCEL)
415 {
416 char *fname;
417
418 edit->lb = cur_lb;
419 fname = tilde_expand (filename_res);
420 g_free (filename_res);
421 ret_vpath = vfs_path_from_str (fname);
422 g_free (fname);
423 }
424
425 return ret_vpath;
426 }
427
428
429
430
431
432 static gboolean
433 edit_save_cmd (WEdit * edit)
434 {
435 int res, save_lock = 0;
436
437 if (!edit->locked && !edit->delete_file)
438 save_lock = lock_file (edit->filename_vpath);
439 res = edit_save_file (edit, edit->filename_vpath);
440
441
442 if ((res > 0 && edit->locked) || save_lock)
443 edit->locked = unlock_file (edit->filename_vpath);
444
445
446 if (res == 0)
447 return edit_save_as_cmd (edit);
448
449 if (res > 0)
450 {
451 edit->delete_file = 0;
452 edit->modified = 0;
453 }
454
455 edit->force |= REDRAW_COMPLETELY;
456
457 return TRUE;
458 }
459
460
461
462 static void
463 edit_delete_column_of_text (WEdit * edit, off_t m1, off_t m2)
464 {
465 off_t n;
466 off_t r;
467 long b, c, d;
468
469 n = edit_buffer_get_forward_offset (&edit->buffer, m1, 0, m2) + 1;
470 r = edit_buffer_get_bol (&edit->buffer, m1);
471 c = (long) edit_move_forward3 (edit, r, 0, m1);
472 r = edit_buffer_get_bol (&edit->buffer, m2);
473 d = (long) edit_move_forward3 (edit, r, 0, m2);
474 b = MAX (MIN (c, d), MIN (edit->column1, edit->column2));
475 c = MAX (c, MAX (edit->column1, edit->column2));
476
477 while (n-- != 0)
478 {
479 off_t p, q;
480
481 r = edit_buffer_get_current_bol (&edit->buffer);
482 p = edit_move_forward3 (edit, r, b, 0);
483 q = edit_move_forward3 (edit, r, c, 0);
484 p = MAX (p, m1);
485 q = MIN (q, m2);
486 edit_cursor_move (edit, p - edit->buffer.curs1);
487
488 for (; q > p; q--)
489 if (edit_buffer_get_current_byte (&edit->buffer) != '\n')
490 edit_delete (edit, TRUE);
491
492
493 if (n != 0)
494 {
495 r = edit_buffer_get_forward_offset (&edit->buffer, edit->buffer.curs1, 1, 0);
496 edit_cursor_move (edit, r - edit->buffer.curs1);
497 }
498 }
499 }
500
501
502
503
504 static gboolean
505 edit_block_delete (WEdit * edit, off_t start_mark, off_t end_mark)
506 {
507 off_t curs_pos;
508 long curs_line, c1, c2;
509
510 if (edit->column_highlight && edit->mark2 < 0)
511 edit_mark_cmd (edit, FALSE);
512
513
514 if ((end_mark - start_mark) > max_undo / 2 &&
515 edit_query_dialog2 (_("Warning"),
516 ("Block is large, you may not be able to undo this action"),
517 _("C&ontinue"), _("&Cancel")) != 0)
518 return FALSE;
519
520 c1 = MIN (edit->column1, edit->column2);
521 c2 = MAX (edit->column1, edit->column2);
522 edit->column1 = c1;
523 edit->column2 = c2;
524
525 edit_push_markers (edit);
526
527 curs_line = edit->buffer.curs_line;
528
529 curs_pos = edit->curs_col + edit->over_col;
530
531
532 edit_cursor_move (edit, start_mark - edit->buffer.curs1);
533 edit_scroll_screen_over_cursor (edit);
534
535 if (start_mark < end_mark)
536 {
537 if (edit->column_highlight)
538 {
539 off_t b, e;
540 off_t line_width;
541
542 if (edit->mark2 < 0)
543 edit_mark_cmd (edit, FALSE);
544 edit_delete_column_of_text (edit, start_mark, end_mark);
545
546 edit_move_to_line (edit, curs_line);
547
548 b = edit_buffer_get_current_bol (&edit->buffer);
549 e = edit_buffer_get_current_eol (&edit->buffer);
550 line_width = edit_move_forward3 (edit, b, 0, e);
551 if (edit_options.cursor_beyond_eol && curs_pos > line_width)
552 edit->over_col = curs_pos - line_width;
553 }
554 else
555 {
556 off_t count;
557
558 for (count = start_mark; count < end_mark; count++)
559 edit_delete (edit, TRUE);
560 }
561 }
562
563 edit_set_markers (edit, 0, 0, 0, 0);
564 edit->force |= REDRAW_PAGE;
565
566 return TRUE;
567 }
568
569
570
571
572 static unsigned char *
573 edit_get_block (WEdit * edit, off_t start, off_t finish, off_t * l)
574 {
575 unsigned char *s, *r;
576
577 r = s = g_malloc0 (finish - start + 1);
578
579 if (edit->column_highlight)
580 {
581 *l = 0;
582
583
584 for (; start < finish; start++)
585 {
586 int c;
587 off_t x;
588
589 x = edit_buffer_get_bol (&edit->buffer, start);
590 x = edit_move_forward3 (edit, x, 0, start);
591 c = edit_buffer_get_byte (&edit->buffer, start);
592 if ((x >= edit->column1 && x < edit->column2)
593 || (x >= edit->column2 && x < edit->column1) || c == '\n')
594 {
595 *s++ = c;
596 (*l)++;
597 }
598 }
599 }
600 else
601 {
602 *l = finish - start;
603
604 for (; start < finish; start++)
605 *s++ = edit_buffer_get_byte (&edit->buffer, start);
606 }
607
608 *s = '\0';
609
610 return r;
611 }
612
613
614
615
616 static gboolean
617 edit_save_block_to_clip_file (WEdit * edit, off_t start, off_t finish)
618 {
619 gboolean ret;
620 gchar *tmp;
621
622 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
623 ret = edit_save_block (edit, tmp, start, finish);
624 g_free (tmp);
625
626 return ret;
627 }
628
629
630
631 static void
632 pipe_mail (const edit_buffer_t * buf, char *to, char *subject, char *cc)
633 {
634 FILE *p = 0;
635 char *s = NULL;
636
637 to = name_quote (to, FALSE);
638 if (to != NULL)
639 {
640 subject = name_quote (subject, FALSE);
641 if (subject != NULL)
642 {
643 cc = name_quote (cc, FALSE);
644 if (cc == NULL)
645 s = g_strdup_printf ("mail -s %s %s", subject, to);
646 else
647 {
648 s = g_strdup_printf ("mail -s %s -c %s %s", subject, cc, to);
649 g_free (cc);
650 }
651
652 g_free (subject);
653 }
654
655 g_free (to);
656 }
657
658 if (s != NULL)
659 {
660 p = popen (s, "w");
661 g_free (s);
662 }
663
664 if (p != NULL)
665 {
666 off_t i;
667
668 for (i = 0; i < buf->size; i++)
669 if (fputc (edit_buffer_get_byte (buf, i), p) < 0)
670 break;
671 pclose (p);
672 }
673 }
674
675
676
677 static void
678 edit_insert_column_of_text (WEdit * edit, unsigned char *data, off_t size, long width,
679 off_t * start_pos, off_t * end_pos, long *col1, long *col2)
680 {
681 off_t i, cursor;
682 long col;
683
684 cursor = edit->buffer.curs1;
685 col = edit_get_col (edit);
686
687 for (i = 0; i < size; i++)
688 {
689 if (data[i] != '\n')
690 edit_insert (edit, data[i]);
691 else
692 {
693 long l;
694 off_t p;
695
696 if (edit_buffer_get_current_byte (&edit->buffer) != '\n')
697 {
698 for (l = width - (edit_get_col (edit) - col); l > 0; l -= space_width)
699 edit_insert (edit, ' ');
700 }
701 for (p = edit->buffer.curs1;; p++)
702 {
703 if (p == edit->buffer.size)
704 {
705 edit_cursor_move (edit, edit->buffer.size - edit->buffer.curs1);
706 edit_insert_ahead (edit, '\n');
707 p++;
708 break;
709 }
710 if (edit_buffer_get_byte (&edit->buffer, p) == '\n')
711 {
712 p++;
713 break;
714 }
715 }
716 edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0) - edit->buffer.curs1);
717
718 for (l = col - edit_get_col (edit); l >= space_width; l -= space_width)
719 edit_insert (edit, ' ');
720 }
721 }
722
723 *col1 = col;
724 *col2 = col + width;
725 *start_pos = cursor;
726 *end_pos = edit->buffer.curs1;
727 edit_cursor_move (edit, cursor - edit->buffer.curs1);
728 }
729
730
731
732
733
734
735
736
737
738
739 static void
740 edit_syntax_onoff_cb (void *data, void *user_data)
741 {
742 (void) user_data;
743
744 if (edit_widget_is_editor (CONST_WIDGET (data)))
745 {
746 WEdit *edit = EDIT (data);
747
748 if (edit_options.syntax_highlighting)
749 edit_load_syntax (edit, NULL, edit->syntax_type);
750 edit->force |= REDRAW_PAGE;
751 }
752 }
753
754
755
756 static cb_ret_t
757 editcmd_dialog_raw_key_query_cb (Widget * w, Widget * sender, widget_msg_t msg, int parm,
758 void *data)
759 {
760 WDialog *h = DIALOG (w);
761
762 switch (msg)
763 {
764 case MSG_KEY:
765 h->ret_value = parm;
766 dlg_close (h);
767 return MSG_HANDLED;
768 default:
769 return dlg_default_callback (w, sender, msg, parm, data);
770 }
771 }
772
773
774
775
776
777 void
778 edit_refresh_cmd (void)
779 {
780 tty_clear_screen ();
781 repaint_screen ();
782 tty_keypad (TRUE);
783 }
784
785
786
787
788
789
790
791
792 void
793 edit_syntax_onoff_cmd (WDialog * h)
794 {
795 edit_options.syntax_highlighting = !edit_options.syntax_highlighting;
796 g_list_foreach (GROUP (h)->widgets, edit_syntax_onoff_cb, NULL);
797 widget_draw (WIDGET (h));
798 }
799
800
801
802
803
804
805
806
807 void
808 edit_show_tabs_tws_cmd (WDialog * h)
809 {
810 enable_show_tabs_tws = !enable_show_tabs_tws;
811 widget_draw (WIDGET (h));
812 }
813
814
815
816
817
818
819
820
821 void
822 edit_show_margin_cmd (WDialog * h)
823 {
824 edit_options.show_right_margin = !edit_options.show_right_margin;
825 widget_draw (WIDGET (h));
826 }
827
828
829
830
831
832
833
834
835 void
836 edit_show_numbers_cmd (WDialog * h)
837 {
838 edit_options.line_state = !edit_options.line_state;
839 edit_options.line_state_width = edit_options.line_state ? LINE_STATE_WIDTH : 0;
840 widget_draw (WIDGET (h));
841 }
842
843
844
845 void
846 edit_save_mode_cmd (void)
847 {
848 char *str_result = NULL;
849
850 const char *str[] = {
851 N_("&Quick save"),
852 N_("&Safe save"),
853 N_("&Do backups with following extension:")
854 };
855
856 #ifdef ENABLE_NLS
857 size_t i;
858
859 for (i = 0; i < 3; i++)
860 str[i] = _(str[i]);
861 #endif
862
863 g_assert (edit_options.backup_ext != NULL);
864
865 {
866 quick_widget_t quick_widgets[] = {
867
868 QUICK_RADIO (3, str, &edit_options.save_mode, &edit_save_mode_radio_id),
869 QUICK_INPUT (edit_options.backup_ext, "edit-backup-ext", &str_result,
870 &edit_save_mode_input_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
871 QUICK_SEPARATOR (TRUE),
872 QUICK_CHECKBOX (N_("Check &POSIX new line"), &edit_options.check_nl_at_eof, NULL),
873 QUICK_BUTTONS_OK_CANCEL,
874 QUICK_END
875
876 };
877
878 WRect r = { -1, -1, 0, 38 };
879
880 quick_dialog_t qdlg = {
881 r, N_("Edit Save Mode"), "[Edit Save Mode]",
882 quick_widgets, edit_save_mode_callback, NULL
883 };
884
885 if (quick_dialog (&qdlg) != B_CANCEL)
886 {
887 g_free (edit_options.backup_ext);
888 edit_options.backup_ext = str_result;
889 }
890 }
891 }
892
893
894
895 void
896 edit_set_filename (WEdit * edit, const vfs_path_t * name_vpath)
897 {
898 vfs_path_free (edit->filename_vpath, TRUE);
899 edit->filename_vpath = vfs_path_clone (name_vpath);
900
901 if (edit->dir_vpath == NULL)
902 edit->dir_vpath = vfs_path_clone (vfs_get_raw_current_dir ());
903 }
904
905
906
907
908
909 gboolean
910 edit_save_as_cmd (WEdit * edit)
911 {
912
913 vfs_path_t *exp_vpath;
914 int save_lock = 0;
915 gboolean different_filename = FALSE;
916 gboolean ret = FALSE;
917
918 if (!edit_check_newline (&edit->buffer))
919 return FALSE;
920
921 exp_vpath = edit_get_save_file_as (edit);
922 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
923
924 if (exp_vpath != NULL && vfs_path_len (exp_vpath) != 0)
925 {
926 int rv;
927
928 if (!vfs_path_equal (edit->filename_vpath, exp_vpath))
929 {
930 int file;
931 struct stat sb;
932
933 if (mc_stat (exp_vpath, &sb) == 0 && !S_ISREG (sb.st_mode))
934 {
935 edit_error_dialog (_("Save as"),
936 get_sys_error (_
937 ("Cannot save: destination is not a regular file")));
938 goto ret;
939 }
940
941 different_filename = TRUE;
942 file = mc_open (exp_vpath, O_RDONLY | O_BINARY);
943
944 if (file == -1)
945 edit->stat1.st_mode |= S_IWUSR;
946 else
947 {
948
949 mc_close (file);
950
951 if (edit_query_dialog2
952 (_("Warning"),
953 _("A file already exists with this name"), _("&Overwrite"), _("&Cancel")))
954 goto ret;
955 }
956
957 save_lock = lock_file (exp_vpath);
958 }
959 else if (!edit->locked && !edit->delete_file)
960
961 save_lock = lock_file (exp_vpath);
962
963 if (different_filename)
964
965
966 edit->stat1.st_mode |= S_IWUSR;
967
968 rv = edit_save_file (edit, exp_vpath);
969 switch (rv)
970 {
971 case 1:
972
973 if (different_filename)
974 {
975 if (save_lock)
976 unlock_file (exp_vpath);
977 if (edit->locked)
978 edit->locked = unlock_file (edit->filename_vpath);
979 }
980 else if (edit->locked || save_lock)
981 edit->locked = unlock_file (edit->filename_vpath);
982
983 edit_set_filename (edit, exp_vpath);
984 if (edit->lb != LB_ASIS)
985 edit_reload (edit, exp_vpath);
986 edit->modified = 0;
987 edit->delete_file = 0;
988 if (different_filename)
989 edit_load_syntax (edit, NULL, edit->syntax_type);
990 ret = TRUE;
991 break;
992
993 default:
994 edit_error_dialog (_("Save as"), get_sys_error (_("Cannot save file")));
995 MC_FALLTHROUGH;
996
997 case -1:
998
999 if (save_lock)
1000 unlock_file (exp_vpath);
1001 break;
1002 }
1003 }
1004
1005 ret:
1006 vfs_path_free (exp_vpath, TRUE);
1007 edit->force |= REDRAW_COMPLETELY;
1008 return ret;
1009 }
1010
1011
1012
1013
1014 gboolean
1015 edit_save_confirm_cmd (WEdit * edit)
1016 {
1017 if (edit->filename_vpath == NULL)
1018 return edit_save_as_cmd (edit);
1019
1020 if (!edit_check_newline (&edit->buffer))
1021 return FALSE;
1022
1023 if (edit_options.confirm_save)
1024 {
1025 char *f;
1026 gboolean ok;
1027
1028 f = g_strdup_printf (_("Confirm save file: \"%s\""),
1029 vfs_path_as_str (edit->filename_vpath));
1030 ok = (edit_query_dialog2 (_("Save file"), f, _("&Save"), _("&Cancel")) == 0);
1031 g_free (f);
1032 if (!ok)
1033 return FALSE;
1034 }
1035
1036 return edit_save_cmd (edit);
1037 }
1038
1039
1040
1041
1042
1043
1044
1045
1046 gboolean
1047 edit_load_cmd (WDialog * h)
1048 {
1049 char *exp;
1050 gboolean ret = TRUE;
1051
1052 exp = input_expand_dialog (_("Load"), _("Enter file name:"),
1053 MC_HISTORY_EDIT_LOAD, INPUT_LAST_TEXT,
1054 INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD);
1055
1056 if (exp != NULL && *exp != '\0')
1057 {
1058 vfs_path_t *exp_vpath;
1059
1060 exp_vpath = vfs_path_from_str (exp);
1061 ret = edit_load_file_from_filename (h, exp_vpath, 0);
1062 vfs_path_free (exp_vpath, TRUE);
1063 }
1064
1065 g_free (exp);
1066
1067 return ret;
1068 }
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 gboolean
1082 edit_load_file_from_filename (WDialog * h, const vfs_path_t * vpath, long line)
1083 {
1084 WRect r = WIDGET (h)->rect;
1085
1086 rect_grow (&r, -1, 0);
1087
1088 return edit_add_window (h, &r, vpath, line);
1089 }
1090
1091
1092
1093
1094
1095
1096
1097
1098 gboolean
1099 edit_load_file_from_history (WDialog * h)
1100 {
1101 char *exp;
1102 int action;
1103 gboolean ret = TRUE;
1104
1105 exp = show_file_history (CONST_WIDGET (h), &action);
1106 if (exp != NULL && (action == CK_Edit || action == CK_Enter))
1107 {
1108 vfs_path_t *exp_vpath;
1109
1110 exp_vpath = vfs_path_from_str (exp);
1111 ret = edit_load_file_from_filename (h, exp_vpath, 0);
1112 vfs_path_free (exp_vpath, TRUE);
1113 }
1114
1115 g_free (exp);
1116
1117 return ret;
1118 }
1119
1120
1121
1122
1123
1124
1125
1126
1127 gboolean
1128 edit_load_syntax_file (WDialog * h)
1129 {
1130 vfs_path_t *extdir_vpath;
1131 int dir = 0;
1132 gboolean ret = FALSE;
1133
1134 if (geteuid () == 0)
1135 dir = query_dialog (_("Syntax file edit"),
1136 _("Which syntax file you want to edit?"), D_NORMAL, 2,
1137 _("&User"), _("&System wide"));
1138
1139 extdir_vpath =
1140 vfs_path_build_filename (mc_global.sysconfig_dir, EDIT_SYNTAX_FILE, (char *) NULL);
1141 if (!exist_file (vfs_path_get_last_path_str (extdir_vpath)))
1142 {
1143 vfs_path_free (extdir_vpath, TRUE);
1144 extdir_vpath =
1145 vfs_path_build_filename (mc_global.share_data_dir, EDIT_SYNTAX_FILE, (char *) NULL);
1146 }
1147
1148 if (dir == 0)
1149 {
1150 vfs_path_t *user_syntax_file_vpath;
1151
1152 user_syntax_file_vpath = mc_config_get_full_vpath (EDIT_SYNTAX_FILE);
1153 check_for_default (extdir_vpath, user_syntax_file_vpath);
1154 ret = edit_load_file_from_filename (h, user_syntax_file_vpath, 0);
1155 vfs_path_free (user_syntax_file_vpath, TRUE);
1156 }
1157 else if (dir == 1)
1158 ret = edit_load_file_from_filename (h, extdir_vpath, 0);
1159
1160 vfs_path_free (extdir_vpath, TRUE);
1161
1162 return ret;
1163 }
1164
1165
1166
1167
1168
1169
1170
1171
1172 gboolean
1173 edit_load_menu_file (WDialog * h)
1174 {
1175 vfs_path_t *buffer_vpath;
1176 vfs_path_t *menufile_vpath;
1177 int dir;
1178 gboolean ret;
1179
1180 query_set_sel (1);
1181 dir = query_dialog (_("Menu edit"),
1182 _("Which menu file do you want to edit?"), D_NORMAL,
1183 geteuid () != 0 ? 2 : 3, _("&Local"), _("&User"), _("&System wide"));
1184
1185 menufile_vpath =
1186 vfs_path_build_filename (mc_global.sysconfig_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1187 if (!exist_file (vfs_path_get_last_path_str (menufile_vpath)))
1188 {
1189 vfs_path_free (menufile_vpath, TRUE);
1190 menufile_vpath =
1191 vfs_path_build_filename (mc_global.share_data_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1192 }
1193
1194 switch (dir)
1195 {
1196 case 0:
1197 buffer_vpath = vfs_path_from_str (EDIT_LOCAL_MENU);
1198 check_for_default (menufile_vpath, buffer_vpath);
1199 chmod (vfs_path_get_last_path_str (buffer_vpath), 0600);
1200 break;
1201
1202 case 1:
1203 buffer_vpath = mc_config_get_full_vpath (EDIT_HOME_MENU);
1204 check_for_default (menufile_vpath, buffer_vpath);
1205 break;
1206
1207 case 2:
1208 buffer_vpath =
1209 vfs_path_build_filename (mc_global.sysconfig_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1210 if (!exist_file (vfs_path_get_last_path_str (buffer_vpath)))
1211 {
1212 vfs_path_free (buffer_vpath, TRUE);
1213 buffer_vpath =
1214 vfs_path_build_filename (mc_global.share_data_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1215 }
1216 break;
1217
1218 default:
1219 vfs_path_free (menufile_vpath, TRUE);
1220 return FALSE;
1221 }
1222
1223 ret = edit_load_file_from_filename (h, buffer_vpath, 0);
1224
1225 vfs_path_free (buffer_vpath, TRUE);
1226 vfs_path_free (menufile_vpath, TRUE);
1227
1228 return ret;
1229 }
1230
1231
1232
1233
1234
1235
1236
1237
1238 gboolean
1239 edit_close_cmd (WEdit * edit)
1240 {
1241 gboolean ret;
1242
1243 ret = (edit != NULL) && edit_ok_to_exit (edit);
1244
1245 if (ret)
1246 {
1247 Widget *w = WIDGET (edit);
1248 WGroup *g = w->owner;
1249
1250 if (edit->locked != 0)
1251 unlock_file (edit->filename_vpath);
1252
1253 group_remove_widget (w);
1254 widget_destroy (w);
1255
1256 if (edit_widget_is_editor (CONST_WIDGET (g->current->data)))
1257 edit = EDIT (g->current->data);
1258 else
1259 {
1260 edit = edit_find_editor (DIALOG (g));
1261 if (edit != NULL)
1262 widget_select (WIDGET (edit));
1263 }
1264 }
1265
1266 if (edit != NULL)
1267 edit->force |= REDRAW_COMPLETELY;
1268
1269 return ret;
1270 }
1271
1272
1273
1274 void
1275 edit_block_copy_cmd (WEdit * edit)
1276 {
1277 off_t start_mark, end_mark, current = edit->buffer.curs1;
1278 off_t mark1 = 0, mark2 = 0;
1279 long c1 = 0, c2 = 0;
1280 off_t size;
1281 unsigned char *copy_buf;
1282
1283 edit_update_curs_col (edit);
1284 if (!eval_marks (edit, &start_mark, &end_mark))
1285 return;
1286
1287 copy_buf = edit_get_block (edit, start_mark, end_mark, &size);
1288
1289
1290
1291 edit_push_markers (edit);
1292
1293 if (edit->column_highlight)
1294 {
1295 long col_delta;
1296
1297 col_delta = labs (edit->column2 - edit->column1);
1298 edit_insert_column_of_text (edit, copy_buf, size, col_delta, &mark1, &mark2, &c1, &c2);
1299 }
1300 else
1301 {
1302 int size_orig = size;
1303
1304 while (size-- != 0)
1305 edit_insert_ahead (edit, copy_buf[size]);
1306
1307
1308 if (edit_options.cursor_after_inserted_block)
1309 edit_cursor_move (edit, size_orig);
1310 }
1311
1312 g_free (copy_buf);
1313 edit_scroll_screen_over_cursor (edit);
1314
1315 if (edit->column_highlight)
1316 edit_set_markers (edit, edit->buffer.curs1, mark2, c1, c2);
1317 else if (start_mark < current && end_mark > current)
1318 edit_set_markers (edit, start_mark, end_mark + end_mark - start_mark, 0, 0);
1319
1320 edit->force |= REDRAW_PAGE;
1321 }
1322
1323
1324
1325
1326 void
1327 edit_block_move_cmd (WEdit * edit)
1328 {
1329 off_t current;
1330 unsigned char *copy_buf = NULL;
1331 off_t start_mark, end_mark;
1332
1333 if (!eval_marks (edit, &start_mark, &end_mark))
1334 return;
1335
1336 if (!edit->column_highlight && edit->buffer.curs1 > start_mark && edit->buffer.curs1 < end_mark)
1337 return;
1338
1339 if (edit->mark2 < 0)
1340 edit_mark_cmd (edit, FALSE);
1341 edit_push_markers (edit);
1342
1343 if (edit->column_highlight)
1344 {
1345 off_t mark1, mark2;
1346 off_t size;
1347 long c1, c2, b_width;
1348 long x, x2;
1349 off_t b1, b2;
1350
1351 c1 = MIN (edit->column1, edit->column2);
1352 c2 = MAX (edit->column1, edit->column2);
1353 b_width = c2 - c1;
1354
1355 edit_update_curs_col (edit);
1356
1357 x = edit->curs_col;
1358 x2 = x + edit->over_col;
1359
1360
1361 b1 = edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1);
1362 b2 = edit_buffer_get_eol (&edit->buffer, start_mark);
1363 if (b1 == b2 && x2 > c1 && x2 <= c2)
1364 return;
1365
1366 if (edit->buffer.curs1 > start_mark
1367 && edit->buffer.curs1 < edit_buffer_get_eol (&edit->buffer, end_mark))
1368 {
1369 if (x > c2)
1370 x -= b_width;
1371 else if (x > c1 && x <= c2)
1372 x = c1;
1373 }
1374
1375 copy_buf = edit_get_block (edit, start_mark, end_mark, &size);
1376
1377
1378 edit_block_delete_cmd (edit);
1379
1380 edit->over_col = MAX (0, edit->over_col - b_width);
1381
1382 b1 = edit_buffer_get_current_bol (&edit->buffer);
1383 current = edit_move_forward3 (edit, b1, x, 0);
1384 edit_cursor_move (edit, current - edit->buffer.curs1);
1385 edit_scroll_screen_over_cursor (edit);
1386
1387
1388 if (edit_options.cursor_beyond_eol && edit->over_col > 0)
1389 edit_insert_over (edit);
1390
1391 edit_insert_column_of_text (edit, copy_buf, size, b_width, &mark1, &mark2, &c1, &c2);
1392 edit_set_markers (edit, mark1, mark2, c1, c2);
1393 }
1394 else
1395 {
1396 off_t count, count_orig;
1397 off_t x;
1398
1399 current = edit->buffer.curs1;
1400 copy_buf = g_malloc0 (end_mark - start_mark);
1401 edit_cursor_move (edit, start_mark - edit->buffer.curs1);
1402 edit_scroll_screen_over_cursor (edit);
1403
1404 for (count = start_mark; count < end_mark; count++)
1405 copy_buf[end_mark - count - 1] = edit_delete (edit, TRUE);
1406
1407 edit_scroll_screen_over_cursor (edit);
1408 x = current > edit->buffer.curs1 ? end_mark - start_mark : 0;
1409 edit_cursor_move (edit, current - edit->buffer.curs1 - x);
1410 edit_scroll_screen_over_cursor (edit);
1411 count_orig = count;
1412 while (count-- > start_mark)
1413 edit_insert_ahead (edit, copy_buf[end_mark - count - 1]);
1414
1415 edit_set_markers (edit, edit->buffer.curs1, edit->buffer.curs1 + end_mark - start_mark, 0,
1416 0);
1417
1418
1419 if (edit_options.cursor_after_inserted_block)
1420 edit_cursor_move (edit, count_orig - start_mark);
1421 }
1422
1423 edit_scroll_screen_over_cursor (edit);
1424 g_free (copy_buf);
1425 edit->force |= REDRAW_PAGE;
1426 }
1427
1428
1429
1430
1431 gboolean
1432 edit_block_delete_cmd (WEdit * edit)
1433 {
1434 off_t start_mark, end_mark;
1435
1436 if (eval_marks (edit, &start_mark, &end_mark))
1437 return edit_block_delete (edit, start_mark, end_mark);
1438
1439 edit_delete_line (edit);
1440
1441 return TRUE;
1442 }
1443
1444
1445
1446
1447
1448
1449
1450
1451 gboolean
1452 edit_ok_to_exit (WEdit * edit)
1453 {
1454 const char *fname = N_("[NoName]");
1455 char *msg;
1456 int act;
1457
1458 if (!edit->modified)
1459 return TRUE;
1460
1461 if (edit->filename_vpath != NULL)
1462 fname = vfs_path_as_str (edit->filename_vpath);
1463 #ifdef ENABLE_NLS
1464 else
1465 fname = _(fname);
1466 #endif
1467
1468 if (!mc_global.midnight_shutdown)
1469 {
1470 query_set_sel (2);
1471
1472 msg = g_strdup_printf (_("File %s was modified.\nSave before close?"), fname);
1473 act = edit_query_dialog3 (_("Close file"), msg, _("&Yes"), _("&No"), _("&Cancel"));
1474 }
1475 else
1476 {
1477 msg = g_strdup_printf (_("Midnight Commander is being shut down.\nSave modified file %s?"),
1478 fname);
1479 act = edit_query_dialog2 (_("Quit"), msg, _("&Yes"), _("&No"));
1480
1481
1482 if (act == -1)
1483 act = 1;
1484 }
1485
1486 g_free (msg);
1487
1488 switch (act)
1489 {
1490 case 0:
1491 if (!mc_global.midnight_shutdown && !edit_check_newline (&edit->buffer))
1492 return FALSE;
1493 edit_push_markers (edit);
1494 edit_set_markers (edit, 0, 0, 0, 0);
1495 if (!edit_save_cmd (edit) || mc_global.midnight_shutdown)
1496 return mc_global.midnight_shutdown;
1497 break;
1498 case 1:
1499 default:
1500 break;
1501 case 2:
1502 case -1:
1503 return FALSE;
1504 }
1505
1506 return TRUE;
1507 }
1508
1509
1510
1511
1512 gboolean
1513 edit_save_block (WEdit * edit, const char *filename, off_t start, off_t finish)
1514 {
1515 int file;
1516 off_t len = 1;
1517 vfs_path_t *vpath;
1518
1519 vpath = vfs_path_from_str (filename);
1520 file = mc_open (vpath, O_CREAT | O_WRONLY | O_TRUNC,
1521 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_BINARY);
1522 vfs_path_free (vpath, TRUE);
1523 if (file == -1)
1524 return FALSE;
1525
1526 if (edit->column_highlight)
1527 {
1528 int r;
1529
1530 r = mc_write (file, VERTICAL_MAGIC, sizeof (VERTICAL_MAGIC));
1531 if (r > 0)
1532 {
1533 unsigned char *block, *p;
1534
1535 p = block = edit_get_block (edit, start, finish, &len);
1536 while (len != 0)
1537 {
1538 r = mc_write (file, p, len);
1539 if (r < 0)
1540 break;
1541 p += r;
1542 len -= r;
1543 }
1544 g_free (block);
1545 }
1546 }
1547 else
1548 {
1549 unsigned char *buf;
1550 off_t i = start;
1551
1552 len = finish - start;
1553 buf = g_malloc0 (TEMP_BUF_LEN);
1554 while (start != finish)
1555 {
1556 off_t end;
1557
1558 end = MIN (finish, start + TEMP_BUF_LEN);
1559 for (; i < end; i++)
1560 buf[i - start] = edit_buffer_get_byte (&edit->buffer, i);
1561 len -= mc_write (file, (char *) buf, end - start);
1562 start = end;
1563 }
1564 g_free (buf);
1565 }
1566 mc_close (file);
1567
1568 return (len == 0);
1569 }
1570
1571
1572
1573 void
1574 edit_paste_from_history (WEdit * edit)
1575 {
1576 (void) edit;
1577 edit_error_dialog (_("Error"), _("This function is not implemented"));
1578 }
1579
1580
1581
1582 gboolean
1583 edit_copy_to_X_buf_cmd (WEdit * edit)
1584 {
1585 off_t start_mark, end_mark;
1586
1587 if (!eval_marks (edit, &start_mark, &end_mark))
1588 return TRUE;
1589
1590 if (!edit_save_block_to_clip_file (edit, start_mark, end_mark))
1591 {
1592 edit_error_dialog (_("Copy to clipboard"), get_sys_error (_("Unable to save to file")));
1593 return FALSE;
1594 }
1595
1596 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
1597
1598 if (edit_options.drop_selection_on_copy)
1599 edit_mark_cmd (edit, TRUE);
1600
1601 return TRUE;
1602 }
1603
1604
1605
1606 gboolean
1607 edit_cut_to_X_buf_cmd (WEdit * edit)
1608 {
1609 off_t start_mark, end_mark;
1610
1611 if (!eval_marks (edit, &start_mark, &end_mark))
1612 return TRUE;
1613
1614 if (!edit_save_block_to_clip_file (edit, start_mark, end_mark))
1615 {
1616 edit_error_dialog (_("Cut to clipboard"), _("Unable to save to file"));
1617 return FALSE;
1618 }
1619
1620 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
1621
1622 edit_block_delete_cmd (edit);
1623 edit_mark_cmd (edit, TRUE);
1624
1625 return TRUE;
1626 }
1627
1628
1629
1630 gboolean
1631 edit_paste_from_X_buf_cmd (WEdit * edit)
1632 {
1633 vfs_path_t *tmp;
1634 gboolean ret;
1635
1636
1637 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_from_ext_clip", NULL);
1638 tmp = mc_config_get_full_vpath (EDIT_HOME_CLIP_FILE);
1639 ret = (edit_insert_file (edit, tmp) >= 0);
1640 vfs_path_free (tmp, TRUE);
1641
1642 return ret;
1643 }
1644
1645
1646
1647
1648
1649
1650
1651 void
1652 edit_goto_cmd (WEdit * edit)
1653 {
1654 static gboolean first_run = TRUE;
1655
1656 char *f;
1657 long l;
1658 char *error;
1659
1660 f = input_dialog (_("Goto line"), _("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE,
1661 first_run ? NULL : INPUT_LAST_TEXT, INPUT_COMPLETE_NONE);
1662 if (f == NULL || *f == '\0')
1663 {
1664 g_free (f);
1665 return;
1666 }
1667
1668 l = strtol (f, &error, 0);
1669 if (*error != '\0')
1670 {
1671 g_free (f);
1672 return;
1673 }
1674
1675 if (l < 0)
1676 l = edit->buffer.lines + l + 2;
1677
1678 edit_move_display (edit, l - WIDGET (edit)->rect.lines / 2 - 1);
1679 edit_move_to_line (edit, l - 1);
1680 edit->force |= REDRAW_COMPLETELY;
1681
1682 g_free (f);
1683 first_run = FALSE;
1684 }
1685
1686
1687
1688
1689 gboolean
1690 edit_save_block_cmd (WEdit * edit)
1691 {
1692 off_t start_mark, end_mark;
1693 char *exp, *tmp;
1694 gboolean ret = FALSE;
1695
1696 if (!eval_marks (edit, &start_mark, &end_mark))
1697 return TRUE;
1698
1699 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
1700 exp =
1701 input_expand_dialog (_("Save block"), _("Enter file name:"),
1702 MC_HISTORY_EDIT_SAVE_BLOCK, tmp, INPUT_COMPLETE_FILENAMES);
1703 g_free (tmp);
1704 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
1705
1706 if (exp != NULL && *exp != '\0')
1707 {
1708 if (edit_save_block (edit, exp, start_mark, end_mark))
1709 ret = TRUE;
1710 else
1711 edit_error_dialog (_("Save block"), get_sys_error (_("Cannot save file")));
1712
1713 edit->force |= REDRAW_COMPLETELY;
1714 }
1715
1716 g_free (exp);
1717
1718 return ret;
1719 }
1720
1721
1722
1723
1724 gboolean
1725 edit_insert_file_cmd (WEdit * edit)
1726 {
1727 char *tmp;
1728 char *exp;
1729 gboolean ret = FALSE;
1730
1731 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
1732 exp = input_expand_dialog (_("Insert file"), _("Enter file name:"),
1733 MC_HISTORY_EDIT_INSERT_FILE, tmp, INPUT_COMPLETE_FILENAMES);
1734 g_free (tmp);
1735
1736 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
1737
1738 if (exp != NULL && *exp != '\0')
1739 {
1740 vfs_path_t *exp_vpath;
1741
1742 exp_vpath = vfs_path_from_str (exp);
1743 ret = (edit_insert_file (edit, exp_vpath) >= 0);
1744 vfs_path_free (exp_vpath, TRUE);
1745
1746 if (!ret)
1747 edit_error_dialog (_("Insert file"), get_sys_error (_("Cannot insert file")));
1748 }
1749
1750 g_free (exp);
1751
1752 edit->force |= REDRAW_COMPLETELY;
1753 return ret;
1754 }
1755
1756
1757
1758
1759 int
1760 edit_sort_cmd (WEdit * edit)
1761 {
1762 char *exp, *tmp, *tmp_edit_block_name, *tmp_edit_temp_name;
1763 off_t start_mark, end_mark;
1764 int e;
1765
1766 if (!eval_marks (edit, &start_mark, &end_mark))
1767 {
1768 edit_error_dialog (_("Sort block"), _("You must first highlight a block of text"));
1769 return 0;
1770 }
1771
1772 tmp = mc_config_get_full_path (EDIT_HOME_BLOCK_FILE);
1773 edit_save_block (edit, tmp, start_mark, end_mark);
1774 g_free (tmp);
1775
1776 exp = input_dialog (_("Run sort"),
1777 _("Enter sort options (see sort(1) manpage) separated by whitespace:"),
1778 MC_HISTORY_EDIT_SORT, INPUT_LAST_TEXT, INPUT_COMPLETE_NONE);
1779
1780 if (exp == NULL)
1781 return 1;
1782
1783 tmp_edit_block_name = mc_config_get_full_path (EDIT_HOME_BLOCK_FILE);
1784 tmp_edit_temp_name = mc_config_get_full_path (EDIT_HOME_TEMP_FILE);
1785 tmp =
1786 g_strconcat (" sort ", exp, " ", tmp_edit_block_name,
1787 " > ", tmp_edit_temp_name, (char *) NULL);
1788 g_free (tmp_edit_temp_name);
1789 g_free (tmp_edit_block_name);
1790 g_free (exp);
1791
1792 e = system (tmp);
1793 g_free (tmp);
1794 if (e != 0)
1795 {
1796 if (e == -1 || e == 127)
1797 edit_error_dialog (_("Sort"), get_sys_error (_("Cannot execute sort command")));
1798 else
1799 {
1800 char q[8];
1801
1802 sprintf (q, "%d ", e);
1803 tmp = g_strdup_printf (_("Sort returned non-zero: %s"), q);
1804 edit_error_dialog (_("Sort"), tmp);
1805 g_free (tmp);
1806 }
1807
1808 return -1;
1809 }
1810
1811 edit->force |= REDRAW_COMPLETELY;
1812
1813 if (!edit_block_delete_cmd (edit))
1814 return 1;
1815
1816 {
1817 vfs_path_t *tmp_vpath;
1818
1819 tmp_vpath = mc_config_get_full_vpath (EDIT_HOME_TEMP_FILE);
1820 edit_insert_file (edit, tmp_vpath);
1821 vfs_path_free (tmp_vpath, TRUE);
1822 }
1823
1824 return 0;
1825 }
1826
1827
1828
1829
1830
1831
1832
1833 int
1834 edit_ext_cmd (WEdit * edit)
1835 {
1836 char *exp, *tmp, *tmp_edit_temp_file;
1837 int e;
1838
1839 exp =
1840 input_dialog (_("Paste output of external command"),
1841 _("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD, INPUT_LAST_TEXT,
1842 INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES
1843 | INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS |
1844 INPUT_COMPLETE_SHELL_ESC);
1845
1846 if (!exp)
1847 return 1;
1848
1849 tmp_edit_temp_file = mc_config_get_full_path (EDIT_HOME_TEMP_FILE);
1850 tmp = g_strconcat (exp, " > ", tmp_edit_temp_file, (char *) NULL);
1851 g_free (tmp_edit_temp_file);
1852 e = system (tmp);
1853 g_free (tmp);
1854 g_free (exp);
1855
1856 if (e != 0)
1857 {
1858 edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command")));
1859 return -1;
1860 }
1861
1862 edit->force |= REDRAW_COMPLETELY;
1863
1864 {
1865 vfs_path_t *tmp_vpath;
1866
1867 tmp_vpath = mc_config_get_full_vpath (EDIT_HOME_TEMP_FILE);
1868 edit_insert_file (edit, tmp_vpath);
1869 vfs_path_free (tmp_vpath, TRUE);
1870 }
1871
1872 return 0;
1873 }
1874
1875
1876
1877
1878
1879
1880 void
1881 edit_block_process_cmd (WEdit * edit, int macro_number)
1882 {
1883 char *fname;
1884 char *macros_fname = NULL;
1885
1886 fname = g_strdup_printf ("%s.%i.sh", EDIT_HOME_MACRO_FILE, macro_number);
1887 macros_fname = g_build_filename (mc_config_get_data_path (), fname, (char *) NULL);
1888 edit_user_menu (edit, macros_fname, 0);
1889 g_free (fname);
1890 g_free (macros_fname);
1891 edit->force |= REDRAW_COMPLETELY;
1892 }
1893
1894
1895
1896 void
1897 edit_mail_dialog (WEdit * edit)
1898 {
1899 char *mail_to, *mail_subject, *mail_cc;
1900
1901 quick_widget_t quick_widgets[] = {
1902
1903 QUICK_LABEL (N_("mail -s <subject> -c <cc> <to>"), NULL),
1904 QUICK_LABELED_INPUT (N_("To"), input_label_above,
1905 INPUT_LAST_TEXT, "mail-dlg-input-3",
1906 &mail_to, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
1907 QUICK_LABELED_INPUT (N_("Subject"), input_label_above,
1908 INPUT_LAST_TEXT, "mail-dlg-input-2",
1909 &mail_subject, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
1910 QUICK_LABELED_INPUT (N_("Copies to"), input_label_above,
1911 INPUT_LAST_TEXT, "mail-dlg-input",
1912 &mail_cc, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
1913 QUICK_BUTTONS_OK_CANCEL,
1914 QUICK_END
1915
1916 };
1917
1918 WRect r = { -1, -1, 0, 50 };
1919
1920 quick_dialog_t qdlg = {
1921 r, N_("Mail"), "[Input Line Keys]",
1922 quick_widgets, NULL, NULL
1923 };
1924
1925 if (quick_dialog (&qdlg) != B_CANCEL)
1926 {
1927 pipe_mail (&edit->buffer, mail_to, mail_subject, mail_cc);
1928 g_free (mail_to);
1929 g_free (mail_subject);
1930 g_free (mail_cc);
1931 }
1932 }
1933
1934
1935
1936 #ifdef HAVE_CHARSET
1937 void
1938 edit_select_codepage_cmd (WEdit * edit)
1939 {
1940 if (do_select_codepage ())
1941 edit_set_codeset (edit);
1942
1943 edit->force = REDRAW_PAGE;
1944 widget_draw (WIDGET (edit));
1945 }
1946 #endif
1947
1948
1949
1950 void
1951 edit_insert_literal_cmd (WEdit * edit)
1952 {
1953 int char_for_insertion;
1954
1955 char_for_insertion = editcmd_dialog_raw_key_query (_("Insert literal"),
1956 _("Press any key:"), FALSE);
1957 edit_execute_key_command (edit, -1, ascii_alpha_to_cntrl (char_for_insertion));
1958 }
1959
1960
1961
1962 gboolean
1963 edit_load_forward_cmd (WEdit * edit)
1964 {
1965 if (edit->modified
1966 && edit_query_dialog2 (_("Warning"),
1967 _("Current text was modified without a file save.\n"
1968 "Continue discards these changes."), _("C&ontinue"),
1969 _("&Cancel")) == 1)
1970 {
1971 edit->force |= REDRAW_COMPLETELY;
1972 return TRUE;
1973 }
1974
1975 if (edit_stack_iterator + 1 >= MAX_HISTORY_MOVETO)
1976 return FALSE;
1977
1978 if (edit_history_moveto[edit_stack_iterator + 1].line < 1)
1979 return FALSE;
1980
1981 edit_stack_iterator++;
1982 if (edit_history_moveto[edit_stack_iterator].filename_vpath != NULL)
1983 return edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath,
1984 edit_history_moveto[edit_stack_iterator].line);
1985
1986 return FALSE;
1987 }
1988
1989
1990
1991 gboolean
1992 edit_load_back_cmd (WEdit * edit)
1993 {
1994 if (edit->modified
1995 && edit_query_dialog2 (_("Warning"),
1996 _("Current text was modified without a file save.\n"
1997 "Continue discards these changes."), _("C&ontinue"),
1998 _("&Cancel")) == 1)
1999 {
2000 edit->force |= REDRAW_COMPLETELY;
2001 return TRUE;
2002 }
2003
2004
2005 if (edit_stack_iterator == 0)
2006 return FALSE;
2007
2008 edit_stack_iterator--;
2009 if (edit_history_moveto[edit_stack_iterator].filename_vpath != NULL)
2010 return edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath,
2011 edit_history_moveto[edit_stack_iterator].line);
2012
2013 return FALSE;
2014 }
2015
2016
2017
2018
2019
2020
2021
2022
2023 int
2024 editcmd_dialog_raw_key_query (const char *heading, const char *query, gboolean cancel)
2025 {
2026 int w, wq;
2027 int y = 2;
2028 WDialog *raw_dlg;
2029 WGroup *g;
2030
2031 w = str_term_width1 (heading) + 6;
2032 wq = str_term_width1 (query);
2033 w = MAX (w, wq + 3 * 2 + 1 + 2);
2034
2035 raw_dlg =
2036 dlg_create (TRUE, 0, 0, cancel ? 7 : 5, w, WPOS_CENTER | WPOS_TRYUP, FALSE, dialog_colors,
2037 editcmd_dialog_raw_key_query_cb, NULL, NULL, heading);
2038 g = GROUP (raw_dlg);
2039 widget_want_tab (WIDGET (raw_dlg), TRUE);
2040
2041 group_add_widget (g, label_new (y, 3, query));
2042 group_add_widget (g,
2043 input_new (y++, 3 + wq + 1, input_colors, w - (6 + wq + 1), "", 0,
2044 INPUT_COMPLETE_NONE));
2045 if (cancel)
2046 {
2047 group_add_widget (g, hline_new (y++, -1, -1));
2048
2049 group_add_widget_autopos (g, button_new (y, 1, B_CANCEL, NORMAL_BUTTON, _("Cancel"), NULL),
2050 WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
2051 }
2052
2053 w = dlg_run (raw_dlg);
2054 widget_destroy (WIDGET (raw_dlg));
2055
2056 return (cancel && (w == ESC_CHAR || w == B_CANCEL)) ? 0 : w;
2057 }
2058
2059