[accounts-dialog] Add a better password strength indicator



commit bb927552aa38f4fb7382bc08525f231f29fef02c
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Feb 4 00:21:43 2010 -0500

    Add a better password strength indicator

 data/password-dialog.ui  |    2 +-
 src/Makefile.am          |    2 +
 src/main.c               |    5 +
 src/um-password-dialog.c |   25 ++++-
 src/um-strength-bar.c    |  264 ++++++++++++++++++++++++++++++++++++++++++++++
 src/um-strength-bar.h    |   62 +++++++++++
 6 files changed, 353 insertions(+), 7 deletions(-)
---
diff --git a/data/password-dialog.ui b/data/password-dialog.ui
index 8dd1d64..39b55cb 100644
--- a/data/password-dialog.ui
+++ b/data/password-dialog.ui
@@ -207,7 +207,7 @@
                             <property name="top_padding">6</property>
                             <property name="bottom_padding">6</property>
                             <child>
-                              <object class="GtkProgressBar" id="strength-indicator-progressbar">
+                              <object class="UmStrengthBar" id="strength-indicator-progressbar">
                                 <property name="visible">True</property>
                               </object>
                             </child>
diff --git a/src/Makefile.am b/src/Makefile.am
index 2c3d5f5..87bb9e8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -44,6 +44,8 @@ accounts_dialog_SOURCES = \
 	um-utils.h			\
 	um-utils.c			\
 	fingerprint-strings.h		\
+	um-strength-bar.h		\
+	um-strength-bar.c		\
 	$(MARSHALFILES)			\
 	main.c
 
diff --git a/src/main.c b/src/main.c
index aff24bd..638ab71 100644
--- a/src/main.c
+++ b/src/main.c
@@ -54,6 +54,7 @@
 #include "um-photo-dialog.h"
 #include "um-fingerprint-dialog.h"
 #include "um-utils.h"
+#include "um-strength-bar.h"
 
 #include "gdm-languages.h"
 
@@ -1503,6 +1504,7 @@ main (int argc, char *argv[])
         GError *error;
         const gchar *filename;
         GtkWidget *button;
+        volatile GType type;
         GOptionContext *context;
         static gboolean do_debug;
         static gboolean do_version;
@@ -1560,6 +1562,9 @@ main (int argc, char *argv[])
                 }
         }
 
+        /* register types that the builder might need */
+        type = um_strength_bar_get_type ();
+
         d->builder = gtk_builder_new ();
         d->um = um_user_manager_ref_default ();
 
diff --git a/src/um-password-dialog.c b/src/um-password-dialog.c
index 6c66b20..6b346f5 100644
--- a/src/um-password-dialog.c
+++ b/src/um-password-dialog.c
@@ -31,6 +31,7 @@
 
 #include "um-password-dialog.h"
 #include "um-user-manager.h"
+#include "um-strength-bar.h"
 
 struct _UmPasswordDialog {
         GtkWidget *dialog;
@@ -272,14 +273,20 @@ update_password_strength (UmPasswordDialog *um)
 
         strength = compute_password_strength (password);
 
-        if (strength < 0.5)
-                hint = C_("Password strength", "Poor");
-        else if (strength < 0.8)
+        if (strlen (password) < 6) {
+                strength = 0.0;
+                hint = C_("Password strength", "Too short");
+        }
+        else if (strength < 0.50)
+                hint = C_("Password strength", "Weak");
+        else if (strength < 0.75)
                 hint = C_("Password strength", "Fair");
-        else
+        else if (strength < 0.90)
                 hint = C_("Password strength", "Good");
+        else
+                hint = C_("Password strength", "Strong");
 
-        gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (um->strength_indicator), strength);
+        um_strength_bar_set_strength (UM_STRENGTH_BAR (um->strength_indicator), strength);
         gtk_label_set_label (GTK_LABEL (um->strength_indicator_label), hint);
 }
 
@@ -325,8 +332,10 @@ um_password_dialog_new (void)
         builder = gtk_builder_new ();
 
         error = NULL;
+#if 0
         filename = UIDIR "/password-dialog.ui";
         if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+#endif
                 filename = "../data/password-dialog.ui";
         if (!gtk_builder_add_from_file (builder, filename, &error)) {
                 g_error ("%s", error->message);
@@ -373,9 +382,12 @@ um_password_dialog_new (void)
                           G_CALLBACK (password_entry_changed), um);
         um->verify_entry = widget;
 
-        len = strlen (C_("Password strength", "Poor"));
+        len = 0;
+        len = MAX (len, strlen (C_("Password strength", "Too short")));
+        len = MAX (len, strlen (C_("Password strength", "Weak")));
         len = MAX (len, strlen (C_("Password strength", "Fair")));
         len = MAX (len, strlen (C_("Password strength", "Good")));
