[Xfce4-commits] r25890 - in xfce4-panel/trunk: . plugins/clock po

Nick Schermer nick at xfce.org
Fri Jul 6 21:57:21 CEST 2007


Author: nick
Date: 2007-07-06 19:57:20 +0000 (Fri, 06 Jul 2007)
New Revision: 25890

Added:
   xfce4-panel/trunk/plugins/clock/clock-analog.c
   xfce4-panel/trunk/plugins/clock/clock-analog.h
   xfce4-panel/trunk/plugins/clock/clock-binary.c
   xfce4-panel/trunk/plugins/clock/clock-binary.h
   xfce4-panel/trunk/plugins/clock/clock-dialog.c
   xfce4-panel/trunk/plugins/clock/clock-dialog.h
   xfce4-panel/trunk/plugins/clock/clock-digital.c
   xfce4-panel/trunk/plugins/clock/clock-digital.h
   xfce4-panel/trunk/plugins/clock/clock-lcd.c
   xfce4-panel/trunk/plugins/clock/clock-lcd.h
   xfce4-panel/trunk/plugins/clock/clock.h
Modified:
   xfce4-panel/trunk/ChangeLog
   xfce4-panel/trunk/NEWS
   xfce4-panel/trunk/configure.in.in
   xfce4-panel/trunk/plugins/clock/Makefile.am
   xfce4-panel/trunk/plugins/clock/clock.c
   xfce4-panel/trunk/plugins/clock/clock.desktop.in.in
   xfce4-panel/trunk/po/POTFILES.in
   xfce4-panel/trunk/po/ar.po
   xfce4-panel/trunk/po/az.po
   xfce4-panel/trunk/po/be.po
   xfce4-panel/trunk/po/bg.po
   xfce4-panel/trunk/po/bn_IN.po
   xfce4-panel/trunk/po/ca.po
   xfce4-panel/trunk/po/cs.po
   xfce4-panel/trunk/po/de.po
   xfce4-panel/trunk/po/dz.po
   xfce4-panel/trunk/po/el.po
   xfce4-panel/trunk/po/en_GB.po
   xfce4-panel/trunk/po/eo.po
   xfce4-panel/trunk/po/es.po
   xfce4-panel/trunk/po/es_MX.po
   xfce4-panel/trunk/po/et.po
   xfce4-panel/trunk/po/eu.po
   xfce4-panel/trunk/po/fa.po
   xfce4-panel/trunk/po/fi.po
   xfce4-panel/trunk/po/fr.po
   xfce4-panel/trunk/po/gl.po
   xfce4-panel/trunk/po/gu.po
   xfce4-panel/trunk/po/he.po
   xfce4-panel/trunk/po/hi.po
   xfce4-panel/trunk/po/hu.po
   xfce4-panel/trunk/po/hy.po
   xfce4-panel/trunk/po/it.po
   xfce4-panel/trunk/po/ja.po
   xfce4-panel/trunk/po/ka.po
   xfce4-panel/trunk/po/ko.po
   xfce4-panel/trunk/po/lt.po
   xfce4-panel/trunk/po/mk.po
   xfce4-panel/trunk/po/mr.po
   xfce4-panel/trunk/po/ms.po
   xfce4-panel/trunk/po/nb_NO.po
   xfce4-panel/trunk/po/nl.po
   xfce4-panel/trunk/po/pa.po
   xfce4-panel/trunk/po/pl.po
   xfce4-panel/trunk/po/pt_BR.po
   xfce4-panel/trunk/po/pt_PT.po
   xfce4-panel/trunk/po/ro.po
   xfce4-panel/trunk/po/ru.po
   xfce4-panel/trunk/po/sk.po
   xfce4-panel/trunk/po/sq.po
   xfce4-panel/trunk/po/sv.po
   xfce4-panel/trunk/po/ta.po
   xfce4-panel/trunk/po/tr.po
   xfce4-panel/trunk/po/uk.po
   xfce4-panel/trunk/po/vi.po
   xfce4-panel/trunk/po/xfce4-panel.pot
   xfce4-panel/trunk/po/zh_CN.po
   xfce4-panel/trunk/po/zh_TW.po
