Merge branch 'wip/datetime-panel'

This commit is contained in:
Thomas Wood 2010-06-29 14:41:48 +01:00
commit 0cbbf01710
56 changed files with 2288 additions and 1 deletions

View file

@ -411,6 +411,8 @@ libgnome-control-center/libgnome-control-center.pc
libwindow-settings/Makefile
libwindow-settings/gnome-window-settings-2.0.pc
panels/Makefile
panels/datetime/Makefile
panels/datetime/gnome-datetime-panel.desktop.in
panels/mouse/Makefile
panels/mouse/gnome-mouse-panel.desktop.in
panels/keyboard/Makefile

View file

@ -4,4 +4,5 @@ SUBDIRS=display \
network \
default-applications \
keybindings \
universal-access
universal-access \
datetime

View file

@ -0,0 +1,81 @@
# This is used in GNOMECC_CAPPLETS_CFLAGS
cappletname = datetime
uidir = $(datadir)/ui/datetime
dist_ui_DATA = \
datetime.ui \
data/bg.png \
data/cc.png \
data/timezone_0.png \
data/timezone_-10.png \
data/timezone_10.png \
data/timezone_10.5.png \
data/timezone_-1.png \
data/timezone_1.png \
data/timezone_-11.png \
data/timezone_11.png \
data/timezone_11.5.png \
data/timezone_12.png \
data/timezone_12.75.png \
data/timezone_13.png \
data/timezone_-2.png \
data/timezone_2.png \
data/timezone_-3.png \
data/timezone_3.png \
data/timezone_-3.5.png \
data/timezone_3.5.png \
data/timezone_-4.png \
data/timezone_4.png \
data/timezone_-4.5.png \
data/timezone_4.5.png \
data/timezone_-5.png \
data/timezone_5.png \
data/timezone_-5.5.png \
data/timezone_5.5.png \
data/timezone_5.75.png \
data/timezone_-6.png \
data/timezone_6.png \
data/timezone_6.5.png \
data/timezone_-7.png \
data/timezone_7.png \
data/timezone_-8.png \
data/timezone_8.png \
data/timezone_-9.png \
data/timezone_9.png \
data/timezone_-9.5.png \
data/timezone_9.5.png
INCLUDES = \
$(PANEL_CFLAGS) \
$(GNOMECC_CAPPLETS_CFLAGS) \
-DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
-DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
-DDATADIR="\"$(uidir)\"" \
$(NULL)
ccpanelsdir = $(PANELS_DIR)
ccpanels_LTLIBRARIES = libdate_time.la
libdate_time_la_SOURCES = \
datetime-module.c \
cc-datetime-panel.c \
cc-datetime-panel.h \
cc-timezone-map.c \
cc-timezone-map.h \
set-timezone.c \
set-timezone.h \
tz.c tz.h
libdate_time_la_LIBADD = $(PANEL_LIBS)
libdate_time_la_LDFLAGS = $(PANEL_LDFLAGS)
@INTLTOOL_DESKTOP_RULE@
desktopdir = $(datadir)/applications
desktop_in_files = gnome-datetime-panel.desktop.in
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
CLEANFILES = $(desktop_in_files) $(desktop_DATA)
-include $(top_srcdir)/git.mk

View file

