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