Log:
	* plugins/launcher/launcher-exec.c: Define WAIT_ANY if it's not
	  loading (and yes this might break internal plugins, but the plugin's

Modified: xfce4-panel/trunk/ChangeLog
===================================================================
--- xfce4-panel/trunk/ChangeLog	2007-07-06 13:14:53 UTC (rev 25889)
+++ xfce4-panel/trunk/ChangeLog	2007-07-06 19:57:20 UTC (rev 25890)
@@ -1,6 +1,14 @@
+2007-07-06 10:50 nick
+
+    * plugins/clock/*: Import code.
+    * NEWS: update.
+    * Configure.in.in: Bump GTK dependency to 2.8.0 and add cairo as
+      new dependency.
+    * po/*: Merge new strings.
+
 2007-05-27 10:50 nick
 
-	* plugins/launcher/launcher-exec.c: Define WAIT_ANY if it's not 
+	* plugins/launcher/launcher-exec.c: Define WAIT_ANY if it's not
 	  available in wait.h. Reported by Daichi.
 
 2007-05-26 12:25 nick
@@ -19,7 +27,7 @@
 	* panel/panel-item-manager.c: Rewrite some code, internal plugins
 	  now need the X-XFCE-Module-Path entry in the desktop file. A
 	  warning is shown if they don't have it. This to avoid wrong module
-	  loading (and yes this might break internal plugins, but the plugin's 
+	  loading (and yes this might break internal plugins, but the plugin's
 	  desktop file needs to be fixed instead!). Also fixes bug #3279.
 
 2007-05-24 14:00 nick

Modified: xfce4-panel/trunk/NEWS
===================================================================
--- xfce4-panel/trunk/NEWS	2007-07-06 13:14:53 UTC (rev 25889)
+++ xfce4-panel/trunk/NEWS	2007-07-06 19:57:20 UTC (rev 25890)
@@ -4,8 +4,7 @@
   (Jasper)
 - Separator can have different styles: space, expanded space, line (default),
   handle and old-style dotted handle. Initial patch by Landry Breuil. (Jasper)
-- Make sure tooltips are set for more than 1 clock instance (bug #3109).
-  (Jasper)
+- Complete rewrite of the clock plugin. (Nick)
 - Fix area that is off-limits to other windows (_NET_WM_STRUT hints) for a
   Xinerama setup with differently sized monitors (Bug #3097). (Jasper)
 - Completely rewritten launcher (Bugs 2336, 2365, 1323, 2262 and 1225)

Modified: xfce4-panel/trunk/configure.in.in
===================================================================
--- xfce4-panel/trunk/configure.in.in	2007-07-06 13:14:53 UTC (rev 25889)
+++ xfce4-panel/trunk/configure.in.in	2007-07-06 19:57:20 UTC (rev 25890)
@@ -90,7 +90,7 @@
 dnl *** Check for standard functions ***
 dnl ************************************
 AC_FUNC_MMAP()
-AC_CHECK_FUNCS([sigaction])
+AC_CHECK_FUNCS([sigaction localtime_r])
 
 dnl ******************************
 dnl *** Check for i18n support ***
@@ -107,11 +107,12 @@
 dnl *** Check for required packages ***
 dnl ***********************************
 XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.4.0])
-XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.6.4])
-XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.6.4])
-XDT_CHECK_PACKAGE([GMODULE], [gmodule-2.0], [2.6.4])
+XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.8.0])
+XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.8.0])
+XDT_CHECK_PACKAGE([GMODULE], [gmodule-2.0], [2.8.0])
 XDT_CHECK_PACKAGE([LIBXFCEGUI4], [libxfcegui4-1.0], [4.4.0])
 XDT_CHECK_PACKAGE([LIBEXO], [exo-0.3], [0.3.1.11])
+XDT_CHECK_PACKAGE([CAIRO], [cairo], [1.0.0])
 
 dnl ***********************************
 dnl *** Check for optional packages ***

Modified: xfce4-panel/trunk/plugins/clock/Makefile.am
===================================================================
--- xfce4-panel/trunk/plugins/clock/Makefile.am	2007-07-06 13:14:53 UTC (rev 25889)
+++ xfce4-panel/trunk/plugins/clock/Makefile.am	2007-07-06 19:57:20 UTC (rev 25890)
@@ -13,11 +13,23 @@
 	libclock.la
 
 libclock_la_SOURCES = 							\
-	clock.c
+	clock.c								\
+	clock.h								\
+	clock-analog.c							\
+	clock-analog.h							\
+	clock-binary.c							\
+	clock-binary.h							\
+	clock-dialog.c							\
+	clock-dialog.h							\
+	clock-digital.c							\
+	clock-digital.h							\
+	clock-lcd.c							\
+	clock-lcd.h
 
 libclock_la_CFLAGS =							\
 	$(GTK_CFLAGS)							\
 	$(LIBXFCE4UTIL_CFLAGS)						\
+	$(CAIRO_CFLAGS)							\
 	$(LIBXFCEGUI4_CFLAGS)						\
 	$(PLATFORM_CFLAGS)
 
@@ -34,6 +46,7 @@
 libclock_la_LIBADD =							\
 	$(top_builddir)/libxfce4panel/libxfce4panel.la			\
 	$(GTK_LIBS)							\
+	$(CAIRO_LIBS)							\
 	$(LIBXFCE4UTIL_LIBS)						\
 	$(LIBXFCEGUI4_LIBS)
 

Added: xfce4-panel/trunk/plugins/clock/clock-analog.c
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock-analog.c	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock-analog.c	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,378 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <cairo/cairo.h>
+
+#include "clock.h"
+#include "clock-analog.h"
+
+#ifndef M_PI
+#define M_PI 3.141592654
+#endif
+
+#define CLOCK_SCALE 0.1
+#define TICKS_TO_RADIANS(x)   (M_PI - (M_PI / 30.0) * (x))
+#define HOURS_TO_RADIANS(x,y) (M_PI - (M_PI / 6.0) * (((x) > 12 ? (x) - 12 : (x)) + (y) / 60.0))
+
+
+
+/* prototypes */
+static void      xfce_clock_analog_class_init    (XfceClockAnalogClass *klass);
+static void      xfce_clock_analog_init          (XfceClockAnalog      *clock);
+static void      xfce_clock_analog_finalize      (GObject              *object);
+static void      xfce_clock_analog_set_property  (GObject              *object,
+                                                  guint                 prop_id,
+                                                  const GValue         *value,
+                                                  GParamSpec           *pspec);
+static void      xfce_clock_analog_get_property  (GObject              *object,
+                                                  guint                 prop_id,
+                                                  GValue               *value,
+                                                  GParamSpec           *pspec);
+static void      xfce_clock_analog_size_request  (GtkWidget            *widget,
+			                                      GtkRequisition       *requisition);
+static gboolean  xfce_clock_analog_expose_event  (GtkWidget            *widget,
+                                                  GdkEventExpose       *event);
+static void      xfce_clock_analog_draw_ticks    (cairo_t              *cr,
+                                                  gdouble               xc,
+                                                  gdouble               yc,
+                                                  gdouble               radius);
+static void      xfce_clock_analog_draw_pointer  (cairo_t              *cr,
+                                                  gdouble               xc,
+                                                  gdouble               yc,
+                                                  gdouble               radius,
+                                                  gdouble               angle,
+                                                  gdouble               scale,
+                                                  gboolean              line);
+
+
+
+enum
+{
+    PROP_0,
+    PROP_SHOW_SECONDS
+};
+
+struct _XfceClockAnalogClass
+{
+    GtkImageClass __parent__;
+};
+
+struct _XfceClockAnalog
+{
+    GtkImage  __parent__;
+
+    /* draw seconds */
+    guint     show_seconds : 1;
+};
+
+
+
+static GObjectClass *xfce_clock_analog_parent_class;
+
+
+
+GType
+xfce_clock_analog_get_type (void)
+{
+    static GType type = G_TYPE_INVALID;
+
+    if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+        type = g_type_register_static_simple (GTK_TYPE_IMAGE,
+                                              I_("XfceClockAnalog"),
+                                              sizeof (XfceClockAnalogClass),
+                                              (GClassInitFunc) xfce_clock_analog_class_init,
+                                              sizeof (XfceClockAnalog),
+                                              (GInstanceInitFunc) xfce_clock_analog_init,
+                                              0);
+    }
+
+    return type;
+}
+
+
+
+static void
+xfce_clock_analog_class_init (XfceClockAnalogClass *klass)
+{
+    GObjectClass   *gobject_class;
+    GtkWidgetClass *gtkwidget_class;
+
+    xfce_clock_analog_parent_class = g_type_class_peek_parent (klass);
+
+    gobject_class = G_OBJECT_CLASS (klass);
+    gobject_class->finalize = xfce_clock_analog_finalize;
+    gobject_class->set_property = xfce_clock_analog_set_property;
+    gobject_class->get_property = xfce_clock_analog_get_property;
+
+    gtkwidget_class = GTK_WIDGET_CLASS (klass);
+    gtkwidget_class->size_request = xfce_clock_analog_size_request;
+    gtkwidget_class->expose_event = xfce_clock_analog_expose_event;
+
+    /**
+     * Whether we display seconds
+     **/
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_SECONDS,
+                                     g_param_spec_boolean ("show-seconds", "show-seconds", "show-seconds",
+                                                           FALSE, PANEL_PARAM_READWRITE));
+}
+
+
+
+static void
+xfce_clock_analog_init (XfceClockAnalog *clock)
+{
+    /* init */
+    clock->show_seconds = FALSE;
+}
+
+
+
+static void
+xfce_clock_analog_finalize (GObject *object)
+{
+    (*G_OBJECT_CLASS (xfce_clock_analog_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfce_clock_analog_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+    XfceClockAnalog *clock = XFCE_CLOCK_ANALOG (object);
+
+    switch (prop_id)
+    {
+        case PROP_SHOW_SECONDS:
+            clock->show_seconds = g_value_get_boolean (value);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+    }
+}
+
+
+
+static void
+xfce_clock_analog_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+    XfceClockAnalog *clock = XFCE_CLOCK_ANALOG (object);
+
+    switch (prop_id)
+    {
+        case PROP_SHOW_SECONDS:
+            g_value_set_boolean (value, clock->show_seconds);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+    }
+}
+
+
+
+static void
+xfce_clock_analog_size_request  (GtkWidget      *widget,
+			                     GtkRequisition *requisition)
+{
+    gint width, height;
+
+    /* get the current widget size */
+    gtk_widget_get_size_request (widget, &width, &height);
+
+    /* square the widget */
+    requisition->width = requisition->height = MAX (width, height);
+}
+
+
+
+static gboolean
+xfce_clock_analog_expose_event (GtkWidget      *widget,
+                                GdkEventExpose *event)
+{
+    XfceClockAnalog *clock = XFCE_CLOCK_ANALOG (widget);
+    gdouble          xc, yc;
+    gdouble          angle, radius;
+    cairo_t         *cr;
+    time_t           now = time (0);
+    struct tm        tm;
+
+    g_return_val_if_fail (XFCE_CLOCK_IS_ANALOG (clock), FALSE);
+
+    /* get center of the widget and the radius */
+    xc = (widget->allocation.width / 2.0);
+    yc = (widget->allocation.height / 2.0);
+    radius = MIN (xc, yc);
+
+    /* add the window offset */
+    xc += widget->allocation.x;
+    yc += widget->allocation.y;
+
+    /* get the cairo context */
+    cr = gdk_cairo_create (widget->window);
+
+    if (G_LIKELY (cr != NULL))
+    {
+        /* get the local time */
+        localtime_r (&now, &tm);
+
+        /* set the line properties */
+        cairo_set_line_width (cr, 1);
+        gdk_cairo_set_source_color (cr, &widget->style->fg[GTK_STATE_NORMAL]);
+
+        /* draw the ticks */
+        xfce_clock_analog_draw_ticks (cr, xc, yc, radius);
+
+        if (clock->show_seconds)
+        {
+            /* second pointer */
+            angle = TICKS_TO_RADIANS (tm.tm_sec);
+            xfce_clock_analog_draw_pointer (cr, xc, yc, radius, angle, 0.7, TRUE);
+        }
+
+        /* minute pointer */
+        angle = TICKS_TO_RADIANS (tm.tm_min);
+        xfce_clock_analog_draw_pointer (cr, xc, yc, radius, angle, 0.8, FALSE);
+
+        /* hour pointer */
+        angle = HOURS_TO_RADIANS (tm.tm_hour, tm.tm_min);
+        xfce_clock_analog_draw_pointer (cr, xc, yc, radius, angle, 0.5, FALSE);
+
+        /* cleanup */
+        cairo_destroy (cr);
+    }
+
+    return FALSE;
+}
+
+
+
+static void
+xfce_clock_analog_draw_ticks (cairo_t *cr,
+                              gdouble  xc,
+                              gdouble  yc,
+                              gdouble  radius)
+{
+    gint    i;
+    gdouble x, y, angle;
+
+    for (i = 0; i < 12; i++)
+    {
+        /* calculate */
+        angle = HOURS_TO_RADIANS (i, 0);
+        x = xc + sin (angle) * (radius * (1.0 - CLOCK_SCALE));
+        y = yc + cos (angle) * (radius * (1.0 - CLOCK_SCALE));
+
+        /* draw arc */
+        cairo_move_to (cr, x, y);
+        cairo_arc (cr, x, y, radius * CLOCK_SCALE, 0, 2 * M_PI);
+        cairo_close_path (cr);
+    }
+
+    /* fill the arcs */
+    cairo_fill (cr);
+}
+
+
+
+static void
+xfce_clock_analog_draw_pointer (cairo_t *cr,
+                                gdouble  xc,
+                                gdouble  yc,
+                                gdouble  radius,
+                                gdouble  angle,
+                                gdouble  scale,
+                                gboolean line)
+{
+    gdouble xs, ys;
+    gdouble xt, yt;
+
+    /* calculate tip position */
+    xt = xc + sin (angle) * radius * scale;
+    yt = yc + cos (angle) * radius * scale;
+
+    if (line)
+    {
+        /* draw the line */
+        cairo_move_to (cr, xc, yc);
+        cairo_line_to (cr, xt, yt);
+
+        /* draw the line */
+        cairo_stroke (cr);
+    }
+    else
+    {
+        /* calculate start position */
+        xs = xc + sin (angle - 0.5 * M_PI) * radius * CLOCK_SCALE;
+        ys = yc + cos (angle - 0.5 * M_PI) * radius * CLOCK_SCALE;
+
+        /* draw the pointer */
+        cairo_move_to (cr, xs, ys);
+        cairo_arc (cr, xc, yc, radius * CLOCK_SCALE, -angle + M_PI, -angle);
+        cairo_line_to (cr, xt, yt);
+        cairo_close_path (cr);
+
+        /* fill the pointer */
+        cairo_fill (cr);
+    }
+}
+
+
+
+GtkWidget *
+xfce_clock_analog_new (void)
+{
+    return g_object_new (XFCE_CLOCK_TYPE_ANALOG, NULL);
+}
+
+
+
+gboolean
+xfce_clock_analog_update (gpointer user_data)
+{
+    GtkWidget *widget = GTK_WIDGET (user_data);
+
+    /* update if the widget if visible */
+    if (G_LIKELY (GTK_WIDGET_VISIBLE (widget)))
+        gtk_widget_queue_draw (widget);
+
+    return TRUE;
+}


Property changes on: xfce4-panel/trunk/plugins/clock/clock-analog.c
___________________________________________________________________
Name: keywords
   + Id

Added: xfce4-panel/trunk/plugins/clock/clock-analog.h
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock-analog.h	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock-analog.h	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,43 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifndef __CLOCK_ANALOG_H__
+#define __CLOCK_ANALOG_H__
+
+G_BEGIN_DECLS
+
+typedef struct _XfceClockAnalogClass XfceClockAnalogClass;
+typedef struct _XfceClockAnalog      XfceClockAnalog;
+
+#define XFCE_CLOCK_TYPE_ANALOG            (xfce_clock_analog_get_type ())
+#define XFCE_CLOCK_ANALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_CLOCK_TYPE_ANALOG, XfceClockAnalog))
+#define XFCE_CLOCK_ANALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_CLOCK_TYPE_ANALOG, XfceClockAnalogClass))
+#define XFCE_CLOCK_IS_ANALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_CLOCK_TYPE_ANALOG))
+#define XFCE_CLOCK_IS_ANALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_CLOCK_TYPE_ANALOG))
+#define XFCE_CLOCK_ANALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_CLOCK_TYPE_ANALOG, XfceClockAnalogClass))
+
+GType      xfce_clock_analog_get_type (void) G_GNUC_CONST  G_GNUC_INTERNAL;
+
+GtkWidget *xfce_clock_analog_new      (void) G_GNUC_MALLOC G_GNUC_INTERNAL;
+
+gboolean   xfce_clock_analog_update   (gpointer user_data) G_GNUC_INTERNAL;
+
+G_END_DECLS
+
+#endif /* !__CLOCK_ANALOG_H__ */


Property changes on: xfce4-panel/trunk/plugins/clock/clock-analog.h
___________________________________________________________________
Name: keywords
   + Id

Added: xfce4-panel/trunk/plugins/clock/clock-binary.c
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock-binary.c	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock-binary.c	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,396 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+
+#ifndef M_PI
+#define M_PI 3.141592654
+#endif
+
+#include <gtk/gtk.h>
+#include <cairo/cairo.h>
+
+#include "clock.h"
+#include "clock-binary.h"
+
+
+
+/* class functions */
+static void      xfce_clock_binary_class_init    (XfceClockBinaryClass *klass);
+static void      xfce_clock_binary_init          (XfceClockBinary      *clock);
+static void      xfce_clock_binary_finalize      (GObject              *object);
+static void      xfce_clock_binary_set_property  (GObject              *object,
+                                                  guint                 prop_id,
+                                                  const GValue         *value,
+                                                  GParamSpec           *pspec);
+static void      xfce_clock_binary_get_property  (GObject              *object,
+                                                  guint                 prop_id,
+                                                  GValue               *value,
+                                                  GParamSpec           *pspec);
+static void      xfce_clock_binary_size_request  (GtkWidget            *widget,
+			                                      GtkRequisition       *requisition);
+static gboolean  xfce_clock_binary_expose_event  (GtkWidget            *widget,
+                                                  GdkEventExpose       *event);
+
+
+enum
+{
+    PROP_0,
+    PROP_SHOW_SECONDS,
+    PROP_TRUE_BINARY
+};
+
+struct _XfceClockBinaryClass
+{
+    GtkImageClass __parent__;
+};
+
+struct _XfceClockBinary
+{
+    GtkImage  __parent__;
+
+    /* whether we draw seconds */
+    guint     show_seconds : 1;
+
+    /* if this is a true binary clock */
+    guint     true_binary : 1;
+};
+
+
+
+static GObjectClass *xfce_clock_binary_parent_class;
+
+
+
+GType
+xfce_clock_binary_get_type (void)
+{
+    static GType type = G_TYPE_INVALID;
+
+    if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+        type = g_type_register_static_simple (GTK_TYPE_IMAGE,
+                                              I_("XfceClockBinary"),
+                                              sizeof (XfceClockBinaryClass),
+                                              (GClassInitFunc) xfce_clock_binary_class_init,
+                                              sizeof (XfceClockBinary),
+                                              (GInstanceInitFunc) xfce_clock_binary_init,
+                                              0);
+    }
+
+    return type;
+}
+
+
+
+static void
+xfce_clock_binary_class_init (XfceClockBinaryClass *klass)
+{
+    GObjectClass   *gobject_class;
+    GtkWidgetClass *gtkwidget_class;
+
+    xfce_clock_binary_parent_class = g_type_class_peek_parent (klass);
+
+    gobject_class = G_OBJECT_CLASS (klass);
+    gobject_class->finalize = xfce_clock_binary_finalize;
+    gobject_class->set_property = xfce_clock_binary_set_property;
+    gobject_class->get_property = xfce_clock_binary_get_property;
+
+    gtkwidget_class = GTK_WIDGET_CLASS (klass);
+    gtkwidget_class->size_request = xfce_clock_binary_size_request;
+    gtkwidget_class->expose_event = xfce_clock_binary_expose_event;
+
+    /**
+     * Whether we display seconds
+     **/
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_SECONDS,
+                                     g_param_spec_boolean ("show-seconds", "show-seconds", "show-seconds",
+                                                           FALSE, PANEL_PARAM_READWRITE));
+
+    /**
+     * Whether this is a true binary clock
+     **/
+    g_object_class_install_property (gobject_class,
+                                     PROP_TRUE_BINARY,
+                                     g_param_spec_boolean ("true-binary", "true-binary", "true-binary",
+                                                           FALSE, PANEL_PARAM_READWRITE));
+}
+
+
+
+static void
+xfce_clock_binary_init (XfceClockBinary *clock)
+{
+    /* init */
+    clock->show_seconds = FALSE;
+    clock->true_binary = FALSE;
+}
+
+
+
+static void
+xfce_clock_binary_finalize (GObject *object)
+{
+    (*G_OBJECT_CLASS (xfce_clock_binary_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfce_clock_binary_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+    XfceClockBinary *clock = XFCE_CLOCK_BINARY (object);
+
+    switch (prop_id)
+    {
+        case PROP_SHOW_SECONDS:
+            clock->show_seconds = g_value_get_boolean (value);
+            break;
+
+        case PROP_TRUE_BINARY:
+            clock->true_binary = g_value_get_boolean (value);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+    }
+}
+
+
+
+static void
+xfce_clock_binary_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+    XfceClockBinary *clock = XFCE_CLOCK_BINARY (object);
+
+    switch (prop_id)
+    {
+        case PROP_SHOW_SECONDS:
+            g_value_set_boolean (value, clock->show_seconds);
+            break;
+
+        case PROP_TRUE_BINARY:
+            g_value_set_boolean (value, clock->true_binary);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+    }
+}
+
+
+
+static void
+xfce_clock_binary_size_request (GtkWidget      *widget,
+			                    GtkRequisition *requisition)
+{
+    gint             width, height;
+    gdouble          ratio;
+    XfceClockBinary *clock = XFCE_CLOCK_BINARY (widget);
+
+    /* get the current widget size */
+    gtk_widget_get_size_request (widget, &width, &height);
+
+    /* ratio of the clock */
+    if (clock->true_binary)
+    {
+        ratio = clock->show_seconds ? 2.0 : 3.0;
+    }
+    else
+    {
+        ratio = clock->show_seconds ? 1.5 : 1.0;
+    }
+
+    /* set requisition based on the plugin orientation */
+    if (width == -1)
+    {
+        requisition->height = height;
+        requisition->width = height * ratio;
+    }
+    else
+    {
+        requisition->height = width / ratio;
+        requisition->width = width;
+    }
+}
+
+
+
+static gboolean
+xfce_clock_binary_expose_event (GtkWidget      *widget,
+                                GdkEventExpose *event)
+{
+    XfceClockBinary *clock = XFCE_CLOCK_BINARY (widget);
+    gdouble          cw, ch, columns;
+    gint             ticks, cells, decimal;
+    gdouble          radius;
+    gdouble          x, y;
+    gint             i, j;
+    gint             decimal_tb[] = {32, 16, 8, 4, 2, 1};
+    gint             decimal_bcd[] = {80, 40, 20, 10, 8, 4, 2, 1};
+    cairo_t         *cr;
+    GdkColor         active, inactive;
+    time_t           now = time (0);
+    struct tm        tm;
+
+    g_return_val_if_fail (XFCE_CLOCK_IS_BINARY (clock), FALSE);
+
+    /* number of columns and cells */
+    columns = clock->show_seconds ? 3.0 : 2.0;
+    cells = clock->true_binary ? 6 : 8;
+
+    /* cell width and height */
+    if (clock->true_binary)
+    {
+        cw = widget->allocation.width / 6.0;
+        ch = widget->allocation.height / columns;
+    }
+    else /* bcd clock */
+    {
+        cw = widget->allocation.width / columns / 2.0;
+        ch = widget->allocation.height / 4.0;
+    }
+
+    /* arc radius */
+    radius = MIN (cw, ch) / 2.0 * 0.7;
+
+    /* get colors */
+    inactive = widget->style->fg[GTK_STATE_NORMAL];
+    active = widget->style->bg[GTK_STATE_SELECTED];
+
+    /* get the cairo context */
+    cr = gdk_cairo_create (widget->window);
+
+    if (G_LIKELY (cr != NULL))
+    {
+        /* get the current time */
+        localtime_r (&now, &tm);
+
+        /* walk the three or two time parts */
+        for (i = 0; i < columns; i++)
+        {
+            /* get the time of this column */
+            if (i == 0)
+                ticks = tm.tm_hour;
+            else if (i == 1)
+                ticks = tm.tm_min;
+            else
+                ticks = tm.tm_sec;
+
+            /* walk the binary columns */
+            for (j = 0; j < cells; j++)
+            {
+                if (clock->true_binary)
+                {
+                    /* skip the columns we don't draw */
+                    if (i == 0 && j == 0)
+                        continue;
+
+                    /* decimal representation of this cell */
+                    decimal = decimal_tb[j];
+
+                    /* center of the arc */
+                    x = cw * (j + 0.5) + widget->allocation.x;
+                    y = ch * (i + 0.5) + widget->allocation.y;
+                }
+                else /* bcd clock */
+                {
+                    /* skip the columns we don't draw */
+                    if ((j == 0) || (i == 0 && j == 1))
+                        continue;
+
+                    /* decimal representation of this cell */
+                    decimal = decimal_bcd[j];
+
+                    /* center of the arc */
+                    x = cw * (i * 2 + (j < 4 ? 0 : 1) + 0.5) + widget->allocation.x;
+                    y = ch * ((j >= 4 ? j - 4 : j) + 0.5) + widget->allocation.y;
+                }
+
+                /* if this binary values 'fits' in the time */
+                if (ticks >= decimal)
+                {
+                    /* extract the decimal value from the time */
+                    ticks -= decimal;
+
+                    /* set the active color */
+                    gdk_cairo_set_source_color (cr, &active);
+                }
+                else
+                {
+                    /* set the inactive color */
+                    gdk_cairo_set_source_color (cr, &inactive);
+                }
+
+                /* draw the arc */
+                cairo_move_to (cr, x, y);
+                cairo_arc (cr, x, y, radius, 0, 2 * M_PI);
+                cairo_close_path (cr);
+
+                /* fill the arc */
+                cairo_fill (cr);
+            }
+        }
+
+        /* cleanup */
+        cairo_destroy (cr);
+    }
+
+    return FALSE;
+}
+
+
+
+GtkWidget *
+xfce_clock_binary_new (void)
+{
+    return g_object_new (XFCE_CLOCK_TYPE_BINARY, NULL);
+}
+
+
+
+gboolean
+xfce_clock_binary_update (gpointer user_data)
+{
+    GtkWidget *widget = GTK_WIDGET (user_data);
+
+    /* update if the widget if visible */
+    if (G_LIKELY (GTK_WIDGET_VISIBLE (widget)))
+        gtk_widget_queue_draw (widget);
+
+    return TRUE;
+}


Property changes on: xfce4-panel/trunk/plugins/clock/clock-binary.c
___________________________________________________________________
Name: keywords
   + Id

Added: xfce4-panel/trunk/plugins/clock/clock-binary.h
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock-binary.h	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock-binary.h	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,43 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifndef __CLOCK_BINARY_H__
+#define __CLOCK_BINARY_H__
+
+G_BEGIN_DECLS
+
+typedef struct _XfceClockBinaryClass XfceClockBinaryClass;
+typedef struct _XfceClockBinary      XfceClockBinary;
+
+#define XFCE_CLOCK_TYPE_BINARY            (xfce_clock_binary_get_type ())
+#define XFCE_CLOCK_BINARY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_CLOCK_TYPE_BINARY, XfceClockBinary))
+#define XFCE_CLOCK_BINARY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_CLOCK_TYPE_BINARY, XfceClockBinaryClass))
+#define XFCE_CLOCK_IS_BINARY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_CLOCK_TYPE_BINARY))
+#define XFCE_CLOCK_IS_BINARY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_CLOCK_TYPE_BINARY))
+#define XFCE_CLOCK_BINARY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_CLOCK_TYPE_BINARY, XfceClockBinaryClass))
+
+GType      xfce_clock_binary_get_type (void) G_GNUC_CONST  G_GNUC_INTERNAL;
+
+GtkWidget *xfce_clock_binary_new      (void) G_GNUC_MALLOC G_GNUC_INTERNAL;
+
+gboolean   xfce_clock_binary_update   (gpointer user_data) G_GNUC_INTERNAL;
+
+G_END_DECLS
+
+#endif /* !__CLOCK_BINARY_H__ */


Property changes on: xfce4-panel/trunk/plugins/clock/clock-binary.h
___________________________________________________________________
Name: keywords
   + Id

Added: xfce4-panel/trunk/plugins/clock/clock-dialog.c
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock-dialog.c	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock-dialog.c	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,543 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4panel/xfce-panel-plugin.h>
+#include <libxfcegui4/xfce-titled-dialog.h>
+#include <libxfcegui4/xfce_framebox.h>
+#include <libxfcegui4/xfce-widget-helpers.h>
+
+#include "clock.h"
+#include "clock-dialog.h"
+
+
+
+/** default formats **/
+static const gchar *tooltip_formats[] = {
+    DEFAULT_TOOLTIP_FORMAT,
+    "%x",
+    NULL
+};
+
+static const gchar *digital_formats[] = {
+    DEFAULT_DIGITAL_FORMAT,
+    "%T",
+    "%r",
+    "%R %p",
+    NULL
+};
+
+
+
+/** prototypes **/
+void xfce_clock_dialog_options (ClockPlugin *clock);
+
+
+
+static void
+xfce_clock_dialog_reload_settings (ClockPlugin *clock)
+{
+    if (G_LIKELY (clock->widget))
+    {
+        /* save the settings */
+        xfce_clock_widget_update_settings (clock);
+
+        /* make sure the plugin sets it's size again */
+        gtk_widget_queue_resize (clock->widget);
+
+        /* run a direct update */
+        (clock->update) (clock->widget);
+
+        /* reschedule the timeout */
+        xfce_clock_widget_sync (clock);
+    }
+}
+
+
+
+static void
+xfce_clock_dialog_mode_changed (GtkComboBox *combo,
+                                ClockPlugin *clock)
+{
+    /* set the new mode */
+    clock->mode = gtk_combo_box_get_active (combo);
+
+    /* update the plugin widget */
+    if (G_LIKELY (clock->widget))
+    {
+        /* set the new clock mode */
+        xfce_clock_widget_set_mode (clock);
+
+        /* update the settings */
+        xfce_clock_dialog_reload_settings (clock);
+
+        /* update the plugin size */
+        xfce_clock_plugin_set_size (clock, xfce_panel_plugin_get_size (clock->plugin));
+    }
+
+    /* update the dialog */
+    xfce_clock_dialog_options (clock);
+}
+
+
+
+static void
+xfce_clock_dialog_show_frame_toggled (GtkToggleButton *button,
+                                      ClockPlugin     *clock)
+{
+    /* set frame mode */
+    clock->show_frame = gtk_toggle_button_get_active (button);
+
+    /* change frame shadow */
+    gtk_frame_set_shadow_type (GTK_FRAME (clock->frame), clock->show_frame ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
+}
+
+
+
+static void
+xfce_clock_dialog_tooltip_format_changed (GtkComboBox *combo,
+                                          ClockPlugin *clock)
+{
+    gint       index;
+    GtkWidget *entry;
+
+    /* stop running timeout */
+    if (clock->tooltip_timeout_id)
+    {
+        g_source_remove (clock->tooltip_timeout_id);
+        clock->tooltip_timeout_id = 0;
+    }
+
+    /* get index of selected item */
+    index = gtk_combo_box_get_active (combo);
+
+    /* get the custom entry */
+    entry = g_object_get_data (G_OBJECT (combo), I_("entry"));
+
+    /* set one of the default formats */
+    if (index < G_N_ELEMENTS (tooltip_formats))
+    {
+        /* hide the entry */
+        gtk_widget_hide (entry);
+
+        /* cleanup old format */
+        g_free (clock->tooltip_format);
+
+        /* set new format */
+        clock->tooltip_format = g_strdup (tooltip_formats[index]);
+
+        /* restart the tooltip timeout */
+        xfce_clock_tooltip_sync (clock);
+    }
+    else
+    {
+        /* set string */
+        gtk_entry_set_text (GTK_ENTRY (entry), clock->tooltip_format);
+
+        /* show */
+        gtk_widget_show (entry);
+    }
+}
+
+
+
+static void
+xfce_clock_dialog_tooltip_entry_changed (GtkEntry    *entry,
+                                         ClockPlugin *clock)
+{
+    /* cleanup old format */
+    g_free (clock->tooltip_format);
+
+    /* set new format */
+    clock->tooltip_format = g_strdup (gtk_entry_get_text (entry));
+
+    /* restart the tooltip timeout */
+    xfce_clock_tooltip_sync (clock);
+}
+
+
+
+static void
+xfce_clock_dialog_show_seconds_toggled (GtkToggleButton *button,
+                                        ClockPlugin     *clock)
+{
+    /* whether we show seconds */
+    clock->show_seconds = gtk_toggle_button_get_active (button);
+
+    /* update the clock */
+    xfce_clock_dialog_reload_settings (clock);
+}
+
+
+
+static void
+xfce_clock_dialog_show_military_toggled (GtkToggleButton *button,
+                                      ClockPlugin     *clock)
+{
+    /* whether we show a 24h clock */
+    clock->show_military = gtk_toggle_button_get_active (button);
+
+    /* update the clock */
+    xfce_clock_dialog_reload_settings (clock);
+}
+
+
+
+static void
+xfce_clock_dialog_show_meridiem_toggled (GtkToggleButton *button,
+                                         ClockPlugin     *clock)
+{
+    /* whether we show am/pm */
+    clock->show_meridiem = gtk_toggle_button_get_active (button);
+
+    /* update the clock */
+    xfce_clock_dialog_reload_settings (clock);
+}
+
+
+
+static void
+xfce_clock_dialog_true_binary_toggled (GtkToggleButton *button,
+                                       ClockPlugin     *clock)
+{
+    /* whether we this is a true binary clock */
+    clock->true_binary = gtk_toggle_button_get_active (button);
+
+    /* update the clock */
+    xfce_clock_dialog_reload_settings (clock);
+}
+
+
+
+static void
+xfce_clock_dialog_digital_format_changed (GtkComboBox *combo,
+                                          ClockPlugin *clock)
+{
+    gint       index;
+    GtkWidget *entry;
+
+    /* get index of selected item */
+    index = gtk_combo_box_get_active (combo);
+
+    /* get the custom entry */
+    entry = g_object_get_data (G_OBJECT (combo), I_("entry"));
+
+    /* set one of the default formats */
+    if (index < G_N_ELEMENTS (digital_formats))
+    {
+        /* hide the entry */
+        gtk_widget_hide (entry);
+
+        /* cleanup old format */
+        g_free (clock->digital_format);
+
+        /* set new format */
+        clock->digital_format = g_strdup (digital_formats[index]);
+
+        /* reload settings */
+        xfce_clock_dialog_reload_settings (clock);
+    }
+    else
+    {
+        /* set string */
+        gtk_entry_set_text (GTK_ENTRY (entry), clock->digital_format);
+
+        /* show */
+        gtk_widget_show (entry);
+    }
+}
+
+
+
+static void
+xfce_clock_dialog_digital_entry_changed (GtkEntry    *entry,
+                                         ClockPlugin *clock)
+{
+    /* cleanup old format */
+    g_free (clock->digital_format);
+
+    /* set new format */
+    clock->digital_format = g_strdup (gtk_entry_get_text (entry));
+
+    /* reload settings */
+    xfce_clock_dialog_reload_settings (clock);
+}
+
+
+
+static gboolean
+xfce_clock_dialog_row_separator_func (GtkTreeModel *model,
+                                      GtkTreeIter  *iter,
+                                      gpointer      user_data)
+{
+    gchar    *title;
+    gboolean  result = FALSE;
+
+    gtk_tree_model_get (model, iter, 0, &title, -1);
+    if (G_LIKELY (title != NULL))
+    {
+        result = (strcmp (title, "-") == 0);
+
+        /* cleanup */
+        g_free (title);
+    }
+
+    return result;
+}
+
+
+
+static gboolean
+xfce_clock_dialog_append_combobox_formats (GtkComboBox *combo,
+                                           const gchar *formats[],
+                                           const gchar *current_format)
+{
+    gint       i;
+    time_t     now = time (0);
+    struct tm  tm;
+    gchar     *string;
+    gboolean   has_active = FALSE;
+
+    /* get the local time */
+    localtime_r (&now, &tm);
+
+    for (i = 0; formats[i] != NULL; i++)
+    {
+        /* insert user-redable string */
+        string = xfce_clock_util_strdup_strftime (formats[i], &tm);
+        gtk_combo_box_append_text (GTK_COMBO_BOX (combo), string);
+        g_free (string);
+
+        /* check if this is the active string */
+        if (!has_active && current_format && strcmp (formats[i], current_format) == 0)
+        {
+            gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i);
+            has_active = TRUE;
+        }
+    }
+
+    /* insert the separator and the custom line */
+    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "-");
+    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Custom"));
+
+    if (!has_active)
+    {
+        if (!current_format)
+        {
+            has_active = TRUE;
+            i = -1;
+        }
+
+        /* select item */
+        gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i + 1);
+    }
+
+    return has_active;
+}
+
+
+
+static void
+xfce_clock_dialog_response (GtkWidget   *dialog,
+                            gint         response,
+                            ClockPlugin *clock)
+{
+    /* destroy the dialog */
+    gtk_widget_destroy (dialog);
+
+    /* remove links */
+    g_object_set_data (G_OBJECT (clock->plugin), I_("configure-dialog"), NULL);
+    g_object_set_data (G_OBJECT (clock->plugin), I_("configure-dialog-bin"), NULL);
+
+    /* unblock the plugin menu */
+    xfce_panel_plugin_unblock_menu (clock->plugin);
+}
+
+
+
+void
+xfce_clock_dialog_options (ClockPlugin *clock)
+{
+    GtkWidget *button, *bin, *vbox, *combo, *entry;
+    gboolean   has_active;
+
+    /* get the frame bin */
+    bin = g_object_get_data (G_OBJECT (clock->plugin), I_("configure-dialog-bin"));
+    gtk_container_foreach (GTK_CONTAINER (bin), (GtkCallback) gtk_widget_destroy, NULL);
+
+    /* main vbox */
+    vbox = gtk_vbox_new (FALSE, 8);
+    gtk_container_add (GTK_CONTAINER (bin), vbox);
+    gtk_widget_show (vbox);
+
+    if (clock->mode == XFCE_CLOCK_ANALOG || clock->mode == XFCE_CLOCK_BINARY || clock->mode == XFCE_CLOCK_LCD)
+    {
+        button = gtk_check_button_new_with_mnemonic (_("Display _seconds"));
+        gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clock->show_seconds);
+        g_signal_connect (button, "toggled", G_CALLBACK (xfce_clock_dialog_show_seconds_toggled), clock);
+        gtk_widget_show (button);
+    }
+
+    if (clock->mode == XFCE_CLOCK_LCD)
+    {
+        button = gtk_check_button_new_with_mnemonic (_("Use 24-_hour clock"));
+        gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clock->show_military);
+        g_signal_connect (button, "toggled", G_CALLBACK (xfce_clock_dialog_show_military_toggled), clock);
+        gtk_widget_show (button);
+
+        button = gtk_check_button_new_with_mnemonic (_("Sho_w AM/PM"));
+        gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clock->show_meridiem);
+        g_signal_connect (button, "toggled", G_CALLBACK (xfce_clock_dialog_show_meridiem_toggled), clock);
+        gtk_widget_show (button);
+    }
+
+    if (clock->mode == XFCE_CLOCK_BINARY)
+    {
+        button = gtk_check_button_new_with_mnemonic (_("True _binary clock"));
+        gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clock->true_binary);
+        g_signal_connect (button, "toggled", G_CALLBACK (xfce_clock_dialog_true_binary_toggled), clock);
+        gtk_widget_show (button);
+    }
+
+    if (clock->mode == XFCE_CLOCK_DIGITAL)
+    {
+        combo = gtk_combo_box_new_text ();
+        gtk_box_pack_start (GTK_BOX (vbox), combo, TRUE, TRUE, 0);
+        gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo), xfce_clock_dialog_row_separator_func, NULL, NULL);
+        has_active = xfce_clock_dialog_append_combobox_formats (GTK_COMBO_BOX (combo), digital_formats, clock->digital_format);
+        g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (xfce_clock_dialog_digital_format_changed), clock);
+        gtk_widget_show (combo);
+
+        entry = gtk_entry_new_with_max_length (BUFFER_SIZE-1);
+        gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
+        g_object_set_data (G_OBJECT (combo), I_("entry"), entry);
+        if (!has_active)
+        {
+            gtk_widget_show (entry);
+            gtk_entry_set_text (GTK_ENTRY (entry), clock->digital_format);
+        }
+        g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK (xfce_clock_dialog_digital_entry_changed), clock);
+    }
+}
+
+
+
+void
+xfce_clock_dialog_show (ClockPlugin *clock)
+{
+    GtkWidget *dialog, *dialog_vbox;
+    GtkWidget *frame, *bin, *vbox, *combo;
+    GtkWidget *button, *entry;
+    gboolean   has_active;
+
+    /* block the right-click menu */
+    xfce_panel_plugin_block_menu (clock->plugin);
+
+    /* create dialog */
+    dialog = xfce_titled_dialog_new_with_buttons (_("Clock"), NULL,
+                                                  GTK_DIALOG_NO_SEPARATOR,
+                                                  GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+                                                  NULL);
+    gtk_window_set_screen (GTK_WINDOW (dialog), gtk_widget_get_screen (GTK_WIDGET (clock->plugin)));
+    gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+    gtk_window_set_icon_name (GTK_WINDOW (dialog), "xfce4-settings");
+    gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
+    g_object_set_data (G_OBJECT (clock->plugin), I_("configure-dialog"), dialog);
+    g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (xfce_clock_dialog_response), clock);
+
+    /* get dialog vbox */
+    dialog_vbox = GTK_DIALOG (dialog)->vbox;
+
+    /* appearance settings */
+    frame = xfce_create_framebox (_("Appearance"), &bin);
+    gtk_box_pack_start (GTK_BOX (dialog_vbox), frame, FALSE, TRUE, 0);
+    gtk_widget_show (frame);
+
+    vbox = gtk_vbox_new (FALSE, 8);
+    gtk_container_add (GTK_CONTAINER (bin), vbox);
+    gtk_widget_show (vbox);
+
+    combo = gtk_combo_box_new_text ();
+    gtk_box_pack_start (GTK_BOX (vbox), combo, TRUE, TRUE, 0);
+    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Analog"));
+    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Binary"));
+    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Digital"));
+    gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("LCD"));
+    gtk_combo_box_set_active (GTK_COMBO_BOX (combo), clock->mode);
+    g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (xfce_clock_dialog_mode_changed), clock);
+    gtk_widget_show (combo);
+
+    button = gtk_check_button_new_with_mnemonic (_("Show _frame"));
+    gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clock->show_frame);
+    g_signal_connect (button, "toggled", G_CALLBACK (xfce_clock_dialog_show_frame_toggled), clock);
+    gtk_widget_show (button);
+
+    /* tooltip settings */
+    frame = xfce_create_framebox (_("Tooltip Format"), &bin);
+    gtk_box_pack_start (GTK_BOX (dialog_vbox), frame, FALSE, TRUE, 0);
+    gtk_widget_show (frame);
+
+    vbox = gtk_vbox_new (FALSE, 8);
+    gtk_container_add (GTK_CONTAINER (bin), vbox);
+    gtk_widget_show (vbox);
+
+    combo = gtk_combo_box_new_text ();
+    gtk_box_pack_start (GTK_BOX (vbox), combo, TRUE, TRUE, 0);
+    gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo), xfce_clock_dialog_row_separator_func, NULL, NULL);
+    has_active = xfce_clock_dialog_append_combobox_formats (GTK_COMBO_BOX (combo), tooltip_formats, clock->tooltip_format);
+    g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (xfce_clock_dialog_tooltip_format_changed), clock);
+    gtk_widget_show (combo);
+
+    entry = gtk_entry_new_with_max_length (BUFFER_SIZE-1);
+    gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
+    g_object_set_data (G_OBJECT (combo), I_("entry"), entry);
+    if (!has_active)
+    {
+        gtk_widget_show (entry);
+        gtk_entry_set_text (GTK_ENTRY (entry), clock->tooltip_format);
+    }
+    g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK (xfce_clock_dialog_tooltip_entry_changed), clock);
+
+    /* clock settings */
+    frame = xfce_create_framebox (_("Clock Options"), &bin);
+    gtk_box_pack_start (GTK_BOX (dialog_vbox), frame, FALSE, TRUE, 0);
+    g_object_set_data (G_OBJECT (clock->plugin), I_("configure-dialog-bin"), bin);
+    gtk_widget_show (frame);
+
+    /* add the potions */
+    xfce_clock_dialog_options (clock);
+
+    /* show the dialog */
+    gtk_widget_show (dialog);
+}
+