@ -0,0 +1,334 @@
/*
* Copyright (C) 2010 Intel, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Author: Thomas Wood <thomas.wood@intel.com>
*
*/
#include "cc-datetime-panel.h"
#include "cc-timezone-map.h"
#include "set-timezone.h"
G_DEFINE_DYNAMIC_TYPE (CcDateTimePanel, cc_date_time_panel, CC_TYPE_PANEL)
#define DATE_TIME_PANEL_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_DATE_TIME_PANEL, CcDateTimePanelPrivate))
struct _CcDateTimePanelPrivate
{
GtkBuilder *builder;
GtkWidget *map;
TzLocation *current_location;
guint timeout;
};
static void
cc_date_time_panel_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
switch (property_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
cc_date_time_panel_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
switch (property_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
cc_date_time_panel_dispose (GObject *object)
{
CcDateTimePanelPrivate *priv = CC_DATE_TIME_PANEL (object)->priv;
if (priv->builder)
{
g_object_unref (priv->builder);
priv->builder = NULL;
}
G_OBJECT_CLASS (cc_date_time_panel_parent_class)->dispose (object);
}
static void
cc_date_time_panel_finalize (GObject *object)
{
CcDateTimePanelPrivate *priv = CC_DATE_TIME_PANEL (object)->priv;
if (priv->timeout)
{
g_source_remove (priv->timeout);
priv->timeout = 0;
}
G_OBJECT_CLASS (cc_date_time_panel_parent_class)->finalize (object);
}
static void
cc_date_time_panel_class_init (CcDateTimePanelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (CcDateTimePanelPrivate));
object_class->get_property = cc_date_time_panel_get_property;
object_class->set_property = cc_date_time_panel_set_property;
object_class->dispose = cc_date_time_panel_dispose;
object_class->finalize = cc_date_time_panel_finalize;
}
static void
cc_date_time_panel_class_finalize (CcDateTimePanelClass *klass)
{
}
static gboolean
update_time (CcDateTimePanel *self)
{
CcDateTimePanelPrivate *priv = self->priv;
GTimeVal timeval;
GtkWidget *widget;
gchar label[32];
time_t t;
g_get_current_time (&timeval);
priv->timeout = gdk_threads_add_timeout (1000 - timeval.tv_usec / 1000,
(GSourceFunc) update_time, self);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder,
"label_current_time");
t = time (NULL);
strftime (label, 32, "%X", localtime (&t));
gtk_label_set_text (GTK_LABEL (widget), label);
return FALSE;
}
static void
set_time_cb (CcDateTimePanel *self,
GError *error)
{
/* TODO: display any error in a user friendly way */
if (error)
{
g_warning ("Could not set system time: %s", error->message);
}
}
static void
set_timezone_cb (CcDateTimePanel *self,
GError *error)
{
/* TODO: display any error in a user friendly way */
if (error)
{
g_warning ("Could not set system timezone: %s", error->message);
}
}
static void
apply_button_clicked_cb (GtkButton *button,
CcDateTimePanel *self)
{
GtkWidget *widget;
CcDateTimePanelPrivate *priv = self->priv;
guint h, mon, s, y, min, d;
struct tm fulltime;
time_t unixtime;
gchar *filename;
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_hour");
h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget));
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_minute");
min = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget));
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_second");
s = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget));
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "calendar");
gtk_calendar_get_date (GTK_CALENDAR (widget), &y, &mon, &d);
fulltime.tm_sec = s;
fulltime.tm_min = min;
fulltime.tm_hour = h;
fulltime.tm_mday = d;
fulltime.tm_mon = mon;
fulltime.tm_year = y - 1900;
fulltime.tm_isdst = -1;
unixtime = mktime (&fulltime);
set_system_time_async (unixtime, (GFunc) set_time_cb, self, NULL);
filename = g_build_filename (SYSTEM_ZONEINFODIR, priv->current_location->zone,
NULL);
set_system_timezone_async (filename, (GFunc) set_timezone_cb, self, NULL);
}
static void
location_changed_cb (CcTimezoneMap *map,
TzLocation *location,
CcDateTimePanel *self)
{
CcDateTimePanelPrivate *priv = self->priv;
GtkWidget *label, *widget;
gchar *s, *p;
time_t t;
struct tm *ltime;
gchar slabel[32];
priv->current_location = location;
label = (GtkWidget *) gtk_builder_get_object (self->priv->builder,
"label_current_location");
/* replace underscores with spaces */
p = s = g_strdup (location->zone);
while (*p)
{
if (*p == '_')
*p = ' ';
p++;
}
gtk_label_set_text (GTK_LABEL (label), s);
g_free (s);
/* tz.c updates the local timezone, which means the spin buttons can be
* updated with the current time of the new location */
t = time (NULL);
ltime = localtime (&t);
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_hour");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), ltime->tm_hour);
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_minute");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), ltime->tm_min);
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_second");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), ltime->tm_sec);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder,
"label_current_time");
strftime (slabel, 32, "%X", localtime (&t));
gtk_label_set_text (GTK_LABEL (widget), slabel);
}
static void
get_timezone_cb (CcDateTimePanel *self,
const gchar *timezone,
GError *error)
{
if (error)
g_warning ("Could not get current timezone: %s", error->message);
else
cc_timezone_map_set_timezone (CC_TIMEZONE_MAP (self->priv->map), timezone);
}
static void
cc_date_time_panel_init (CcDateTimePanel *self)
{
CcDateTimePanelPrivate *priv;
gchar *objects[] = { "datetime-panel", "adjustment_min", "adjustment_hour",
"adjustment_sec", NULL };
GtkWidget *widget;
GError *err = NULL;
GDate *date;
struct tm *ltime;
time_t t;
priv = self->priv = DATE_TIME_PANEL_PRIVATE (self);
priv->builder = gtk_builder_new ();
gtk_builder_add_objects_from_file (priv->builder, DATADIR"/datetime.ui",
objects, &err);
if (err)
{
g_warning ("Could not load ui: %s", err->message);
g_error_free (err);
return;
}
priv->map = widget = (GtkWidget *) cc_timezone_map_new ();
g_signal_connect (widget, "location-changed",
G_CALLBACK (location_changed_cb), self);
gtk_widget_show (widget);
gtk_container_add (GTK_CONTAINER (gtk_builder_get_object (priv->builder,
"aspectmap")),
widget);
gtk_container_add (GTK_CONTAINER (self),
GTK_WIDGET (gtk_builder_get_object (priv->builder,
"datetime-panel")));
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "calendar");
date = g_date_new ();
g_date_set_time_t (date, time (NULL));
gtk_calendar_select_day (GTK_CALENDAR (widget), g_date_get_day (date));
gtk_calendar_select_month (GTK_CALENDAR (widget), g_date_get_month (date) -1,
g_date_get_year (date));
update_time (self);
t = time (NULL);
ltime = localtime (&t);
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_hour");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), ltime->tm_hour);
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_minute");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), ltime->tm_min);
widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "spin_second");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), ltime->tm_sec);
g_signal_connect ((GtkWidget*) gtk_builder_get_object (priv->builder, "button_apply"),
"clicked",
G_CALLBACK (apply_button_clicked_cb),
self);
get_system_timezone_async ((GetTimezoneFunc) get_timezone_cb, self, NULL);
}
void
cc_date_time_panel_register (GIOModule *module)
{
cc_date_time_panel_register_type (G_TYPE_MODULE (module));
g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
CC_TYPE_DATE_TIME_PANEL,
"gnome-datetime-panel.desktop", 0);
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (C) 2010 Intel, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Author: Thomas Wood <thomas.wood@intel.com>
*
*/
#ifndef _CC_DATE_TIME_PANEL_H
#define _CC_DATE_TIME_PANEL_H
#include <libgnome-control-center/cc-panel.h>
G_BEGIN_DECLS
#define CC_TYPE_DATE_TIME_PANEL cc_date_time_panel_get_type()
#define CC_DATE_TIME_PANEL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
CC_TYPE_DATE_TIME_PANEL, CcDateTimePanel))
#define CC_DATE_TIME_PANEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
CC_TYPE_DATE_TIME_PANEL, CcDateTimePanelClass))
#define CC_IS_DATE_TIME_PANEL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
CC_TYPE_DATE_TIME_PANEL))
#define CC_IS_DATE_TIME_PANEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
CC_TYPE_DATE_TIME_PANEL))
#define CC_DATE_TIME_PANEL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
CC_TYPE_DATE_TIME_PANEL, CcDateTimePanelClass))
typedef struct _CcDateTimePanel CcDateTimePanel;
typedef struct _CcDateTimePanelClass CcDateTimePanelClass;
typedef struct _CcDateTimePanelPrivate CcDateTimePanelPrivate;
struct _CcDateTimePanel
{
CcPanel parent;
CcDateTimePanelPrivate *priv;
};
struct _CcDateTimePanelClass
{
CcPanelClass parent_class;
};
GType cc_date_time_panel_get_type (void) G_GNUC_CONST;
void cc_date_time_panel_register (GIOModule *module);
G_END_DECLS
#endif /* _CC_DATE_TIME_PANEL_H */

