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);
}
Beispiel #5
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;
}
Beispiel #6
0
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
}