Property changes on: xfce4-panel/trunk/plugins/clock/clock-dialog.c
___________________________________________________________________
Name: keywords
   + Id

Added: xfce4-panel/trunk/plugins/clock/clock-dialog.h
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock-dialog.h	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock-dialog.h	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,31 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifndef __CLOCK_DIALOG_H__
+#define __CLOCK_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void xfce_clock_dialog_show (ClockPlugin *clock) G_GNUC_INTERNAL;
+
+G_END_DECLS
+
+#endif /* !__CLOCK_DIALOG_H__ */


Property changes on: xfce4-panel/trunk/plugins/clock/clock-dialog.h
___________________________________________________________________
Name: keywords
   + Id

Added: xfce4-panel/trunk/plugins/clock/clock-digital.c
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock-digital.c	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock-digital.c	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,224 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "clock.h"
+#include "clock-digital.h"
+
+
+
+/* class functions */
+static void xfce_clock_digital_class_init   (XfceClockDigitalClass *klass);
+static void xfce_clock_digital_init         (XfceClockDigital      *clock);
+static void xfce_clock_digital_finalize     (GObject               *object);
+static void xfce_clock_digital_set_property (GObject               *object,
+                                             guint                  prop_id,
+                                             const GValue          *value,
+                                             GParamSpec            *pspec);
+static void xfce_clock_digital_get_property (GObject               *object,
+                                             guint                  prop_id,
+                                             GValue                *value,
+                                             GParamSpec            *pspec);
+
+
+
+enum
+{
+    PROP_0,
+    PROP_DIGITAL_FORMAT
+};
+
+struct _XfceClockDigitalClass
+{
+    GtkLabelClass __parent__;
+};
+
+struct _XfceClockDigital
+{
+    GtkLabel  __parent__;
+
+    /* current clock format */
+    gchar    *format;
+};
+
+
+
+static GObjectClass *xfce_clock_digital_parent_class;
+
+
+
+GType
+xfce_clock_digital_get_type (void)
+{
+    static GType type = G_TYPE_INVALID;
+
+    if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+        type = g_type_register_static_simple (GTK_TYPE_LABEL,
+                                              I_("XfceClockDigital"),
+                                              sizeof (XfceClockDigitalClass),
+                                              (GClassInitFunc) xfce_clock_digital_class_init,
+                                              sizeof (XfceClockDigital),
+                                              (GInstanceInitFunc) xfce_clock_digital_init,
+                                              0);
+    }
+
+    return type;
+}
+
+
+
+static void
+xfce_clock_digital_class_init (XfceClockDigitalClass *klass)
+{
+    GObjectClass *gobject_class;
+
+    xfce_clock_digital_parent_class = g_type_class_peek_parent (klass);
+
+    gobject_class = G_OBJECT_CLASS (klass);
+    gobject_class->finalize = xfce_clock_digital_finalize;
+    gobject_class->set_property = xfce_clock_digital_set_property;
+    gobject_class->get_property = xfce_clock_digital_get_property;
+
+    /**
+     * Digital clock format
+     **/
+    g_object_class_install_property (gobject_class,
+                                     PROP_DIGITAL_FORMAT,
+                                     g_param_spec_string ("digital-format", "digital-format", "digital-format",
+                                                          NULL, PANEL_PARAM_READWRITE));
+}
+
+
+
+static void
+xfce_clock_digital_init (XfceClockDigital *clock)
+{
+    /* init */
+    clock->format = NULL;
+}
+
+
+
+static void
+xfce_clock_digital_finalize (GObject *object)
+{
+    XfceClockDigital *clock = XFCE_CLOCK_DIGITAL (object);
+
+    /* cleanup */
+    g_free (clock->format);
+
+    (*G_OBJECT_CLASS (xfce_clock_digital_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfce_clock_digital_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
+{
+    XfceClockDigital *clock = XFCE_CLOCK_DIGITAL (object);
+
+    switch (prop_id)
+    {
+        case PROP_DIGITAL_FORMAT:
+            /* cleanup */
+            g_free (clock->format);
+
+            /* set new format */
+            clock->format = g_value_dup_string (value);
+
+            /* update the widget */
+            xfce_clock_digital_update (clock);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+    }
+}
+
+
+
+static void
+xfce_clock_digital_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+    XfceClockDigital *clock = XFCE_CLOCK_DIGITAL (object);
+
+    switch (prop_id)
+    {
+        case PROP_DIGITAL_FORMAT:
+            g_value_set_string (value,clock->format);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+    }
+}
+
+
+
+GtkWidget *
+xfce_clock_digital_new (void)
+{
+    return g_object_new (XFCE_CLOCK_TYPE_DIGITAL, NULL);
+}
+
+
+
+gboolean
+xfce_clock_digital_update (gpointer user_data)
+{
+    XfceClockDigital *clock = XFCE_CLOCK_DIGITAL (user_data);
+    gchar            *string;
+    time_t            now = time (0);
+    struct tm         tm;
+
+    g_return_val_if_fail (XFCE_CLOCK_IS_DIGITAL (clock), FALSE);
+    g_return_val_if_fail (clock->format != NULL, FALSE);
+
+    /* get the local time */
+    localtime_r (&now, &tm);
+
+    /* get the string */
+    string = xfce_clock_util_strdup_strftime (clock->format, &tm);
+
+    /* set the new label */
+    gtk_label_set_text (GTK_LABEL (clock), string);
+
+    /* cleanup */
+    g_free (string);
+
+    return TRUE;
+}


Property changes on: xfce4-panel/trunk/plugins/clock/clock-digital.c
___________________________________________________________________
Name: keywords
   + Id

Added: xfce4-panel/trunk/plugins/clock/clock-digital.h
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock-digital.h	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock-digital.h	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,43 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifndef __CLOCK_DIGITAL_H__
+#define __CLOCK_DIGITAL_H__
+
+G_BEGIN_DECLS
+
+typedef struct _XfceClockDigitalClass XfceClockDigitalClass;
+typedef struct _XfceClockDigital      XfceClockDigital;
+
+#define XFCE_CLOCK_TYPE_DIGITAL            (xfce_clock_digital_get_type ())
+#define XFCE_CLOCK_DIGITAL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_CLOCK_TYPE_DIGITAL, XfceClockDigital))
+#define XFCE_CLOCK_DIGITAL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_CLOCK_TYPE_DIGITAL, XfceClockDigitalClass))
+#define XFCE_CLOCK_IS_DIGITAL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_CLOCK_TYPE_DIGITAL))
+#define XFCE_CLOCK_IS_DIGITAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_CLOCK_TYPE_DIGITAL))
+#define XFCE_CLOCK_DIGITAL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_CLOCK_TYPE_DIGITAL, XfceClockDigitalClass))
+
+GType        xfce_clock_digital_get_type (void) G_GNUC_CONST  G_GNUC_INTERNAL;
+
+GtkWidget   *xfce_clock_digital_new      (void) G_GNUC_MALLOC G_GNUC_INTERNAL;
+
+gboolean     xfce_clock_digital_update   (gpointer user_data) G_GNUC_INTERNAL;
+
+G_END_DECLS
+
+#endif /* !__CLOCK_DIGITAL_H__ */


Property changes on: xfce4-panel/trunk/plugins/clock/clock-digital.h
___________________________________________________________________
Name: keywords
   + Id

Added: xfce4-panel/trunk/plugins/clock/clock-lcd.c
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock-lcd.c	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock-lcd.c	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,523 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+
+#include <gtk/gtk.h>
+#include <cairo/cairo.h>
+
+#include "clock.h"
+#include "clock-lcd.h"
+
+#define RELATIVE_SPACE 0.10
+
+/* the height varies between 12px -> 122px. in this range there is
+   a ratio from 1.0 -> 0.5 */
+#define HEIGHT_RATIO(x) (1.00 - (((x) - 12) * (0.50 / (122 -12))))
+
+
+
+/* prototypes */
+static void      xfce_clock_lcd_class_init   (XfceClockLcdClass *klass);
+static void      xfce_clock_lcd_init         (XfceClockLcd      *clock);
+static void      xfce_clock_lcd_finalize     (GObject           *object);
+static void      xfce_clock_lcd_set_property (GObject           *object,
+                                              guint              prop_id,
+                                              const GValue      *value,
+                                              GParamSpec        *pspec);
+static void      xfce_clock_lcd_get_property (GObject           *object,
+                                              guint              prop_id,
+                                              GValue            *value,
+                                              GParamSpec        *pspec);
+static void      xfce_clock_lcd_size_request (GtkWidget         *widget,
+			                                  GtkRequisition    *requisition);
+static gboolean  xfce_clock_lcd_expose_event (GtkWidget         *widget,
+                                              GdkEventExpose    *event);
+static gdouble   xfce_clock_lcd_get_ratio    (XfceClockLcd      *clock);
+static gdouble   xfce_clock_lcd_draw_dots    (cairo_t           *cr,
+                                              gdouble            size,
+                                              gdouble            offset_x,
+                                              gdouble            offset_y);
+static gdouble   xfce_clock_lcd_draw_digit   (cairo_t           *cr,
+                                              guint              number,
+                                              gdouble            size,
+                                              gdouble            offset_x,
+                                              gdouble            offset_y);
+
+
+
+enum
+{
+    PROP_0,
+    PROP_SHOW_SECONDS,
+    PROP_SHOW_MILITARY,
+    PROP_SHOW_MERIDIEM
+};
+
+struct _XfceClockLcdClass
+{
+    GtkImageClass __parent__;
+};
+
+struct _XfceClockLcd
+{
+    GtkImage __parent__;
+
+    /* whether we show seconds */
+    guint    show_seconds : 1;
+
+    /* whether it's a 24h clock */
+    guint    show_military : 1;
+
+    /* whether we display am/pm */
+    guint    show_meridiem : 1;
+};
+
+
+
+static GObjectClass *xfce_clock_lcd_parent_class;
+
+
+
+GType
+xfce_clock_lcd_get_type (void)
+{
+    static GType type = G_TYPE_INVALID;
+
+    if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+        type = g_type_register_static_simple (GTK_TYPE_IMAGE,
+                                              I_("XfceClockLcd"),
+                                              sizeof (XfceClockLcdClass),
+                                              (GClassInitFunc) xfce_clock_lcd_class_init,
+                                              sizeof (XfceClockLcd),
+                                              (GInstanceInitFunc) xfce_clock_lcd_init,
+                                              0);
+    }
+
+    return type;
+}
+
+
+
+static void
+xfce_clock_lcd_class_init (XfceClockLcdClass *klass)
+{
+    GObjectClass   *gobject_class;
+    GtkWidgetClass *gtkwidget_class;
+
+    xfce_clock_lcd_parent_class = g_type_class_peek_parent (klass);
+
+    gobject_class = G_OBJECT_CLASS (klass);
+    gobject_class->finalize = xfce_clock_lcd_finalize;
+    gobject_class->set_property = xfce_clock_lcd_set_property;
+    gobject_class->get_property = xfce_clock_lcd_get_property;
+
+    gtkwidget_class = GTK_WIDGET_CLASS (klass);
+    gtkwidget_class->size_request = xfce_clock_lcd_size_request;
+    gtkwidget_class->expose_event = xfce_clock_lcd_expose_event;
+
+    /**
+     * Whether we display seconds
+     **/
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_SECONDS,
+                                     g_param_spec_boolean ("show-seconds", "show-seconds", "show-seconds",
+                                                           FALSE,
+                                                           PANEL_PARAM_READWRITE));
+
+    /**
+     * Whether we show a 24h clock
+     **/
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_MILITARY,
+                                     g_param_spec_boolean ("show-military", "show-military", "show-military",
+                                                           FALSE,
+                                                           PANEL_PARAM_READWRITE));
+
+    /**
+     * Whether we show am or pm
+     **/
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_MERIDIEM,
+                                     g_param_spec_boolean ("show-meridiem", "show-meridiem", "show-meridiem",
+                                                           TRUE,
+                                                           PANEL_PARAM_READWRITE));
+}
+
+
+
+static void
+xfce_clock_lcd_init (XfceClockLcd *clock)
+{
+    /* init */
+    clock->show_seconds = FALSE;
+    clock->show_meridiem = FALSE;
+    clock->show_military = TRUE;
+}
+
+
+
+static void
+xfce_clock_lcd_finalize (GObject *object)
+{
+    (*G_OBJECT_CLASS (xfce_clock_lcd_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfce_clock_lcd_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+    XfceClockLcd *clock = XFCE_CLOCK_LCD (object);
+
+    switch (prop_id)
+    {
+        case PROP_SHOW_SECONDS:
+            clock->show_seconds = g_value_get_boolean (value);
+            break;
+
+        case PROP_SHOW_MILITARY:
+            clock->show_military = g_value_get_boolean (value);
+            break;
+
+        case PROP_SHOW_MERIDIEM:
+            clock->show_meridiem = g_value_get_boolean (value);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+    }
+}
+
+
+
+static void
+xfce_clock_lcd_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+    XfceClockLcd *clock = XFCE_CLOCK_LCD (object);
+
+    switch (prop_id)
+    {
+        case PROP_SHOW_SECONDS:
+            g_value_set_boolean (value, clock->show_seconds);
+            break;
+
+        case PROP_SHOW_MILITARY:
+            g_value_set_boolean (value, clock->show_military);
+            break;
+
+        case PROP_SHOW_MERIDIEM:
+            g_value_set_boolean (value, clock->show_meridiem);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+    }
+}
+
+
+
+static void
+xfce_clock_lcd_size_request (GtkWidget      *widget,
+			                 GtkRequisition *requisition)
+{
+    gint    width, height;
+    gdouble ratio;
+
+    /* get the current widget size */
+    gtk_widget_get_size_request (widget, &width, &height);
+
+    /* get the width:height ratio */
+    ratio = xfce_clock_lcd_get_ratio (XFCE_CLOCK_LCD (widget));
+
+    if (width == -1)
+    {
+        requisition->height = height;
+        requisition->width = height * ratio * HEIGHT_RATIO (height);
+    }
+    else
+    {
+        requisition->width = width;
+        requisition->height = width / (ratio - (2 * 0.1));
+    }
+}
+
+
+
+static gboolean
+xfce_clock_lcd_expose_event (GtkWidget      *widget,
+                             GdkEventExpose *event)
+{
+    XfceClockLcd *clock = XFCE_CLOCK_LCD (widget);
+    cairo_t      *cr;
+    gdouble       offset_x, offset_y;
+    gint          ticks, i;
+    gdouble       size;
+    time_t        now = time (0);
+    struct tm     tm;
+
+    g_return_val_if_fail (XFCE_CLOCK_IS_LCD (clock), FALSE);
+
+    /* widget sizes */
+    if (widget->allocation.width >= widget->allocation.height)
+        size = widget->allocation.height * HEIGHT_RATIO (widget->allocation.height);
+    else
+        size = widget->allocation.height;
+
+    /* begin offsets */
+    offset_x = widget->allocation.x + size * RELATIVE_SPACE;
+    offset_y = widget->allocation.y + (widget->allocation.height - size) / 2;
+
+    /* get the cairo context */
+    cr = gdk_cairo_create (widget->window);
+
+    if (G_LIKELY (cr != NULL))
+    {
+        /* get the local time */
+        localtime_r (&now, &tm);
+
+        /* draw the hours */
+        ticks = tm.tm_hour;
+
+        /* convert 24h clock to 12h clock */
+        if (!clock->show_military && ticks > 12)
+            ticks -= 12;
+
+        if (ticks >= 10)
+        {
+            /* draw the number and increase the offset*/
+            offset_x = xfce_clock_lcd_draw_digit (cr, ticks >= 20 ? 2 : 8, size, offset_x, offset_y);
+        }
+
+        /* draw the other number of the hour and increase the offset */
+        offset_x = xfce_clock_lcd_draw_digit (cr, ticks % 10, size, offset_x, offset_y);
+
+        for (i = 0; i < 2; i++)
+        {
+            /* get the time */
+            if (i == 0)
+            {
+                /* get the minutes */
+                ticks = tm.tm_min;
+            }
+            else
+            {
+                /* leave when we don't want seconds */
+                if (!clock->show_seconds)
+                    break;
+
+                /* get the seconds */
+                ticks = tm.tm_sec;
+            }
+
+            /* draw the dots */
+            offset_x = xfce_clock_lcd_draw_dots (cr, size, offset_x, offset_y);
+
+            /* draw the first digit */
+            offset_x = xfce_clock_lcd_draw_digit (cr, (ticks - (ticks % 10)) / 10, size, offset_x, offset_y);
+
+            /* draw the second digit */
+            offset_x = xfce_clock_lcd_draw_digit (cr, ticks % 10, size, offset_x, offset_y);
+        }
+
+        if (clock->show_meridiem)
+        {
+            /* am or pm? */
+            ticks = tm.tm_hour >= 12 ? 11 : 10;
+
+            /* draw the digit */
+            offset_x = xfce_clock_lcd_draw_digit (cr, ticks, size, offset_x, offset_y);
+        }
+
+        /* cleanup */
+        cairo_destroy (cr);
+    }
+
+    return FALSE;
+}
+
+
+
+static gdouble
+xfce_clock_lcd_get_ratio (XfceClockLcd *clock)
+{
+    gdouble   ratio;
+    gint      ticks;
+    time_t    now = time (0);
+    struct tm tm;
+
+    /* get the local time */
+    localtime_r (&now, &tm);
+
+    /* hour + minutes */
+    ratio = (3 * 0.5 + 6 * RELATIVE_SPACE);
+
+    ticks = tm.tm_hour;
+
+    if (!clock->show_military && ticks > 12)
+        ticks -= 12;
+
+    if (ticks >= 10)
+        ratio += (0.5 + RELATIVE_SPACE);
+
+    if (clock->show_seconds)
+        ratio += (2 * 0.5 + 4 * RELATIVE_SPACE);
+
+    if (clock->show_meridiem)
+        ratio += (0.5 + RELATIVE_SPACE);
+
+    return ratio;
+}
+
+
+
+static gdouble
+xfce_clock_lcd_draw_dots (cairo_t *cr,
+                          gdouble  size,
+                          gdouble  offset_x,
+                          gdouble  offset_y)
+{
+    gint i;
+
+    /* draw the dots */
+    for (i = 1; i < 3; i++)
+        cairo_rectangle (cr, offset_x, offset_y + size * 0.30 * i,
+                         size * 0.10, size * 0.10);
+
+    /* fill the dots */
+    cairo_fill (cr);
+
+    return (offset_x + size * RELATIVE_SPACE * 2);
+}
+
+
+
+static gdouble
+xfce_clock_lcd_draw_digit (cairo_t *cr,
+                           guint    number,
+                           gdouble  size,
+                           gdouble  offset_x,
+                           gdouble  offset_y)
+{
+    gint    i, j;
+    gint    segment;
+    gdouble x, y;
+
+    g_return_val_if_fail (number >= 0 || number <= 11, offset_x);
+
+    /* coordicates to draw for each segment */
+    gdouble segments_x[][6] = { { 0.02, 0.48, 0.38, 0.12, -1.0, 0.00 },
+                                { 0.40, 0.50, 0.50, 0.40, -1.0, 0.00 },
+                                { 0.40, 0.50, 0.50, 0.40, -1.0, 0.00 },
+                                { 0.12, 0.38, 0.48, 0.02, -1.0, 0.00 },
+                                { 0.00, 0.10, 0.10, 0.00, -1.0, 0.00 },
+                                { 0.00, 0.10, 0.10, 0.00, -1.0, 0.00 },
+                                { 0.00, 0.10, 0.40, 0.50, 0.40, 0.10 } };
+    gdouble segments_y[][6] = { { 0.00, 0.00, 0.10, 0.10, -1.0, 0.00 },
+                                { 0.12, 0.02, 0.48, 0.43, -1.0, 0.00 },
+                                { 0.57, 0.52, 0.98, 0.88, -1.0, 0.00 },
+                                { 0.90, 0.90, 1.00, 1.00, -1.0, 0.00 },
+                                { 0.52, 0.57, 0.88, 0.98, -1.0, 0.00 },
+                                { 0.02, 0.12, 0.43, 0.48, -1.0, 0.00 },
+                                { 0.50, 0.45, 0.45, 0.50, 0.55, 0.55 } };
+
+    /* segment to draw for each number: 0, 1, ..., 9, A, P */
+    gint    numbers[][8] = { { 0, 1, 2, 3, 4, 5, -1 },
+                             { 1, 2, -1 },
+                             { 0, 1, 6, 4, 3, -1 },
+                             { 0, 1, 6, 2, 3, -1 },
+                             { 5, 6, 1, 2, -1 },
+                             { 0, 5, 6, 2, 3, -1 },
+                             { 0, 5, 4, 3, 2, 6, -1 },
+                             { 0, 1, 2, -1 },
+                             { 0, 1, 2, 3, 4, 5, 6, -1 },
+                             { 3, 2, 1, 0, 5, 6, -1 },
+                             { 4, 5, 0, 1, 2, 6, -1 },
+                             { 4, 5, 0, 1, 6, -1 } };
+
+    for (i = 0; i < 9; i++)
+    {
+        /* get the segment we're going to draw */
+        segment = numbers[number][i];
+
+        /* leave when there are no more segments left */
+        if (segment == -1)
+            break;
+
+        /* walk through the coordinate points */
+        for (j = 0; j < 6; j++)
+        {
+            /* get x and y coordinates for this point */
+            x = segments_x[segment][j] * size + offset_x;
+            y = segments_y[segment][j] * size + offset_y;
+
+            /* leave when there are no valid coordinates */
+            if (x < 0 || y < 0)
+                break;
+
+            if (j == 0)
+                cairo_move_to (cr, x, y);
+            else
+                cairo_line_to (cr, x, y);
+        }
+
+        /* close the line */
+        cairo_close_path (cr);
+    }
+
+    /* fill the segments */
+    cairo_fill (cr);
+
+    return (offset_x + size * (0.50 + RELATIVE_SPACE));
+}
+
+
+
+GtkWidget *
+xfce_clock_lcd_new (void)
+{
+    return g_object_new (XFCE_CLOCK_TYPE_LCD, NULL);
+}
+
+
+
+gboolean
+xfce_clock_lcd_update (gpointer user_data)
+{
+    GtkWidget *widget = GTK_WIDGET (user_data);
+
+    /* update if the widget if visible */
+    if (G_LIKELY (GTK_WIDGET_VISIBLE (widget)))
+        gtk_widget_queue_draw (widget);
+
+    return TRUE;
+}


Property changes on: xfce4-panel/trunk/plugins/clock/clock-lcd.c
___________________________________________________________________
Name: keywords
   + Id

Added: xfce4-panel/trunk/plugins/clock/clock-lcd.h
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock-lcd.h	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock-lcd.h	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,43 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifndef __CLOCK_LCD_H__
+#define __CLOCK_LCD_H__
+
+G_BEGIN_DECLS
+
+typedef struct _XfceClockLcdClass XfceClockLcdClass;
+typedef struct _XfceClockLcd      XfceClockLcd;
+
+#define XFCE_CLOCK_TYPE_LCD            (xfce_clock_lcd_get_type ())
+#define XFCE_CLOCK_LCD(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_CLOCK_TYPE_LCD, XfceClockLcd))
+#define XFCE_CLOCK_LCD_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_CLOCK_TYPE_LCD, XfceClockLcdClass))
+#define XFCE_CLOCK_IS_LCD(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_CLOCK_TYPE_LCD))
+#define XFCE_CLOCK_IS_LCD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_CLOCK_TYPE_LCD))
+#define XFCE_CLOCK_LCD_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_CLOCK_TYPE_LCD, XfceClockLcdClass))
+
+GType      xfce_clock_lcd_get_type (void) G_GNUC_CONST  G_GNUC_INTERNAL;
+
+GtkWidget *xfce_clock_lcd_new      (void) G_GNUC_MALLOC G_GNUC_INTERNAL;
+
+gboolean   xfce_clock_lcd_update   (gpointer user_data) G_GNUC_INTERNAL;
+
+G_END_DECLS
+
+#endif /* !__CLOCK_LCD_H__ */


Property changes on: xfce4-panel/trunk/plugins/clock/clock-lcd.h
___________________________________________________________________
Name: keywords
   + Id

Modified: xfce4-panel/trunk/plugins/clock/clock.c
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock.c	2007-07-06 13:14:53 UTC (rev 25889)
+++ xfce4-panel/trunk/plugins/clock/clock.c	2007-07-06 19:57:20 UTC (rev 25890)
@@ -1,627 +1,598 @@
-/* vim: set expandtab ts=8 sw=4: */
-
-/*  $Id$
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
  *
- *  Copyright © 2005 - 2007 The Xfce Development Team
+ * 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 free software; you can redistribute it and/or modify
- *  it under the terms of the GNU Library 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.
  *
- *  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 Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library 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.
- *
- *  Authors:
- *      Jasper Huijsmans <jasper at xfce.org>
- *      Jannis Pohlmann <info at sten-net.de>
+ * 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
  */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
 #ifdef HAVE_TIME_H
 #include <time.h>
 #endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
 
-#include <gtk/gtk.h>
-#include <gdk/gdkevents.h>
+#include "clock.h"
+#include "clock-analog.h"
+#include "clock-binary.h"
+#include "clock-dialog.h"
+#include "clock-digital.h"
+#include "clock-lcd.h"
 
-#include <libxfce4util/libxfce4util.h>
-#include <libxfcegui4/libxfcegui4.h>
-#include <libxfce4panel/xfce-panel-plugin.h>
 
-typedef struct
+
+/** prototypes **/
+static guint        xfce_clock_util_interval_from_format (const gchar     *format);
+static guint        xfce_clock_util_next_interval        (guint            timeout_interval);
+static gboolean     xfce_clock_tooltip_update            (gpointer         user_data);
+static gboolean     xfce_clock_tooltip_sync_timeout      (gpointer         user_data);
+static gboolean     xfce_clock_widget_sync_timeout       (gpointer         user_data);
+static ClockPlugin *xfce_clock_plugin_init               (XfcePanelPlugin *plugin);
+static void         xfce_clock_plugin_read               (ClockPlugin     *clock);
+static void         xfce_clock_plugin_write              (ClockPlugin     *clock);
+static void         xfce_clock_plugin_free               (ClockPlugin     *clock);
+static void         xfce_clock_plugin_construct          (XfcePanelPlugin *plugin);
+
+
+
+/** register the plugin **/
+XFCE_PANEL_PLUGIN_REGISTER_INTERNAL (xfce_clock_plugin_construct);
+
+
+
+/** utilities **/
+static guint
+xfce_clock_util_interval_from_format (const gchar *format)
 {
-    XfcePanelPlugin *plugin;
+    const gchar *p;
+    guint        interval = CLOCK_INTERVAL_HOUR;
 
-    GtkWidget *frame;
-    GtkWidget *clock;
-    GtkTooltips *tips;
+    g_return_val_if_fail (format != NULL, CLOCK_INTERVAL_HOUR);
 
-    int timeout_id;
-    int reschedule_id;
-    int screen_changed_id;
+    for (p = format; *p != '\0'; ++p)
+    {
+        if (p[0] == '%' && p[1] != '\0')
+        {
+            switch (*++p)
+            {
+                case 'c':
+                case 'N':
+                case 'r':
+                case 's':
+                case 'S':
+                case 'T':
+                case 'X':
+                    return CLOCK_INTERVAL_SECOND;
 
-    /* Settings */
-    int mode;
-    gboolean military;
-    gboolean ampm;
-    gboolean secs;
+                case 'M':
+                case 'R':
+                    interval = CLOCK_INTERVAL_MINUTE;
+                    break;
+            }
+        }
+    }
 
-    gboolean show_frame;
-    gint mday;
+    return interval;
 }
-Clock;
 
-typedef struct
+
+
+static guint
+xfce_clock_util_next_interval (guint timeout_interval)
 {
-    Clock *clock;
+    time_t    now = time (0);
+    struct tm tm;
+    GTimeVal  timeval;
+    guint     interval;
 
-    GtkWidget *cb_mode;
-    GtkWidget *cb_frame;
-    GtkWidget *cb_military;
-    GtkWidget *cb_ampm;
-    GtkWidget *cb_secs;
-}
-ClockDialog;
+    /* get the precise time */
+    g_get_current_time (&timeval);
 
-static void clock_properties_dialog (XfcePanelPlugin *plugin,
-                                     Clock *clock);
+    /* ms to next second */
+    interval = 1000 - (timeval.tv_usec / 1000);
 
-static void clock_construct (XfcePanelPlugin *plugin);
+    /* get current time */
+    localtime_r (&now, &tm);
 
+    /* add the interval time to the next update */
+    switch (timeout_interval)
+    {
+        case CLOCK_INTERVAL_HOUR:
+            /* ms to next hour */
+            interval += (60 - tm.tm_min) * CLOCK_INTERVAL_MINUTE;
 
-/* -------------------------------------------------------------------- *
- *                               Clock                                  *
- * -------------------------------------------------------------------- */
- 
-static gboolean
-clock_reschedule_callback (Clock *clock)
-{
-    g_return_val_if_fail (clock->secs == FALSE, FALSE);
-    
-    /* update the clock every minute */
-    xfce_clock_set_interval (XFCE_CLOCK (clock->clock), 60 * 1000);
-    
-    return FALSE;
-}
+            /* fall-through to add the minutes */
 
-static void
-clock_reschedule_callback_destroy (Clock *clock)
-{
-    clock->reschedule_id = 0;
+        case CLOCK_INTERVAL_MINUTE:
+            /* ms to next minute */
+            interval += (60 - tm.tm_sec) * CLOCK_INTERVAL_SECOND;
+            break;
+
+        default:
+            break;
+    }
+
+    return interval;
 }
 
-static void
-clock_reschedule (Clock *clock)
+
+
+gchar *
+xfce_clock_util_strdup_strftime (const gchar *format,
+                                 const struct tm *tm)
 {
-    time_t ticks;
-    struct tm *tm;
-    gint interval;
-    
-    /* stop running reschudule */
-    if (clock->reschedule_id)
-        g_source_remove (clock->reschedule_id);
-        
-    /* update every second if seconds are displayed or the led clock is used */
-    if (clock->secs || clock->mode == XFCE_CLOCK_LEDS)
-    {
-    	/* update every second */
-    	xfce_clock_set_interval (XFCE_CLOCK (clock->clock), 1000);
-    }
-    else
-    {
-        /* get the time */
-        time (&ticks);
-        tm = localtime (&ticks);
-    
-        /* get the interval up to the next minute */
-        interval = ((60 - tm->tm_sec) * 1000) + 500;
-        
-        /* set the new clock timeout (for this minute) */
-        xfce_clock_set_interval (XFCE_CLOCK (clock->clock), interval);
-        
-        /* start a new reschedule event */
-        clock->reschedule_id = 
-            g_timeout_add_full (G_PRIORITY_LOW, interval, (GSourceFunc)clock_reschedule_callback, 
-                                clock, (GDestroyNotify)clock_reschedule_callback_destroy);
-    }
+    gchar *converted, *result;
+    gsize  length;
+    gchar  buffer[BUFFER_SIZE];
+
+    /* convert to locale, because that's what strftime uses */
+    converted = g_locale_from_utf8 (format, -1, NULL, NULL, NULL);
+    if (G_UNLIKELY (converted == NULL))
+        return NULL;
+
+    /* parse the time string */
+    length = strftime (buffer, sizeof (buffer), converted, tm);
+    if (G_UNLIKELY (length == 0))
+        buffer[0] = '\0';
+
+    /* convert the string back to utf-8 */
+    result = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
+
+    /* cleanup */
+    g_free (converted);
+
+    return result;
 }
 
+
+
+/** tooltip functions **/
 static gboolean
-clock_date_tooltip (Clock *clock)
+xfce_clock_tooltip_update (gpointer user_data)
 {
-    time_t ticks;
-    struct tm *tm;
-    char date_s[255];
-    char *utf8date = NULL;
+    ClockPlugin        *clock = (ClockPlugin *) user_data;
+    gchar              *string;
+    time_t              now = time (0);
+    struct tm           tm;
+    static GtkTooltips *tooltips = NULL;
 
-    ticks = time (0);
-    tm = localtime (&ticks);
+    g_return_val_if_fail (clock->tooltip_format != NULL, TRUE);
 
-    if (clock->mday != tm->tm_mday)
-    {
-        clock->mday = tm->tm_mday;
+    /* allocate the tooltip on-demand */
+    if (G_UNLIKELY (tooltips == NULL))
+        tooltips = gtk_tooltips_new ();
 
-        /* Use format characters from strftime(3)
-	 * to get the proper string for your locale.
-	 * I used these:
-	 * %A  : full weekday name
-	 * %d  : day of the month
-	 * %B  : full month name
-	 * %Y  : four digit year
-	 */
-        strftime(date_s, sizeof(date_s), _("%A %d %B %Y"), tm);
+    /* get the local time */
+    localtime_r (&now, &tm);
 
-        /* Conversion to utf8
-         * Patch by Oliver M. Bolzer <oliver at fakeroot.net>
-         */
-        if (!g_utf8_validate(date_s, -1, NULL))
-        {
-            utf8date = g_locale_to_utf8(date_s, -1, NULL, NULL, NULL);
-        }
+    /* get the string */
+    string = xfce_clock_util_strdup_strftime (clock->tooltip_format, &tm);
 
-        if (utf8date)
-        {
-            gtk_tooltips_set_tip (clock->tips, GTK_WIDGET (clock->plugin),
-                                  utf8date, NULL);
-            g_free (utf8date);
-        }
-        else
-        {
-            gtk_tooltips_set_tip (clock->tips, GTK_WIDGET (clock->plugin),
-                                  date_s, NULL);
-        }
-    }
+    /* set the tooltip */
+    gtk_tooltips_set_tip (tooltips, clock->ebox, string, NULL);
 
+    /* cleanup */
+    g_free (string);
+
     return TRUE;
 }
 
-static void
-clock_update_size (Clock *clock, int size)
+
+
+static gboolean
+xfce_clock_tooltip_sync_timeout (gpointer user_data)
 {
-    XfceClock *clk = XFCE_CLOCK (clock->clock);
+    ClockPlugin *clock = (ClockPlugin *) user_data;
 
-    g_return_if_fail (clk != NULL);
-    g_return_if_fail (GTK_IS_WIDGET (clk));
+    /* start the tooltip update interval */
+    clock->clock_timeout_id = g_timeout_add (clock->tooltip_interval, xfce_clock_tooltip_update, clock);
 
-    /* keep in sync with systray */
-    if (size > 26)
-    {
-        gtk_container_set_border_width (GTK_CONTAINER (clock->frame), 1);
-        size -= 3;
-    }
-    else
-    {
-        gtk_container_set_border_width (GTK_CONTAINER (clock->frame), 0);
-        size -= 1;
-    }
+    /* manual update for this timeout */
+    xfce_clock_tooltip_update (clock);
 
-    /* Replaced old 4-stage switch; Perhaps DIGIT_*_HEIGHT
-     * should be moved from xfce_clock.c to xfce_clock.h so we
-     * can use them here (e.g. 10*2 => DIGIT_SMALL_HEIGHT*2)
-     * */
+    /* stop the sync timeout */
+    return FALSE;
+}
 
-    if (xfce_panel_plugin_get_orientation (clock->plugin)
-            == GTK_ORIENTATION_HORIZONTAL)
+
+
+void
+xfce_clock_tooltip_sync (ClockPlugin *clock)
+{
+    guint interval;
+
+    if (clock->tooltip_timeout_id)
     {
-        if (size <= 10*2)
-        {
-            xfce_clock_set_led_size (clk, DIGIT_SMALL);
-        }
-        else if (size <= 14*2)
-        {
-            xfce_clock_set_led_size (clk, DIGIT_MEDIUM);
-        }
-        else if (size <= 20*2)
-        {
-            xfce_clock_set_led_size (clk, DIGIT_LARGE);
-        }
-        else
-        {
-            xfce_clock_set_led_size (clk, DIGIT_HUGE);
-        }
+        /* stop old and reset timeout */
+        g_source_remove (clock->tooltip_timeout_id);
+        clock->tooltip_timeout_id = 0;
     }
-    else
-    {
-        /* Always use small size in vertical mode */
-        xfce_clock_set_led_size (clk, DIGIT_SMALL);
-    }
 
-    if ((xfce_clock_get_mode (clk) == XFCE_CLOCK_LEDS) ||
-        (xfce_clock_get_mode (clk) == XFCE_CLOCK_DIGITAL))
+    /* detect the tooltip interval from the string */
+    clock->tooltip_interval = xfce_clock_util_interval_from_format (clock->tooltip_format);
+
+    /* get the interval to the next update */
+    interval = xfce_clock_util_next_interval (clock->tooltip_interval);
+
+    /* start the sync timeout */
+    clock->tooltip_timeout_id = g_timeout_add (interval, xfce_clock_tooltip_sync_timeout, clock);
+
+    /* update the tooltip */
+    xfce_clock_tooltip_update (clock);
+}
+
+
+
+/** clock widget functions **/
+static gboolean
+xfce_clock_widget_sync_timeout (gpointer user_data)
+{
+    ClockPlugin *clock = (ClockPlugin *) user_data;
+
+    if (G_LIKELY (clock->widget))
     {
-        gtk_widget_set_size_request (GTK_WIDGET (clk), -1, -1);
+        /* start the clock update timeout */
+        clock->clock_timeout_id = g_timeout_add (clock->interval, clock->update, clock->widget);
+
+        /* manual update for this interval */
+        (clock->update) (clock->widget);
     }
     else
     {
-        gtk_widget_set_size_request (GTK_WIDGET (clk), size, size);
+        /* remove timer id */
+        clock->clock_timeout_id = 0;
     }
 
-    gtk_widget_queue_resize (GTK_WIDGET (clk));
+    /* stop the sync timeout */
+    return FALSE;
 }
 
 
-/* -------------------------------------------------------------------- *
- *                     Panel Plugin Interface                           *
- * -------------------------------------------------------------------- */
 
-/* Register with the panel */
+void
+xfce_clock_widget_sync (ClockPlugin *clock)
+{
+    guint interval;
 
-XFCE_PANEL_PLUGIN_REGISTER_INTERNAL (clock_construct);
+    if (clock->clock_timeout_id)
+    {
+        /* stop old and reset timeout */
+        g_source_remove (clock->clock_timeout_id);
+        clock->clock_timeout_id = 0;
+    }
 
+    if (G_LIKELY (clock->widget))
+    {
+        /* get the interval to the next update */
+        interval = xfce_clock_util_next_interval (clock->interval);
 
-/* Interface Implementation */
+        /* start the sync timeout */
+        clock->clock_timeout_id = g_timeout_add (interval, xfce_clock_widget_sync_timeout, clock);
+    }
+}
 
-static gboolean
-clock_set_size (XfcePanelPlugin *plugin, int size, Clock *clock)
-{
-    clock_update_size(clock, size);
 
-    return TRUE;
-}
 
-static void
-clock_free_data (XfcePanelPlugin *plugin, Clock *clock)
+void
+xfce_clock_widget_update_settings (ClockPlugin *clock)
 {
-    GtkWidget *dlg = g_object_get_data (G_OBJECT (plugin), "dialog");
+    g_return_if_fail (clock->widget != NULL);
 
-    if (dlg)
-        gtk_widget_destroy (dlg);
-        
-    if (clock->reschedule_id)
-        g_source_remove (clock->reschedule_id);
-        
-    g_signal_handler_disconnect (plugin, clock->screen_changed_id);
+    /* send the settings based on the clock mode */
+    switch (clock->mode)
+    {
+        case XFCE_CLOCK_ANALOG:
+            /* set settings */
+            g_object_set (G_OBJECT (clock->widget),
+                          "show-seconds", clock->show_seconds, NULL);
+            break;
 
-    g_source_remove (clock->timeout_id);
-    g_object_unref (G_OBJECT (clock->tips));
-    panel_slice_free (Clock, clock);
-}
+        case XFCE_CLOCK_BINARY:
+            /* set settings */
+            g_object_set (G_OBJECT (clock->widget),
+                          "show-seconds", clock->show_seconds,
+                          "true-binary", clock->true_binary, NULL);
+            break;
 
-static void
-clock_read_rc_file (XfcePanelPlugin *plugin, Clock* clock)
-{
-    char *file;
-    XfceRc *rc;
-    int mode;
-    gboolean military, ampm, secs, show_frame;
+        case XFCE_CLOCK_DIGITAL:
+            /* set settings */
+            g_object_set (G_OBJECT (clock->widget),
+                          "digital-format", clock->digital_format, NULL);
+            break;
 
-    mode = XFCE_CLOCK_DIGITAL;
-    military = TRUE;
-    ampm = FALSE;
-    secs = FALSE;
-    show_frame = FALSE;
+        case XFCE_CLOCK_LCD:
+            /* set settings */
+            g_object_set (G_OBJECT (clock->widget),
+                          "show-seconds", clock->show_seconds,
+                          "show-military", clock->show_military,
+                          "show-meridiem", clock->show_meridiem, NULL);
+            break;
+    }
 
-    if ((file = xfce_panel_plugin_lookup_rc_file (plugin)) != NULL)
+    /* get update interval */
+    if (clock->mode == XFCE_CLOCK_DIGITAL)
     {
-        rc = xfce_rc_simple_open (file, TRUE);
-        g_free (file);
-
-        if (rc != NULL)
-        {
-            mode = xfce_rc_read_int_entry (rc, "mode", XFCE_CLOCK_DIGITAL);
-            military = xfce_rc_read_bool_entry (rc, "military", TRUE);
-            ampm = xfce_rc_read_bool_entry (rc, "ampm", FALSE);
-            secs = xfce_rc_read_bool_entry (rc, "secs", FALSE);
-            show_frame = xfce_rc_read_bool_entry (rc, "show_frame", FALSE);
-            xfce_rc_close (rc);
-        }
+        /* get interval from string */
+        clock->interval = xfce_clock_util_interval_from_format (clock->digital_format);
     }
+    else
+    {
+        /* interval from setting */
+        clock->interval = clock->show_seconds ? CLOCK_INTERVAL_SECOND : CLOCK_INTERVAL_MINUTE;
+    }
+}
 
-    clock->mode = mode;
-    clock->military = military;
-    clock->ampm = ampm;
-    clock->secs = secs;
 
-    xfce_clock_set_mode (XFCE_CLOCK (clock->clock), mode);
-    xfce_clock_show_military (XFCE_CLOCK (clock->clock), military);
-    xfce_clock_show_ampm (XFCE_CLOCK (clock->clock), ampm);
-    xfce_clock_show_secs (XFCE_CLOCK (clock->clock), secs);
 
-    clock->show_frame = show_frame;
-    gtk_frame_set_shadow_type (GTK_FRAME (clock->frame),
-                               show_frame ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
-
-    clock_update_size (clock,
-            xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin)));
-}
-
-static void
-clock_write_rc_file (XfcePanelPlugin *plugin, Clock *clock)
+void
+xfce_clock_widget_set_mode (ClockPlugin *clock)
 {
-    char *file;
-    XfceRc *rc;
+    GtkWidget *widget;
 
-    if (!(file = xfce_panel_plugin_save_location (plugin, TRUE)))
-        return;
+    /* stop runing timeout */
+    if (clock->clock_timeout_id)
+    {
+        g_source_remove (clock->clock_timeout_id);
+        clock->clock_timeout_id = 0;
+    }
 
-    rc = xfce_rc_simple_open (file, FALSE);
-    g_free (file);
+    /* destroy the old widget */
+    if (clock->widget)
+    {
+        gtk_widget_destroy (clock->widget);
+        clock->widget = NULL;
+    }
 
-    if (!rc)
-        return;
+    switch (clock->mode)
+    {
+        case XFCE_CLOCK_ANALOG:
+            widget = xfce_clock_analog_new ();
+            clock->update = xfce_clock_analog_update;
+            break;
 
-    xfce_rc_write_int_entry (rc, "mode", clock->mode);
-    xfce_rc_write_bool_entry (rc, "military", clock->military);
-    xfce_rc_write_bool_entry (rc, "ampm", clock->ampm);
-    xfce_rc_write_bool_entry (rc, "secs", clock->secs);
-    xfce_rc_write_bool_entry (rc, "show_frame", clock->show_frame);
+        case XFCE_CLOCK_BINARY:
+            widget = xfce_clock_binary_new ();
+            clock->update = xfce_clock_binary_update;
+            break;
 
-    xfce_rc_close (rc);
-}
+        case XFCE_CLOCK_DIGITAL:
+            widget = xfce_clock_digital_new ();
+            clock->update = xfce_clock_digital_update;
+            break;
 
-static void
-clock_screen_changed (GtkWidget *plugin, GdkScreen *screen,
-                      Clock *clock)
-{
-	/* return when the widget is not visible (when moving the plugin) */
-	if (GTK_IS_INVISIBLE (clock->clock) == FALSE)
-	    return;
-	
-    gtk_widget_destroy (clock->clock);
+        case XFCE_CLOCK_LCD:
+            widget = xfce_clock_lcd_new ();
+            clock->update = xfce_clock_lcd_update;
+            break;
 
-    clock->clock = xfce_clock_new ();
-    gtk_widget_show (clock->clock);
-    gtk_container_add (GTK_CONTAINER (clock->frame), clock->clock);
+        default:
+            g_error ("Unknown clock type");
+            return;
+    }
 
-    clock->mday = -1;
-    
-    clock_read_rc_file (clock->plugin, clock);
-    
-    /* set the clock timeout */
-    clock_reschedule (clock);
+    /* set the clock */
+    clock->widget = widget;
+
+    /* add and show the clock */
+    gtk_container_add (GTK_CONTAINER (clock->frame), widget);
+    gtk_widget_show (widget);
 }
 
