/* * Copyright (C) 2010 Intel, Inc * * 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 2 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 . * * Author: Thomas Wood * */ #include #include #include #include #include #include #include "cc-background-panel.h" #include "cc-background-chooser.h" #include "cc-background-item.h" #include "cc-background-preview.h" #include "cc-background-resources.h" #include "cc-background-xml.h" #include "bg-pictures-source.h" #define WP_PATH_ID "org.gnome.desktop.background" #define WP_LOCK_PATH_ID "org.gnome.desktop.screensaver" #define WP_URI_KEY "picture-uri" #define WP_OPTIONS_KEY "picture-options" #define WP_SHADING_KEY "color-shading-type" #define WP_PCOLOR_KEY "primary-color" #define WP_SCOLOR_KEY "secondary-color" struct _CcBackgroundPanel { CcPanel parent_instance; GDBusConnection *connection; GSettings *settings; GSettings *lock_settings; GnomeDesktopThumbnailFactory *thumb_factory; CcBackgroundItem *current_background; CcBackgroundChooser *background_chooser; GtkButton *add_picture_button; CcBackgroundPreview *desktop_preview; }; CC_PANEL_REGISTER (CcBackgroundPanel, cc_background_panel) static void update_preview (CcBackgroundPanel *panel) { CcBackgroundItem *current_background; current_background = panel->current_background; cc_background_preview_set_item (panel->desktop_preview, current_background); } static gchar * get_save_path (void) { return g_build_filename (g_get_user_config_dir (), "gnome-control-center", "backgrounds", "last-edited.xml", NULL); } static void reload_current_bg (CcBackgroundPanel *panel) { g_autoptr(CcBackgroundItem) saved = NULL; CcBackgroundItem *configured; GSettings *settings = NULL; g_autofree gchar *uri = NULL; g_autofree gchar *pcolor = NULL; g_autofree gchar *scolor = NULL; /* Load the saved configuration */ uri = get_save_path (); saved = cc_background_xml_get_item (uri); /* initalise the current background information from settings */ settings = panel->settings; uri = g_settings_get_string (settings, WP_URI_KEY); if (uri && *uri == '\0') g_clear_pointer (&uri, g_free); configured = cc_background_item_new (uri); pcolor = g_settings_get_string (settings, WP_PCOLOR_KEY); scolor = g_settings_get_string (settings, WP_SCOLOR_KEY); g_object_set (G_OBJECT (configured), "name", _("Current background"), "placement", g_settings_get_enum (settings, WP_OPTIONS_KEY), "shading", g_settings_get_enum (settings, WP_SHADING_KEY), "primary-color", pcolor, "secondary-color", scolor, NULL); if (saved != NULL && cc_background_item_compare (saved, configured)) { CcBackgroundItemFlags flags; flags = cc_background_item_get_flags (saved); /* Special case for colours */ if (cc_background_item_get_placement (saved) == G_DESKTOP_BACKGROUND_STYLE_NONE) flags &=~ (CC_BACKGROUND_ITEM_HAS_PCOLOR | CC_BACKGROUND_ITEM_HAS_SCOLOR); g_object_set (G_OBJECT (configured), "name", cc_background_item_get_name (saved), "flags", flags, "source-url", cc_background_item_get_source_url (saved), "source-xml", cc_background_item_get_source_xml (saved), NULL); } g_clear_object (&panel->current_background); panel->current_background = configured; cc_background_item_load (configured, NULL); } static gboolean create_save_dir (void) { g_autofree char *path = NULL; path = g_build_filename (g_get_user_config_dir (), "gnome-control-center", "backgrounds", NULL); if (g_mkdir_with_parents (path, USER_DIR_MODE) < 0) { g_warning ("Failed to create directory '%s'", path); return FALSE; } return TRUE; } static void set_background (CcBackgroundPanel *panel, GSettings *settings, CcBackgroundItem *item) { GDesktopBackgroundStyle style; CcBackgroundItemFlags flags; g_autofree gchar *filename = NULL; const char *uri; if (item == NULL) return; uri = cc_background_item_get_uri (item); flags = cc_background_item_get_flags (item); g_settings_set_string (settings, WP_URI_KEY, uri); /* Also set the placement if we have a URI and the previous value was none */ if (flags & CC_BACKGROUND_ITEM_HAS_PLACEMENT) { g_settings_set_enum (settings, WP_OPTIONS_KEY, cc_background_item_get_placement (item)); } else if (uri != NULL) { style = g_settings_get_enum (settings, WP_OPTIONS_KEY); if (style == G_DESKTOP_BACKGROUND_STYLE_NONE) g_settings_set_enum (settings, WP_OPTIONS_KEY, cc_background_item_get_placement (item)); } if (flags & CC_BACKGROUND_ITEM_HAS_SHADING) g_settings_set_enum (settings, WP_SHADING_KEY, cc_background_item_get_shading (item)); g_settings_set_string (settings, WP_PCOLOR_KEY, cc_background_item_get_pcolor (item)); g_settings_set_string (settings, WP_SCOLOR_KEY, cc_background_item_get_scolor (item)); /* Apply all changes */ g_settings_apply (settings); /* Save the source XML if there is one */ filename = get_save_path (); if (create_save_dir ()) cc_background_xml_save (panel->current_background, filename); } static void on_chooser_background_chosen_cb (CcBackgroundPanel *self, CcBackgroundItem *item) { set_background (self, self->settings, item); set_background (self, self->lock_settings, item); } static void on_add_picture_button_clicked_cb (CcBackgroundPanel *self) { cc_background_chooser_select_file (self->background_chooser); } static const char * cc_background_panel_get_help_uri (CcPanel *panel) { return "help:gnome-help/look-background"; } static void cc_background_panel_constructed (GObject *object) { CcBackgroundPanel *self; CcShell *shell; self = CC_BACKGROUND_PANEL (object); shell = cc_panel_get_shell (CC_PANEL (self)); cc_shell_embed_widget_in_header (shell, GTK_WIDGET (self->add_picture_button), GTK_POS_RIGHT); G_OBJECT_CLASS (cc_background_panel_parent_class)->constructed (object); } static void cc_background_panel_dispose (GObject *object) { CcBackgroundPanel *panel = CC_BACKGROUND_PANEL (object); g_clear_object (&panel->settings); g_clear_object (&panel->lock_settings); g_clear_object (&panel->thumb_factory); G_OBJECT_CLASS (cc_background_panel_parent_class)->dispose (object); } static void cc_background_panel_finalize (GObject *object) { CcBackgroundPanel *panel = CC_BACKGROUND_PANEL (object); g_clear_object (&panel->current_background); G_OBJECT_CLASS (cc_background_panel_parent_class)->finalize (object); } static void cc_background_panel_class_init (CcBackgroundPanelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); CcPanelClass *panel_class = CC_PANEL_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); g_type_ensure (CC_TYPE_BACKGROUND_CHOOSER); g_type_ensure (CC_TYPE_BACKGROUND_PREVIEW); panel_class->get_help_uri = cc_background_panel_get_help_uri; object_class->constructed = cc_background_panel_constructed; object_class->dispose = cc_background_panel_dispose; object_class->finalize = cc_background_panel_finalize; gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/background/cc-background-panel.ui"); gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, add_picture_button); gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, background_chooser); gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, desktop_preview); gtk_widget_class_bind_template_callback (widget_class, on_chooser_background_chosen_cb); gtk_widget_class_bind_template_callback (widget_class, on_add_picture_button_clicked_cb); } static void on_settings_changed (CcBackgroundPanel *panel) { reload_current_bg (panel); update_preview (panel); } static void cc_background_panel_init (CcBackgroundPanel *panel) { g_resources_register (cc_background_get_resource ()); gtk_widget_init_template (GTK_WIDGET (panel)); panel->connection = g_application_get_dbus_connection (g_application_get_default ()); panel->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE); panel->settings = g_settings_new (WP_PATH_ID); g_settings_delay (panel->settings); panel->lock_settings = g_settings_new (WP_LOCK_PATH_ID); g_settings_delay (panel->lock_settings); /* Load the background */ reload_current_bg (panel); update_preview (panel); /* Background settings */ g_signal_connect_object (panel->settings, "changed", G_CALLBACK (on_settings_changed), panel, G_CONNECT_SWAPPED); }