[gnome-control-center] color: Allow uploading to the Internet when using a LiveCD



commit 829f703af667bd8d1c8c22780c8ef32c46671171
Author: Richard Hughes <richard hughsie com>
Date:   Thu Apr 18 15:19:50 2013 +0100

    color: Allow uploading to the Internet when using a LiveCD
    
    If the user is calibrating on a LiveCD the final finished profile is written to
    disk. This somehow needs to be transfered to the main system before it will work.
    
    Two button are now provided, one to save the profile to disk, and one to upload
    the profile to the Internet.

 configure.ac                  |   3 +-
 panels/color/cc-color-panel.c | 118 +++++++++++++++++++++++++++
 panels/color/color.ui         | 186 ++++++++++++++++++++++++++++++++++++------
 3 files changed, 281 insertions(+), 26 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 94e5c7c..37fd471 100644
--- a/configure.ac
+++ b/configure.ac
@@ -109,7 +109,7 @@ LIBWACOM_REQUIRED_VERSION=0.7
 CLUTTER_REQUIRED_VERSION=1.11.3
 GOA_REQUIRED_VERSION=3.8.1
 ACCOUNTSSERVICE_REQUIRED_VERSION=0.6.30
-COLORD_REQUIRED_VERSION=0.1.29
+COLORD_REQUIRED_VERSION=0.1.34
 COLORD_GTK_REQUIRED_VERSION=0.1.24
 
 COMMON_MODULES="gtk+-3.0 >= $GTK_REQUIRED_VERSION
@@ -149,6 +149,7 @@ PKG_CHECK_MODULES(POWER_PANEL, $COMMON_MODULES upower-glib >= 0.9.1
 PKG_CHECK_MODULES(COLOR_PANEL, $COMMON_MODULES
                   colord >= $COLORD_REQUIRED_VERSION
                   colord-gtk >= $COLORD_GTK_REQUIRED_VERSION
+                  libsoup-2.4
                   gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
 PKG_CHECK_MODULES(PRINTERS_PANEL, $COMMON_MODULES
                   polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION)
diff --git a/panels/color/cc-color-panel.c b/panels/color/cc-color-panel.c
index 37ac5a3..8990dbb 100644
--- a/panels/color/cc-color-panel.c
+++ b/panels/color/cc-color-panel.c
@@ -26,6 +26,7 @@
 #include <colord.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
+#include <libsoup/soup.h>
 
 #include "cc-color-calibrate.h"
 #include "cc-color-cell-renderer-text.h"
@@ -50,6 +51,7 @@ struct _CcColorPanelPrivate
   GCancellable  *cancellable;
   GDBusProxy    *proxy;
   GSettings     *settings;
+  GSettings     *settings_colord;
   GtkBuilder    *builder;
   GtkWidget     *main_window;
   CcColorCalibrate *calibrate;
@@ -93,6 +95,7 @@ enum {
   COLUMN_CALIB_TEMP_LAST
 };
 
+#define COLORD_SETTINGS_SCHEMA                          "org.freedesktop.ColorHelper"
 #define GCM_SETTINGS_SCHEMA                             "org.gnome.settings-daemon.plugins.color"
 #define GCM_SETTINGS_RECALIBRATE_PRINTER_THRESHOLD      "recalibrate-printer-threshold"
 #define GCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD      "recalibrate-display-threshold"
@@ -302,6 +305,9 @@ gcm_prefs_calib_apply_cb (GtkWidget *widget, CcColorPanel *prefs)
   GtkWindow *window = NULL;
 
   /* setup the calibration object with items that can fail */
+  widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
+                                               "button_calib_upload"));
+  gtk_widget_show (widget);
   ret = cc_color_calibrate_setup (prefs->priv->calibrate,
                                   &error);
   if (!ret)
@@ -839,6 +845,112 @@ out:
 }
 
 static void