-/* Create widgets and connect to signals */
 
-static void
-clock_construct (XfcePanelPlugin *plugin)
+
+/** plugin functions **/
+static ClockPlugin *
+xfce_clock_plugin_init (XfcePanelPlugin *plugin)
 {
-    Clock *clock = panel_slice_new0 (Clock);
+    ClockPlugin *clock;
 
+    /* create structure */
+    clock = panel_slice_new0 (ClockPlugin);
+
+    /* set plugin */
     clock->plugin = plugin;
-    clock->reschedule_id = 0;
 
-    g_signal_connect (plugin, "size-changed",
-                      G_CALLBACK (clock_set_size), clock);
+    /* initialize */
+    clock->clock_timeout_id = 0;
+    clock->tooltip_timeout_id = 0;
+    clock->widget = NULL;
+    clock->tooltip_format = NULL;
+    clock->digital_format = NULL;
 
-    g_signal_connect (plugin, "free-data",
-                      G_CALLBACK (clock_free_data), clock);
+    /* read the user settings */
+    xfce_clock_plugin_read (clock);
 
-    g_signal_connect (plugin, "save",
-                      G_CALLBACK (clock_write_rc_file), clock);
+    /* build widgets */
+    clock->ebox = gtk_event_box_new ();
+    gtk_container_add (GTK_CONTAINER (plugin), clock->ebox);
+    gtk_event_box_set_visible_window (GTK_EVENT_BOX (clock->ebox), FALSE);
+    gtk_widget_show (clock->ebox);
 
-    xfce_panel_plugin_menu_show_configure (plugin);
-    g_signal_connect (plugin, "configure-plugin",
-                      G_CALLBACK (clock_properties_dialog), clock);
-                      
-    clock->screen_changed_id =
-        g_signal_connect (plugin, "screen-changed",
-                          G_CALLBACK (clock_screen_changed), clock);
-
     clock->frame = gtk_frame_new (NULL);
+    gtk_container_add (GTK_CONTAINER (clock->ebox), clock->frame);
+    gtk_frame_set_shadow_type (GTK_FRAME (clock->frame), clock->show_frame ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
     gtk_widget_show (clock->frame);
-    gtk_container_add (GTK_CONTAINER (plugin), clock->frame);
 
-    clock->clock = xfce_clock_new ();
-    gtk_widget_show (clock->clock);
-    gtk_container_add (GTK_CONTAINER (clock->frame), clock->clock);
+    /* set the clock */
+    xfce_clock_widget_set_mode (clock);
 
-    clock_read_rc_file (plugin, clock);
-    clock->mday = -1;
+    /* set the clock settings */
+    xfce_clock_widget_update_settings (clock);
 
-    clock->tips = gtk_tooltips_new ();
-    g_object_ref (G_OBJECT (clock->tips));
-    gtk_object_sink (GTK_OBJECT (clock->tips));
+    /* start the timeout */
+    xfce_clock_widget_sync (clock);
 
-    clock_date_tooltip (clock);
-    
-    /* set the clock timeout */
-    clock_reschedule (clock);
+    /* start the tooltip sync */
+    xfce_clock_tooltip_sync (clock);
 
-    /* update the tooltip every minute */
-    clock->timeout_id =
-        g_timeout_add (60 * 1000, (GSourceFunc) clock_date_tooltip, clock);
+    return clock;
 }
 
-/* -------------------------------------------------------------------- *
- *                        Configuration Dialog                          *
- * -------------------------------------------------------------------- */
 
-static void
-clock_set_sensitive (ClockDialog *cd)
+
+gboolean
+xfce_clock_plugin_set_size (ClockPlugin *clock,
+                            guint        size)
 {
-    if (cd->clock->mode == XFCE_CLOCK_ANALOG)
-    {
-	gtk_widget_set_sensitive (cd->cb_military, FALSE);
-	gtk_widget_set_sensitive (cd->cb_ampm, FALSE);
-    }
+    GtkOrientation orientation;
+
+    /* set the frame border */
+    gtk_container_set_border_width (GTK_CONTAINER (clock->frame), size > 26 ? 1 : 0);
+
+    /* get the clock size */
+    size -= size > 26 ? 6 : 4;
+
+    /* get plugin orientation */
+    orientation = xfce_panel_plugin_get_orientation (clock->plugin);
+
+    /* set the clock size */
+    if (orientation == GTK_ORIENTATION_HORIZONTAL)
+        gtk_widget_set_size_request (clock->widget, -1, size);
     else
-    {
-	gtk_widget_set_sensitive (cd->cb_military, TRUE);
+        gtk_widget_set_size_request (clock->widget, size, -1);
 
-	if (cd->clock->military)
-	    gtk_widget_set_sensitive (cd->cb_ampm, FALSE);
-        else
-	    gtk_widget_set_sensitive (cd->cb_ampm, TRUE);
-    }
+    return TRUE;
 }
 
+
+
 static void
-clock_button_toggled (GtkWidget *cb, ClockDialog *cd)
+xfce_clock_plugin_read (ClockPlugin *clock)
 {
-    gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb));
+    gchar       *filename;
+    const gchar *value;
+    XfceRc      *rc;
 
