예제 #1
0
파일: dialogs.c 프로젝트: alfanak/gimp
static void
dialogs_ensure_factory_entry_on_recent_dock (GimpSessionInfo *info)
{
  if (! gimp_session_info_get_factory_entry (info))
    {
      GimpDialogFactoryEntry *entry = NULL;

      /* The recent docks container only contains session infos for
       * dock windows
       */
      entry = gimp_dialog_factory_find_entry (gimp_dialog_factory_get_singleton (),
                                              "gimp-dock-window");

      gimp_session_info_set_factory_entry (info, entry);
    }
}
예제 #2
0
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);
}
예제 #3
0
파일: session.c 프로젝트: peixuan/GIMP-Mod
void
session_init (Gimp *gimp)
{
  gchar      *filename;
  GScanner   *scanner;
  GTokenType  token;
  GError     *error = NULL;

  g_return_if_fail (GIMP_IS_GIMP (gimp));

  filename = session_filename (gimp);

  scanner = gimp_scanner_new_file (filename, &error);

  if (! scanner && error->code == GIMP_CONFIG_ERROR_OPEN_ENOENT)
    {
      g_clear_error (&error);
      g_free (filename);

      filename = g_build_filename (gimp_sysconf_directory (),
                                   "sessionrc", NULL);
      scanner = gimp_scanner_new_file (filename, NULL);
    }

  if (! scanner)
    {
      g_clear_error (&error);
      g_free (filename);
      return;
    }

  if (gimp->be_verbose)
    g_print ("Parsing '%s'\n", gimp_filename_to_utf8 (filename));

  g_scanner_scope_add_symbol (scanner, 0, "session-info",
                              GINT_TO_POINTER (SESSION_INFO));
  g_scanner_scope_add_symbol (scanner, 0,  "hide-docks",
                              GINT_TO_POINTER (HIDE_DOCKS));
  g_scanner_scope_add_symbol (scanner, 0,  "single-window-mode",
                              GINT_TO_POINTER (SINGLE_WINDOW_MODE));
  g_scanner_scope_add_symbol (scanner, 0,  "last-tip-shown",
                              GINT_TO_POINTER (LAST_TIP_SHOWN));

  token = G_TOKEN_LEFT_PAREN;

  while (g_scanner_peek_next_token (scanner) == token)
    {
      token = g_scanner_get_next_token (scanner);

      switch (token)
        {
        case G_TOKEN_LEFT_PAREN:
          token = G_TOKEN_SYMBOL;
          break;

        case G_TOKEN_SYMBOL:
          if (scanner->value.v_symbol == GINT_TO_POINTER (SESSION_INFO))
            {
              GimpDialogFactory      *factory      = NULL;
              GimpSessionInfo        *info         = NULL;
              gchar                  *factory_name = NULL;
              gchar                  *entry_name   = NULL;
              GimpDialogFactoryEntry *entry        = NULL;

              token = G_TOKEN_STRING;

              if (! gimp_scanner_parse_string (scanner, &factory_name))
                break;

              /* In versions <= GIMP 2.6 there was a "toolbox", a
               * "dock", a "display" and a "toplevel" factory. These
               * are now merged to a single gimp_dialog_factory_get_singleton (). We
               * need the legacy name though, so keep it around.
               */
              factory = gimp_dialog_factory_get_singleton ();

              info = gimp_session_info_new ();

              /* GIMP 2.6 has the entry name as part of the
               * session-info header, so try to get it
               */
              gimp_scanner_parse_string (scanner, &entry_name);
              if (entry_name)
                {
                  /* Previously, GimpDock was a toplevel. That is why
                   * versions <= GIMP 2.6 has "dock" as the entry name. We
                   * want "dock" to be interpreted as 'dock window'
                   * however so have some special-casing for that. When
                   * the entry name is "dock" the factory name is either
                   * "dock" or "toolbox".
                   */
                  if (strcmp (entry_name, "dock") == 0)
                    {
                      entry =
                        gimp_dialog_factory_find_entry (factory,
                                                        (strcmp (factory_name, "toolbox") == 0 ?
                                                         "gimp-toolbox-window" :
                                                         "gimp-dock-window"));
                    }
                  else
                    {
                      entry = gimp_dialog_factory_find_entry (factory,
                                                              entry_name);
                    }
                }

              /* We're done with these now */
              g_free (factory_name);
              g_free (entry_name);

              /* We can get the factory entry either now (the GIMP <=
               * 2.6 way), or when we deserialize (the GIMP 2.8 way)
               */
              if (entry)
                {
                  gimp_session_info_set_factory_entry (info, entry);
                }

              /* Always try to deserialize */
              if (gimp_config_deserialize (GIMP_CONFIG (info), scanner, 1, NULL))
                {
                  /* Make sure we got a factory entry either the 2.6
                   * or 2.8 way
                   */
                  if (gimp_session_info_get_factory_entry (info))
                    {
                      GIMP_LOG (DIALOG_FACTORY,
                                "successfully parsed and added session info %p",
                                info);

                      gimp_dialog_factory_add_session_info (factory, info);
                    }
                  else
                    {
                      GIMP_LOG (DIALOG_FACTORY,
                                "failed to parse session info %p, not adding",
                                info);
                    }

                  g_object_unref (info);
                }
              else
                {
                  g_object_unref (info);
                  break;
                }
            }
          else if (scanner->value.v_symbol == GINT_TO_POINTER (HIDE_DOCKS))
            {
              gboolean hide_docks;

              token = G_TOKEN_IDENTIFIER;

              if (! gimp_scanner_parse_boolean (scanner, &hide_docks))
                break;

              g_object_set (gimp->config,
                            "hide-docks", hide_docks,
                            NULL);
            }
          else if (scanner->value.v_symbol == GINT_TO_POINTER (SINGLE_WINDOW_MODE))
            {
              gboolean single_window_mode;

              token = G_TOKEN_IDENTIFIER;

              if (! gimp_scanner_parse_boolean (scanner, &single_window_mode))
                break;

              g_object_set (gimp->config,
                            "single-window-mode", single_window_mode,
                            NULL);
            }
          else if (scanner->value.v_symbol == GINT_TO_POINTER (LAST_TIP_SHOWN))
            {
              gint last_tip_shown;

              token = G_TOKEN_INT;

              if (! gimp_scanner_parse_int (scanner, &last_tip_shown))
                break;

              g_object_set (gimp->config,
                            "last-tip-shown", last_tip_shown,
                            NULL);
            }
          token = G_TOKEN_RIGHT_PAREN;
          break;

        case G_TOKEN_RIGHT_PAREN:
          token = G_TOKEN_LEFT_PAREN;
          break;

        default: /* do nothing */
          break;
        }
    }

  if (token != G_TOKEN_LEFT_PAREN)
    {
      g_scanner_get_next_token (scanner);
      g_scanner_unexp_token (scanner, token, NULL, NULL, NULL,
                             _("fatal parse error"), TRUE);
    }

  if (error)
    {
      gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
      g_clear_error (&error);

      gimp_config_file_backup_on_error (filename, "sessionrc", NULL);
    }

  gimp_scanner_destroy (scanner);
  g_free (filename);

  dialogs_load_recent_docks (gimp);
}
예제 #4
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;
}
예제 #5
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
}
예제 #6
0
static gboolean
gimp_session_info_deserialize (GimpConfig *config,
                               GScanner   *scanner,
                               gint        nest_level,
                               gpointer    data)
{
  GimpSessionInfo *info = GIMP_SESSION_INFO (config);
  GTokenType       token;
  guint            scope_id;
  guint            old_scope_id;

  scope_id = g_type_qname (G_TYPE_FROM_INSTANCE (config));
  old_scope_id = g_scanner_set_scope (scanner, scope_id);

  g_scanner_scope_add_symbol (scanner, scope_id, "factory-entry",
                              GINT_TO_POINTER (SESSION_INFO_FACTORY_ENTRY));
  g_scanner_scope_add_symbol (scanner, scope_id, "position",
                              GINT_TO_POINTER (SESSION_INFO_POSITION));
  g_scanner_scope_add_symbol (scanner, scope_id, "size",
                              GINT_TO_POINTER (SESSION_INFO_SIZE));
  g_scanner_scope_add_symbol (scanner, scope_id, "monitor",
                              GINT_TO_POINTER (SESSION_INFO_MONITOR));
  g_scanner_scope_add_symbol (scanner, scope_id, "open-on-exit",
                              GINT_TO_POINTER (SESSION_INFO_OPEN));
  g_scanner_scope_add_symbol (scanner, scope_id, "aux-info",
                              GINT_TO_POINTER (SESSION_INFO_AUX));
  g_scanner_scope_add_symbol (scanner, scope_id, "gimp-dock",
                              GINT_TO_POINTER (SESSION_INFO_GIMP_DOCK));
  g_scanner_scope_add_symbol (scanner, scope_id, "gimp-toolbox",
                              GINT_TO_POINTER (SESSION_INFO_GIMP_TOOLBOX));

  /* For sessionrc files from version <= GIMP 2.6 */
  g_scanner_scope_add_symbol (scanner, scope_id, "dock",
                              GINT_TO_POINTER (SESSION_INFO_DOCK));

  token = G_TOKEN_LEFT_PAREN;

  while (g_scanner_peek_next_token (scanner) == token)
    {
      token = g_scanner_get_next_token (scanner);

      switch (token)
        {
          gint dummy;

        case G_TOKEN_LEFT_PAREN:
          token = G_TOKEN_SYMBOL;
          break;

        case G_TOKEN_SYMBOL:
          switch (GPOINTER_TO_INT (scanner->value.v_symbol))
            {
            case SESSION_INFO_FACTORY_ENTRY:
              {
                gchar                  *identifier = NULL;
                GimpDialogFactoryEntry *entry      = NULL;

                token = G_TOKEN_STRING;
                if (! gimp_scanner_parse_string (scanner, &identifier))
                  goto error;

                entry = gimp_dialog_factory_find_entry (gimp_dialog_factory_get_singleton (),
                                                        identifier);
                if (! entry)
                  goto error;

                gimp_session_info_set_factory_entry (info, entry);

                g_free (identifier);
              }
              break;

            case SESSION_INFO_POSITION:
              token = G_TOKEN_INT;
              if (! gimp_session_info_parse_offset (scanner,
                                                    &info->p->x,
                                                    &info->p->right_align))
                goto error;
              if (! gimp_session_info_parse_offset (scanner,
                                                    &info->p->y,
                                                    &info->p->bottom_align))
                goto error;
              break;

            case SESSION_INFO_SIZE:
              token = G_TOKEN_INT;
              if (! gimp_scanner_parse_int (scanner, &info->p->width))
                goto error;
              if (! gimp_scanner_parse_int (scanner, &info->p->height))
                goto error;
              break;

            case SESSION_INFO_MONITOR:
              token = G_TOKEN_INT;
              if (gimp_scanner_parse_int (scanner, &dummy))
                {
                  info->p->monitor =
                    gdk_display_get_monitor (gdk_display_get_default (), dummy);
                }
              else
                goto error;
              break;

            case SESSION_INFO_OPEN:
              info->p->open = TRUE;

              /*  the screen number is optional, and obsolete  */
              if (g_scanner_peek_next_token (scanner) == G_TOKEN_RIGHT_PAREN)
                break;

              token = G_TOKEN_INT;
              if (! gimp_scanner_parse_int (scanner, &dummy))
                goto error;
              break;

            case SESSION_INFO_AUX:
              token = gimp_session_info_aux_deserialize (scanner,
                                                         &info->p->aux_info);
              if (token != G_TOKEN_LEFT_PAREN)
                goto error;
              break;

            case SESSION_INFO_GIMP_TOOLBOX:
            case SESSION_INFO_GIMP_DOCK:
            case SESSION_INFO_DOCK:
              {
                GimpSessionInfoDock *dock_info  = NULL;
                const gchar         *dock_type = NULL;

                /* Handle old sessionrc:s from versions <= GIMP 2.6 */
                if (GPOINTER_TO_INT (scanner->value.v_symbol) == SESSION_INFO_DOCK &&
                    info->p->factory_entry &&
                    info->p->factory_entry->identifier &&
                    strcmp ("gimp-toolbox-window",
                            info->p->factory_entry->identifier) == 0)
                  {
                    dock_type = "gimp-toolbox";
                  }
                else
                  {
                    dock_type = ((GPOINTER_TO_INT (scanner->value.v_symbol) ==
                                  SESSION_INFO_GIMP_TOOLBOX) ?
                                 "gimp-toolbox" :
                                 "gimp-dock");
                  }

                g_scanner_set_scope (scanner, scope_id + 1);
                token = gimp_session_info_dock_deserialize (scanner, scope_id + 1,
                                                            &dock_info,
                                                            dock_type);

                if (token == G_TOKEN_LEFT_PAREN)
                  {
                    g_scanner_set_scope (scanner, scope_id);
                    info->p->docks = g_list_append (info->p->docks, dock_info);
                  }
                else
                  goto error;
              }
              break;

            default:
              break;
            }
          token = G_TOKEN_RIGHT_PAREN;
          break;

        case G_TOKEN_RIGHT_PAREN:
          token = G_TOKEN_LEFT_PAREN;
          break;

        default:
          break;
        }
    }

 error:

  /* If we don't have docks, assume it is a toolbox dock window from a
   * sessionrc file from GIMP <= 2.6 and add a toolbox dock manually
   */
  if (! info->p->docks &&
      info->p->factory_entry &&
      strcmp ("gimp-toolbox-window",
              info->p->factory_entry->identifier) == 0)
    {
      info->p->docks =
        g_list_append (info->p->docks,
                       gimp_session_info_dock_new ("gimp-toolbox"));
    }

  g_scanner_scope_remove_symbol (scanner, scope_id, "factory-entry");
  g_scanner_scope_remove_symbol (scanner, scope_id, "position");
  g_scanner_scope_remove_symbol (scanner, scope_id, "size");
  g_scanner_scope_remove_symbol (scanner, scope_id, "open-on-exit");
  g_scanner_scope_remove_symbol (scanner, scope_id, "aux-info");
  g_scanner_scope_remove_symbol (scanner, scope_id, "gimp-dock");
  g_scanner_scope_remove_symbol (scanner, scope_id, "gimp-toolbox");
  g_scanner_scope_remove_symbol (scanner, scope_id, "dock");

  g_scanner_set_scope (scanner, old_scope_id);

  return gimp_config_deserialize_return (scanner, token, nest_level);
}