View file

@ -0,0 +1,558 @@
/*
* Copyright (C) 2010 Intel, Inc
*
* Portions from Ubiquity, Copyright (C) 2009 Canonical Ltd.
* Written by Evan Dandrea <evand@ubuntu.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Author: Thomas Wood <thomas.wood@intel.com>
*
*/
#include "cc-timezone-map.h"
#include <math.h>
#include "tz.h"
G_DEFINE_TYPE (CcTimezoneMap, cc_timezone_map, GTK_TYPE_WIDGET)
#define TIMEZONE_MAP_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_TIMEZONE_MAP, CcTimezoneMapPrivate))
typedef struct
{
gdouble offset;
guchar red;
guchar green;
guchar blue;
guchar alpha;
} CcTimezoneMapOffset;
struct _CcTimezoneMapPrivate
{
GdkPixbuf *orig_background;
GdkPixbuf *orig_color_map;
GdkPixbuf *background;
GdkPixbuf *color_map;
guchar *visible_map_pixels;
gint visible_map_rowstride;
gdouble selected_offset;
TzDB *tzdb;
TzLocation *location;
};
enum
{
LOCATION_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
static CcTimezoneMapOffset color_codes[] =
{
{-11.0, 43, 0, 0, 255 },
{-10.0, 85, 0, 0, 255 },
{-9.5, 102, 255, 0, 255 },
{-9.0, 128, 0, 0, 255 },
{-8.0, 170, 0, 0, 255 },
{-7.0, 212, 0, 0, 255 },
{-6.0, 255, 0, 1, 255 }, // north
{-6.0, 255, 0, 0, 255 }, // south
{-5.0, 255, 42, 42, 255 },
{-4.5, 192, 255, 0, 255 },
{-4.0, 255, 85, 85, 255 },
{-3.5, 0, 255, 0, 255 },
{-3.0, 255, 128, 128, 255 },
{-2.0, 255, 170, 170, 255 },
{-1.0, 255, 213, 213, 255 },
{0.0, 43, 17, 0, 255 },
{1.0, 85, 34, 0, 255 },
{2.0, 128, 51, 0, 255 },
{3.0, 170, 68, 0, 255 },
{3.5, 0, 255, 102, 255 },
{4.0, 212, 85, 0, 255 },
{4.5, 0, 204, 255, 255 },
{5.0, 255, 102, 0, 255 },
{5.5, 0, 102, 255, 255 },
{5.75, 0, 238, 207, 247 },
{6.0, 255, 127, 42, 255 },
{6.5, 204, 0, 254, 254 },
{7.0, 255, 153, 85, 255 },
{8.0, 255, 179, 128, 255 },
{9.0, 255, 204, 170, 255 },
{9.5, 170, 0, 68, 250 },
{10.0, 255, 230, 213, 255 },
{10.5, 212, 124, 21, 250 },
{11.0, 212, 170, 0, 255 },
{11.5, 249, 25, 87, 253 },
{12.0, 255, 204, 0, 255 },
{12.75, 254, 74, 100, 248 },
{13.0, 255, 85, 153, 250 },
{-100, 0, 0, 0, 0 }
};
static void
cc_timezone_map_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
switch (property_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
cc_timezone_map_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
switch (property_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
cc_timezone_map_dispose (GObject *object)
{
CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (object)->priv;
if (priv->orig_background)
{
g_object_unref (priv->orig_background);
priv->orig_background = NULL;
}
if (priv->orig_color_map)
{
g_object_unref (priv->orig_color_map);
priv->orig_color_map = NULL;
}
if (priv->background)
{
g_object_unref (priv->background);
priv->background = NULL;
}
if (priv->color_map)
{
g_object_unref (priv->color_map);
priv->color_map = NULL;
priv->visible_map_pixels = NULL;
priv->visible_map_rowstride = 0;
}
G_OBJECT_CLASS (cc_timezone_map_parent_class)->dispose (object);
}
static void
cc_timezone_map_finalize (GObject *object)
{
CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (object)->priv;
if (priv->tzdb)
{
g_free (priv->tzdb);
priv->tzdb = NULL;
}
G_OBJECT_CLASS (cc_timezone_map_parent_class)->finalize (object);
}
/* GtkWidget functions */
static void
cc_timezone_map_size_request (GtkWidget *widget,
GtkRequisition *req)
{
CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
req->width = gdk_pixbuf_get_width (priv->orig_background) / 2;
req->height = gdk_pixbuf_get_height (priv->orig_background) / 2;
GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->size_request (widget, req);
}
static void
cc_timezone_map_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
GdkPixbuf *color_map;
priv->background = gdk_pixbuf_scale_simple (priv->orig_background,
allocation->width,
allocation->height,
GDK_INTERP_BILINEAR);
color_map = gdk_pixbuf_scale_simple (priv->orig_color_map,
allocation->width,
allocation->height,
GDK_INTERP_BILINEAR);
priv->visible_map_pixels = gdk_pixbuf_get_pixels (color_map);
priv->visible_map_rowstride = gdk_pixbuf_get_rowstride (color_map);
GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->size_allocate (widget,
allocation);
}
static void
cc_timezone_map_realize (GtkWidget *widget)
{
GdkWindowAttr attr = { 0, };
GtkAllocation allocation;
GdkCursor *cursor;
GdkWindow *window;
gtk_widget_get_allocation (widget, &allocation);
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
attr.window_type = GDK_WINDOW_CHILD;
attr.wclass = GDK_INPUT_OUTPUT;
attr.width = allocation.width;
attr.height = allocation.height;
attr.x = allocation.x;
attr.y = allocation.y;
attr.event_mask = gtk_widget_get_events (widget)
| GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
window = gdk_window_new (gtk_widget_get_parent_window (widget), &attr,
GDK_WA_X | GDK_WA_Y);
gtk_widget_set_style (widget,
gtk_style_attach (gtk_widget_get_style (widget),
window));
gdk_window_set_user_data (window, widget);
cursor = gdk_cursor_new (GDK_HAND2);
gdk_window_set_cursor (window, cursor);
gtk_widget_set_window (widget, window);
}
static gdouble
convert_longtitude_to_x (gdouble longitude, gint map_width)
{
const gdouble xdeg_offset = -6;
gdouble x;
x = (map_width * (180.0 + longitude) / 360.0)
+ (map_width * xdeg_offset / 180.0);
return x;
}
static gdouble
radians (gdouble degrees)
{
return (degrees / 360.0) * G_PI * 2;
}
static gdouble
convert_latitude_to_y (gdouble latitude, gdouble map_height)
{
gdouble bottom_lat = -59;
gdouble top_lat = 81;
gdouble top_per, y, full_range, top_offset, map_range;
top_per = top_lat / 180.0;
y = 1.25 * log (tan (G_PI_4 + 0.4 * radians (latitude)));
full_range = 4.6068250867599998;
top_offset = full_range * top_per;
map_range = fabs (1.25 * log (tan (G_PI_4 + 0.4 * radians (bottom_lat))) - top_offset);
y = fabs (y - top_offset);
y = y / map_range;
y = y * map_height;
return y;
}
static gboolean
cc_timezone_map_expose_event (GtkWidget *widget,
GdkEventExpose *event)
{
CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
GdkPixbuf *hilight, *orig_hilight;
cairo_t *cr;
GtkAllocation alloc;
gchar *file;
GError *err = NULL;
gdouble pointx, pointy;
cr = gdk_cairo_create (gtk_widget_get_window (widget));
gtk_widget_get_allocation (widget, &alloc);
/* paint background */
gdk_cairo_set_source_pixbuf (cr, priv->background, 0, 0);
cairo_paint (cr);
/* paint hilight */
file = g_strdup_printf (DATADIR "/timezone_%g.png",
priv->selected_offset);
orig_hilight = gdk_pixbuf_new_from_file (file, &err);
if (!orig_hilight)
{
g_warning ("Could not load hilight: %s",
(err) ? err->message : "Unknown Error");
if (err)
g_clear_error (&err);
}
else
{
hilight = gdk_pixbuf_scale_simple (orig_hilight, alloc.width,
alloc.height, GDK_INTERP_BILINEAR);
gdk_cairo_set_source_pixbuf (cr, hilight, 0, 0);
cairo_paint (cr);
g_object_unref (hilight);
g_object_unref (orig_hilight);
}
if (priv->location)
{
pointx = convert_longtitude_to_x (priv->location->longitude, alloc.width);
pointy = convert_latitude_to_y (priv->location->latitude, alloc.height);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_arc (cr, pointx, pointy, 3.0, 0, 2 * G_PI);
cairo_fill (cr);
}
cairo_destroy (cr);
return TRUE;
}
static void
cc_timezone_map_class_init (CcTimezoneMapClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
g_type_class_add_private (klass, sizeof (CcTimezoneMapPrivate));
object_class->get_property = cc_timezone_map_get_property;
object_class->set_property = cc_timezone_map_set_property;
object_class->dispose = cc_timezone_map_dispose;
object_class->finalize = cc_timezone_map_finalize;
widget_class->size_request = cc_timezone_map_size_request;
widget_class->size_allocate = cc_timezone_map_size_allocate;
widget_class->realize = cc_timezone_map_realize;
widget_class->expose_event = cc_timezone_map_expose_event;
signals[LOCATION_CHANGED] = g_signal_new ("location-changed",
CC_TYPE_TIMEZONE_MAP,
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
}
static gint
sort_locations (TzLocation *a,
TzLocation *b)
{
if (a->dist > b->dist)
return 1;
if (a->dist < b->dist)
return -1;
return 0;
}
static void
set_location (CcTimezoneMap *map,
TzLocation *location)
{
CcTimezoneMapPrivate *priv = map->priv;
TzInfo *info;
priv->location = location;
info = tz_info_from_location (priv->location);
priv->selected_offset = tz_location_get_utc_offset (priv->location)
/ (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0);
g_signal_emit (map, signals[LOCATION_CHANGED], 0, priv->location);
tz_info_free (info);
}
static gboolean
button_press_event (GtkWidget *widget,
GdkEventButton *event)
{
CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
gint x, y;
guchar r, g, b, a;
guchar *pixels;
gint rowstride;
gint i;
const GPtrArray *array;
gint width, height;
GList *distances = NULL;
GtkAllocation alloc;
x = event->x;
y = event->y;
rowstride = priv->visible_map_rowstride;
pixels = priv->visible_map_pixels;
r = pixels[(rowstride * y + x * 4)];
g = pixels[(rowstride * y + x * 4) + 1];
b = pixels[(rowstride * y + x * 4) + 2];
a = pixels[(rowstride * y + x * 4) + 3];
for (i = 0; color_codes[i].offset != -100; i++)
{
if (color_codes[i].red == r && color_codes[i].green == g
&& color_codes[i].blue == b && color_codes[i].alpha == a)
{
priv->selected_offset = color_codes[i].offset;
}
}
gtk_widget_queue_draw (widget);
/* work out the co-ordinates */
array = tz_get_locations (priv->tzdb);
gtk_widget_get_allocation (widget, &alloc);
width = alloc.width;
height = alloc.height;
for (i = 0; i < array->len; i++)
{
gdouble pointx, pointy, dx, dy;
TzLocation *loc = array->pdata[i];
pointx = convert_longtitude_to_x (loc->longitude, width);
pointy = convert_latitude_to_y (loc->latitude, height);
dx = pointx - x;
dy = pointy - y;
loc->dist = dx * dx + dy * dy;
distances = g_list_prepend (distances, loc);
}
distances = g_list_sort (distances, (GCompareFunc) sort_locations);
set_location (CC_TIMEZONE_MAP (widget), (TzLocation*) distances->data);
g_list_free (distances);
return TRUE;
}
static void
cc_timezone_map_init (CcTimezoneMap *self)
{
CcTimezoneMapPrivate *priv;
GError *err = NULL;
priv = self->priv = TIMEZONE_MAP_PRIVATE (self);
priv->orig_background = gdk_pixbuf_new_from_file (DATADIR "/bg.png",
&err);
if (!priv->orig_background)
{
g_warning ("Could not load background image: %s",
(err) ? err->message : "Unknown error");
g_clear_error (&err);
}
priv->orig_color_map = gdk_pixbuf_new_from_file (DATADIR "/cc.png",
&err);
if (!priv->orig_color_map)
{
g_warning ("Could not load background image: %s",
(err) ? err->message : "Unknown error");
g_clear_error (&err);
}
priv->tzdb = tz_load_db ();
g_signal_connect (self, "button-press-event", G_CALLBACK (button_press_event),
NULL);
/*
g_signal_connect (self, "map-event", G_CALLBACK (map_event), NULL);
g_signal_connect (self, "unmap-event", G_CALLBACK (unmap_event), NULL);
*/
}
CcTimezoneMap *
cc_timezone_map_new (void)
{
return g_object_new (CC_TYPE_TIMEZONE_MAP, NULL);
}
void
cc_timezone_map_set_timezone (CcTimezoneMap *map,
const gchar *timezone)
{
GPtrArray *locations;
guint i;
locations = tz_get_locations (map->priv->tzdb);
for (i = 0; i < locations->len; i++)
{
TzLocation *loc = locations->pdata[i];
if (!g_strcmp0 (loc->zone, timezone))
{
set_location (map, loc);
break;
}
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (C) 2010 Intel, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Author: Thomas Wood <thomas.wood@intel.com>
*
*/
#ifndef _CC_TIMEZONE_MAP_H
#define _CC_TIMEZONE_MAP_H
#include <gtk/gtk.h>
#include "tz.h"
G_BEGIN_DECLS
#define CC_TYPE_TIMEZONE_MAP cc_timezone_map_get_type()
#define CC_TIMEZONE_MAP(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
CC_TYPE_TIMEZONE_MAP, CcTimezoneMap))
#define CC_TIMEZONE_MAP_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
CC_TYPE_TIMEZONE_MAP, CcTimezoneMapClass))
#define CC_IS_TIMEZONE_MAP(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
CC_TYPE_TIMEZONE_MAP))
#define CC_IS_TIMEZONE_MAP_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
CC_TYPE_TIMEZONE_MAP))
#define CC_TIMEZONE_MAP_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
CC_TYPE_TIMEZONE_MAP, CcTimezoneMapClass))
typedef struct _CcTimezoneMap CcTimezoneMap;
typedef struct _CcTimezoneMapClass CcTimezoneMapClass;
typedef struct _CcTimezoneMapPrivate CcTimezoneMapPrivate;
struct _CcTimezoneMap
{
GtkWidget parent;
CcTimezoneMapPrivate *priv;
};
struct _CcTimezoneMapClass
{
GtkWidgetClass parent_class;
};
GType cc_timezone_map_get_type (void) G_GNUC_CONST;
CcTimezoneMap *cc_timezone_map_new (void);
void cc_timezone_map_set_timezone (CcTimezoneMap *map,
const gchar *timezone);
G_END_DECLS
#endif /* _CC_TIMEZONE_MAP_H */

