[gnome-control-center] printers: Add authentication dialog for samba printers



commit 8f2d51cb5e191603dcac16e07f7ec8cd0c3c7a9d
Author: Marek Kasik <mkasik redhat com>
Date:   Fri Feb 15 17:45:15 2013 +0100

    printers: Add authentication dialog for samba printers
    
    Add new class PpAuthenticationDialog which shows dialog
    requesting username and password. The dialog has 3 parameters.
    The first one is a text which will be shown to the user and
    the second is username by which username entry will be prefilled.
    The last parameter is parent window so thedialog is properly
    decorated and positioned.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=683229

 panels/printers/Makefile.am                |    2 +
 panels/printers/authentication-dialog.ui   |  213 ++++++++++++++++++++
 panels/printers/pp-authentication-dialog.c |  298 ++++++++++++++++++++++++++++
 panels/printers/pp-authentication-dialog.h |   62 ++++++
 panels/printers/printers.gresource.xml     |    1 +
 5 files changed, 576 insertions(+), 0 deletions(-)
---
diff --git a/panels/printers/Makefile.am b/panels/printers/Makefile.am
index 173d958..b276546 100644
--- a/panels/printers/Makefile.am
+++ b/panels/printers/Makefile.am
@@ -37,6 +37,8 @@ libprinters_la_SOURCES =              \
        pp-options-dialog.h             \
        pp-jobs-dialog.c                \
        pp-jobs-dialog.h                \
+       pp-authentication-dialog.c      \
+       pp-authentication-dialog.h      \
        cc-printers-panel.c             \
        cc-printers-panel.h
 