+        len = MAX (len, strlen (C_("Password strength", "Strong")));
         len += 2;
 
         widget = (GtkWidget *) gtk_builder_get_object (builder, "strength-indicator-label");
@@ -411,6 +423,7 @@ um_password_dialog_new (void)
         um->medium_radio = (GtkWidget *) gtk_builder_get_object (builder, "length-medium-radiobutton");
         um->long_radio = (GtkWidget *) gtk_builder_get_object (builder, "length-long-radiobutton");
         um->strength_indicator = (GtkWidget *) gtk_builder_get_object (builder, "strength-indicator-progressbar");
+
         um->strength_indicator_label = (GtkWidget *) gtk_builder_get_object (builder, "strength-indicator-label");
 
         /* More label size hacks */
diff --git a/src/um-strength-bar.c b/src/um-strength-bar.c
new file mode 100644
index 0000000..88b8c37
--- /dev/null
+++ b/src/um-strength-bar.c
@@ -0,0 +1,264 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2010  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 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by: Matthias Clasen <mclasen redhat com>
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "um-strength-bar.h"
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UM_TYPE_STRENGTH_BAR, UmStrengthBarPrivate))
+
+struct _UmStrengthBarPrivate {
+        gdouble strength;
+};
+
+enum {
+        PROP_0,
+        PROP_STRENGTH
+};
+
+G_DEFINE_TYPE (UmStrengthBar, um_strength_bar, GTK_TYPE_WIDGET);
+
+
+static void
+um_strength_bar_set_property (GObject      *object,
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+        UmStrengthBar *bar = UM_STRENGTH_BAR (object);
+
+        switch (prop_id) {
+        case PROP_STRENGTH:
+                um_strength_bar_set_strength (bar, g_value_get_double (value));
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+um_strength_bar_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+        UmStrengthBar *bar = UM_STRENGTH_BAR (object);
+
+        switch (prop_id) {
+        case PROP_STRENGTH:
+                g_value_set_double (value, um_strength_bar_get_strength (bar));
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+curved_rectangle (cairo_t *cr,
+                  double   x0,
+                  double   y0,
+                  double   width,
+                  double   height,
+                  double   radius)
+{
+        double x1;
+        double y1;
+
+        x1 = x0 + width;
+        y1 = y0 + height;
+
+        if (!width || !height) {
+                return;
+        }
+
+        if (width / 2 < radius) {
+                if (height / 2 < radius) {
+                        cairo_move_to  (cr, x0, (y0 + y1) / 2);
+                        cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1) / 2, y0);
+                        cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
+                        cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
+                        cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
+                } else {
+                        cairo_move_to  (cr, x0, y0 + radius);
+                        cairo_curve_to (cr, x0, y0, x0, y0, (x0 + x1) / 2, y0);
+                        cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
+                        cairo_line_to (cr, x1, y1 - radius);
+                        cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
+                        cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius);
+                }
+        } else {
+                if (height / 2 < radius) {
+                        cairo_move_to  (cr, x0, (y0 + y1) / 2);
+                        cairo_curve_to (cr, x0, y0, x0 , y0, x0 + radius, y0);
+                        cairo_line_to (cr, x1 - radius, y0);
+                        cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
+                        cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
+                        cairo_line_to (cr, x0 + radius, y1);
+                        cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
+                } else {
+                        cairo_move_to  (cr, x0, y0 + radius);
+                        cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
+                        cairo_line_to (cr, x1 - radius, y0);
+                        cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
+                        cairo_line_to (cr, x1, y1 - radius);
+                        cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
+                        cairo_line_to (cr, x0 + radius, y1);
+                        cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius);
+                }
+        }
+
+        cairo_close_path (cr);
+}
+
+gdouble color1[3] = { 213.0/255.0, 4.0/255.0, 4.0/255.0 };
+gdouble color2[3] = { 234.0/255.0, 236.0/255.0, 31.0/255.0 };
+gdouble color3[3] = { 141.0/255.0, 133.0/255.0, 241.0/255.0 };
+gdouble color4[3] = { 99.0/255.0, 251.0/255.0, 107.0/255.0 };
+
+static void
+get_color (gdouble value, gdouble *r, gdouble *g, gdouble *b)
+{
+        gdouble *c;
+
+        if (value < 0.50) {
+                c = color1;
+        }
+        else if (value < 0.75) {
+                c = color2;
+        }
+        else if (value < 0.90) {
+                c = color3;
+        }
+        else {
+                c = color4;
+        }
+
+        *r = c[0];
+        *g = c[1];
+        *b = c[2];
+}
+
+static gboolean
+um_strength_bar_expose (GtkWidget      *widget,
+                        GdkEventExpose *event)
+{
+        UmStrengthBar *bar = UM_STRENGTH_BAR (widget);
+        gdouble r, g, b;
+
+        if (GTK_WIDGET_DRAWABLE (widget)) {
+                cairo_t *cr;
+
+                cr = gdk_cairo_create (widget->window);
+                cairo_set_line_width (cr, 1);
+
+                cairo_rectangle (cr,
+                                 widget->allocation.x,
+                                 widget->allocation.y,
+                                 bar->priv->strength * widget->allocation.width,
+                                 widget->allocation.height);
+                cairo_clip (cr);
+
+                curved_rectangle (cr,
+                                 widget->allocation.x + 0.5,
+                                 widget->allocation.y + 0.5,
+                                 widget->allocation.width - 1,
+                                 widget->allocation.height - 1,
+                                 4);
+                get_color (bar->priv->strength, &r, &g ,&b);
+                cairo_set_source_rgb (cr, r, g, b);
+                cairo_fill_preserve (cr);
+
+                cairo_reset_clip (cr);
+                cairo_set_source_rgb (cr, 0, 0, 0);
+                cairo_stroke (cr);
+
+                cairo_destroy (cr);
+        }
+
+        return FALSE;
+}
+
+static void
+um_strength_bar_class_init (UmStrengthBarClass *class)
+{
+        GObjectClass *gobject_class;
+        GtkWidgetClass *widget_class;
+
+        gobject_class = (GObjectClass*)class;
+        widget_class = (GtkWidgetClass*)class;
+
+        gobject_class->set_property = um_strength_bar_set_property;
+        gobject_class->get_property = um_strength_bar_get_property;
+
+        widget_class->expose_event = um_strength_bar_expose;
+
+         g_object_class_install_property (gobject_class,
+                                          PROP_STRENGTH,
+                                          g_param_spec_double ("strength",
+                                                               "Strength",
+                                                               "Strength",
+                                                               0.0, 1.0, 0.0,
+                                                               G_PARAM_READWRITE));
+
+        g_type_class_add_private (class, sizeof (UmStrengthBarPrivate));
+}
+
+static void
+um_strength_bar_init (UmStrengthBar *bar)
+{
+        GTK_WIDGET_SET_FLAGS (bar, GTK_NO_WINDOW);
+        GTK_WIDGET (bar)->requisition.width = 120;
+        GTK_WIDGET (bar)->requisition.height = 8;
+
+        bar->priv = GET_PRIVATE (bar);
+        bar->priv->strength = 0.0;
+}
+
+GtkWidget *
+um_strength_bar_new (void)
+{
+        return (GtkWidget*) g_object_new (UM_TYPE_STRENGTH_BAR, NULL);
+}
+
+void
+um_strength_bar_set_strength (UmStrengthBar *bar,
+                              gdouble        strength)
+{
+        bar->priv->strength = strength;
+
+        g_object_notify (G_OBJECT (bar), "strength");
+
+        if (GTK_WIDGET_DRAWABLE (bar)) {
+                gtk_widget_queue_draw (GTK_WIDGET (bar));
+        }
+}
+
+gdouble
+um_strength_bar_get_strength (UmStrengthBar *bar)
+{
+        return bar->priv->strength;
+}
diff --git a/src/um-strength-bar.h b/src/um-strength-bar.h
new file mode 100644
index 0000000..8bf0572
--- /dev/null
+++ b/src/um-strength-bar.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2010 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 3
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Author: Matthias Clasen
+ */
+
+#ifndef _UM_STRENGTH_BAR_H_
+#define _UM_STRENGTH_BAR_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define UM_TYPE_STRENGTH_BAR            (um_strength_bar_get_type ())
+#define UM_STRENGTH_BAR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), UM_TYPE_STRENGTH_BAR, \
+                                                                           UmStrengthBar))
+#define UM_STRENGTH_BAR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), UM_TYPE_STRENGTH_BAR, \
+                                                                        UmStrengthBarClass))
+#define UM_IS_STRENGTH_BAR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UM_TYPE_STRENGTH_BAR))
+#define UM_IS_STRENGTH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UM_TYPE_STRENGTH_BAR))
+#define UM_STRENGTH_BAR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), UM_TYPE_STRENGTH_BAR, \
+                                                                          UmStrengthBarClass))
+
+typedef struct _UmStrengthBarClass UmStrengthBarClass;
+typedef struct _UmStrengthBar UmStrengthBar;
+typedef struct _UmStrengthBarPrivate UmStrengthBarPrivate;
+
+struct _UmStrengthBarClass {
+        GtkWidgetClass parent_class;
+};
+
+struct _UmStrengthBar {
+        GtkWidget parent_instance;
+        UmStrengthBarPrivate *priv;
+};
+
+GType      um_strength_bar_get_type             (void) G_GNUC_CONST;
+
+GtkWidget *um_strength_bar_new                  (void);
+void       um_strength_bar_set_strength         (UmStrengthBar *bar,
+                                                 gdouble        strength);
+gdouble    um_strength_bar_get_strength         (UmStrengthBar *bar);
+
+G_END_DECLS
+
+#endif /* _UM_STRENGTH_BAR_H_ */



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