| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733 |
- using Gtk;
- using Adw;
- using GtkCommonMark;
- namespace Publicate.Editors {
- public class MarkdownEditor : Box, EditorWidget, Savable {
- private Paned paned_view;
- private Box toolbar;
- 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 = null;
- private ViewerWindow window;
- private TabPage page;
- private DropDown style_selector;
- private ToggleButton bold_button;
- 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";
- private const string STYLE_HEADING_3 = "Heading 3";
- private const string STYLE_HEADING_4 = "Heading 4";
- private const string STYLE_HEADING_5 = "Heading 5";
- private const string STYLE_HEADING_6 = "Heading 6";
- private const string STYLE_QUOTATION = "Quotation";
- private const string STYLE_PREFORMATTED = "Preformatted";
- private const string STYLE_PARAGRAPH = "Paragraph";
- private Spelling.Checker spell_checker;
- private Spelling.TextBufferAdapter spell_adapter;
- private bool inhibit_toolbar_updates = false;
- private Gee.HashMap<string, Gdk.Pixbuf> pixbuf_cache = new Gee.HashMap<string, Gdk.Pixbuf>();
- public Adw.TabPage tab_page { get {
- return page;
- } }
- public string asset_name { get{
- return asset.name;
- } }
- private bool unsaved = false;
- public bool has_unsaved_changes { get{
- return unsaved;
- } }
- private Ppub.Asset asset;
- public MarkdownEditor(ViewerWindow win, TabView tab_view) {
- window = win;
- orientation = Orientation.VERTICAL;
- source_scroller = new ScrolledWindow ();
- paned_view = new Paned(Orientation.HORIZONTAL);
- text_view = new GtkSource.View ();
- language_manager = new GtkSource.LanguageManager ();
- style_manager = new GtkSource.StyleSchemeManager();
- text_view.monospace = true;
- text_view.show_line_numbers = true;
- text_view.auto_indent = true;
- source_buffer = (GtkSource.Buffer) text_view.buffer;
- language_manager.append_search_path("/usr/share/publicate/gtk-source-view");
- source_buffer.language = language_manager.get_language("ppub-markdown");
- text_view.hexpand = true;
- text_view.set_wrap_mode (WrapMode.WORD_CHAR);
- text_view.top_margin = 18;
- text_view.bottom_margin = 18;
- text_view.left_margin = 18;
- text_view.right_margin = 18;
- text_view.buffer.changed.connect (() => update_preview());
- spell_checker = Spelling.Checker.get_default();
- spell_adapter = new Spelling.TextBufferAdapter(source_buffer, spell_checker);
- text_view.set_extra_menu(spell_adapter.get_menu_model());
- text_view.insert_action_group("spelling", spell_adapter);
- spell_adapter.set_enabled(true);
- source_scroller.set_policy (PolicyType.NEVER, PolicyType.AUTOMATIC);
- source_scroller.vexpand = true;
- source_scroller.vadjustment.value_changed.connect(sync_scroll);
- source_scroller.child = text_view;
-
- var source_box = new Box(Orientation.VERTICAL, 0);
- source_box.append(source_scroller);
- paned_view.start_child = source_box;
- Gtk.Settings.get_default().notify["gtk-application-prefer-dark-theme"].connect(() => configure_tags());
- configure_tags();
- toolbar = new Box(Orientation.HORIZONTAL, 8);
- toolbar.margin_start = 8;
- toolbar.margin_end = 8;
- toolbar.margin_top = 8;
- toolbar.margin_bottom = 8;
- style_selector = new DropDown.from_strings(new string[] {STYLE_HEADING_1, STYLE_HEADING_2, STYLE_HEADING_3, STYLE_HEADING_4, STYLE_HEADING_5, STYLE_HEADING_6, STYLE_QUOTATION, STYLE_PREFORMATTED, STYLE_PARAGRAPH});
- toolbar.append(style_selector);
- bold_button = new ToggleButton();
- bold_button.child = new Image.from_icon_name("format-text-bold-symbolic");
- bold_button.tooltip_text = "Bold";
- bold_button.clicked.connect(() => toggle_bold());
- toolbar.append(bold_button);
- italic_button = new ToggleButton();
- italic_button.child = new Image.from_icon_name("format-text-italic-symbolic");
- italic_button.tooltip_text = "Italic";
- italic_button.clicked.connect(() => toggle_italic());
- toolbar.append(italic_button);
- insert_link = new Button.from_icon_name("insert-link-symbolic");
- insert_link.tooltip_text = "Insert link";
- insert_link.hexpand = true;
- insert_link.halign = Align.END;
- insert_link.clicked.connect(() => insert_link_clicked());
- toolbar.append(insert_link);
- insert_image = new Button.from_icon_name("insert-image-symbolic");
- 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(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) {
- 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) {
- if(markdown_view != null) {
- markdown_view.buffer.set_text("", 0);
- }
- page.title = asset.name;
- this.asset = asset;
- text_view.buffer.set_text("", 0);
- MemoryOutputStream os = new MemoryOutputStream (null, GLib.realloc, GLib.free);
- yield os.splice_async (publication.read_asset (asset.name), OutputStreamSpliceFlags.CLOSE_SOURCE | OutputStreamSpliceFlags.CLOSE_TARGET);
- var text = os.steal_data ();
- text.length = (int) os.get_data_size ();
- text_view.buffer.set_text ((string)text, text.length);
- set_tab_name(false);
- 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) {
- var article_data = get_text().to_utf8();
- var article_stream = new MemoryInputStream.from_data((uint8[])article_data);
- var compression_info = new Ppub.CompressionInfo(article_stream);
- article_stream.seek(0, SeekType.SET);
- builder.add_asset(asset.name, asset.mimetype, article_stream, Invercargill.Iterate.nothing<string>(), compression_info);
- set_tab_name(false);
- }
- protected async void widget_embedded(GtkCommonMark.MarkdownViewEmbeddedWidgetHost widget, string file, string title) {
- var image = new Gtk.Picture();
- image.content_fit = Gtk.ContentFit.FILL;
- widget.append (image);
- Gdk.Pixbuf pixbuf;
- if(pixbuf_cache.has_key(file)) {
- pixbuf = pixbuf_cache[file];
- }
- else {
- pixbuf = yield new Gdk.Pixbuf.from_stream_async (window.publication.read_asset (file), null);
- pixbuf_cache.set(file, pixbuf);
- }
- image.set_pixbuf (pixbuf);
- widget.available_width_changed.connect(wid => {
- image.width_request = wid;
- var ratio = image.get_paintable().get_intrinsic_aspect_ratio ();
- image.height_request = (int)(wid / ratio);
- });
- image.destroy.connect(() => print("IT gone\n"));
- }
- private void configure_tags() {
- var link = new LinkButton("");
- 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");
- }
- else {
- source_buffer.style_scheme = style_manager.get_scheme("Adwaita");
- }
- }
- 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);
- }
- public string get_text() {
- TextIter start_iter;
- TextIter end_iter;
- text_view.buffer.get_start_iter (out start_iter);
- text_view.buffer.get_end_iter (out end_iter);
- var text = text_view.buffer.get_text (start_iter, end_iter, true);
- return text;
- }
- private void sync_scroll() {
- if(markdown_scroller != null) {
- set_scroll_from_frac(markdown_scroller, get_scroll_frac(source_scroller));
- }
- }
- private static double get_scroll_frac(ScrolledWindow scroller) {
- return (scroller.vadjustment.value/(scroller.vadjustment.upper - scroller.vadjustment.page_size));
- }
- private void set_scroll_from_frac(ScrolledWindow scroller, double frac) {
- scroller.vadjustment.value = (scroller.vadjustment.upper - scroller.vadjustment.page_size)*frac;
- }
- private void set_tab_name(bool unsaved) {
- this.unsaved = unsaved;
- if(unsaved) {
- tab_page.title = @"⏺ $(asset.name)";
- }
- else {
- tab_page.title = asset.name;
- }
- }
- private void update_toolbar() {
- if(inhibit_toolbar_updates) {
- print("Toolbar update inhibited\n");
- return;
- }
- TextIter iter_start;
- TextIter iter_end;
- source_buffer.get_iter_at_offset(out iter_start, source_buffer.cursor_position);
- var multi_line = false;
- if(source_buffer.has_selection) {
- source_buffer.get_selection_bounds(out iter_start, out iter_end);
- multi_line = (iter_start.get_line() != iter_end.get_line());
- }
- var classes = Invercargill.Wrap.array<string>(source_buffer.get_context_classes_at_iter(iter_start));
- // Disable formatting changes if the selection is over many lines or the "no-format" class is applied
- toolbar.sensitive = !multi_line && !classes.any(c => c == "no-format");
- print(@"$(classes.to_string(s => s, " "))\n");
-
- set_line_style_type_in_dropdown(get_line_style_from_buffer());
- bold_button.active = classes.any(c => c == "b");
- italic_button.active = classes.any(c => c == "i");
- }
- private int get_line_style_from_buffer() {
- TextIter iter;
- source_buffer.get_iter_at_offset(out iter, source_buffer.cursor_position);
- if(iter.ends_line()) {
- iter.backward_char();
- }
- var classes = Invercargill.Wrap.array<string>(source_buffer.get_context_classes_at_iter(iter));
- var heading = classes.first_or_default(c => c.has_prefix("h") && c.length == 2);
- if(heading != null) {
- var level = int.parse(heading[1:2]);
- return level - 1;
- }
- else if(classes.any(c => c == "quot")) {
- return 6;
- }
- else if(classes.any(c => c == "pre")) {
- return 7;
- }
- return 8;
- }
- private void remove_line_style() {
- TextIter iter;
- source_buffer.get_iter_at_offset(out iter, source_buffer.cursor_position);
- if(iter.ends_line()) {
- iter.backward_char();
- }
- var classes = Invercargill.Wrap.array<string>(source_buffer.get_context_classes_at_iter(iter));
- var line_no = iter.get_line();
- var heading = classes.first_or_default(c => c.has_prefix("h") && c.length == 2);
- if(heading != null) {
- var level = int.parse(heading[1:2]);
- source_buffer.get_iter_at_line(out iter, line_no);
- iter.forward_chars(level+1);
- for(int i = 0; i <= level; i++) {
- source_buffer.backspace(ref iter, false, true);
- }
- }
- else if(classes.any(c => c == "quot")) {
- source_buffer.get_iter_at_line(out iter, line_no);
- iter.forward_chars(2);
- source_buffer.backspace(ref iter, false, true);
- source_buffer.backspace(ref iter, false, true);
- }
- }
- private void set_line_style_type_in_dropdown(uint type) {
- style_selector.notify["selected"].disconnect(set_line_style);
- style_selector.selected = type;
- style_selector.notify["selected"].connect(set_line_style);
- }
- private void set_line_style() {
- var style = style_selector.selected;
- inhibit_toolbar_updates = true;
- source_buffer.begin_user_action();
- remove_line_style();
- print(@"Set style $style\n");
- if(style < 6) {
- // Headings
- format_line_heading(style + 1);
- }
- else if(style == 6) {
- format_line_quote();
- }
- else if(style == 7) {
- format_line_preformatted();
- }
- set_line_style_type_in_dropdown(style);
- inhibit_toolbar_updates = false;
- source_buffer.end_user_action();
- }
- private void format_line_heading(uint level) {
- TextIter iter;
- source_buffer.get_iter_at_offset(out iter, source_buffer.cursor_position);
- var line_no = iter.get_line();
- source_buffer.get_iter_at_line(out iter, line_no);
- for(var i = 0; i < level; i++) {
- source_buffer.insert(ref iter, "#", 1);
- }
- source_buffer.insert(ref iter, " ", 1);
- iter.forward_line();
- iter.backward_char();
- source_buffer.place_cursor(iter);
- }
- private void format_line_quote() {
- TextIter iter;
- source_buffer.get_iter_at_offset(out iter, source_buffer.cursor_position);
- var line_no = iter.get_line();
- source_buffer.get_iter_at_line(out iter, line_no);
- source_buffer.insert(ref iter, "> ", 2);
- iter.forward_line();
- iter.backward_char();
- source_buffer.place_cursor(iter);
- }
- private void format_line_preformatted() {
- TextIter iter;
- source_buffer.get_iter_at_offset(out iter, source_buffer.cursor_position);
- var line_no = iter.get_line();
- source_buffer.get_iter_at_line(out iter, line_no);
- source_buffer.insert(ref iter, "```\n", 4);
- iter.forward_line();
- iter.backward_char();
- source_buffer.insert(ref iter, "\n```", 4);
- iter.forward_line();
- iter.backward_chars(5);
- source_buffer.place_cursor(iter);
- }
- private void format_text_bold() {
- TextIter iter_start;
- TextIter iter_end;
- if(source_buffer.has_selection) {
- source_buffer.get_selection_bounds(out iter_start, out iter_end);
- }
- else {
- source_buffer.get_iter_at_offset(out iter_start, source_buffer.cursor_position);
- source_buffer.get_iter_at_offset(out iter_end, source_buffer.cursor_position);
- if(!iter_start.starts_word()) {
- iter_start.backward_word_start();
- }
- if(!iter_end.ends_word()) {
- iter_end.forward_word_end();
- }
- }
- var difference = iter_end.get_offset() - iter_start.get_offset();
- source_buffer.insert(ref iter_start, "**", 2);
- iter_start.forward_chars(difference);
- source_buffer.insert(ref iter_start, "**", 2);
- }
- private void format_text_unbold() {
- TextIter iter;
- source_buffer.get_iter_at_offset(out iter, source_buffer.cursor_position);
- source_buffer.iter_forward_to_context_class_toggle(ref iter, "b");
- var end_pos = iter.get_offset();
- source_buffer.iter_backward_to_context_class_toggle(ref iter, "b");
- iter.forward_chars(2);
- source_buffer.backspace(ref iter, false, true);
- source_buffer.backspace(ref iter, false, true);
- iter.set_offset(end_pos-2);
- source_buffer.backspace(ref iter, false, true);
- source_buffer.backspace(ref iter, false, true);
- }
- private void toggle_bold() {
- source_buffer.begin_user_action();
- if(!bold_button.active) {
- format_text_unbold();
- }
- else {
- format_text_bold();
- }
- source_buffer.end_user_action();
- }
- private void format_text_italic() {
- TextIter iter_start;
- TextIter iter_end;
- if(source_buffer.has_selection) {
- source_buffer.get_selection_bounds(out iter_start, out iter_end);
- }
- else {
- source_buffer.get_iter_at_offset(out iter_start, source_buffer.cursor_position);
- source_buffer.get_iter_at_offset(out iter_end, source_buffer.cursor_position);
- if(!iter_start.starts_word()) {
- iter_start.backward_word_start();
- }
- if(!iter_end.ends_word()) {
- iter_end.forward_word_end();
- }
- }
- var difference = iter_end.get_offset() - iter_start.get_offset();
- source_buffer.insert(ref iter_start, "*", 1);
- iter_start.forward_chars(difference);
- source_buffer.insert(ref iter_start, "*", 1);
- }
- private void format_text_unitalic() {
- TextIter iter;
- source_buffer.get_iter_at_offset(out iter, source_buffer.cursor_position);
- source_buffer.iter_forward_to_context_class_toggle(ref iter, "i");
- var end_pos = iter.get_offset();
- source_buffer.iter_backward_to_context_class_toggle(ref iter, "i");
- iter.forward_chars(1);
- source_buffer.backspace(ref iter, false, true);
- iter.set_offset(end_pos-1);
- source_buffer.backspace(ref iter, false, true);
- }
- private void toggle_italic() {
- source_buffer.begin_user_action();
- if(!italic_button.active) {
- format_text_unitalic();
- }
- else {
- format_text_italic();
- }
- source_buffer.end_user_action();
- }
- private void insert_link_clicked() {
- string selected = null;
- if(source_buffer.has_selection) {
- TextIter iter_start;
- TextIter iter_end;
- source_buffer.get_selection_bounds(out iter_start, out iter_end);
- selected = iter_start.get_text(iter_end);
- }
- var win = new AddLinkWindow(selected);
- win.insert_link.connect(link_insert);
- win.set_transient_for(window);
- win.modal = true;
- win.present();
- }
- private void link_insert(string url, string? label) {
- TextIter iter;
- source_buffer.begin_user_action();
- if(source_buffer.has_selection) {
- TextIter iter_end;
- source_buffer.get_selection_bounds(out iter, out iter_end);
- source_buffer.delete(ref iter, ref iter_end);
- }
- else {
- source_buffer.get_iter_at_offset(out iter, source_buffer.cursor_position);
- }
- var link = "";
- if(label != null) {
- link = @"[$label]($url)";
- }
- else {
- link = @"<$url>";
- }
- source_buffer.insert(ref iter, link, link.length);
- source_buffer.end_user_action();
- }
- private void insert_image_clicked() {
- string selected = null;
- if(source_buffer.has_selection) {
- TextIter iter_start;
- TextIter iter_end;
- source_buffer.get_selection_bounds(out iter_start, out iter_end);
- selected = iter_start.get_text(iter_end);
- }
- var win = new AddImageWindow(selected, window);
- win.insert_image.connect(image_insert);
- win.set_transient_for(window);
- win.modal = true;
- win.present();
- }
- private void image_insert(string url, string label) {
- TextIter iter;
- source_buffer.begin_user_action();
- if(source_buffer.has_selection) {
- TextIter iter_end;
- source_buffer.get_selection_bounds(out iter, out iter_end);
- source_buffer.delete(ref iter, ref iter_end);
- }
- else {
- source_buffer.get_iter_at_offset(out iter, source_buffer.cursor_position);
- }
- var link = @"";
- 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();
- }
- }
-
- }
- public class AddLinkWindow : Adw.Window {
- public signal void insert_link(string url, string? text);
- private EntryRow url_entry;
- private EntryRow text_entry;
- public AddLinkWindow(string? text) {
- title = "Insert link";
- var box = new Box(Orientation.VERTICAL, 18);
- var header = new Adw.HeaderBar();
- header.show_end_title_buttons = false;
- box.append(header);
- var insert_button = new Button.with_label("Insert");
- var cancel_button = new Button.with_label("Cancel");
- insert_button.add_css_class("suggested-action");
- insert_button.clicked.connect(() => insert());
- cancel_button.clicked.connect(() => close());
- header.pack_start(cancel_button);
- header.pack_end(insert_button);
- var group = new PreferencesGroup();
- group.width_request = 400;
- group.title = "Link properties";
- group.margin_bottom = 18;
- group.margin_end = 18;
- group.margin_start = 18;
- url_entry = new EntryRow ();
- url_entry.title = "URI";
- group.add(url_entry);
- text_entry = new EntryRow ();
- text_entry.title = "Label (optional)";
- group.add(text_entry);
- if(text != null) {
- try {
- Uri.is_valid(text, UriFlags.NONE);
- url_entry.text = text;
- }
- catch (Error e) {
- text_entry.text = text;
- }
- }
- box.append(group);
- content = box;
- }
- private void insert() {
- string text = null;
- if(text_entry.text.chomp().chug() != "" || text_entry.text == url_entry.text) {
- text = text_entry.text;
- }
- insert_link(url_entry.text, text);
- close();
- }
- }
- public class AddImageWindow : Adw.Window {
- public signal void insert_image(string url, string text);
- private FileChooserRow file_entry;
- private EntryRow text_entry;
- public AddImageWindow(string? text, ViewerWindow win) {
- title = "Insert link";
- var box = new Box(Orientation.VERTICAL, 18);
- var header = new Adw.HeaderBar();
- header.show_end_title_buttons = false;
- box.append(header);
- var insert_button = new Button.with_label("Insert");
- var cancel_button = new Button.with_label("Cancel");
- insert_button.add_css_class("suggested-action");
- insert_button.clicked.connect(() => insert());
- cancel_button.clicked.connect(() => close());
- header.pack_start(cancel_button);
- header.pack_end(insert_button);
- var group = new PreferencesGroup();
- group.width_request = 400;
- group.title = "Link properties";
- group.margin_bottom = 18;
- group.margin_end = 18;
- group.margin_start = 18;
- file_entry = new FileChooserRow(win);
- file_entry.title = "Image file";
- file_entry.set_assets(win.publication.assets.where(a => a.mimetype.has_prefix ("image/")));
- group.add(file_entry);
- text_entry = new EntryRow ();
- text_entry.title = "Image description";
- group.add(text_entry);
- if(text != null) {
- text_entry.text = text;
- }
- box.append(group);
- content = box;
- }
- private void insert() {
- insert_image(file_entry.selected_asset, text_entry.text);
- close();
- }
- }
- }
|