BIN
panels/datetime/data/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

BIN
panels/datetime/data/cc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2010 Intel, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Author: Thomas Wood <thomas.wood@intel.com>
*
*/
#include <config.h>
#include "cc-datetime-panel.h"
#include <glib/gi18n.h>
void
g_io_module_load (GIOModule *module)
{
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
/* register the panel */
cc_date_time_panel_register (module);
}
void
g_io_module_unload (GIOModule *module)
{
}

242
panels/datetime/datetime.ui Normal file
View file

@ -0,0 +1,242 @@
<?xml version="1.0"?>
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<child>
<object class="GtkVBox" id="datetime-panel">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkHBox" id="vbox">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">Current Location:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_current_location">
<property name="visible">True</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAspectFrame" id="aspectmap">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<property name="yalign">0</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox4">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkCheckButton" id="check_auto_update">
<property name="label" translatable="yes">Keep date and time updated automatically</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="no_show_all">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCalendar" id="calendar">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="year">2010</property>
<property name="month">4</property>
<property name="day">25</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkSpinButton" id="spin_hour">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x2022;</property>
<property name="width_chars">2</property>
<property name="adjustment">adjustment_hour</property>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="spin_minute">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x2022;</property>
<property name="width_chars">2</property>
<property name="adjustment">adjustment_min</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="spin_second">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x2022;</property>
<property name="width_chars">2</property>
<property name="adjustment">adjustment_sec</property>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Current Time:</property>
</object>
</child>
<child>
<object class="GtkLabel" id="label_current_time">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">12:00:00</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Time:</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button_apply">
<property name="label">gtk-apply</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkAdjustment" id="adjustment_hour">
<property name="upper">23</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="adjustment_min">
<property name="upper">60</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="adjustment_sec">
<property name="upper">60</property>
<property name="step_increment">1</property>
</object>
</interface>

