=== modified file 'src/MainWindow.vala' --- src/MainWindow.vala 2013-02-13 17:04:34 +0000 +++ src/MainWindow.vala 2013-04-20 09:25:05 +0000 @@ -85,10 +85,10 @@ /** * Search manager - */ - Gtk.Toolbar search_bar; + */ + Gtk.Toolbar search_bar; public Scratch.Services.SearchManager search_manager; - + /** * The Gtk.Notebook which is used to display panels which are related * to the current files. @@ -107,7 +107,7 @@ //dialogs public NotificationBar info_bar; private Dialogs.Preferences? preferences = null; - + public Scratch.Widgets.Tab current_tab { get { return (Scratch.Widgets.Tab) current_notebook.current_tab; }} public ScratchNotebook current_notebook { get { return split_view.get_current_notebook (); } } public Document current_document { get { return current_tab.document; } } @@ -121,12 +121,12 @@ Granite.Widgets.HCollapsablePaned hpaned_sidebar; private Zeitgeist.DataSourceRegistry registry; - + // Signals public signal void welcome_state_change (Scratch.Widgets.ScratchWelcomeState state); - + public MainWindow (Scratch.ScratchApp scratch_app) { - + this.scratch_app = scratch_app; set_application (scratch_app); @@ -134,13 +134,13 @@ this.icon_name = "accessories-text-editor"; restore_saved_state (); this.window_position = Gtk.WindowPosition.CENTER; - + //main actions main_actions = new Gtk.ActionGroup ("MainActionGroup"); /* Actions and UIManager */ main_actions.set_translation_domain (Constants.GETTEXT_PACKAGE); main_actions.add_actions (main_entries, this); main_actions.add_toggle_actions (toggle_entries, this); - + settings.schema.bind("sidebar-visible", main_actions.get_action ("ShowSidebar"), "active", SettingsBindFlags.DEFAULT); settings.schema.bind("context-visible", main_actions.get_action ("ShowContextView"), "active", SettingsBindFlags.DEFAULT); settings.schema.bind("bottom-panel-visible", main_actions.get_action ("ShowBottomPanel"), "active", SettingsBindFlags.DEFAULT); @@ -153,7 +153,7 @@ plugins.plugin_iface.template_manager.notify["template_available"].connect ( () => { main_actions.get_action ("Templates").sensitive = plugins.plugin_iface.template_manager.template_available; }); - + ui = new Gtk.UIManager (); try { @@ -171,18 +171,18 @@ create_window (); connect_signals (); - + /* Update app status at settings updates */ - settings.schema.changed.connect ((key) => { + settings.schema.changed.connect ((key) => { if (key == "autosave" && settings.autosave == false) action_save_all (); }); - + set_theme (); - + // Set up the Data Source Registry registry = new DataSourceRegistry (); - + var ds_event = new Zeitgeist.Event(); ds_event.set_actor("application://scratch.desktop"); ds_event.add_subject(new Zeitgeist.Subject()); @@ -200,7 +200,7 @@ { warning ("%s", reg_err.message); } - + // Set minimum window size. this.set_size_request(300,250); } @@ -248,7 +248,7 @@ notebook.show_tabs = num >= 1; } notebook_settings_changed (part); - + ui.ensure_update (); } @@ -298,13 +298,13 @@ warning("The focused widget is not a valid TextView"); } - + Gtk.Box? vbox_split_view_toolbar = null; public void create_window () { this.toolbar = new Widgets.Toolbar (this, ui, main_actions); - + notebook_context = new Gtk.Notebook (); notebook_context.page_added.connect (on_notebook_context_new_page); notebook_context.page_removed.connect (on_notebook_context_new_page); @@ -323,14 +323,14 @@ welcome_screen = new ScratchWelcome (this); hpaned_sidebar.pack1 (notebook_sidebar, false, false); notebook_sidebar.visible = false; - - + + vbox_split_view_toolbar = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); statusbar = new Scratch.Widgets.StatusBar (); vbox_split_view_toolbar.pack_start (split_view, true, true, 0); vbox_split_view_toolbar.pack_end (statusbar, false, false, 0); hpaned_sidebar.pack2 (vbox_split_view_toolbar, true, true); - + hpaned_addons.pack2 (notebook_context, false, false); notebook_context.visible = true; settings.schema.changed.connect (notebook_settings_changed); @@ -339,14 +339,14 @@ plugins.hook_notebook_sidebar (); plugins.context = notebook_context; plugins.hook_notebook_context (); - + /** * Search manager - */ + */ search_manager = new Scratch.Services.SearchManager (main_actions); //Scratch.settings.schema.bind ("search-sensitive", search_manager, "case-sensitive", SettingsBindFlags.DEFAULT); search_manager.need_hide.connect (hide_search_bar); - + search_bar = new Gtk.Toolbar (); search_bar.get_style_context ().add_class ("secondary-toolbar"); search_bar.add (search_manager.get_search_entry ()); @@ -361,13 +361,13 @@ search_manager.get_go_to_label ().set_margin_right (5); search_bar.add (search_manager.get_go_to_entry ()); search_bar.add (search_manager.get_close_button ()); - + /** * Info bar */ info_bar = new NotificationBar (); info_bar.no_show_all = true; - + var notebook = new ScratchNotebook (this); notebook.switch_page.connect( () => { hide_search_bar(); }); search_bar.no_show_all = true; @@ -379,12 +379,12 @@ notebook_bottom = new Gtk.Notebook (); notebook_bottom.page_added.connect (on_notebook_context_new_page); notebook_bottom.page_removed.connect (on_notebook_context_new_page); - + /* Add the sourceview + the sidepanel to the container of the bottom panel */ vpaned_bottom_panel.pack1 (hpaned_addons, true, true); vpaned_bottom_panel.pack2 (notebook_bottom, false, false); plugins.hook_notebook_bottom (notebook_bottom); - + //adding all to the vbox var vbox = new VBox (false, 0); vbox.pack_start (toolbar, false, false, 0); @@ -400,10 +400,10 @@ notebook_settings_changed ("sidebar-visible"); notebook_settings_changed ("context-visible"); notebook_settings_changed ("bottom-panel-visible"); - + main_actions.get_action ("ShowStatusBar").visible = false; statusbar.check (); - + on_split_view_empty_changed (); /* trap SIGINT and SIGTERM and terminate properly when catching one */ @@ -411,7 +411,7 @@ Unix.signal_add (Posix.SIGTERM, action_quit_source_func, Priority.HIGH); } - + void hide_search_bar () { search_bar.no_show_all = true; search_bar.visible = false; @@ -443,14 +443,14 @@ { if (split_view.is_empty) { set_actions (false); - + if (statusbar != null) { statusbar.check (); action_show_status_bar (main_actions.get_action ("ShowStatusBar")); } - + welcome_state_change (ScratchWelcomeState.HIDE); - + if (split_view.get_parent () != null && vbox_split_view_toolbar != null) { vbox_split_view_toolbar.remove (split_view); vbox_split_view_toolbar.remove (statusbar); @@ -467,14 +467,14 @@ else { set_actions (true); - + if (statusbar != null) { statusbar.check (); action_show_status_bar (main_actions.get_action ("ShowStatusBar")); } - + welcome_state_change (ScratchWelcomeState.SHOW); - + if (split_view.get_parent () == null && vbox_split_view_toolbar != null) { vbox_split_view_toolbar.remove (welcome_screen); vbox_split_view_toolbar.pack_start (split_view, true, true); @@ -504,7 +504,7 @@ public void connect_signals () { drag_data_received.connect (on_drag_data_received); } - + void update_opened_files () { int n = 0; var opened_files = new string [scratch_app.documents.length ()]; @@ -516,9 +516,9 @@ } /* Update the opened-files setting */ if (settings.show_at_start == "last-tabs") - /*settings.opened_files = opened_files;*/settings.schema.set_strv ("opened-files", opened_files); + /*settings.opened_files = opened_files;*/settings.schema.set_strv ("opened-files", opened_files); } - + void action_preferences () { if (preferences == null) preferences = new Dialogs.Preferences (_("Preferences"), this); @@ -532,39 +532,53 @@ } void action_quit () { + /*unless all unsaved modifications are saved or deliberately + * closed without saving, cancel the quit action + */ + if (!save_modified_documents(scratch_app.documents)) + return; + + destroy (); + } + + public bool save_modified_documents(List docs) { update_saved_state (); update_opened_files (); - - uint n = 0; - bool quit = true; - - foreach (var doc in scratch_app.documents) { - if (doc.modified) { - var save_dialog = new SaveOnCloseDialog (doc.name, this); - doc.focus_sourceview (); - int response = save_dialog.run (); - switch (response) { - case Gtk.ResponseType.CANCEL: - save_dialog.destroy (); - quit = false; - break; - case Gtk.ResponseType.YES: - doc.save (); - quit = true; - break; - case Gtk.ResponseType.NO: - quit = true; - break; - } - save_dialog.destroy (); - } - doc.delete_backup (); - if (n != scratch_app.documents.length ()) - n++; - } - - if (quit) - destroy (); + + foreach (var doc in docs) { + if (!doc.modified) + continue; + if (!save_modified_document(doc)) + return false; //cancel the process + } + + foreach(var doc in docs) { + doc.delete_backup (); + } + + return true; + } + + public bool save_modified_document(Document doc) { + bool can_quit=false; + var save_dialog = new SaveOnCloseDialog (doc.name, this); + doc.focus_sourceview (); + + int response = save_dialog.run (); + switch (response) { + case Gtk.ResponseType.YES: + doc.save (); + can_quit = true; + break; + case Gtk.ResponseType.NO: + can_quit = true; + break; + default: + break; + } + save_dialog.destroy (); + //return false unless YES or NO was pressed + return can_quit; } public bool action_quit_source_func () { @@ -582,7 +596,7 @@ if (settings.autosave) this.toolbar.save_button.show (); } - + public void action_restore_tab () { scratch_app.restore_tab (); } @@ -615,10 +629,10 @@ if (filech.run () == ResponseType.ACCEPT) foreach (string file in filech.get_uris ()) { - scratch_app.open_file (file); + scratch_app.open_file (file); scratch_app.current_directory = Path.get_dirname (file); } - + filech.close (); set_undo_redo (); } @@ -634,18 +648,18 @@ public void action_save_all () { int n = 0; string[] opened_files = {}; - - foreach (var doc in scratch_app.documents) { - + + foreach (var doc in scratch_app.documents) { + if (doc.filename != null) opened_files[n] = doc.filename; else return; - + doc.save (); } - } - + } + public void action_save_as () { current_tab.document.save_as (); } @@ -692,52 +706,21 @@ var home_dir = Environment.get_home_dir (); var path = Path.get_dirname (filename).replace (home_dir, "~"); path = path.replace ("file://", ""); - + if ("trash://" in path) path = _("Trash"); - + var file = File.new_for_uri (filename); - + this.title = file.get_basename () + " (%s) - %s".printf(path, TITLE); } protected override bool delete_event (Gdk.EventAny event) { - - update_saved_state (); - update_opened_files (); - - uint n = 0; - bool ret = false; - - foreach (var doc in scratch_app.documents) { - if (doc.modified) { - var save_dialog = new SaveOnCloseDialog (doc.name, this); - doc.focus_sourceview (); - int response = save_dialog.run (); - switch (response) { - case Gtk.ResponseType.CANCEL: - save_dialog.destroy (); - return true; - case Gtk.ResponseType.YES: - doc.save (); - ret = false; - break; - case Gtk.ResponseType.NO: - ret = false; - break; - } - save_dialog.destroy (); - } - doc.delete_backup (); - if (n == scratch_app.documents.length ()) - return ret; - else - n++; - } - - return false; - + /*unless all unsaved modifications are saved or deliberately + * closed without saving, cancel the delete event + */ + return !save_modified_documents(scratch_app.documents); } private void restore_saved_state () { @@ -804,10 +787,10 @@ scratch_app.open_document (doc); } - + if (split_view.get_children ().length () == 2) ; //main_actions.get_action (). - + } @@ -834,7 +817,7 @@ if (current_document.file.query_exists ()) current_document.save (); } - + void action_duplicate () { if (current_tab != null) { TextIter start, end; @@ -850,14 +833,14 @@ buf.get_iter_at_mark (out end, buf.get_insert ()); if (!end.ends_line ()) end.forward_sentence_end (); - + selected = buf.get_text (start, end, true); buf.insert (ref end, "\n" + selected, -1); } } - - } - + + } + void action_new_view () { create_instance (); set_actions (true); @@ -873,37 +856,29 @@ this.fullscreen (); } } - + void action_remove_view () { var notebook = split_view.get_current_notebook (); + List doclist=new List(); foreach(var w in notebook.get_children ()) { - var tab = w as Scratch.Widgets.Tab; - if (tab != null) { - var doc = tab.document; - if (doc.modified) { - var save_dialog = new SaveOnCloseDialog (doc.name, this); - int response = save_dialog.run (); - switch(response) { - case Gtk.ResponseType.CANCEL: - save_dialog.destroy (); - return; - case Gtk.ResponseType.YES: - doc.save (); - break; - case Gtk.ResponseType.NO: - break; - } - save_dialog.destroy (); - scratch_app.documents.remove (doc); - } - } + weak Scratch.Widgets.Tab tab = w as Scratch.Widgets.Tab; + + if (tab != null) + doclist.append(tab.document); + } + + if(!save_modified_documents(doclist)) + return; //remove view has been cancelled + + foreach(var doc in doclist) { + scratch_app.documents.remove (doc); } if (split_view != null) split_view.remove_current_view (); } - + void action_show_status_bar (Gtk.Action action) { if (statusbar != null) { if (!((Gtk.ToggleAction)action).active || statusbar.get_children ().length () == 0) { @@ -920,7 +895,7 @@ statusbar.check (); } } - + void action_fetch () { /* Get selected text to put it in the search entry */ if (current_tab != null) { @@ -932,11 +907,11 @@ if (selected != "") search_manager.search_entry.text = selected; } - + search_bar.no_show_all = false; search_bar.show_all (); } - + void action_templates () { plugins.plugin_iface.template_manager.show_window (this); } @@ -1002,12 +977,12 @@ /* label, accelerator */ N_("Previous Search"), "g", /* tooltip */ N_("Previous Search"), case_up }, - + { "Duplicate", null, /* label, accelerator */ N_("Duplicate selected strings"), "d", /* tooltip */ N_("Duplicate selected strings"), action_duplicate }, - + { "Open", Gtk.Stock.OPEN, /* label, accelerator */ N_("Open"), "o", /* tooltip */ N_("Open a file"), @@ -1051,7 +1026,7 @@ /* label, accelerator */ N_("Bottom Panel"), null, /* tooltip */ N_("Bottom Panel"), null } - + }; } === modified file 'src/Widgets/SplitView.vala' --- src/Widgets/SplitView.vala 2013-02-12 19:57:43 +0000 +++ src/Widgets/SplitView.vala 2013-04-20 09:27:13 +0000 @@ -91,8 +91,8 @@ return false; else { remove (focused_widget); - var notebook = focused_widget as ScratchNotebook; - show_save_dialog (notebook); + //var notebook = focused_widget as ScratchNotebook; + //show_save_dialog (notebook); focused_widget = null; } return true; @@ -116,13 +116,13 @@ public unowned ScratchNotebook get_current_notebook () { focused_widget = get_focus_child (); - + if (focused_widget != null && focused_widget.get_parent () != this) { focused_widget = null; } - + weak ScratchNotebook child = focused_widget as ScratchNotebook; - + if (child == null) { child = get_children ().nth_data (0) as ScratchNotebook; if( child == null) { === modified file 'src/Widgets/Tab.vala' --- src/Widgets/Tab.vala 2013-03-22 11:05:09 +0000 +++ src/Widgets/Tab.vala 2013-04-20 09:30:04 +0000 @@ -40,25 +40,25 @@ scrolled_window.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); text_view = new SourceView (); - + label = new TabLabel (this, labeltext); - + scrolled_window.add (text_view); attach (scrolled_window, 0, 1, 1, 1); scrolled_window.hexpand = true; scrolled_window.vexpand = true; - + show_all(); - + scrolled_window.grab_focus (); } - + public void set_overlay (Gtk.Widget widget) { ((Gtk.Container)widget.get_parent ()).remove (widget); attach (widget, 0, 0, 1, 1); show_all (); - } + } public void change_syntax_highlight_for_filename (string? filename) { if (filename != null) @@ -67,25 +67,29 @@ public void on_close_clicked() { if (document.can_write () && document.modified == true) { - - var save_dialog = new SaveOnCloseDialog (document.name, ((MainWindow)get_toplevel ())); - document.focus_sourceview (); - int response = save_dialog.run (); - switch(response) { - case Gtk.ResponseType.CANCEL: - save_dialog.destroy (); - return; - case Gtk.ResponseType.YES: - document.save (); - close (); - break; - case Gtk.ResponseType.NO: - close (); - break; - } - save_dialog.destroy (); - - } else this.close (); +// USE SIMILAR CODE IN MainWindow INSTEAD +// var save_dialog = new SaveOnCloseDialog (document.name, ((MainWindow)get_toplevel ())); +// document.focus_sourceview (); +// int response = save_dialog.run (); +// switch(response) { +// case Gtk.ResponseType.CANCEL: +// save_dialog.destroy (); +// return; +// case Gtk.ResponseType.YES: +// document.save (); +// close (); +// break; +// case Gtk.ResponseType.NO: +// close (); +// break; +// } +// save_dialog.destroy (); + + var mw= get_toplevel() as MainWindow; + if (!mw.save_modified_document(this.document)) + return; //do not close + } + this.close (); } public void close () { @@ -94,13 +98,13 @@ closed (); document.delete_backup (); ((Gtk.Notebook)get_parent()).remove(this); - + } - + public int save () { - + this.filename = document.filename; - + if (this.filename == null) { string new_filename = null; @@ -115,7 +119,7 @@ return false; }); filech.set_filename (GLib.Environment.get_user_special_dir (GLib.UserDirectory.DOCUMENTS) + "/*"); - + var response = filech.run(); switch (response) { @@ -140,37 +144,37 @@ try { document.filename = this.filename; - + if (document.file.query_exists () == false) { FileOutputStream file_out_stream = document.file.create (FileCreateFlags.NONE); file_out_stream.close(); } - + uint8[] data = text_view.buffer.text.data; string s; - + document.file.replace_contents (data, null, false, 0, out s); - + this.saved = true; - - //updating the tab label and window title + + //updating the tab label and window title label.label.set_text (document.file.get_basename ()); var top = get_toplevel () as MainWindow; - top.set_window_title (this.filename); - + top.set_window_title (this.filename); + this.document.filename = this.filename; this.document.last_saved_text = this.text_view.buffer.text; - this.document.modified = false; - - /* If autosave is on, - * to avoid to change - * the syntax highlight - * at every change, - * it is not changed - */ - if (!settings.autosave) - change_syntax_highlight_for_filename(this.filename); - + this.document.modified = false; + + /* If autosave is on, + * to avoid to change + * the syntax highlight + * at every change, + * it is not changed + */ + if (!settings.autosave) + change_syntax_highlight_for_filename(this.filename); + return 0; } catch (Error e) { @@ -197,7 +201,7 @@ filech.destroy (); return false; }); - + if (this.filename != null) filech.set_filename (this.filename); @@ -223,17 +227,17 @@ message ("Saving: %s", this.filename); try { - + if (!document.exists) { FileUtils.set_contents (this.filename, this.text_view.buffer.text); } else { uint8[] data = text_view.buffer.text.data; string s; - + document.file.replace_contents (data, null, false, 0, out s); } - + this.saved = true; //updating the tab label and the window title @@ -244,16 +248,16 @@ this.document.filename = this.filename; this.document.last_saved_text = this.text_view.buffer.text; this.document.modified = false; - - /* If autosave is on, - * to avoid to change - * the syntax highlight - * at every change, - * it is not changed - */ - if (!settings.autosave) - change_syntax_highlight_for_filename(this.filename); - + + /* If autosave is on, + * to avoid to change + * the syntax highlight + * at every change, + * it is not changed + */ + if (!settings.autosave) + change_syntax_highlight_for_filename(this.filename); + return 0; } catch (Error e) { @@ -264,6 +268,6 @@ } } - + } }