-    if (cb == cd->cb_frame)
-    {
-	cd->clock->show_frame = active;
-	gtk_frame_set_shadow_type (GTK_FRAME (cd->clock->frame),
-	                           active ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
-    }
-    else if (cb == cd->cb_military)
-    {
-	cd->clock->military = active;
-	xfce_clock_show_military (XFCE_CLOCK (cd->clock->clock),
-	                          active);
+    /* config filename */
+    filename = xfce_panel_plugin_save_location (clock->plugin, TRUE);
 
-	clock_set_sensitive (cd);
-    }
-    else if (cb == cd->cb_ampm)
+    if (G_LIKELY (filename))
     {
-	cd->clock->ampm = active;
-	xfce_clock_show_ampm (XFCE_CLOCK (cd->clock->clock),
-	                      active);
-    }
-    else if (cb == cd->cb_secs)
-    {
-	cd->clock->secs = active;
-	xfce_clock_show_secs (XFCE_CLOCK (cd->clock->clock),
-	                      active);
-	
-	/* set the clock timeout */
-        clock_reschedule (cd->clock);
-    }
+        /* open rc file (readonly) and cleanup */
+        rc = xfce_rc_simple_open (filename, TRUE);
+        g_free (filename);
 
-    clock_update_size (cd->clock,
-            xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (cd->clock->plugin)));
-}
+        if (G_LIKELY (rc))
+        {
+            /* read strings */
+            value = xfce_rc_read_entry (rc, "DigitalFormat", DEFAULT_DIGITAL_FORMAT);
+            if (G_LIKELY (value != NULL && *value != '\0'))
+                clock->digital_format = g_strdup (value);
 
-static void
-clock_mode_changed (GtkComboBox *cb, ClockDialog *cd)
-{
-    cd->clock->mode = gtk_combo_box_get_active(cb);
-    xfce_clock_set_mode (XFCE_CLOCK (cd->clock->clock), cd->clock->mode);
-    
-    clock_reschedule (cd->clock);
+            value = xfce_rc_read_entry (rc, "TooltipFormat", DEFAULT_TOOLTIP_FORMAT);
+            if (G_LIKELY (value != NULL && *value != '\0'))
+                clock->tooltip_format = g_strdup (value);
 
-    clock_set_sensitive (cd);
+            /* read clock type */
+            clock->mode = xfce_rc_read_int_entry (rc, "ClockType", XFCE_CLOCK_DIGITAL);
 
-    clock_update_size (cd->clock,
-            xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (cd->clock->plugin)));
+            /* read boolean settings */
+            clock->show_frame    = xfce_rc_read_bool_entry (rc, "ShowFrame", TRUE);
+            clock->show_seconds  = xfce_rc_read_bool_entry (rc, "ShowSeconds", FALSE);
+            clock->show_military = xfce_rc_read_bool_entry (rc, "ShowMilitary", TRUE);
+            clock->show_meridiem = xfce_rc_read_bool_entry (rc, "ShowMeridiem", FALSE);
+            clock->true_binary   = xfce_rc_read_bool_entry (rc, "TrueBinary", FALSE);
+
+            /* close the rc file */
+            xfce_rc_close (rc);
+        }
+    }
 }
 