View file

@ -0,0 +1,11 @@
[Desktop Entry]
_Name=Date And Time
_Comment=Date and Time preferences panel
Exec=gnome-date_time-properties
Icon=application-x-executable
Terminal=false
Type=Application
StartupNotify=true
Categories=GNOME;GTK;Settings;DesktopSettings;
OnlyShowIn=GNOME;

View file

@ -0,0 +1,386 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2007 David Zeuthen <david@fubar.dk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "set-timezone.h"
static DBusGConnection *
get_system_bus (GError **err)
{
GError *error;
static DBusGConnection *bus = NULL;
if (bus == NULL) {
error = NULL;
bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (bus == NULL) {
g_propagate_error (err, error);
}
}
return bus;
}
#define CACHE_VALIDITY_SEC 2
typedef void (*CanDoFunc) (gint value);
static void
notify_can_do (DBusGProxy *proxy,
DBusGProxyCall *call,
void *user_data)
{
CanDoFunc callback = user_data;
GError *error = NULL;
gint value;
if (dbus_g_proxy_end_call (proxy, call,
&error,
G_TYPE_INT, &value,
G_TYPE_INVALID)) {
callback (value);
}
}
static void
refresh_can_do (const gchar *action, CanDoFunc callback)
{
DBusGConnection *bus;
DBusGProxy *proxy;
bus = get_system_bus (NULL);
if (bus == NULL)
return;
proxy = dbus_g_proxy_new_for_name (bus,
"org.gnome.SettingsDaemon.DateTimeMechanism",
"/",
"org.gnome.SettingsDaemon.DateTimeMechanism");
dbus_g_proxy_begin_call_with_timeout (proxy,
action,
notify_can_do,
callback, NULL,
INT_MAX,
G_TYPE_INVALID);
}
static gint settimezone_cache = 0;
static time_t settimezone_stamp = 0;
static void
update_can_settimezone (gint res)
{
settimezone_cache = res;
time (&settimezone_stamp);
}
gint
can_set_system_timezone (void)
{
time_t now;
time (&now);
if (ABS (now - settimezone_stamp) > CACHE_VALIDITY_SEC) {
refresh_can_do ("CanSetTimezone", update_can_settimezone);
settimezone_stamp = now;
}
return settimezone_cache;
}
static gint settime_cache = 0;
static time_t settime_stamp = 0;
static void
update_can_settime (gint res)
{
settime_cache = res;
time (&settime_stamp);
}
gint
can_set_system_time (void)
{
time_t now;
time (&now);
if (ABS (now - settime_stamp) > CACHE_VALIDITY_SEC) {
refresh_can_do ("CanSetTime", update_can_settime);
settime_stamp = now;
}
return settime_cache;
}
typedef struct {
gint ref_count;
gchar *call;
gint64 time;
gchar *filename;
GFunc callback;
gpointer data;
GDestroyNotify notify;
} SetTimeCallbackData;
static void
free_data (gpointer d)
{
SetTimeCallbackData *data = d;
data->ref_count--;
if (data->ref_count == 0) {
if (data->notify)
data->notify (data->data);
g_free (data->filename);
g_free (data);
}
}
static void
set_time_notify (DBusGProxy *proxy,
DBusGProxyCall *call,
void *user_data)
{
SetTimeCallbackData *data = user_data;
GError *error = NULL;
if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
if (data->callback)
data->callback (data->data, NULL);
}
else {
if (error->domain == DBUS_GERROR &&
error->code == DBUS_GERROR_NO_REPLY) {
/* these errors happen because dbus doesn't
* use monotonic clocks
*/
g_warning ("ignoring no-reply error when setting time");
g_error_free (error);
if (data->callback)
data->callback (data->data, NULL);
}
else {
if (data->callback)
data->callback (data->data, error);
else
g_error_free (error);
}
}
}
static void
set_time_async (SetTimeCallbackData *data)
{
DBusGConnection *bus;
DBusGProxy *proxy;
GError *err = NULL;
bus = get_system_bus (&err);
if (bus == NULL) {
if (err) {
if (data->callback)
data->callback (data->data, err);
g_clear_error (&err);
}
return;
}
proxy = dbus_g_proxy_new_for_name (bus,
"org.gnome.SettingsDaemon.DateTimeMechanism",
"/",
"org.gnome.SettingsDaemon.DateTimeMechanism");
data->ref_count++;
if (strcmp (data->call, "SetTime") == 0)
dbus_g_proxy_begin_call_with_timeout (proxy,
"SetTime",
set_time_notify,
data, free_data,
INT_MAX,
/* parameters: */
G_TYPE_INT64, data->time,
G_TYPE_INVALID,
/* return values: */
G_TYPE_INVALID);
else
dbus_g_proxy_begin_call_with_timeout (proxy,
"SetTimezone",
set_time_notify,
data, free_data,
INT_MAX,
/* parameters: */
G_TYPE_STRING, data->filename,
G_TYPE_INVALID,
/* return values: */
G_TYPE_INVALID);
}
void
set_system_time_async (gint64 time,
GFunc callback,
gpointer d,
GDestroyNotify notify)
{
SetTimeCallbackData *data;
if (time == -1)
return;
data = g_new0 (SetTimeCallbackData, 1);
data->ref_count = 1;
data->call = "SetTime";
data->time = time;
data->filename = NULL;
data->callback = callback;
data->data = d;
data->notify = notify;
set_time_async (data);
free_data (data);
}
void
set_system_timezone_async (const gchar *filename,
GFunc callback,
gpointer d,
GDestroyNotify notify)
{
SetTimeCallbackData *data;
if (filename == NULL)
return;
data = g_new0 (SetTimeCallbackData, 1);
data->ref_count = 1;
data->call = "SetTimezone";
data->time = -1;
data->filename = g_strdup (filename);
data->callback = callback;
data->data = d;
data->notify = notify;
set_time_async (data);
free_data (data);
}
/* get timezone */
typedef struct
{
GetTimezoneFunc callback;
GDestroyNotify notify;
gpointer data;
} GetTimezoneData;
static void
get_timezone_destroy_notify (GetTimezoneData *data)
{
if (data->notify && data->data)
data->notify (data);
g_free (data);
}
static void
get_timezone_notify (DBusGProxy *proxy,
DBusGProxyCall *call,
void *user_data)
{
GError *error = NULL;
gboolean retval;
gchar *string = NULL;
GetTimezoneData *data = user_data;
retval = dbus_g_proxy_end_call (proxy, call, &error,
G_TYPE_STRING, &string,
G_TYPE_INVALID);
if (data->callback) {
if (!retval) {
data->callback (data->data, NULL, error);
g_error_free (error);
}
else {
data->callback (data->data, string, NULL);
g_free (string);
}
}
}
void
get_system_timezone_async (GetTimezoneFunc callback,
gpointer user_data,
GDestroyNotify notify)
{
DBusGConnection *bus;
DBusGProxy *proxy;
GetTimezoneData *data;
GError *error = NULL;
bus = get_system_bus (&error);
if (bus == NULL) {
if (error) {
if (callback)
callback (user_data, NULL, error);
g_clear_error (&error);
}
return;
}
data = g_new0 (GetTimezoneData, 1);
data->data = user_data;
data->notify = notify;
data->callback = callback;
proxy = dbus_g_proxy_new_for_name (bus,
"org.gnome.SettingsDaemon.DateTimeMechanism",
"/",
"org.gnome.SettingsDaemon.DateTimeMechanism");
dbus_g_proxy_begin_call (proxy,
"GetTimezone",
get_timezone_notify,
data,
(GDestroyNotify) get_timezone_destroy_notify,
/* parameters: */
G_TYPE_INVALID,
/* return values: */
G_TYPE_STRING,
G_TYPE_INVALID);
}

