diff --git a/xed/xed-commands-file.c b/xed/xed-commands-file.c index ee79caa..2323cab 100644 --- a/xed/xed-commands-file.c +++ b/xed/xed-commands-file.c @@ -1125,9 +1125,9 @@ void _xed_cmd_file_revert (GtkAction *action, XedWindow *window) { - XedTab *tab; - XedDocument *doc; - GtkWidget *dialog; + XedTab *tab; + XedDocument *doc; + GtkWidget *dialog; GtkWindowGroup *wg; xed_debug (DEBUG_COMMANDS); @@ -1138,7 +1138,7 @@ _xed_cmd_file_revert (GtkAction *action, /* If we are already displaying a notification * reverting will drop local modifications, do * not bug the user further */ - if (xed_tab_get_state (tab) == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) + if (xed_tab_get_state (tab) == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION || _xed_tab_get_can_close (tab)) { do_revert (window, tab); return; @@ -1532,7 +1532,7 @@ tab_can_close (XedTab *tab, doc = xed_tab_get_document (tab); - if (!_xed_tab_can_close (tab)) + if (!_xed_tab_get_can_close (tab)) { GtkWidget *dlg; diff --git a/xed/xed-notebook.c b/xed/xed-notebook.c index b0ee7c1..b0b7022 100644 --- a/xed/xed-notebook.c +++ b/xed/xed-notebook.c @@ -969,6 +969,18 @@ xed_notebook_remove_all_tabs (XedNotebook *nb) gtk_container_foreach (GTK_CONTAINER (nb), (GtkCallback)remove_tab, nb); } +GList * +xed_notebook_get_all_tabs (XedNotebook *nb) +{ + GList *children = NULL; + + g_return_val_if_fail (XED_IS_NOTEBOOK (nb), NULL); + + children = gtk_container_get_children (GTK_CONTAINER (nb)); + + return children; +} + static void set_close_buttons_sensitivity (XedTab *tab, XedNotebook *nb) diff --git a/xed/xed-notebook.h b/xed/xed-notebook.h index 8a8c059..db4df81 100644 --- a/xed/xed-notebook.h +++ b/xed/xed-notebook.h @@ -110,6 +110,8 @@ void xed_notebook_remove_tab (XedNotebook *nb, void xed_notebook_remove_all_tabs (XedNotebook *nb); +GList *xed_notebook_get_all_tabs (XedNotebook *nb); + void xed_notebook_reorder_tab (XedNotebook *src, XedTab *tab, gint dest_position); diff --git a/xed/xed-tab.c b/xed/xed-tab.c index 5237267..5c89645 100644 --- a/xed/xed-tab.c +++ b/xed/xed-tab.c @@ -123,7 +123,8 @@ enum PROP_NAME, PROP_STATE, PROP_AUTO_SAVE, - PROP_AUTO_SAVE_INTERVAL + PROP_AUTO_SAVE_INTERVAL, + PROP_CAN_CLOSE }; static gboolean xed_tab_auto_save (XedTab *tab); @@ -227,6 +228,8 @@ xed_tab_get_property (GObject *object, case PROP_AUTO_SAVE_INTERVAL: g_value_set_int (value, xed_tab_get_auto_save_interval (tab)); break; + case PROP_CAN_CLOSE: + g_value_set_boolean (value, _xed_tab_get_can_close (tab)); default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -345,6 +348,15 @@ xed_tab_class_init (XedTabClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_CAN_CLOSE, + g_param_spec_boolean ("can-close", + "Can close", + "Wheather the tab can be closed", + TRUE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_type_class_add_private (object_class, sizeof (XedTabPrivate)); } @@ -475,6 +487,7 @@ xed_tab_set_state (XedTab *tab, update_auto_save_timeout (tab); g_object_notify (G_OBJECT (tab), "state"); + g_object_notify (G_OBJECT (tab), "can-close"); } static void @@ -504,6 +517,7 @@ document_modified_changed (GtkTextBuffer *document, XedTab *tab) { g_object_notify (G_OBJECT (tab), "name"); + g_object_notify (G_OBJECT (tab), "can-close"); } static void @@ -2830,7 +2844,7 @@ _xed_tab_mark_for_closing (XedTab *tab) } gboolean -_xed_tab_can_close (XedTab *tab) +_xed_tab_get_can_close (XedTab *tab) { XedDocument *doc; XedTabState ts; diff --git a/xed/xed-tab.h b/xed/xed-tab.h index 43f0cf2..40ee976 100644 --- a/xed/xed-tab.h +++ b/xed/xed-tab.h @@ -156,7 +156,7 @@ void _xed_tab_save_as_async (XedTab *tab, void _xed_tab_print (XedTab *tab); void _xed_tab_print_preview (XedTab *tab); void _xed_tab_mark_for_closing (XedTab *tab); -gboolean _xed_tab_can_close (XedTab *tab); +gboolean _xed_tab_get_can_close (XedTab *tab); GtkWidget *_xed_tab_get_view_frame (XedTab *tab); G_END_DECLS diff --git a/xed/xed-window-private.h b/xed/xed-window-private.h index 6796964..c7ec07a 100644 --- a/xed/xed-window-private.h +++ b/xed/xed-window-private.h @@ -107,6 +107,8 @@ struct _XedWindowPrivate gint height; GdkWindowState window_state; + guint inhibition_cookie; + gint side_panel_size; gint bottom_panel_size; diff --git a/xed/xed-window.c b/xed/xed-window.c index 64e34f4..f034760 100644 --- a/xed/xed-window.c +++ b/xed/xed-window.c @@ -2406,6 +2406,43 @@ update_window_state (XedWindow *window) } } +static void +update_can_close (XedWindow *window) +{ + XedWindowPrivate *priv = window->priv; + GList *tabs; + GList *l; + gboolean can_close = TRUE; + + tabs = xed_notebook_get_all_tabs (priv->notebook); + + for (l = tabs; l != NULL; l = g_list_next (l)) + { + XedTab *tab = l->data; + + if (!_xed_tab_get_can_close (tab)) + { + can_close = FALSE; + break; + } + } + + if (can_close && (priv->inhibition_cookie != 0)) + { + gtk_application_uninhibit (GTK_APPLICATION (g_application_get_default ()), priv->inhibition_cookie); + priv->inhibition_cookie = 0; + } + else if (!can_close && (priv->inhibition_cookie == 0)) + { + priv->inhibition_cookie = gtk_application_inhibit (GTK_APPLICATION (g_application_get_default ()), + GTK_WINDOW (window), + GTK_APPLICATION_INHIBIT_LOGOUT, + _("There are unsaved documents")); + } + + g_list_free (tabs); +} + static void sync_state (XedTab *tab, GParamSpec *pspec, @@ -2463,6 +2500,14 @@ sync_name (XedTab *tab, peas_extension_set_call (window->priv->extensions, "update_state"); } +static void +sync_can_close (XedTab *tab, + GParamSpec *pspec, + XedWindow *window) +{ + update_can_close (window); +} + static XedWindow * get_drop_window (GtkWidget *widget) { @@ -2942,24 +2987,26 @@ notebook_tab_added (XedNotebook *notebook, /* IMPORTANT: remember to disconnect the signal in notebook_tab_removed * if a new signal is connected here */ - g_signal_connect(tab, "notify::name", G_CALLBACK (sync_name), window); - g_signal_connect(tab, "notify::state", G_CALLBACK (sync_state), window); + g_signal_connect (tab, "notify::name", G_CALLBACK (sync_name), window); + g_signal_connect (tab, "notify::state", G_CALLBACK (sync_state), window); + g_signal_connect (tab, "notify::can-close", G_CALLBACK (sync_can_close), window); - g_signal_connect(doc, "cursor-moved", G_CALLBACK (update_cursor_position_statusbar), window); - g_signal_connect(doc, "notify::search-text", G_CALLBACK (search_text_notify_cb), window); - g_signal_connect(doc, "notify::can-undo", G_CALLBACK (can_undo), window); - g_signal_connect(doc, "notify::can-redo", G_CALLBACK (can_redo), window); - g_signal_connect(doc, "notify::has-selection", G_CALLBACK (selection_changed), window); - g_signal_connect(doc, "notify::language", G_CALLBACK (sync_languages_menu), window); - g_signal_connect(doc, "notify::read-only", G_CALLBACK (readonly_changed), window); - g_signal_connect(view, "toggle_overwrite", G_CALLBACK (update_overwrite_mode_statusbar), window); - g_signal_connect(view, "notify::editable", G_CALLBACK (editable_changed), window); + g_signal_connect (doc, "cursor-moved", G_CALLBACK (update_cursor_position_statusbar), window); + g_signal_connect (doc, "notify::search-text", G_CALLBACK (search_text_notify_cb), window); + g_signal_connect (doc, "notify::can-undo", G_CALLBACK (can_undo), window); + g_signal_connect (doc, "notify::can-redo", G_CALLBACK (can_redo), window); + g_signal_connect (doc, "notify::has-selection", G_CALLBACK (selection_changed), window); + g_signal_connect (doc, "notify::language", G_CALLBACK (sync_languages_menu), window); + g_signal_connect (doc, "notify::read-only", G_CALLBACK (readonly_changed), window); + g_signal_connect (view, "toggle_overwrite", G_CALLBACK (update_overwrite_mode_statusbar), window); + g_signal_connect (view, "notify::editable", G_CALLBACK (editable_changed), window); update_documents_list_menu (window); g_signal_connect(view, "drop_uris", G_CALLBACK (drop_uris_cb), NULL); update_window_state (window); + update_can_close (window); g_signal_emit (G_OBJECT(window), signals[TAB_ADDED], 0, tab); } @@ -2981,18 +3028,19 @@ notebook_tab_removed (XedNotebook *notebook, view = xed_tab_get_view (tab); doc = xed_tab_get_document (tab); - g_signal_handlers_disconnect_by_func(tab, G_CALLBACK (sync_name), window); - g_signal_handlers_disconnect_by_func(tab, G_CALLBACK (sync_state), window); - g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (update_cursor_position_statusbar), window); - g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (search_text_notify_cb), window); - g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (can_undo), window); - g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (can_redo), window); - g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (selection_changed), window); - g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (sync_languages_menu), window); - g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (readonly_changed), window); - g_signal_handlers_disconnect_by_func(view, G_CALLBACK (update_overwrite_mode_statusbar), window); - g_signal_handlers_disconnect_by_func(view, G_CALLBACK (editable_changed), window); - g_signal_handlers_disconnect_by_func(view, G_CALLBACK (drop_uris_cb), NULL); + g_signal_handlers_disconnect_by_func (tab, G_CALLBACK (sync_name), window); + g_signal_handlers_disconnect_by_func (tab, G_CALLBACK (sync_state), window); + g_signal_handlers_disconnect_by_func (tab, G_CALLBACK (sync_can_close), window); + g_signal_handlers_disconnect_by_func (doc, G_CALLBACK (update_cursor_position_statusbar), window); + g_signal_handlers_disconnect_by_func (doc, G_CALLBACK (search_text_notify_cb), window); + g_signal_handlers_disconnect_by_func (doc, G_CALLBACK (can_undo), window); + g_signal_handlers_disconnect_by_func (doc, G_CALLBACK (can_redo), window); + g_signal_handlers_disconnect_by_func (doc, G_CALLBACK (selection_changed), window); + g_signal_handlers_disconnect_by_func (doc, G_CALLBACK (sync_languages_menu), window); + g_signal_handlers_disconnect_by_func (doc, G_CALLBACK (readonly_changed), window); + g_signal_handlers_disconnect_by_func (view, G_CALLBACK (update_overwrite_mode_statusbar), window); + g_signal_handlers_disconnect_by_func (view, G_CALLBACK (editable_changed), window); + g_signal_handlers_disconnect_by_func (view, G_CALLBACK (drop_uris_cb), NULL); if (window->priv->tab_width_id && tab == xed_window_get_active_tab (window)) { @@ -3056,6 +3104,7 @@ notebook_tab_removed (XedNotebook *notebook, } update_window_state (window); + update_can_close (window); g_signal_emit (G_OBJECT(window), signals[TAB_REMOVED], 0, tab); } @@ -3502,6 +3551,7 @@ xed_window_init (XedWindow *window) window->priv->num_tabs = 0; window->priv->removing_tabs = FALSE; window->priv->state = XED_WINDOW_STATE_NORMAL; + window->priv->inhibition_cookie = 0; window->priv->dispose_has_run = FALSE; window->priv->fullscreen_controls = NULL; window->priv->fullscreen_animation_timeout_id = 0; @@ -4152,7 +4202,7 @@ xed_window_get_unsaved_documents (XedWindow *window) { XedTab *tab; tab = XED_TAB(l->data); - if (!_xed_tab_can_close (tab)) + if (!_xed_tab_get_can_close (tab)) { XedDocument *doc; doc = xed_tab_get_document (tab);