/* PIKA - Photo and Image Kooker Application * a rebranding of The GNU Image Manipulation Program (created with heckimp) * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio * * Original copyright, applying to most contents (license remains unchanged): * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * pikasessioninfo-dockable.c * Copyright (C) 2001-2007 Michael Natterer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "config.h" #include #include "libpikaconfig/pikaconfig.h" #include "widgets-types.h" #include "pikacontainerview-utils.h" #include "pikacontainerview.h" #include "pikadialogfactory.h" #include "pikadock.h" #include "pikadockable.h" #include "pikasessioninfo-aux.h" #include "pikasessioninfo-dockable.h" #include "pikasessionmanaged.h" #include "pikatoolbox.h" enum { SESSION_INFO_DOCKABLE_LOCKED, SESSION_INFO_DOCKABLE_TAB_STYLE, SESSION_INFO_DOCKABLE_VIEW_SIZE, SESSION_INFO_DOCKABLE_AUX }; /* public functions */ PikaSessionInfoDockable * pika_session_info_dockable_new (void) { return g_slice_new0 (PikaSessionInfoDockable); } void pika_session_info_dockable_free (PikaSessionInfoDockable *info) { g_return_if_fail (info != NULL); g_clear_pointer (&info->identifier, g_free); if (info->aux_info) { g_list_free_full (info->aux_info, (GDestroyNotify) pika_session_info_aux_free); info->aux_info = NULL; } g_slice_free (PikaSessionInfoDockable, info); } void pika_session_info_dockable_serialize (PikaConfigWriter *writer, PikaSessionInfoDockable *info) { GEnumClass *enum_class; GEnumValue *enum_value; const gchar *tab_style = "icon"; g_return_if_fail (writer != NULL); g_return_if_fail (info != NULL); enum_class = g_type_class_ref (PIKA_TYPE_TAB_STYLE); pika_config_writer_open (writer, "dockable"); pika_config_writer_string (writer, info->identifier); if (info->locked) { pika_config_writer_open (writer, "locked"); pika_config_writer_close (writer); } enum_value = g_enum_get_value (enum_class, info->tab_style); if (enum_value) tab_style = enum_value->value_nick; pika_config_writer_open (writer, "tab-style"); pika_config_writer_print (writer, tab_style, -1); pika_config_writer_close (writer); if (info->view_size > 0) { pika_config_writer_open (writer, "preview-size"); pika_config_writer_printf (writer, "%d", info->view_size); pika_config_writer_close (writer); } if (info->aux_info) pika_session_info_aux_serialize (writer, info->aux_info); pika_config_writer_close (writer); g_type_class_unref (enum_class); } GTokenType pika_session_info_dockable_deserialize (GScanner *scanner, gint scope, PikaSessionInfoDockable **dockable) { PikaSessionInfoDockable *info; GEnumClass *enum_class; GEnumValue *enum_value; GTokenType token; g_return_val_if_fail (scanner != NULL, G_TOKEN_LEFT_PAREN); g_return_val_if_fail (dockable != NULL, G_TOKEN_LEFT_PAREN); g_scanner_scope_add_symbol (scanner, scope, "locked", GINT_TO_POINTER (SESSION_INFO_DOCKABLE_LOCKED)); g_scanner_scope_add_symbol (scanner, scope, "tab-style", GINT_TO_POINTER (SESSION_INFO_DOCKABLE_TAB_STYLE)); g_scanner_scope_add_symbol (scanner, scope, "preview-size", GINT_TO_POINTER (SESSION_INFO_DOCKABLE_VIEW_SIZE)); g_scanner_scope_add_symbol (scanner, scope, "aux-info", GINT_TO_POINTER (SESSION_INFO_DOCKABLE_AUX)); info = pika_session_info_dockable_new (); enum_class = g_type_class_ref (PIKA_TYPE_TAB_STYLE); token = G_TOKEN_STRING; if (! pika_scanner_parse_string (scanner, &info->identifier)) goto error; 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: switch (GPOINTER_TO_INT (scanner->value.v_symbol)) { case SESSION_INFO_DOCKABLE_LOCKED: info->locked = TRUE; break; case SESSION_INFO_DOCKABLE_TAB_STYLE: token = G_TOKEN_IDENTIFIER; if (g_scanner_peek_next_token (scanner) != token) goto error; g_scanner_get_next_token (scanner); enum_value = g_enum_get_value_by_nick (enum_class, scanner->value.v_identifier); if (! enum_value) enum_value = g_enum_get_value_by_name (enum_class, scanner->value.v_identifier); if (enum_value) info->tab_style = enum_value->value; break; case SESSION_INFO_DOCKABLE_VIEW_SIZE: token = G_TOKEN_INT; if (! pika_scanner_parse_int (scanner, &info->view_size)) goto error; break; case SESSION_INFO_DOCKABLE_AUX: token = pika_session_info_aux_deserialize (scanner, &info->aux_info); if (token != G_TOKEN_LEFT_PAREN) goto error; break; default: goto error; } token = G_TOKEN_RIGHT_PAREN; break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: break; } } *dockable = info; g_type_class_unref (enum_class); g_scanner_scope_remove_symbol (scanner, scope, "locked"); g_scanner_scope_remove_symbol (scanner, scope, "tab-style"); g_scanner_scope_remove_symbol (scanner, scope, "preview-size"); g_scanner_scope_remove_symbol (scanner, scope, "aux-info"); return token; error: *dockable = NULL; pika_session_info_dockable_free (info); g_type_class_unref (enum_class); return token; } PikaSessionInfoDockable * pika_session_info_dockable_from_widget (PikaDockable *dockable) { PikaSessionInfoDockable *info; PikaDialogFactoryEntry *entry; PikaContainerView *view; gint view_size = -1; g_return_val_if_fail (PIKA_IS_DOCKABLE (dockable), NULL); pika_dialog_factory_from_widget (GTK_WIDGET (dockable), &entry); g_return_val_if_fail (entry != NULL, NULL); info = pika_session_info_dockable_new (); info->locked = pika_dockable_get_locked (dockable); info->identifier = g_strdup (entry->identifier); info->tab_style = pika_dockable_get_tab_style (dockable); info->view_size = -1; view = pika_container_view_get_by_dockable (dockable); if (view) view_size = pika_container_view_get_view_size (view, NULL); if (view_size > 0 && view_size != entry->view_size) info->view_size = view_size; if (PIKA_IS_SESSION_MANAGED (dockable)) info->aux_info = pika_session_managed_get_aux_info (PIKA_SESSION_MANAGED (dockable)); return info; } PikaDockable * pika_session_info_dockable_restore (PikaSessionInfoDockable *info, PikaDock *dock) { GtkWidget *dockable; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (PIKA_IS_DOCK (dock), NULL); if (info->view_size < PIKA_VIEW_SIZE_TINY || info->view_size > PIKA_VIEW_SIZE_GIGANTIC) info->view_size = -1; dockable = pika_dialog_factory_dockable_new (pika_dock_get_dialog_factory (dock), dock, info->identifier, info->view_size); if (dockable) { /* pika_dialog_factory_dockable_new() might return an already * existing singleton dockable, return NULL so our caller won't * try to add it to another dockbook */ if (pika_dockable_get_dockbook (PIKA_DOCKABLE (dockable))) return NULL; pika_dockable_set_locked (PIKA_DOCKABLE (dockable), info->locked); pika_dockable_set_tab_style (PIKA_DOCKABLE (dockable), info->tab_style); if (info->aux_info) pika_session_managed_set_aux_info (PIKA_SESSION_MANAGED (dockable), info->aux_info); } return PIKA_DOCKABLE (dockable); }