-static void
-clock_dialog_response (GtkWidget *dlg, int reponse,
-                       ClockDialog *cd)
-{
-    g_object_set_data (G_OBJECT (cd->clock->plugin), "dialog", NULL);
 
-    gtk_widget_destroy (dlg);
-    xfce_panel_plugin_unblock_menu (cd->clock->plugin);
-    clock_write_rc_file (cd->clock->plugin, cd->clock);
 
-    g_free (cd);
-}
-
 static void
-clock_properties_dialog (XfcePanelPlugin *plugin, Clock *clock)
+xfce_clock_plugin_write (ClockPlugin *clock)
 {
-    GtkWidget *dlg, *frame, *bin, *vbox, *cb;
-    ClockDialog *cd;
+    gchar  *filename;
+    XfceRc *rc;
 
-    xfce_panel_plugin_block_menu (plugin);
+    /* config filename */
+    filename = xfce_panel_plugin_save_location (clock->plugin, TRUE);
 
-    cd = g_new0 (ClockDialog, 1);
-    cd->clock = clock;
+    if (G_LIKELY (filename))
+    {
+        /* open rc file and cleanup */
+        rc = xfce_rc_simple_open (filename, FALSE);
+        g_free (filename);
 
-    dlg = xfce_titled_dialog_new_with_buttons (_("Clock"), NULL,
-                GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
-                GTK_STOCK_CLOSE, GTK_RESPONSE_OK,
-                NULL);
+        if (G_LIKELY (rc))
+        {
+            /* write settings */
+            if (G_LIKELY (clock->digital_format && *clock->digital_format != '\0'))
+                xfce_rc_write_entry (rc, "DigitalFormat", clock->digital_format);
 
-    gtk_window_set_screen (GTK_WINDOW (dlg),
-                           gtk_widget_get_screen (GTK_WIDGET (plugin)));
+            if (G_LIKELY (clock->tooltip_format && *clock->tooltip_format != '\0'))
+                xfce_rc_write_entry (rc, "TooltipFormat", clock->tooltip_format);
 
-    g_object_set_data (G_OBJECT (plugin), "dialog", dlg);
+            xfce_rc_write_int_entry (rc, "ClockType", clock->mode);
+            xfce_rc_write_bool_entry (rc, "ShowFrame", clock->show_frame);
+            xfce_rc_write_bool_entry (rc, "ShowSeconds", clock->show_seconds);
+            xfce_rc_write_bool_entry (rc, "ShowMilitary", clock->show_military);
+            xfce_rc_write_bool_entry (rc, "ShowMeridiem", clock->show_meridiem);
+            xfce_rc_write_bool_entry (rc, "TrueBinary", clock->true_binary);
 
-    gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_CENTER);
-    gtk_window_set_icon_name (GTK_WINDOW (dlg), "xfce4-settings");
+            /* close the rc file */
+            xfce_rc_close (rc);
+        }
+    }
+}
 
