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 #include "lib/charsets.h"
58
59 #include "src/history.h"
60 #include "src/file_history.h"
61 #include "src/selcodepage.h"
62 #include "src/util.h"
63
64 #include "edit-impl.h"
65 #include "editwidget.h"
66 #include "editsearch.h"
67 #include "etags.h"
68
69
70
71
72 int search_create_bookmark = FALSE;
73
74
75
76 #define space_width 1
77
78 #define TEMP_BUF_LEN 1024
79
80
81
82
83
84
85
86 static unsigned long edit_save_mode_radio_id, edit_save_mode_input_id;
87
88
89
90
91
92 static cb_ret_t
93 edit_save_mode_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
94 {
95 switch (msg)
96 {
97 case MSG_CHANGED_FOCUS:
98 if (sender != NULL && sender->id == edit_save_mode_radio_id)
99 {
100 Widget *ww;
101
102 ww = widget_find_by_id (w, edit_save_mode_input_id);
103 widget_disable (ww, RADIO (sender)->sel != 2);
104 return MSG_HANDLED;
105 }
106 return MSG_NOT_HANDLED;
107
108 default:
109 return dlg_default_callback (w, sender, msg, parm, data);
110 }
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124
125 static int
126 edit_save_file (WEdit *edit, const vfs_path_t *filename_vpath)
127 {
128 char *p;
129 off_t filelen = 0;
130 int this_save_mode, rv, fd = -1;
131 vfs_path_t *real_filename_vpath;
132 vfs_path_t *savename_vpath = NULL;
133 const char *start_filename;
134 const vfs_path_element_t *vpath_element;
135 struct stat sb;
136
137 vpath_element = vfs_path_get_by_index (filename_vpath, 0);
138 if (vpath_element == NULL)
139 return 0;
140
141 start_filename = vpath_element->path;
142 if (*start_filename == '\0')
143 return 0;
144
145 if (!IS_PATH_SEP (*start_filename) && edit->dir_vpath != NULL)
146 real_filename_vpath = vfs_path_append_vpath_new (edit->dir_vpath, filename_vpath, NULL);
147 else
148 real_filename_vpath = vfs_path_clone (filename_vpath);
149
150 this_save_mode = edit_options.save_mode;
151 if (this_save_mode != EDIT_QUICK_SAVE)
152 {
153 if (!vfs_file_is_local (real_filename_vpath))
154
155 this_save_mode = EDIT_QUICK_SAVE;
156 else
157 {
158 fd = mc_open (real_filename_vpath, O_RDONLY | O_BINARY);
159 if (fd == -1)
160
161 this_save_mode = EDIT_QUICK_SAVE;
162 }
163
164 if (fd != -1)
165 mc_close (fd);
166 }
167
168 rv = mc_stat (real_filename_vpath, &sb);
169 if (rv == 0)
170 {
171 if (this_save_mode == EDIT_QUICK_SAVE && edit->skip_detach_prompt == 0 && sb.st_nlink > 1)
172 {
173 rv =
174 edit_query_dialog3 (_ ("Warning"), _ ("File has hard-links. Detach before saving?"),
175 _ ("&Yes"), _ ("&No"), _ ("&Cancel"));
176 switch (rv)
177 {
178 case 0:
179 this_save_mode = EDIT_SAFE_SAVE;
180 MC_FALLTHROUGH;
181 case 1:
182 edit->skip_detach_prompt = 1;
183 break;
184 default:
185 vfs_path_free (real_filename_vpath, TRUE);
186 return -1;
187 }
188 }
189
190
191 if (edit->stat1.st_mtime != 0 && edit->stat1.st_mtime != sb.st_mtime)
192 {
193
194 query_set_sel (1);
195
196 rv = edit_query_dialog2 (_ ("Warning"),
197 _ ("The file has been modified in the meantime. Save anyway?"),
198 _ ("&Yes"), _ ("&Cancel"));
199 if (rv != 0)
200 {
201 vfs_path_free (real_filename_vpath, TRUE);
202 return -1;
203 }
204 }
205 }
206
207 if (this_save_mode == EDIT_QUICK_SAVE)
208 savename_vpath = vfs_path_clone (real_filename_vpath);
209 else
210 {
211 char *savedir, *saveprefix;
212
213 savedir = vfs_path_tokens_get (real_filename_vpath, 0, -1);
214 if (savedir == NULL)
215 savedir = g_strdup (".");
216
217
218 saveprefix = mc_build_filename (PATH_SEP_STR, savedir, "cooledit", (char *) NULL);
219 g_free (savedir);
220 fd = mc_mkstemps (&savename_vpath, saveprefix, NULL);
221 g_free (saveprefix);
222 if (savename_vpath == NULL)
223 {
224 vfs_path_free (real_filename_vpath, TRUE);
225 return 0;
226 }
227
228
229
230
231
232 close (fd);
233 }
234
235 (void) mc_chown (savename_vpath, edit->stat1.st_uid, edit->stat1.st_gid);
236 (void) mc_chmod (savename_vpath, edit->stat1.st_mode);
237 if (edit->attrs_ok)
238 (void) mc_fsetflags (savename_vpath, edit->attrs);
239
240 fd = mc_open (savename_vpath, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, edit->stat1.st_mode);
241 if (fd == -1)
242 goto error_save;
243
244
245 p = edit_get_write_filter (savename_vpath, real_filename_vpath);
246 if (p != NULL)
247 {
248 FILE *file;
249
250 mc_close (fd);
251 file = (FILE *) popen (p, "w");
252
253 if (file != NULL)
254 {
255 filelen = edit_write_stream (edit, file);
256 #if 1
257 pclose (file);
258 #else
259 if (pclose (file) != 0)
260 {
261 message (D_ERROR, MSG_ERROR, _ ("Error writing to pipe: %s"), p);
262 g_free (p);
263 goto error_save;
264 }
265 #endif
266 }
267 else
268 {
269 message (D_ERROR, MSG_ERROR, _ ("Cannot open pipe for writing: %s"), p);
270 g_free (p);
271 goto error_save;
272 }
273 g_free (p);
274 }
275 else if (edit->lb == LB_ASIS)
276 {
277 filelen = edit_buffer_write_file (&edit->buffer, fd);
278
279 if (filelen != edit->buffer.size)
280 {
281 mc_close (fd);
282 goto error_save;
283 }
284
285 if (mc_close (fd) != 0)
286 goto error_save;
287
288
289 if (mc_stat (savename_vpath, &edit->stat1) == -1)
290 goto error_save;
291 }
292 else
293 {
294 FILE *file;
295 const char *savename;
296
297 mc_close (fd);
298
299 savename = vfs_path_get_last_path_str (savename_vpath);
300 file = (FILE *) fopen (savename, "w");
301 if (file != NULL)
302 {
303 filelen = edit_write_stream (edit, file);
304 fclose (file);
305 }
306 else
307 {
308 message (D_ERROR, MSG_ERROR, _ ("Cannot open file for writing: %s"), savename);
309 goto error_save;
310 }
311 }
312
313 if (filelen != edit->buffer.size)
314 goto error_save;
315
316 if (this_save_mode == EDIT_DO_BACKUP)
317 {
318 char *tmp_store_filename;
319 vfs_path_element_t *last_vpath_element;
320 vfs_path_t *tmp_vpath;
321 gboolean ok;
322
323 g_assert (edit_options.backup_ext != NULL);
324
325
326 tmp_vpath = vfs_path_clone (real_filename_vpath);
327 last_vpath_element = (vfs_path_element_t *) vfs_path_get_by_index (tmp_vpath, -1);
328 tmp_store_filename = last_vpath_element->path;
329 last_vpath_element->path =
330 g_strdup_printf ("%s%s", tmp_store_filename, edit_options.backup_ext);
331 g_free (tmp_store_filename);
332
333 ok = (mc_rename (real_filename_vpath, tmp_vpath) != -1);
334 vfs_path_free (tmp_vpath, TRUE);
335 if (!ok)
336 goto error_save;
337 }
338
339 if (this_save_mode != EDIT_QUICK_SAVE && mc_rename (savename_vpath, real_filename_vpath) == -1)
340 goto error_save;
341
342 vfs_path_free (real_filename_vpath, TRUE);
343 vfs_path_free (savename_vpath, TRUE);
344 return 1;
345 error_save:
346
347
348
349
350 vfs_path_free (real_filename_vpath, TRUE);
351 vfs_path_free (savename_vpath, TRUE);
352 return 0;
353 }
354
355
356
357 static gboolean
358 edit_check_newline (const edit_buffer_t *buf)
359 {
360 return !(edit_options.check_nl_at_eof && buf->size > 0
361 && edit_buffer_get_byte (buf, buf->size - 1) != '\n'
362 && edit_query_dialog2 (_ ("Warning"),
363 _ ("The file you are saving does not end with a newline."),
364 _ ("C&ontinue"), _ ("&Cancel"))
365 != 0);
366 }
367
368
369
370 static vfs_path_t *
371 edit_get_save_file_as (WEdit *edit)
372 {
373 static LineBreaks cur_lb = LB_ASIS;
374 char *filename_res = NULL;
375 vfs_path_t *ret_vpath = NULL;
376
377 const char *lb_names[LB_NAMES] = {
378 N_ ("&Do not change"),
379 N_ ("&Unix format (LF)"),
380 N_ ("&Windows/DOS format (CR LF)"),
381 N_ ("&Macintosh format (CR)"),
382 };
383
384 quick_widget_t quick_widgets[] = {
385 QUICK_LABELED_INPUT (N_ ("Enter file name:"), input_label_above,
386 vfs_path_as_str (edit->filename_vpath), "save-as", &filename_res, NULL,
387 FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
388 QUICK_SEPARATOR (TRUE),
389 QUICK_LABEL (N_ ("Change line breaks to:"), NULL),
390 QUICK_RADIO (LB_NAMES, lb_names, (int *) &cur_lb, NULL),
391 QUICK_BUTTONS_OK_CANCEL,
392 QUICK_END,
393 };
394
395 WRect r = { -1, -1, 0, 64 };
396
397 quick_dialog_t qdlg = {
398 .rect = r,
399 .title = N_ ("Save As"),
400 .help = "[Save File As]",
401 .widgets = quick_widgets,
402 .callback = NULL,
403 .mouse_callback = NULL,
404 };
405
406 if (quick_dialog (&qdlg) != B_CANCEL)
407 {
408 char *fname;
409
410 edit->lb = cur_lb;
411 fname = tilde_expand (filename_res);
412 g_free (filename_res);
413 ret_vpath = vfs_path_from_str (fname);
414 g_free (fname);
415 }
416
417 return ret_vpath;
418 }
419
420
421
422
423
424 static gboolean
425 edit_save_cmd (WEdit *edit)
426 {
427 int save_lock = 0;
428
429 if (edit->locked == 0 && edit->delete_file == 0)
430 save_lock = lock_file (edit->filename_vpath);
431
432 const int res = edit_save_file (edit, edit->filename_vpath);
433
434
435 if ((res > 0 && edit->locked != 0) || save_lock != 0)
436 edit->locked = unlock_file (edit->filename_vpath);
437
438
439 if (res == 0)
440 return edit_save_as_cmd (edit);
441
442 if (res > 0)
443 {
444 edit->delete_file = 0;
445 edit->modified = 0;
446 }
447
448 edit->force |= REDRAW_COMPLETELY;
449
450 return TRUE;
451 }
452
453
454
455 static void
456 edit_delete_column_of_text (WEdit *edit, off_t m1, off_t m2)
457 {
458 off_t n;
459 off_t r;
460 long b, c, d;
461
462 n = edit_buffer_get_forward_offset (&edit->buffer, m1, 0, m2) + 1;
463 r = edit_buffer_get_bol (&edit->buffer, m1);
464 c = (long) edit_move_forward3 (edit, r, 0, m1);
465 r = edit_buffer_get_bol (&edit->buffer, m2);
466 d = (long) edit_move_forward3 (edit, r, 0, m2);
467 b = MAX (MIN (c, d), MIN (edit->column1, edit->column2));
468 c = MAX (c, MAX (edit->column1, edit->column2));
469
470 while (n-- != 0)
471 {
472 off_t p, q;
473
474 r = edit_buffer_get_current_bol (&edit->buffer);
475 p = edit_move_forward3 (edit, r, b, 0);
476 q = edit_move_forward3 (edit, r, c, 0);
477 p = MAX (p, m1);
478 q = MIN (q, m2);
479 edit_cursor_move (edit, p - edit->buffer.curs1);
480
481 for (; q > p; q--)
482 if (edit_buffer_get_current_byte (&edit->buffer) != '\n')
483 edit_delete (edit, TRUE);
484
485
486 if (n != 0)
487 {
488 r = edit_buffer_get_forward_offset (&edit->buffer, edit->buffer.curs1, 1, 0);
489 edit_cursor_move (edit, r - edit->buffer.curs1);
490 }
491 }
492 }
493
494
495
496
497 static gboolean
498 edit_block_delete (WEdit *edit, off_t start_mark, off_t end_mark)
499 {
500 off_t curs_pos;
501 long curs_line, c1, c2;
502
503 if (edit->column_highlight && edit->mark2 < 0)
504 edit_mark_cmd (edit, FALSE);
505
506
507 if ((end_mark - start_mark) > max_undo / 2
508 && edit_query_dialog2 (_ ("Warning"),
509 ("Block is large, you may not be able to undo this action"),
510 _ ("C&ontinue"), _ ("&Cancel"))
511 != 0)
512 return FALSE;
513
514 c1 = MIN (edit->column1, edit->column2);
515 c2 = MAX (edit->column1, edit->column2);
516 edit->column1 = c1;
517 edit->column2 = c2;
518
519 edit_push_markers (edit);
520
521 curs_line = edit->buffer.curs_line;
522
523 curs_pos = edit->curs_col + edit->over_col;
524
525
526 edit_cursor_move (edit, start_mark - edit->buffer.curs1);
527 edit_scroll_screen_over_cursor (edit);
528
529 if (start_mark < end_mark)
530 {
531 if (edit->column_highlight)
532 {
533 off_t b, e;
534 off_t line_width;
535
536 if (edit->mark2 < 0)
537 edit_mark_cmd (edit, FALSE);
538 edit_delete_column_of_text (edit, start_mark, end_mark);
539
540 edit_move_to_line (edit, curs_line);
541
542 b = edit_buffer_get_current_bol (&edit->buffer);
543 e = edit_buffer_get_current_eol (&edit->buffer);
544 line_width = edit_move_forward3 (edit, b, 0, e);
545 if (edit_options.cursor_beyond_eol && curs_pos > line_width)
546 edit->over_col = curs_pos - line_width;
547 }
548 else
549 {
550 off_t count;
551
552 for (count = start_mark; count < end_mark; count++)
553 edit_delete (edit, TRUE);
554 }
555 }
556
557 edit_set_markers (edit, 0, 0, 0, 0);
558 edit->force |= REDRAW_PAGE;
559
560 return TRUE;
561 }
562
563
564
565
566 static unsigned char *
567 edit_get_block (WEdit *edit, off_t start, off_t finish, off_t *l)
568 {
569 unsigned char *s, *r;
570
571 r = s = g_malloc0 (finish - start + 1);
572
573 if (edit->column_highlight)
574 {
575 *l = 0;
576
577
578 for (; start < finish; start++)
579 {
580 int c;
581 off_t x;
582
583 x = edit_buffer_get_bol (&edit->buffer, start);
584 x = edit_move_forward3 (edit, x, 0, start);
585 c = edit_buffer_get_byte (&edit->buffer, start);
586 if ((x >= edit->column1 && x < edit->column2)
587 || (x >= edit->column2 && x < edit->column1) || c == '\n')
588 {
589 *s++ = c;
590 (*l)++;
591 }
592 }
593 }
594 else
595 {
596 *l = finish - start;
597
598 for (; start < finish; start++)
599 *s++ = edit_buffer_get_byte (&edit->buffer, start);
600 }
601
602 *s = '\0';
603
604 return r;
605 }
606
607
608
609
610 static gboolean
611 edit_save_block_to_clip_file (WEdit *edit, off_t start, off_t finish)
612 {
613 gboolean ret;
614 gchar *tmp;
615
616 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
617 ret = edit_save_block (edit, tmp, start, finish);
618 g_free (tmp);
619
620 return ret;
621 }
622
623
624
625 static void
626 pipe_mail (const edit_buffer_t *buf, char *to, char *subject, char *cc)
627 {
628 FILE *p = 0;
629 char *s = NULL;
630
631 to = name_quote (to, FALSE);
632 if (to != NULL)
633 {
634 subject = name_quote (subject, FALSE);
635 if (subject != NULL)
636 {
637 cc = name_quote (cc, FALSE);
638 if (cc == NULL)
639 s = g_strdup_printf ("mail -s %s %s", subject, to);
640 else
641 {
642 s = g_strdup_printf ("mail -s %s -c %s %s", subject, cc, to);
643 g_free (cc);
644 }
645
646 g_free (subject);
647 }
648
649 g_free (to);
650 }
651
652 if (s != NULL)
653 {
654 p = popen (s, "w");
655 g_free (s);
656 }
657
658 if (p != NULL)
659 {
660 off_t i;
661
662 for (i = 0; i < buf->size; i++)
663 if (fputc (edit_buffer_get_byte (buf, i), p) < 0)
664 break;
665 pclose (p);
666 }
667 }
668
669
670
671 static void
672 edit_insert_column_of_text (WEdit *edit, unsigned char *data, off_t size, long width,
673 off_t *start_pos, off_t *end_pos, long *col1, long *col2)
674 {
675 off_t i, cursor;
676 long col;
677
678 cursor = edit->buffer.curs1;
679 col = edit_get_col (edit);
680
681 for (i = 0; i < size; i++)
682 {
683 if (data[i] != '\n')
684 edit_insert (edit, data[i]);
685 else
686 {
687 long l;
688 off_t p;
689
690 if (edit_buffer_get_current_byte (&edit->buffer) != '\n')
691 {
692 for (l = width - (edit_get_col (edit) - col); l > 0; l -= space_width)
693 edit_insert (edit, ' ');
694 }
695 for (p = edit->buffer.curs1;; p++)
696 {
697 if (p == edit->buffer.size)
698 {
699 edit_cursor_move (edit, edit->buffer.size - edit->buffer.curs1);
700 edit_insert_ahead (edit, '\n');
701 p++;
702 break;
703 }
704 if (edit_buffer_get_byte (&edit->buffer, p) == '\n')
705 {
706 p++;
707 break;
708 }
709 }
710 edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0) - edit->buffer.curs1);
711
712 for (l = col - edit_get_col (edit); l >= space_width; l -= space_width)
713 edit_insert (edit, ' ');
714 }
715 }
716
717 *col1 = col;
718 *col2 = col + width;
719 *start_pos = cursor;
720 *end_pos = edit->buffer.curs1;
721 edit_cursor_move (edit, cursor - edit->buffer.curs1);
722 }
723
724
725
726
727
728
729
730
731
732
733 static void
734 edit_syntax_onoff_cb (void *data, void *user_data)
735 {
736 (void) user_data;
737
738 if (edit_widget_is_editor (CONST_WIDGET (data)))
739 {
740 WEdit *edit = EDIT (data);
741
742 if (edit_options.syntax_highlighting)
743 edit_load_syntax (edit, NULL, edit->syntax_type);
744 edit->force |= REDRAW_PAGE;
745 }
746 }
747
748
749
750 static cb_ret_t
751 editcmd_dialog_raw_key_query_cb (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
752 {
753 WDialog *h = DIALOG (w);
754
755 switch (msg)
756 {
757 case MSG_KEY:
758 h->ret_value = parm;
759 dlg_close (h);
760 return MSG_HANDLED;
761 default:
762 return dlg_default_callback (w, sender, msg, parm, data);
763 }
764 }
765
766
767
768
769
770 void
771 edit_refresh_cmd (void)
772 {
773 tty_clear_screen ();
774 repaint_screen ();
775 tty_keypad (TRUE);
776 }
777
778
779
780
781
782
783
784
785 void
786 edit_syntax_onoff_cmd (WDialog *h)
787 {
788 edit_options.syntax_highlighting = !edit_options.syntax_highlighting;
789 g_list_foreach (GROUP (h)->widgets, edit_syntax_onoff_cb, NULL);
790 widget_draw (WIDGET (h));
791 }
792
793
794
795
796
797
798
799
800 void
801 edit_show_tabs_tws_cmd (WDialog *h)
802 {
803 enable_show_tabs_tws = !enable_show_tabs_tws;
804 widget_draw (WIDGET (h));
805 }
806
807
808
809
810
811
812
813
814 void
815 edit_show_margin_cmd (WDialog *h)
816 {
817 edit_options.show_right_margin = !edit_options.show_right_margin;
818 widget_draw (WIDGET (h));
819 }
820
821
822
823
824
825
826
827
828 void
829 edit_show_numbers_cmd (WDialog *h)
830 {
831 edit_options.line_state = !edit_options.line_state;
832 edit_options.line_state_width = edit_options.line_state ? LINE_STATE_WIDTH : 0;
833 widget_draw (WIDGET (h));
834 }
835
836
837
838 void
839 edit_save_mode_cmd (void)
840 {
841 char *str_result = NULL;
842
843 const char *str[] = {
844 N_ ("&Quick save"),
845 N_ ("&Safe save"),
846 N_ ("&Do backups with following extension:"),
847 };
848
849 #ifdef ENABLE_NLS
850 size_t i;
851
852 for (i = 0; i < 3; i++)
853 str[i] = _ (str[i]);
854 #endif
855
856 g_assert (edit_options.backup_ext != NULL);
857
858 {
859 quick_widget_t quick_widgets[] = {
860 QUICK_RADIO (3, str, &edit_options.save_mode, &edit_save_mode_radio_id),
861 QUICK_INPUT (edit_options.backup_ext, "edit-backup-ext", &str_result,
862 &edit_save_mode_input_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
863 QUICK_SEPARATOR (TRUE),
864 QUICK_CHECKBOX (N_ ("Check &POSIX new line"), &edit_options.check_nl_at_eof, NULL),
865 QUICK_BUTTONS_OK_CANCEL,
866 QUICK_END,
867 };
868
869 WRect r = { -1, -1, 0, 38 };
870
871 quick_dialog_t qdlg = {
872 .rect = r,
873 .title = N_ ("Edit Save Mode"),
874 .help = "[Edit Save Mode]",
875 .widgets = quick_widgets,
876 .callback = edit_save_mode_callback,
877 .mouse_callback = NULL,
878 };
879
880 if (quick_dialog (&qdlg) != B_CANCEL)
881 {
882 g_free (edit_options.backup_ext);
883 edit_options.backup_ext = str_result;
884 }
885 }
886 }
887
888
889
890 void
891 edit_set_filename (WEdit *edit, const vfs_path_t *name_vpath)
892 {
893 vfs_path_free (edit->filename_vpath, TRUE);
894 edit->filename_vpath = vfs_path_clone (name_vpath);
895
896 if (edit->dir_vpath == NULL)
897 edit->dir_vpath = vfs_path_clone (vfs_get_raw_current_dir ());
898 }
899
900
901
902
903
904 gboolean
905 edit_save_as_cmd (WEdit *edit)
906 {
907
908 vfs_path_t *exp_vpath;
909 int save_lock = 0;
910 gboolean different_filename = FALSE;
911 gboolean ret = FALSE;
912
913 if (!edit_check_newline (&edit->buffer))
914 return FALSE;
915
916 exp_vpath = edit_get_save_file_as (edit);
917 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
918
919 if (exp_vpath != NULL && vfs_path_len (exp_vpath) != 0)
920 {
921 int rv;
922
923 if (!vfs_path_equal (edit->filename_vpath, exp_vpath))
924 {
925 int file;
926 struct stat sb;
927
928 if (mc_stat (exp_vpath, &sb) == 0 && !S_ISREG (sb.st_mode))
929 {
930 message (D_ERROR, MSG_ERROR, "%s",
931 _ ("Cannot save: destination is not a regular file"));
932 goto ret;
933 }
934
935 different_filename = TRUE;
936 file = mc_open (exp_vpath, O_RDONLY | O_BINARY);
937
938 if (file == -1)
939 edit->stat1.st_mode |= S_IWUSR;
940 else
941 {
942
943 mc_close (file);
944
945 if (edit_query_dialog2 (_ ("Warning"), _ ("A file already exists with this name"),
946 _ ("&Overwrite"), _ ("&Cancel")))
947 goto ret;
948 }
949
950 save_lock = lock_file (exp_vpath);
951 }
952 else if (edit->locked == 0 && edit->delete_file == 0)
953
954 save_lock = lock_file (exp_vpath);
955
956 if (different_filename)
957
958
959 edit->stat1.st_mode |= S_IWUSR;
960
961 rv = edit_save_file (edit, exp_vpath);
962 switch (rv)
963 {
964 case 1:
965
966 if (different_filename)
967 {
968 if (save_lock != 0)
969 unlock_file (exp_vpath);
970 if (edit->locked != 0)
971 edit->locked = unlock_file (edit->filename_vpath);
972 }
973 else if (edit->locked != 0 || save_lock != 0)
974 edit->locked = unlock_file (edit->filename_vpath);
975
976 edit_set_filename (edit, exp_vpath);
977 if (edit->lb != LB_ASIS)
978 edit_reload (edit, exp_vpath);
979 edit->modified = 0;
980 edit->delete_file = 0;
981 if (different_filename)
982 edit_load_syntax (edit, NULL, edit->syntax_type);
983 ret = TRUE;
984 break;
985
986 default:
987 message (D_ERROR, MSG_ERROR, "%s", _ ("Cannot save file"));
988 MC_FALLTHROUGH;
989
990 case -1:
991
992 if (save_lock != 0)
993 unlock_file (exp_vpath);
994 break;
995 }
996 }
997
998 ret:
999 vfs_path_free (exp_vpath, TRUE);
1000 edit->force |= REDRAW_COMPLETELY;
1001 return ret;
1002 }
1003
1004
1005
1006
1007 gboolean
1008 edit_save_confirm_cmd (WEdit *edit)
1009 {
1010 if (edit->filename_vpath == NULL)
1011 return edit_save_as_cmd (edit);
1012
1013 if (!edit_check_newline (&edit->buffer))
1014 return FALSE;
1015
1016 if (edit_options.confirm_save)
1017 {
1018 char *f;
1019 gboolean ok;
1020
1021 f = g_strdup_printf (_ ("Confirm save file: \"%s\""),
1022 vfs_path_as_str (edit->filename_vpath));
1023 ok = (edit_query_dialog2 (_ ("Save file"), f, _ ("&Save"), _ ("&Cancel")) == 0);
1024 g_free (f);
1025 if (!ok)
1026 return FALSE;
1027 }
1028
1029 return edit_save_cmd (edit);
1030 }
1031
1032
1033
1034
1035
1036
1037
1038
1039 gboolean
1040 edit_load_cmd (WDialog *h)
1041 {
1042 char *exp;
1043 gboolean ret = TRUE;
1044
1045 exp = input_expand_dialog (_ ("Load"), _ ("Enter file name:"), MC_HISTORY_EDIT_LOAD,
1046 INPUT_LAST_TEXT, INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD);
1047
1048 if (exp != NULL && *exp != '\0')
1049 {
1050 vfs_path_t *exp_vpath;
1051 edit_arg_t arg;
1052
1053 exp_vpath = vfs_path_from_str (exp);
1054 edit_arg_init (&arg, exp_vpath, 0);
1055 ret = edit_load_file_from_filename (h, &arg);
1056 vfs_path_free (exp_vpath, TRUE);
1057 }
1058
1059 g_free (exp);
1060
1061 return ret;
1062 }
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075 gboolean
1076 edit_load_file_from_filename (WDialog *h, const edit_arg_t *arg)
1077 {
1078 WRect r = WIDGET (h)->rect;
1079
1080 rect_grow (&r, -1, 0);
1081
1082 return edit_add_window (h, &r, arg);
1083 }
1084
1085
1086
1087
1088
1089
1090
1091
1092 gboolean
1093 edit_load_file_from_history (WDialog *h)
1094 {
1095 char *exp;
1096 int action;
1097 gboolean ret = TRUE;
1098
1099 exp = show_file_history (CONST_WIDGET (h), &action);
1100 if (exp != NULL && (action == CK_Edit || action == CK_Enter))
1101 {
1102 vfs_path_t *exp_vpath;
1103 edit_arg_t arg;
1104
1105 exp_vpath = vfs_path_from_str (exp);
1106 edit_arg_init (&arg, exp_vpath, 0);
1107 ret = edit_load_file_from_filename (h, &arg);
1108 vfs_path_free (exp_vpath, TRUE);
1109 }
1110
1111 g_free (exp);
1112
1113 return ret;
1114 }
1115
1116
1117
1118
1119
1120
1121
1122
1123 gboolean
1124 edit_load_syntax_file (WDialog *h)
1125 {
1126 vfs_path_t *extdir_vpath;
1127 int dir = 0;
1128 edit_arg_t arg;
1129 gboolean ret = FALSE;
1130
1131 if (geteuid () == 0)
1132 dir = query_dialog (_ ("Syntax file edit"), _ ("Which syntax file you want to edit?"),
1133 D_NORMAL, 2, _ ("&User"), _ ("&System wide"));
1134
1135 extdir_vpath =
1136 vfs_path_build_filename (mc_global.sysconfig_dir, EDIT_SYNTAX_FILE, (char *) NULL);
1137 if (!exist_file (vfs_path_get_last_path_str (extdir_vpath)))
1138 {
1139 vfs_path_free (extdir_vpath, TRUE);
1140 extdir_vpath =
1141 vfs_path_build_filename (mc_global.share_data_dir, EDIT_SYNTAX_FILE, (char *) NULL);
1142 }
1143
1144 if (dir == 0)
1145 {
1146 vfs_path_t *user_syntax_file_vpath;
1147
1148 user_syntax_file_vpath = mc_config_get_full_vpath (EDIT_SYNTAX_FILE);
1149 check_for_default (extdir_vpath, user_syntax_file_vpath);
1150 edit_arg_init (&arg, user_syntax_file_vpath, 0);
1151 ret = edit_load_file_from_filename (h, &arg);
1152 vfs_path_free (user_syntax_file_vpath, TRUE);
1153 }
1154 else if (dir == 1)
1155 {
1156 edit_arg_init (&arg, extdir_vpath, 0);
1157 ret = edit_load_file_from_filename (h, &arg);
1158 }
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 edit_arg_t arg;
1179 gboolean ret;
1180
1181 query_set_sel (1);
1182 dir = query_dialog (_ ("Menu edit"), _ ("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 edit_arg_init (&arg, buffer_vpath, 0);
1224 ret = edit_load_file_from_filename (h, &arg);
1225
1226 vfs_path_free (buffer_vpath, TRUE);
1227 vfs_path_free (menufile_vpath, TRUE);
1228
1229 return ret;
1230 }
1231
1232
1233
1234
1235
1236
1237
1238
1239 gboolean
1240 edit_close_cmd (WEdit *edit)
1241 {
1242 gboolean ret;
1243
1244 ret = (edit != NULL) && edit_ok_to_exit (edit);
1245
1246 if (ret)
1247 {
1248 Widget *w = WIDGET (edit);
1249 WGroup *g = w->owner;
1250
1251 if (edit->locked != 0)
1252 edit->locked = unlock_file (edit->filename_vpath);
1253
1254 group_remove_widget (w);
1255 widget_destroy (w);
1256
1257 if (edit_widget_is_editor (CONST_WIDGET (g->current->data)))
1258 edit = EDIT (g->current->data);
1259 else
1260 {
1261 edit = edit_find_editor (DIALOG (g));
1262 if (edit != NULL)
1263 widget_select (WIDGET (edit));
1264 }
1265 }
1266
1267 if (edit != NULL)
1268 edit->force |= REDRAW_COMPLETELY;
1269
1270 return ret;
1271 }
1272
1273
1274
1275 void
1276 edit_block_copy_cmd (WEdit *edit)
1277 {
1278 off_t start_mark, end_mark, current = edit->buffer.curs1;
1279 off_t mark1 = 0, mark2 = 0;
1280 long c1 = 0, c2 = 0;
1281 off_t size;
1282 unsigned char *copy_buf;
1283
1284 edit_update_curs_col (edit);
1285 if (!eval_marks (edit, &start_mark, &end_mark))
1286 return;
1287
1288 copy_buf = edit_get_block (edit, start_mark, end_mark, &size);
1289
1290
1291
1292 edit_push_markers (edit);
1293
1294 if (edit->column_highlight)
1295 {
1296 long col_delta;
1297
1298 col_delta = labs (edit->column2 - edit->column1);
1299 edit_insert_column_of_text (edit, copy_buf, size, col_delta, &mark1, &mark2, &c1, &c2);
1300 }
1301 else
1302 {
1303 int size_orig = size;
1304
1305 while (size-- != 0)
1306 edit_insert_ahead (edit, copy_buf[size]);
1307
1308
1309 if (edit_options.cursor_after_inserted_block)
1310 edit_cursor_move (edit, size_orig);
1311 }
1312
1313 g_free (copy_buf);
1314 edit_scroll_screen_over_cursor (edit);
1315
1316 if (edit->column_highlight)
1317 edit_set_markers (edit, edit->buffer.curs1, mark2, c1, c2);
1318 else if (start_mark < current && end_mark > current)
1319 edit_set_markers (edit, start_mark, end_mark + end_mark - start_mark, 0, 0);
1320
1321 edit->force |= REDRAW_PAGE;
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 == 0)
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
1578 message (D_ERROR, MSG_ERROR, "%s", _ ("This function is not implemented"));
1579 }
1580
1581
1582
1583 gboolean
1584 edit_copy_to_X_buf_cmd (WEdit *edit)
1585 {
1586 off_t start_mark, end_mark;
1587
1588 if (!eval_marks (edit, &start_mark, &end_mark))
1589 return TRUE;
1590
1591 if (!edit_save_block_to_clip_file (edit, start_mark, end_mark))
1592 {
1593 message (D_ERROR, MSG_ERROR, "%s", _ ("Unable to save to file"));
1594 return FALSE;
1595 }
1596
1597 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
1598
1599 if (edit_options.drop_selection_on_copy)
1600 edit_mark_cmd (edit, TRUE);
1601
1602 return TRUE;
1603 }
1604
1605
1606
1607 gboolean
1608 edit_cut_to_X_buf_cmd (WEdit *edit)
1609 {
1610 off_t start_mark, end_mark;
1611
1612 if (!eval_marks (edit, &start_mark, &end_mark))
1613 return TRUE;
1614
1615 if (!edit_save_block_to_clip_file (edit, start_mark, end_mark))
1616 {
1617 message (D_ERROR, MSG_ERROR, "%s", _ ("Unable to save to file"));
1618 return FALSE;
1619 }
1620
1621 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
1622
1623 edit_block_delete_cmd (edit);
1624 edit_mark_cmd (edit, TRUE);
1625
1626 return TRUE;
1627 }
1628
1629
1630
1631 gboolean
1632 edit_paste_from_X_buf_cmd (WEdit *edit)
1633 {
1634 vfs_path_t *tmp;
1635 gboolean ret;
1636
1637
1638 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_from_ext_clip", NULL);
1639 tmp = mc_config_get_full_vpath (EDIT_HOME_CLIP_FILE);
1640 ret = (edit_insert_file (edit, tmp) >= 0);
1641 vfs_path_free (tmp, TRUE);
1642
1643 return ret;
1644 }
1645
1646
1647
1648
1649
1650
1651
1652 void
1653 edit_goto_cmd (WEdit *edit)
1654 {
1655 static gboolean first_run = TRUE;
1656
1657 char *f;
1658 long l;
1659 char *error;
1660
1661 f = input_dialog (_ ("Goto line"), _ ("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE,
1662 first_run ? NULL : INPUT_LAST_TEXT, INPUT_COMPLETE_NONE);
1663 if (f == NULL || *f == '\0')
1664 {
1665 g_free (f);
1666 return;
1667 }
1668
1669 l = strtol (f, &error, 0);
1670 if (*error != '\0')
1671 {
1672 g_free (f);
1673 return;
1674 }
1675
1676 if (l < 0)
1677 l = edit->buffer.lines + l + 2;
1678
1679 edit_move_display (edit, l - WIDGET (edit)->rect.lines / 2 - 1);
1680 edit_move_to_line (edit, l - 1);
1681 edit->force |= REDRAW_COMPLETELY;
1682
1683 g_free (f);
1684 first_run = FALSE;
1685 }
1686
1687
1688
1689
1690 gboolean
1691 edit_save_block_cmd (WEdit *edit)
1692 {
1693 off_t start_mark, end_mark;
1694 char *exp, *tmp;
1695 gboolean ret = FALSE;
1696
1697 if (!eval_marks (edit, &start_mark, &end_mark))
1698 return TRUE;
1699
1700 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
1701 exp = input_expand_dialog (_ ("Save block"), _ ("Enter file name:"), MC_HISTORY_EDIT_SAVE_BLOCK,
1702 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 message (D_ERROR, MSG_ERROR, "%s", _ ("Cannot save block"));
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 message (D_ERROR, MSG_ERROR, "%s", _ ("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 message (D_ERROR, MSG_ERROR, "%s", _ ("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 = g_strconcat (" sort ", exp, " ", tmp_edit_block_name, " > ", tmp_edit_temp_name,
1786 (char *) NULL);
1787 g_free (tmp_edit_temp_name);
1788 g_free (tmp_edit_block_name);
1789 g_free (exp);
1790
1791 e = system (tmp);
1792 g_free (tmp);
1793 if (e != 0)
1794 {
1795 if (e == -1 || e == 127)
1796 message (D_ERROR, MSG_ERROR, "%s", _ ("Cannot execute sort command"));
1797 else
1798 {
1799 char q[8];
1800
1801 sprintf (q, "%d ", e);
1802 message (D_ERROR, MSG_ERROR, _ ("Sort returned non-zero: %s"), q);
1803 }
1804
1805 return -1;
1806 }
1807
1808 edit->force |= REDRAW_COMPLETELY;
1809
1810 if (!edit_block_delete_cmd (edit))
1811 return 1;
1812
1813 {
1814 vfs_path_t *tmp_vpath;
1815
1816 tmp_vpath = mc_config_get_full_vpath (EDIT_HOME_TEMP_FILE);
1817 edit_insert_file (edit, tmp_vpath);
1818 vfs_path_free (tmp_vpath, TRUE);
1819 }
1820
1821 return 0;
1822 }
1823
1824
1825
1826
1827
1828
1829
1830 int
1831 edit_ext_cmd (WEdit *edit)
1832 {
1833 char *exp, *tmp, *tmp_edit_temp_file;
1834 int e;
1835
1836 exp =
1837 input_dialog (_ ("Paste output of external command"), _ ("Enter shell command(s):"),
1838 MC_HISTORY_EDIT_PASTE_EXTCMD, INPUT_LAST_TEXT,
1839 INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES
1840 | INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS
1841 | INPUT_COMPLETE_SHELL_ESC);
1842
1843 if (!exp)
1844 return 1;
1845
1846 tmp_edit_temp_file = mc_config_get_full_path (EDIT_HOME_TEMP_FILE);
1847 tmp = g_strconcat (exp, " > ", tmp_edit_temp_file, (char *) NULL);
1848 g_free (tmp_edit_temp_file);
1849 e = system (tmp);
1850 g_free (tmp);
1851 g_free (exp);
1852
1853 if (e != 0)
1854 {
1855 message (D_ERROR, MSG_ERROR, "%s", _ ("Cannot execute external command"));
1856 return -1;
1857 }
1858
1859 edit->force |= REDRAW_COMPLETELY;
1860
1861 {
1862 vfs_path_t *tmp_vpath;
1863
1864 tmp_vpath = mc_config_get_full_vpath (EDIT_HOME_TEMP_FILE);
1865 edit_insert_file (edit, tmp_vpath);
1866 vfs_path_free (tmp_vpath, TRUE);
1867 }
1868
1869 return 0;
1870 }
1871
1872
1873
1874
1875
1876
1877 void
1878 edit_block_process_cmd (WEdit *edit, int macro_number)
1879 {
1880 char *fname;
1881 char *macros_fname = NULL;
1882
1883 fname = g_strdup_printf ("%s.%i.sh", EDIT_HOME_MACRO_FILE, macro_number);
1884 macros_fname = g_build_filename (mc_config_get_data_path (), fname, (char *) NULL);
1885 edit_user_menu (edit, macros_fname, 0);
1886 g_free (fname);
1887 g_free (macros_fname);
1888 edit->force |= REDRAW_COMPLETELY;
1889 }
1890
1891
1892
1893 void
1894 edit_mail_dialog (WEdit *edit)
1895 {
1896 char *mail_to = NULL;
1897 char *mail_subject = NULL;
1898 char *mail_cc = NULL;
1899
1900 quick_widget_t quick_widgets[] = {
1901 QUICK_LABEL (N_ ("mail -s <subject> -c <cc> <to>"), NULL),
1902 QUICK_LABELED_INPUT (N_ ("To"), input_label_above, INPUT_LAST_TEXT, "mail-dlg-input-3",
1903 &mail_to, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
1904 QUICK_LABELED_INPUT (N_ ("Subject"), input_label_above, INPUT_LAST_TEXT, "mail-dlg-input-2",
1905 &mail_subject, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
1906 QUICK_LABELED_INPUT (N_ ("Copies to"), input_label_above, INPUT_LAST_TEXT, "mail-dlg-input",
1907 &mail_cc, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
1908 QUICK_BUTTONS_OK_CANCEL,
1909 QUICK_END,
1910 };
1911
1912 WRect r = { -1, -1, 0, 50 };
1913
1914 quick_dialog_t qdlg = {
1915 .rect = r,
1916 .title = N_ ("Mail"),
1917 .help = "[Input Line Keys]",
1918 .widgets = quick_widgets,
1919 .callback = NULL,
1920 .mouse_callback = NULL,
1921 };
1922
1923 if (quick_dialog (&qdlg) != B_CANCEL)
1924 {
1925 pipe_mail (&edit->buffer, mail_to, mail_subject, mail_cc);
1926 g_free (mail_to);
1927 g_free (mail_subject);
1928 g_free (mail_cc);
1929 }
1930 }
1931
1932
1933
1934 void
1935 edit_select_codepage_cmd (WEdit *edit)
1936 {
1937 if (do_select_codepage ())
1938 edit_set_codeset (edit);
1939
1940 edit->force = REDRAW_PAGE;
1941 widget_draw (WIDGET (edit));
1942 }
1943
1944
1945
1946 void
1947 edit_insert_literal_cmd (WEdit *edit)
1948 {
1949 int char_for_insertion;
1950
1951 char_for_insertion =
1952 editcmd_dialog_raw_key_query (_ ("Insert literal"), _ ("Press any key:"), FALSE);
1953 edit_execute_key_command (edit, -1, ascii_alpha_to_cntrl (char_for_insertion));
1954 }
1955
1956
1957
1958 gboolean
1959 edit_load_forward_cmd (WEdit *edit)
1960 {
1961 if (edit->modified != 0
1962 && edit_query_dialog2 (_ ("Warning"),
1963 _ ("Current text was modified without a file save.\n"
1964 "Continue discards these changes."),
1965 _ ("C&ontinue"), _ ("&Cancel"))
1966 == 1)
1967 {
1968 edit->force |= REDRAW_COMPLETELY;
1969 return TRUE;
1970 }
1971
1972 if (edit_stack_iterator + 1 >= MAX_HISTORY_MOVETO)
1973 return FALSE;
1974
1975 if (edit_history_moveto[edit_stack_iterator + 1].line_number < 1)
1976 return FALSE;
1977
1978 edit_stack_iterator++;
1979 if (edit_history_moveto[edit_stack_iterator].file_vpath != NULL)
1980 return edit_reload_line (edit, &edit_history_moveto[edit_stack_iterator]);
1981
1982 return FALSE;
1983 }
1984
1985
1986
1987 gboolean
1988 edit_load_back_cmd (WEdit *edit)
1989 {
1990 if (edit->modified != 0
1991 && edit_query_dialog2 (_ ("Warning"),
1992 _ ("Current text was modified without a file save.\n"
1993 "Continue discards these changes."),
1994 _ ("C&ontinue"), _ ("&Cancel"))
1995 == 1)
1996 {
1997 edit->force |= REDRAW_COMPLETELY;
1998 return TRUE;
1999 }
2000
2001
2002 if (edit_stack_iterator == 0)
2003 return FALSE;
2004
2005 edit_stack_iterator--;
2006 if (edit_history_moveto[edit_stack_iterator].file_vpath != NULL)
2007 return edit_reload_line (edit, &edit_history_moveto[edit_stack_iterator]);
2008
2009 return FALSE;
2010 }
2011
2012
2013
2014
2015
2016
2017
2018
2019 int
2020 editcmd_dialog_raw_key_query (const char *heading, const char *query, gboolean cancel)
2021 {
2022 int w, wq;
2023 int y = 2;
2024 WDialog *raw_dlg;
2025 WGroup *g;
2026
2027 w = str_term_width1 (heading) + 6;
2028 wq = str_term_width1 (query);
2029 w = MAX (w, wq + 3 * 2 + 1 + 2);
2030
2031 raw_dlg = dlg_create (TRUE, 0, 0, cancel ? 7 : 5, w, WPOS_CENTER | WPOS_TRYUP, FALSE,
2032 dialog_colors, editcmd_dialog_raw_key_query_cb, NULL, NULL, heading);
2033 g = GROUP (raw_dlg);
2034 widget_want_tab (WIDGET (raw_dlg), TRUE);
2035
2036 group_add_widget (g, label_new (y, 3, query));
2037 group_add_widget (
2038 g, input_new (y++, 3 + wq + 1, input_colors, w - (6 + wq + 1), "", 0, INPUT_COMPLETE_NONE));
2039 if (cancel)
2040 {
2041 group_add_widget (g, hline_new (y++, -1, -1));
2042
2043 group_add_widget_autopos (g, button_new (y, 1, B_CANCEL, NORMAL_BUTTON, _ ("Cancel"), NULL),
2044 WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
2045 }
2046
2047 w = dlg_run (raw_dlg);
2048 widget_destroy (WIDGET (raw_dlg));
2049
2050 return (cancel && (w == ESC_CHAR || w == B_CANCEL)) ? 0 : w;
2051 }
2052
2053