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);
}
Exemple #3
0
/**
 * 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;
}
Exemple #6
0
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);
}
Exemple #8
0
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;
        }
    }
}
Exemple #9
0
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);
}
Exemple #10
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;
        }
    }
}