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 off_t filelen = 0;
134 int this_save_mode, rv, fd = -1;
135 vfs_path_t *real_filename_vpath;
136 vfs_path_t *savename_vpath = NULL;
137 const char *start_filename;
138 const vfs_path_element_t *vpath_element;
139 struct stat sb;
140
141 vpath_element = vfs_path_get_by_index (filename_vpath, 0);
142 if (vpath_element == NULL)
143 return 0;
144
145 start_filename = vpath_element->path;
146 if (*start_filename == '\0')
147 return 0;
148
149 if (!IS_PATH_SEP (*start_filename) && edit->dir_vpath != NULL)
150 real_filename_vpath = vfs_path_append_vpath_new (edit->dir_vpath, filename_vpath, NULL);
151 else
152 real_filename_vpath = vfs_path_clone (filename_vpath);
153
154 this_save_mode = edit_options.save_mode;
155 if (this_save_mode != EDIT_QUICK_SAVE)
156 {
157 if (!vfs_file_is_local (real_filename_vpath))
158
159 this_save_mode = EDIT_QUICK_SAVE;
160 else
161 {
162 fd = mc_open (real_filename_vpath, O_RDONLY | O_BINARY);
163 if (fd == -1)
164
165 this_save_mode = EDIT_QUICK_SAVE;
166 }
167
168 if (fd != -1)
169 mc_close (fd);
170 }
171
172 rv = mc_stat (real_filename_vpath, &sb);
173 if (rv == 0)
174 {
175 if (this_save_mode == EDIT_QUICK_SAVE && edit->skip_detach_prompt == 0 && sb.st_nlink > 1)
176 {
177 rv = edit_query_dialog3 (_("Warning"),
178 _("File has hard-links. Detach before saving?"),
179 _("&Yes"), _("&No"), _("&Cancel"));
180 switch (rv)
181 {
182 case 0:
183 this_save_mode = EDIT_SAFE_SAVE;
184 MC_FALLTHROUGH;
185 case 1:
186 edit->skip_detach_prompt = 1;
187 break;
188 default:
189 vfs_path_free (real_filename_vpath, TRUE);
190 return -1;
191 }
192 }
193
194
195 if (edit->stat1.st_mtime != 0 && edit->stat1.st_mtime != sb.st_mtime)
196 {
197
198 query_set_sel (1);
199
200 rv = edit_query_dialog2 (_("Warning"),
201 _("The file has been modified in the meantime. Save anyway?"),
202 _("&Yes"), _("&Cancel"));
203 if (rv != 0)
204 {
205 vfs_path_free (real_filename_vpath, TRUE);
206 return -1;
207 }
208 }
209 }
210
211 if (this_save_mode == EDIT_QUICK_SAVE)
212 savename_vpath = vfs_path_clone (real_filename_vpath);
213 else
214 {
215 char *savedir, *saveprefix;
216
217 savedir = vfs_path_tokens_get (real_filename_vpath, 0, -1);
218 if (savedir == NULL)
219 savedir = g_strdup (".");
220
221
222 saveprefix = mc_build_filename (PATH_SEP_STR, savedir, "cooledit", (char *) NULL);
223 g_free (savedir);
224 fd = mc_mkstemps (&savename_vpath, saveprefix, NULL);
225 g_free (saveprefix);
226 if (savename_vpath == NULL)
227 {
228 vfs_path_free (real_filename_vpath, TRUE);
229 return 0;
230 }
231
232
233
234
235
236 close (fd);
237 }
238
239 (void) mc_chown (savename_vpath, edit->stat1.st_uid, edit->stat1.st_gid);
240 (void) mc_chmod (savename_vpath, edit->stat1.st_mode);
241 if (edit->attrs_ok)
242 (void) mc_fsetflags (savename_vpath, edit->attrs);
243
244 fd = mc_open (savename_vpath, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, edit->stat1.st_mode);
245 if (fd == -1)
246 goto error_save;
247
248
249 p = edit_get_write_filter (savename_vpath, real_filename_vpath);
250 if (p != NULL)
251 {
252 FILE *file;
253
254 mc_close (fd);
255 file = (FILE *) popen (p, "w");
256
257 if (file != NULL)
258 {
259 filelen = edit_write_stream (edit, file);
260 #if 1
261 pclose (file);
262 #else
263 if (pclose (file) != 0)
264 {
265 message (D_ERROR, MSG_ERROR, _("Error writing to pipe: %s"), p);
266 g_free (p);
267 goto error_save;
268 }
269 #endif
270 }
271 else
272 {
273 message (D_ERROR, MSG_ERROR, _("Cannot open pipe for writing: %s"), p);
274 g_free (p);
275 goto error_save;
276 }
277 g_free (p);
278 }
279 else if (edit->lb == LB_ASIS)
280 {
281 filelen = edit_buffer_write_file (&edit->buffer, fd);
282
283 if (filelen != edit->buffer.size)
284 {
285 mc_close (fd);
286 goto error_save;
287 }
288
289 if (mc_close (fd) != 0)
290 goto error_save;
291
292
293 if (mc_stat (savename_vpath, &edit->stat1) == -1)
294 goto error_save;
295 }
296 else
297 {
298 FILE *file;
299 const char *savename;
300
301 mc_close (fd);
302
303 savename = vfs_path_get_last_path_str (savename_vpath);
304 file = (FILE *) fopen (savename, "w");
305 if (file != NULL)
306 {
307 filelen = edit_write_stream (edit, file);
308 fclose (file);
309 }
310 else
311 {
312 message (D_ERROR, MSG_ERROR, _("Cannot open file for writing: %s"), savename);
313 goto error_save;
314 }
315 }
316
317 if (filelen != edit->buffer.size)
318 goto error_save;
319
320 if (this_save_mode == EDIT_DO_BACKUP)
321 {
322 char *tmp_store_filename;
323 vfs_path_element_t *last_vpath_element;
324 vfs_path_t *tmp_vpath;
325 gboolean ok;
326
327 g_assert (edit_options.backup_ext != NULL);
328
329
330 tmp_vpath = vfs_path_clone (real_filename_vpath);
331 last_vpath_element = (vfs_path_element_t *) vfs_path_get_by_index (tmp_vpath, -1);
332 tmp_store_filename = last_vpath_element->path;
333 last_vpath_element->path =
334 g_strdup_printf ("%s%s", tmp_store_filename, edit_options.backup_ext);
335 g_free (tmp_store_filename);
336
337 ok = (mc_rename (real_filename_vpath, tmp_vpath) != -1);
338 vfs_path_free (tmp_vpath, TRUE);
339 if (!ok)
340 goto error_save;
341 }
342
343 if (this_save_mode != EDIT_QUICK_SAVE && mc_rename (savename_vpath, real_filename_vpath) == -1)
344 goto error_save;
345
346 vfs_path_free (real_filename_vpath, TRUE);
347 vfs_path_free (savename_vpath, TRUE);
348 return 1;
349 error_save:
350
351
352
353
354 vfs_path_free (real_filename_vpath, TRUE);
355 vfs_path_free (savename_vpath, TRUE);
356 return 0;
357 }
358
359
360
361 static gboolean
362 edit_check_newline (const edit_buffer_t *buf)
363 {
364 return !(edit_options.check_nl_at_eof && buf->size > 0
365 && edit_buffer_get_byte (buf, buf->size - 1) != '\n'
366 && edit_query_dialog2 (_("Warning"),
367 _("The file you are saving does not end with a newline."),
368 _("C&ontinue"), _("&Cancel")) != 0);
369 }
370
371
372
373 static vfs_path_t *
374 edit_get_save_file_as (WEdit *edit)
375 {
376 static LineBreaks cur_lb = LB_ASIS;
377 char *filename_res = NULL;
378 vfs_path_t *ret_vpath = NULL;
379
380 const char *lb_names[LB_NAMES] = {
381 N_("&Do not change"),
382 N_("&Unix format (LF)"),
383 N_("&Windows/DOS format (CR LF)"),
384 N_("&Macintosh format (CR)")
385 };
386
387 quick_widget_t quick_widgets[] = {
388
389 QUICK_LABELED_INPUT (N_("Enter file name:"), input_label_above,
390 vfs_path_as_str (edit->filename_vpath), "save-as",
391 &filename_res, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
392 QUICK_SEPARATOR (TRUE),
393 QUICK_LABEL (N_("Change line breaks to:"), NULL),
394 QUICK_RADIO (LB_NAMES, lb_names, (int *) &cur_lb, NULL),
395 QUICK_BUTTONS_OK_CANCEL,
396 QUICK_END
397
398 };
399
400 WRect r = { -1, -1, 0, 64 };
401
402 quick_dialog_t qdlg = {
403 r, N_("Save As"), "[Save File As]",
404 quick_widgets, NULL, NULL
405 };
406
407 if (quick_dialog (&qdlg) != B_CANCEL)
408 {
409 char *fname;
410
411 edit->lb = cur_lb;
412 fname = tilde_expand (filename_res);
413 g_free (filename_res);
414 ret_vpath = vfs_path_from_str (fname);
415 g_free (fname);
416 }
417
418 return ret_vpath;
419 }
420
421
422
423
424
425 static gboolean
426 edit_save_cmd (WEdit *edit)
427 {
428 int save_lock = 0;
429
430 if (edit->locked == 0 && edit->delete_file == 0)
431 save_lock = lock_file (edit->filename_vpath);
432
433 const int res = edit_save_file (edit, edit->filename_vpath);
434
435
436 if ((res > 0 && edit->locked != 0) || save_lock != 0)
437 edit->locked = unlock_file (edit->filename_vpath);
438
439
440 if (res == 0)
441 return edit_save_as_cmd (edit);
442
443 if (res > 0)
444 {
445 edit->delete_file = 0;
446 edit->modified = 0;
447 }
448
449 edit->force |= REDRAW_COMPLETELY;
450
451 return TRUE;
452 }
453
454
455
456 static void
457 edit_delete_column_of_text (WEdit *edit, off_t m1, off_t m2)
458 {
459 off_t n;
460 off_t r;
461 long b, c, d;
462
463 n = edit_buffer_get_forward_offset (&edit->buffer, m1, 0, m2) + 1;
464 r = edit_buffer_get_bol (&edit->buffer, m1);
465 c = (long) edit_move_forward3 (edit, r, 0, m1);
466 r = edit_buffer_get_bol (&edit->buffer, m2);
467 d = (long) edit_move_forward3 (edit, r, 0, m2);
468 b = MAX (MIN (c, d), MIN (edit->column1, edit->column2));
469 c = MAX (c, MAX (edit->column1, edit->column2));
470
471 while (n-- != 0)
472 {
473 off_t p, q;
474
475 r = edit_buffer_get_current_bol (&edit->buffer);
476 p = edit_move_forward3 (edit, r, b, 0);
477 q = edit_move_forward3 (edit, r, c, 0);
478 p = MAX (p, m1);
479 q = MIN (q, m2);
480 edit_cursor_move (edit, p - edit->buffer.curs1);
481
482 for (; q > p; q--)
483 if (edit_buffer_get_current_byte (&edit->buffer) != '\n')
484 edit_delete (edit, TRUE);
485
486
487 if (n != 0)
488 {
489 r = edit_buffer_get_forward_offset (&edit->buffer, edit->buffer.curs1, 1, 0);
490 edit_cursor_move (edit, r - edit->buffer.curs1);
491 }
492 }
493 }
494
495
496
497
498 static gboolean
499 edit_block_delete (WEdit *edit, off_t start_mark, off_t end_mark)
500 {
501 off_t curs_pos;
502 long curs_line, c1, c2;
503
504 if (edit->column_highlight && edit->mark2 < 0)
505 edit_mark_cmd (edit, FALSE);
506
507
508 if ((end_mark - start_mark) > max_undo / 2 &&
509 edit_query_dialog2 (_("Warning"),
510 ("Block is large, you may not be able to undo this action"),
511 _("C&ontinue"), _("&Cancel")) != 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
861 QUICK_RADIO (3, str, &edit_options.save_mode, &edit_save_mode_radio_id),
862 QUICK_INPUT (edit_options.backup_ext, "edit-backup-ext", &str_result,
863 &edit_save_mode_input_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
864 QUICK_SEPARATOR (TRUE),
865 QUICK_CHECKBOX (N_("Check &POSIX new line"), &edit_options.check_nl_at_eof, NULL),
866 QUICK_BUTTONS_OK_CANCEL,
867 QUICK_END
868
869 };
870
871 WRect r = { -1, -1, 0, 38 };
872
873 quick_dialog_t qdlg = {
874 r, N_("Edit Save Mode"), "[Edit Save Mode]",
875 quick_widgets, edit_save_mode_callback, NULL
876 };
877
878 if (quick_dialog (&qdlg) != B_CANCEL)
879 {
880 g_free (edit_options.backup_ext);
881 edit_options.backup_ext = str_result;
882 }
883 }
884 }
885
886
887
888 void
889 edit_set_filename (WEdit *edit, const vfs_path_t *name_vpath)
890 {
891 vfs_path_free (edit->filename_vpath, TRUE);
892 edit->filename_vpath = vfs_path_clone (name_vpath);
893
894 if (edit->dir_vpath == NULL)
895 edit->dir_vpath = vfs_path_clone (vfs_get_raw_current_dir ());
896 }
897
898
899
900
901
902 gboolean
903 edit_save_as_cmd (WEdit *edit)
904 {
905
906 vfs_path_t *exp_vpath;
907 int save_lock = 0;
908 gboolean different_filename = FALSE;
909 gboolean ret = FALSE;
910
911 if (!edit_check_newline (&edit->buffer))
912 return FALSE;
913
914 exp_vpath = edit_get_save_file_as (edit);
915 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
916
917 if (exp_vpath != NULL && vfs_path_len (exp_vpath) != 0)
918 {
919 int rv;
920
921 if (!vfs_path_equal (edit->filename_vpath, exp_vpath))
922 {
923 int file;
924 struct stat sb;
925
926 if (mc_stat (exp_vpath, &sb) == 0 && !S_ISREG (sb.st_mode))
927 {
928 message (D_ERROR, MSG_ERROR, "%s",
929 _("Cannot save: destination is not a regular file"));
930 goto ret;
931 }
932
933 different_filename = TRUE;
934 file = mc_open (exp_vpath, O_RDONLY | O_BINARY);
935
936 if (file == -1)
937 edit->stat1.st_mode |= S_IWUSR;
938 else
939 {
940
941 mc_close (file);
942
943 if (edit_query_dialog2
944 (_("Warning"),
945 _("A file already exists with this name"), _("&Overwrite"), _("&Cancel")))
946 goto ret;
947 }
948
949 save_lock = lock_file (exp_vpath);
950 }
951 else if (edit->locked == 0 && edit->delete_file == 0)
952
953 save_lock = lock_file (exp_vpath);
954
955 if (different_filename)
956
957
958 edit->stat1.st_mode |= S_IWUSR;
959
960 rv = edit_save_file (edit, exp_vpath);
961 switch (rv)
962 {
963 case 1:
964
965 if (different_filename)
966 {
967 if (save_lock != 0)
968 unlock_file (exp_vpath);
969 if (edit->locked != 0)
970 edit->locked = unlock_file (edit->filename_vpath);
971 }
972 else if (edit->locked != 0 || save_lock != 0)
973 edit->locked = unlock_file (edit->filename_vpath);
974
975 edit_set_filename (edit, exp_vpath);
976 if (edit->lb != LB_ASIS)
977 edit_reload (edit, exp_vpath);
978 edit->modified = 0;
979 edit->delete_file = 0;
980 if (different_filename)
981 edit_load_syntax (edit, NULL, edit->syntax_type);
982 ret = TRUE;
983 break;
984
985 default:
986 message (D_ERROR, MSG_ERROR, "%s", _("Cannot save file"));
987 MC_FALLTHROUGH;
988
989 case -1:
990
991 if (save_lock != 0)
992 unlock_file (exp_vpath);
993 break;
994 }
995 }
996
997 ret:
998 vfs_path_free (exp_vpath, TRUE);
999 edit->force |= REDRAW_COMPLETELY;
1000 return ret;
1001 }
1002
1003
1004
1005
1006 gboolean
1007 edit_save_confirm_cmd (WEdit *edit)
1008 {
1009 if (edit->filename_vpath == NULL)
1010 return edit_save_as_cmd (edit);
1011
1012 if (!edit_check_newline (&edit->buffer))
1013 return FALSE;
1014
1015 if (edit_options.confirm_save)
1016 {
1017 char *f;
1018 gboolean ok;
1019
1020 f = g_strdup_printf (_("Confirm save file: \"%s\""),
1021 vfs_path_as_str (edit->filename_vpath));
1022 ok = (edit_query_dialog2 (_("Save file"), f, _("&Save"), _("&Cancel")) == 0);
1023 g_free (f);
1024 if (!ok)
1025 return FALSE;
1026 }
1027
1028 return edit_save_cmd (edit);
1029 }
1030
1031
1032
1033
1034
1035
1036
1037
1038 gboolean
1039 edit_load_cmd (WDialog *h)
1040 {
1041 char *exp;
1042 gboolean ret = TRUE;
1043
1044 exp = input_expand_dialog (_("Load"), _("Enter file name:"),
1045 MC_HISTORY_EDIT_LOAD, INPUT_LAST_TEXT,
1046 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"),
1133 _("Which syntax file you want to edit?"), D_NORMAL, 2,
1134 _("&User"), _("&System wide"));
1135
1136 extdir_vpath =
1137 vfs_path_build_filename (mc_global.sysconfig_dir, EDIT_SYNTAX_FILE, (char *) NULL);
1138 if (!exist_file (vfs_path_get_last_path_str (extdir_vpath)))
1139 {
1140 vfs_path_free (extdir_vpath, TRUE);
1141 extdir_vpath =
1142 vfs_path_build_filename (mc_global.share_data_dir, EDIT_SYNTAX_FILE, (char *) NULL);
1143 }
1144
1145 if (dir == 0)
1146 {
1147 vfs_path_t *user_syntax_file_vpath;
1148
1149 user_syntax_file_vpath = mc_config_get_full_vpath (EDIT_SYNTAX_FILE);
1150 check_for_default (extdir_vpath, user_syntax_file_vpath);
1151 edit_arg_init (&arg, user_syntax_file_vpath, 0);
1152 ret = edit_load_file_from_filename (h, &arg);
1153 vfs_path_free (user_syntax_file_vpath, TRUE);
1154 }
1155 else if (dir == 1)
1156 {
1157 edit_arg_init (&arg, extdir_vpath, 0);
1158 ret = edit_load_file_from_filename (h, &arg);
1159 }
1160
1161 vfs_path_free (extdir_vpath, TRUE);
1162
1163 return ret;
1164 }
1165
1166
1167
1168
1169
1170
1171
1172
1173 gboolean
1174 edit_load_menu_file (WDialog *h)
1175 {
1176 vfs_path_t *buffer_vpath;
1177 vfs_path_t *menufile_vpath;
1178 int dir;
1179 edit_arg_t arg;
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 edit_arg_init (&arg, buffer_vpath, 0);
1226 ret = edit_load_file_from_filename (h, &arg);
1227
1228 vfs_path_free (buffer_vpath, TRUE);
1229 vfs_path_free (menufile_vpath, TRUE);
1230
1231 return ret;
1232 }
1233
1234
1235
1236
1237
1238
1239
1240
1241 gboolean
1242 edit_close_cmd (WEdit *edit)
1243 {
1244 gboolean ret;
1245
1246 ret = (edit != NULL) && edit_ok_to_exit (edit);
1247
1248 if (ret)
1249 {
1250 Widget *w = WIDGET (edit);
1251 WGroup *g = w->owner;
1252
1253 if (edit->locked != 0)
1254 edit->locked = unlock_file (edit->filename_vpath);
1255
1256 group_remove_widget (w);
1257 widget_destroy (w);
1258
1259 if (edit_widget_is_editor (CONST_WIDGET (g->current->data)))
1260 edit = EDIT (g->current->data);
1261 else
1262 {
1263 edit = edit_find_editor (DIALOG (g));
1264 if (edit != NULL)
1265 widget_select (WIDGET (edit));
1266 }
1267 }
1268
1269 if (edit != NULL)
1270 edit->force |= REDRAW_COMPLETELY;
1271
1272 return ret;
1273 }
1274
1275
1276
1277 void
1278 edit_block_copy_cmd (WEdit *edit)
1279 {
1280 off_t start_mark, end_mark, current = edit->buffer.curs1;
1281 off_t mark1 = 0, mark2 = 0;
1282 long c1 = 0, c2 = 0;
1283 off_t size;
1284 unsigned char *copy_buf;
1285
1286 edit_update_curs_col (edit);
1287 if (!eval_marks (edit, &start_mark, &end_mark))
1288 return;
1289
1290 copy_buf = edit_get_block (edit, start_mark, end_mark, &size);
1291
1292
1293
1294 edit_push_markers (edit);
1295
1296 if (edit->column_highlight)
1297 {
1298 long col_delta;
1299
1300 col_delta = labs (edit->column2 - edit->column1);
1301 edit_insert_column_of_text (edit, copy_buf, size, col_delta, &mark1, &mark2, &c1, &c2);
1302 }
1303 else
1304 {
1305 int size_orig = size;
1306
1307 while (size-- != 0)
1308 edit_insert_ahead (edit, copy_buf[size]);
1309
1310
1311 if (edit_options.cursor_after_inserted_block)
1312 edit_cursor_move (edit, size_orig);
1313 }
1314
1315 g_free (copy_buf);
1316 edit_scroll_screen_over_cursor (edit);
1317
1318 if (edit->column_highlight)
1319 edit_set_markers (edit, edit->buffer.curs1, mark2, c1, c2);
1320 else if (start_mark < current && end_mark > current)
1321 edit_set_markers (edit, start_mark, end_mark + end_mark - start_mark, 0, 0);
1322
1323 edit->force |= REDRAW_PAGE;
1324 }
1325
1326
1327
1328
1329 void
1330 edit_block_move_cmd (WEdit *edit)
1331 {
1332 off_t current;
1333 unsigned char *copy_buf = NULL;
1334 off_t start_mark, end_mark;
1335
1336 if (!eval_marks (edit, &start_mark, &end_mark))
1337 return;
1338
1339 if (!edit->column_highlight && edit->buffer.curs1 > start_mark && edit->buffer.curs1 < end_mark)
1340 return;
1341
1342 if (edit->mark2 < 0)
1343 edit_mark_cmd (edit, FALSE);
1344 edit_push_markers (edit);
1345
1346 if (edit->column_highlight)
1347 {
1348 off_t mark1, mark2;
1349 off_t size;
1350 long c1, c2, b_width;
1351 long x, x2;
1352 off_t b1, b2;
1353
1354 c1 = MIN (edit->column1, edit->column2);
1355 c2 = MAX (edit->column1, edit->column2);
1356 b_width = c2 - c1;
1357
1358 edit_update_curs_col (edit);
1359
1360 x = edit->curs_col;
1361 x2 = x + edit->over_col;
1362
1363
1364 b1 = edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1);
1365 b2 = edit_buffer_get_eol (&edit->buffer, start_mark);
1366 if (b1 == b2 && x2 > c1 && x2 <= c2)
1367 return;
1368
1369 if (edit->buffer.curs1 > start_mark
1370 && edit->buffer.curs1 < edit_buffer_get_eol (&edit->buffer, end_mark))
1371 {
1372 if (x > c2)
1373 x -= b_width;
1374 else if (x > c1 && x <= c2)
1375 x = c1;
1376 }
1377
1378 copy_buf = edit_get_block (edit, start_mark, end_mark, &size);
1379
1380
1381 edit_block_delete_cmd (edit);
1382
1383 edit->over_col = MAX (0, edit->over_col - b_width);
1384
1385 b1 = edit_buffer_get_current_bol (&edit->buffer);
1386 current = edit_move_forward3 (edit, b1, x, 0);
1387 edit_cursor_move (edit, current - edit->buffer.curs1);
1388 edit_scroll_screen_over_cursor (edit);
1389
1390
1391 if (edit_options.cursor_beyond_eol && edit->over_col > 0)
1392 edit_insert_over (edit);
1393
1394 edit_insert_column_of_text (edit, copy_buf, size, b_width, &mark1, &mark2, &c1, &c2);
1395 edit_set_markers (edit, mark1, mark2, c1, c2);
1396 }
1397 else
1398 {
1399 off_t count, count_orig;
1400 off_t x;
1401
1402 current = edit->buffer.curs1;
1403 copy_buf = g_malloc0 (end_mark - start_mark);
1404 edit_cursor_move (edit, start_mark - edit->buffer.curs1);
1405 edit_scroll_screen_over_cursor (edit);
1406
1407 for (count = start_mark; count < end_mark; count++)
1408 copy_buf[end_mark - count - 1] = edit_delete (edit, TRUE);
1409
1410 edit_scroll_screen_over_cursor (edit);
1411 x = current > edit->buffer.curs1 ? end_mark - start_mark : 0;
1412 edit_cursor_move (edit, current - edit->buffer.curs1 - x);
1413 edit_scroll_screen_over_cursor (edit);
1414 count_orig = count;
1415 while (count-- > start_mark)
1416 edit_insert_ahead (edit, copy_buf[end_mark - count - 1]);
1417
1418 edit_set_markers (edit, edit->buffer.curs1, edit->buffer.curs1 + end_mark - start_mark, 0,
1419 0);
1420
1421
1422 if (edit_options.cursor_after_inserted_block)
1423 edit_cursor_move (edit, count_orig - start_mark);
1424 }
1425
1426 edit_scroll_screen_over_cursor (edit);
1427 g_free (copy_buf);
1428 edit->force |= REDRAW_PAGE;
1429 }
1430
1431
1432
1433
1434 gboolean
1435 edit_block_delete_cmd (WEdit *edit)
1436 {
1437 off_t start_mark, end_mark;
1438
1439 if (eval_marks (edit, &start_mark, &end_mark))
1440 return edit_block_delete (edit, start_mark, end_mark);
1441
1442 edit_delete_line (edit);
1443
1444 return TRUE;
1445 }
1446
1447
1448
1449
1450
1451
1452
1453
1454 gboolean
1455 edit_ok_to_exit (WEdit *edit)
1456 {
1457 const char *fname = N_("[NoName]");
1458 char *msg;
1459 int act;
1460
1461 if (edit->modified == 0)
1462 return TRUE;
1463
1464 if (edit->filename_vpath != NULL)
1465 fname = vfs_path_as_str (edit->filename_vpath);
1466 #ifdef ENABLE_NLS
1467 else
1468 fname = _(fname);
1469 #endif
1470
1471 if (!mc_global.midnight_shutdown)
1472 {
1473 query_set_sel (2);
1474
1475 msg = g_strdup_printf (_("File %s was modified.\nSave before close?"), fname);
1476 act = edit_query_dialog3 (_("Close file"), msg, _("&Yes"), _("&No"), _("&Cancel"));
1477 }
1478 else
1479 {
1480 msg = g_strdup_printf (_("Midnight Commander is being shut down.\nSave modified file %s?"),
1481 fname);
1482 act = edit_query_dialog2 (_("Quit"), msg, _("&Yes"), _("&No"));
1483
1484
1485 if (act == -1)
1486 act = 1;
1487 }
1488
1489 g_free (msg);
1490
1491 switch (act)
1492 {
1493 case 0:
1494 if (!mc_global.midnight_shutdown && !edit_check_newline (&edit->buffer))
1495 return FALSE;
1496 edit_push_markers (edit);
1497 edit_set_markers (edit, 0, 0, 0, 0);
1498 if (!edit_save_cmd (edit) || mc_global.midnight_shutdown)
1499 return mc_global.midnight_shutdown;
1500 break;
1501 case 1:
1502 default:
1503 break;
1504 case 2:
1505 case -1:
1506 return FALSE;
1507 }
1508
1509 return TRUE;
1510 }
1511
1512
1513
1514
1515 gboolean
1516 edit_save_block (WEdit *edit, const char *filename, off_t start, off_t finish)
1517 {
1518 int file;
1519 off_t len = 1;
1520 vfs_path_t *vpath;
1521
1522 vpath = vfs_path_from_str (filename);
1523 file = mc_open (vpath, O_CREAT | O_WRONLY | O_TRUNC,
1524 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_BINARY);
1525 vfs_path_free (vpath, TRUE);
1526 if (file == -1)
1527 return FALSE;
1528
1529 if (edit->column_highlight)
1530 {
1531 int r;
1532
1533 r = mc_write (file, VERTICAL_MAGIC, sizeof (VERTICAL_MAGIC));
1534 if (r > 0)
1535 {
1536 unsigned char *block, *p;
1537
1538 p = block = edit_get_block (edit, start, finish, &len);
1539 while (len != 0)
1540 {
1541 r = mc_write (file, p, len);
1542 if (r < 0)
1543 break;
1544 p += r;
1545 len -= r;
1546 }
1547 g_free (block);
1548 }
1549 }
1550 else
1551 {
1552 unsigned char *buf;
1553 off_t i = start;
1554
1555 len = finish - start;
1556 buf = g_malloc0 (TEMP_BUF_LEN);
1557 while (start != finish)
1558 {
1559 off_t end;
1560
1561 end = MIN (finish, start + TEMP_BUF_LEN);
1562 for (; i < end; i++)
1563 buf[i - start] = edit_buffer_get_byte (&edit->buffer, i);
1564 len -= mc_write (file, (char *) buf, end - start);
1565 start = end;
1566 }
1567 g_free (buf);
1568 }
1569 mc_close (file);
1570
1571 return (len == 0);
1572 }
1573
1574
1575
1576 void
1577 edit_paste_from_history (WEdit *edit)
1578 {
1579 (void) edit;
1580
1581 message (D_ERROR, MSG_ERROR, "%s", _("This function is not implemented"));
1582 }
1583
1584
1585
1586 gboolean
1587 edit_copy_to_X_buf_cmd (WEdit *edit)
1588 {
1589 off_t start_mark, end_mark;
1590
1591 if (!eval_marks (edit, &start_mark, &end_mark))
1592 return TRUE;
1593
1594 if (!edit_save_block_to_clip_file (edit, start_mark, end_mark))
1595 {
1596 message (D_ERROR, MSG_ERROR, "%s", _("Unable to save to file"));
1597 return FALSE;
1598 }
1599
1600 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
1601
1602 if (edit_options.drop_selection_on_copy)
1603 edit_mark_cmd (edit, TRUE);
1604
1605 return TRUE;
1606 }
1607
1608
1609
1610 gboolean
1611 edit_cut_to_X_buf_cmd (WEdit *edit)
1612 {
1613 off_t start_mark, end_mark;
1614
1615 if (!eval_marks (edit, &start_mark, &end_mark))
1616 return TRUE;
1617
1618 if (!edit_save_block_to_clip_file (edit, start_mark, end_mark))
1619 {
1620 message (D_ERROR, MSG_ERROR, "%s", _("Unable to save to file"));
1621 return FALSE;
1622 }
1623
1624 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
1625
1626 edit_block_delete_cmd (edit);
1627 edit_mark_cmd (edit, TRUE);
1628
1629 return TRUE;
1630 }
1631
1632
1633
1634 gboolean
1635 edit_paste_from_X_buf_cmd (WEdit *edit)
1636 {
1637 vfs_path_t *tmp;
1638 gboolean ret;
1639
1640
1641 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_from_ext_clip", NULL);
1642 tmp = mc_config_get_full_vpath (EDIT_HOME_CLIP_FILE);
1643 ret = (edit_insert_file (edit, tmp) >= 0);
1644 vfs_path_free (tmp, TRUE);
1645
1646 return ret;
1647 }
1648
1649
1650
1651
1652
1653
1654
1655 void
1656 edit_goto_cmd (WEdit *edit)
1657 {
1658 static gboolean first_run = TRUE;
1659
1660 char *f;
1661 long l;
1662 char *error;
1663
1664 f = input_dialog (_("Goto line"), _("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE,
1665 first_run ? NULL : INPUT_LAST_TEXT, INPUT_COMPLETE_NONE);
1666 if (f == NULL || *f == '\0')
1667 {
1668 g_free (f);
1669 return;
1670 }
1671
1672 l = strtol (f, &error, 0);
1673 if (*error != '\0')
1674 {
1675 g_free (f);
1676 return;
1677 }
1678
1679 if (l < 0)
1680 l = edit->buffer.lines + l + 2;
1681
1682 edit_move_display (edit, l - WIDGET (edit)->rect.lines / 2 - 1);
1683 edit_move_to_line (edit, l - 1);
1684 edit->force |= REDRAW_COMPLETELY;
1685
1686 g_free (f);
1687 first_run = FALSE;
1688 }
1689
1690
1691
1692
1693 gboolean
1694 edit_save_block_cmd (WEdit *edit)
1695 {
1696 off_t start_mark, end_mark;
1697 char *exp, *tmp;
1698 gboolean ret = FALSE;
1699
1700 if (!eval_marks (edit, &start_mark, &end_mark))
1701 return TRUE;
1702
1703 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
1704 exp =
1705 input_expand_dialog (_("Save block"), _("Enter file name:"),
1706 MC_HISTORY_EDIT_SAVE_BLOCK, tmp, INPUT_COMPLETE_FILENAMES);
1707 g_free (tmp);
1708 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
1709
1710 if (exp != NULL && *exp != '\0')
1711 {
1712 if (edit_save_block (edit, exp, start_mark, end_mark))
1713 ret = TRUE;
1714 else
1715 message (D_ERROR, MSG_ERROR, "%s", _("Cannot save block"));
1716
1717 edit->force |= REDRAW_COMPLETELY;
1718 }
1719
1720 g_free (exp);
1721
1722 return ret;
1723 }
1724
1725
1726
1727
1728 gboolean
1729 edit_insert_file_cmd (WEdit *edit)
1730 {
1731 char *tmp;
1732 char *exp;
1733 gboolean ret = FALSE;
1734
1735 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
1736 exp = input_expand_dialog (_("Insert file"), _("Enter file name:"),
1737 MC_HISTORY_EDIT_INSERT_FILE, tmp, INPUT_COMPLETE_FILENAMES);
1738 g_free (tmp);
1739
1740 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
1741
1742 if (exp != NULL && *exp != '\0')
1743 {
1744 vfs_path_t *exp_vpath;
1745
1746 exp_vpath = vfs_path_from_str (exp);
1747 ret = (edit_insert_file (edit, exp_vpath) >= 0);
1748 vfs_path_free (exp_vpath, TRUE);
1749
1750 if (!ret)
1751 message (D_ERROR, MSG_ERROR, "%s", _("Cannot insert file"));
1752 }
1753
1754 g_free (exp);
1755
1756 edit->force |= REDRAW_COMPLETELY;
1757 return ret;
1758 }
1759
1760
1761
1762
1763 int
1764 edit_sort_cmd (WEdit *edit)
1765 {
1766 char *exp, *tmp, *tmp_edit_block_name, *tmp_edit_temp_name;
1767 off_t start_mark, end_mark;
1768 int e;
1769
1770 if (!eval_marks (edit, &start_mark, &end_mark))
1771 {
1772 message (D_ERROR, MSG_ERROR, "%s", _("You must first highlight a block of text"));
1773 return 0;
1774 }
1775
1776 tmp = mc_config_get_full_path (EDIT_HOME_BLOCK_FILE);
1777 edit_save_block (edit, tmp, start_mark, end_mark);
1778 g_free (tmp);
1779
1780 exp = input_dialog (_("Run sort"),
1781 _("Enter sort options (see sort(1) manpage) separated by whitespace:"),
1782 MC_HISTORY_EDIT_SORT, INPUT_LAST_TEXT, INPUT_COMPLETE_NONE);
1783
1784 if (exp == NULL)
1785 return 1;
1786
1787 tmp_edit_block_name = mc_config_get_full_path (EDIT_HOME_BLOCK_FILE);
1788 tmp_edit_temp_name = mc_config_get_full_path (EDIT_HOME_TEMP_FILE);
1789 tmp =
1790 g_strconcat (" sort ", exp, " ", tmp_edit_block_name,
1791 " > ", tmp_edit_temp_name, (char *) NULL);
1792 g_free (tmp_edit_temp_name);
1793 g_free (tmp_edit_block_name);
1794 g_free (exp);
1795
1796 e = system (tmp);
1797 g_free (tmp);
1798 if (e != 0)
1799 {
1800 if (e == -1 || e == 127)
1801 message (D_ERROR, MSG_ERROR, "%s", _("Cannot execute sort command"));
1802 else
1803 {
1804 char q[8];
1805
1806 sprintf (q, "%d ", e);
1807 message (D_ERROR, MSG_ERROR, _("Sort returned non-zero: %s"), q);
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 message (D_ERROR, MSG_ERROR, "%s", _("Cannot execute external 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 = NULL;
1902 char *mail_subject = NULL;
1903 char *mail_cc = NULL;
1904
1905 quick_widget_t quick_widgets[] = {
1906
1907 QUICK_LABEL (N_("mail -s <subject> -c <cc> <to>"), NULL),
1908 QUICK_LABELED_INPUT (N_("To"), input_label_above,
1909 INPUT_LAST_TEXT, "mail-dlg-input-3",
1910 &mail_to, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
1911 QUICK_LABELED_INPUT (N_("Subject"), input_label_above,
1912 INPUT_LAST_TEXT, "mail-dlg-input-2",
1913 &mail_subject, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
1914 QUICK_LABELED_INPUT (N_("Copies to"), input_label_above,
1915 INPUT_LAST_TEXT, "mail-dlg-input",
1916 &mail_cc, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
1917 QUICK_BUTTONS_OK_CANCEL,
1918 QUICK_END
1919
1920 };
1921
1922 WRect r = { -1, -1, 0, 50 };
1923
1924 quick_dialog_t qdlg = {
1925 r, N_("Mail"), "[Input Line Keys]",
1926 quick_widgets, NULL, NULL
1927 };
1928
1929 if (quick_dialog (&qdlg) != B_CANCEL)
1930 {
1931 pipe_mail (&edit->buffer, mail_to, mail_subject, mail_cc);
1932 g_free (mail_to);
1933 g_free (mail_subject);
1934 g_free (mail_cc);
1935 }
1936 }
1937
1938
1939
1940 #ifdef HAVE_CHARSET
1941 void
1942 edit_select_codepage_cmd (WEdit *edit)
1943 {
1944 if (do_select_codepage ())
1945 edit_set_codeset (edit);
1946
1947 edit->force = REDRAW_PAGE;
1948 widget_draw (WIDGET (edit));
1949 }
1950 #endif
1951
1952
1953
1954 void
1955 edit_insert_literal_cmd (WEdit *edit)
1956 {
1957 int char_for_insertion;
1958
1959 char_for_insertion = editcmd_dialog_raw_key_query (_("Insert literal"),
1960 _("Press any key:"), FALSE);
1961 edit_execute_key_command (edit, -1, ascii_alpha_to_cntrl (char_for_insertion));
1962 }
1963
1964
1965
1966 gboolean
1967 edit_load_forward_cmd (WEdit *edit)
1968 {
1969 if (edit->modified != 0
1970 && edit_query_dialog2 (_("Warning"),
1971 _("Current text was modified without a file save.\n"
1972 "Continue discards these changes."), _("C&ontinue"),
1973 _("&Cancel")) == 1)
1974 {
1975 edit->force |= REDRAW_COMPLETELY;
1976 return TRUE;
1977 }
1978
1979 if (edit_stack_iterator + 1 >= MAX_HISTORY_MOVETO)
1980 return FALSE;
1981
1982 if (edit_history_moveto[edit_stack_iterator + 1].line_number < 1)
1983 return FALSE;
1984
1985 edit_stack_iterator++;
1986 if (edit_history_moveto[edit_stack_iterator].file_vpath != NULL)
1987 return edit_reload_line (edit, &edit_history_moveto[edit_stack_iterator]);
1988
1989 return FALSE;
1990 }
1991
1992
1993
1994 gboolean
1995 edit_load_back_cmd (WEdit *edit)
1996 {
1997 if (edit->modified != 0
1998 && edit_query_dialog2 (_("Warning"),
1999 _("Current text was modified without a file save.\n"
2000 "Continue discards these changes."), _("C&ontinue"),
2001 _("&Cancel")) == 1)
2002 {
2003 edit->force |= REDRAW_COMPLETELY;
2004 return TRUE;
2005 }
2006
2007
2008 if (edit_stack_iterator == 0)
2009 return FALSE;
2010
2011 edit_stack_iterator--;
2012 if (edit_history_moveto[edit_stack_iterator].file_vpath != NULL)
2013 return edit_reload_line (edit, &edit_history_moveto[edit_stack_iterator]);
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