1 /*
2 * marker-editor.c
3 *
4 * Copyright (C) 2017 - 2018 Fabio Colacio
5 *
6 * Marker is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * Marker is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with Marker; see the file LICENSE.md. If not,
18 * see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include <string.h>
23
24 #include <locale.h>
25 #include <glib/gi18n.h>
26
27 #include "marker-prefs.h"
28 #include "marker-string.h"
29
30 #include "marker-editor.h"
31
32 struct _MarkerEditor
33 {
34 GtkBox parent_instance;
35
36 GFile *file;
37 GFileMonitor *file_monitor;
38 gchar* title;
39 gboolean unsaved_changes;
40
41 GtkPaned *paned;
42 GtkBox *vbox;
43 GtkSearchEntry *search_entry;
44 GtkSearchBar *search_bar;
45 MarkerPreview *preview;
46 MarkerSourceView *source_view;
47 GtkScrolledWindow *source_scroll;
48 MarkerViewMode view_mode;
49
50 gboolean search_active;
51 gboolean needs_refresh;
52 guint timer_id;
53
54 GtkTextIter *text_iter;
55 };
56
57 G_DEFINE_TYPE (MarkerEditor, marker_editor, GTK_TYPE_BOX);
58
59 static void
emit_signal_title_changed(MarkerEditor * editor)60 emit_signal_title_changed (MarkerEditor *editor)
61 {
62 g_autofree gchar *title = marker_editor_get_title (editor);
63 g_autofree gchar *raw_title = marker_editor_get_raw_title(editor);
64 g_signal_emit_by_name (editor, "title-changed", title, raw_title);
65 }
66
67 static void
emit_signal_subtitle_changed(MarkerEditor * editor)68 emit_signal_subtitle_changed (MarkerEditor *editor)
69 {
70 g_autofree gchar *subtitle = marker_editor_get_subtitle (editor);
71 g_signal_emit_by_name (editor, "subtitle-changed", subtitle);
72 }
73
74 static gboolean
refresh_timeout_cb(gpointer user_data)75 refresh_timeout_cb (gpointer user_data)
76 {
77 MarkerEditor *editor = user_data;
78 if (editor->needs_refresh)
79 marker_editor_refresh_preview (editor);
80 return G_SOURCE_CONTINUE;
81 }
82
83 static gboolean
file_changed_cb(GFileMonitor * monior,GFile * file,GFile * other_file,GFileMonitorEvent event_type,gpointer user_data)84 file_changed_cb (GFileMonitor *monior,
85 GFile *file,
86 GFile *other_file,
87 GFileMonitorEvent event_type,
88 gpointer user_data)
89 {
90 MarkerEditor * editor = MARKER_EDITOR(user_data);
91 g_assert (MARKER_IS_EDITOR (editor));
92 if (file) {
93 g_autofree gchar *file_contents = NULL;
94 gsize file_size = 0;
95 GError *err = NULL;
96
97 g_file_load_contents (file, NULL, &file_contents, &file_size, NULL, &err);
98
99 if (err)
100 {
101 g_error_free (err);
102 }
103 else
104 {
105 MarkerSourceView *source_view = editor->source_view;
106 GtkSourceBuffer *buffer =
107 GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (source_view)));
108 gtk_source_buffer_begin_not_undoable_action (buffer);
109 marker_source_view_set_text (source_view, file_contents, file_size);
110 gtk_source_buffer_end_not_undoable_action (buffer);
111 }
112
113 editor->unsaved_changes = FALSE;
114
115 }
116 return G_SOURCE_CONTINUE;
117 }
118
119 static void
buffer_changed_cb(GtkTextBuffer * buffer,gpointer user_data)120 buffer_changed_cb (GtkTextBuffer *buffer,
121 gpointer user_data)
122 {
123 MarkerEditor *editor = user_data;
124 if (editor->view_mode != PREVIEW_ONLY_MODE) {
125 editor->unsaved_changes = TRUE;
126 }
127 editor->needs_refresh = TRUE;
128 if (editor->text_iter) {
129 editor->text_iter = NULL;
130 }
131 emit_signal_title_changed (editor);
132 }
133
134 static gboolean
preview_window_closed_cb(GtkWindow * preview_window,GdkEvent * event,gpointer user_data)135 preview_window_closed_cb (GtkWindow *preview_window,
136 GdkEvent *event,
137 gpointer user_data)
138 {
139 GtkWidget *preview = user_data;
140 g_object_ref (preview);
141 gtk_container_remove (GTK_CONTAINER (preview_window), preview);
142 gtk_widget_destroy (GTK_WIDGET (preview_window));
143 return TRUE;
144 }
145
146 static void
search_text_changed(GtkEntry * entry,MarkerEditor * editor)147 search_text_changed (GtkEntry *entry,
148 MarkerEditor *editor)
149 {
150 GtkSourceSearchContext* context = marker_source_get_search_context(editor->source_view);
151 GtkSourceSearchSettings * settings = gtk_source_search_context_get_settings(context);
152 gtk_source_search_settings_set_search_text(settings, gtk_entry_get_text(entry));
153 }
154
155 static void
search_next(GtkEntry * entry,MarkerEditor * editor)156 search_next (GtkEntry *entry,
157 MarkerEditor *editor)
158 {
159 GtkSourceSearchContext* context = marker_source_get_search_context(editor->source_view);
160 GtkTextBuffer * buffer = GTK_TEXT_BUFFER(gtk_source_search_context_get_buffer(context));
161
162 GtkTextIter *iter;
163 GtkTextIter close;
164
165 gtk_text_buffer_get_end_iter(buffer, &close);
166
167 if (editor->text_iter)
168 {
169 iter = editor->text_iter;
170 if (gtk_text_iter_compare(iter, &close) == 0)
171 {
172 gtk_text_buffer_get_start_iter(buffer, iter);
173 }
174 } else {
175 GtkTextIter tmp;
176 iter = &tmp;
177 gtk_text_buffer_get_start_iter(buffer, iter);
178 }
179
180
181 /** TODO use async forward instead **/
182 GtkTextIter start;
183 GtkTextIter end;
184 gtk_text_buffer_get_start_iter(buffer, &start);
185 gtk_text_buffer_get_start_iter(buffer, &end);
186
187 gtk_source_search_context_forward2(context, iter, &start, &end, NULL);
188
189 if (gtk_text_iter_compare(&start, &end) != 0){
190 gtk_text_buffer_select_range(buffer, &start, &end);
191 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(editor->source_view), &start, 0, TRUE, 0, 0);
192 editor->text_iter = gtk_text_iter_copy(&end);
193 } else {
194 gtk_text_buffer_get_start_iter(buffer, &start);
195 editor->text_iter = gtk_text_iter_copy(&start);
196 }
197 }
198
199
200 static void
search_previous(GtkEntry * entry,MarkerEditor * editor)201 search_previous (GtkEntry *entry,
202 MarkerEditor *editor)
203 {
204
205 GtkSourceSearchContext* context = marker_source_get_search_context(editor->source_view);
206 GtkTextBuffer * buffer = GTK_TEXT_BUFFER(gtk_source_search_context_get_buffer(context));
207
208 GtkTextIter *iter;
209 GtkTextIter close;
210
211 gtk_text_buffer_get_start_iter(buffer, &close);
212
213 if (editor->text_iter)
214 {
215 iter = editor->text_iter;
216 if (gtk_text_iter_compare(iter, &close) == 0)
217 {
218 gtk_text_buffer_get_end_iter(buffer, iter);
219 }
220 } else {
221 GtkTextIter tmp;
222 iter = &tmp;
223 gtk_text_buffer_get_start_iter(buffer,iter);
224 }
225
226 /** TODO use async forward instead **/
227 GtkTextIter start;
228 GtkTextIter end;
229 gtk_text_buffer_get_start_iter(buffer, &start);
230 gtk_text_buffer_get_start_iter(buffer, &end);
231
232 gtk_source_search_context_backward2(context, iter, &start, &end, NULL);
233
234 if (gtk_text_iter_compare(&start, &end) != 0){
235 gtk_text_buffer_select_range(buffer, &start, &end);
236 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(editor->source_view), &start, 0, TRUE, 0, 0);
237 editor->text_iter = gtk_text_iter_copy(&start);
238 } else {
239 gtk_text_buffer_get_end_iter(buffer, &start);
240 editor->text_iter = gtk_text_iter_copy(&start);
241 }
242 }
243
244 static void
marker_editor_init(MarkerEditor * editor)245 marker_editor_init (MarkerEditor *editor)
246 {
247 editor->file = NULL;
248 editor->title = g_strdup(_("Untitled.md"));
249 editor->unsaved_changes = FALSE;
250 editor->search_active = FALSE;
251 editor->text_iter = NULL;
252
253 editor->paned = GTK_PANED (gtk_paned_new (GTK_ORIENTATION_HORIZONTAL));
254 editor->vbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0));
255
256 /** SEARCH TOOL BAR **/
257 editor->search_entry = GTK_SEARCH_ENTRY(gtk_search_entry_new());
258
259 GtkSearchBar * sbar = GTK_SEARCH_BAR(gtk_search_bar_new());
260 editor->search_bar = sbar;
261
262 gtk_container_add(GTK_CONTAINER(sbar), GTK_WIDGET(editor->search_entry));
263
264 gtk_box_pack_start(editor->vbox, GTK_WIDGET(sbar), FALSE, TRUE, 0);
265
266 gtk_widget_show_all(GTK_WIDGET(sbar));
267
268 gtk_search_bar_set_search_mode(sbar, FALSE);
269 gtk_search_bar_set_show_close_button(sbar, TRUE);
270
271 g_signal_connect(editor->search_entry,
272 "search-changed",
273 G_CALLBACK(search_text_changed),
274 editor);
275
276 g_signal_connect(editor->search_entry,
277 "activate",
278 G_CALLBACK(search_next),
279 editor);
280
281 g_signal_connect(editor->search_entry,
282 "next-match",
283 G_CALLBACK(search_next),
284 editor);
285
286
287 g_signal_connect(editor->search_entry,
288 "previous-match",
289 G_CALLBACK(search_previous),
290 editor);
291 /** DONE **/
292
293 gtk_paned_set_position (editor->paned, 450);
294 gtk_widget_show (GTK_WIDGET (editor->paned));
295 gtk_box_pack_start (GTK_BOX (editor), GTK_WIDGET (editor->paned), TRUE, TRUE, 0);
296
297 editor->preview = marker_preview_new ();
298 gtk_widget_show (GTK_WIDGET (editor->preview));
299
300 editor->source_view = marker_source_view_new ();
301 gtk_widget_show (GTK_WIDGET (editor->source_view));
302 editor->source_scroll = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new (NULL, NULL));
303 gtk_widget_show (GTK_WIDGET (editor->source_scroll));
304 gtk_container_add (GTK_CONTAINER (editor->source_scroll), GTK_WIDGET (editor->source_view));
305 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->source_view));
306 g_signal_connect (buffer, "changed", G_CALLBACK (buffer_changed_cb), editor);
307
308 gtk_box_pack_end(editor->vbox, GTK_WIDGET(editor->source_scroll), TRUE, TRUE, 0);
309 gtk_widget_show(GTK_WIDGET (editor->vbox));
310 gtk_widget_show(GTK_WIDGET (editor->search_entry));
311
312 editor->view_mode = marker_prefs_get_default_view_mode ();
313 editor->needs_refresh = FALSE;
314
315 marker_editor_set_view_mode (editor, editor->view_mode);
316 gtk_widget_show (GTK_WIDGET (editor));
317
318 editor->timer_id = g_timeout_add (20, refresh_timeout_cb, editor);
319
320 marker_editor_apply_prefs (editor);
321 }
322
323 static void
marker_editor_class_init(MarkerEditorClass * class)324 marker_editor_class_init (MarkerEditorClass *class)
325 {
326 g_signal_new ("title-changed",
327 G_TYPE_FROM_CLASS (class),
328 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
329 0, NULL, NULL, NULL,
330 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
331
332 g_signal_new ("subtitle-changed",
333 G_TYPE_FROM_CLASS (class),
334 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
335 0, NULL, NULL, NULL,
336 G_TYPE_NONE, 1, G_TYPE_STRING);
337 }
338
339 MarkerEditor *
marker_editor_new(void)340 marker_editor_new (void)
341 {
342 return g_object_new (MARKER_TYPE_EDITOR,
343 "orientation", GTK_ORIENTATION_VERTICAL,
344 "spacing", 0,
345 NULL);
346 }
347
348 MarkerEditor *
marker_editor_new_from_file(GFile * file)349 marker_editor_new_from_file (GFile *file)
350 {
351 MarkerEditor *editor = g_object_new (MARKER_TYPE_EDITOR,
352 "orientation", GTK_ORIENTATION_VERTICAL,
353 "spacing", 0, NULL);
354 marker_editor_open_file (editor, file);
355 return editor;
356 }
357
358 void
marker_editor_refresh_preview(MarkerEditor * editor)359 marker_editor_refresh_preview (MarkerEditor *editor)
360 {
361 g_assert (MARKER_IS_EDITOR (editor));
362
363 editor->needs_refresh = FALSE;
364
365 g_autofree gchar *markdown = marker_source_view_get_text (editor->source_view, false);
366 int cursor = marker_source_view_get_cursor_position(editor->source_view);
367
368 const char* css_theme = (marker_prefs_get_use_css_theme()) ? marker_prefs_get_css_theme() : NULL;
369 g_autofree gchar *uri = (G_IS_FILE(editor->file)) ? g_file_get_path(editor->file) : NULL;
370
371 marker_preview_render_markdown(editor->preview, markdown, css_theme, uri, cursor);
372 }
373
374 MarkerViewMode
marker_editor_get_view_mode(MarkerEditor * editor)375 marker_editor_get_view_mode (MarkerEditor *editor)
376 {
377 g_assert (MARKER_IS_EDITOR (editor));
378 return editor->view_mode;
379 }
380
381 void
marker_editor_set_view_mode(MarkerEditor * editor,MarkerViewMode view_mode)382 marker_editor_set_view_mode (MarkerEditor *editor,
383 MarkerViewMode view_mode)
384 {
385 g_assert (MARKER_IS_EDITOR (editor));
386
387 if (editor->view_mode != view_mode){
388 if (view_mode == PREVIEW_ONLY_MODE && editor->file)
389 {
390 editor->file_monitor = g_file_monitor_file(editor->file, G_FILE_MONITOR_NONE, NULL, NULL);
391 g_signal_connect(editor->file_monitor, "changed", G_CALLBACK(file_changed_cb), editor);
392
393 } else if (editor->view_mode == PREVIEW_ONLY_MODE && editor->file)
394 {
395 g_file_monitor_cancel(editor->file_monitor);
396 }
397 }
398 editor->view_mode = view_mode;
399
400 GtkWidget * const paned = GTK_WIDGET (editor->paned);
401 GtkWidget * const preview = GTK_WIDGET (editor->preview);
402 GtkWidget * const source_scroll = GTK_WIDGET (editor->vbox);
403 GtkContainer *parent;
404
405 parent = GTK_CONTAINER (gtk_widget_get_parent (preview));
406 if (parent)
407 {
408 g_object_ref (preview);
409 gtk_container_remove (parent, preview);
410
411 if (GTK_IS_WINDOW (parent))
412 {
413 gtk_widget_destroy (GTK_WIDGET (parent));
414 }
415 }
416
417 parent = GTK_CONTAINER (gtk_widget_get_parent (source_scroll));
418 if (parent)
419 {
420 g_object_ref (source_scroll);
421 gtk_container_remove (parent, source_scroll);
422 }
423
424 switch (view_mode)
425 {
426 case EDITOR_ONLY_MODE:
427 gtk_paned_add1 (GTK_PANED (paned), source_scroll);
428 gtk_widget_grab_focus (GTK_WIDGET (editor->source_view));
429 break;
430
431 case PREVIEW_ONLY_MODE:
432 gtk_paned_add2 (GTK_PANED (paned), preview);
433 gtk_widget_grab_focus (GTK_WIDGET (preview));
434 break;
435
436 case DUAL_PANE_MODE:
437 gtk_paned_add1 (GTK_PANED (paned), source_scroll);
438 gtk_paned_add2 (GTK_PANED (paned), preview);
439 gtk_widget_grab_focus (GTK_WIDGET (editor->source_view));
440 break;
441
442 case DUAL_WINDOW_MODE:
443 gtk_paned_add1(GTK_PANED(paned), source_scroll);
444
445 GtkWindow *preview_window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
446 g_signal_connect(preview_window, "delete-event", G_CALLBACK (preview_window_closed_cb), preview);
447 gtk_container_add (GTK_CONTAINER (preview_window), preview);
448 gtk_window_set_title (preview_window, "Preview");
449 gtk_window_set_default_size (preview_window, 500, 600);
450 gtk_widget_show_all (GTK_WIDGET (preview_window));
451 gtk_widget_grab_focus (GTK_WIDGET (editor->source_view));
452 break;
453 }
454
455 }
456
457 void
marker_editor_open_file(MarkerEditor * editor,GFile * file)458 marker_editor_open_file (MarkerEditor *editor,
459 GFile *file)
460 {
461 g_assert (MARKER_IS_EDITOR (editor));
462
463 if (G_IS_FILE (editor->file))
464 g_object_unref (editor->file);
465
466 editor->file = file;
467 editor->title = g_file_get_basename(file);
468 editor->needs_refresh = TRUE;
469
470 g_autofree gchar *file_contents = NULL;
471 gsize file_size = 0;
472 GError *err = NULL;
473
474 g_file_load_contents (file, NULL, &file_contents, &file_size, NULL, &err);
475
476 if (err)
477 {
478 g_error_free (err);
479 }
480 else
481 {
482 MarkerSourceView *source_view = editor->source_view;
483 GtkSourceBuffer *buffer =
484 GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (source_view)));
485 gtk_source_buffer_begin_not_undoable_action (buffer);
486 marker_source_view_set_text (source_view, file_contents, file_size);
487 gtk_source_buffer_end_not_undoable_action (buffer);
488 }
489
490 editor->unsaved_changes = FALSE;
491
492 emit_signal_title_changed (editor);
493 emit_signal_subtitle_changed (editor);
494 }
495
496 void
marker_editor_save_file(MarkerEditor * editor)497 marker_editor_save_file (MarkerEditor *editor)
498 {
499 g_assert (MARKER_IS_EDITOR (editor));
500 g_return_if_fail (G_IS_FILE (editor->file));
501
502 g_autofree gchar *filepath = g_file_get_path (editor->file);
503
504 FILE *fp = fopen (filepath, "w");
505
506 if (fp)
507 {
508 g_autofree gchar *buffer = marker_source_view_get_text (editor->source_view, false);
509 fputs (buffer, fp);
510 fclose (fp);
511 }
512
513 editor->unsaved_changes = FALSE;
514 emit_signal_title_changed (editor);
515 }
516
517 void
marker_editor_save_file_as(MarkerEditor * editor,GFile * file)518 marker_editor_save_file_as (MarkerEditor *editor,
519 GFile *file)
520 {
521 g_assert (MARKER_IS_EDITOR (editor));
522
523 if (G_IS_FILE (editor->file))
524 {
525 g_object_unref (editor->file);
526 }
527 editor->title = g_file_get_basename(file);
528 editor->file = file;
529 marker_editor_save_file (editor);
530 emit_signal_subtitle_changed (editor);
531 }
532
533 GFile *
marker_editor_get_file(MarkerEditor * editor)534 marker_editor_get_file (MarkerEditor *editor)
535 {
536 g_assert (MARKER_IS_EDITOR (editor));
537 if (G_IS_FILE (editor->file))
538 {
539 return editor->file;
540 }
541 return NULL;
542 }
543
544 gboolean
marker_editor_has_unsaved_changes(MarkerEditor * editor)545 marker_editor_has_unsaved_changes (MarkerEditor *editor)
546 {
547 g_assert (MARKER_IS_EDITOR (editor));
548 return editor->unsaved_changes;
549 }
550
551 gchar *
marker_editor_get_title(MarkerEditor * editor)552 marker_editor_get_title (MarkerEditor *editor)
553 {
554 g_assert (MARKER_IS_EDITOR (editor));
555
556 gchar *title = NULL;
557
558 if (marker_editor_has_unsaved_changes (editor))
559 {
560 title = g_strdup_printf ("*%s", editor->title);
561 }
562 else
563 {
564 title = g_strdup(editor->title);
565 }
566
567 return title;
568 }
569
570 gchar *
marker_editor_get_raw_title(MarkerEditor * editor)571 marker_editor_get_raw_title (MarkerEditor *editor)
572 {
573 g_assert(MARKER_IS_EDITOR(editor));
574 return g_strdup(editor->title);
575 }
576
577 gchar *
marker_editor_get_subtitle(MarkerEditor * editor)578 marker_editor_get_subtitle (MarkerEditor *editor)
579 {
580 g_assert (MARKER_IS_EDITOR (editor));
581
582 gchar *subtitle = NULL;
583 GFile *file = marker_editor_get_file (editor);
584
585 if (G_IS_FILE (file))
586 {
587 g_autofree gchar *path = g_file_get_path (file);
588 subtitle = marker_string_filename_get_path (path);
589 }
590
591 return subtitle;
592 }
593
594 MarkerPreview *
marker_editor_get_preview(MarkerEditor * editor)595 marker_editor_get_preview (MarkerEditor *editor)
596 {
597 g_assert (MARKER_IS_EDITOR (editor));
598 return editor->preview;
599 }
600
601 MarkerSourceView *
marker_editor_get_source_view(MarkerEditor * editor)602 marker_editor_get_source_view (MarkerEditor *editor)
603 {
604 g_assert (MARKER_IS_EDITOR (editor));
605 return editor->source_view;
606 }
607
608 void
marker_editor_apply_prefs(MarkerEditor * editor)609 marker_editor_apply_prefs (MarkerEditor *editor)
610 {
611 g_assert (MARKER_IS_EDITOR (editor));
612
613 GtkSourceView * const source_view = GTK_SOURCE_VIEW (marker_editor_get_source_view (editor));
614
615 gboolean state;
616
617 state = marker_prefs_get_show_line_numbers ();
618 gtk_source_view_set_show_line_numbers (source_view, state);
619
620 state = marker_prefs_get_wrap_text ();
621 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (source_view), (state) ? GTK_WRAP_WORD : GTK_WRAP_NONE );
622
623 state = marker_prefs_get_show_right_margin ();
624 gtk_source_view_set_show_right_margin (source_view, state);
625
626 guint position = marker_prefs_get_right_margin_position ();
627 gtk_source_view_set_right_margin_position (source_view, position);
628
629 state = marker_prefs_get_spell_check ();
630 marker_source_view_set_spell_check (MARKER_SOURCE_VIEW (source_view), state);
631
632 g_autofree gchar *lang = marker_prefs_get_spell_check_language ();
633 marker_source_view_set_spell_check_lang (MARKER_SOURCE_VIEW (source_view), lang);
634
635 state = marker_prefs_get_highlight_current_line ();
636 gtk_source_view_set_highlight_current_line (source_view, state);
637
638 GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (source_view)));
639 state = marker_prefs_get_use_syntax_theme ();
640 gtk_source_buffer_set_highlight_syntax(buffer, state);
641
642 g_autofree gchar *theme = marker_prefs_get_syntax_theme ();
643 marker_source_view_set_syntax_theme (MARKER_SOURCE_VIEW (source_view), theme);
644
645 state = marker_prefs_get_auto_indent ();
646 gtk_source_view_set_auto_indent (source_view, state);
647
648 state = marker_prefs_get_replace_tabs ();
649 gtk_source_view_set_insert_spaces_instead_of_tabs (source_view, state);
650
651 state = marker_prefs_get_show_spaces();
652 GtkSourceSpaceDrawer * space_drawer = gtk_source_view_get_space_drawer(source_view);
653 if (state) {
654 gtk_source_space_drawer_set_types_for_locations(space_drawer, GTK_SOURCE_SPACE_LOCATION_ALL,
655 GTK_SOURCE_SPACE_TYPE_NBSP |
656 GTK_SOURCE_SPACE_TYPE_SPACE |
657 GTK_SOURCE_SPACE_TYPE_TAB);
658 }
659 gtk_source_space_drawer_set_enable_matrix(space_drawer, state);
660
661 guint tab_width = marker_prefs_get_tab_width ();
662 gtk_source_view_set_indent_width (source_view, tab_width);
663 }
664
665
666 void
marker_editor_closing(MarkerEditor * editor)667 marker_editor_closing(MarkerEditor *editor)
668 {
669 g_source_remove (editor->timer_id);
670 editor->needs_refresh = FALSE;
671 }
672
673 gboolean
marker_editor_rename_file(MarkerEditor * editor,gchar * name)674 marker_editor_rename_file (MarkerEditor *editor,
675 gchar* name)
676 {
677 if (G_IS_FILE (editor->file))
678 {
679 /** Get new path **/
680 gchar * parent = marker_editor_get_subtitle(editor);
681 gchar * path = g_strdup_printf("%s/%s",
682 parent,
683 name);
684
685 /** Delete old file **/
686 g_file_delete(editor->file,
687 NULL,
688 NULL);
689
690 /** Save file in new destination **/
691 GFile * file = g_file_new_for_path(path);
692 marker_editor_save_file_as(editor, file);
693 g_free(parent);
694 g_free(path);
695 }else {
696 /** Just change the title... **/
697 editor->title = name;
698 }
699 return TRUE;
700 }
701
702
703 void
marker_editor_toggle_search_bar(MarkerEditor * editor)704 marker_editor_toggle_search_bar (MarkerEditor *editor)
705 {
706 if (!editor->search_active){
707 editor->search_active = TRUE;
708 } else {
709 gtk_entry_set_text(GTK_ENTRY(editor->search_entry), "");
710 if (editor->text_iter)
711 {
712 g_free(editor->text_iter);
713 editor->text_iter = NULL;
714 }
715 }
716
717 gtk_search_bar_set_search_mode (editor->search_bar, editor->search_active);
718 }
719
720 GtkSearchBar*
marker_editor_get_search_bar(MarkerEditor * editor)721 marker_editor_get_search_bar (MarkerEditor *editor)
722 {
723 return editor->search_bar;
724 }
725