-    gtk_container_set_border_width (GTK_CONTAINER (dlg), 2);
 
-    frame = xfce_create_framebox (_("Appearance"), &bin);
-    gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
-    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame,
-                        FALSE, FALSE, 0);
 
-    vbox = gtk_vbox_new (FALSE, 8);
-    gtk_container_add (GTK_CONTAINER (bin), vbox);
+static void
+xfce_clock_plugin_free (ClockPlugin *clock)
+{
+    GtkWidget *dialog;
 
-    cd->cb_mode = cb = gtk_combo_box_new_text ();
-    gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
+    /* stop timeouts */
+    if (G_LIKELY (clock->clock_timeout_id))
+        g_source_remove (clock->clock_timeout_id);
 
-    /* Keep order in sync with XfceClockMode */
-    gtk_combo_box_append_text (GTK_COMBO_BOX (cb), _("Analog"));
-    gtk_combo_box_append_text (GTK_COMBO_BOX (cb), _("Digital"));
-    gtk_combo_box_append_text (GTK_COMBO_BOX (cb), _("LED"));
-    gtk_combo_box_set_active (GTK_COMBO_BOX (cb), clock->mode);
-    g_signal_connect (cb, "changed",
-            G_CALLBACK (clock_mode_changed), cd);
+    if (G_LIKELY (clock->tooltip_timeout_id))
+        g_source_remove (clock->tooltip_timeout_id);
 
-    cd->cb_frame = cb = gtk_check_button_new_with_mnemonic (_("Show _frame"));
-    gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb),
-            clock->show_frame);
-    g_signal_connect (cb, "toggled",
-            G_CALLBACK (clock_button_toggled), cd);
+    /* destroy the configure dialog if it's still open */
+    dialog = g_object_get_data (G_OBJECT (clock->plugin), I_("configure-dialog"));
+    if (G_UNLIKELY (dialog != NULL))
+        gtk_widget_destroy (dialog);
 
