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); }
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); }
static GtkWidget * gimp_single_window_strategy_show_dockable_dialog (GimpWindowStrategy *strategy, Gimp *gimp, GimpDialogFactory *factory, GdkMonitor *monitor, const gchar *identifiers) { GList *windows = gimp_get_image_windows (gimp); GtkWidget *widget = NULL; GimpImageWindow *window; g_return_val_if_fail (windows != NULL, NULL); /* In single-window mode, there should only be one window... */ window = GIMP_IMAGE_WINDOW (windows->data); if (strcmp ("gimp-toolbox", identifiers) == 0) { /* Only allow one toolbox... */ if (! gimp_image_window_has_toolbox (window)) { GimpDockColumns *columns; GimpUIManager *ui_manager = gimp_image_window_get_ui_manager (window); widget = gimp_dialog_factory_dialog_new (factory, monitor, ui_manager, GTK_WIDGET (window), "gimp-toolbox", -1 /*view_size*/, FALSE /*present*/); gtk_widget_show (widget); columns = gimp_image_window_get_left_docks (window); gimp_dock_columns_add_dock (columns, GIMP_DOCK (widget), -1 /*index*/); } } else if (gimp_dialog_factory_find_widget (factory, identifiers)) { /* if the dialog is already open, simply raise it */ return gimp_dialog_factory_dialog_raise (factory, monitor, GTK_WIDGET (window), identifiers, -1); } else { GtkWidget *dockbook; dockbook = gimp_image_window_get_default_dockbook (window); if (! dockbook) { GimpDockColumns *dock_columns; /* No dock, need to add one */ dock_columns = gimp_image_window_get_right_docks (window); gimp_dock_columns_prepare_dockbook (dock_columns, -1 /*index*/, &dockbook); } widget = gimp_dockbook_add_from_dialog_factory (GIMP_DOCKBOOK (dockbook), identifiers); } g_list_free (windows); return widget; }
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); }
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; }
void dockable_actions_update (GimpActionGroup *group, gpointer data) { GimpDockable *dockable; GimpDockbook *dockbook; GimpDocked *docked; GimpDialogFactoryEntry *entry; GimpContainerView *view; GimpViewType view_type = -1; gboolean list_view_available = FALSE; gboolean grid_view_available = FALSE; GimpViewSize view_size = -1; GimpTabStyle tab_style = -1; gint n_pages = 0; gint n_books = 0; if (GIMP_IS_DOCKBOOK (data)) { gint page_num; dockbook = GIMP_DOCKBOOK (data); page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook)); dockable = (GimpDockable *) gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num); } else if (GIMP_IS_DOCKABLE (data)) { dockable = GIMP_DOCKABLE (data); dockbook = dockable->dockbook; } else { return; } docked = GIMP_DOCKED (gtk_bin_get_child (GTK_BIN (dockable))); gimp_dialog_factory_from_widget (GTK_WIDGET (dockable), &entry); if (entry) { gchar *identifier; gchar *substring = NULL; identifier = g_strdup (entry->identifier); if ((substring = strstr (identifier, "grid"))) view_type = GIMP_VIEW_TYPE_GRID; else if ((substring = strstr (identifier, "list"))) view_type = GIMP_VIEW_TYPE_LIST; if (substring) { memcpy (substring, "list", 4); if (gimp_dialog_factory_find_entry (dockbook->dock->dialog_factory, identifier)) list_view_available = TRUE; memcpy (substring, "grid", 4); if (gimp_dialog_factory_find_entry (dockbook->dock->dialog_factory, identifier)) grid_view_available = TRUE; } g_free (identifier); } view = gimp_container_view_get_by_dockable (dockable); if (view) view_size = gimp_container_view_get_view_size (view, NULL); tab_style = dockable->tab_style; n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (dockbook)); n_books = g_list_length (dockbook->dock->dockbooks); #define SET_ACTIVE(action,active) \ gimp_action_group_set_action_active (group, action, (active) != 0) #define SET_VISIBLE(action,active) \ gimp_action_group_set_action_visible (group, action, (active) != 0) #define SET_SENSITIVE(action,sensitive) \ gimp_action_group_set_action_sensitive (group, action, (sensitive) != 0) SET_SENSITIVE ("dockable-detach-tab", n_pages > 1 || n_books > 1); SET_VISIBLE ("dockable-preview-size-menu", view_size != -1); if (view_size != -1) { if (view_size >= GIMP_VIEW_SIZE_GIGANTIC) { SET_ACTIVE ("dockable-preview-size-gigantic", TRUE); } else if (view_size >= GIMP_VIEW_SIZE_ENORMOUS) { SET_ACTIVE ("dockable-preview-size-enormous", TRUE); } else if (view_size >= GIMP_VIEW_SIZE_HUGE) { SET_ACTIVE ("dockable-preview-size-huge", TRUE); } else if (view_size >= GIMP_VIEW_SIZE_EXTRA_LARGE) { SET_ACTIVE ("dockable-preview-size-extra-large", TRUE); } else if (view_size >= GIMP_VIEW_SIZE_LARGE) { SET_ACTIVE ("dockable-preview-size-large", TRUE); } else if (view_size >= GIMP_VIEW_SIZE_MEDIUM) { SET_ACTIVE ("dockable-preview-size-medium", TRUE); } else if (view_size >= GIMP_VIEW_SIZE_SMALL) { SET_ACTIVE ("dockable-preview-size-small", TRUE); } else if (view_size >= GIMP_VIEW_SIZE_EXTRA_SMALL) { SET_ACTIVE ("dockable-preview-size-extra-small", TRUE); } else if (view_size >= GIMP_VIEW_SIZE_TINY) { SET_ACTIVE ("dockable-preview-size-tiny", TRUE); } } SET_VISIBLE ("dockable-tab-style-menu", n_pages > 1); if (n_pages > 1) { GimpDockedInterface *docked_iface = GIMP_DOCKED_GET_INTERFACE (docked); if (tab_style == GIMP_TAB_STYLE_ICON) SET_ACTIVE ("dockable-tab-style-icon", TRUE); else if (tab_style == GIMP_TAB_STYLE_PREVIEW) SET_ACTIVE ("dockable-tab-style-preview", TRUE); else if (tab_style == GIMP_TAB_STYLE_NAME) SET_ACTIVE ("dockable-tab-style-name", TRUE); else if (tab_style == GIMP_TAB_STYLE_ICON_NAME) SET_ACTIVE ("dockable-tab-style-icon-name", TRUE); else if (tab_style == GIMP_TAB_STYLE_PREVIEW_NAME) SET_ACTIVE ("dockable-tab-style-preview-name", TRUE); SET_SENSITIVE ("dockable-tab-style-preview", docked_iface->get_preview); SET_SENSITIVE ("dockable-tab-style-preview-name", docked_iface->get_preview); } SET_VISIBLE ("dockable-view-type-grid", view_type != -1); SET_VISIBLE ("dockable-view-type-list", view_type != -1); if (view_type != -1) { if (view_type == GIMP_VIEW_TYPE_LIST) SET_ACTIVE ("dockable-view-type-list", TRUE); else SET_ACTIVE ("dockable-view-type-grid", TRUE); SET_SENSITIVE ("dockable-view-type-grid", grid_view_available); SET_SENSITIVE ("dockable-view-type-list", list_view_available); } SET_VISIBLE ("dockable-show-button-bar", gimp_docked_has_button_bar (docked)); SET_ACTIVE ("dockable-show-button-bar", gimp_docked_get_show_button_bar (docked)); #undef SET_ACTIVE #undef SET_VISIBLE #undef SET_SENSITIVE }