diff options
Diffstat (limited to 'panels/background/cc-background-panel.c')
-rw-r--r-- | panels/background/cc-background-panel.c | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/panels/background/cc-background-panel.c b/panels/background/cc-background-panel.c new file mode 100644 index 0000000..29dedf1 --- /dev/null +++ b/panels/background/cc-background-panel.c @@ -0,0 +1,314 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + * + * Author: Thomas Wood <thomas.wood@intel.com> + * + */ + +#include <config.h> + +#include <string.h> +#include <glib.h> +#include <glib/gi18n-lib.h> +#include <glib/gstdio.h> + +#include <gdesktop-enums.h> + +#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); +} |