|
@@ -6,17 +6,17 @@ namespace Publicate.Editors {
|
|
|
|
|
|
public class MarkdownEditor : Box, EditorWidget, Savable {
|
|
|
|
|
|
- private Paned leaflet;
|
|
|
+ private Paned paned_view;
|
|
|
|
|
|
private Box toolbar;
|
|
|
- private GtkCommonMark.MarkdownView markdown_view;
|
|
|
+ private GtkCommonMark.MarkdownView? markdown_view = null;
|
|
|
private GtkSource.View text_view;
|
|
|
private GtkSource.Buffer source_buffer;
|
|
|
private GtkSource.LanguageManager language_manager;
|
|
|
private GtkSource.StyleSchemeManager style_manager;
|
|
|
|
|
|
private ScrolledWindow source_scroller;
|
|
|
- private ScrolledWindow markdown_scroller;
|
|
|
+ private ScrolledWindow? markdown_scroller = null;
|
|
|
|
|
|
private ViewerWindow window;
|
|
|
private TabPage page;
|
|
@@ -26,6 +26,7 @@ namespace Publicate.Editors {
|
|
|
private ToggleButton italic_button;
|
|
|
private Button insert_link;
|
|
|
private Button insert_image;
|
|
|
+ private ToggleButton preview_button;
|
|
|
|
|
|
private const string STYLE_HEADING_1 = "Heading 1";
|
|
|
private const string STYLE_HEADING_2 = "Heading 2";
|
|
@@ -65,8 +66,7 @@ namespace Publicate.Editors {
|
|
|
orientation = Orientation.VERTICAL;
|
|
|
|
|
|
source_scroller = new ScrolledWindow ();
|
|
|
- markdown_scroller = new ScrolledWindow ();
|
|
|
- leaflet = new Paned(Orientation.HORIZONTAL);
|
|
|
+ paned_view = new Paned(Orientation.HORIZONTAL);
|
|
|
|
|
|
text_view = new GtkSource.View ();
|
|
|
language_manager = new GtkSource.LanguageManager ();
|
|
@@ -83,7 +83,7 @@ namespace Publicate.Editors {
|
|
|
text_view.bottom_margin = 18;
|
|
|
text_view.left_margin = 18;
|
|
|
text_view.right_margin = 18;
|
|
|
- text_view.buffer.changed.connect (update_preview);
|
|
|
+ text_view.buffer.changed.connect (() => update_preview());
|
|
|
|
|
|
spell_checker = Spelling.Checker.get_default();
|
|
|
spell_adapter = new Spelling.TextBufferAdapter(source_buffer, spell_checker);
|
|
@@ -94,23 +94,13 @@ namespace Publicate.Editors {
|
|
|
|
|
|
source_scroller.set_policy (PolicyType.NEVER, PolicyType.AUTOMATIC);
|
|
|
source_scroller.vexpand = true;
|
|
|
- markdown_scroller.set_policy (PolicyType.NEVER, PolicyType.AUTOMATIC);
|
|
|
- markdown_scroller.vexpand = true;
|
|
|
-
|
|
|
source_scroller.vadjustment.value_changed.connect(sync_scroll);
|
|
|
-
|
|
|
- markdown_view = new GtkCommonMark.MarkdownView ();
|
|
|
- markdown_view.hexpand = true;
|
|
|
- markdown_view.set_wrap_mode (WrapMode.WORD_CHAR);
|
|
|
- markdown_view.widget_embedded.connect(widget_embedded);
|
|
|
-
|
|
|
source_scroller.child = text_view;
|
|
|
- markdown_scroller.child = markdown_view;
|
|
|
+
|
|
|
|
|
|
var source_box = new Box(Orientation.VERTICAL, 0);
|
|
|
source_box.append(source_scroller);
|
|
|
- leaflet.start_child = source_box;
|
|
|
- leaflet.end_child = markdown_scroller;
|
|
|
+ paned_view.start_child = source_box;
|
|
|
|
|
|
Gtk.Settings.get_default().notify["gtk-application-prefer-dark-theme"].connect(() => configure_tags());
|
|
|
configure_tags();
|
|
@@ -142,22 +132,56 @@ namespace Publicate.Editors {
|
|
|
insert_image.tooltip_text = "Insert image";
|
|
|
insert_image.clicked.connect(() => insert_image_clicked());
|
|
|
toolbar.append(insert_image);
|
|
|
+ preview_button = new ToggleButton();
|
|
|
+ preview_button.child = new Image.from_icon_name("view-dual-symbolic");
|
|
|
+ preview_button.tooltip_text = "Markdown Preview";
|
|
|
+ preview_button.active = true;
|
|
|
+ preview_button.clicked.connect(() => toggle_preview());
|
|
|
+ toolbar.append(preview_button);
|
|
|
source_box.append(toolbar);
|
|
|
|
|
|
source_buffer.cursor_moved.connect(() => update_toolbar());
|
|
|
source_buffer.highlight_updated.connect(() => update_toolbar());
|
|
|
- append(leaflet);
|
|
|
+ append(paned_view);
|
|
|
+ initialise_preview();
|
|
|
|
|
|
page = tab_view.add_page (this, null);
|
|
|
}
|
|
|
|
|
|
+ private void initialise_preview() {
|
|
|
+ markdown_scroller = new ScrolledWindow ();
|
|
|
+ markdown_scroller.set_policy (PolicyType.NEVER, PolicyType.AUTOMATIC);
|
|
|
+ markdown_scroller.vexpand = true;
|
|
|
+
|
|
|
+ markdown_view = new GtkCommonMark.MarkdownView ();
|
|
|
+ markdown_view.hexpand = true;
|
|
|
+ markdown_view.set_wrap_mode (WrapMode.WORD_CHAR);
|
|
|
+ markdown_view.widget_embedded.connect(widget_embedded);
|
|
|
+
|
|
|
+ markdown_scroller.child = markdown_view;
|
|
|
+ // markdown_scroller.hadjustment.changed.connect(() => sync_scroll());
|
|
|
+ paned_view.end_child = markdown_scroller;
|
|
|
+ set_leaflet_size();
|
|
|
+ configure_tags();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void destruct_preview() {
|
|
|
+ paned_view.end_child = null;
|
|
|
+ markdown_scroller = null;
|
|
|
+ markdown_view = null;
|
|
|
+ }
|
|
|
+
|
|
|
public void set_zoom_percentage (int percent) {
|
|
|
- var scale = (float)percent / 100f;
|
|
|
- markdown_view.tag_manager.font_scale = scale;
|
|
|
+ if(markdown_view != null) {
|
|
|
+ var scale = (float)percent / 100f;
|
|
|
+ markdown_view.tag_manager.font_scale = scale;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public async void load_asset (Ppub.Publication publication, Ppub.Asset asset) {
|
|
|
- markdown_view.buffer.set_text("", 0);
|
|
|
+ if(markdown_view != null) {
|
|
|
+ markdown_view.buffer.set_text("", 0);
|
|
|
+ }
|
|
|
page.title = asset.name;
|
|
|
this.asset = asset;
|
|
|
|
|
@@ -170,7 +194,11 @@ namespace Publicate.Editors {
|
|
|
text_view.buffer.set_text ((string)text, text.length);
|
|
|
set_tab_name(false);
|
|
|
|
|
|
- Timeout.add_once(100, () => leaflet.position = int.max(300, leaflet.get_width() / 2));
|
|
|
+ Timeout.add_once(100, () => set_leaflet_size());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void set_leaflet_size() {
|
|
|
+ paned_view.position = int.max(300, paned_view.get_width() / 2);
|
|
|
}
|
|
|
|
|
|
public void save_asset(Ppub.Builder builder) {
|
|
@@ -211,7 +239,9 @@ namespace Publicate.Editors {
|
|
|
|
|
|
private void configure_tags() {
|
|
|
var link = new LinkButton("");
|
|
|
- markdown_view.tag_manager.update_link_colour(link.get_color());
|
|
|
+ if(markdown_view != null) {
|
|
|
+ markdown_view.tag_manager.update_link_colour(link.get_color());
|
|
|
+ }
|
|
|
|
|
|
if(Gtk.Settings.get_default().gtk_application_prefer_dark_theme) {
|
|
|
source_buffer.style_scheme = style_manager.get_scheme("Adwaita-dark");
|
|
@@ -221,11 +251,16 @@ namespace Publicate.Editors {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void update_preview() {
|
|
|
+ private void update_preview(bool changes = true) {
|
|
|
+ if(changes) {
|
|
|
+ set_tab_name(true);
|
|
|
+ }
|
|
|
+ if(markdown_view == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
var text = get_text();
|
|
|
markdown_view.buffer.set_text("", 0);
|
|
|
markdown_view.load_from_string((string)text);
|
|
|
- set_tab_name(true);
|
|
|
}
|
|
|
|
|
|
public string get_text() {
|
|
@@ -239,7 +274,9 @@ namespace Publicate.Editors {
|
|
|
}
|
|
|
|
|
|
private void sync_scroll() {
|
|
|
- set_scroll_from_frac(markdown_scroller, get_scroll_frac(source_scroller));
|
|
|
+ if(markdown_scroller != null) {
|
|
|
+ set_scroll_from_frac(markdown_scroller, get_scroll_frac(source_scroller));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private static double get_scroll_frac(ScrolledWindow scroller) {
|
|
@@ -566,6 +603,16 @@ namespace Publicate.Editors {
|
|
|
source_buffer.insert(ref iter, link, link.length);
|
|
|
source_buffer.end_user_action();
|
|
|
}
|
|
|
+
|
|
|
+ private void toggle_preview() {
|
|
|
+ if(preview_button.active) {
|
|
|
+ initialise_preview();
|
|
|
+ update_preview(false);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ destruct_preview();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|