aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2013-06-14 16:01:43 -0500
committerCharles Kerr <charles.kerr@canonical.com>2013-06-14 16:01:43 -0500
commite392dd10a5dde1a0333fdeb963ecb1efecc8b19a (patch)
treea289289da305cf050d861418e32d1be16371b366 /src
parent8002a463e5fcd9d0b65ca2a445addf37cb117e32 (diff)
downloadayatana-indicator-datetime-e392dd10a5dde1a0333fdeb963ecb1efecc8b19a.tar.gz
ayatana-indicator-datetime-e392dd10a5dde1a0333fdeb963ecb1efecc8b19a.tar.bz2
ayatana-indicator-datetime-e392dd10a5dde1a0333fdeb963ecb1efecc8b19a.zip
remove the old indicator & service code
Diffstat (limited to 'src')
-rw-r--r--src/datetime-interface.c200
-rw-r--r--src/datetime-interface.h57
-rw-r--r--src/datetime-service.c1138
-rw-r--r--src/datetime-service.xml11
-rw-r--r--src/indicator-datetime.c1535
5 files changed, 0 insertions, 2941 deletions
diff --git a/src/datetime-interface.c b/src/datetime-interface.c
deleted file mode 100644
index 72c7437..0000000
--- a/src/datetime-interface.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
-An indicator to time and date related information in the menubar.
-
-Copyright 2010 Canonical Ltd.
-
-Authors:
- Ted Gould <ted@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gio/gio.h>
-
-#include "datetime-interface.h"
-#include "gen-datetime-service.xml.h"
-#include "dbus-shared.h"
-
-/**
- DatetimeInterfacePrivate:
- @dbus_registration: The handle for this object being registered
- on dbus.
-
- Structure to define the memory for the private area
- of the datetime interface instance.
-*/
-struct _DatetimeInterfacePrivate {
- GDBusConnection * bus;
- GCancellable * bus_cancel;
- guint dbus_registration;
-};
-
-#define DATETIME_INTERFACE_GET_PRIVATE(o) (DATETIME_INTERFACE(o)->priv)
-
-/* GDBus Stuff */
-static GDBusNodeInfo * node_info = NULL;
-static GDBusInterfaceInfo * interface_info = NULL;
-
-static void datetime_interface_class_init (DatetimeInterfaceClass *klass);
-static void datetime_interface_init (DatetimeInterface *self);
-static void datetime_interface_dispose (GObject *object);
-static void datetime_interface_finalize (GObject *object);
-static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data);
-
-G_DEFINE_TYPE (DatetimeInterface, datetime_interface, G_TYPE_OBJECT);
-
-static void
-datetime_interface_class_init (DatetimeInterfaceClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (DatetimeInterfacePrivate));
-
- object_class->dispose = datetime_interface_dispose;
- object_class->finalize = datetime_interface_finalize;
-
- /* Setting up the DBus interfaces */
- if (node_info == NULL) {
- GError * error = NULL;
-
- node_info = g_dbus_node_info_new_for_xml(_datetime_service, &error);
- if (error != NULL) {
- g_error("Unable to parse Datetime Service Interface description: %s", error->message);
- g_error_free(error);
- }
- }
-
- if (interface_info == NULL) {
- interface_info = g_dbus_node_info_lookup_interface(node_info, SERVICE_IFACE);
-
- if (interface_info == NULL) {
- g_error("Unable to find interface '" SERVICE_IFACE "'");
- }
- }
-
- return;
-}
-
-static void
-datetime_interface_init (DatetimeInterface *self)
-{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, DATETIME_INTERFACE_TYPE, DatetimeInterfacePrivate);
-
- self->priv->bus = NULL;
- self->priv->bus_cancel = NULL;
- self->priv->dbus_registration = 0;
-
- self->priv->bus_cancel = g_cancellable_new();
- g_bus_get(G_BUS_TYPE_SESSION,
- self->priv->bus_cancel,
- bus_get_cb,
- self);
-
- return;
-}
-
-static void
-bus_get_cb (GObject * object G_GNUC_UNUSED, GAsyncResult * res, gpointer user_data)
-{
- GError * error = NULL;
- GDBusConnection * connection = g_bus_get_finish(res, &error);
-
- if (error != NULL) {
- g_error("OMG! Unable to get a connection to DBus: %s", error->message);
- g_error_free(error);
- return;
- }
-
- DatetimeInterfacePrivate * priv = DATETIME_INTERFACE_GET_PRIVATE(user_data);
-
- g_warn_if_fail(priv->bus == NULL);
- priv->bus = connection;
-
- g_clear_object (&priv->bus_cancel);
-
- /* Now register our object on our new connection */
- priv->dbus_registration = g_dbus_connection_register_object(priv->bus,
- SERVICE_OBJ,
- interface_info,
- NULL,
- user_data,
- NULL,
- &error);
-
- if (error != NULL) {
- g_error("Unable to register the object to DBus: %s", error->message);
- g_error_free(error);
- return;
- }
-
- return;
-}
-
-static void
-datetime_interface_dispose (GObject *object)
-{
- DatetimeInterfacePrivate * priv = DATETIME_INTERFACE_GET_PRIVATE(object);
-
- if (priv->dbus_registration != 0) {
- g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration);
- /* Don't care if it fails, there's nothing we can do */
- priv->dbus_registration = 0;
- }
-
- g_clear_object (&priv->bus);
-
- if (priv->bus_cancel != NULL) {
- g_cancellable_cancel(priv->bus_cancel);
- g_clear_object (&priv->bus_cancel);
- }
-
- G_OBJECT_CLASS (datetime_interface_parent_class)->dispose (object);
- return;
-}
-
-static void
-datetime_interface_finalize (GObject *object)
-{
-
- G_OBJECT_CLASS (datetime_interface_parent_class)->finalize (object);
- return;
-}
-
-void
-datetime_interface_update (DatetimeInterface *self)
-{
- g_return_if_fail(IS_DATETIME_INTERFACE(self));
-
- DatetimeInterfacePrivate * priv = DATETIME_INTERFACE_GET_PRIVATE(self);
- GError * error = NULL;
-
- g_dbus_connection_emit_signal (priv->bus,
- NULL,
- SERVICE_OBJ,
- SERVICE_IFACE,
- "UpdateTime",
- NULL,
- &error);
-
- if (error != NULL) {
- g_error("Unable to send UpdateTime signal: %s", error->message);
- g_error_free(error);
- return;
- }
-
- return;
-}
diff --git a/src/datetime-interface.h b/src/datetime-interface.h
deleted file mode 100644
index ae85605..0000000
--- a/src/datetime-interface.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-An indicator to time and date related information in the menubar.
-
-Copyright 2010 Canonical Ltd.
-
-Authors:
- Ted Gould <ted@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __DATETIME_INTERFACE_H__
-#define __DATETIME_INTERFACE_H__
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define DATETIME_INTERFACE_TYPE (datetime_interface_get_type ())
-#define DATETIME_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DATETIME_INTERFACE_TYPE, DatetimeInterface))
-#define DATETIME_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DATETIME_INTERFACE_TYPE, DatetimeInterfaceClass))
-#define IS_DATETIME_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DATETIME_INTERFACE_TYPE))
-#define IS_DATETIME_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DATETIME_INTERFACE_TYPE))
-#define DATETIME_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DATETIME_INTERFACE_TYPE, DatetimeInterfaceClass))
-
-typedef struct _DatetimeInterface DatetimeInterface;
-typedef struct _DatetimeInterfacePrivate DatetimeInterfacePrivate;
-typedef struct _DatetimeInterfaceClass DatetimeInterfaceClass;
-
-struct _DatetimeInterfaceClass {
- GObjectClass parent_class;
-
- void (*update_time) (void);
-};
-
-struct _DatetimeInterface {
- GObject parent;
- DatetimeInterfacePrivate * priv;
-};
-
-GType datetime_interface_get_type (void);
-void datetime_interface_update (DatetimeInterface *self);
-
-G_END_DECLS
-
-#endif
diff --git a/src/datetime-service.c b/src/datetime-service.c
deleted file mode 100644
index 1a29949..0000000
--- a/src/datetime-service.c
+++ /dev/null
@@ -1,1138 +0,0 @@
-/*-*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
-An indicator to time and date related information in the menubar.
-
-Copyright 2010 Canonical Ltd.
-
-Authors:
- Ted Gould <ted@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-#include <libindicator/indicator-service.h>
-#include <locale.h>
-
-#include <gtk/gtk.h>
-#include <gdk/gdk.h>
-#include <glib/gi18n.h>
-#include <math.h> /* fabs() */
-
-#include <libdbusmenu-gtk/menuitem.h>
-#include <libdbusmenu-glib/server.h>
-#include <libdbusmenu-glib/client.h>
-#include <libdbusmenu-glib/menuitem.h>
-
-#include <cairo/cairo.h>
-
-#include "datetime-interface.h"
-#include "dbus-shared.h"
-#include "settings-shared.h"
-#include "planner-eds.h"
-#include "timezone-file.h"
-#include "timezone-geoclue.h"
-#include "utils.h"
-
-/* how often to check for clock skew */
-#define SKEW_CHECK_INTERVAL_SEC 10
-
-#define MAX_APPOINTMENT_MENUITEMS 5
-
-#define SKEW_DIFF_THRESHOLD_SEC (SKEW_CHECK_INTERVAL_SEC + 5)
-
-#ifdef HAVE_CCPANEL
- #define SETTINGS_APP_INVOCATION "gnome-control-center indicator-datetime"
-#else
- #define SETTINGS_APP_INVOCATION "gnome-control-center datetime"
-#endif
-
-static gboolean get_greeter_mode (void);
-
-static void quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, gpointer user_data);
-
-static DbusmenuMenuitem * root = NULL;
-static DatetimeInterface * dbus = NULL;
-
-typedef struct IndicatorDatetimeService
-{
- DbusmenuMenuitem * date;
- DbusmenuMenuitem * calendar;
- DbusmenuMenuitem * settings;
- DbusmenuMenuitem * events_separator;
- DbusmenuMenuitem * locations_separator;
- DbusmenuMenuitem * add_appointment;
- DbusmenuMenuitem * appointment_menuitems[MAX_APPOINTMENT_MENUITEMS];
-
- GSList * location_menu_items;
- gboolean updating_appointments;
- time_t start_time_appointments;
- GSettings * conf;
-
- IndicatorDatetimeTimezone * geo_location;
- IndicatorDatetimeTimezone * tz_file;
- IndicatorDatetimePlanner * planner;
-
- guint ecaltimer;
- guint day_timer;
-}
-IndicatorDatetimeService;
-
-static void update_location_menu_items (IndicatorDatetimeService * self);
-static void update_appointment_menu_items (IndicatorDatetimeService * self);
-static void day_timer_reset (IndicatorDatetimeService * self);
-
-/**
- * A temp struct used by update_location_menu_items() for pruning duplicates and sorting.
- */
-struct TimeLocation
-{
- gint32 offset;
- gchar * zone;
- gchar * name;
- gboolean visible;
-};
-
-static void
-time_location_free (struct TimeLocation * loc)
-{
- g_free (loc->name);
- g_free (loc->zone);
- g_free (loc);
-}
-
-static struct TimeLocation*
-time_location_new (const char * zone, const char * name, gboolean visible, time_t now)
-{
- struct TimeLocation * loc = g_new (struct TimeLocation, 1);
- GTimeZone * tz = g_time_zone_new (zone);
- gint interval = g_time_zone_find_interval (tz, G_TIME_TYPE_UNIVERSAL, now);
- loc->offset = g_time_zone_get_offset (tz, interval);
- loc->zone = g_strdup (zone);
- loc->name = g_strdup (name);
- loc->visible = visible;
- g_time_zone_unref (tz);
- g_debug ("%s zone '%s' name '%s' offset is %d", G_STRLOC, zone, name, (int)loc->offset);
- return loc;
-}
-
-static int
-time_location_compare (const struct TimeLocation * a, const struct TimeLocation * b)
-{
- int ret = a->offset - b->offset; /* primary key */
- if (!ret)
- ret = g_strcmp0 (a->name, b->name); /* secondary key */
- if (!ret)
- ret = a->visible - b->visible; /* tertiary key */
- g_debug ("%s comparing '%s' (%d) to '%s' (%d), returning %d", G_STRLOC, a->name, (int)a->offset, b->name, (int)b->offset, ret);
- return ret;
-}
-
-static GSList*
-locations_add (GSList * locations, const char * zone, const char * name, gboolean visible, time_t now)
-{
- struct TimeLocation * loc = time_location_new (zone, name, visible, now);
-
- if (g_slist_find_custom (locations, loc, (GCompareFunc)time_location_compare) == NULL)
- {
- g_debug ("%s Adding zone '%s', name '%s'", G_STRLOC, zone, name);
- locations = g_slist_append (locations, loc);
- }
- else
- {
- g_debug("%s Skipping duplicate zone '%s' name '%s'", G_STRLOC, zone, name);
- time_location_free (loc);
- }
-
- return locations;
-}
-
-/* Update the timezone entries */
-static void
-update_location_menu_items (IndicatorDatetimeService * self)
-{
- /* if we're in greeter mode, don't bother */
- if (self->locations_separator == NULL)
- return;
-
- /* remove the previous locations */
- while (self->location_menu_items != NULL) {
- DbusmenuMenuitem * item = DBUSMENU_MENUITEM(self->location_menu_items->data);
- self->location_menu_items = g_slist_remove (self->location_menu_items, item);
- dbusmenu_menuitem_child_delete (root, DBUSMENU_MENUITEM(item));
- g_object_unref (item);
- }
-
- /***
- **** Build a list of locations to add: use geo_timezone,
- **** current_timezone, and SETTINGS_LOCATIONS_S, but omit duplicates.
- ***/
-
- GSList * locations = NULL;
- const time_t now = time(NULL); /* FIXME: unmockable */
-
- /* maybe add geo_timezone */
- if (self->geo_location != NULL) {
- const char * geo_timezone = indicator_datetime_timezone_get_timezone (self->geo_location);
- if (geo_timezone && *geo_timezone) {
- const gboolean visible = g_settings_get_boolean (self->conf, SETTINGS_SHOW_DETECTED_S);
- gchar * name = get_current_zone_name (geo_timezone);
- locations = locations_add (locations, geo_timezone, name, visible, now);
- g_free (name);
- }
- }
-
- /* maybe add current_timezone */
- if (self->tz_file != NULL) {
- const char * tz = indicator_datetime_timezone_get_timezone (self->tz_file);
- if (tz && *tz) {
- const gboolean visible = g_settings_get_boolean (self->conf, SETTINGS_SHOW_DETECTED_S);
- gchar * name = get_current_zone_name (tz);
- locations = locations_add (locations, tz, name, visible, now);
- g_free (name);
- }
- }
-
- /* maybe add the user-specified custom locations */
- gchar ** user_locations = g_settings_get_strv (self->conf, SETTINGS_LOCATIONS_S);
- if (user_locations != NULL) {
- guint i;
- const guint location_count = g_strv_length (user_locations);
- const gboolean visible = g_settings_get_boolean (self->conf, SETTINGS_SHOW_LOCATIONS_S);
- g_debug ("%s Found %u user-specified locations", G_STRLOC, location_count);
- for (i=0; i<location_count; i++) {
- gchar * zone;
- gchar * name;
- split_settings_location (user_locations[i], &zone, &name);
- locations = locations_add (locations, zone, name, visible, now);
- g_free (name);
- g_free (zone);
- }
- g_strfreev (user_locations);
- user_locations = NULL;
- }
-
- /* finally create menuitems for each location */
- gint offset = dbusmenu_menuitem_get_position (self->locations_separator, root)+1;
- GSList * l;
- gboolean have_visible_location = FALSE;
- for (l=locations; l!=NULL; l=l->next) {
- struct TimeLocation * loc = l->data;
- g_debug("%s Adding location: zone '%s', name '%s'", G_STRLOC, loc->zone, loc->name);
- DbusmenuMenuitem * item = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, TIMEZONE_MENUITEM_TYPE);
- dbusmenu_menuitem_property_set (item, TIMEZONE_MENUITEM_PROP_NAME, loc->name);
- dbusmenu_menuitem_property_set (item, TIMEZONE_MENUITEM_PROP_ZONE, loc->zone);
- dbusmenu_menuitem_property_set_bool (item, TIMEZONE_MENUITEM_PROP_RADIO, FALSE);
- dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
- dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, loc->visible);
- dbusmenu_menuitem_child_add_position (root, item, offset++);
- g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(quick_set_tz), NULL);
- self->location_menu_items = g_slist_append (self->location_menu_items, item);
- if (loc->visible)
- have_visible_location = TRUE;
- time_location_free (loc);
- }
- g_slist_free (locations);
- locations = NULL;
-
- /* if there's at least one item being shown, show the separator too */
- dbusmenu_menuitem_property_set_bool (self->locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, have_visible_location);
-}
-
-static void
-quick_set_tz_cb (GObject *object, GAsyncResult *res, gpointer data G_GNUC_UNUSED)
-{
- GError * error = NULL;
- GVariant * answers = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
-
- if (error != NULL) {
- g_warning("Could not set timezone using timedated: %s", error->message);
- g_clear_error (&error);
- return;
- }
-
- g_variant_unref (answers);
-}
-
-static void
-quick_set_tz_proxy_cb (GObject *object G_GNUC_UNUSED, GAsyncResult *res, gpointer zone)
-{
- GError * error = NULL;
-
- GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
-
- if (error != NULL) {
- g_warning("Could not grab DBus proxy for timedated: %s", error->message);
- g_clear_error (&error);
- g_free (zone);
- return;
- }
-
- g_dbus_proxy_call (proxy, "SetTimezone", g_variant_new ("(sb)", zone, TRUE),
- G_DBUS_CALL_FLAGS_NONE, -1, NULL, quick_set_tz_cb, NULL);
- g_free (zone);
- g_object_unref (proxy);
-}
-
-static void
-quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)
-{
- const gchar * tz = dbusmenu_menuitem_property_get(menuitem, TIMEZONE_MENUITEM_PROP_ZONE);
- g_debug("Quick setting timezone to: %s", tz);
-
- g_return_if_fail(tz != NULL);
-
- const gchar * name = dbusmenu_menuitem_property_get(menuitem, TIMEZONE_MENUITEM_PROP_NAME);
-
- /* Set it in gsettings so we don't lose user's preferred name */
- GSettings * conf = g_settings_new (SETTINGS_INTERFACE);
- gchar * tz_full = g_strdup_printf ("%s %s", tz, name);
- g_settings_set_string (conf, SETTINGS_TIMEZONE_NAME_S, tz_full);
- g_free (tz_full);
- g_object_unref (conf);
-
- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL,
- "org.freedesktop.timedate1",
- "/org/freedesktop/timedate1",
- "org.freedesktop.timedate1",
- NULL, quick_set_tz_proxy_cb, g_strdup (tz));
-
- return;
-}
-
-/* Updates the label in the date menuitem */
-static gboolean
-update_datetime (gpointer gself)
-{
- GDateTime *datetime;
- gchar * utf8;
- IndicatorDatetimeService * self = gself;
-
- g_debug("Updating Date/Time");
-
- datetime = g_date_time_new_now_local (); /* FIXME: unmockable */
- if (datetime == NULL) {
- g_warning("Error getting local time");
- dbusmenu_menuitem_property_set(self->date, DBUSMENU_MENUITEM_PROP_LABEL, _("Error getting time"));
- return FALSE;
- }
-
- /* eranslators: strftime(3) style date format on top of the menu when you click on the clock */
- utf8 = g_date_time_format (datetime, _("%A, %e %B %Y"));
- dbusmenu_menuitem_property_set (self->date, DBUSMENU_MENUITEM_PROP_LABEL, utf8);
- g_free(utf8);
-
- g_date_time_unref (datetime);
- return G_SOURCE_REMOVE;
-}
-
-/* Run a particular program based on an activation */
-static void
-execute_command (const gchar * command)
-{
- GError * error = NULL;
-
- g_debug("Issuing command '%s'", command);
- if (!g_spawn_command_line_async(command, &error)) {
- g_warning("Unable to start %s: %s", (char *)command, error->message);
- g_clear_error (&error);
- }
-}
-
-/* Run a particular program based on an activation */
-static void
-activate_cb (DbusmenuMenuitem * menuitem G_GNUC_UNUSED,
- guint timestamp G_GNUC_UNUSED,
- const gchar * command)
-{
- execute_command (command);
-}
-
-static gboolean
-update_appointment_menu_items_idle (gpointer gself)
-{
- update_appointment_menu_items (gself);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-update_appointment_menu_items_soon (IndicatorDatetimeService * self)
-{
- g_idle_add (update_appointment_menu_items_idle, self);
-}
-
-static void
-hide_all_appointments (IndicatorDatetimeService * self)
-{
- int i;
-
- for (i=0; i<MAX_APPOINTMENT_MENUITEMS; i++)
- {
- if (self->appointment_menuitems[i])
- {
- dbusmenu_menuitem_property_set_bool (self->appointment_menuitems[i], DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
- dbusmenu_menuitem_property_set_bool (self->appointment_menuitems[i], DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
- }
- }
-}
-
-static gboolean
-month_changed_cb (DbusmenuMenuitem * menuitem,
- gchar * name G_GNUC_UNUSED,
- GVariant * variant,
- guint timestamp G_GNUC_UNUSED,
- gpointer gself)
-{
- IndicatorDatetimeService * self = gself;
-
- self->start_time_appointments = (time_t)g_variant_get_uint32(variant);
-
- g_debug("Received month changed with timestamp: %d -> %s",(int)self->start_time_appointments, ctime(&self->start_time_appointments));
-
- /* By default, one of the first things we do is
- clear the marks as we don't know the correct
- ones yet and we don't want to confuse the user. */
-
- dbusmenu_menuitem_property_remove(menuitem, CALENDAR_MENUITEM_PROP_MARKS);
-
- update_appointment_menu_items_soon (self);
- return TRUE;
-}
-
-static gboolean
-day_selected_cb (DbusmenuMenuitem * menuitem,
- gchar * name G_GNUC_UNUSED,
- GVariant * variant,
- guint timestamp G_GNUC_UNUSED,
- gpointer gself)
-{
- time_t new_time;
- IndicatorDatetimeService * self = gself;
-
- new_time = (time_t)g_variant_get_uint32(variant);
-
- if (self->start_time_appointments == 0 || new_time == 0)
- {
- /* If we've got nothing, assume everyhting is going to
- get repopulated, let's start with a clean slate */
- dbusmenu_menuitem_property_remove (menuitem, CALENDAR_MENUITEM_PROP_MARKS);
- }
- else
- {
- /* No check to see if we changed months. If we did we'll
- want to clear the marks. Otherwise we're cool keeping
- them around. */
- struct tm start_tm;
- struct tm new_tm;
-
- localtime_r (&self->start_time_appointments, &start_tm);
- localtime_r (&new_time, &new_tm);
-
- if (start_tm.tm_mon != new_tm.tm_mon)
- dbusmenu_menuitem_property_remove(menuitem, CALENDAR_MENUITEM_PROP_MARKS);
- }
-
- self->start_time_appointments = new_time;
-
- g_debug ("Received day-selected with timestamp: %d -> %s",(int)self->start_time_appointments, ctime(&self->start_time_appointments));
- update_appointment_menu_items_soon (self);
-
- return TRUE;
-}
-
-static gboolean
-day_selected_double_click_cb (DbusmenuMenuitem * menuitem G_GNUC_UNUSED,
- gchar * name G_GNUC_UNUSED,
- GVariant * variant,
- guint timestamp G_GNUC_UNUSED,
- gpointer gself)
-{
- time_t evotime;
- GDateTime * dt;
- IndicatorDatetimeService * self = gself;
-
- evotime = (time_t) g_variant_get_uint32 (variant);
- dt = g_date_time_new_from_unix_utc (evotime);
- indicator_datetime_planner_activate_time (self->planner, dt);
- g_date_time_unref (dt);
-
- return TRUE;
-}
-
-
-static gboolean
-update_appointment_menu_items_timerfunc (gpointer self)
-{
- update_appointment_menu_items (self);
- return G_SOURCE_CONTINUE;
-}
-
-static void
-start_ecal_timer (IndicatorDatetimeService * self)
-{
- if (self->ecaltimer != 0)
- self->ecaltimer = g_timeout_add_seconds (60*5, update_appointment_menu_items_timerfunc, self);
-}
-
-static void
-stop_ecal_timer (IndicatorDatetimeService * self)
-{
- if (self->ecaltimer != 0)
- {
- g_source_remove (self->ecaltimer);
- self->ecaltimer = 0;
- }
-}
-
-static gboolean
-idle_start_ecal_timer (gpointer gself)
-{
- start_ecal_timer (gself);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-show_events_changed (IndicatorDatetimeService * self)
-{
- const gboolean b = g_settings_get_boolean (self->conf, SETTINGS_SHOW_EVENTS_S);
-
- dbusmenu_menuitem_property_set_bool (self->add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, b);
- dbusmenu_menuitem_property_set_bool (self->events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, b);
-
- if (b)
- {
- start_ecal_timer (self);
- }
- else
- {
- hide_all_appointments (self);
- stop_ecal_timer (self);
- }
-}
-
-
-/* Looks for the calendar application and enables the item if
- we have one, starts ecal timer if events are turned on */
-static gboolean
-check_for_calendar (gpointer gself)
-{
- gboolean b;
- IndicatorDatetimeService * self = gself;
-
- g_return_val_if_fail (self->calendar != NULL, FALSE);
-
- dbusmenu_menuitem_property_set_bool(self->date, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
-
- if (!get_greeter_mode () && indicator_datetime_planner_is_configured(self->planner)) {
-
- int i;
- int pos = 2;
-
- g_signal_connect (G_OBJECT(self->date), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- G_CALLBACK (activate_cb), "evolution -c calendar");
-
- self->events_separator = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(self->events_separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
- dbusmenu_menuitem_child_add_position(root, self->events_separator, pos++);
-
- for (i=0; i<MAX_APPOINTMENT_MENUITEMS; i++)
- {
- DbusmenuMenuitem * item = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, APPOINTMENT_MENUITEM_TYPE);
- dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
- dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
- self->appointment_menuitems[i] = item;
- dbusmenu_menuitem_child_add_position(root, item, pos++);
- }
-
- self->add_appointment = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (self->add_appointment, DBUSMENU_MENUITEM_PROP_LABEL, _("Add Event…"));
- dbusmenu_menuitem_property_set_bool(self->add_appointment, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
- g_signal_connect(G_OBJECT(self->add_appointment), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), "evolution -c calendar");
- dbusmenu_menuitem_child_add_position (root, self->add_appointment, pos++);
-
- if (g_settings_get_boolean(self->conf, SETTINGS_SHOW_EVENTS_S)) {
- dbusmenu_menuitem_property_set_bool(self->add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
- dbusmenu_menuitem_property_set_bool(self->events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
- g_idle_add((GSourceFunc)idle_start_ecal_timer, self);
- } else {
- dbusmenu_menuitem_property_set_bool(self->add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
- dbusmenu_menuitem_property_set_bool(self->events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
- stop_ecal_timer (self);
- }
-
- // Connect to calendar events
- g_signal_connect(self->calendar, "event::month-changed", G_CALLBACK(month_changed_cb), self);
- g_signal_connect(self->calendar, "event::day-selected", G_CALLBACK(day_selected_cb), self);
- g_signal_connect(self->calendar, "event::day-selected-double-click", G_CALLBACK(day_selected_double_click_cb), self);
- } else {
- g_debug("Unable to find calendar app.");
- if (self->add_appointment != NULL)
- dbusmenu_menuitem_property_set_bool(self->add_appointment, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
- if (self->events_separator != NULL)
- dbusmenu_menuitem_property_set_bool(self->events_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
- }
-
- b = g_settings_get_boolean (self->conf, SETTINGS_SHOW_CALENDAR_S);
- dbusmenu_menuitem_property_set_bool(self->calendar, DBUSMENU_MENUITEM_PROP_ENABLED, b);
- dbusmenu_menuitem_property_set_bool(self->calendar, DBUSMENU_MENUITEM_PROP_VISIBLE, b);
-
- return FALSE;
-}
-
-static GdkPixbuf *
-create_color_icon_pixbuf (const char * color_spec)
-{
- static int width = -1;
- static int height = -1;
- GdkPixbuf * pixbuf = NULL;
-
- if (width == -1)
- {
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
- width = CLAMP (width, 10, 30);
- height = CLAMP (height, 10, 30);
- }
-
- if (color_spec && *color_spec)
- {
- cairo_surface_t * surface;
- cairo_t * cr;
- GdkRGBA rgba;
-
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
- cr = cairo_create (surface);
-
- if (gdk_rgba_parse (&rgba, color_spec))
- gdk_cairo_set_source_rgba (cr, &rgba);
-
- cairo_paint (cr);
- cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
- cairo_set_line_width (cr, 1);
- cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
- cairo_stroke (cr);
-
- pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
-
- cairo_destroy (cr);
- cairo_surface_destroy (surface);
- }
-
- return pixbuf;
-}
-
-
-/**
- * Populate the menu with todays, next MAX_APPOINTMENT_MENUITEMS appointments.
- * we should hook into the ABOUT TO SHOW signal and use that to update the appointments.
- * Experience has shown that caldav's and webcals can be slow to load from eds
- * this is a problem mainly on the EDS side of things, not ours.
- */
-static void
-update_appointment_menu_items (IndicatorDatetimeService * self)
-{
- char * str;
- GSList * l;
- GSList * appointments;
- gint i;
- GDateTime * begin;
- GDateTime * end;
- GdkPixbuf * pixbuf;
- gint apt_output;
- GVariantBuilder markeddays;
- GVariant * marks;
-
- // FFR: we should take into account short term timers, for instance
- // tea timers, pomodoro timers etc... that people may add, this is hinted to in the spec.
-
- g_debug ("Update appointments called");
-
- if (self->calendar == NULL)
- return;
- if (!g_settings_get_boolean (self->conf, SETTINGS_SHOW_EVENTS_S))
- return;
- if (self->updating_appointments)
- return;
-
- self->updating_appointments = TRUE;
-
- g_variant_builder_init (&markeddays, G_VARIANT_TYPE ("ai"));
-
- if (self->start_time_appointments != 0)
- begin = g_date_time_new_from_unix_local (self->start_time_appointments);
- else
- begin = g_date_time_new_now_local (); /* FIXME: unmockable */
- end = g_date_time_add_months (begin, 1);
- indicator_datetime_planner_set_timezone (self->planner, indicator_datetime_timezone_get_timezone (self->tz_file));
- appointments = indicator_datetime_planner_get_appointments (self->planner, begin, end);
-
- hide_all_appointments (self);
-
- /* decide whether to use 12hr or 24hr format */
- str = g_settings_get_string (self->conf, SETTINGS_TIME_FORMAT_S);
- if (g_strcmp0 (str, "12-hour") == 0)
- apt_output = SETTINGS_TIME_12_HOUR;
- else if (g_strcmp0 (str, "24-hour") == 0)
- apt_output = SETTINGS_TIME_24_HOUR;
- else if (is_locale_12h())
- apt_output = SETTINGS_TIME_12_HOUR;
- else
- apt_output = SETTINGS_TIME_24_HOUR;
- g_free (str);
-
- i = 0;
- for (l=appointments; l!=NULL; l=l->next)
- {
- GDateTime * due;
- DbusmenuMenuitem * item;
- const struct IndicatorDatetimeAppt * appt = l->data;
- char * right = NULL;
-
- due = appt->is_event ? appt->begin : appt->end;
-
- /* mark day if our query hasn't hit the next month. */
- if (g_date_time_get_month (begin) == g_date_time_get_month (due))
- g_variant_builder_add (&markeddays, "i", g_date_time_get_day_of_month (due));
-
- if (i >= MAX_APPOINTMENT_MENUITEMS)
- continue;
-
- item = self->appointment_menuitems[i];
- i++;
-
- /* remove the icon as we might not replace it on error */
- dbusmenu_menuitem_property_remove(item, APPOINTMENT_MENUITEM_PROP_ICON);
-
- /* remove the activate handler */
- g_signal_handlers_disconnect_matched(G_OBJECT(item), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(activate_cb), NULL);
-
- dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
- dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
- dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_LABEL, appt->summary);
-
- gboolean full_day = FALSE;
- if (appt->is_event)
- full_day = g_date_time_difference (appt->end, appt->begin) == G_TIME_SPAN_DAY;
-
- if (full_day)
- {
- /* TRANSLATORS: This is a strftime string for the day for full day events
- in the menu. It should most likely be either '%A' for a full text day
- (Wednesday) or '%a' for a shortened one (Wed). You should only need to
- change for '%a' in the case of languages with very long day names. */
- right = g_date_time_format (due, _("%A"));
- }
- else
- {
- int ay, am, ad;
- int by, bm, bd;
- gboolean same_day;
- gboolean hr12;
- const char * fmt;
-
- g_date_time_get_ymd (due, &ay, &am, &ad);
- g_date_time_get_ymd (begin, &by, &bm, &bd);
- same_day = (ay==by) && (am==bm) && (ad==bd);
- hr12 = apt_output == SETTINGS_TIME_12_HOUR;
-
- if (same_day && hr12)
- fmt = _(DEFAULT_TIME_12_FORMAT);
- else if (same_day)
- fmt = _(DEFAULT_TIME_24_FORMAT);
- else if (hr12)
- fmt = _(DEFAULT_TIME_12_FORMAT_WITH_DAY);
- else
- fmt = _(DEFAULT_TIME_24_FORMAT_WITH_DAY);
-
- right = g_date_time_format (due, fmt);
- }
-
- dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, right);
- g_free (right);
-
- // Now we pull out the URI for the calendar event and try to create a URI that'll work when we execute evolution
- // FIXME Because the URI stuff is really broken, we're going to open the calendar at todays date instead
- //e_cal_component_get_uid(ecalcomp, &uri);
-/* FIXME: appointment menuitems aren't clickable */
-#if 0
- gchar * ad = isodate_from_time_t(mktime(due));
- gchar * cmd = g_strconcat("evolution calendar:///?startdate=", ad, NULL);
- g_debug("Command to Execute: %s", cmd);
- g_signal_connect_data (G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- G_CALLBACK(activate_cb), cmd, (GClosureNotify)g_free, 0);
- g_free (ad);
-#endif
-
- if ((pixbuf = create_color_icon_pixbuf (appt->color)))
- {
- dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
- g_clear_object (&pixbuf);
- }
- }
-
-
- marks = g_variant_builder_end (&markeddays);
- dbusmenu_menuitem_property_set_variant (self->calendar, CALENDAR_MENUITEM_PROP_MARKS, marks);
-
- g_slist_free_full (appointments, (GDestroyNotify)indicator_datetime_appt_free);
-
- self->updating_appointments = FALSE;
- g_date_time_unref (end);
- g_date_time_unref (begin);
-}
-
-/* Looks for the time and date admin application and enables the
- item we have one */
-static gboolean
-check_for_timeadmin (gpointer gself)
-{
- gchar * timeadmin;
- IndicatorDatetimeService * self = gself;
-
- g_return_val_if_fail (self->settings != NULL, FALSE);
-
- timeadmin = g_find_program_in_path ("gnome-control-center");
- if (timeadmin != NULL)
- {
- g_debug ("Found the gnome-control-center application: %s", timeadmin);
- dbusmenu_menuitem_property_set_bool (self->settings, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
- g_free(timeadmin);
- }
- else
- {
- g_debug ("Unable to find gnome-control-center app.");
- dbusmenu_menuitem_property_set_bool (self->settings, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
- }
-
- return G_SOURCE_REMOVE;
-}
-
-/* Does the work to build the default menu, really calls out
- to other functions but this is the core to clean up the
- main function. */
-static void
-build_menus (IndicatorDatetimeService * self, DbusmenuMenuitem * root)
-{
- g_debug("Building Menus.");
- if (self->date == NULL) {
- self->date = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (self->date, DBUSMENU_MENUITEM_PROP_LABEL, _("No date yet…"));
- dbusmenu_menuitem_property_set_bool(self->date, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
- dbusmenu_menuitem_child_append(root, self->date);
-
- g_idle_add(update_datetime, self);
- }
-
- if (self->calendar == NULL) {
- self->calendar = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (self->calendar, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CALENDAR_MENUITEM_TYPE);
- /* insensitive until we check for available apps */
- dbusmenu_menuitem_property_set_bool(self->calendar, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
- g_signal_connect (G_OBJECT(self->calendar), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- G_CALLBACK (activate_cb), "evolution -c calendar");
- dbusmenu_menuitem_child_append(root, self->calendar);
-
- g_idle_add(check_for_calendar, self);
- }
-
- if (!get_greeter_mode ()) {
- self->locations_separator = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(self->locations_separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
- dbusmenu_menuitem_property_set_bool (self->locations_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
- dbusmenu_menuitem_child_append(root, self->locations_separator);
-
- update_location_menu_items (self);
-
- g_signal_connect (self->conf, "changed::" SETTINGS_SHOW_EVENTS_S, G_CALLBACK (show_events_changed), self);
- g_signal_connect_swapped (self->conf, "changed::" SETTINGS_SHOW_LOCATIONS_S, G_CALLBACK (update_location_menu_items), self);
- g_signal_connect_swapped (self->conf, "changed::" SETTINGS_SHOW_DETECTED_S, G_CALLBACK (update_location_menu_items), self);
- g_signal_connect_swapped (self->conf, "changed::" SETTINGS_LOCATIONS_S, G_CALLBACK (update_location_menu_items), self);
- g_signal_connect_swapped (self->conf, "changed::" SETTINGS_TIME_FORMAT_S, G_CALLBACK (update_appointment_menu_items), self);
-
- DbusmenuMenuitem * separator = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
- dbusmenu_menuitem_child_append(root, separator);
-
- self->settings = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (self->settings, DBUSMENU_MENUITEM_PROP_LABEL, _("Time & Date Settings…"));
- /* insensitive until we check for available apps */
- dbusmenu_menuitem_property_set_bool(self->settings, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
- g_signal_connect(G_OBJECT(self->settings), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), SETTINGS_APP_INVOCATION);
- dbusmenu_menuitem_child_append(root, self->settings);
- g_idle_add(check_for_timeadmin, self);
- update_appointment_menu_items_soon (self);
- }
-
- return;
-}
-
-static void
-on_clock_skew (gpointer self)
-{
- /* tell the indicators to refresh */
- if (IS_DATETIME_INTERFACE (dbus))
- datetime_interface_update (DATETIME_INTERFACE(dbus));
-
- /* update our day label */
- update_datetime (self);
- day_timer_reset (self);
-}
-
-static void
-on_timezone_changed (gpointer self)
-{
- update_location_menu_items (self);
-
- on_clock_skew (self);
-}
-
-/* Execute at a given time, update and setup a new
- timer to go again. */
-static gboolean
-day_timer_func (gpointer self)
-{
- day_timer_reset (self);
- update_datetime (self);
-
- return G_SOURCE_REMOVE;
-}
-
-/* Sets up the time to launch the timer to update the
- date in the datetime entry */
-static void
-day_timer_reset (IndicatorDatetimeService * self)
-{
- GDateTime * now;
- GDateTime * tomorrow;
- GDateTime * new_day;
- guint seconds_until_tomorrow;
-
- if (self->day_timer != 0)
- {
- g_source_remove (self->day_timer);
- self->day_timer = 0;
- }
-
- now = g_date_time_new_now_local ();
- tomorrow = g_date_time_add_days (now, 1);
- new_day = g_date_time_new_local (g_date_time_get_year (tomorrow),
- g_date_time_get_month (tomorrow),
- g_date_time_get_day_of_month (tomorrow),
- 0, 0, 0);
- seconds_until_tomorrow = (guint)(g_date_time_difference (new_day, now) / G_TIME_SPAN_SECOND);
-g_message ("seconds until tomorrow is %u", seconds_until_tomorrow);
-
- self->day_timer = g_timeout_add_seconds (seconds_until_tomorrow + 15,
- day_timer_func,
- self);
-
- g_date_time_unref (new_day);
- g_date_time_unref (tomorrow);
- g_date_time_unref (now);
-}
-
-static gboolean
-skew_check_timer_func (gpointer self)
-{
- static time_t prev_time = 0;
- const time_t cur_time = time (NULL); /* FIXME: unmockable */
- const double diff_sec = fabs (difftime (cur_time, prev_time));
-
- if (prev_time && (diff_sec > SKEW_DIFF_THRESHOLD_SEC))
- {
- g_debug (G_STRLOC" clock skew detected (%.0f seconds)", diff_sec);
- on_clock_skew (self);
- }
-
- prev_time = cur_time;
- return G_SOURCE_CONTINUE;
-}
-
-static void
-session_active_change_cb (GDBusProxy * proxy G_GNUC_UNUSED,
- gchar * sender_name G_GNUC_UNUSED,
- gchar * signal_name,
- GVariant * parameters,
- gpointer gself)
-{
- IndicatorDatetimeService * self = gself;
-
- /* suspending / returning from suspend (true / false) */
- if (g_strcmp0(signal_name, "PrepareForSleep") == 0)
- {
- gboolean sleeping = FALSE;
- g_variant_get (parameters, "(b)", &sleeping);
- if (!sleeping)
- {
- g_debug ("System has been resumed; adjusting clock");
- on_clock_skew (self);
- }
- }
-}
-
-/* for hooking into console kit signal on wake from suspend */
-static void
-system_proxy_cb (GObject * object G_GNUC_UNUSED,
- GAsyncResult * res,
- gpointer gself)
-{
- GError * error = NULL;
-
- GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
-
- if (error != NULL) {
- g_warning("Could not grab DBus proxy for logind: %s", error->message);
- g_clear_error (&error);
- return;
- }
-
- g_signal_connect(proxy, "g-signal", G_CALLBACK(session_active_change_cb), gself);
-}
-
-/****
-*****
-****/
-
-static gboolean
-get_greeter_mode (void)
-{
- const gchar *var;
- var = g_getenv("INDICATOR_GREETER_MODE");
- return (g_strcmp0(var, "1") == 0);
-}
-
-/* Repsonds to the service object saying it's time to shutdown.
- It stops the mainloop. */
-static void
-service_shutdown (IndicatorService * service G_GNUC_UNUSED,
- gpointer gmainloop)
-{
- g_warning ("Shutting down service!");
- g_main_loop_quit (gmainloop);
-}
-
-static void
-on_use_geoclue_changed_cb (GSettings * settings,
- gchar * key G_GNUC_UNUSED,
- gpointer gself)
-{
- IndicatorDatetimeService * self = gself;
- const gboolean use_geoclue = g_settings_get_boolean (settings, "show-auto-detected-location");
-
- if (self->geo_location && !use_geoclue)
- {
- g_signal_handlers_disconnect_by_func (self->geo_location, update_location_menu_items, self);
- g_clear_object (&self->geo_location);
- update_location_menu_items (self);
- }
- else if (use_geoclue && !self->geo_location)
- {
- self->geo_location = indicator_datetime_timezone_geoclue_new ();
- g_signal_connect_swapped (self->geo_location, "notify::timezone",
- G_CALLBACK(update_location_menu_items), self);
- }
-}
-
-/* Function to build everything up. Entry point from asm. */
-int
-main (int argc, char ** argv)
-{
- GMainLoop * mainloop;
- IndicatorService * service;
- DbusmenuServer * server;
- struct IndicatorDatetimeService self;
-
- memset (&self, 0, sizeof(struct IndicatorDatetimeService));
-
- gtk_init (&argc, &argv);
- mainloop = g_main_loop_new (NULL, FALSE);
-
- /* acknowledging the service init and setting up the interface */
- service = indicator_service_new_version(SERVICE_NAME, SERVICE_VERSION);
- g_signal_connect (service, INDICATOR_SERVICE_SIGNAL_SHUTDOWN,
- G_CALLBACK(service_shutdown), mainloop);
-
- /* setting up i18n and gettext. apparently we need all of these. */
- setlocale (LC_ALL, "");
- bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
- textdomain (GETTEXT_PACKAGE);
-
- /* set up GSettings */
- self.conf = g_settings_new (SETTINGS_INTERFACE);
- g_signal_connect (self.conf, "changed::show-auto-detected-location",
- G_CALLBACK(on_use_geoclue_changed_cb), &self);
-
- /* setup geoclue */
- on_use_geoclue_changed_cb (self.conf, NULL, &self);
-
- /* setup timezone watch */
- self.tz_file = indicator_datetime_timezone_file_new (TIMEZONE_FILE);
- g_signal_connect_swapped (self.tz_file, "notify::timezone",
- G_CALLBACK(on_timezone_changed), &self);
-
- /* build our list of appointment calendar sources.
- When a source changes, update our menu items.
- When sources are added or removed, update our list and menu items. */
- self.planner = indicator_datetime_planner_eds_new ();
- g_signal_connect_swapped (self.planner, "appointments-changed",
- G_CALLBACK(update_appointment_menu_items_soon), &self);
-
- /* building the base menu */
- server = dbusmenu_server_new (MENU_OBJ);
- root = dbusmenu_menuitem_new ();
- dbusmenu_server_set_root (server, root);
-
- build_menus (&self, root);
-
- /* cache the timezone */
- update_location_menu_items (&self);
-
- /* setup dbus interface */
- dbus = g_object_new (DATETIME_INTERFACE_TYPE, NULL);
-
- /* set up the day timer */
- day_timer_reset (&self);
-
- /* set up the skew-check timer */
- g_timeout_add_seconds (SKEW_CHECK_INTERVAL_SEC,
- skew_check_timer_func,
- &self);
-
- /* and watch for system resumes */
- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- NULL, /* FIXME: cancellable */
- system_proxy_cb,
- &self);
-
- g_main_loop_run (mainloop);
- g_main_loop_unref (mainloop);
-
- g_object_unref (self.conf);
- g_object_unref (dbus);
- g_object_unref (service);
- g_object_unref (server);
- g_object_unref (root);
- g_object_unref (self.planner);
- g_object_unref (self.geo_location);
- g_object_unref (self.tz_file);
-
- return 0;
-}
diff --git a/src/datetime-service.xml b/src/datetime-service.xml
deleted file mode 100644
index eda064f..0000000
--- a/src/datetime-service.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<node name="/">
- <interface name="com.canonical.indicator.datetime.service">
-
-<!-- Methods -->
-
-<!-- Signals -->
- <signal name="UpdateTime" />
-
- </interface>
-</node>
diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c
deleted file mode 100644
index f7d1a78..0000000
--- a/src/indicator-datetime.c
+++ /dev/null
@@ -1,1535 +0,0 @@
-/*
-An indicator to time and date related information in the menubar.
-
-Copyright 2010 Canonical Ltd.
-
-Authors:
- Ted Gould <ted@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <locale.h>
-#include <langinfo.h>
-#include <string.h>
-#include <time.h>
-
-/* GStuff */
-#include <glib.h>
-#include <glib/gprintf.h>
-#include <glib-object.h>
-#include <glib/gi18n-lib.h>
-#include <gio/gio.h>
-
-/* Indicator Stuff */
-#include <libindicator/indicator.h>
-#include <libindicator/indicator-object.h>
-#include <libindicator/indicator-service-manager.h>
-
-/* DBusMenu */
-#include <libdbusmenu-gtk/menu.h>
-#include <libido/libido.h>
-#include <libdbusmenu-gtk/menuitem.h>
-
-#include "utils.h"
-#include "dbus-shared.h"
-#include "settings-shared.h"
-
-
-#define INDICATOR_DATETIME_TYPE (indicator_datetime_get_type ())
-#define INDICATOR_DATETIME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_DATETIME_TYPE, IndicatorDatetime))
-#define INDICATOR_DATETIME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_DATETIME_TYPE, IndicatorDatetimeClass))
-#define IS_INDICATOR_DATETIME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_DATETIME_TYPE))
-#define IS_INDICATOR_DATETIME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_DATETIME_TYPE))
-#define INDICATOR_DATETIME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_DATETIME_TYPE, IndicatorDatetimeClass))
-
-typedef struct _IndicatorDatetime IndicatorDatetime;
-typedef struct _IndicatorDatetimeClass IndicatorDatetimeClass;
-typedef struct _IndicatorDatetimePrivate IndicatorDatetimePrivate;
-
-struct _IndicatorDatetimeClass {
- IndicatorObjectClass parent_class;
-};
-
-struct _IndicatorDatetime {
- IndicatorObject parent;
- IndicatorDatetimePrivate * priv;
-};
-
-struct _IndicatorDatetimePrivate {
- GtkLabel * label;
- guint timer;
-
- gchar * time_string;
-
- gboolean show_clock;
- gint time_mode;
- gboolean show_seconds;
- gboolean show_date;
- gboolean show_day;
- gchar * custom_string;
- gboolean custom_show_seconds;
-
- gboolean show_week_numbers;
- gboolean show_calendar;
- gint week_start;
-
- guint idle_measure;
- gint max_width;
-
- IndicatorServiceManager * sm;
- DbusmenuGtkMenu * menu;
-
- GCancellable * service_proxy_cancel;
- GDBusProxy * service_proxy;
- IdoCalendarMenuItem *ido_calendar;
-
- GList * timezone_items;
-
- GSettings * settings;
-
- GtkSizeGroup * indicator_right_group;
-};
-
-/* Enum for the properties so that they can be quickly
- found and looked up. */
-enum {
- PROP_0,
- PROP_SHOW_CLOCK,
- PROP_TIME_FORMAT,
- PROP_SHOW_SECONDS,
- PROP_SHOW_DAY,
- PROP_SHOW_DATE,
- PROP_CUSTOM_TIME_FORMAT,
- PROP_SHOW_WEEK_NUMBERS,
- PROP_SHOW_CALENDAR
-};
-
-typedef struct _indicator_item_t indicator_item_t;
-struct _indicator_item_t {
- IndicatorDatetime * self;
- DbusmenuMenuitem * mi;
- GtkWidget * gmi;
- GtkWidget * icon;
- GtkWidget * label;
- GtkWidget * right;
-};
-
-#define PROP_SHOW_CLOCK_S "show-clock"
-#define PROP_TIME_FORMAT_S "time-format"
-#define PROP_SHOW_SECONDS_S "show-seconds"
-#define PROP_SHOW_DAY_S "show-day"
-#define PROP_SHOW_DATE_S "show-date"
-#define PROP_CUSTOM_TIME_FORMAT_S "custom-time-format"
-#define PROP_SHOW_WEEK_NUMBERS_S "show-week-numbers"
-#define PROP_SHOW_CALENDAR_S "show-calendar"
-
-enum {
- STRFTIME_MASK_NONE = 0, /* Hours or minutes as we always test those */
- STRFTIME_MASK_SECONDS = 1 << 0, /* Seconds count */
- STRFTIME_MASK_AMPM = 1 << 1, /* AM/PM counts */
- STRFTIME_MASK_WEEK = 1 << 2, /* Day of the week maters (Sat, Sun, etc.) */
- STRFTIME_MASK_DAY = 1 << 3, /* Day of the month counts (Feb 1st) */
- STRFTIME_MASK_MONTH = 1 << 4, /* Which month matters */
- STRFTIME_MASK_YEAR = 1 << 5, /* Which year matters */
- /* Last entry, combines all previous */
- STRFTIME_MASK_ALL = (STRFTIME_MASK_SECONDS | STRFTIME_MASK_AMPM | STRFTIME_MASK_WEEK | STRFTIME_MASK_DAY | STRFTIME_MASK_MONTH | STRFTIME_MASK_YEAR)
-};
-
-GType indicator_datetime_get_type (void) G_GNUC_CONST;
-
-static void indicator_datetime_class_init (IndicatorDatetimeClass *klass);
-static void indicator_datetime_init (IndicatorDatetime *self);
-static void timezone_update_all_labels (IndicatorDatetime *self);
-static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
-static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
-static void indicator_datetime_dispose (GObject *object);
-static void indicator_datetime_finalize (GObject *object);
-static GtkLabel * get_label (IndicatorObject * io);
-static GtkMenu * get_menu (IndicatorObject * io);
-static const gchar * get_accessible_desc (IndicatorObject * io);
-static const gchar * get_name_hint (IndicatorObject * io);
-static gboolean bind_enum_get (GValue * value, GVariant * variant, gpointer user_data);
-static gchar * generate_format_string_now (IndicatorDatetime * self);
-static void update_label (IndicatorDatetime * io, GDateTime ** datetime);
-static void guess_label_size (IndicatorDatetime * self);
-static void setup_timer (IndicatorDatetime * self, GDateTime * datetime);
-static void update_time (IndicatorDatetime * self);
-static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data);
-static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data);
-static gint generate_strftime_bitmask (const char *time_str);
-static void timezone_update_labels (indicator_item_t * mi_data);
-static gboolean new_calendar_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
-static gboolean new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
-static gboolean new_timezone_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
-
-/* Indicator Module Config */
-INDICATOR_SET_VERSION
-INDICATOR_SET_TYPE(INDICATOR_DATETIME_TYPE)
-
-G_DEFINE_TYPE (IndicatorDatetime, indicator_datetime, INDICATOR_OBJECT_TYPE);
-
-static void
-indicator_datetime_class_init (IndicatorDatetimeClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (IndicatorDatetimePrivate));
-
- object_class->dispose = indicator_datetime_dispose;
- object_class->finalize = indicator_datetime_finalize;
-
- object_class->set_property = set_property;
- object_class->get_property = get_property;
-
- IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
-
- io_class->get_label = get_label;
- io_class->get_menu = get_menu;
- io_class->get_accessible_desc = get_accessible_desc;
- io_class->get_name_hint = get_name_hint;
-
- g_object_class_install_property (object_class,
- PROP_SHOW_CLOCK,
- g_param_spec_boolean(PROP_SHOW_CLOCK_S,
- "Whether to show the clock in the menu bar.",
- "Shows indicator-datetime in the shell's menu bar.",
- TRUE, /* default */
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class,
- PROP_TIME_FORMAT,
- g_param_spec_int(PROP_TIME_FORMAT_S,
- "A choice of which format should be used on the panel",
- "Chooses between letting the locale choose the time, 12-hour time, 24-time or using the custom string passed to g_date_time_format().",
- SETTINGS_TIME_LOCALE, /* min */
- SETTINGS_TIME_CUSTOM, /* max */
- SETTINGS_TIME_LOCALE, /* default */
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class,
- PROP_SHOW_SECONDS,
- g_param_spec_boolean(PROP_SHOW_SECONDS_S,
- "Whether to show seconds in the indicator.",
- "Shows seconds along with the time in the indicator. Also effects refresh interval.",
- FALSE, /* default */
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class,
- PROP_SHOW_DAY,
- g_param_spec_boolean(PROP_SHOW_DAY_S,
- "Whether to show the day of the week in the indicator.",
- "Shows the day of the week along with the time in the indicator.",
- FALSE, /* default */
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class,
- PROP_SHOW_DATE,
- g_param_spec_boolean(PROP_SHOW_DATE_S,
- "Whether to show the day and month in the indicator.",
- "Shows the day and month along with the time in the indicator.",
- FALSE, /* default */
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class,
- PROP_CUSTOM_TIME_FORMAT,
- g_param_spec_string(PROP_CUSTOM_TIME_FORMAT_S,
- "The format that is used to show the time on the panel.",
- "A format string in the form used to pass to g_date_time_format() to make a string for displaying on the panel.",
- DEFAULT_TIME_FORMAT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (object_class,
- PROP_SHOW_WEEK_NUMBERS,
- g_param_spec_boolean(PROP_SHOW_WEEK_NUMBERS_S,
- "Whether to show the week numbers in the calendar.",
- "Shows the week numbers in the monthly calendar in indicator-datetime's menu.",
- FALSE, /* default */
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class,
- PROP_SHOW_CALENDAR,
- g_param_spec_boolean(PROP_SHOW_CALENDAR_S,
- "Whether to show the calendar.",
- "Shows the monthly calendar in indicator-datetime's menu.",
- TRUE, /* default */
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- return;
-}
-
-static void
-menu_visible_notify_cb(GtkWidget * menu, G_GNUC_UNUSED GParamSpec *pspec, gpointer user_data)
-{
- IndicatorDatetime * self;
- g_debug ("notify visible signal received");
-
- self = INDICATOR_DATETIME (user_data);
- g_assert (self != NULL);
-
- /* if the calendar widget's been created, set it to today's datë */
- if (self->priv->ido_calendar != NULL) {
- GtkWidget * w;
- GtkCalendar * calendar;
- gint cur_y, cur_m, cur_d;
- guint cal_y, cal_m, cal_d;
- GDateTime * datetime = g_date_time_new_now_local ();
-
- g_date_time_get_ymd (datetime, &cur_y, &cur_m, &cur_d);
- w = ido_calendar_menu_item_get_calendar (self->priv->ido_calendar);
- calendar = GTK_CALENDAR(w);
- g_return_if_fail (calendar != NULL);
-
- gtk_calendar_get_date (calendar, &cal_y, &cal_m, &cal_d);
- if ((cur_y != cal_y) || (cur_m-1 != cal_m))
- gtk_calendar_select_month (calendar, cur_m-1, cur_y); /* (cur_m is 1-based) */
- if (cur_d != cal_d)
- gtk_calendar_select_day (calendar, cur_d);
-
- g_date_time_unref (datetime);
- }
-
- /* Update in case date was changed outside of indicator-datetime */
- update_label(self, NULL);
- timezone_update_all_labels(self);
-
- // Make sure the day-selected signal is sent so the menu updates - may duplicate
- /*GVariant *variant = g_variant_new_uint32((guint)curtime);
- guint timestamp = (guint)time(NULL);
- dbusmenu_menuitem_handle_event(DBUSMENU_MENUITEM(self->priv->ido_calendar), "day-selected", variant, timestamp);*/
-}
-
-static void
-indicator_datetime_init (IndicatorDatetime *self)
-{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- INDICATOR_DATETIME_TYPE,
- IndicatorDatetimePrivate);
-
- self->priv->label = NULL;
- self->priv->timer = 0;
-
- self->priv->idle_measure = 0;
- self->priv->max_width = 0;
-
- self->priv->show_clock = TRUE;
- self->priv->time_mode = SETTINGS_TIME_LOCALE;
- self->priv->show_seconds = FALSE;
- self->priv->show_date = FALSE;
- self->priv->show_day = FALSE;
- self->priv->custom_string = g_strdup(DEFAULT_TIME_FORMAT);
- self->priv->custom_show_seconds = FALSE;
-
- self->priv->time_string = generate_format_string_now(self);
-
- self->priv->service_proxy = NULL;
-
- self->priv->sm = NULL;
- self->priv->menu = NULL;
-
- self->priv->settings = g_settings_new(SETTINGS_INTERFACE);
- if (self->priv->settings != NULL) {
- g_settings_bind(self->priv->settings,
- SETTINGS_SHOW_CLOCK_S,
- self,
- PROP_SHOW_CLOCK_S,
- G_SETTINGS_BIND_GET);
- g_settings_bind_with_mapping(self->priv->settings,
- SETTINGS_TIME_FORMAT_S,
- self,
- PROP_TIME_FORMAT_S,
- G_SETTINGS_BIND_GET,
- bind_enum_get,
- NULL, NULL, NULL); /* set mapping, userdata and destroy func */
- g_settings_bind(self->priv->settings,
- SETTINGS_SHOW_SECONDS_S,
- self,
- PROP_SHOW_SECONDS_S,
- G_SETTINGS_BIND_GET);
- g_settings_bind(self->priv->settings,
- SETTINGS_SHOW_DAY_S,
- self,
- PROP_SHOW_DAY_S,
- G_SETTINGS_BIND_GET);
- g_settings_bind(self->priv->settings,
- SETTINGS_SHOW_DATE_S,
- self,
- PROP_SHOW_DATE_S,
- G_SETTINGS_BIND_GET);
- g_settings_bind(self->priv->settings,
- SETTINGS_CUSTOM_TIME_FORMAT_S,
- self,
- PROP_CUSTOM_TIME_FORMAT_S,
- G_SETTINGS_BIND_GET);
- g_settings_bind(self->priv->settings,
- SETTINGS_SHOW_WEEK_NUMBERS_S,
- self,
- PROP_SHOW_WEEK_NUMBERS_S,
- G_SETTINGS_BIND_GET);
- g_settings_bind(self->priv->settings,
- SETTINGS_SHOW_CALENDAR_S,
- self,
- PROP_SHOW_CALENDAR_S,
- G_SETTINGS_BIND_GET);
- } else {
- g_warning("Unable to get settings for '" SETTINGS_INTERFACE "'");
- }
-
- self->priv->sm = indicator_service_manager_new_version(SERVICE_NAME, SERVICE_VERSION);
- self->priv->indicator_right_group = GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
-
- self->priv->menu = dbusmenu_gtkmenu_new(SERVICE_NAME, MENU_OBJ);
-
- g_signal_connect(self->priv->menu, "notify::visible", G_CALLBACK(menu_visible_notify_cb), self);
-
- DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(self->priv->menu);
- dbusmenu_client_add_type_handler_full(DBUSMENU_CLIENT(client), DBUSMENU_CALENDAR_MENUITEM_TYPE, new_calendar_item, self, NULL);
- dbusmenu_client_add_type_handler_full(DBUSMENU_CLIENT(client), APPOINTMENT_MENUITEM_TYPE, new_appointment_item, self, NULL);
- dbusmenu_client_add_type_handler_full(DBUSMENU_CLIENT(client), TIMEZONE_MENUITEM_TYPE, new_timezone_item, self, NULL);
-
- self->priv->service_proxy_cancel = g_cancellable_new();
-
- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- SERVICE_NAME,
- SERVICE_OBJ,
- SERVICE_IFACE,
- self->priv->service_proxy_cancel,
- service_proxy_cb,
- self);
-
- return;
-}
-
-/* Callback from trying to create the proxy for the serivce, this
- could include starting the service. Sometime it'll fail and
- we'll try to start that dang service again! */
-static void
-service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
-{
- GError * error = NULL;
-
- IndicatorDatetime * self = INDICATOR_DATETIME(user_data);
- g_return_if_fail(self != NULL);
- IndicatorDatetimePrivate * priv = self->priv;
-
- GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
-
- g_clear_object (&priv->service_proxy_cancel);
-
- if (error != NULL) {
- g_warning("Could not grab DBus proxy for %s: %s", SERVICE_NAME, error->message);
- g_error_free(error);
- return;
- }
-
- /* Okay, we're good to grab the proxy at this point, we're
- sure that it's ours. */
- priv->service_proxy = proxy;
-
- g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self);
-
- return;
-}
-
-static void
-indicator_datetime_dispose (GObject *object)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(object);
- IndicatorDatetimePrivate * priv = self->priv;
-
- if (priv->timer != 0) {
- g_source_remove(priv->timer);
- priv->timer = 0;
- }
-
- if (priv->idle_measure != 0) {
- g_source_remove(priv->idle_measure);
- priv->idle_measure = 0;
- }
-
- g_clear_object (&priv->label);
- g_clear_object (&priv->menu);
- g_clear_object (&priv->sm);
- g_clear_object (&priv->settings);
- g_clear_object (&priv->service_proxy);
- g_clear_object (&priv->indicator_right_group);
- g_clear_object (&priv->ido_calendar);
- g_clear_object (&priv->service_proxy_cancel);
-
- G_OBJECT_CLASS (indicator_datetime_parent_class)->dispose (object);
- return;
-}
-
-static void
-indicator_datetime_finalize (GObject *object)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(object);
-
- if (self->priv->time_string != NULL) {
- g_free(self->priv->time_string);
- self->priv->time_string = NULL;
- }
-
- if (self->priv->custom_string != NULL) {
- g_free(self->priv->custom_string);
- self->priv->custom_string = NULL;
- }
-
- G_OBJECT_CLASS (indicator_datetime_parent_class)->finalize (object);
- return;
-}
-
-/* Turns a string GVariant into an int value */
-static gboolean
-bind_enum_get (GValue * value, GVariant * variant, gpointer user_data)
-{
- const gchar * str = g_variant_get_string(variant, NULL);
- gint output = 0;
-
- if (g_strcmp0(str, "locale-default") == 0) {
- output = SETTINGS_TIME_LOCALE;
- } else if (g_strcmp0(str, "12-hour") == 0) {
- output = SETTINGS_TIME_12_HOUR;
- } else if (g_strcmp0(str, "24-hour") == 0) {
- output = SETTINGS_TIME_24_HOUR;
- } else if (g_strcmp0(str, "custom") == 0) {
- output = SETTINGS_TIME_CUSTOM;
- } else {
- return FALSE;
- }
-
- g_value_set_int(value, output);
- return TRUE;
-}
-
-static void
-timezone_update_all_labels (IndicatorDatetime * self)
-{
- IndicatorDatetimePrivate *priv = self->priv;
-
- g_list_foreach(priv->timezone_items, (GFunc)timezone_update_labels, NULL);
-}
-
-/* Sets a property on the object */
-static void
-set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(object);
- gboolean update = FALSE;
-
- switch(prop_id) {
- case PROP_SHOW_CLOCK: {
- if (g_value_get_boolean(value) != self->priv->show_clock) {
- self->priv->show_clock = g_value_get_boolean(value);
- if (self->priv->label != NULL) {
- gtk_widget_set_visible (GTK_WIDGET (self->priv->label), self->priv->show_clock);
- }
- }
- break;
- }
- case PROP_TIME_FORMAT: {
- gint newval = g_value_get_int(value);
- if (newval != self->priv->time_mode) {
- update = TRUE;
- self->priv->time_mode = newval;
- setup_timer(self, NULL);
- }
- break;
- }
- case PROP_SHOW_SECONDS: {
- if (g_value_get_boolean(value) != self->priv->show_seconds) {
- self->priv->show_seconds = !self->priv->show_seconds;
- if (self->priv->time_mode != SETTINGS_TIME_CUSTOM) {
- update = TRUE;
- setup_timer(self, NULL);
- }
- }
- break;
- }
- case PROP_SHOW_DAY: {
- if (g_value_get_boolean(value) != self->priv->show_day) {
- self->priv->show_day = !self->priv->show_day;
- if (self->priv->time_mode != SETTINGS_TIME_CUSTOM) {
- update = TRUE;
- }
- }
- break;
- }
- case PROP_SHOW_DATE: {
- if (g_value_get_boolean(value) != self->priv->show_date) {
- self->priv->show_date = !self->priv->show_date;
- if (self->priv->time_mode != SETTINGS_TIME_CUSTOM) {
- update = TRUE;
- }
- }
- break;
- }
- case PROP_CUSTOM_TIME_FORMAT: {
- const gchar * newstr = g_value_get_string(value);
- if (g_strcmp0(newstr, self->priv->custom_string) != 0) {
- if (self->priv->custom_string != NULL) {
- g_free(self->priv->custom_string);
- self->priv->custom_string = NULL;
- }
- self->priv->custom_string = g_strdup(newstr);
- gint time_mask = generate_strftime_bitmask(newstr);
- self->priv->custom_show_seconds = (time_mask & STRFTIME_MASK_SECONDS);
- if (self->priv->time_mode == SETTINGS_TIME_CUSTOM) {
- update = TRUE;
- setup_timer(self, NULL);
- }
- }
- break;
- }
- case PROP_SHOW_WEEK_NUMBERS: {
- if (g_value_get_boolean(value) != self->priv->show_week_numbers) {
- GtkCalendarDisplayOptions flags = ido_calendar_menu_item_get_display_options (self->priv->ido_calendar);
- if (g_value_get_boolean(value) == TRUE)
- flags |= GTK_CALENDAR_SHOW_WEEK_NUMBERS;
- else
- flags &= ~GTK_CALENDAR_SHOW_WEEK_NUMBERS;
- ido_calendar_menu_item_set_display_options (self->priv->ido_calendar, flags);
- self->priv->show_week_numbers = g_value_get_boolean(value);
- }
- break;
- }
- case PROP_SHOW_CALENDAR: {
- if (g_value_get_boolean(value) != self->priv->show_calendar) {
- self->priv->show_calendar = g_value_get_boolean(value);
- if (self->priv->ido_calendar != NULL) {
- gtk_widget_set_visible (GTK_WIDGET (self->priv->ido_calendar), self->priv->show_calendar);
- }
- }
- break;
- }
- default: {
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- return;
- }
- }
-
- if (!update) {
- return;
- }
-
- /* Get the new format string */
- gchar * newformat = generate_format_string_now(self);
-
- /* check to ensure the format really changed */
- if (g_strcmp0(self->priv->time_string, newformat) == 0) {
- g_free(newformat);
- return;
- }
-
- /* Okay now process the change */
- if (self->priv->time_string != NULL) {
- g_free(self->priv->time_string);
- self->priv->time_string = NULL;
- }
- self->priv->time_string = newformat;
-
- /* And update everything */
- update_label(self, NULL);
- timezone_update_all_labels(self);
- guess_label_size(self);
-
- return;
-}
-
-/* Gets a property from the object */
-static void
-get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(object);
-
- switch(prop_id) {
- case PROP_SHOW_CLOCK:
- g_value_set_boolean(value, self->priv->show_clock);
- break;
- case PROP_TIME_FORMAT:
- g_value_set_int(value, self->priv->time_mode);
- break;
- case PROP_SHOW_SECONDS:
- g_value_set_boolean(value, self->priv->show_seconds);
- break;
- case PROP_SHOW_DAY:
- g_value_set_boolean(value, self->priv->show_day);
- break;
- case PROP_SHOW_DATE:
- g_value_set_boolean(value, self->priv->show_date);
- break;
- case PROP_CUSTOM_TIME_FORMAT:
- g_value_set_string(value, self->priv->custom_string);
- break;
- case PROP_SHOW_WEEK_NUMBERS:
- g_value_set_boolean(value, self->priv->show_week_numbers);
- break;
- case PROP_SHOW_CALENDAR:
- g_value_set_boolean(value, self->priv->show_calendar);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- return;
- }
-
- return;
-}
-
-/* Looks at the size of the label, if it grew beyond what we
- thought was the max, make sure it doesn't shrink again. */
-static gboolean
-idle_measure (gpointer data)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(data);
- self->priv->idle_measure = 0;
-
- GtkAllocation allocation;
- gtk_widget_get_allocation(GTK_WIDGET(self->priv->label), &allocation);
-
- if (allocation.width > self->priv->max_width) {
- if (self->priv->max_width != 0) {
- g_warning("Guessed wrong. We thought the max would be %d but we're now at %d", self->priv->max_width, allocation.width);
- }
- self->priv->max_width = allocation.width;
- gtk_widget_set_size_request(GTK_WIDGET(self->priv->label), self->priv->max_width, -1);
- }
-
- return FALSE;
-}
-
-/* Updates the accessible description */
-static void
-update_accessible_description (IndicatorDatetime * io)
-{
- GList * entries = indicator_object_get_entries(INDICATOR_OBJECT(io));
- IndicatorObjectEntry * entry = (IndicatorObjectEntry *)entries->data;
-
- entry->accessible_desc = get_accessible_desc(INDICATOR_OBJECT(io));
-
- g_signal_emit(G_OBJECT(io),
- INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID,
- 0,
- entry,
- TRUE);
-
- g_list_free(entries);
-
- return;
-}
-
-/* Updates the label to be the current time. */
-static void
-set_label_to_time_in_zone (IndicatorDatetime * self, GtkLabel * label,
- GTimeZone * tz, const gchar * format,
- GDateTime ** datetime)
-{
- gboolean unref_tz = FALSE;
- if (tz == NULL) {
- gchar * zone = read_timezone ();
- if (zone == NULL)
- return;
- tz = g_time_zone_new(zone);
- unref_tz = TRUE;
- g_free (zone);
- }
-
- GDateTime * datetime_now;
- datetime_now = g_date_time_new_now(tz);
-
- gchar * timestr;
- if (format == NULL) {
- gchar * format_for_time = generate_format_string_at_time(datetime_now);
- timestr = g_date_time_format(datetime_now, format_for_time);
- g_free(format_for_time);
- }
- else {
- timestr = g_date_time_format(datetime_now, format);
- if (timestr == NULL) {
- g_warning ("The custom date format is not valid, check the\n"
- "g_date_time_format() documentation for the supported\n"
- "format specifiers ");
- timestr = g_strdup ("Date format not supported");
- }
- }
-
- gboolean use_markup = FALSE;
- if (pango_parse_markup(timestr, -1, 0, NULL, NULL, NULL, NULL))
- use_markup = TRUE;
-
- if (use_markup)
- gtk_label_set_markup(label, timestr);
- else
- gtk_label_set_text(label, timestr);
-
- g_free(timestr);
-
- if (datetime)
- *datetime = datetime_now;
- else
- g_date_time_unref(datetime_now);
-
- if (unref_tz)
- g_time_zone_unref(tz);
-
- return;
-}
-
-/* Updates the label to be the current time. */
-static void
-update_label (IndicatorDatetime * io, GDateTime ** datetime)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(io);
-
- if (self->priv->label == NULL) return;
-
- set_label_to_time_in_zone(self, self->priv->label, NULL, self->priv->time_string, datetime);
-
- if (self->priv->idle_measure == 0) {
- self->priv->idle_measure = g_idle_add(idle_measure, io);
- }
-
- update_accessible_description(io);
-
- return;
-}
-
-/* Update the time right now. Usually the result of a timezone switch. */
-static void
-update_time (IndicatorDatetime * self)
-{
- GDateTime * dt = NULL;
- update_label(self, &dt);
- timezone_update_all_labels(self);
- if (dt != NULL) {
- setup_timer(self, dt);
- g_date_time_unref(dt);
- }
- return;
-}
-
-/* Receives all signals from the service, routed to the appropriate functions */
-static void
-receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name,
- GVariant * parameters, gpointer user_data)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(user_data);
-
- if (g_strcmp0(signal_name, "UpdateTime") == 0) {
- update_time(self);
- }
-
- return;
-}
-
-/* Runs every minute and updates the time */
-gboolean
-timer_func (gpointer user_data)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(user_data);
- self->priv->timer = 0;
- GDateTime * dt = NULL;
- update_label(self, &dt);
- timezone_update_all_labels(self);
- if (dt != NULL) {
- setup_timer(self, dt);
- g_date_time_unref(dt);
- }
- return FALSE;
-}
-
-/* Configure the timer to run the next time through */
-static void
-setup_timer (IndicatorDatetime * self, GDateTime * datetime)
-{
- gboolean unref = FALSE;
-
- if (self->priv->timer != 0) {
- g_source_remove(self->priv->timer);
- self->priv->timer = 0;
- }
-
- if (self->priv->show_seconds ||
- (self->priv->time_mode == SETTINGS_TIME_CUSTOM && self->priv->custom_show_seconds)) {
- self->priv->timer = g_timeout_add_full(G_PRIORITY_HIGH, 999, timer_func, self, NULL);
- } else {
- if (datetime == NULL) {
- datetime = g_date_time_new_now_local();
- unref = TRUE;
- }
-
- /* Plus 2 so we're just after the minute, don't want to be early. */
- gint seconds = (gint)g_date_time_get_seconds(datetime);
- self->priv->timer = g_timeout_add_seconds(60 - seconds + 2, timer_func, self);
-
- if (unref) {
- g_date_time_unref(datetime);
- }
- }
-
- return;
-}
-
-/* Does a quick meausre of how big the string is in
- pixels with a Pango layout */
-static gint
-measure_string (GtkStyle * style, PangoContext * context, const gchar * string)
-{
- PangoLayout * layout = pango_layout_new(context);
-
- if (pango_parse_markup(string, -1, 0, NULL, NULL, NULL, NULL))
- pango_layout_set_markup(layout, string, -1);
- else
- pango_layout_set_text(layout, string, -1);
-
- pango_layout_set_font_description(layout, style->font_desc);
-
- gint width;
- pango_layout_get_pixel_size(layout, &width, NULL);
- g_object_unref(layout);
- return width;
-}
-
-/* Format for the table of strftime() modifiers to what
- we need to check when determining the length */
-typedef struct _strftime_type_t strftime_type_t;
-struct _strftime_type_t {
- char character;
- gint mask;
-};
-
-/* A table taken from the man page of strftime to what the different
- characters can effect. These are worst case in that we need to
- test the length based on all these things to ensure that we have
- a reasonable string lenght measurement. */
-const static strftime_type_t strftime_type[] = {
- {'a', STRFTIME_MASK_WEEK},
- {'A', STRFTIME_MASK_WEEK},
- {'b', STRFTIME_MASK_MONTH},
- {'B', STRFTIME_MASK_MONTH},
- {'c', STRFTIME_MASK_ALL}, /* We don't know, so we have to assume all */
- {'C', STRFTIME_MASK_YEAR},
- {'d', STRFTIME_MASK_MONTH},
- {'D', STRFTIME_MASK_MONTH | STRFTIME_MASK_YEAR | STRFTIME_MASK_DAY},
- {'e', STRFTIME_MASK_DAY},
- {'F', STRFTIME_MASK_MONTH | STRFTIME_MASK_YEAR | STRFTIME_MASK_DAY},
- {'G', STRFTIME_MASK_YEAR},
- {'g', STRFTIME_MASK_YEAR},
- {'h', STRFTIME_MASK_MONTH},
- {'j', STRFTIME_MASK_DAY},
- {'m', STRFTIME_MASK_MONTH},
- {'p', STRFTIME_MASK_AMPM},
- {'P', STRFTIME_MASK_AMPM},
- {'r', STRFTIME_MASK_AMPM},
- {'s', STRFTIME_MASK_SECONDS},
- {'S', STRFTIME_MASK_SECONDS},
- {'T', STRFTIME_MASK_SECONDS},
- {'u', STRFTIME_MASK_WEEK},
- {'U', STRFTIME_MASK_DAY | STRFTIME_MASK_MONTH},
- {'V', STRFTIME_MASK_DAY | STRFTIME_MASK_MONTH},
- {'w', STRFTIME_MASK_DAY},
- {'W', STRFTIME_MASK_DAY | STRFTIME_MASK_MONTH},
- {'x', STRFTIME_MASK_YEAR | STRFTIME_MASK_MONTH | STRFTIME_MASK_DAY | STRFTIME_MASK_WEEK},
- {'X', STRFTIME_MASK_SECONDS},
- {'y', STRFTIME_MASK_YEAR},
- {'Y', STRFTIME_MASK_YEAR},
- /* Last one */
- {0, 0}
-};
-
-#define FAT_NUMBER 8
-
-/* Looks through the characters in the format string to
- ensure that we can figure out which of the things we
- need to check in determining the length. */
-static gint
-generate_strftime_bitmask (const char *time_str)
-{
- gint retval = 0;
- glong strlength = g_utf8_strlen(time_str, -1);
- gint i;
- g_debug("Evaluating bitmask for '%s'", time_str);
-
- for (i = 0; i < strlength; i++) {
- if (time_str[i] == '%' && i + 1 < strlength) {
- gchar evalchar = time_str[i + 1];
-
- /* If we're using alternate formats we need to skip those characters */
- if (evalchar == 'E' || evalchar == 'O') {
- if (i + 2 < strlength) {
- evalchar = time_str[i + 2];
- } else {
- continue;
- }
- }
-
- /* Let's look at that character in the table */
- int j;
- for (j = 0; strftime_type[j].character != 0; j++) {
- if (strftime_type[j].character == evalchar) {
- retval |= strftime_type[j].mask;
- break;
- }
- }
- }
- }
-
- return retval;
-}
-
-/* Build an array up of all the time values that we want to check
- for length to ensure we're in a good place */
-static void
-build_timeval_array (GArray * timevals, gint mask)
-{
- struct tm mytm = {0};
-
- /* Sun 12/28/8888 00:00 */
- mytm.tm_hour = 0;
- mytm.tm_mday = 28;
- mytm.tm_mon = 11;
- mytm.tm_year = 8888 - 1900;
- mytm.tm_wday = 0;
- mytm.tm_yday = 363;
- g_array_append_val(timevals, mytm);
-
- if (mask & STRFTIME_MASK_AMPM) {
- /* Sun 12/28/8888 12:00 */
- mytm.tm_hour = 12;
- g_array_append_val(timevals, mytm);
- }
-
- /* NOTE: Ignoring year 8888 should handle it */
-
- if (mask & STRFTIME_MASK_MONTH) {
- gint oldlen = timevals->len;
- gint i, j;
- for (i = 0; i < oldlen; i++) {
- for (j = 0; j < 11; j++) {
- struct tm localval = g_array_index(timevals, struct tm, i);
- localval.tm_mon = j;
- /* Not sure if I need to adjust yday & wday, hope not */
- g_array_append_val(timevals, localval);
- }
- }
- }
-
- /* Doing these together as it seems like just slightly more
- coverage on the numerical days, but worth it. */
- if (mask & (STRFTIME_MASK_WEEK | STRFTIME_MASK_DAY)) {
- gint oldlen = timevals->len;
- gint i, j;
- for (i = 0; i < oldlen; i++) {
- for (j = 22; j < 28; j++) {
- struct tm localval = g_array_index(timevals, struct tm, i);
-
- gint diff = 28 - j;
-
- localval.tm_mday = j;
- localval.tm_wday = localval.tm_wday - diff;
- if (localval.tm_wday < 0) {
- localval.tm_wday += 7;
- }
- localval.tm_yday = localval.tm_yday - diff;
-
- g_array_append_val(timevals, localval);
- }
- }
- }
-
- return;
-}
-
-/* Try to get a good guess at what a maximum width of the entire
- string would be. */
-static void
-guess_label_size (IndicatorDatetime * self)
-{
- /* This is during startup. */
- if (self->priv->label == NULL) return;
-
- GtkStyle * style = gtk_widget_get_style(GTK_WIDGET(self->priv->label));
- PangoContext * context = gtk_widget_get_pango_context(GTK_WIDGET(self->priv->label));
- gint * max_width = &(self->priv->max_width);
- gint posibilitymask = generate_strftime_bitmask(self->priv->time_string);
-
- /* Reset max width */
- *max_width = 0;
-
- /* Build the array of possibilities that we want to test */
- GArray * timevals = g_array_new(FALSE, TRUE, sizeof(struct tm));
- build_timeval_array(timevals, posibilitymask);
-
- g_debug("Checking against %d possible times", timevals->len);
- gint check_time;
- for (check_time = 0; check_time < timevals->len; check_time++) {
- struct tm * timeval = &g_array_index(timevals, struct tm, check_time);
- GDateTime * dt = g_date_time_new_local(timeval->tm_year, timeval->tm_mon, timeval->tm_mday, timeval->tm_hour, timeval->tm_min, timeval->tm_sec);
- gchar * timestr = g_date_time_format(dt, self->priv->time_string);
-
- gint length = measure_string(style, context, timestr);
-
- g_free(timestr);
- g_date_time_unref(dt);
-
- if (length > *max_width) {
- *max_width = length;
- }
- }
-
- g_array_free(timevals, TRUE);
-
- gtk_widget_set_size_request(GTK_WIDGET(self->priv->label), self->priv->max_width, -1);
- g_debug("Guessing max time width: %d", self->priv->max_width);
-
- return;
-}
-
-/* React to the style changing, which could mean an font
- update. */
-static void
-style_changed (GtkWidget * widget, GtkStyle * oldstyle, gpointer data)
-{
- g_debug("New style for time label");
- IndicatorDatetime * self = INDICATOR_DATETIME(data);
- guess_label_size(self);
- update_label(self, NULL);
- timezone_update_all_labels(self);
- return;
-}
-
-/* Respond to changes in the screen to update the text gravity */
-static void
-update_text_gravity (GtkWidget *widget, GdkScreen *previous_screen, gpointer data)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(data);
- if (self->priv->label == NULL) return;
-
- PangoLayout *layout;
- PangoContext *context;
-
- layout = gtk_label_get_layout (GTK_LABEL(self->priv->label));
- context = pango_layout_get_context(layout);
- pango_context_set_base_gravity(context, PANGO_GRAVITY_AUTO);
-}
-
-static gchar *
-generate_format_string_now (IndicatorDatetime * self)
-{
- if (self->priv->time_mode == SETTINGS_TIME_CUSTOM) {
- return g_strdup(self->priv->custom_string);
- }
- else {
- return generate_format_string_full(self->priv->show_day,
- self->priv->show_date);
- }
-}
-
-static void
-timezone_update_labels (indicator_item_t * mi_data)
-{
- const gchar * zone = dbusmenu_menuitem_property_get(mi_data->mi, TIMEZONE_MENUITEM_PROP_ZONE);
- const gchar * name = dbusmenu_menuitem_property_get(mi_data->mi, TIMEZONE_MENUITEM_PROP_NAME);
-
- gtk_label_set_text(GTK_LABEL(mi_data->label), name);
-
- /* Show current time in that zone on the right */
- GTimeZone * tz = g_time_zone_new(zone);
- set_label_to_time_in_zone(mi_data->self, GTK_LABEL(mi_data->right), tz, NULL, NULL);
- g_time_zone_unref(tz);
-}
-
-/* Whenever we have a property change on a DbusmenuMenuitem
- we need to be responsive to that. */
-static void
-indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant *value, indicator_item_t * mi_data)
-{
- if (!g_strcmp0(prop, APPOINTMENT_MENUITEM_PROP_LABEL)) {
- /* Set the main label */
- gtk_label_set_text(GTK_LABEL(mi_data->label), g_variant_get_string(value, NULL));
- } else if (!g_strcmp0(prop, APPOINTMENT_MENUITEM_PROP_RIGHT)) {
- /* Set the right label */
- gtk_label_set_text(GTK_LABEL(mi_data->right), g_variant_get_string(value, NULL));
- } else if (!g_strcmp0(prop, APPOINTMENT_MENUITEM_PROP_ICON)) {
- /* We don't use the value here, which is probably less efficient,
- but it's easier to use the easy function. And since th value
- is already cached, shouldn't be a big deal really. */
- GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(mi, APPOINTMENT_MENUITEM_PROP_ICON);
- if (pixbuf != NULL) {
- /* If we've got a pixbuf we need to make sure it's of a reasonable
- size to fit in the menu. If not, rescale it. */
- GdkPixbuf * resized_pixbuf;
- gint width, height;
- gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
- if (gdk_pixbuf_get_width(pixbuf) > width ||
- gdk_pixbuf_get_height(pixbuf) > height) {
- g_debug("Resizing icon from %dx%d to %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), width, height);
- resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf,
- width,
- height,
- GDK_INTERP_BILINEAR);
- } else {
- g_debug("Happy with icon sized %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
- resized_pixbuf = pixbuf;
- }
- gtk_image_set_from_pixbuf(GTK_IMAGE(mi_data->icon), resized_pixbuf);
- /* The other pixbuf should be free'd by the dbusmenu. */
- if (resized_pixbuf != pixbuf) {
- g_object_unref(resized_pixbuf);
- }
- }
- } else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_ZONE)) {
- timezone_update_labels(mi_data);
- } else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_NAME)) {
- timezone_update_labels(mi_data);
- } else if (!g_strcmp0(prop, TIMEZONE_MENUITEM_PROP_RADIO)) {
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mi_data->gmi), g_variant_get_boolean(value));
- }
- return;
-}
-// Properties for marking and unmarking the calendar
-static void
-calendar_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant *value, IdoCalendarMenuItem * mi_data)
-{
- g_debug("Changing calendar property: %s", prop);
- if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_MARKS)) {
- ido_calendar_menu_item_clear_marks (IDO_CALENDAR_MENU_ITEM (mi_data));
-
- if (value != NULL) {
- GVariantIter *iter;
- gint day;
-
- g_debug("\tMarks: %s", g_variant_print(value, FALSE));
-
- g_variant_get (value, "ai", &iter);
- while (g_variant_iter_loop (iter, "i", &day)) {
- ido_calendar_menu_item_mark_day (IDO_CALENDAR_MENU_ITEM (mi_data), day);
- }
- g_variant_iter_free (iter);
- } else {
- g_debug("\tMarks: <cleared>");
- }
- }
- return;
-}
-
-/* We have a small little menuitem type that handles all
- of the fun stuff for indicators. Mostly this is the
- shifting over and putting the icon in with some right
- side text that'll be determined by the service.
- Copied verbatim from an old revision (including comments) of indicator-messages
-*/
-static gboolean
-new_appointment_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
-{
- g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
- g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
- g_return_val_if_fail(IS_INDICATOR_DATETIME(user_data), FALSE);
- /* Note: not checking parent, it's reasonable for it to be NULL */
- IndicatorDatetime * self = INDICATOR_DATETIME(user_data);
-
- indicator_item_t * mi_data = g_new0(indicator_item_t, 1);
-
- mi_data->gmi = gtk_menu_item_new();
-
- GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
-
- /* Icon, probably someone's face or avatar on an IM */
- mi_data->icon = gtk_image_new();
- GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(newitem, APPOINTMENT_MENUITEM_PROP_ICON);
-
- if (pixbuf != NULL) {
- /* If we've got a pixbuf we need to make sure it's of a reasonable
- size to fit in the menu. If not, rescale it. */
- GdkPixbuf * resized_pixbuf;
- gint width, height;
- gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
- if (gdk_pixbuf_get_width(pixbuf) > width ||
- gdk_pixbuf_get_height(pixbuf) > height) {
- g_debug("Resizing icon from %dx%d to %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), width, height);
- resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf,
- width,
- height,
- GDK_INTERP_BILINEAR);
- } else {
- g_debug("Happy with icon sized %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
- resized_pixbuf = pixbuf;
- }
-
- gtk_image_set_from_pixbuf(GTK_IMAGE(mi_data->icon), resized_pixbuf);
-
- /* The other pixbuf should be free'd by the dbusmenu. */
- if (resized_pixbuf != pixbuf) {
- g_object_unref(resized_pixbuf);
- }
- }
- gtk_misc_set_alignment(GTK_MISC(mi_data->icon), 0.0, 0.5);
- gtk_box_pack_start(GTK_BOX(hbox), mi_data->icon, FALSE, FALSE, 0);
- gtk_widget_show(mi_data->icon);
-
- /* Label, probably a username, chat room or mailbox name */
- mi_data->label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, APPOINTMENT_MENUITEM_PROP_LABEL));
- gtk_misc_set_alignment(GTK_MISC(mi_data->label), 0.0, 0.5);
-
- GtkStyle * style = gtk_widget_get_style(GTK_WIDGET(mi_data->label));
- PangoContext * context = gtk_widget_get_pango_context(GTK_WIDGET(mi_data->label));
- gint length = measure_string(style, context, "MMMMMMMMMMMMMMM"); // 15 char wide string max
- gtk_widget_set_size_request(GTK_WIDGET(mi_data->label), length, -1); // Set the min size in pixels
-
- gtk_label_set_ellipsize(GTK_LABEL(mi_data->label), PANGO_ELLIPSIZE_END);
- gtk_box_pack_start(GTK_BOX(hbox), mi_data->label, TRUE, TRUE, 0);
- gtk_widget_show(mi_data->label);
-
- /* Usually either the time or the count on the individual
- item. */
- mi_data->right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, APPOINTMENT_MENUITEM_PROP_RIGHT));
- gtk_size_group_add_widget(self->priv->indicator_right_group, mi_data->right);
- gtk_misc_set_alignment(GTK_MISC(mi_data->right), 1.0, 0.5);
- gtk_box_pack_start(GTK_BOX(hbox), mi_data->right, FALSE, FALSE, 0);
- gtk_widget_show(mi_data->right);
-
- gtk_container_add(GTK_CONTAINER(mi_data->gmi), hbox);
- gtk_widget_show(hbox);
-
- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(mi_data->gmi), parent);
-
- g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), mi_data);
- return TRUE;
-}
-
-static void
-month_changed_cb (IdoCalendarMenuItem *ido,
- gpointer user_data)
-{
- guint d,m,y;
- DbusmenuMenuitem * item = DBUSMENU_MENUITEM (user_data);
- ido_calendar_menu_item_get_date(ido, &y, &m, &d);
- struct tm date = {0};
- date.tm_mday = d;
- date.tm_mon = m;
- date.tm_year = y - 1900;
- guint selecteddate = (guint)mktime(&date);
- g_debug("Got month changed signal: %s", asctime(&date));
- GVariant *variant = g_variant_new_uint32(selecteddate);
- guint timestamp = (guint)time(NULL);
- dbusmenu_menuitem_handle_event(DBUSMENU_MENUITEM(item), "month-changed", variant, timestamp);
-}
-
-static void
-day_selected_cb (IdoCalendarMenuItem *ido,
- gpointer user_data)
-{
- guint d,m,y;
- DbusmenuMenuitem * item = DBUSMENU_MENUITEM (user_data);
- ido_calendar_menu_item_get_date(ido, &y, &m, &d);
- struct tm date = {0};
- date.tm_mday = d;
- date.tm_mon = m;
- date.tm_year = y - 1900;
- guint selecteddate = (guint)mktime(&date);
- g_debug("Got day selected signal: %s", asctime(&date));
- GVariant *variant = g_variant_new_uint32(selecteddate);
- guint timestamp = (guint)time(NULL);
- dbusmenu_menuitem_handle_event(DBUSMENU_MENUITEM(item), "day-selected", variant, timestamp);
-}
-
-static void
-day_selected_double_click_cb (IdoCalendarMenuItem *ido,
- gpointer user_data)
-{
- guint d,m,y;
- DbusmenuMenuitem * item = DBUSMENU_MENUITEM (user_data);
- ido_calendar_menu_item_get_date(ido, &y, &m, &d);
- struct tm date = {0};
- date.tm_mday = d;
- date.tm_mon = m;
- date.tm_year = y - 1900;
- guint selecteddate = (guint)mktime(&date);
- g_debug("Got day selected double click signal: %s", asctime(&date));
- GVariant *variant = g_variant_new_uint32(selecteddate);
- guint timestamp = (guint)time(NULL);
- dbusmenu_menuitem_handle_event(DBUSMENU_MENUITEM(item), "day-selected-double-click", variant, timestamp);
-}
-
-static gboolean
-new_calendar_item (DbusmenuMenuitem * newitem,
- DbusmenuMenuitem * parent,
- DbusmenuClient * client,
- gpointer user_data)
-{
- g_debug("New calendar item");
- g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
- g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
- g_return_val_if_fail(IS_INDICATOR_DATETIME(user_data), FALSE);
- /* Note: not checking parent, it's reasonable for it to be NULL */
-
- IndicatorDatetime *self = INDICATOR_DATETIME(user_data);
-
- IdoCalendarMenuItem *ido = IDO_CALENDAR_MENU_ITEM (ido_calendar_menu_item_new ());
- self->priv->ido_calendar = ido;
-
- GtkCalendarDisplayOptions flags = ido_calendar_menu_item_get_display_options (self->priv->ido_calendar);
- if (self->priv->show_week_numbers == TRUE)
- flags |= GTK_CALENDAR_SHOW_WEEK_NUMBERS;
- else
- flags &= ~GTK_CALENDAR_SHOW_WEEK_NUMBERS;
- ido_calendar_menu_item_set_display_options (self->priv->ido_calendar, flags);
-
- gtk_widget_set_visible (GTK_WIDGET (self->priv->ido_calendar), self->priv->show_calendar);
-
- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(ido), parent);
-
- g_signal_connect_after(ido, "month-changed", G_CALLBACK(month_changed_cb), (gpointer)newitem);
- g_signal_connect_after(ido, "day-selected", G_CALLBACK(day_selected_cb), (gpointer)newitem);
- g_signal_connect_after(ido, "day-selected-double-click", G_CALLBACK(day_selected_double_click_cb), (gpointer)newitem);
-
- g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(calendar_prop_change_cb), ido);
-
- /* Run the current values through prop changed */
- GVariant * propval = NULL;
-
- propval = dbusmenu_menuitem_property_get_variant(newitem, CALENDAR_MENUITEM_PROP_MARKS);
- if (propval != NULL) {
- calendar_prop_change_cb(newitem, CALENDAR_MENUITEM_PROP_MARKS, propval, ido);
- }
-
- return TRUE;
-}
-
-static void
-timezone_toggled_cb (GtkCheckMenuItem *checkmenuitem, DbusmenuMenuitem * dbusitem)
-{
- /* Make sure that the displayed radio-active setting is always
- consistent with the dbus menuitem */
- gtk_check_menu_item_set_active(checkmenuitem,
- dbusmenu_menuitem_property_get_bool(dbusitem, TIMEZONE_MENUITEM_PROP_RADIO));
-}
-
-static void
-timezone_destroyed_cb (indicator_item_t * mi_data, DbusmenuMenuitem * dbusitem)
-{
- IndicatorDatetime *self = INDICATOR_DATETIME (mi_data->self);
- IndicatorDatetimePrivate *priv = self->priv;
-
- priv->timezone_items = g_list_remove(priv->timezone_items, mi_data);
- g_signal_handlers_disconnect_by_func(G_OBJECT(mi_data->gmi), G_CALLBACK(timezone_toggled_cb), dbusitem);
- g_free(mi_data);
-}
-
-static gboolean
-new_timezone_item(DbusmenuMenuitem * newitem,
- DbusmenuMenuitem * parent,
- DbusmenuClient * client,
- gpointer user_data)
-{
- g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
- g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
- g_return_val_if_fail(IS_INDICATOR_DATETIME(user_data), FALSE);
- /* Note: not checking parent, it's reasonable for it to be NULL */
-
- IndicatorDatetime * self = INDICATOR_DATETIME(user_data);
- IndicatorDatetimePrivate *priv = self->priv;
-
- // Menu item with a radio button and a right aligned time
- indicator_item_t * mi_data = g_new0(indicator_item_t, 1);
-
- priv->timezone_items = g_list_prepend(priv->timezone_items, mi_data);
-
- mi_data->self = self;
- mi_data->mi = newitem;
- mi_data->gmi = gtk_check_menu_item_new();
-
- gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(mi_data->gmi), TRUE);
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mi_data->gmi),
- dbusmenu_menuitem_property_get_bool(newitem, TIMEZONE_MENUITEM_PROP_RADIO));
-
- GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
-
- /* Label, probably a username, chat room or mailbox name */
- mi_data->label = gtk_label_new("");
- gtk_misc_set_alignment(GTK_MISC(mi_data->label), 0.0, 0.5);
- gtk_box_pack_start(GTK_BOX(hbox), mi_data->label, TRUE, TRUE, 0);
- gtk_widget_show(mi_data->label);
-
- /* Usually either the time or the count on the individual
- item. */
- mi_data->right = gtk_label_new("");
- gtk_size_group_add_widget(self->priv->indicator_right_group, mi_data->right);
- gtk_misc_set_alignment(GTK_MISC(mi_data->right), 1.0, 0.5);
- gtk_box_pack_start(GTK_BOX(hbox), mi_data->right, FALSE, FALSE, 0);
- gtk_widget_show(mi_data->right);
-
- timezone_update_labels(mi_data);
-
- gtk_container_add(GTK_CONTAINER(mi_data->gmi), hbox);
- gtk_widget_show(hbox);
-
- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(mi_data->gmi), parent);
-
- g_signal_connect(G_OBJECT(mi_data->gmi), "toggled", G_CALLBACK(timezone_toggled_cb), newitem);
- g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), mi_data);
- g_object_weak_ref(G_OBJECT(newitem), (GWeakNotify)timezone_destroyed_cb, mi_data);
-
- return TRUE;
-}
-
-/* Grabs the label. Creates it if it doesn't
- exist already */
-static GtkLabel *
-get_label (IndicatorObject * io)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(io);
-
- /* If there's not a label, we'll build ourselves one */
- if (self->priv->label == NULL) {
- self->priv->label = GTK_LABEL(gtk_label_new("Time"));
- gtk_label_set_justify (GTK_LABEL(self->priv->label), GTK_JUSTIFY_CENTER);
- g_object_ref(G_OBJECT(self->priv->label));
- g_signal_connect(G_OBJECT(self->priv->label), "style-set", G_CALLBACK(style_changed), self);
- g_signal_connect(G_OBJECT(self->priv->label), "screen-changed", G_CALLBACK(update_text_gravity), self);
- guess_label_size(self);
- update_label(self, NULL);
- gtk_widget_set_visible(GTK_WIDGET (self->priv->label), self->priv->show_clock);
- }
-
- if (self->priv->timer == 0) {
- setup_timer(self, NULL);
- }
-
- return self->priv->label;
-}
-
-static GtkMenu *
-get_menu (IndicatorObject * io)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(io);
-
- return GTK_MENU(self->priv->menu);
-}
-
-static const gchar *
-get_accessible_desc (IndicatorObject * io)
-{
- IndicatorDatetime * self = INDICATOR_DATETIME(io);
- const gchar * name;
-
- if (self->priv->label != NULL) {
- name = gtk_label_get_text(self->priv->label);
- return name;
- }
- return NULL;
-}
-
-static const gchar *
-get_name_hint (IndicatorObject * io)
-{
- return PACKAGE_NAME;
-}