+gcm_prefs_calib_upload_cb (GtkWidget *widget, CcColorPanel *prefs)
+{
+  CcColorPanelPrivate *priv = prefs->priv;
+  CdProfile *profile;
+  const gchar *uri;
+  gboolean ret;
+  gchar *upload_uri = NULL;
+  gchar *msg_result = NULL;
+  gchar *data = NULL;
+  GError *error = NULL;
+  gsize length;
+  guint status_code;
+  SoupBuffer *buffer = NULL;
+  SoupMessage *msg = NULL;
+  SoupMultipart *multipart = NULL;
+  SoupSession *session = NULL;
+
+  profile = cc_color_calibrate_get_profile (prefs->priv->calibrate);
+  ret = cd_profile_connect_sync (profile, NULL, &error);
+  if (!ret)
+    {
+      g_warning ("Failed to get imported profile: %s", error->message);
+      g_error_free (error);
+      goto out;
+    }
+
+  /* read file */
+  ret = g_file_get_contents (cd_profile_get_filename (profile),
+                             &data,
+                             &length,
+                             &error);
+  if (!ret)
+    {
+      g_warning ("Failed to read file: %s", error->message);
+      g_error_free (error);
+      goto out;
+    }
+
+  /* setup the session */
+  session = soup_session_sync_new_with_options (SOUP_SESSION_USER_AGENT, "gnome-control-center",
+                                                SOUP_SESSION_TIMEOUT, 5000,
+                                                NULL);
+  if (session == NULL)
+  {
+    g_warning ("Failed to setup networking");
+    goto out;
+  }
+  soup_session_add_feature_by_type (session, SOUP_TYPE_PROXY_RESOLVER_DEFAULT);
+
+  /* create multipart form and upload file */
+  multipart = soup_multipart_new (SOUP_FORM_MIME_TYPE_MULTIPART);
+  buffer = soup_buffer_new (SOUP_MEMORY_STATIC, data, length);
+  soup_multipart_append_form_file (multipart,
+                                   "upload",
+                                   cd_profile_get_filename (profile),
+                                   NULL,
+                                   buffer);
+  upload_uri = g_settings_get_string (priv->settings_colord, "profile-upload-uri");
+  msg = soup_form_request_new_from_multipart (upload_uri, multipart);
+  status_code = soup_session_send_message (session, msg);
+  if (status_code != 201)
+    {
+      widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
+                                                   "label_calib_upload_location"));
+      /* TRANSLATORS: this is when the upload of the profile failed */
+      msg_result = g_strdup_printf (_("Failed to upload file: %s"), msg->reason_phrase),
+      gtk_label_set_label (GTK_LABEL (widget), msg_result);
+      gtk_widget_show (widget);
+      goto out;
+    }
+
+  /* show instructions to the user */
+  widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
+                                               "label_calib_upload_location"));
+  uri = soup_message_headers_get_one (msg->response_headers, "Location");
+  msg_result = g_strdup_printf ("%s %s\n\n• %s\n• %s\n• %s",
+                                /* TRANSLATORS: these are instructions on how to recover
+                                 * the ICC profile on the native operating system and are
+                                 * only shown when the user uses a LiveCD to calibrate */
+                                _("The profile has been uploaded to:"),
+                                uri,
+                                _("Write down this URL."),
+                                _("Restart this computer and boot your normal operating system."),
+                                _("Type the URL into your browser to download and install the profile.")),
+  gtk_label_set_label (GTK_LABEL (widget), msg_result);
+  gtk_widget_show (widget);
+
+  /* hide the upload button as duplicate uploads will fail */
+  widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
+                                               "button_calib_upload"));
+  gtk_widget_hide (widget);
+out:
+  if (session != NULL)
+    g_object_unref (session);
+  if (buffer != NULL)
+    soup_buffer_free (buffer);
+  if (msg != NULL)
+    g_object_unref (msg);
+  if (multipart != NULL)
+    soup_multipart_free (multipart);
+  g_free (data);
+  g_free (upload_uri);
+  g_free (msg_result);
+}
+
+static void
 gcm_prefs_calib_export_cb (GtkWidget *widget, CcColorPanel *prefs)
 {
   CdProfile *profile;
@@ -2013,6 +2125,7 @@ cc_color_panel_dispose (GObject *object)
   if (priv->cancellable != NULL)
     g_cancellable_cancel (priv->cancellable);
   g_clear_object (&priv->settings);
+  g_clear_object (&priv->settings_colord);
   g_clear_object (&priv->cancellable);
   g_clear_object (&priv->builder);
   g_clear_object (&priv->client);
@@ -2155,6 +2268,7 @@ cc_color_panel_init (CcColorPanel *prefs)
 
   /* setup defaults */
   priv->settings = g_settings_new (GCM_SETTINGS_SCHEMA);
+  priv->settings_colord = g_settings_new (COLORD_SETTINGS_SCHEMA);
 
   /* assign buttons */
   widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
@@ -2427,6 +2541,10 @@ cc_color_panel_init (CcColorPanel *prefs)
   g_signal_connect (widget, "clicked",
                     G_CALLBACK (gcm_prefs_calib_export_cb), prefs);
   widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
+                                               "button_calib_upload"));
+  g_signal_connect (widget, "clicked",
+                    G_CALLBACK (gcm_prefs_calib_upload_cb), prefs);
+  widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
                                                "label_calib_summary_message"));
   g_signal_connect (widget, "activate-link",
                     G_CALLBACK (gcm_prefs_calib_export_link_cb), prefs);
