Browse Source

Add metadata editor

Billy Barrow 2 năm trước cách đây
mục cha
commit
aa1d521c20
2 tập tin đã thay đổi với 97 bổ sung3 xóa
  1. 94 2
      src/Editor.vala
  2. 3 1
      src/Editors/EditorWidget.vala

+ 94 - 2
src/Editor.vala

@@ -11,6 +11,7 @@ namespace Publicate {
         private Leaflet leaflet;
 
         private Ppub.Publication publication;
+        private File publication_file;
         private ViewerWindow window;
 
         private FileExplorer file_explorer;
@@ -18,6 +19,10 @@ namespace Publicate {
         private TabView tab_view;
         private TabBar tab_bar;
 
+        private Button save_tab_button;
+
+        private Gee.HashMap<string, Editors.EditorWidget> open_editors = new Gee.HashMap<string, Editors.EditorWidget>();
+
         public PpubEditor(ViewerWindow win) {
             window = win;
 
@@ -28,27 +33,57 @@ namespace Publicate {
             header_title = new WindowTitle("Untitled Publication", "");
             header.title_widget = header_title;
 
+            var file_box = new Box(Orientation.VERTICAL, 0);
+            file_box.vexpand = true;
             file_explorer = new FileExplorer();
             file_explorer.asset_selected.connect(open_asset);
+            file_explorer.vexpand = true;
+            file_box.append(file_explorer);
+            
+            var file_buttons = new Box(Orientation.HORIZONTAL, 0);
+            file_buttons.add_css_class("linked");
+            file_buttons.halign = Align.END;
+            file_buttons.margin_end = 8;
+            file_buttons.margin_bottom = 8;
+            file_buttons.margin_start = 8;
+            file_buttons.margin_top = 8;
+            file_box.append(file_buttons);
+            
+            var new_file_button = new Button.from_icon_name("document-new-symbolic");
+            file_buttons.append(new_file_button);
 
+            var add_file_button = new Button.from_icon_name("list-add-symbolic");
+            file_buttons.append(add_file_button);
+
+            var remove_file_button = new Button.from_icon_name("user-trash-symbolic");
+            file_buttons.append(remove_file_button);
+            
             leaflet = new Leaflet();
             leaflet.vexpand = true;
-            leaflet.append(file_explorer);
+            leaflet.append(file_box);
             
             tab_view = new TabView();
             tab_bar = new TabBar();
             tab_box = new Box(Orientation.VERTICAL, 0);
+            tab_bar.autohide = false;
             tab_bar.set_view(tab_view);
             tab_box.append(tab_bar);
             tab_box.append(tab_view);
             leaflet.append(tab_box);
 
+            save_tab_button = new Button.from_icon_name("document-save-symbolic");
+            save_tab_button.clicked.connect(save_tab);
+            header.pack_end(save_tab_button);
+
+            tab_view.notify["selected-page"].connect(() => select_file_from_tab());
+
             append(leaflet);
         }
 
         public async void load_ppub(File file) throws Error {
 
             publication = new Ppub.Publication(file.get_path());
+            publication_file = file;
 
             header_title.title = publication.metadata.title ?? "Untitled PPUB";
             header_title.subtitle = publication.metadata.author_name ?? "";
@@ -59,13 +94,70 @@ namespace Publicate {
         }
 
         public async void open_asset(Ppub.Asset asset) {
+
+            if(open_editors.has_key(asset.name)) {
+                tab_view.selected_page = open_editors[asset.name].tab_page;
+                return;
+            }
             
             if(asset.mimetype == "text/markdown") {
                 var editor = new Editors.MarkdownEditor(window, tab_view);
-                editor.load_asset(publication, asset);
+                add_editor(editor, asset);
+            }
+            else if(asset.mimetype.has_prefix("text/")) {
+                var editor = new Editors.PlainTextEditor(window, tab_view);
+                add_editor(editor, asset);
+            }
+            if(asset.mimetype == "application/x-ppub-metadata") {
+                var editor = new Editors.MetadataEditor(window, tab_view);
+                add_editor(editor, asset);
+            }
+
+        }
+
+        private void add_editor(Editors.EditorWidget editor, Ppub.Asset asset) {
+            editor.load_asset(publication, asset);
+            open_editors.set(asset.name, editor);
+            tab_view.selected_page = editor.tab_page;
+        }
+
+        private async void save(Invercargill.Enumerable<Savable> to_save) {
+
+            var builder = new Ppub.Builder();
+            foreach (var item in to_save) {
+                item.save_asset(builder);
             }
 
+            var temp_file = File.new_for_path(publication_file.get_path() + ".tmp");
+            var stream = yield temp_file.replace_async(null, false, FileCreateFlags.REPLACE_DESTINATION, Priority.DEFAULT);
+
+            builder.write(stream);
+            yield stream.close_async(Priority.DEFAULT, null);
+            
+            yield temp_file.move_async(publication_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null, null);
+            yield load_ppub(publication_file);
+
+            select_file_from_tab();
         }
 
+        private async void save_tab() {
+            var current_editor = (Editors.EditorWidget)tab_view.selected_page.child;
+            var to_save = publication.assets.select<Savable>(a => a.name == current_editor.asset_name ? (Savable)current_editor : new SavableAsset(publication, a));
+            yield save(to_save);
+        }
+
+
+        private void select_file_from_tab() {
+            var editor = (Editors.EditorWidget)tab_view.selected_page.child;
+            file_explorer.set_selected_item(editor.asset_name);
+        }
+
+        public async void add_asset (string name, string mimetype, GLib.InputStream stream, Ppub.CompressionInfo compression) {
+
+            var to_save = publication.assets.select<Savable>(a => new SavableAsset(publication, a)).to_sequence();
+            to_save.add(new SavableNewAsset(name, mimetype, stream, compression));
+            yield save(to_save);
+            
+        }
     }
 }

+ 3 - 1
src/Editors/EditorWidget.vala

@@ -1,7 +1,9 @@
 
 namespace Publicate.Editors {
     public interface EditorWidget : Gtk.Widget {
-        public abstract void set_zoom_percentage(int percent);
         public abstract async void load_asset(Ppub.Publication publication, Ppub.Asset asset);
+        public abstract string asset_name {get;}
+        public abstract Adw.TabPage tab_page {get;}
+        public abstract bool has_unsaved_changes {get;}
     }
 }