diff --git a/panels/printers/authentication-dialog.ui b/panels/printers/authentication-dialog.ui
new file mode 100644
index 0000000..3394aaf
--- /dev/null
+++ b/panels/printers/authentication-dialog.ui
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkDialog" id="authentication-dialog">
+    <property name="width_request">430</property>
+    <property name="height_request">270</property>
+    <property name="can_focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes"> </property>
+    <property name="resizable">False</property>
+    <property name="modal">True</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="main-vbox">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">10</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action-area1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button1">
+                <property name="label" translatable="yes">Cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="authentication-button">
+                <property name="label" translatable="yes">Authenticate</property>
+                <property name="visible">True</property>
+                <property name="sensitive">False</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+              </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">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkAlignment" id="content-alignment">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="hexpand">True</property>
+            <child>
+              <object class="GtkGrid" id="grid1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_left">5</property>
+                <property name="margin_right">5</property>
+                <property name="row_spacing">5</property>
+                <property name="column_spacing">15</property>
+                <child>
+                  <object class="GtkLabel" id="username-label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">end</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Username</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="password-label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">end</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Password</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">3</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="username-entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="hexpand">True</property>
+                    <property name="invisible_char">●</property>
+                    <property name="activates_default">True</property>
+                    <property name="invisible_char_set">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="password-entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="hexpand">True</property>
+                    <property name="visibility">False</property>
+                    <property name="invisible_char">●</property>
+                    <property name="activates_default">True</property>
+                    <property name="invisible_char_set">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">3</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="authentication-title">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="hexpand">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Authentication Required</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage" id="image1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">end</property>
+                    <property name="xalign">1</property>
+                    <property name="yalign">0</property>
+                    <property name="pixel_size">48</property>
+                    <property name="icon_name">dialog-password-symbolic</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="authentication-text">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_bottom">15</property>
+                    <property name="hexpand">True</property>
+                    <property name="xalign">0</property>
+                    <property name="wrap">True</property>
+                    <property name="max_width_chars">36</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">button1</action-widget>
+      <action-widget response="-5">authentication-button</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/panels/printers/pp-authentication-dialog.c b/panels/printers/pp-authentication-dialog.c
new file mode 100644
index 0000000..2e6d33e
--- /dev/null
+++ b/panels/printers/pp-authentication-dialog.c
@@ -0,0 +1,298 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2012 - 2013 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Author: Marek Kasik <mkasik redhat com>
+ */
+
+#include "pp-authentication-dialog.h"
+
+struct _PpAuthenticationDialogPrivate
+{
+  GtkBuilder *builder;
+  GtkWidget  *dialog;
+
+  gchar *text;
+  gchar *username;
+};
+
+#define PP_AUTHENTICATION_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), 
PP_TYPE_AUTHENTICATION_DIALOG, PpAuthenticationDialogPrivate))
+
+#define WID(s) GTK_WIDGET (gtk_builder_get_object (priv->builder, s))
+
+static void pp_authentication_dialog_finalize     (GObject      *object);
+static void pp_authentication_dialog_get_property (GObject      *object,
+                                                   guint         prop_id,
+                                                   GValue       *value,
+                                                   GParamSpec   *param_spec);
+static void pp_authentication_dialog_set_property (GObject      *object,
+                                                   guint         prop_id,
+                                                   const GValue *value,
+                                                   GParamSpec   *param_spec);
+
+enum
+{
+  RESPONSE,
+  LAST_SIGNAL
+};
+
+enum
+{
+  PROP_0 = 0,
+  PROP_TEXT,
+  PROP_USERNAME,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (PpAuthenticationDialog, pp_authentication_dialog, G_TYPE_OBJECT)
+
+static void
+pp_authentication_dialog_class_init (PpAuthenticationDialogClass *klass)
+{
+  GObjectClass *object_class;
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->finalize = pp_authentication_dialog_finalize;
+  object_class->set_property = pp_authentication_dialog_set_property;
+  object_class->get_property = pp_authentication_dialog_get_property;
+
+  g_type_class_add_private (object_class, sizeof (PpAuthenticationDialogPrivate));
+
+  g_object_class_install_property (object_class, PROP_TEXT,
+    g_param_spec_string ("text",
+                         "Text",
+                         "Text of the dialog",
+                         NULL,
+                         G_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_USERNAME,
+    g_param_spec_string ("username",
+                         "Username",
+                         "Initial username",
+                         NULL,
+                         G_PARAM_READWRITE));
+
+  /**
+   * PpAuthenticationDialog::response:
+   *
+   * The signal which gets emitted after user enters authentication informations.
+   */
+  signals[RESPONSE] =
+    g_signal_new ("response",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (PpAuthenticationDialogClass, response),
+                  NULL, NULL,
+                  g_cclosure_marshal_generic,
+                  G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+}
+
+static void
+pp_authentication_dialog_get_property (GObject    *object,
+                                       guint       prop_id,
+                                       GValue     *value,
+                                       GParamSpec *param_spec)
+{
+  PpAuthenticationDialog        *dialog = PP_AUTHENTICATION_DIALOG (object);
+  PpAuthenticationDialogPrivate *priv = dialog->priv;
+
+  switch (prop_id)
+    {
+      case PROP_TEXT:
+        g_value_set_string (value, priv->text);
+        break;
+      case PROP_USERNAME:
+        g_value_set_string (value, priv->username);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+                                           prop_id,
+                                           param_spec);
+      break;
+    }
+}
+
+static void
+pp_authentication_dialog_set_property (GObject      *object,
+                                       guint         prop_id,
+                                       const GValue *value,
+                                       GParamSpec   *param_spec)
+{
+  PpAuthenticationDialog        *dialog = PP_AUTHENTICATION_DIALOG (object);
+  PpAuthenticationDialogPrivate *priv = dialog->priv;
+
+  switch (prop_id)
+    {
+      case PROP_TEXT:
+        g_free (priv->text);
+        priv->text = g_value_dup_string (value);
+        if (priv->text)
+          {
+            gtk_label_set_text (GTK_LABEL (WID ("authentication-text")),
+                                priv->text);
+          }
+        break;
+      case PROP_USERNAME:
+        g_free (priv->username);
+        priv->username = g_value_dup_string (value);
+        if (priv->username)
+          {
+            gtk_entry_set_text (GTK_ENTRY (WID ("username-entry")),
+                                priv->username);
+          }
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+                                           prop_id,
+                                           param_spec);
+        break;
+    }
+}
+
+PpAuthenticationDialog *
+pp_authentication_dialog_new (GtkWindow   *parent,
+                              const gchar *text,
+                              const gchar *default_username)
+{
+  PpAuthenticationDialogPrivate *priv;
+  PpAuthenticationDialog        *dialog;
+  GtkWidget                     *widget;
+
+  dialog = g_object_new (PP_TYPE_AUTHENTICATION_DIALOG,
+                         "text", text,
+                         "username", default_username,
+                         NULL);
+  priv = dialog->priv;
+
+  if (default_username && strlen (default_username) > 0)
+    {
+      widget = WID ("password-entry");
+    }
+  else
+    {
+      widget = WID ("username-entry");
+    }
+
+  gtk_widget_grab_focus (widget);
+
+  gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), GTK_WINDOW (parent));
+
+  return PP_AUTHENTICATION_DIALOG (dialog);
+}
+
+static gchar *
+get_entry_text (const gchar            *object_name,
+                PpAuthenticationDialog *dialog)
+{
+  PpAuthenticationDialogPrivate *priv = dialog->priv;
+
+  return g_strdup (gtk_entry_get_text (GTK_ENTRY (WID (object_name))));
+}
+
+static void
+authentication_dialog_response_cb (GtkDialog *_dialog,
+                                   gint       response_id,
+                                   gpointer   user_data)
+{
+  PpAuthenticationDialog *dialog = (PpAuthenticationDialog*) user_data;
+  gchar                  *password = NULL;
+  gchar                  *username = NULL;
+
+  if (response_id == GTK_RESPONSE_OK)
+    {
+      username = get_entry_text ("username-entry", dialog);
+      password = get_entry_text ("password-entry", dialog);
+
+      if (username[0] == '\0')
+        g_clear_pointer (&username, g_free);
+
+      if (password[0] == '\0')
+        g_clear_pointer (&password, g_free);
+    }
+
+  g_signal_emit (dialog,
+                 signals[RESPONSE],
+                 0,
+                 username,
+                 password);
+
+  g_clear_pointer (&password, g_free);
+  g_clear_pointer (&username, g_free);
+}
+
+static void
+data_changed_cb (GtkEditable *editable,
+                 gpointer     user_data)
+{
+  PpAuthenticationDialog        *dialog = (PpAuthenticationDialog*) user_data;
+  PpAuthenticationDialogPrivate *priv = dialog->priv;
+
+  gtk_widget_set_sensitive (WID ("authentication-button"),
+                            strlen (gtk_entry_get_text (GTK_ENTRY (WID ("password-entry")))) > 0 &&
+                            strlen (gtk_entry_get_text (GTK_ENTRY (WID ("username-entry")))) > 0);
+}
+
+static void
+pp_authentication_dialog_init (PpAuthenticationDialog *dialog)
+{
+  PpAuthenticationDialogPrivate *priv;
+  GError                        *error = NULL;
+  gchar                         *objects[] = { "authentication-dialog", NULL };
+  guint                          builder_result;
+
+  dialog->priv = priv = PP_AUTHENTICATION_DIALOG_GET_PRIVATE (dialog);
+
+  priv->builder = gtk_builder_new ();
+
+  builder_result = gtk_builder_add_objects_from_resource (priv->builder,
+                                                          
"/org/gnome/control-center/printers/authentication-dialog.ui",
+                                                          objects, &error);
+
+  if (builder_result == 0)
+    {
+      g_warning ("Could not load ui: %s", error->message);
+      g_clear_error (&error);
+      return;
+    }
+
+  /* Construct dialog */
+  priv->dialog = WID ("authentication-dialog");
+
+  /* Connect signals */
+  g_signal_connect (priv->dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
+  g_signal_connect (priv->dialog, "response", G_CALLBACK (authentication_dialog_response_cb), dialog);
+  g_signal_connect (G_OBJECT (WID ("password-entry")), "changed", G_CALLBACK (data_changed_cb), dialog);
+  g_signal_connect (G_OBJECT (WID ("username-entry")), "changed", G_CALLBACK (data_changed_cb), dialog);
+
+  gtk_widget_show (priv->dialog);
+}
+
+static void
+pp_authentication_dialog_finalize (GObject *object)
+{
+  PpAuthenticationDialog        *dialog = PP_AUTHENTICATION_DIALOG (object);
+  PpAuthenticationDialogPrivate *priv = dialog->priv;
+
+  gtk_widget_hide (priv->dialog);
+
+  g_object_unref (priv->builder);
+  g_free (priv->text);
+  g_free (priv->username);
+
+  G_OBJECT_CLASS (pp_authentication_dialog_parent_class)->finalize (object);
+}
diff --git a/panels/printers/pp-authentication-dialog.h b/panels/printers/pp-authentication-dialog.h
new file mode 100644
index 0000000..e8e1a2c
--- /dev/null
+++ b/panels/printers/pp-authentication-dialog.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2012 - 2013 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Author: Marek Kasik <mkasik redhat com>
+ */
+
+#ifndef __PP_AUTHENTICATION_DIALOG_H__
+#define __PP_AUTHENTICATION_DIALOG_H__
+
+#include "pp-utils.h"
+
+G_BEGIN_DECLS
+
+#define PP_TYPE_AUTHENTICATION_DIALOG            (pp_authentication_dialog_get_type ())
+#define PP_AUTHENTICATION_DIALOG(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), 
PP_TYPE_AUTHENTICATION_DIALOG, PpAuthenticationDialog))
+#define PP_AUTHENTICATION_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), 
PP_TYPE_AUTHENTICATION_DIALOG, PpAuthenticationDialogClass))
+#define PP_IS_AUTHENTICATION_DIALOG(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), 
PP_TYPE_AUTHENTICATION_DIALOG))
+#define PP_IS_AUTHENTICATION_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
PP_TYPE_AUTHENTICATION_DIALOG))
+#define PP_AUTHENTICATION_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), 
PP_TYPE_AUTHENTICATION_DIALOG, PpAuthenticationDialogClass))
+
+typedef struct _PpAuthenticationDialog        PpAuthenticationDialog;
+typedef struct _PpAuthenticationDialogClass   PpAuthenticationDialogClass;
+typedef struct _PpAuthenticationDialogPrivate PpAuthenticationDialogPrivate;
+
+struct _PpAuthenticationDialog
+{
+  GObject                        parent_instance;
+  PpAuthenticationDialogPrivate *priv;
+};
+
+struct _PpAuthenticationDialogClass
+{
+  GObjectClass parent_class;
+
+  void (*response)      (PpAuthenticationDialog *dialog,
+                         const gchar            *username,
+                         const gchar            *password);
+};
+
+GType                   pp_authentication_dialog_get_type (void) G_GNUC_CONST;
+PpAuthenticationDialog *pp_authentication_dialog_new      (GtkWindow   *parent,
+                                                           const gchar *text,
+                                                           const gchar *default_username);
+
+G_END_DECLS
+
+#endif /* __PP_AUTHENTICATION_DIALOG_H__ */
diff --git a/panels/printers/printers.gresource.xml b/panels/printers/printers.gresource.xml
index 291c65a..607055e 100644
--- a/panels/printers/printers.gresource.xml
+++ b/panels/printers/printers.gresource.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gresources>
   <gresource prefix="/org/gnome/control-center/printers">
+    <file preprocess="xml-stripblanks">authentication-dialog.ui</file>
     <file preprocess="xml-stripblanks">jobs-dialog.ui</file>
     <file preprocess="xml-stripblanks">new-printer-dialog.ui</file>
     <file preprocess="xml-stripblanks">options-dialog.ui</file>



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