diff --git a/panels/color/color.ui b/panels/color/color.ui
index 63060d6..d561b9e 100644
--- a/panels/color/color.ui
+++ b/panels/color/color.ui
@@ -399,54 +399,190 @@
           </packing>
         </child>
         <child>
-          <object class="GtkButton" id="button_calib_export">
+          <object class="GtkBox" id="box2">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
+            <property name="can_focus">False</property>
             <property name="halign">center</property>
+            <property name="spacing">6</property>
             <child>
-              <object class="GtkBox" id="box3">
+              <object class="GtkButton" id="button_calib_export">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="border_width">24</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">9</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">start</property>
                 <child>
-                  <object class="GtkImage" id="image2">
+                  <object class="GtkBox" id="box3">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="pixel_size">48</property>
-                    <property name="icon_name">folder-symbolic</property>
+                    <property name="border_width">6</property>
+                    <property name="spacing">9</property>
+                    <child>
+                      <object class="GtkImage" id="image2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="pixel_size">48</property>
+                        <property name="icon_name">folder-symbolic</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkBox" id="box6">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">3</property>
+                        <child>
+                          <object class="GtkLabel" id="label1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Copy profile</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label2">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Requires writable media</property>
+                            <attributes>
+                              <attribute name="style" value="italic"/>
+                            </attributes>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button_calib_upload">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">start</property>
                 <child>
-                  <object class="GtkLabel" id="label1">
+                  <object class="GtkBox" id="box4">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Export</property>
+                    <property name="border_width">6</property>
+                    <property name="spacing">9</property>
+                    <child>
+                      <object class="GtkImage" id="image3">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="pixel_size">48</property>
+                        <property name="icon_name">preferences-system-sharing-symbolic</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkBox" id="box5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">3</property>
+                        <child>
+                          <object class="GtkLabel" id="label3">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Upload profile</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label4">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Requires Internet connection</property>
+                            <attributes>
+                              <attribute name="style" value="italic"/>
+                            </attributes>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="padding">12</property>
+                <property name="position">1</property>
+              </packing>
             </child>
           </object>
           <packing>
             <property name="expand">False</property>
             <property name="fill">False</property>
-            <property name="padding">24</property>
+            <property name="padding">12</property>
             <property name="position">1</property>
           </packing>
         </child>
         <child>
+          <object class="GtkLabel" id="label_calib_upload_location">
+            <property name="can_focus">False</property>
+            <property name="xalign">0</property>
+            <property name="xpad">6</property>
+            <property name="label">The profile has been uploaded to http://foo.bar/deadbeef.icc</property>
+            <property name="selectable">True</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
           <object class="GtkLabel" id="label_calib_summary_message">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
@@ -462,7 +598,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
-            <property name="position">2</property>
+            <property name="position">3</property>
           </packing>
         </child>
       </object>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]