static gboolean gimp_dialog_factory_dialog_configure (GtkWidget *dialog, GdkEventConfigure *cevent, GimpDialogFactory *factory) { GimpDialogFactory *dialog_factory; GimpDialogFactoryEntry *entry; GList *list; if (! g_list_find (factory->open_dialogs, dialog)) { g_warning ("%s: dialog not registered", G_STRFUNC); return FALSE; } dialog_factory = gimp_dialog_factory_from_widget (dialog, &entry); if (! dialog_factory || (! entry && ! GIMP_IS_DOCK (dialog))) { g_warning ("%s: dialog was not created by a GimpDialogFactory", G_STRFUNC); return FALSE; } if (dialog_factory != factory) { g_warning ("%s: dialog was created by a different GimpDialogFactory", G_STRFUNC); return FALSE; } for (list = factory->session_infos; list; list = g_list_next (list)) { GimpSessionInfo *session_info = list->data; if (session_info->widget == dialog) { gimp_session_info_get_geometry (session_info); GIMP_LOG (DIALOG_FACTORY, "updated session info for \"%s\" from window geometry " "(x=%d y=%d %dx%d)", entry ? entry->identifier : "dock", session_info->x, session_info->y, session_info->width, session_info->height); break; } } return FALSE; }
GimpDockbook * gimp_session_info_book_restore (GimpSessionInfoBook *info, GimpDock *dock) { GtkWidget *dockbook; GList *pages; gint n_dockables = 0; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL); dockbook = gimp_dockbook_new (global_menu_factory); gimp_dock_add_book (dock, GIMP_DOCKBOOK (dockbook), -1); for (pages = info->dockables; pages; pages = g_list_next (pages)) { GimpSessionInfoDockable *dockable_info = pages->data; GimpDockable *dockable; dockable = gimp_session_info_dockable_restore (dockable_info, dock); if (dockable) { gimp_dockbook_add (GIMP_DOCKBOOK (dockbook), dockable, -1); n_dockables++; } } if (info->current_page < gtk_notebook_get_n_pages (GTK_NOTEBOOK (dockbook))) { gtk_notebook_set_current_page (GTK_NOTEBOOK (dockbook), info->current_page); } else if (n_dockables > 1) { gtk_notebook_set_current_page (GTK_NOTEBOOK (dockbook), 0); } /* Return the dockbook even if no dockable could be restored * (n_dockables == 0) because otherwise we would have to remove it * from the dock right here, which could implicitly destroy the * dock and make catching restore errors much harder on higher * levels. Instead, we check for restored empty dockbooks in our * caller. */ return GIMP_DOCKBOOK (dockbook); }
/** * gimp_dialog_factory_dockable_new: * @factory: a #GimpDialogFactory * @dock: a #GimpDock crated by this %factory. * @identifier: the identifier of the dialog as registered with * gimp_dialog_factory_register_entry() * @view_size: * * Creates a new #GimpDockable in the context of the #GimpDock it will be * added to. * * Implicitly raises & returns an already existing singleton dockable, * so callers should check that dockable->dockbook is NULL before trying * to add it to it's #GimpDockbook. * * Return value: the newly created #GimpDockable or an already existing * singleton dockable. **/ GtkWidget * gimp_dialog_factory_dockable_new (GimpDialogFactory *factory, GimpDock *dock, const gchar *identifier, gint view_size) { g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL); g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL); g_return_val_if_fail (identifier != NULL, NULL); return gimp_dialog_factory_dialog_new_internal (factory, gtk_widget_get_screen (GTK_WIDGET (dock)), dock->context, identifier, view_size, FALSE, FALSE); }
GimpDockbook * gimp_session_info_book_restore (GimpSessionInfoBook *info, GimpDock *dock) { GtkWidget *dockbook; GList *pages; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL); dockbook = gimp_dockbook_new (dock->dialog_factory->menu_factory); gimp_dock_add_book (dock, GIMP_DOCKBOOK (dockbook), -1); for (pages = info->dockables; pages; pages = g_list_next (pages)) { GimpSessionInfoDockable *dockable_info = pages->data; GimpDockable *dockable; dockable = gimp_session_info_dockable_restore (dockable_info, dock); if (dockable) gimp_dockbook_add (GIMP_DOCKBOOK (dockbook), dockable, -1); } if (info->current_page < gtk_notebook_get_n_pages (GTK_NOTEBOOK (dockbook))) { gtk_notebook_set_current_page (GTK_NOTEBOOK (dockbook), info->current_page); } else { gtk_notebook_set_current_page (GTK_NOTEBOOK (dockbook), 0); } return GIMP_DOCKBOOK (dockbook); }
GimpSessionInfoDock * gimp_session_info_dock_from_widget (GimpDock *dock) { GimpSessionInfoDock *dock_info; GList *list; GtkWidget *parent; g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL); dock_info = gimp_session_info_dock_new (GIMP_IS_TOOLBOX (dock) ? "gimp-toolbox" : "gimp-dock"); for (list = gimp_dock_get_dockbooks (dock); list; list = g_list_next (list)) { GimpSessionInfoBook *book; book = gimp_session_info_book_from_widget (list->data); dock_info->books = g_list_prepend (dock_info->books, book); } dock_info->books = g_list_reverse (dock_info->books); dock_info->side = gimp_session_info_dock_get_side (dock); parent = gtk_widget_get_parent (GTK_WIDGET (dock)); if (GTK_IS_PANED (parent)) { GtkPaned *paned = GTK_PANED (parent); if (GTK_WIDGET (dock) == gtk_paned_get_child2 (paned)) dock_info->position = gtk_paned_get_position (paned); } return dock_info; }
GimpContext * action_data_get_context (gpointer data) { GimpContext *result = NULL; static gboolean recursion = FALSE; if (! data || recursion) return NULL; recursion = TRUE; if (GIMP_IS_DOCK (data)) result = gimp_dock_get_context ((GimpDock *) data); else if (GIMP_IS_DOCK_WINDOW (data)) result = gimp_dock_window_get_context (((GimpDockWindow *) data)); else if (GIMP_IS_CONTAINER_VIEW (data)) result = gimp_container_view_get_context ((GimpContainerView *) data); else if (GIMP_IS_CONTAINER_EDITOR (data)) result = gimp_container_view_get_context (((GimpContainerEditor *) data)->view); else if (GIMP_IS_IMAGE_EDITOR (data)) result = ((GimpImageEditor *) data)->context; else if (GIMP_IS_NAVIGATION_EDITOR (data)) result = ((GimpNavigationEditor *) data)->context; if (! result) { Gimp *gimp = action_data_get_gimp (data); if (gimp) result = gimp_get_user_context (gimp); } recursion = FALSE; return result; }
GimpDock * gimp_session_info_dock_restore (GimpSessionInfoDock *dock_info, GimpDialogFactory *factory, GdkScreen *screen, gint monitor, GimpDockContainer *dock_container) { gint n_books = 0; GtkWidget *dock; GList *iter; GimpUIManager *ui_manager; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL); g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); ui_manager = gimp_dock_container_get_ui_manager (dock_container); dock = gimp_dialog_factory_dialog_new (factory, screen, monitor, ui_manager, dock_info->dock_type, -1 /*view_size*/, FALSE /*present*/); g_return_val_if_fail (GIMP_IS_DOCK (dock), NULL); /* Add the dock to the dock window immediately so the stuff in the * dock has access to e.g. a dialog factory */ gimp_dock_container_add_dock (dock_container, GIMP_DOCK (dock), dock_info); /* Note that if it is a toolbox, we will get here even though we * don't have any books */ for (iter = dock_info->books; iter; iter = g_list_next (iter)) { GimpSessionInfoBook *book_info = iter->data; GtkWidget *dockbook; dockbook = GTK_WIDGET (gimp_session_info_book_restore (book_info, GIMP_DOCK (dock))); if (dockbook) { GtkWidget *parent = gtk_widget_get_parent (dockbook); n_books++; if (GTK_IS_PANED (parent)) { GtkPaned *paned = GTK_PANED (parent); if (dockbook == gtk_paned_get_child2 (paned)) gtk_paned_set_position (paned, book_info->position); } } } /* Now remove empty dockbooks from the list, check the comment in * gimp_session_info_book_restore() which explains why the dock * can contain empty dockbooks at all */ if (dock_info->books) { GList *books; books = g_list_copy (gimp_dock_get_dockbooks (GIMP_DOCK (dock))); while (books) { GtkContainer *dockbook = books->data; GList *children = gtk_container_get_children (dockbook); if (children) { g_list_free (children); } else { g_object_ref (dockbook); gimp_dock_remove_book (GIMP_DOCK (dock), GIMP_DOCKBOOK (dockbook)); gtk_widget_destroy (GTK_WIDGET (dockbook)); g_object_unref (dockbook); n_books--; } books = g_list_remove (books, dockbook); } } /* if we removed all books again, the dock was destroyed, so bail out */ if (dock_info->books && n_books == 0) { return NULL; } gtk_widget_show (dock); return GIMP_DOCK (dock); }
void gimp_dialog_factory_remove_dialog (GimpDialogFactory *factory, GtkWidget *dialog) { GimpDialogFactory *dialog_factory; GimpDialogFactoryEntry *entry; GimpSessionInfo *session_info; GList *list; g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); g_return_if_fail (GTK_IS_WIDGET (dialog)); if (! g_list_find (factory->open_dialogs, dialog)) { g_warning ("%s: dialog not registered", G_STRFUNC); return; } factory->open_dialogs = g_list_remove (factory->open_dialogs, dialog); dialog_factory = gimp_dialog_factory_from_widget (dialog, &entry); if (! (dialog_factory && (entry || GIMP_IS_DOCK (dialog)))) { g_warning ("%s: dialog was not created by a GimpDialogFactory", G_STRFUNC); return; } if (dialog_factory != factory) { g_warning ("%s: dialog was created by a different GimpDialogFactory", G_STRFUNC); return; } D (g_print ("%s: removing \"%s\"\n", G_STRFUNC, entry ? entry->identifier : "dock")); for (list = factory->session_infos; list; list = g_list_next (list)) { session_info = (GimpSessionInfo *) list->data; if (session_info->widget == dialog) { D (g_print ("%s: clearing session info %p (widget %p) for \"%s\"\n", G_STRFUNC, session_info, session_info->widget, entry ? entry->identifier : "dock")); session_info->widget = NULL; /* don't save session info for empty docks */ if (GIMP_IS_DOCK (dialog)) { factory->session_infos = g_list_remove (factory->session_infos, session_info); gimp_session_info_free (session_info); } break; } } }
void gimp_dialog_factory_add_dialog (GimpDialogFactory *factory, GtkWidget *dialog) { GimpDialogFactory *dialog_factory; GimpDialogFactoryEntry *entry; GimpSessionInfo *info; GList *list; gboolean toplevel; g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); g_return_if_fail (GTK_IS_WIDGET (dialog)); if (g_list_find (factory->open_dialogs, dialog)) { g_warning ("%s: dialog already registered", G_STRFUNC); return; } dialog_factory = gimp_dialog_factory_from_widget (dialog, &entry); if (! (dialog_factory && (entry || GIMP_IS_DOCK (dialog)))) { g_warning ("%s: dialog was not created by a GimpDialogFactory", G_STRFUNC); return; } if (dialog_factory != factory) { g_warning ("%s: dialog was created by a different GimpDialogFactory", G_STRFUNC); return; } toplevel = GTK_WIDGET_TOPLEVEL (dialog); if (entry) /* dialog is a toplevel (but not a GimpDock) or a GimpDockable */ { D (g_print ("%s: adding %s \"%s\"\n", G_STRFUNC, toplevel ? "toplevel" : "dockable", entry->identifier)); for (list = factory->session_infos; list; list = g_list_next (list)) { info = list->data; if ((info->toplevel_entry == entry) || (info->dockable_entry == entry)) { if (info->widget) { if (entry->singleton) { g_warning ("%s: singleton dialog \"%s\" created twice", G_STRFUNC, entry->identifier); D (g_print ("%s: corrupt session info: %p (widget %p)\n", G_STRFUNC, info, info->widget)); return; } continue; } info->widget = dialog; D (g_print ("%s: updating session info %p (widget %p) for %s \"%s\"\n", G_STRFUNC, info, info->widget, toplevel ? "toplevel" : "dockable", entry->identifier)); if (toplevel && entry->session_managed) gimp_session_info_set_geometry (info); break; } } if (! list) /* didn't find a session info */ { info = gimp_session_info_new (); info->widget = dialog; D (g_print ("%s: creating session info %p (widget %p) for %s \"%s\"\n", G_STRFUNC, info, info->widget, toplevel ? "toplevel" : "dockable", entry->identifier)); if (toplevel) { info->toplevel_entry = entry; /* if we create a new session info, we never call * gimp_session_info_set_geometry(), but still the * dialog needs GDK_HINT_USER_POS so it keeps its * position when hidden/shown within this(!) session. */ if (entry->session_managed) g_signal_connect (dialog, "configure-event", G_CALLBACK (gimp_dialog_factory_set_user_pos), NULL); } else { info->dockable_entry = entry; } factory->session_infos = g_list_append (factory->session_infos, info); } } else /* dialog is a GimpDock */ { D (g_print ("%s: adding dock\n", G_STRFUNC)); for (list = factory->session_infos; list; list = g_list_next (list)) { info = list->data; /* take the first empty slot */ if (! info->toplevel_entry && ! info->dockable_entry && ! info->widget) { info->widget = dialog; D (g_print ("%s: updating session info %p (widget %p) for dock\n", G_STRFUNC, info, info->widget)); gimp_session_info_set_geometry (info); break; } } if (! list) /* didn't find a session info */ { info = gimp_session_info_new (); info->widget = dialog; D (g_print ("%s: creating session info %p (widget %p) for dock\n", G_STRFUNC, info, info->widget)); /* if we create a new session info, we never call * gimp_session_info_set_geometry(), but still the * dialog needs GDK_HINT_USER_POS so it keeps its * position when hidden/shown within this(!) session. */ g_signal_connect (dialog, "configure-event", G_CALLBACK (gimp_dialog_factory_set_user_pos), NULL); factory->session_infos = g_list_append (factory->session_infos, info); } } factory->open_dialogs = g_list_prepend (factory->open_dialogs, dialog); g_signal_connect_object (dialog, "destroy", G_CALLBACK (gimp_dialog_factory_remove_dialog), factory, G_CONNECT_SWAPPED); if (entry && entry->session_managed && toplevel) g_signal_connect_object (dialog, "configure-event", G_CALLBACK (gimp_dialog_factory_dialog_configure), factory, 0); }
void gimp_dialog_factory_remove_dialog (GimpDialogFactory *factory, GtkWidget *dialog) { GimpDialogFactory *dialog_factory; GimpDialogFactoryEntry *entry; GList *list; g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); g_return_if_fail (GTK_IS_WIDGET (dialog)); if (! g_list_find (factory->open_dialogs, dialog)) { g_warning ("%s: dialog not registered", G_STRFUNC); return; } factory->open_dialogs = g_list_remove (factory->open_dialogs, dialog); dialog_factory = gimp_dialog_factory_from_widget (dialog, &entry); if (! (dialog_factory && (entry || GIMP_IS_DOCK (dialog)))) { g_warning ("%s: dialog was not created by a GimpDialogFactory", G_STRFUNC); return; } if (dialog_factory != factory) { g_warning ("%s: dialog was created by a different GimpDialogFactory", G_STRFUNC); return; } GIMP_LOG (DIALOG_FACTORY, "removing \"%s\"", entry ? entry->identifier : "dock"); for (list = factory->session_infos; list; list = g_list_next (list)) { GimpSessionInfo *session_info = list->data; if (session_info->widget == dialog) { GIMP_LOG (DIALOG_FACTORY, "clearing session info %p (widget %p) for \"%s\"", session_info, session_info->widget, entry ? entry->identifier : "dock"); session_info->widget = NULL; gimp_dialog_factory_unset_widget_data (dialog); g_signal_handlers_disconnect_by_func (dialog, gimp_dialog_factory_set_user_pos, NULL); g_signal_handlers_disconnect_by_func (dialog, gimp_dialog_factory_remove_dialog, factory); if (entry && entry->session_managed && GTK_WIDGET_TOPLEVEL (dialog)) g_signal_handlers_disconnect_by_func (dialog, gimp_dialog_factory_dialog_configure, factory); if (GIMP_IS_DOCK (dialog)) { /* don't save session info for empty docks */ factory->session_infos = g_list_remove (factory->session_infos, session_info); g_object_unref (session_info); g_signal_emit (factory, factory_signals[DOCK_REMOVED], 0, dialog); } break; } } }