void gimp_session_info_restore (GimpSessionInfo *info, GimpDialogFactory *factory) { GtkWidget *dialog = NULL; GdkDisplay *display = NULL; GdkScreen *screen = NULL; GimpRestoreDocksData *data = NULL; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); g_object_ref (info); display = gdk_display_get_default (); if (info->p->screen != DEFAULT_SCREEN) screen = gdk_display_get_screen (display, info->p->screen); if (! screen) screen = gdk_display_get_default_screen (display); info->p->open = FALSE; info->p->screen = DEFAULT_SCREEN; if (info->p->factory_entry && info->p->factory_entry->restore_func) { dialog = info->p->factory_entry->restore_func (factory, screen, info); } if (GIMP_IS_SESSION_MANAGED (dialog) && info->p->aux_info) gimp_session_managed_set_aux_info (GIMP_SESSION_MANAGED (dialog), info->p->aux_info); /* In single-window mode, gimp_session_managed_set_aux_info() * will set the size of the dock areas at the sides. If we don't * wait for those areas to get their size-allocation, we can't * properly restore the docks inside them, so do that in an idle * callback. */ /* Objects are unreffed again in the callback */ data = g_slice_new0 (GimpRestoreDocksData); data->info = g_object_ref (info); data->factory = g_object_ref (factory); data->screen = g_object_ref (screen); data->dialog = g_object_ref (dialog); g_idle_add ((GSourceFunc) gimp_session_info_restore_docks, data); g_object_unref (info); }
void gimp_dialog_factory_set_constructor (GimpDialogFactory *factory, GimpDialogConstructor constructor) { g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); if (! constructor) constructor = gimp_dialog_factory_default_constructor; factory->constructor = constructor; }
void gimp_dialog_factory_show_toolbox (GimpDialogFactory *toolbox_factory) { GtkWidget *toolbox; g_return_if_fail (GIMP_IS_DIALOG_FACTORY (toolbox_factory)); toolbox = gimp_dialog_factory_get_toolbox (toolbox_factory); if (toolbox) gtk_window_present (GTK_WINDOW (toolbox)); }
/** * gimp_dialog_factory_dialog_raise: * @factory: a #GimpDialogFactory * @screen: the #GdkScreen the dialog should appear on * @identifiers: a '|' separated list of identifiers of dialogs as * registered with gimp_dialog_factory_register_entry() * @view_size: * * Raises any of a list of already existing toplevel dialog or * #GimpDockable if it was already created by this %facory. * * Implicitly creates the first dialog in the list if none of the dialogs * were found. * * Return value: the raised or newly created dialog. **/ GtkWidget * gimp_dialog_factory_dialog_raise (GimpDialogFactory *factory, GdkScreen *screen, const gchar *identifiers, gint view_size) { GtkWidget *dialog; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL); g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); g_return_val_if_fail (identifiers != NULL, NULL); /* If the identifier is a list, try to find a matching dialog and * raise it. If there's no match, use the first list item. */ if (strchr (identifiers, '|')) { gchar **ids = g_strsplit (identifiers, "|", 0); gint i; for (i = 0; ids[i]; i++) { GimpSessionInfo *info; info = gimp_dialog_factory_find_session_info (factory, ids[i]); if (info && info->widget) break; } dialog = gimp_dialog_factory_dialog_new_internal (factory, screen, NULL, ids[i] ? ids[i] : ids[0], view_size, TRUE, TRUE); g_strfreev (ids); } else { dialog = gimp_dialog_factory_dialog_new_internal (factory, screen, NULL, identifiers, view_size, TRUE, TRUE); } return dialog; }
static GimpPaletteEditor * context_get_palette_editor (void) { GtkWidget *widget; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (gimp_dialog_factory_get_singleton ()), NULL); widget = gimp_dialog_factory_find_widget (gimp_dialog_factory_get_singleton (), "gimp-palette-editor"); if (widget) return GIMP_PALETTE_EDITOR (gtk_bin_get_child (GTK_BIN (widget))); return NULL; }
static GimpColormapEditor * context_get_colormap_editor (void) { GtkWidget *widget; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (gimp_dialog_factory_get_singleton ()), NULL); widget = gimp_dialog_factory_find_widget (gimp_dialog_factory_get_singleton (), "gimp-indexed-palette"); if (widget) return GIMP_COLORMAP_EDITOR (gtk_bin_get_child (GTK_BIN (widget))); return NULL; }
static GimpPaletteEditor * context_get_palette_editor (void) { GimpSessionInfo *info = NULL; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (gimp_dialog_factory_get_singleton ()), NULL); info = gimp_dialog_factory_find_session_info (gimp_dialog_factory_get_singleton (), "gimp-palette-editor"); if (info && gimp_session_info_get_widget (info)) return GIMP_PALETTE_EDITOR (gtk_bin_get_child (GTK_BIN (gimp_session_info_get_widget (info)))); return NULL; }
static GimpColormapEditor * context_get_colormap_editor (void) { GimpSessionInfo *info = NULL; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (gimp_dialog_factory_get_singleton ()), NULL); info = gimp_dialog_factory_find_session_info (gimp_dialog_factory_get_singleton (), "gimp-indexed-palette"); if (info && gimp_session_info_get_widget (info)) return GIMP_COLORMAP_EDITOR (gtk_bin_get_child (GTK_BIN (gimp_session_info_get_widget (info)))); return NULL; }
void gimp_session_info_restore (GimpSessionInfo *info, GimpDialogFactory *factory, GdkMonitor *monitor) { GtkWidget *dialog = NULL; GimpRestoreDocksData *data; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); g_return_if_fail (GDK_IS_MONITOR (monitor)); g_object_ref (info); info->p->open = FALSE; if (info->p->factory_entry && info->p->factory_entry->restore_func) { dialog = info->p->factory_entry->restore_func (factory, monitor, info); } else g_printerr ("EEEEK\n"); if (GIMP_IS_SESSION_MANAGED (dialog) && info->p->aux_info) gimp_session_managed_set_aux_info (GIMP_SESSION_MANAGED (dialog), info->p->aux_info); /* In single-window mode, gimp_session_managed_set_aux_info() * will set the size of the dock areas at the sides. If we don't * wait for those areas to get their size-allocation, we can't * properly restore the docks inside them, so do that in an idle * callback. */ /* Objects are unreffed again in the callback */ data = g_slice_new0 (GimpRestoreDocksData); data->info = g_object_ref (info); data->factory = g_object_ref (factory); data->monitor = g_object_ref (monitor); data->dialog = dialog ? g_object_ref (dialog) : NULL; g_idle_add ((GSourceFunc) gimp_session_info_restore_docks, data); g_object_unref (info); }
GtkWidget * dialogs_get_toolbox (void) { GList *list; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (global_toolbox_factory), NULL); for (list = global_toolbox_factory->open_dialogs; list; list = g_list_next (list)) { if (GTK_WIDGET_TOPLEVEL (list->data)) return list->data; } return NULL; }
/** * 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); }
GtkWidget * dialogs_get_toolbox (void) { GList *list; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (gimp_dialog_factory_get_singleton ()), NULL); for (list = gimp_dialog_factory_get_open_dialogs (gimp_dialog_factory_get_singleton ()); list; list = g_list_next (list)) { if (GIMP_IS_DOCK_WINDOW (list->data) && gimp_dock_window_has_toolbox (list->data)) return list->data; } return NULL; }
GimpDialogFactoryEntry * gimp_dialog_factory_find_entry (GimpDialogFactory *factory, const gchar *identifier) { GList *list; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL); g_return_val_if_fail (identifier != NULL, NULL); for (list = factory->registered_dialogs; list; list = g_list_next (list)) { GimpDialogFactoryEntry *entry = list->data; if (! strcmp (identifier, entry->identifier)) return entry; } return NULL; }
/** * gimp_dock_with_window_new: * @factory: a #GimpDialogFacotry * @screen: the #GdkScreen the dock window should appear on * @toolbox: if %TRUE; gives a "gimp-toolbox-window" with a * "gimp-toolbox", "gimp-dock-window"+"gimp-dock" * otherwise * * Returns: the newly created #GimpDock with the #GimpDockWindow **/ GtkWidget * gimp_dock_with_window_new (GimpDialogFactory *factory, GdkScreen *screen, gboolean toolbox) { GtkWidget *dock_window; GimpDockContainer *dock_container; GtkWidget *dock; GimpUIManager *ui_manager; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL); g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); /* Create a dock window to put the dock in. We need to create the * dock window before the dock because the dock has a dependency to * the ui manager in the dock window */ dock_window = gimp_dialog_factory_dialog_new (factory, screen, NULL /*ui_manager*/, (toolbox ? "gimp-toolbox-window" : "gimp-dock-window"), -1 /*view_size*/, FALSE /*present*/); dock_container = GIMP_DOCK_CONTAINER (dock_window); ui_manager = gimp_dock_container_get_ui_manager (dock_container); dock = gimp_dialog_factory_dialog_new (factory, screen, ui_manager, (toolbox ? "gimp-toolbox" : "gimp-dock"), -1 /*view_size*/, FALSE /*present*/); if (dock) gimp_dock_window_add_dock (GIMP_DOCK_WINDOW (dock_window), GIMP_DOCK (dock), -1); return dock; }
/** * gimp_dialog_factory_dialog_new: * @factory: a #GimpDialogFactory * @screen: the #GdkScreen the dialog should appear on * @identifier: the identifier of the dialog as registered with * gimp_dialog_factory_register_entry() * @view_size: * @present: whether gtk_window_present() should be called * * Creates a new toplevel dialog or a #GimpDockable, depending on whether * %factory is a toplevel of dockable factory. * * Return value: the newly created dialog or an already existing singleton * dialog. **/ GtkWidget * gimp_dialog_factory_dialog_new (GimpDialogFactory *factory, GdkScreen *screen, const gchar *identifier, gint view_size, gboolean present) { g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL); g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); g_return_val_if_fail (identifier != NULL, NULL); return gimp_dialog_factory_dialog_new_internal (factory, screen, factory->context, identifier, view_size, FALSE, present); }
void gimp_dialog_factory_add_foreign (GimpDialogFactory *factory, const gchar *identifier, GtkWidget *dialog) { GimpDialogFactory *dialog_factory; GimpDialogFactoryEntry *entry; g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); g_return_if_fail (identifier != NULL); g_return_if_fail (GTK_IS_WIDGET (dialog)); g_return_if_fail (GTK_WIDGET_TOPLEVEL (dialog)); dialog_factory = gimp_dialog_factory_from_widget (dialog, &entry); if (dialog_factory || entry) { g_warning ("%s: dialog was created by a GimpDialogFactory", G_STRFUNC); return; } entry = gimp_dialog_factory_find_entry (factory, identifier); if (! entry) { g_warning ("%s: no entry registered for \"%s\"", G_STRFUNC, identifier); return; } if (entry->new_func) { g_warning ("%s: entry for \"%s\" has a constructor (is not foreign)", G_STRFUNC, identifier); return; } gimp_dialog_factory_set_widget_data (dialog, factory, entry); gimp_dialog_factory_add_dialog (factory, dialog); }
static void gimp_dialog_factory_set_widget_data (GtkWidget *dialog, GimpDialogFactory *factory, GimpDialogFactoryEntry *entry) { g_return_if_fail (GTK_IS_WIDGET (dialog)); g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); if (! gimp_dialog_factory_key) { gimp_dialog_factory_key = g_quark_from_static_string ("gimp-dialog-factory"); gimp_dialog_factory_entry_key = g_quark_from_static_string ("gimp-dialog-factory-entry"); } g_object_set_qdata (G_OBJECT (dialog), gimp_dialog_factory_key, factory); if (entry) g_object_set_qdata (G_OBJECT (dialog), gimp_dialog_factory_entry_key, entry); }
/** * gimp_dialog_factory_dock_new: * @factory: a #GimpDialogFacotry * @screen: the #GdkScreen the dock should appear on * * Returns a new #GimpDock in this %factory's context. We use a function * pointer passed to this %factory's constructor instead of simply * gimp_dock_new() because we may want different instances of * #GimpDialogFactory create different subclasses of #GimpDock. * * Return value: the newly created #GimpDock. **/ GtkWidget * gimp_dialog_factory_dock_new (GimpDialogFactory *factory, GdkScreen *screen) { GtkWidget *dock; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL); g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); g_return_val_if_fail (factory->new_dock_func != NULL, NULL); dock = factory->new_dock_func (factory, factory->context, 0); if (dock) { gtk_window_set_screen (GTK_WINDOW (dock), screen); gimp_dialog_factory_set_widget_data (dock, factory, NULL); gimp_dialog_factory_add_dialog (factory, dock); } return dock; }
void gimp_dialog_factory_register_entry (GimpDialogFactory *factory, const gchar *identifier, const gchar *name, const gchar *blurb, const gchar *stock_id, const gchar *help_id, GimpDialogNewFunc new_func, gint view_size, gboolean singleton, gboolean session_managed, gboolean remember_size, gboolean remember_if_open) { GimpDialogFactoryEntry *entry; g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); g_return_if_fail (identifier != NULL); entry = g_slice_new0 (GimpDialogFactoryEntry); entry->identifier = g_strdup (identifier); entry->name = g_strdup (name); entry->blurb = g_strdup (blurb); entry->stock_id = g_strdup (stock_id); entry->help_id = g_strdup (help_id); entry->new_func = new_func; entry->view_size = view_size; entry->singleton = singleton ? TRUE : FALSE; entry->session_managed = session_managed ? TRUE : FALSE; entry->remember_size = remember_size ? TRUE : FALSE; entry->remember_if_open = remember_if_open ? TRUE : FALSE; factory->registered_dialogs = g_list_prepend (factory->registered_dialogs, entry); }
GimpSessionInfo * gimp_dialog_factory_find_session_info (GimpDialogFactory *factory, const gchar *identifier) { GList *list; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL); g_return_val_if_fail (identifier != NULL, NULL); for (list = factory->session_infos; list; list = g_list_next (list)) { GimpSessionInfo *info = list->data; if ((info->toplevel_entry && ! strcmp (identifier, info->toplevel_entry->identifier)) || (info->dockable_entry && ! strcmp (identifier, info->dockable_entry->identifier))) { return info; } } return NULL; }
GtkWidget * gimp_color_dialog_new (GimpViewable *viewable, GimpContext *context, const gchar *title, const gchar *stock_id, const gchar *desc, GtkWidget *parent, GimpDialogFactory *dialog_factory, const gchar *dialog_identifier, const GimpRGB *color, gboolean wants_updates, gboolean show_alpha) { GimpColorDialog *dialog; const gchar *role; g_return_val_if_fail (viewable == NULL || GIMP_IS_VIEWABLE (viewable), NULL); g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (GTK_IS_WIDGET (parent), NULL); g_return_val_if_fail (dialog_factory == NULL || GIMP_IS_DIALOG_FACTORY (dialog_factory), NULL); g_return_val_if_fail (dialog_factory == NULL || dialog_identifier != NULL, NULL); g_return_val_if_fail (color != NULL, NULL); if (! context) g_warning ("gimp_color_dialog_new() called with a NULL context"); role = dialog_identifier ? dialog_identifier : "gimp-color-selector"; dialog = g_object_new (GIMP_TYPE_COLOR_DIALOG, "title", title, "role", role, "help-func", gimp_color_dialog_help_func, "help-id", GIMP_HELP_COLOR_DIALOG, "stock-id", stock_id, "description", desc, "parent", parent, NULL); if (viewable) { gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (dialog), viewable, context); } else { GtkWidget *parent; parent = gtk_widget_get_parent (GIMP_VIEWABLE_DIALOG (dialog)->icon); parent = gtk_widget_get_parent (parent); gtk_widget_hide (parent); } dialog->wants_updates = wants_updates; if (dialog_factory) gimp_dialog_factory_add_foreign (dialog_factory, dialog_identifier, GTK_WIDGET (dialog)); gimp_color_selection_set_show_alpha (GIMP_COLOR_SELECTION (dialog->selection), show_alpha); if (context) { g_object_set_data (G_OBJECT (context->gimp->config->color_management), "gimp-context", context); gimp_color_selection_set_config (GIMP_COLOR_SELECTION (dialog->selection), context->gimp->config->color_management); g_object_set_data (G_OBJECT (context->gimp->config->color_management), "gimp-context", NULL); } gimp_color_selection_set_color (GIMP_COLOR_SELECTION (dialog->selection), color); gimp_color_selection_set_old_color (GIMP_COLOR_SELECTION (dialog->selection), color); return GTK_WIDGET (dialog); }
GtkWidget * gimp_container_popup_new (GimpContainer *container, GimpContext *context, GimpViewType view_type, gint default_view_size, gint view_size, gint view_border_width, GimpDialogFactory *dialog_factory, const gchar *dialog_identifier, const gchar *dialog_stock_id, const gchar *dialog_tooltip) { GimpContainerPopup *popup; g_return_val_if_fail (GIMP_IS_CONTAINER (container), NULL); g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (default_view_size > 0 && default_view_size <= GIMP_VIEWABLE_MAX_POPUP_SIZE, NULL); g_return_val_if_fail (view_size > 0 && view_size <= GIMP_VIEWABLE_MAX_POPUP_SIZE, NULL); g_return_val_if_fail (view_border_width >= 0 && view_border_width <= GIMP_VIEW_MAX_BORDER_WIDTH, NULL); g_return_val_if_fail (dialog_factory == NULL || GIMP_IS_DIALOG_FACTORY (dialog_factory), NULL); if (dialog_factory) { g_return_val_if_fail (dialog_identifier != NULL, NULL); g_return_val_if_fail (dialog_stock_id != NULL, NULL); g_return_val_if_fail (dialog_tooltip != NULL, NULL); } popup = g_object_new (GIMP_TYPE_CONTAINER_POPUP, "type", GTK_WINDOW_POPUP, NULL); gtk_window_set_resizable (GTK_WINDOW (popup), FALSE); popup->container = container; popup->orig_context = context; popup->context = gimp_context_new (context->gimp, "popup", context); popup->view_type = view_type; popup->default_view_size = default_view_size; popup->view_size = view_size; popup->view_border_width = view_border_width; g_signal_connect (popup->context, gimp_context_type_to_signal_name (gimp_container_get_children_type (container)), G_CALLBACK (gimp_container_popup_context_changed), popup); if (dialog_factory) { popup->dialog_factory = dialog_factory; popup->dialog_identifier = g_strdup (dialog_identifier); popup->dialog_stock_id = g_strdup (dialog_stock_id); popup->dialog_tooltip = g_strdup (dialog_tooltip); } gimp_container_popup_create_view (popup); return GTK_WIDGET (popup); }
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; } } }
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); }
static GtkWidget * gimp_dialog_factory_dialog_new_internal (GimpDialogFactory *factory, GdkScreen *screen, GimpContext *context, const gchar *identifier, gint view_size, gboolean return_existing, gboolean present) { GimpDialogFactoryEntry *entry; GtkWidget *dialog = NULL; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL); g_return_val_if_fail (identifier != NULL, NULL); entry = gimp_dialog_factory_find_entry (factory, identifier); if (! entry) { g_warning ("%s: no entry registered for \"%s\"", G_STRFUNC, identifier); return NULL; } if (! entry->new_func) { g_warning ("%s: entry for \"%s\" has no constructor", G_STRFUNC, identifier); return NULL; } /* a singleton dialog is always returned if it already exisits */ if (return_existing || entry->singleton) { GimpSessionInfo *info; info = gimp_dialog_factory_find_session_info (factory, identifier); if (info) dialog = info->widget; } /* create the dialog if it was not found */ if (! dialog) { GtkWidget *dock = NULL; /* If the dialog will be a dockable (factory->new_dock_func) and * we are called from gimp_dialog_factory_dialog_raise() (! context), * create a new dock _before_ creating the dialog. * We do this because the new dockable needs to be created in it's * dock's context. */ if (factory->new_dock_func && ! context) { GtkWidget *dockbook; dock = gimp_dialog_factory_dock_new (factory, screen); dockbook = gimp_dockbook_new (factory->menu_factory); gimp_dock_add_book (GIMP_DOCK (dock), GIMP_DOCKBOOK (dockbook), 0); } /* Create the new dialog in the appropriate context which is * - the passed context if not NULL * - the newly created dock's context if we just created it * - the factory's context, which happens when raising a toplevel * dialog was the original request. */ if (view_size < GIMP_VIEW_SIZE_TINY) view_size = entry->view_size; if (context) dialog = factory->constructor (factory, entry, context, view_size); else if (dock) dialog = factory->constructor (factory, entry, GIMP_DOCK (dock)->context, view_size); else dialog = factory->constructor (factory, entry, factory->context, view_size); if (dialog) { gimp_dialog_factory_set_widget_data (dialog, factory, entry); /* If we created a dock before, the newly created dialog is * supposed to be a GimpDockable. */ if (dock) { if (GIMP_IS_DOCKABLE (dialog)) { gimp_dock_add (GIMP_DOCK (dock), GIMP_DOCKABLE (dialog), 0, 0); gtk_widget_show (dock); } else { g_warning ("%s: GimpDialogFactory is a dockable factory " "but constructor for \"%s\" did not return a " "GimpDockable", G_STRFUNC, identifier); gtk_widget_destroy (dialog); gtk_widget_destroy (dock); dialog = NULL; dock = NULL; } } } else if (dock) { g_warning ("%s: constructor for \"%s\" returned NULL", G_STRFUNC, identifier); gtk_widget_destroy (dock); dock = NULL; } if (dialog) gimp_dialog_factory_add_dialog (factory, dialog); } /* Finally, if we found an existing dialog or created a new one, raise it. */ if (! dialog) return NULL; if (GTK_WIDGET_TOPLEVEL (dialog)) { gtk_window_set_screen (GTK_WINDOW (dialog), screen); if (present) gtk_window_present (GTK_WINDOW (dialog)); } else if (GIMP_IS_DOCKABLE (dialog)) { GimpDockable *dockable = GIMP_DOCKABLE (dialog); if (dockable->dockbook && dockable->dockbook->dock) { GtkNotebook *notebook = GTK_NOTEBOOK (dockable->dockbook); gint num = gtk_notebook_page_num (notebook, dialog); if (num != -1) { gtk_notebook_set_current_page (notebook, num); gimp_dockable_blink (dockable); } } if (present) { GtkWidget *toplevel = gtk_widget_get_toplevel (dialog); if (GTK_IS_WINDOW (toplevel)) gtk_window_present (GTK_WINDOW (toplevel)); } } return dialog; }