View file

@ -0,0 +1,57 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2007 David Zeuthen <david@fubar.dk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __SET_SYSTEM_TIMEZONE_H__
#include <config.h>
#include <glib.h>
#include <time.h>
typedef void (*GetTimezoneFunc) (gpointer data,
const gchar *timezone,
GError *error);
void get_system_timezone_async (GetTimezoneFunc callback,
gpointer data,
GDestroyNotify notify);
gint can_set_system_timezone (void);
gint can_set_system_time (void);
void set_system_time_async (gint64 time,
GFunc callback,
gpointer data,
GDestroyNotify notify);
void set_system_timezone_async (const gchar *filename,
GFunc callback,
gpointer data,
GDestroyNotify notify);
#ifdef HAVE_SOLARIS
#define SYSTEM_ZONEINFODIR "/usr/share/lib/zoneinfo/tab"
#else
#define SYSTEM_ZONEINFODIR "/usr/share/zoneinfo"
#endif
#endif

336
panels/datetime/tz.c Normal file
View file

@ -0,0 +1,336 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* Generic timezone utilities.
*
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Authors: Hans Petter Jansson <hpj@ximian.com>
*
* Largely based on Michael Fulbright's work on Anaconda.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include "tz.h"
/* Forward declarations for private functions */
static float convert_pos (gchar *pos, int digits);
static int compare_country_names (const void *a, const void *b);
static void sort_locations_by_country (GPtrArray *locations);
static gchar * tz_data_file_get (void);
/* ---------------- *
* Public interface *
* ---------------- */
TzDB *
tz_load_db (void)
{
gchar *tz_data_file;
TzDB *tz_db;
FILE *tzfile;
char buf[4096];
tz_data_file = tz_data_file_get ();
if (!tz_data_file) {
g_warning ("Could not get the TimeZone data file name");
return NULL;
}
tzfile = fopen (tz_data_file, "r");
if (!tzfile) {
g_warning ("Could not open *%s*\n", tz_data_file);
g_free (tz_data_file);
return NULL;
}
tz_db = g_new0 (TzDB, 1);
tz_db->locations = g_ptr_array_new ();
while (fgets (buf, sizeof(buf), tzfile))
{
gchar **tmpstrarr;
gchar *latstr, *lngstr, *p;
TzLocation *loc;
if (*buf == '#') continue;
g_strchomp(buf);
tmpstrarr = g_strsplit(buf,"\t", 6);
latstr = g_strdup (tmpstrarr[1]);
p = latstr + 1;
while (*p != '-' && *p != '+') p++;
lngstr = g_strdup (p);
*p = '\0';
loc = g_new0 (TzLocation, 1);
loc->country = g_strdup (tmpstrarr[0]);
loc->zone = g_strdup (tmpstrarr[2]);
loc->latitude = convert_pos (latstr, 2);
loc->longitude = convert_pos (lngstr, 3);
#ifdef __sun
if (tmpstrarr[3] && *tmpstrarr[3] == '-' && tmpstrarr[4])
loc->comment = g_strdup (tmpstrarr[4]);
if (tmpstrarr[3] && *tmpstrarr[3] != '-' && !islower(loc->zone)) {
TzLocation *locgrp;
/* duplicate entry */
locgrp = g_new0 (TzLocation, 1);
locgrp->country = g_strdup (tmpstrarr[0]);
locgrp->zone = g_strdup (tmpstrarr[3]);
locgrp->latitude = convert_pos (latstr, 2);
locgrp->longitude = convert_pos (lngstr, 3);
locgrp->comment = (tmpstrarr[4]) ? g_strdup (tmpstrarr[4]) : NULL;
g_ptr_array_add (tz_db->locations, (gpointer) locgrp);
}
#else
loc->comment = (tmpstrarr[3]) ? g_strdup(tmpstrarr[3]) : NULL;
#endif
g_ptr_array_add (tz_db->locations, (gpointer) loc);
g_free (latstr);
g_free (lngstr);
g_strfreev (tmpstrarr);
}
fclose (tzfile);
/* now sort by country */
sort_locations_by_country (tz_db->locations);
g_free (tz_data_file);
return tz_db;
}
GPtrArray *
tz_get_locations (TzDB *db)
{
return db->locations;
}
gchar *
tz_location_get_country (TzLocation *loc)
{
return loc->country;
}
gchar *
tz_location_get_zone (TzLocation *loc)
{
return loc->zone;
}
gchar *
tz_location_get_comment (TzLocation *loc)
{
return loc->comment;
}
void
tz_location_get_position (TzLocation *loc, double *longitude, double *latitude)
{
*longitude = loc->longitude;
*latitude = loc->latitude;
}
glong
tz_location_get_utc_offset (TzLocation *loc)
{
TzInfo *tz_info;
glong offset;
tz_info = tz_info_from_location (loc);
offset = tz_info->utc_offset;
tz_info_free (tz_info);
return offset;
}
gint
tz_location_set_locally (TzLocation *loc)
{
gchar *str;
time_t curtime;
struct tm *curzone;
gboolean is_dst = FALSE;
gint correction = 0;
g_return_val_if_fail (loc != NULL, 0);
g_return_val_if_fail (loc->zone != NULL, 0);
curtime = time (NULL);
curzone = localtime (&curtime);
is_dst = curzone->tm_isdst;
str = g_strdup_printf ("TZ=%s", loc->zone);
putenv (str);
#if 0
curtime = time (NULL);
curzone = localtime (&curtime);
if (!is_dst && curzone->tm_isdst) {
correction = (60 * 60);
}
else if (is_dst && !curzone->tm_isdst) {
correction = 0;
}
#endif
return correction;
}
TzInfo *
tz_info_from_location (TzLocation *loc)
{
TzInfo *tzinfo;
gchar *str;
time_t curtime;
struct tm *curzone;
g_return_val_if_fail (loc != NULL, NULL);
g_return_val_if_fail (loc->zone != NULL, NULL);
str = g_strdup_printf ("TZ=%s", loc->zone);
putenv (str);
#if 0
tzset ();
#endif
tzinfo = g_new0 (TzInfo, 1);
curtime = time (NULL);
curzone = localtime (&curtime);
#ifndef __sun
/* Currently this solution doesnt seem to work - I get that */
/* America/Phoenix uses daylight savings, which is wrong */
tzinfo->tzname_normal = g_strdup (curzone->tm_zone);
if (curzone->tm_isdst)
tzinfo->tzname_daylight =
g_strdup (&curzone->tm_zone[curzone->tm_isdst]);
else
tzinfo->tzname_daylight = NULL;
tzinfo->utc_offset = curzone->tm_gmtoff;
#else
tzinfo->tzname_normal = NULL;
tzinfo->tzname_daylight = NULL;
tzinfo->utc_offset = 0;
#endif
tzinfo->daylight = curzone->tm_isdst;
return tzinfo;
}
void
tz_info_free (TzInfo *tzinfo)
{
g_return_if_fail (tzinfo != NULL);
if (tzinfo->tzname_normal) g_free (tzinfo->tzname_normal);
if (tzinfo->tzname_daylight) g_free (tzinfo->tzname_daylight);
g_free (tzinfo);
}
/* ----------------- *
* Private functions *
* ----------------- */
static gchar *
tz_data_file_get (void)
{
gchar *file;
file = g_strdup (TZ_DATA_FILE);
return file;
}
static float
convert_pos (gchar *pos, int digits)
{
gchar whole[10];
gchar *fraction;
gint i;
float t1, t2;
if (!pos || strlen(pos) < 4 || digits > 9) return 0.0;
for (i = 0; i < digits + 1; i++) whole[i] = pos[i];
whole[i] = '\0';
fraction = pos + digits + 1;
t1 = g_strtod (whole, NULL);
t2 = g_strtod (fraction, NULL);
if (t1 >= 0.0) return t1 + t2/pow (10.0, strlen(fraction));
else return t1 - t2/pow (10.0, strlen(fraction));
}
#if 0
/* Currently not working */
static void
free_tzdata (TzLocation *tz)
{
if (tz->country)
g_free(tz->country);
if (tz->zone)
g_free(tz->zone);
if (tz->comment)
g_free(tz->comment);
g_free(tz);
}
#endif
static int
compare_country_names (const void *a, const void *b)
{
const TzLocation *tza = * (TzLocation **) a;
const TzLocation *tzb = * (TzLocation **) b;
return strcmp (tza->zone, tzb->zone);
}
static void
sort_locations_by_country (GPtrArray *locations)
{
qsort (locations->pdata, locations->len, sizeof (gpointer),
compare_country_names);
}