-    frame = xfce_create_framebox (_("Clock Options"), &bin);
-    gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
-    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame,
-                        FALSE, FALSE, 0);
+    /* cleanup */
+    g_free (clock->tooltip_format);
+    g_free (clock->digital_format);
 
-    vbox = gtk_vbox_new (FALSE, 8);
-    gtk_container_add (GTK_CONTAINER (bin), vbox);
+    /* free structure */
+    panel_slice_free (ClockPlugin, clock);
+}
 
-    cd->cb_military = cb = gtk_check_button_new_with_mnemonic (_("Use 24-_hour clock"));
-    gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb),
-            clock->military);
-    g_signal_connect (cb, "toggled",
-            G_CALLBACK (clock_button_toggled), cd);
 
-    cd->cb_ampm = cb = gtk_check_button_new_with_mnemonic (_("Show AM/PM"));
-    gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb),
-            clock->ampm);
-    g_signal_connect (cb, "toggled",
-            G_CALLBACK (clock_button_toggled), cd);
 
-    cd->cb_secs = cb = gtk_check_button_new_with_mnemonic (_("Display seconds"));
-    gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb),
-            clock->secs);
-    g_signal_connect (cb, "toggled",
-            G_CALLBACK (clock_button_toggled), cd);
+static void
+xfce_clock_plugin_construct (XfcePanelPlugin *plugin)
+{
+    ClockPlugin *clock = xfce_clock_plugin_init (plugin);
 
-    clock_set_sensitive (cd);
+    /* plugin settings */
+    xfce_panel_plugin_add_action_widget (plugin, clock->ebox);
+    xfce_panel_plugin_menu_show_configure (plugin);
 
-    g_signal_connect (dlg, "response",
-            G_CALLBACK (clock_dialog_response), cd);
-
-    gtk_widget_show_all (dlg);
+    /* connect signals */
+    g_signal_connect_swapped (G_OBJECT (plugin), "size-changed", G_CALLBACK (xfce_clock_plugin_set_size), clock);
+    g_signal_connect_swapped (G_OBJECT (plugin), "save", G_CALLBACK (xfce_clock_plugin_write), clock);
+    g_signal_connect_swapped (G_OBJECT (plugin), "free-data", G_CALLBACK (xfce_clock_plugin_free), clock);
+    g_signal_connect_swapped (G_OBJECT (plugin), "configure-plugin", G_CALLBACK (xfce_clock_dialog_show), clock);
 }
 


Property changes on: xfce4-panel/trunk/plugins/clock/clock.c
___________________________________________________________________
Name: keywords
   + Id

Modified: xfce4-panel/trunk/plugins/clock/clock.desktop.in.in
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock.desktop.in.in	2007-07-06 13:14:53 UTC (rev 25889)
+++ xfce4-panel/trunk/plugins/clock/clock.desktop.in.in	2007-07-06 19:57:20 UTC (rev 25890)
@@ -6,4 +6,3 @@
 Icon=xfce4-clock
 X-XFCE-Module=clock
 X-XFCE-Module-Path=@libdir@/xfce4/panel-plugins
-


Property changes on: xfce4-panel/trunk/plugins/clock/clock.desktop.in.in
___________________________________________________________________
Name: keywords
   + Id

Added: xfce4-panel/trunk/plugins/clock/clock.h
===================================================================
--- xfce4-panel/trunk/plugins/clock/clock.h	                        (rev 0)
+++ xfce4-panel/trunk/plugins/clock/clock.h	2007-07-06 19:57:20 UTC (rev 25890)
@@ -0,0 +1,101 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifndef __CLOCK_H__
+#define __CLOCK_H__
+
+#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4panel/xfce-panel-plugin.h>
+
+G_BEGIN_DECLS
+
+#define CLOCK_INTERVAL_SECOND (1000)
+#define CLOCK_INTERVAL_MINUTE (60 * 1000)
+#define CLOCK_INTERVAL_HOUR   (3600 * 1000)
+
+#define BUFFER_SIZE            256
+#define DEFAULT_TOOLTIP_FORMAT "%A %d %B %Y"
+#define DEFAULT_DIGITAL_FORMAT "%R"
+
+
+
+typedef struct _ClockPlugin     ClockPlugin;
+typedef enum   _ClockPluginMode ClockPluginMode;
+
+enum _ClockPluginMode
+{
+    XFCE_CLOCK_ANALOG = 0,
+    XFCE_CLOCK_BINARY,
+    XFCE_CLOCK_DIGITAL,
+    XFCE_CLOCK_LCD
+};
+
+struct _ClockPlugin
+{
+    /* plugin */
+    XfcePanelPlugin *plugin;
+
+    /* widgets */
+    GtkWidget       *ebox;
+    GtkWidget       *frame;
+    GtkWidget       *widget;
+
+    /* clock update function and timeout */
+    GSourceFunc      update;
+    guint            interval;
+
+    /* tooltip interval */
+    guint            tooltip_interval;
+
+    /* clock type */
+    ClockPluginMode  mode;
+
+    /* timeouts */
+    guint            clock_timeout_id;
+    guint            tooltip_timeout_id;
+
+    /* settings */
+    gchar           *tooltip_format;
+    gchar           *digital_format;
+    guint            show_frame : 1;
+    guint            show_seconds : 1;
+    guint            show_military : 1;
+    guint            show_meridiem : 1;
+    guint            true_binary : 1;
+};
+
+
+gchar    *xfce_clock_util_strdup_strftime   (const gchar     *format,
+                                             const struct tm *tm)    G_GNUC_MALLOC G_GNUC_INTERNAL;
+
+void      xfce_clock_tooltip_sync           (ClockPlugin     *clock) G_GNUC_INTERNAL;
+
+void      xfce_clock_widget_sync            (ClockPlugin     *clock) G_GNUC_INTERNAL;
+
+void      xfce_clock_widget_update_settings (ClockPlugin     *clock) G_GNUC_INTERNAL;
+
+void      xfce_clock_widget_set_mode        (ClockPlugin     *clock) G_GNUC_INTERNAL;
+
+gboolean  xfce_clock_plugin_set_size        (ClockPlugin     *clock,
+                                             guint            size)  G_GNUC_INTERNAL;
+
+G_END_DECLS
+
+#endif /* !__CLOCK_H__ */


Property changes on: xfce4-panel/trunk/plugins/clock/clock.h
___________________________________________________________________
Name: keywords
   + Id

Modified: xfce4-panel/trunk/po/POTFILES.in
===================================================================
--- xfce4-panel/trunk/po/POTFILES.in	2007-07-06 13:14:53 UTC (rev 25889)
+++ xfce4-panel/trunk/po/POTFILES.in	2007-07-06 19:57:20 UTC (rev 25890)
@@ -25,6 +25,7 @@
 
 plugins/actions/actions.c
 plugins/clock/clock.c
+plugins/clock/clock-dialog.c
 plugins/iconbox/iconbox.c
 plugins/launcher/launcher.c
 plugins/launcher/launcher-exec.c

Modified: xfce4-panel/trunk/po/ar.po
===================================================================
--- xfce4-panel/trunk/po/ar.po	2007-07-06 13:14:53 UTC (rev 25889)
+++ xfce4-panel/trunk/po/ar.po	2007-07-06 19:57:20 UTC (rev 25890)
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: xfce4-panel\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-03-27 16:30+0200\n"
+"POT-Creation-Date: 2007-07-06 21:54+0200\n"
 "PO-Revision-Date: 2007-02-02 10:45+0200\n"
 "Last-Translator: Mohamed Magdy <alnokta at yahoo.com>\n"
 "Language-Team: Arabeyes Translation & Documentation <admin at arabeyes.org>\n"
@@ -110,28 +110,28 @@
 msgid "About the Xfce Panel"
 msgstr "حول شريط اكسفس"
 
-#: ../panel/panel-app.c:255 ../panel/panel-app.c:896
+#: ../panel/panel-app.c:256 ../panel/panel-app.c:886
 msgid "Exit Xfce Panel?"
 msgstr "اخرج من شريط اكسفس؟"
 
-#: ../panel/panel-app.c:894 ../panel/panel-app.c:926 ../panel/panel-app.c:959
+#: ../panel/panel-app.c:884 ../panel/panel-app.c:916 ../panel/panel-app.c:949
 msgid "Xfce Panel"
 msgstr "شريط Xfce"
 
-#: ../panel/panel-app.c:897
+#: ../panel/panel-app.c:887
 msgid "You can't remove the last panel. Would you like to exit the program?"
 msgstr ""
 
-#: ../panel/panel-app.c:924
+#: ../panel/panel-app.c:914
 #, c-format
 msgid "Remove Panel \"%d\"?"
 msgstr "ازل الشريط \"%d\"?"
 
-#: ../panel/panel-app.c:928
+#: ../panel/panel-app.c:918
 msgid "The selected panel and all its items will be removed."
 msgstr ""
 
-#: ../panel/panel-app.c:965 ../panel/panel-app.c:966
+#: ../panel/panel-app.c:955 ../panel/panel-app.c:956
 msgid "Developer"
 msgstr "مطوّر"
 
@@ -166,30 +166,30 @@
 msgid "Add new items"
 msgstr "أضف شيء جديد"
 
-#: ../panel/main.c:89
+#: ../panel/main.c:90
 #, fuzzy
 msgid "Failed to open display"
 msgstr "لم أستطع تشغيل \"%s\""
 
-#: ../panel/main.c:101
+#: ../panel/main.c:102
 msgid "Copyright (c) 2004