84
panels/datetime/tz.h Normal file
View file

@ -0,0 +1,84 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* Generic timezone utilities.
*
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Authors: Hans Petter Jansson <hpj@ximian.com>
*
* Largely based on Michael Fulbright's work on Anaconda.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _E_TZ_H
#define _E_TZ_H
#ifndef __sun
# define TZ_DATA_FILE "/usr/share/zoneinfo/zone.tab"
#else
# define TZ_DATA_FILE "/usr/share/lib/zoneinfo/tab/zone_sun.tab"
#endif
typedef struct _TzDB TzDB;
typedef struct _TzLocation TzLocation;
typedef struct _TzInfo TzInfo;
struct _TzDB
{
GPtrArray *locations;
};
struct _TzLocation
{
gchar *country;
gdouble latitude;
gdouble longitude;
gchar *zone;
gchar *comment;
gdouble dist; /* distance to clicked point for comparison */
};
/* see the glibc info page information on time zone information */
/* tzname_normal is the default name for the timezone */
/* tzname_daylight is the name of the zone when in daylight savings */
/* utc_offset is offset in seconds from utc */
/* daylight if non-zero then location obeys daylight savings */
struct _TzInfo
{
gchar *tzname_normal;
gchar *tzname_daylight;
glong utc_offset;
gint daylight;
};
TzDB *tz_load_db (void);
GPtrArray *tz_get_locations (TzDB *db);
void tz_location_get_position (TzLocation *loc,
double *longitude, double *latitude);
char *tz_location_get_country (TzLocation *loc);
gchar *tz_location_get_zone (TzLocation *loc);
gchar *tz_location_get_comment (TzLocation *loc);
glong tz_location_get_utc_offset (TzLocation *loc);
gint tz_location_set_locally (TzLocation *loc);
TzInfo *tz_info_from_location (TzLocation *loc);
void tz_info_free (TzInfo *tz_info);
#endif

View file

@ -33,6 +33,8 @@ capplets/common/file-transfer-dialog.c
capplets/common/gconf-property-editor.c
libgnome-control-center/gconf-property-editor.c
capplets/common/gnome-theme-info.c
panels/datetime/datetime.ui
panels/datetime/gnome-datetime-panel.desktop.in.in
panels/default-applications/gnome-default-applications-panel.desktop.in.in
panels/default-applications/gnome-at-session.desktop.in.in
panels/default-applications/gnome-da-capplet.c

View file

@ -2,6 +2,7 @@ capplets/about-me/gnome-about-me.desktop.in
capplets/appearance/data/gnome-appearance-properties.desktop.in
capplets/appearance/data/gnome-theme-installer.desktop.in
capplets/appearance/data/gnome-theme-package.xml
panels/datetime/gnome-datetime-panel.desktop.in
panels/default-applications/gnome-default-applications-panel.desktop.in
panels/default-applications/gnome-at-session.desktop.in
panels/display/gnome-display-panel.desktop.in