diff options
Diffstat (limited to 'widgets')
49 files changed, 0 insertions, 17814 deletions
diff --git a/widgets/.cvsignore b/widgets/.cvsignore deleted file mode 100644 index d5b3a2ad62..0000000000 --- a/widgets/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -*.lo -*.la -minicard-test -minicard-label-test -reflow-test diff --git a/widgets/ChangeLog b/widgets/ChangeLog deleted file mode 100644 index f80719b0cc..0000000000 --- a/widgets/ChangeLog +++ /dev/null @@ -1,203 +0,0 @@ -2001-05-08 Gediminas Paulauskas <menesis@delfi.lt> - - * misc/e-search-bar.c (add_dropdown), (set_option): first try to - translate, then if not suceeded -- convert from utf8. This handles - cases when menuitem needs to be translated (it is passed as N_()), or is - utf8 search title. However you cannot have a search like "Folders" -- it - is translated. Part of fix for #2253. - - * misc/e-filter-bar.c: d() debugging strings. Use E_FILTERBAR_ADVANCED - macro instead of own "Advanced ..." for consistency. - -2001-05-07 Gediminas Paulauskas <menesis@delfi.lt> - - * menus/gal-view-menus.c (build_menus): convert label to locale - encoding. Still displays truncated strings. - - * menus/Makefile.am: removed -DEVOLUTION_VERSION. - -2001-04-21 Gediminas Paulauskas <menesis@delfi.lt> - - * menus/gal-view-menus.c: bonobo_ui_node_set_attr expects unstranslated - strings, so change _() to N_(). - -2001-04-12 Dan Winship <danw@ximian.com> - - * menus/gal-view-menus.c (build_menus): Fix a memory leak. - (Doesn't anyone ever change any other file in this directory? :) - -2001-04-10 Gediminas Paulauskas <menesis@delfi.lt> - - * menus/gal-view-menus.c: convert label to utf8. - -2001-04-04 Kjartan Maraas <kmaraas@gnome.org> - - * menus/gal-view-menus.c: Fix headers. - -2001-03-28 Christopher James Lahey <clahey@ximian.com> - - * menus/gal-view-menus.c (build_menus): Don't print the xml tree - here. - -2001-03-16 Miguel de Icaza <miguel@ximian.com> - - * menus/gal-view-menus.c (build_menus): Hook this up under the - "ViewBegin" node. - -2001-02-28 Miguel de Icaza <miguel@ximian.com> - - * menus/gal-view-menus.c (build_menus): Add translation string - here. - -2001-03-05 Christopher James Lahey <clahey@ximian.com> - - * menus/gal-view-menus.c (collection_changed): Rebuild when the - collection changes. - -2001-01-27 Jason Leach <jasonleach@usa.net> - - * cvs remove all files in shortcut-bar/, this widget is now in - gal, will be maintained there. - - * Makefile.am (SUBDIRS): Remove shortcut-bar from here. - -2001-01-25 Christopher James Lahey <clahey@helixcode.com> - - * menus/gal-view-menus.c: Make this actually deploy the titles - from the GalViewCollection and emit the display_view signals and - such. - -2001-01-22 Jon Trowbridge <trow@gnu.org> - - * menus/gal-view-menus.c (define_views): Fixed - gal_define_views_dialog_new to be called with its proper argument. - -2000-12-06 Christopher James Lahey <clahey@helixcode.com> - - * menus/gal-view-menus.c, menus/gal-view-menus.h: Added a - GalViewCollection argument to the new function here. - -2000-12-04 Dan Winship <danw@helixcode.com> - - * menus/gal-view-menus.c: NULL-terminate gal_view_menus_apply's - BonoboUIVerb array to prevent a crash. (Why are there gal* things - in the evolution sources?) - -2000-11-05 Christopher James Lahey <clahey@helixcode.com> - - * e-paned/.cvsignore, e-table/.cvsignore, e-text/.cvsignore: - Removed unnecessary .cvsignore files. - -2000-09-18 Christopher James Lahey <clahey@helixcode.com> - - * Makefile.am: Removed directories that have been moved to gal. - - * e-paned/.cvsignore, e-paned/Makefile.am, e-paned/e-hpaned.c, - e-paned/e-hpaned.h, e-paned/e-paned.c, e-paned/e-paned.h, - e-paned/e-vpaned.c, e-paned/e-vpaned.h: Moved to gal. - - * e-reflow/.cvsignore, e-reflow/Makefile.am, - e-reflow/e-reflow-sorted.c, e-reflow/e-reflow-sorted.h, - e-reflow/e-reflow.c, e-reflow/e-reflow.h: Moved to gal. - - * e-table/.cvsignore, e-table/ChangeLog, e-table/LICENSE, - e-table/Makefile.am, e-table/ROADMAP.e-table, e-table/TODO, - e-table/add-col.xpm, e-table/arrow-down.xpm, e-table/arrow-up.xpm, - e-table/check-empty.xpm, e-table/check-filled.xpm, - e-table/clip.png, e-table/e-cell-checkbox.c, - e-table/e-cell-checkbox.h, e-table/e-cell-string.c, - e-table/e-cell-text.c, e-table/e-cell-text.h, - e-table/e-cell-toggle.c, e-table/e-cell-toggle.h, - e-table/e-cell-tree.c, e-table/e-cell-tree.h, e-table/e-cell.c, - e-table/e-cell.h, e-table/e-table-click-to-add.c, - e-table/e-table-click-to-add.h, e-table/e-table-col-dnd.h, - e-table/e-table-col.c, e-table/e-table-col.h, - e-table/e-table-column-model.h, e-table/e-table-column.c, - e-table/e-table-config.c, e-table/e-table-config.glade, - e-table/e-table-config.glade.h, e-table/e-table-config.h, - e-table/e-table-defines.h, e-table/e-table-example-1.c, - e-table/e-table-example-2.c, - e-table/e-table-field-chooser-dialog.c, - e-table/e-table-field-chooser-dialog.h, - e-table/e-table-field-chooser-item.c, - e-table/e-table-field-chooser-item.h, - e-table/e-table-field-chooser.c, - e-table/e-table-field-chooser.glade, - e-table/e-table-field-chooser.glade.h, - e-table/e-table-field-chooser.h, - e-table/e-table-group-container.c, - e-table/e-table-group-container.h, e-table/e-table-group-leaf.c, - e-table/e-table-group-leaf.h, e-table/e-table-group.c, - e-table/e-table-group.glade, e-table/e-table-group.glade.h, - e-table/e-table-group.h, e-table/e-table-header-item.c, - e-table/e-table-header-item.h, e-table/e-table-header.c, - e-table/e-table-header.h, e-table/e-table-item.c, - e-table/e-table-item.h, e-table/e-table-model.c, - e-table/e-table-model.h, e-table/e-table-one.c, - e-table/e-table-one.h, e-table/e-table-scrolled.c, - e-table/e-table-scrolled.h, e-table/e-table-selection-model.c, - e-table/e-table-selection-model.h, e-table/e-table-simple.c, - e-table/e-table-simple.h, e-table/e-table-size-test.c, - e-table/e-table-sort-info.c, e-table/e-table-sort-info.h, - e-table/e-table-sorted-variable.c, - e-table/e-table-sorted-variable.h, e-table/e-table-sorted.c, - e-table/e-table-sorted.h, e-table/e-table-sorter.c, - e-table/e-table-sorter.h, e-table/e-table-subset-variable.c, - e-table/e-table-subset-variable.h, e-table/e-table-subset.c, - e-table/e-table-subset.h, e-table/e-table-text-model.c, - e-table/e-table-text-model.h, e-table/e-table-tooltip.h, - e-table/e-table-tree.h, e-table/e-table.c, e-table/e-table.h, - e-table/e-tree-example-1.c, e-table/e-tree-example-2.c, - e-table/e-tree-model.c, e-table/e-tree-model.h, - e-table/e-tree-simple.c, e-table/e-tree-simple.h, - e-table/image1.png, e-table/image2.png, e-table/image3.png, - e-table/remove-col.xpm, e-table/sample.table, - e-table/table-test.c, e-table/table-test.h, e-table/test-check.c, - e-table/test-cols.c, e-table/test-table.c: Moved to gal. - - * e-text/.cvsignore, e-text/Makefile.am, e-text/e-entry-test.c, - e-text/e-entry.c, e-text/e-entry.h, - e-text/e-text-event-processor-emacs-like.c, - e-text/e-text-event-processor-emacs-like.h, - e-text/e-text-event-processor-types.h, - e-text/e-text-event-processor.c, e-text/e-text-event-processor.h, - e-text/e-text-model.c, e-text/e-text-model.h, - e-text/e-text-test.c, e-text/e-text.c, e-text/e-text.h: Moved to - gal. - -2000-09-14 Michael Meeks <michael@helixcode.com> - - * e-reflow/e-reflow-sorted.h: fix include. - -2000-09-13 Christopher James Lahey <clahey@helixcode.com> - - * Makefile.am (SUBDIRS): Added e-reflow. - - * e-reflow/e-reflow.c, e-reflow/e-reflow.h: Moved from - addressbook/gui/minicard/. - - * e-reflow/Makefile.am, e-reflow/.cvsignore: New files for a new - directory. - -2000-09-08 Lauris Kaplinski <lauris@helixcode.com> - - * e-text/e-text.c (calc_line_widths): Fix byte/char confusion - -2000-08-30 Federico Mena Quintero <federico@helixcode.com> - - * e-paned/e-hpaned.c (e_hpaned_motion): Do not flicker while - trying to resize a quantized pane. - - * e-paned/e-vpaned.c (e_vpaned_motion): Likewise. - -2000-08-30 Federico Mena Quintero <federico@helixcode.com> - - * widgets/e-paned/e-vpaned.c (e_vpaned_size_allocate): Ensure that - the child's allocation height is >= 1. - - * widgets/e-paned/e-hpaned.c (e_hpaned_size_allocate): Ensure that - the child's allocation width is >= 1. - -2000-08-30 Federico Mena Quintero <federico@helixcode.com> - - * ChangeLog: Started a ChangeLog here. diff --git a/widgets/LICENSE b/widgets/LICENSE deleted file mode 100644 index b1f6ae08a4..0000000000 --- a/widgets/LICENSE +++ /dev/null @@ -1 +0,0 @@ -This code is released under the terms of the GNU GPL. diff --git a/widgets/Makefile.am b/widgets/Makefile.am deleted file mode 100644 index b5380daa7f..0000000000 --- a/widgets/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ - -SUBDIRS = \ - misc \ - meeting-time-sel \ - menus diff --git a/widgets/meeting-time-sel/.cvsignore b/widgets/meeting-time-sel/.cvsignore deleted file mode 100644 index 50530fdf4e..0000000000 --- a/widgets/meeting-time-sel/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.deps -.libs -.pure -Makefile -Makefile.in -*.lo -*.la -test-meeting-time-selector diff --git a/widgets/meeting-time-sel/ChangeLog b/widgets/meeting-time-sel/ChangeLog deleted file mode 100644 index f2598d9fa2..0000000000 --- a/widgets/meeting-time-sel/ChangeLog +++ /dev/null @@ -1,82 +0,0 @@ -2001-05-04 JP Rosevear <jpr@ximian.com> - - * e-meeting-time-sel-list-item.c - (e_meeting_time_selector_list_item_destroy): correct type where - same pixmap mask was unreffed twice - -2001-04-24 Kjartan Maraas <kmaraas@gnome.org> - - * e-meeting-time-sel.c, test-meeting-time-sel.c: Added #include - <glib.h>. - -2001-04-08 Federico Mena Quintero <federico@ximian.com> - - * e-meeting-time-sel-item.c (e_meeting_time_selector_item_init): - Use a pretty arrow instead of GDK_TOP_LEFT_ARROW. - -2001-04-04 Kjartan Maraas <kmaraas@gnome.org> - - * e-meeting-time-sel-item.c: Fix headers. - * e-meeting-time-sel-list-item.c: Same here. - * e-meeting-time-sel.[ch]: Same here. - * test-meeting-time-sel.c: Same here. - -2001-03-29 Larry Ewing <lewing@ximian.com> - - * e-meeting-time-sel-list-item.c: s/#include/#ifdef/ to fix - Kjartan's commit. - -2001-03-29 Kjartan Maraas <kmaraas@gnome.org> - - * e-meeting-time-sel-item.c: #ifdef HAVE_CONFIG_H - * e-meeting-time-sel-list-item.c: Same here. - * e-meeting-time-sel.c: Same here. - * test-meeting-time-sel.c: And here. - -2001-03-15 Dan Winship <danw@ximian.com> - - * e-meeting-time-sel.c - (e_meeting_time_selector_on_text_item_event): - * e-meeting-time-sel-list-item.c - (e_meeting_time_selector_list_item_button_press): Update arguments - to e_canvas_item_grab_focus. - -2000-12-25 Miguel de Icaza <miguel@helixcode.com> - - * e-meeting-time-sel.c (e_meeting_time_selector_attendee_add): Set - draw_background to FALSE. - -2000-12-06 Christopher James Lahey <clahey@helixcode.com> - - * e-meeting-time-sel.c: Fixed a bunch of warnings. - -2000-09-25 Damon Chaplin <damon@helixcode.com> - - * e-meeting-time-sel-item.c: - * e-meeting-time-sel.c: fixed use of date strings to support i18n - better. - (e_meeting_time_selector_update_attendees_list_positions): updated to - use e_canvas_item_move_absolute() to position the EText items. - -2000-09-18 Christopher James Lahey <clahey@helixcode.com> - - * Makefile.am: Added $(EXTRA_GNOME_CFLAGS) and - $(EXTRA_GNOME_LIBS). Removed unneeded libraries. - - * e-meeting-time-sel-list-item.c, e-meeting-time-sel.c, - e-meeting-time-sel.h: Fixed the #include lines to deal properly - with gal. - -2000-09-06 Ettore Perazzoli <ettore@helixcode.com> - - * Makefile.am (INCLUDES): Add `$(EXTRA_GNOME_CFLAGS)'. - -2000-06-26 Christopher James Lahey <clahey@helixcode.com> - - * Makefile.am: Added the include path to top_srcdir. - -2000-06-25 Ettore Perazzoli <ettore@helixcode.com> - - * e-meeting-time-sel.c: Specify the #include path for - `e-canvas-utils.h' so that we build with builddir != srcdir. - diff --git a/widgets/meeting-time-sel/LICENSE b/widgets/meeting-time-sel/LICENSE deleted file mode 100644 index 9babf4395f..0000000000 --- a/widgets/meeting-time-sel/LICENSE +++ /dev/null @@ -1 +0,0 @@ -This code is licensed under the terms of the GNU GPL diff --git a/widgets/meeting-time-sel/Makefile.am b/widgets/meeting-time-sel/Makefile.am deleted file mode 100644 index 767de5cd86..0000000000 --- a/widgets/meeting-time-sel/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ - -INCLUDES = \ - $(EXTRA_GNOME_CFLAGS) \ - $(GNOME_INCLUDEDIR) \ - -I $(top_srcdir) \ - -DG_LOG_DOMAIN=\"meeting-time-sel\" - -noinst_LIBRARIES = \ - libevolutionmtsel.a - -libevolutionmtsel_a_SOURCES = \ - e-meeting-time-sel.c \ - e-meeting-time-sel.h \ - e-meeting-time-sel-item.c \ - e-meeting-time-sel-item.h \ - e-meeting-time-sel-list-item.c \ - e-meeting-time-sel-list-item.h - -noinst_PROGRAMS = \ - test-meeting-time-selector - -test_meeting_time_selector_SOURCES = \ - test-meeting-time-sel.c - -test_meeting_time_selector_LDADD = \ - libevolutionmtsel.a \ - $(EXTRA_GNOME_LIBS) \ - $(GNOMEUI_LIBS) - -test_meeting_time_selector_LDFLAGS = $(GNOME_LIBDIR) - -EXTRA_DIST = \ - e-meeting-time-sel-mail.xpm \ - e-meeting-time-sel-no-mail.xpm - diff --git a/widgets/meeting-time-sel/e-meeting-time-sel-item.c b/widgets/meeting-time-sel/e-meeting-time-sel-item.c deleted file mode 100644 index f67524055a..0000000000 --- a/widgets/meeting-time-sel/e-meeting-time-sel-item.c +++ /dev/null @@ -1,993 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Helix Code, 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 - */ - -/* - * EMeetingTimeSelectorItem - A GnomeCanvasItem which is used for both the main - * display canvas and the top display (with the dates, times & All Attendees). - * I didn't make these separate GnomeCanvasItems since they share a lot of - * code. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <time.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include "e-meeting-time-sel-item.h" -#include "e-meeting-time-sel.h" - -/* Initially the grid lines were drawn at the bottom of cells, but this didn't - line up well with the GtkEntry widgets, which in the default theme draw a - black shadow line across the top. So I've switched our code to draw the - lines across the top of cells. */ -#define E_MEETING_TIME_SELECTOR_DRAW_GRID_LINES_AT_BOTTOM 0 - -static void e_meeting_time_selector_item_class_init (EMeetingTimeSelectorItemClass *mts_item_class); -static void e_meeting_time_selector_item_init (EMeetingTimeSelectorItem *mts_item); -static void e_meeting_time_selector_item_destroy (GtkObject *object); - -static void e_meeting_time_selector_item_set_arg (GtkObject *o, GtkArg *arg, - guint arg_id); -static void e_meeting_time_selector_item_realize (GnomeCanvasItem *item); -static void e_meeting_time_selector_item_unrealize (GnomeCanvasItem *item); -static void e_meeting_time_selector_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, int flags); -static void e_meeting_time_selector_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, int y, - int width, int height); -static double e_meeting_time_selector_item_point (GnomeCanvasItem *item, - double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item); -static gint e_meeting_time_selector_item_event (GnomeCanvasItem *item, - GdkEvent *event); -static gint e_meeting_time_selector_item_button_press (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event); -static gint e_meeting_time_selector_item_button_release (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event); -static gint e_meeting_time_selector_item_motion_notify (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event); - -static void e_meeting_time_selector_item_paint_day_top (EMeetingTimeSelectorItem *mts_item, - GdkDrawable *drawable, - GDate *date, - int x, int scroll_y, - int width, int height); -static void e_meeting_time_selector_item_paint_all_attendees_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, GDate *date, int x, int y, int width, int height); -static void e_meeting_time_selector_item_paint_day (EMeetingTimeSelectorItem *mts_item, - GdkDrawable *drawable, - GDate *date, - int x, int scroll_y, - int width, int height); -static void e_meeting_time_selector_item_paint_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, GDate *date, int x, int scroll_y, int width, int height); -static gint e_meeting_time_selector_item_find_first_busy_period (EMeetingTimeSelectorItem *mts_item, GDate *date, gint row); -static void e_meeting_time_selector_item_paint_attendee_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, int row, int x, int y, int width, int first_period, EMeetingTimeSelectorBusyType busy_type); - -static EMeetingTimeSelectorPosition e_meeting_time_selector_item_get_drag_position (EMeetingTimeSelectorItem *mts_item, gint x, gint y); -static gboolean e_meeting_time_selector_item_calculate_busy_range (EMeetingTimeSelector *mts, - gint row, - gint x, - gint width, - gint *start_x, - gint *end_x); - -static GnomeCanvasItemClass *parent_class; - -/* The arguments we take */ -enum { - ARG_0, - ARG_MEETING_TIME_SELECTOR -}; - - -GtkType -e_meeting_time_selector_item_get_type (void) -{ - static GtkType e_meeting_time_selector_item_type = 0; - - if (!e_meeting_time_selector_item_type) { - GtkTypeInfo e_meeting_time_selector_item_info = { - "EMeetingTimeSelectorItem", - sizeof (EMeetingTimeSelectorItem), - sizeof (EMeetingTimeSelectorItemClass), - (GtkClassInitFunc) e_meeting_time_selector_item_class_init, - (GtkObjectInitFunc) e_meeting_time_selector_item_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - e_meeting_time_selector_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_meeting_time_selector_item_info); - } - - return e_meeting_time_selector_item_type; -} - - -static void -e_meeting_time_selector_item_class_init (EMeetingTimeSelectorItemClass *mts_item_class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type()); - - object_class = (GtkObjectClass *) mts_item_class; - item_class = (GnomeCanvasItemClass *) mts_item_class; - - gtk_object_add_arg_type ("EMeetingTimeSelectorItem::meeting_time_selector", - GTK_TYPE_POINTER, GTK_ARG_WRITABLE, - ARG_MEETING_TIME_SELECTOR); - - object_class->destroy = e_meeting_time_selector_item_destroy; - object_class->set_arg = e_meeting_time_selector_item_set_arg; - - /* GnomeCanvasItem method overrides */ - item_class->realize = e_meeting_time_selector_item_realize; - item_class->unrealize = e_meeting_time_selector_item_unrealize; - item_class->update = e_meeting_time_selector_item_update; - item_class->draw = e_meeting_time_selector_item_draw; - item_class->point = e_meeting_time_selector_item_point; - item_class->event = e_meeting_time_selector_item_event; -} - - -static void -e_meeting_time_selector_item_init (EMeetingTimeSelectorItem *mts_item) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (mts_item); - - mts_item->mts = NULL; - - mts_item->main_gc = NULL; - mts_item->stipple_gc = NULL; - - /* Create the cursors. */ - mts_item->normal_cursor = gdk_cursor_new (GDK_LEFT_PTR); - mts_item->resize_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - mts_item->last_cursor_set = NULL; - - item->x1 = 0; - item->y1 = 0; - item->x2 = 0; - item->y2 = 0; -} - - -static void -e_meeting_time_selector_item_destroy (GtkObject *object) -{ - EMeetingTimeSelectorItem *mts_item; - - mts_item = E_MEETING_TIME_SELECTOR_ITEM (object); - - gdk_cursor_destroy (mts_item->normal_cursor); - gdk_cursor_destroy (mts_item->resize_cursor); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (*GTK_OBJECT_CLASS (parent_class)->destroy)(object); -} - - -static void -e_meeting_time_selector_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - EMeetingTimeSelectorItem *mts_item; - - item = GNOME_CANVAS_ITEM (o); - mts_item = E_MEETING_TIME_SELECTOR_ITEM (o); - - switch (arg_id){ - case ARG_MEETING_TIME_SELECTOR: - mts_item->mts = GTK_VALUE_POINTER (*arg); - break; - } -} - - -static void -e_meeting_time_selector_item_realize (GnomeCanvasItem *item) -{ - GnomeCanvas *canvas; - GdkWindow *window; - EMeetingTimeSelectorItem *mts_item; - - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->realize) - (*GNOME_CANVAS_ITEM_CLASS (parent_class)->realize)(item); - - mts_item = E_MEETING_TIME_SELECTOR_ITEM (item); - - canvas = item->canvas; - window = GTK_WIDGET (canvas)->window; - - mts_item->main_gc = gdk_gc_new (window); - mts_item->stipple_gc = gdk_gc_new (window); -} - - -static void -e_meeting_time_selector_item_unrealize (GnomeCanvasItem *item) -{ - EMeetingTimeSelectorItem *mts_item; - - mts_item = E_MEETING_TIME_SELECTOR_ITEM (item); - - gdk_gc_unref (mts_item->main_gc); - mts_item->main_gc = NULL; - gdk_gc_unref (mts_item->stipple_gc); - mts_item->stipple_gc = NULL; - - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize) - (*GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize)(item); -} - - -static void -e_meeting_time_selector_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) -{ - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags); - - /* The grid covers the entire canvas area. */ - item->x1 = 0; - item->y1 = 0; - item->x2 = INT_MAX; - item->y2 = INT_MAX; -} - - -/* - * DRAWING ROUTINES - functions to paint the canvas item. - */ - -static void -e_meeting_time_selector_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorItem *mts_item; - EMeetingTimeSelectorAttendee *attendee; - gint day_x, meeting_start_x, meeting_end_x, bar_y, bar_height; - gint row, row_y, start_x, end_x; - GDate date, last_date, current_date; - gboolean is_display_top, show_meeting_time; - GdkGC *gc, *stipple_gc; - - mts_item = E_MEETING_TIME_SELECTOR_ITEM (item); - mts = mts_item->mts; - g_return_if_fail (mts != NULL); - gc = mts_item->main_gc; - stipple_gc = mts_item->stipple_gc; - - is_display_top = (GTK_WIDGET (item->canvas) == mts->display_top) - ? TRUE : FALSE; - - /* Calculate the first and last visible days and positions. */ - e_meeting_time_selector_calculate_day_and_position (mts, x, - &date, &day_x); - e_meeting_time_selector_calculate_day_and_position (mts, x + width, - &last_date, NULL); - - /* For the top display draw the 'All Attendees' row background. */ - if (is_display_top) { - gdk_gc_set_foreground (gc, &mts->all_attendees_bg_color); - gdk_draw_rectangle (drawable, gc, TRUE, - 0, mts->row_height * 2 - y, - width, mts->row_height); - } else { - gdk_gc_set_foreground (gc, &mts->bg_color); - gdk_draw_rectangle (drawable, gc, TRUE, 0, 0, width, height); - } - - /* Calculate the x coordinates of the meeting time. */ - show_meeting_time = e_meeting_time_selector_get_meeting_time_positions (mts, &meeting_start_x, &meeting_end_x); - - /* Draw the meeting time background. */ - if (show_meeting_time - && (meeting_end_x - 1 >= x) && (meeting_start_x + 1 < x + width) - && (meeting_end_x - meeting_start_x > 2)) { - gdk_gc_set_foreground (gc, &mts->meeting_time_bg_color); - if (is_display_top) - gdk_draw_rectangle (drawable, gc, TRUE, - meeting_start_x + 1 - x, mts->row_height * 2 - y, - meeting_end_x - meeting_start_x - 2, mts->row_height); - else - gdk_draw_rectangle (drawable, gc, TRUE, - meeting_start_x + 1 - x, 0, - meeting_end_x - meeting_start_x - 2, height); - } - - /* For the main display draw the stipple background for attendee's - that have no calendar information. */ - if (!is_display_top) { - gdk_gc_set_foreground (gc, &mts->grid_color); - gdk_gc_set_foreground (stipple_gc, &mts->grid_color); - gdk_gc_set_background (stipple_gc, &mts->stipple_bg_color); - gdk_gc_set_stipple (stipple_gc, mts->stipple); - gnome_canvas_set_stipple_origin (item->canvas, stipple_gc); - gdk_gc_set_fill (stipple_gc, GDK_OPAQUE_STIPPLED); - row = y / mts->row_height; - row_y = row * mts->row_height - y; - while (row < mts->attendees->len && row_y < height) { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - if (attendee->has_calendar_info) { - if (e_meeting_time_selector_item_calculate_busy_range (mts, row, x, width, &start_x, &end_x)) { - if (start_x >= width || end_x <= 0) { - gdk_draw_rectangle (drawable, stipple_gc, TRUE, 0, row_y, width, mts->row_height); - } else { - if (start_x >= 0) { - gdk_draw_rectangle (drawable, stipple_gc, TRUE, 0, row_y, start_x, mts->row_height); - gdk_draw_line (drawable, gc, start_x, row_y, start_x, row_y + mts->row_height); - } - if (end_x <= width) { - gdk_draw_rectangle (drawable, stipple_gc, TRUE, end_x, row_y, width - end_x, mts->row_height); - gdk_draw_line (drawable, gc, end_x, row_y, end_x, row_y + mts->row_height); - } - } - } - } else { - gdk_draw_rectangle (drawable, stipple_gc, TRUE, - 0, row_y, - width, mts->row_height); - } - row++; - row_y += mts->row_height; - } - gdk_gc_set_fill (gc, GDK_SOLID); - } - - /* Now paint the visible days one by one. */ - current_date = date; - for (;;) { - /* Currently we use the same GnomeCanvasItem class for the - top display and the main display. We may use separate - classes in future if necessary. */ - if (is_display_top) - e_meeting_time_selector_item_paint_day_top (mts_item, drawable, ¤t_date, day_x, y, width, height); - else - e_meeting_time_selector_item_paint_day (mts_item, drawable, ¤t_date, day_x, y, width, height); - - day_x += mts_item->mts->day_width; - if (g_date_compare (¤t_date, &last_date) == 0) - break; - g_date_add_days (¤t_date, 1); - } - - /* Draw the busy periods. */ - if (is_display_top) - e_meeting_time_selector_item_paint_all_attendees_busy_periods (mts_item, drawable, &date, x, y, width, height); - else - e_meeting_time_selector_item_paint_busy_periods (mts_item, drawable, &date, x, y, width, height); - - - /* Draw the currently-selected meeting time vertical bars. */ - if (show_meeting_time) { - if (is_display_top) { - bar_y = mts->row_height * 2 - y; - bar_height = mts->row_height; - } else { - bar_y = 0; - bar_height = height; - } - - gdk_gc_set_foreground (gc, &mts->grid_color); - - if ((meeting_start_x + 2 >= x) - && (meeting_start_x - 2 < x + width)) { - gdk_draw_rectangle (drawable, gc, TRUE, - meeting_start_x - 2 - x, bar_y, - 5, bar_height); - } - - if ((meeting_end_x + 2 >= x) - && (meeting_end_x - 2 < x + width)) { - gdk_draw_rectangle (drawable, gc, TRUE, - meeting_end_x - 2 - x, bar_y, - 5, bar_height); - } - } -} - - -static void -e_meeting_time_selector_item_paint_day_top (EMeetingTimeSelectorItem *mts_item, - GdkDrawable *drawable, GDate *date, - int x, int scroll_y, - int width, int height) -{ - EMeetingTimeSelector *mts; - GdkGC *gc; - GdkFont *font; - gint y, grid_x; - gchar buffer[128], *format; - gint hour, hour_x, hour_y; - GdkRectangle clip_rect; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - gdk_gc_set_foreground (gc, &mts->grid_color); - - /* Draw the horizontal lines. */ - y = mts->row_height - 1 - scroll_y; - gdk_draw_line (drawable, gc, x, y, x + mts->day_width - 1, y); - gdk_gc_set_foreground (gc, &mts->grid_shadow_color); - gdk_draw_line (drawable, gc, x, y + 1, x + mts->day_width - 1, y + 1); - gdk_gc_set_foreground (gc, &mts->grid_color); - y += mts->row_height; - gdk_draw_line (drawable, gc, x, y, x + mts->day_width - 1, y); - y += mts->row_height; - gdk_draw_line (drawable, gc, x, y, x + mts->day_width - 1, y); - - - /* Draw the vertical grid lines. */ - for (grid_x = mts->col_width - 1; - grid_x < mts->day_width - mts->col_width; - grid_x += mts->col_width) { - gdk_draw_line (drawable, gc, - x + grid_x, mts->row_height * 2 - 4 - scroll_y, - x + grid_x, height); - } - grid_x = mts->day_width - 2; - gdk_draw_line (drawable, gc, x + grid_x, 0, x + grid_x, height); - grid_x++; - gdk_draw_line (drawable, gc, x + grid_x, 0, x + grid_x, height); - - /* Draw the date. Set a clipping rectangle so we don't draw over the - next day. */ - font = GTK_WIDGET (mts)->style->font; - if (mts->date_format == E_MEETING_TIME_SELECTOR_DATE_FULL) - /* This is a strftime() format string %A = full weekday name, - %B = full month name, %d = month day, %Y = full year. */ - format = _("%A, %B %d, %Y"); - else if (mts->date_format == E_MEETING_TIME_SELECTOR_DATE_ABBREVIATED_DAY) - /* This is a strftime() format string %a = abbreviated weekday - name, %m = month number, %d = month day, %Y = full year. */ - format = _("%a %m/%d/%Y"); - else - /* This is a strftime() format string %m = month number, - %d = month day, %Y = full year. */ - format = _("%m/%d/%Y"); - - g_date_strftime (buffer, sizeof (buffer), format, date); - - clip_rect.x = x; - clip_rect.y = -scroll_y; - clip_rect.width = mts->day_width - 2; - clip_rect.height = mts->row_height - 2; - gdk_gc_set_clip_rectangle (gc, &clip_rect); - gdk_draw_string (drawable, font, gc, - x + 4, 4 + font->ascent - scroll_y, buffer); - gdk_gc_set_clip_rectangle (gc, NULL); - - /* Draw the hours. */ - hour = mts->first_hour_shown + (mts->zoomed_out ? 3 : 1); - hour_x = x + mts->col_width; - hour_y = mts->row_height + 4 + font->ascent - scroll_y; - while (hour < mts->last_hour_shown) { - gdk_draw_string (drawable, font, gc, - hour_x - (mts->hour_widths[hour] / 2), - hour_y, EMeetingTimeSelectorHours[hour]); - - hour += mts->zoomed_out ? 3 : 1; - hour_x += mts->col_width; - } -} - - -/* This paints the colored bars representing busy periods for the combined - list of attendees. For now we just paint the bars for each attendee of - each other. If we want to speed it up we could optimise it later. */ -static void -e_meeting_time_selector_item_paint_all_attendees_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, GDate *date, int x, int scroll_y, int width, int height) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorBusyType busy_type; - gint row, y; - GdkGC *gc; - gint *first_periods; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - /* Calculate the y coordinate to paint the row at in the drawable. */ - y = 2 * mts->row_height - scroll_y - 1; - - /* Get the first visible busy periods for all the attendees. */ - first_periods = g_new (gint, mts->attendees->len); - for (row = 0; row < mts->attendees->len; row++) { - first_periods[row] = e_meeting_time_selector_item_find_first_busy_period (mts_item, date, row); - } - - for (busy_type = 0; - busy_type < E_MEETING_TIME_SELECTOR_BUSY_LAST; - busy_type++) { - gdk_gc_set_foreground (gc, &mts->busy_colors[busy_type]); - for (row = 0; row < mts->attendees->len; row++) { - if (first_periods[row] == -1) - continue; - e_meeting_time_selector_item_paint_attendee_busy_periods (mts_item, drawable, x, y, width, row, first_periods[row], busy_type); - } - } - - g_free (first_periods); -} - - -static void -e_meeting_time_selector_item_paint_day (EMeetingTimeSelectorItem *mts_item, - GdkDrawable *drawable, GDate *date, - int x, int scroll_y, - int width, int height) -{ - EMeetingTimeSelector *mts; - GdkGC *gc; - gint grid_x, grid_y, attendee_index, unused_y; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - /* Draw the grid lines. The grid lines around unused rows are drawn in - a different color. */ - - /* Draw the horizontal grid lines. */ - attendee_index = scroll_y / mts->row_height; -#if E_MEETING_TIME_SELECTOR_DRAW_GRID_LINES_AT_BOTTOM - for (grid_y = mts->row_height - 1 - (scroll_y % mts->row_height); -#else - for (grid_y = - (scroll_y % mts->row_height); -#endif - grid_y < height; - grid_y += mts->row_height) - { - if (attendee_index <= mts->attendees->len) { - gdk_gc_set_foreground (gc, &mts->grid_color); - gdk_draw_line (drawable, gc, 0, grid_y, - width, grid_y); - } else { - gdk_gc_set_foreground (gc, &mts->grid_unused_color); - gdk_draw_line (drawable, gc, 0, grid_y, - width, grid_y); - } - attendee_index++; - } - - /* Draw the vertical grid lines. */ - unused_y = (mts->attendees->len * mts->row_height) - scroll_y; - if (unused_y >= 0) { - gdk_gc_set_foreground (gc, &mts->grid_color); - for (grid_x = mts->col_width - 1; - grid_x < mts->day_width - mts->col_width; - grid_x += mts->col_width) - { - gdk_draw_line (drawable, gc, - x + grid_x, 0, - x + grid_x, unused_y - 1); - } - gdk_draw_rectangle (drawable, gc, TRUE, - x + mts->day_width - 2, 0, - 2, unused_y); - } - - if (unused_y < height) { - gdk_gc_set_foreground (gc, &mts->grid_unused_color); - for (grid_x = mts->col_width - 1; - grid_x < mts->day_width - mts->col_width; - grid_x += mts->col_width) - { - gdk_draw_line (drawable, gc, - x + grid_x, unused_y, - x + grid_x, height); - } - gdk_draw_rectangle (drawable, gc, TRUE, - x + mts->day_width - 2, unused_y, - 2, height - unused_y); - } - - -} - - -/* This paints the colored bars representing busy periods for the individual - attendees. */ -static void -e_meeting_time_selector_item_paint_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, GDate *date, int x, int scroll_y, int width, int height) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorBusyType busy_type; - gint row, y, first_period; - GdkGC *gc; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - /* Calculate the first visible attendee row. */ - row = scroll_y / mts->row_height; - - /* Calculate the y coordinate to paint the row at in the drawable. */ - y = row * mts->row_height - scroll_y; - - /* Step through the attendees painting the busy periods. */ - while (y < height && row < mts->attendees->len) { - - /* Find the first visible busy period. */ - first_period = e_meeting_time_selector_item_find_first_busy_period (mts_item, date, row); - if (first_period != -1) { - /* Paint the different types of busy periods, in - reverse order of precedence, so the highest - precedences are displayed. */ - for (busy_type = 0; - busy_type < E_MEETING_TIME_SELECTOR_BUSY_LAST; - busy_type++) { - gdk_gc_set_foreground (gc, &mts->busy_colors[busy_type]); - e_meeting_time_selector_item_paint_attendee_busy_periods (mts_item, drawable, x, y, width, row, first_period, busy_type); - } - } - y += mts->row_height; - row++; - } -} - - -/* This subtracts the attendees longest_period_in_days from the given date, - and does a binary search of the attendee's busy periods array to find the - first one which could possible end on the given day or later. - If none are found it returns -1. */ -static gint -e_meeting_time_selector_item_find_first_busy_period (EMeetingTimeSelectorItem *mts_item, GDate *date, gint row) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorAttendee *attendee; - EMeetingTimeSelectorPeriod *period; - gint period_num; - - mts = mts_item->mts; - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - - period_num = e_meeting_time_selector_find_first_busy_period (mts, attendee, date); - if (period_num == -1) - return -1; - - /* Check if the period starts after the end of the current canvas - scroll area. */ - period = &g_array_index (attendee->busy_periods, - EMeetingTimeSelectorPeriod, period_num); - if (g_date_compare (&mts->last_date_shown, &period->start.date) < 0) - return -1; - - return period_num; -} - - -/* This paints the visible busy periods for one attendee which are of a certain - busy type, e.g out of office. It is passed the index of the first visible - busy period of the attendee and continues until it runs off the screen. */ -static void -e_meeting_time_selector_item_paint_attendee_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, int x, int y, int width, int row, int first_period, EMeetingTimeSelectorBusyType busy_type) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorAttendee *attendee; - EMeetingTimeSelectorPeriod *period; - GdkGC *gc; - gint period_num, x1, x2, x2_within_day, x2_within_col; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - - for (period_num = first_period; - period_num < attendee->busy_periods->len; - period_num++) { - period = &g_array_index (attendee->busy_periods, - EMeetingTimeSelectorPeriod, period_num); - - if (period->busy_type != busy_type) - continue; - - /* Convert the period start and end times to x coordinates. */ - x1 = e_meeting_time_selector_calculate_time_position (mts, &period->start); - /* If the period is off the right of the area being drawn, we - are finished. */ - if (x1 >= x + width) - return; - - x2 = e_meeting_time_selector_calculate_time_position (mts, &period->end); - /* If the period is off the left edge of the area skip it. */ - if (x2 <= x) - continue; - - /* We paint from x1 to x2 - 1, so that for example a time - from 5:00-6:00 is distinct from 6:00-7:00. - We never finish on a grid line separating days, and we only - ever paint on a normal vertical grid line if the period is - only 1 pixel wide. */ - x2_within_day = x2 % mts->day_width; - if (x2_within_day == 0) { - x2 -= 2; - } else if (x2_within_day == mts->day_width - 1) { - x2 -= 1; - } else { - x2_within_col = x2_within_day % mts->col_width; - if (x2_within_col == 0 && x2 > x1 + 1) - x2 -= 1; - } - - /* Paint the rectangle. We leave a gap of 2 pixels at the - top and bottom, remembering that the grid is painted along - the top/bottom line of each row. */ - if (x2 - x1 > 0) { -#if E_MEETING_TIME_SELECTOR_DRAW_GRID_LINES_AT_BOTTOM - gdk_draw_rectangle (drawable, gc, TRUE, - x1 - x, y + 2, - x2 - x1, mts->row_height - 5); -#else - gdk_draw_rectangle (drawable, gc, TRUE, - x1 - x, y + 3, - x2 - x1, mts->row_height - 5); -#endif - } - } -} - - -/* - * CANVAS ITEM ROUTINES - functions to be a GnomeCanvasItem. - */ - -/* This is supposed to return the nearest item the the point and the distance. - Since we are the only item we just return ourself and 0 for the distance. - This is needed so that we get button/motion events. */ -static double -e_meeting_time_selector_item_point (GnomeCanvasItem *item, double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item) -{ - *actual_item = item; - return 0.0; -} - - -static gint -e_meeting_time_selector_item_event (GnomeCanvasItem *item, GdkEvent *event) -{ - EMeetingTimeSelectorItem *mts_item; - - mts_item = E_MEETING_TIME_SELECTOR_ITEM (item); - - switch (event->type) { - case GDK_BUTTON_PRESS: - return e_meeting_time_selector_item_button_press (mts_item, - event); - case GDK_BUTTON_RELEASE: - return e_meeting_time_selector_item_button_release (mts_item, - event); - case GDK_MOTION_NOTIFY: - return e_meeting_time_selector_item_motion_notify (mts_item, - event); - default: - break; - } - - return FALSE; -} - - -/* This handles all button press events for the item. If the cursor is over - one of the meeting time vertical bars we start a drag. If not we set the - meeting time to the nearest half-hour interval. - Note that GnomeCanvas converts the event coords to world coords, - i.e. relative to the entire canvas scroll area. */ -static gint -e_meeting_time_selector_item_button_press (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorTime start_time, end_time; - EMeetingTimeSelectorPosition position; - GDate *start_date, *end_date; - gint x, y; - - mts = mts_item->mts; - x = (gint) event->button.x; - y = (gint) event->button.y; - - /* Check if we are starting a drag of the vertical meeting time bars.*/ - position = e_meeting_time_selector_item_get_drag_position (mts_item, - x, y); - if (position != E_MEETING_TIME_SELECTOR_POS_NONE) { - if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (mts_item), - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - mts_item->resize_cursor, - event->button.time) == 0 /*Success*/) { - mts->dragging_position = position; - return TRUE; - } - } - - /* Convert the x coordinate into a EMeetingTimeSelectorTime. */ - e_meeting_time_selector_calculate_time (mts, x, &start_time); - start_date = &start_time.date; - end_date = &end_time.date; - - /* Find the nearest half-hour or hour interval, depending on whether - zoomed_out is set. */ - if (mts->zoomed_out) { - start_time.minute = 0; - end_time = start_time; - end_time.hour += 1; - } else { - start_time.minute -= start_time.minute % 30; - end_time = start_time; - end_time.minute += 30; - } - - /* Fix any overflows. */ - e_meeting_time_selector_fix_time_overflows (&end_time); - - /* Set the new meeting time. */ - e_meeting_time_selector_set_meeting_time (mts_item->mts, - g_date_year (start_date), - g_date_month (start_date), - g_date_day (start_date), - start_time.hour, - start_time.minute, - g_date_year (end_date), - g_date_month (end_date), - g_date_day (end_date), - end_time.hour, - end_time.minute); - - - return FALSE; -} - - -/* This handles all button release events for the item. If we were dragging, - we finish the drag. */ -static gint -e_meeting_time_selector_item_button_release (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event) -{ - EMeetingTimeSelector *mts; - - mts = mts_item->mts; - - /* Reset any drag. */ - if (mts->dragging_position != E_MEETING_TIME_SELECTOR_POS_NONE) { - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_NONE; - e_meeting_time_selector_remove_timeout (mts); - gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (mts_item), - event->button.time); - } - - return FALSE; -} - - -/* This handles all motion notify events for the item. If button1 is pressed - we check if a drag is in progress. If not, we set the cursor if we are over - the meeting time vertical bars. Note that GnomeCanvas doesn't use motion - hints, which may affect performance. */ -static gint -e_meeting_time_selector_item_motion_notify (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorPosition position; - GdkCursor *cursor; - gint x, y; - - mts = mts_item->mts; - x = (gint) event->motion.x; - y = (gint) event->motion.y; - - if (mts->dragging_position != E_MEETING_TIME_SELECTOR_POS_NONE) { - e_meeting_time_selector_drag_meeting_time (mts, x); - return TRUE; - } - - position = e_meeting_time_selector_item_get_drag_position (mts_item, - x, y); - - /* Determine which cursor should be used. */ - if (position == E_MEETING_TIME_SELECTOR_POS_NONE) - cursor = mts_item->normal_cursor; - else - cursor = mts_item->resize_cursor; - - /* Only set the cursor if it is different to the last one we set. */ - if (mts_item->last_cursor_set != cursor) { - mts_item->last_cursor_set = cursor; - gdk_window_set_cursor (GTK_WIDGET (GNOME_CANVAS_ITEM (mts_item)->canvas)->window, cursor); - } - - return FALSE; -} - - -static EMeetingTimeSelectorPosition -e_meeting_time_selector_item_get_drag_position (EMeetingTimeSelectorItem *mts_item, - gint x, gint y) -{ - EMeetingTimeSelector *mts; - gboolean is_display_top; - gint meeting_start_x, meeting_end_x; - - mts = mts_item->mts; - - is_display_top = (GTK_WIDGET (GNOME_CANVAS_ITEM (mts_item)->canvas) == mts->display_top) ? TRUE : FALSE; - - if (is_display_top && y < mts->row_height * 2) - return E_MEETING_TIME_SELECTOR_POS_NONE; - - if (!e_meeting_time_selector_get_meeting_time_positions (mts, &meeting_start_x, &meeting_end_x)) - return E_MEETING_TIME_SELECTOR_POS_NONE; - - if (x >= meeting_end_x - 2 && x <= meeting_end_x + 2) - return E_MEETING_TIME_SELECTOR_POS_END; - - if (x >= meeting_start_x - 2 && x <= meeting_start_x + 2) - return E_MEETING_TIME_SELECTOR_POS_START; - - return E_MEETING_TIME_SELECTOR_POS_NONE; -} - - -static gboolean -e_meeting_time_selector_item_calculate_busy_range (EMeetingTimeSelector *mts, - gint row, - gint x, - gint width, - gint *start_x, - gint *end_x) -{ - EMeetingTimeSelectorAttendee *attendee; - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - - *start_x = -1; - *end_x = -1; - - if (!g_date_valid (&attendee->busy_periods_start.date) - || !g_date_valid (&attendee->busy_periods_end.date)) - return FALSE; - - *start_x = e_meeting_time_selector_calculate_time_position (mts, &attendee->busy_periods_start) - x - 1; - - *end_x = e_meeting_time_selector_calculate_time_position (mts, &attendee->busy_periods_end) - x; - - return TRUE; -} diff --git a/widgets/meeting-time-sel/e-meeting-time-sel-item.h b/widgets/meeting-time-sel/e-meeting-time-sel-item.h deleted file mode 100644 index d9fe6c6a9b..0000000000 --- a/widgets/meeting-time-sel/e-meeting-time-sel-item.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Helix Code, 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 - */ - -/* - * MeetingTimeSelectorItem - A GnomeCanvasItem which is used for both the main - * display canvas and the top display (with the dates, times & All Attendees). - * I didn't make these separate GnomeCanvasItems since they share a lot of - * code. - */ - -#ifndef _E_MEETING_TIME_SELECTOR_ITEM_H_ -#define _E_MEETING_TIME_SELECTOR_ITEM_H_ - -#include "e-meeting-time-sel.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define E_MEETING_TIME_SELECTOR_ITEM(obj) (GTK_CHECK_CAST((obj), e_meeting_time_selector_item_get_type (), EMeetingTimeSelectorItem)) -#define E_MEETING_TIME_SELECTOR_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), e_meeting_time_selector_item_get_type (), EMeetingTimeSelectorItemClass)) -#define IS_E_MEETING_TIME_SELECTOR_ITEM(o) (GTK_CHECK_TYPE((o), e_meeting_time_selector_item_get_type ())) - - -typedef struct _EMeetingTimeSelectorItem EMeetingTimeSelectorItem; -typedef struct _EMeetingTimeSelectorItemClass EMeetingTimeSelectorItemClass; - -struct _EMeetingTimeSelectorItem -{ - GnomeCanvasItem canvas_item; - - /* The parent EMeetingTimeSelector widget. */ - EMeetingTimeSelector *mts; - - /* This GC is used for most of the drawing. The fg/bg colors are - changed for each bit. */ - GdkGC *main_gc; - GdkGC *stipple_gc; - - /* The normal & resize cursors. */ - GdkCursor *normal_cursor; - GdkCursor *resize_cursor; - - /* This remembers the last cursor set on the window. */ - GdkCursor *last_cursor_set; -}; - - -struct _EMeetingTimeSelectorItemClass -{ - GnomeCanvasItemClass parent_class; -}; - -GtkType e_meeting_time_selector_item_get_type (void); - - -#endif /* _E_MEETING_TIME_SELECTOR_ITEM_H_ */ diff --git a/widgets/meeting-time-sel/e-meeting-time-sel-list-item.c b/widgets/meeting-time-sel/e-meeting-time-sel-list-item.c deleted file mode 100644 index 08fc45fae4..0000000000 --- a/widgets/meeting-time-sel/e-meeting-time-sel-list-item.c +++ /dev/null @@ -1,397 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Helix Code, 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 - */ - -/* - * EMeetingTimeSelectorListItem - A GnomeCanvasItem covering the entire attendee - * list. It just draws the grid lines between the rows and after the icon - * column. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <time.h> -#include <gtk/gtksignal.h> -#include <gal/widgets/e-canvas.h> -#include "e-meeting-time-sel-list-item.h" -#include "e-meeting-time-sel.h" - -/* This is the size of our icons. */ -#define E_MEETING_TIME_SELECTOR_ICON_WIDTH 19 -#define E_MEETING_TIME_SELECTOR_ICON_HEIGHT 16 - -#include "e-meeting-time-sel-mail.xpm" -#include "e-meeting-time-sel-no-mail.xpm" - -static void e_meeting_time_selector_list_item_class_init (EMeetingTimeSelectorListItemClass *mtsl_item_class); -static void e_meeting_time_selector_list_item_init (EMeetingTimeSelectorListItem *mtsl_item); -static void e_meeting_time_selector_list_item_destroy (GtkObject *object); - -static void e_meeting_time_selector_list_item_set_arg (GtkObject *o, GtkArg *arg, - guint arg_id); -static void e_meeting_time_selector_list_item_realize (GnomeCanvasItem *item); -static void e_meeting_time_selector_list_item_unrealize (GnomeCanvasItem *item); -static void e_meeting_time_selector_list_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, int flags); -static void e_meeting_time_selector_list_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, int y, - int width, int height); -static double e_meeting_time_selector_list_item_point (GnomeCanvasItem *item, - double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item); -static gint e_meeting_time_selector_list_item_event (GnomeCanvasItem *item, - GdkEvent *event); -static gboolean e_meeting_time_selector_list_item_button_press (EMeetingTimeSelectorListItem *mtsl_item, - GdkEvent *event); - - -static GnomeCanvasItemClass *e_meeting_time_selector_list_item_parent_class; - -/* The arguments we take */ -enum { - ARG_0, - ARG_MEETING_TIME_SELECTOR -}; - - -GtkType -e_meeting_time_selector_list_item_get_type (void) -{ - static GtkType e_meeting_time_selector_list_item_type = 0; - - if (!e_meeting_time_selector_list_item_type) { - GtkTypeInfo e_meeting_time_selector_list_item_info = { - "EMeetingTimeSelectorListItem", - sizeof (EMeetingTimeSelectorListItem), - sizeof (EMeetingTimeSelectorListItemClass), - (GtkClassInitFunc) e_meeting_time_selector_list_item_class_init, - (GtkObjectInitFunc) e_meeting_time_selector_list_item_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - e_meeting_time_selector_list_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_meeting_time_selector_list_item_info); - } - - return e_meeting_time_selector_list_item_type; -} - - -static void -e_meeting_time_selector_list_item_class_init (EMeetingTimeSelectorListItemClass *mtsl_item_class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - e_meeting_time_selector_list_item_parent_class = gtk_type_class (gnome_canvas_item_get_type()); - - object_class = (GtkObjectClass *) mtsl_item_class; - item_class = (GnomeCanvasItemClass *) mtsl_item_class; - - gtk_object_add_arg_type ("EMeetingTimeSelectorListItem::meeting_time_selector", - GTK_TYPE_POINTER, GTK_ARG_WRITABLE, - ARG_MEETING_TIME_SELECTOR); - - object_class->destroy = e_meeting_time_selector_list_item_destroy; - object_class->set_arg = e_meeting_time_selector_list_item_set_arg; - - /* GnomeCanvasItem method overrides */ - item_class->realize = e_meeting_time_selector_list_item_realize; - item_class->unrealize = e_meeting_time_selector_list_item_unrealize; - item_class->update = e_meeting_time_selector_list_item_update; - item_class->draw = e_meeting_time_selector_list_item_draw; - item_class->point = e_meeting_time_selector_list_item_point; - item_class->event = e_meeting_time_selector_list_item_event; -} - - -static void -e_meeting_time_selector_list_item_init (EMeetingTimeSelectorListItem *mtsl_item) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (mtsl_item); - GdkColormap *colormap; - - mtsl_item->mts = NULL; - - colormap = gtk_widget_get_default_colormap (); - mtsl_item->mail_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mtsl_item->mail_icon_mask, NULL, e_meeting_time_sel_mail_xpm); - mtsl_item->no_mail_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mtsl_item->no_mail_icon_mask, NULL, e_meeting_time_sel_no_mail_xpm); - - item->x1 = 0; - item->y1 = 0; - item->x2 = 0; - item->y2 = 0; -} - - -static void -e_meeting_time_selector_list_item_destroy (GtkObject *object) -{ - EMeetingTimeSelectorListItem *mtsl_item; - - mtsl_item = E_MEETING_TIME_SELECTOR_LIST_ITEM (object); - - gdk_pixmap_unref (mtsl_item->mail_icon); - gdk_pixmap_unref (mtsl_item->no_mail_icon); - gdk_bitmap_unref (mtsl_item->mail_icon_mask); - gdk_bitmap_unref (mtsl_item->no_mail_icon_mask); - - if (GTK_OBJECT_CLASS (e_meeting_time_selector_list_item_parent_class)->destroy) - (*GTK_OBJECT_CLASS (e_meeting_time_selector_list_item_parent_class)->destroy)(object); -} - - -static void -e_meeting_time_selector_list_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - EMeetingTimeSelectorListItem *mtsl_item; - - item = GNOME_CANVAS_ITEM (o); - mtsl_item = E_MEETING_TIME_SELECTOR_LIST_ITEM (o); - - switch (arg_id){ - case ARG_MEETING_TIME_SELECTOR: - mtsl_item->mts = GTK_VALUE_POINTER (*arg); - break; - } -} - - -static void -e_meeting_time_selector_list_item_realize (GnomeCanvasItem *item) -{ - GnomeCanvas *canvas; - GdkWindow *window; - EMeetingTimeSelectorListItem *mtsl_item; - - if (GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_list_item_parent_class)->realize) - (*GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_list_item_parent_class)->realize)(item); - - mtsl_item = E_MEETING_TIME_SELECTOR_LIST_ITEM (item); - - canvas = item->canvas; - window = GTK_WIDGET (canvas)->window; - - mtsl_item->main_gc = gdk_gc_new (window); -} - - -static void -e_meeting_time_selector_list_item_unrealize (GnomeCanvasItem *item) -{ - EMeetingTimeSelectorListItem *mtsl_item; - - mtsl_item = E_MEETING_TIME_SELECTOR_LIST_ITEM (item); - - gdk_gc_unref (mtsl_item->main_gc); - mtsl_item->main_gc = NULL; - - if (GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_list_item_parent_class)->unrealize) - (*GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_list_item_parent_class)->unrealize)(item); -} - - -static void -e_meeting_time_selector_list_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) -{ - if (GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_list_item_parent_class)->update) - (* GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_list_item_parent_class)->update) (item, affine, clip_path, flags); - - /* The item covers the entire canvas area. */ - item->x1 = 0; - item->y1 = 0; - item->x2 = INT_MAX; - item->y2 = INT_MAX; -} - - -/* - * DRAWING ROUTINES - functions to paint the canvas item. - */ - -static void -e_meeting_time_selector_list_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) -{ - EMeetingTimeSelectorListItem *mtsl_item; - EMeetingTimeSelector *mts; - EMeetingTimeSelectorAttendee *attendee; - GdkGC *gc; - GdkFont *font; - gint row, row_y, icon_x, icon_y; - GdkPixmap *pixmap; - GdkBitmap *mask; - - mtsl_item = E_MEETING_TIME_SELECTOR_LIST_ITEM (item); - mts = mtsl_item->mts; - gc = mtsl_item->main_gc; - - gdk_gc_set_foreground (gc, &mts->attendee_list_bg_color); - gdk_draw_rectangle (drawable, gc, TRUE, 0, 0, width, height); - - gdk_gc_set_foreground (gc, &mts->grid_unused_color); - gdk_draw_line (drawable, gc, 24 - x, 0, 24 - x, height); - - /* Draw the grid line across the top of the row. */ - row = y / mts->row_height; - row_y = row * mts->row_height - y; - while (row_y < height) { - gdk_draw_line (drawable, gc, 0, row_y, width, row_y); - row_y += mts->row_height; - } - - row = y / mts->row_height; - row_y = row * mts->row_height - y; - icon_x = (E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH - E_MEETING_TIME_SELECTOR_ICON_WIDTH + 1) / 2 - x; - icon_y = row_y + (mts->row_height - E_MEETING_TIME_SELECTOR_ICON_HEIGHT + 1) / 2; - while (row < mts->attendees->len && row_y < height) { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - - if (attendee->send_meeting_to) { - pixmap = mtsl_item->mail_icon; - mask = mtsl_item->mail_icon_mask; - } else { - pixmap = mtsl_item->no_mail_icon; - mask = mtsl_item->no_mail_icon_mask; - } - - gdk_gc_set_clip_mask (gc, mask); - gdk_draw_pixmap (drawable, gc, pixmap, 0, 0, - icon_x, icon_y, 24, 24); - - row++; - row_y += mts->row_height; - icon_y += mts->row_height; - } - gdk_gc_set_clip_mask (gc, NULL); - - /* Draw 'Click here to add attendee' on the last dummy row. */ - row_y = mts->attendees->len * mts->row_height; - - font = GTK_WIDGET (mts)->style->font; - gdk_gc_set_foreground (gc, &mts->grid_unused_color); - gdk_draw_string (drawable, font, gc, - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH - + E_MEETING_TIME_SELECTOR_TEXT_X_PAD - x, - row_y + E_MEETING_TIME_SELECTOR_TEXT_Y_PAD - + font->ascent + 1 - y, - "Click here to add attendee"); -} - - -/* This is supposed to return the nearest item the the point and the distance. - Since we cover the entire canvas we just return ourself and 0 for the - distance. This is needed so that we get button/motion events. */ -static double -e_meeting_time_selector_list_item_point (GnomeCanvasItem *item, - double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item) -{ - *actual_item = item; - return 0.0; -} - - -static gint -e_meeting_time_selector_list_item_event (GnomeCanvasItem *item, - GdkEvent *event) -{ - EMeetingTimeSelectorListItem *mtsl_item; - - mtsl_item = E_MEETING_TIME_SELECTOR_LIST_ITEM (item); - - switch (event->type) { - case GDK_BUTTON_PRESS: - return e_meeting_time_selector_list_item_button_press (mtsl_item, event); - case GDK_BUTTON_RELEASE: - break; - case GDK_MOTION_NOTIFY: - break; - default: - break; - } - - return FALSE; -} - - -static gboolean -e_meeting_time_selector_list_item_button_press (EMeetingTimeSelectorListItem *mtsl_item, - GdkEvent *event) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorAttendee *attendee; - gint row; - gboolean return_val; - - mts = mtsl_item->mts; - row = event->button.y / mts->row_height; - - g_print ("In e_meeting_time_selector_list_item_button_press: %g,%g row:%i\n", - event->button.x, event->button.y, row); - - if (event->button.x >= E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH) { - if (row < mts->attendees->len) { - attendee = &g_array_index (mts->attendees, EMeetingTimeSelectorAttendee, row); - gtk_signal_emit_by_name (GTK_OBJECT (attendee->text_item), - "event", event, &return_val); - return return_val; - } else { - row = e_meeting_time_selector_attendee_add (mts, "", - NULL); - - /* Scroll down to show the last line.?? */ -#if 0 - adjustment = GTK_LAYOUT (mts->display_main)->vadjustment; - adjustment->value = adjustment->upper - adjustment->page_size; - gtk_adjustment_value_changed (adjustment); -#endif - - attendee = &g_array_index (mts->attendees, EMeetingTimeSelectorAttendee, row); - e_canvas_item_grab_focus (attendee->text_item, TRUE); - return TRUE; - } - } else { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - - attendee->send_meeting_to = !attendee->send_meeting_to; - - gnome_canvas_request_redraw (GNOME_CANVAS_ITEM (mtsl_item)->canvas, - 0, row * mts->row_height, - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH, - (row + 1) * mts->row_height); - return TRUE; - } -} - diff --git a/widgets/meeting-time-sel/e-meeting-time-sel-list-item.h b/widgets/meeting-time-sel/e-meeting-time-sel-list-item.h deleted file mode 100644 index 07df052c08..0000000000 --- a/widgets/meeting-time-sel/e-meeting-time-sel-list-item.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Helix Code, 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 - */ - -/* - * MeetingTimeSelectorListItem - A GnomeCanvasItem covering the entire attendee - * list. It just draws the grid lines between the rows and after the icon - * column. - */ - -#ifndef _E_MEETING_TIME_SELECTOR_LIST_ITEM_H_ -#define _E_MEETING_TIME_SELECTOR_LIST_ITEM_H_ - -#include "e-meeting-time-sel.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define E_MEETING_TIME_SELECTOR_LIST_ITEM(obj) (GTK_CHECK_CAST((obj), e_meeting_time_selector_list_item_get_type (), EMeetingTimeSelectorListItem)) -#define E_MEETING_TIME_SELECTOR_LIST_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), e_meeting_time_selector_list_item_get_type (), EMeetingTimeSelectorListItemClass)) -#define IS_E_MEETING_TIME_SELECTOR_LIST_ITEM(o) (GTK_CHECK_TYPE((o), e_meeting_time_selector_list_item_get_type ())) - - -typedef struct _EMeetingTimeSelectorListItem EMeetingTimeSelectorListItem; -typedef struct _EMeetingTimeSelectorListItemClass EMeetingTimeSelectorListItemClass; - -struct _EMeetingTimeSelectorListItem -{ - GnomeCanvasItem canvas_item; - - /* The parent EMeetingTimeSelector widget. */ - EMeetingTimeSelector *mts; - - /* This GC is used for most of the drawing. The fg/bg colors are - changed for each bit. */ - GdkGC *main_gc; - - GdkPixmap *mail_icon, *no_mail_icon; - GdkBitmap *mail_icon_mask, *no_mail_icon_mask; -}; - - -struct _EMeetingTimeSelectorListItemClass -{ - GnomeCanvasItemClass parent_class; -}; - -GtkType e_meeting_time_selector_list_item_get_type (void); - - -#endif /* _E_MEETING_TIME_SELECTOR_LIST_ITEM_H_ */ diff --git a/widgets/meeting-time-sel/e-meeting-time-sel-mail.xpm b/widgets/meeting-time-sel/e-meeting-time-sel-mail.xpm deleted file mode 100644 index 5a03c7ea8a..0000000000 --- a/widgets/meeting-time-sel/e-meeting-time-sel-mail.xpm +++ /dev/null @@ -1,135 +0,0 @@ -/* XPM */ -static char * e_meeting_time_sel_mail_xpm[] = { -"19 16 116 2", -" c None", -". c #000000", -"+ c #7B7B78", -"@ c #C7C7C3", -"# c #F1F0EB", -"$ c #BFBFBC", -"% c #5F5E5E", -"& c #E3E3DF", -"* c #F3F3EF", -"= c #F2F2EE", -"- c #F1F1EC", -"; c #F0EFEB", -"> c #D2D2CD", -", c #969592", -"' c #616060", -") c #B5B5B4", -"! c #F8F8F6", -"~ c #F7F7F5", -"{ c #F6F6F3", -"] c #F5F5F2", -"^ c #F4F4F0", -"/ c #F2F1ED", -"( c #F1F0EC", -"_ c #F0EFEA", -": c #EFEEE9", -"< c #4F4F4D", -"[ c #BDBCB8", -"} c #A7A6A3", -"| c #C6C6C4", -"1 c #7C7C7B", -"2 c #525251", -"3 c #DBDBD9", -"4 c #F5F4F1", -"5 c #F4F3F0", -"6 c #F3F2EE", -"7 c #999894", -"8 c #62625F", -"9 c #BCBCB6", -"0 c #EBE9E3", -"a c #838381", -"b c #D7D6D4", -"c c #A8A8A6", -"d c #515150", -"e c #7E7D7C", -"f c #DAD9D5", -"g c #EFEEE8", -"h c #EEEDE7", -"i c #4F4E4C", -"j c #BCBBB6", -"k c #EBE9E2", -"l c #EAE8E1", -"m c #F6F5F2", -"n c #F4F3EF", -"o c #B5B4B1", -"p c #9B9A97", -"q c #646361", -"r c #92918E", -"s c #EEEDE8", -"t c #EDECE6", -"u c #4E4E4C", -"v c #797976", -"w c #797874", -"x c #E9E8E1", -"y c #E8E7DF", -"z c #B4B3AF", -"A c #D0D0CD", -"B c #F2F2ED", -"C c #BFBEBA", -"D c #BEBDB9", -"E c #7A7A77", -"F c #979691", -"G c #EAE9E2", -"H c #959590", -"I c #787773", -"J c #B8B7B0", -"K c #E6E4DC", -"L c #A9A9A6", -"M c #626260", -"N c #ECEBE4", -"O c #EBEAE3", -"P c #E9E7E0", -"Q c #E8E6DF", -"R c #E7E5DD", -"S c #777671", -"T c #93918C", -"U c #BEBDB8", -"V c #989793", -"W c #ECEAE4", -"X c #E8E6DE", -"Y c #E6E4DB", -"Z c #E4E3DA", -"` c #75746F", -" . c #91908A", -".. c #EEECE7", -"+. c #62615F", -"@. c #EBEAE4", -"#. c #E7E6DE", -"$. c #E6E5DC", -"%. c #E5E4DB", -"&. c #E4E2DA", -"*. c #CCCBC4", -"=. c #A3A29D", -"-. c #B6B5B2", -";. c #BCBCB7", -">. c #CDCCC6", -",. c #959490", -"'. c #ECEBE5", -"). c #61615E", -"!. c #E9E8E0", -"~. c #CECDC7", -"{. c #797875", -"]. c #969590", -"^. c #CFCEC8", -"/. c #AEADA8", -"(. c #585754", -"_. c #7B7A76", -" . . . . ", -" . . . . . + @ # $ . ", -" . . . . . % $ & * = - ; > , . ", -". ' ) ! ~ { ] ^ * / ( _ : < [ } . ", -". | 1 2 3 4 5 6 / # _ : 7 8 9 0 . ", -". a b c d e f / # _ g h i j k l . ", -" . m 4 n o p q r s t u v w x y z . ", -" . A * B ( ; C D E u F G H I J K . ", -" . L / ( _ : M t N O l P Q R S T . ", -" . # _ g U V W 0 l P X R Y Z ` .. ", -" . ; g ..+.@.G x y #.$.%.&.*.=.. . ", -" . -.t ;.F G x y #.K >.,.. . . ", -" . '.).G !.Q ~.H . . . ", -" . {.].^./.. . . ", -" . (._.. . ", -" . . "}; diff --git a/widgets/meeting-time-sel/e-meeting-time-sel-no-mail.xpm b/widgets/meeting-time-sel/e-meeting-time-sel-no-mail.xpm deleted file mode 100644 index 747202b3e2..0000000000 --- a/widgets/meeting-time-sel/e-meeting-time-sel-no-mail.xpm +++ /dev/null @@ -1,123 +0,0 @@ -/* XPM */ -static char * e_meeting_time_sel_no_mail_xpm[] = { -"19 16 104 2", -" c None", -". c #000000", -"+ c #7B7B78", -"@ c #C7C7C3", -"# c #F1F0EB", -"$ c #BFBFBC", -"% c #5F5E5E", -"& c #E3E3DF", -"* c #F3F3EF", -"= c #F2F2EE", -"- c #F1F1EC", -"; c #F0EFEB", -"> c #D2D2CD", -", c #969592", -"' c #616060", -") c #B5B5B4", -"! c #F8F8F6", -"~ c #F7F7F5", -"{ c #F6F6F3", -"] c #F5F5F2", -"^ c #F4F4F0", -"/ c #F2F1ED", -"( c #F1F0EC", -"_ c #F0EFEA", -": c #EFEEE9", -"< c #4F4F4D", -"[ c #BDBCB8", -"} c #A7A6A3", -"| c #C6C6C4", -"1 c #7C7C7B", -"2 c #525251", -"3 c #DBDBD9", -"4 c #F5F4F1", -"5 c #F4F3F0", -"6 c #F3F2EE", -"7 c #999894", -"8 c #62625F", -"9 c #BCBCB6", -"0 c #EBE9E3", -"a c #838381", -"b c #D7D6D4", -"c c #A8A8A6", -"d c #515150", -"e c #7E7D7C", -"f c #DAD9D5", -"g c #D16069", -"h c #EEEDE7", -"i c #4F4E4C", -"j c #BCBBB6", -"k c #F6F5F2", -"l c #F4F3EF", -"m c #B5B4B1", -"n c #9B9A97", -"o c #646361", -"p c #92918E", -"q c #9F3C44", -"r c #797976", -"s c #B5444E", -"t c #B4B3AF", -"u c #D0D0CD", -"v c #F2F2ED", -"w c #BFBEBA", -"x c #BEBDB9", -"y c #BB565F", -"z c #812F36", -"A c #E6E4DC", -"B c #A9A9A6", -"C c #626260", -"D c #EDECE6", -"E c #ECEBE4", -"F c #BB555D", -"G c #90353D", -"H c #777671", -"I c #93918C", -"J c #EFEEE8", -"K c #BEBDB8", -"L c #989793", -"M c #ECEAE4", -"N c #E6E4DB", -"O c #E4E3DA", -"P c #75746F", -"Q c #91908A", -"R c #EEECE7", -"S c #62615F", -"T c #EBEAE4", -"U c #EAE9E2", -"V c #BD5A62", -"W c #E4E2DA", -"X c #CCCBC4", -"Y c #A3A29D", -"Z c #B6B5B2", -"` c #BCBCB7", -" . c #979691", -".. c #BC5760", -"+. c #A13C45", -"@. c #ECEBE5", -"#. c #61615E", -"$. c #C0636B", -"%. c #A83F48", -"&. c #797875", -"*. c #969590", -"=. c #CFCEC8", -"-. c #585754", -";. c #7B7A76", -" . . . . ", -" . . . . . + @ # $ . ", -" . . . . . % $ & * = - ; > , . ", -". ' ) ! ~ { ] ^ * / ( _ : < [ } . ", -". | 1 2 3 4 5 6 / # _ : 7 8 9 0 . ", -". a b c d e f / # g g h i j g g . ", -" . k 4 l m n o p g q g r g s g t . ", -" . u * v ( ; w x g s g g y z g A . ", -" . B / ( _ : C D E g s F G g H I . ", -" . # _ J K L M 0 g s s g N O P Q . ", -" . ; J R S T U g V s s g W X Y . . ", -" . Z D ` .U g ..G g g +.g . . ", -" . @.#.U g $.G g . g %.g ", -" . &.*.=.g g g . g g ", -" . -.;.. . ", -" . . "}; diff --git a/widgets/meeting-time-sel/e-meeting-time-sel.c b/widgets/meeting-time-sel/e-meeting-time-sel.c deleted file mode 100644 index 6a7c7a0f26..0000000000 --- a/widgets/meeting-time-sel/e-meeting-time-sel.c +++ /dev/null @@ -1,3308 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Helix Code, 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 - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-meeting-time-sel.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <glib.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtkalignment.h> -#include <gtk/gtkarrow.h> -#include <gtk/gtkbutton.h> -#include <gtk/gtkdrawingarea.h> -#include <gtk/gtkentry.h> -#include <gtk/gtkhbox.h> -#include <gtk/gtkhscrollbar.h> -#include <gtk/gtkhseparator.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkmenu.h> -#include <gtk/gtkradiomenuitem.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkvbox.h> -#include <gtk/gtkvscrollbar.h> -#include <libgnomeui/gnome-dateedit.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-canvas-widget.h> - -#include <gal/widgets/e-canvas.h> -#include <gal/widgets/e-canvas-utils.h> -#include "e-meeting-time-sel-item.h" -#include "e-meeting-time-sel-list-item.h" - -/* An array of hour strings, "0:00" .. "23:00". */ -const gchar *EMeetingTimeSelectorHours[24] = { - "0:00", "1:00", "2:00", "3:00", "4:00", "5:00", "6:00", "7:00", - "8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", - "16:00", "17:00", "18:00", "19:00", "20:00", "21:00", "22:00", "23:00" -}; - -/* The number of days shown in the entire canvas. */ -#define E_MEETING_TIME_SELECTOR_DAYS_SHOWN 365 - -/* This is the number of pixels between the mouse has to move before the - scroll speed is incremented. */ -#define E_MEETING_TIME_SELECTOR_SCROLL_INCREMENT_WIDTH 10 - -/* This is the maximum scrolling speed. */ -#define E_MEETING_TIME_SELECTOR_MAX_SCROLL_SPEED 4 - - -static void e_meeting_time_selector_class_init (EMeetingTimeSelectorClass * klass); -static void e_meeting_time_selector_init (EMeetingTimeSelector * mts); -static void e_meeting_time_selector_destroy (GtkObject *object); -static void e_meeting_time_selector_alloc_named_color (EMeetingTimeSelector * mts, - const char *name, GdkColor *c); -static void e_meeting_time_selector_add_key_color (EMeetingTimeSelector * mts, - GtkWidget *hbox, - gchar *label_text, - GdkColor *color); -static gint e_meeting_time_selector_expose_key_color (GtkWidget *darea, - GdkEventExpose *event, - GdkColor *color); -static gint e_meeting_time_selector_expose_title_bar (GtkWidget *darea, - GdkEventExpose *event, - gpointer data); -static void e_meeting_time_selector_options_menu_detacher (GtkWidget *widget, - GtkMenu *menu); -static void e_meeting_time_selector_autopick_menu_detacher (GtkWidget *widget, - GtkMenu *menu); -static void e_meeting_time_selector_realize (GtkWidget *widget); -static void e_meeting_time_selector_unrealize (GtkWidget *widget); -static void e_meeting_time_selector_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static gint e_meeting_time_selector_expose_event (GtkWidget *widget, - GdkEventExpose *event); -static void e_meeting_time_selector_draw (GtkWidget *widget, - GdkRectangle *area); -static void e_meeting_time_selector_draw_shadow (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_hadjustment_changed (GtkAdjustment *adjustment, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_vadjustment_changed (GtkAdjustment *adjustment, - EMeetingTimeSelector *mts); - -static void e_meeting_time_selector_on_canvas_realized (GtkWidget *widget, - EMeetingTimeSelector *mts); - -static gint e_meeting_time_selector_compare_period_starts (const void *arg1, - const void *arg2); -#if 0 -static gint e_meeting_time_selector_compare_periods (const void *arg1, - const void *arg2); -#endif -static gint e_meeting_time_selector_compare_times (EMeetingTimeSelectorTime *time1, - EMeetingTimeSelectorTime *time2); -static void e_meeting_time_selector_on_options_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_options_menu_position_callback (GtkMenu *menu, - gint *x, - gint *y, - gpointer user_data); -static void e_meeting_time_selector_on_zoomed_out_toggled (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_working_hours_toggled (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_invite_others_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_update_free_busy (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_autopick_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_autopick_menu_position_callback (GtkMenu *menu, - gint *x, - gint *y, - gpointer user_data); -static void e_meeting_time_selector_on_autopick_option_toggled (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_prev_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_next_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_autopick (EMeetingTimeSelector *mts, - gboolean forward); -static void e_meeting_time_selector_calculate_time_difference (EMeetingTimeSelectorTime *start, - EMeetingTimeSelectorTime *end, - gint *days, - gint *hours, - gint *minutes); -static void e_meeting_time_selector_find_nearest_interval (EMeetingTimeSelector *mts, - EMeetingTimeSelectorTime *start_time, - EMeetingTimeSelectorTime *end_time, - gint days, gint hours, gint mins); -static void e_meeting_time_selector_find_nearest_interval_backward (EMeetingTimeSelector *mts, - EMeetingTimeSelectorTime *start_time, - EMeetingTimeSelectorTime *end_time, - gint days, gint hours, gint mins); -static void e_meeting_time_selector_adjust_time (EMeetingTimeSelectorTime *mtstime, - gint days, gint hours, gint minutes); -static EMeetingTimeSelectorPeriod* e_meeting_time_selector_find_time_clash (EMeetingTimeSelector *mts, - EMeetingTimeSelectorAttendee *attendee, - EMeetingTimeSelectorTime *start_time, - EMeetingTimeSelectorTime *end_time); - - -static void e_meeting_time_selector_recalc_grid (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_recalc_date_format (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_save_position (EMeetingTimeSelector *mts, - EMeetingTimeSelectorTime *mtstime); -static void e_meeting_time_selector_restore_position (EMeetingTimeSelector *mts, - EMeetingTimeSelectorTime *mtstime); -static void e_meeting_time_selector_on_start_time_changed (GtkWidget *widget, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_end_time_changed (GtkWidget *widget, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_update_date_popup_menus (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_attendees_list_size_allocate (GtkWidget *widget, - GtkAllocation *allocation, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_canvas_size_allocate (GtkWidget *widget, - GtkAllocation *allocation, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_update_main_canvas_scroll_region (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_update_attendees_list_scroll_region (EMeetingTimeSelector *mts); -static gboolean e_meeting_time_selector_timeout_handler (gpointer data); -static void e_meeting_time_selector_update_start_date_edit (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_update_end_date_edit (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_ensure_meeting_time_shown (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_update_dates_shown (EMeetingTimeSelector *mts); - -static void e_meeting_time_selector_update_attendees_list_positions (EMeetingTimeSelector *mts); -static gboolean e_meeting_time_selector_on_text_item_event (GnomeCanvasItem *item, - GdkEvent *event, - EMeetingTimeSelector *mts); -static gint e_meeting_time_selector_find_row_from_text_item (EMeetingTimeSelector *mts, - GnomeCanvasItem *item); - -static GtkTableClass *parent_class; - - -GtkType -e_meeting_time_selector_get_type (void) -{ - static guint e_meeting_time_selector_type = 0; - - if (!e_meeting_time_selector_type) { - GtkTypeInfo e_meeting_time_selector_info = - { - "EMeetingTimeSelector", - sizeof (EMeetingTimeSelector), - sizeof (EMeetingTimeSelectorClass), - (GtkClassInitFunc) e_meeting_time_selector_class_init, - (GtkObjectInitFunc) e_meeting_time_selector_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - e_meeting_time_selector_type = gtk_type_unique (GTK_TYPE_TABLE, - &e_meeting_time_selector_info); - } - return e_meeting_time_selector_type; -} - - -static void -e_meeting_time_selector_class_init (EMeetingTimeSelectorClass * klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - parent_class = gtk_type_class (gtk_table_get_type()); - - object_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - - object_class->destroy = e_meeting_time_selector_destroy; - - widget_class->realize = e_meeting_time_selector_realize; - widget_class->unrealize = e_meeting_time_selector_unrealize; - widget_class->style_set = e_meeting_time_selector_style_set; - widget_class->expose_event = e_meeting_time_selector_expose_event; - widget_class->draw = e_meeting_time_selector_draw; -} - - -static void -e_meeting_time_selector_init (EMeetingTimeSelector * mts) -{ - GtkWidget *hbox, *separator, *button, *label, *table; - GtkWidget *alignment, *child_hbox, *arrow, *menuitem; - GSList *group; - GdkVisual *visual; - GdkColormap *colormap; - guint accel_key; - GtkAccelGroup *menu_accel_group; - time_t meeting_start_time; - struct tm *meeting_start_tm; - guchar stipple_bits[] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - }; - - /* The shadow is drawn in the border so it must be >= 2 pixels. */ - gtk_container_set_border_width (GTK_CONTAINER (mts), 2); - - mts->accel_group = gtk_accel_group_new (); - - mts->attendees = g_array_new (FALSE, FALSE, - sizeof (EMeetingTimeSelectorAttendee)); - - mts->working_hours_only = TRUE; - mts->day_start_hour = 9; - mts->day_start_minute = 0; - mts->day_end_hour = 18; - mts->day_end_minute = 0; - mts->zoomed_out = FALSE; - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_NONE; - - /* The default meeting time is the nearest half-hour interval in the - future, in working hours. */ - meeting_start_time = time (NULL); - g_date_clear (&mts->meeting_start_time.date, 1); - g_date_set_time (&mts->meeting_start_time.date, meeting_start_time); - meeting_start_tm = localtime (&meeting_start_time); - mts->meeting_start_time.hour = meeting_start_tm->tm_hour; - mts->meeting_start_time.minute = meeting_start_tm->tm_min; - - e_meeting_time_selector_find_nearest_interval (mts, &mts->meeting_start_time, - &mts->meeting_end_time, - 0, 0, 30); - - e_meeting_time_selector_update_dates_shown (mts); - - mts->meeting_positions_valid = FALSE; - - mts->row_height = 30; - mts->col_width = 50; - mts->day_width = 50 * 24 + 1; - - mts->auto_scroll_timeout_id = 0; - - - mts->attendees_title_bar_vbox = gtk_vbox_new (FALSE, 2); - /* Add some horizontal padding for the shadow around the display. */ - gtk_table_attach (GTK_TABLE (mts), - mts->attendees_title_bar_vbox, - 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 2, 0); - gtk_widget_show (mts->attendees_title_bar_vbox); - - mts->attendees_title_bar = gtk_drawing_area_new (); - gtk_box_pack_end (GTK_BOX (mts->attendees_title_bar_vbox), - mts->attendees_title_bar, FALSE, FALSE, 0); - gtk_widget_show (mts->attendees_title_bar); - gtk_signal_connect (GTK_OBJECT (mts->attendees_title_bar), - "expose_event", - GTK_SIGNAL_FUNC (e_meeting_time_selector_expose_title_bar), mts); - - mts->attendees_list = e_canvas_new (); - /* Add some horizontal padding for the shadow around the display. */ - gtk_table_attach (GTK_TABLE (mts), mts->attendees_list, - 0, 1, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 0); - gtk_widget_show (mts->attendees_list); - gtk_signal_connect (GTK_OBJECT (mts->attendees_list), "realize", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_canvas_realized), mts); - gtk_signal_connect (GTK_OBJECT (mts->attendees_list), "size_allocate", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_attendees_list_size_allocate), mts); - - /* Create the item in the list canvas. */ - gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (mts->attendees_list)->root), - e_meeting_time_selector_list_item_get_type (), - "EMeetingTimeSelectorListItem::meeting_time_selector", mts, - NULL); - - mts->display_top = gnome_canvas_new (); - gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->display_top), - 0, 0, - mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN, - mts->row_height * 3); - /* Add some horizontal padding for the shadow around the display. */ - gtk_table_attach (GTK_TABLE (mts), mts->display_top, - 1, 4, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 0); - gtk_widget_show (mts->display_top); - gtk_signal_connect (GTK_OBJECT (mts->display_top), "realize", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_canvas_realized), mts); - - mts->display_main = gnome_canvas_new (); - e_meeting_time_selector_update_main_canvas_scroll_region (mts); - /* Add some horizontal padding for the shadow around the display. */ - gtk_table_attach (GTK_TABLE (mts), mts->display_main, - 1, 4, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 0); - gtk_widget_show (mts->display_main); - gtk_signal_connect (GTK_OBJECT (mts->display_main), "realize", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_canvas_realized), mts); - gtk_signal_connect (GTK_OBJECT (mts->display_main), "size_allocate", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_canvas_size_allocate), mts); - - mts->hscrollbar = gtk_hscrollbar_new (GTK_LAYOUT (mts->display_main)->hadjustment); - gtk_table_attach (GTK_TABLE (mts), mts->hscrollbar, - 1, 4, 2, 3, GTK_EXPAND | GTK_FILL, 0, 0, 0); - gtk_widget_show (mts->hscrollbar); - - mts->vscrollbar = gtk_vscrollbar_new (GTK_LAYOUT (mts->display_main)->vadjustment); - gtk_table_attach (GTK_TABLE (mts), mts->vscrollbar, - 4, 5, 1, 2, 0, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (mts->vscrollbar); - - /* Create the item in the top canvas. */ - gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (mts->display_top)->root), - e_meeting_time_selector_item_get_type (), - "EMeetingTimeSelectorItem::meeting_time_selector", mts, - NULL); - - /* Create the item in the main canvas. */ - gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (mts->display_main)->root), - e_meeting_time_selector_item_get_type (), - "EMeetingTimeSelectorItem::meeting_time_selector", mts, - NULL); - - /* Create the hbox containing the color key. */ - hbox = gtk_hbox_new (FALSE, 2); - gtk_table_attach (GTK_TABLE (mts), hbox, - 1, 4, 3, 4, GTK_FILL, 0, 0, 8); - gtk_widget_show (hbox); - - e_meeting_time_selector_add_key_color (mts, hbox, _("Tentative"), &mts->busy_colors[E_MEETING_TIME_SELECTOR_BUSY_TENTATIVE]); - e_meeting_time_selector_add_key_color (mts, hbox, _("Busy"), &mts->busy_colors[E_MEETING_TIME_SELECTOR_BUSY_BUSY]); - e_meeting_time_selector_add_key_color (mts, hbox, _("Out of Office"), &mts->busy_colors[E_MEETING_TIME_SELECTOR_BUSY_OUT_OF_OFFICE]); - e_meeting_time_selector_add_key_color (mts, hbox, _("No Information"), - NULL); - - separator = gtk_hseparator_new (); - gtk_table_attach (GTK_TABLE (mts), separator, - 0, 5, 4, 5, GTK_FILL, 0, 0, 0); - gtk_widget_show (separator); - - /* Create the Invite Others & Options buttons on the left. */ - hbox = gtk_hbox_new (FALSE, 4); - gtk_table_attach (GTK_TABLE (mts), hbox, - 0, 1, 3, 4, GTK_FILL, 0, 0, 0); - gtk_widget_show (hbox); - - button = gtk_button_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (button)->child), - _("_Invite Others...")); - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); - gtk_widget_show (button); - gtk_widget_add_accelerator (button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_invite_others_button_clicked), mts); - - mts->options_button = gtk_button_new (); - gtk_box_pack_start (GTK_BOX (hbox), mts->options_button, TRUE, TRUE, 0); - gtk_widget_show (mts->options_button); - - gtk_signal_connect (GTK_OBJECT (mts->options_button), "clicked", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_options_button_clicked), mts); - - child_hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (mts->options_button), child_hbox); - gtk_widget_show (child_hbox); - - label = gtk_label_new (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (label), _("_Options")); - gtk_box_pack_start (GTK_BOX (child_hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - gtk_widget_add_accelerator (mts->options_button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK, 0); - - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT); - gtk_box_pack_start (GTK_BOX (child_hbox), arrow, FALSE, FALSE, 2); - gtk_widget_show (arrow); - - /* Create the Options menu. */ - mts->options_menu = gtk_menu_new (); - gtk_menu_attach_to_widget (GTK_MENU (mts->options_menu), mts->options_button, - e_meeting_time_selector_options_menu_detacher); - menu_accel_group = gtk_menu_ensure_uline_accel_group (GTK_MENU (mts->options_menu)); - - menuitem = gtk_check_menu_item_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("Show _Only Working Hours")); - gtk_menu_append (GTK_MENU (mts->options_menu), menuitem); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), - mts->working_hours_only); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "toggled", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_working_hours_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_check_menu_item_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("Show _Zoomed Out")); - gtk_menu_append (GTK_MENU (mts->options_menu), menuitem); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), - mts->zoomed_out); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "toggled", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_zoomed_out_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_menu_item_new (); - gtk_menu_append (GTK_MENU (mts->options_menu), menuitem); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - - menuitem = gtk_menu_item_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("_Update Free/Busy")); - gtk_menu_append (GTK_MENU (mts->options_menu), menuitem); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_update_free_busy), mts); - gtk_widget_show (menuitem); - - /* Create the 3 AutoPick buttons on the left. */ - hbox = gtk_hbox_new (FALSE, 0); - gtk_table_attach (GTK_TABLE (mts), hbox, - 0, 1, 5, 6, GTK_FILL, 0, 0, 0); - gtk_widget_show (hbox); - - button = gtk_button_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (button)->child), - _("_<<")); - gtk_widget_add_accelerator (button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK | GDK_SHIFT_MASK, 0); - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); - gtk_widget_show (button); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_prev_button_clicked), mts); - - mts->autopick_button = gtk_button_new (); - gtk_box_pack_start (GTK_BOX (hbox), mts->autopick_button, TRUE, TRUE, 0); - gtk_widget_show (mts->autopick_button); - - child_hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (mts->autopick_button), child_hbox); - gtk_widget_show (child_hbox); - - label = gtk_label_new (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (label), _("_Autopick")); - gtk_box_pack_start (GTK_BOX (child_hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - gtk_widget_add_accelerator (mts->autopick_button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (mts->autopick_button), "clicked", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_autopick_button_clicked), mts); - - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT); - gtk_box_pack_start (GTK_BOX (child_hbox), arrow, FALSE, FALSE, 2); - gtk_widget_show (arrow); - - button = gtk_button_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (button)->child), - _(">_>")); - gtk_widget_add_accelerator (button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK | GDK_SHIFT_MASK, 0); - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); - gtk_widget_show (button); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_next_button_clicked), mts); - - /* Create the Autopick menu. */ - mts->autopick_menu = gtk_menu_new (); - gtk_menu_attach_to_widget (GTK_MENU (mts->autopick_menu), mts->autopick_button, - e_meeting_time_selector_autopick_menu_detacher); - menu_accel_group = gtk_menu_ensure_uline_accel_group (GTK_MENU (mts->autopick_menu)); - - menuitem = gtk_radio_menu_item_new_with_label (NULL, ""); - mts->autopick_all_item = menuitem; - group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("_All People and Resources")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "toggled", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_autopick_option_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_radio_menu_item_new_with_label (group, ""); - mts->autopick_all_people_one_resource_item = menuitem; - group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("All _People and One Resource")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "toggled", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_autopick_option_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_radio_menu_item_new_with_label (group, ""); - mts->autopick_required_people_item = menuitem; - group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("_Required People")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_autopick_option_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_radio_menu_item_new_with_label (group, ""); - mts->autopick_required_people_one_resource_item = menuitem; - group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("Required People and _One Resource")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_autopick_option_toggled), mts); - gtk_widget_show (menuitem); - - /* Create the date entry fields on the right. */ - alignment = gtk_alignment_new (0.5, 0.5, 0, 0); - gtk_table_attach (GTK_TABLE (mts), alignment, - 1, 4, 5, 6, GTK_FILL, 0, 0, 0); - gtk_widget_show (alignment); - - table = gtk_table_new (2, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_container_add (GTK_CONTAINER (alignment), table); - gtk_widget_show (table); - - label = gtk_label_new (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (label), - _("Meeting _start time:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 0, 1, GTK_FILL, 0, 4, 0); - gtk_widget_show (label); - - mts->start_date_edit = gnome_date_edit_new (0, TRUE, TRUE); - /* I don't like the 'Calendar' label. */ - gtk_widget_hide (GNOME_DATE_EDIT (mts->start_date_edit)->cal_label); - gtk_table_attach (GTK_TABLE (table), mts->start_date_edit, - 1, 2, 0, 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (mts->start_date_edit); - gtk_signal_connect (GTK_OBJECT (mts->start_date_edit), "date_changed", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_start_time_changed), mts); - gtk_signal_connect (GTK_OBJECT (mts->start_date_edit), "time_changed", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_start_time_changed), mts); - gtk_signal_connect (GTK_OBJECT (GNOME_DATE_EDIT (mts->start_date_edit)->date_entry), "activate", GTK_SIGNAL_FUNC (e_meeting_time_selector_on_start_time_changed), mts); - gtk_signal_connect (GTK_OBJECT (GNOME_DATE_EDIT (mts->start_date_edit)->time_entry), "activate", GTK_SIGNAL_FUNC (e_meeting_time_selector_on_start_time_changed), mts); - gtk_widget_add_accelerator (GNOME_DATE_EDIT (mts->start_date_edit)->date_entry, - "grab_focus", mts->accel_group, - accel_key, GDK_MOD1_MASK, 0); - - label = gtk_label_new (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (label), - _("Meeting _end time:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 1, 2, GTK_FILL, 0, 4, 0); - gtk_widget_show (label); - - mts->end_date_edit = gnome_date_edit_new (0, TRUE, TRUE); - gtk_widget_hide (GNOME_DATE_EDIT (mts->end_date_edit)->cal_label); - gtk_table_attach (GTK_TABLE (table), mts->end_date_edit, - 1, 2, 1, 2, GTK_FILL, 0, 0, 0); - gtk_widget_show (mts->end_date_edit); - gtk_signal_connect (GTK_OBJECT (mts->end_date_edit), "date_changed", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_end_time_changed), mts); - gtk_signal_connect (GTK_OBJECT (mts->end_date_edit), "time_changed", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_end_time_changed), mts); - gtk_signal_connect (GTK_OBJECT (GNOME_DATE_EDIT (mts->end_date_edit)->date_entry), "activate", GTK_SIGNAL_FUNC (e_meeting_time_selector_on_end_time_changed), mts); - gtk_signal_connect (GTK_OBJECT (GNOME_DATE_EDIT (mts->end_date_edit)->time_entry), "activate", GTK_SIGNAL_FUNC (e_meeting_time_selector_on_end_time_changed), mts); - gtk_widget_add_accelerator (GNOME_DATE_EDIT (mts->end_date_edit)->date_entry, - "grab_focus", mts->accel_group, - accel_key, GDK_MOD1_MASK, 0); - - gtk_table_set_col_spacing (GTK_TABLE (mts), 0, 4); - gtk_table_set_row_spacing (GTK_TABLE (mts), 4, 12); - - /* Allocate the colors. */ - visual = gtk_widget_get_visual (GTK_WIDGET (mts)); - colormap = gtk_widget_get_colormap (GTK_WIDGET (mts)); - mts->color_context = gdk_color_context_new (visual, colormap); - e_meeting_time_selector_alloc_named_color (mts, "gray75", &mts->bg_color); - e_meeting_time_selector_alloc_named_color (mts, "gray50", &mts->all_attendees_bg_color); - gdk_color_black (colormap, &mts->grid_color); - gdk_color_white (colormap, &mts->grid_shadow_color); - e_meeting_time_selector_alloc_named_color (mts, "gray50", &mts->grid_unused_color); - gdk_color_white (colormap, &mts->meeting_time_bg_color); - gdk_color_white (colormap, &mts->stipple_bg_color); - gdk_color_white (colormap, &mts->attendee_list_bg_color); - - e_meeting_time_selector_alloc_named_color (mts, "LightSkyBlue2", &mts->busy_colors[E_MEETING_TIME_SELECTOR_BUSY_TENTATIVE]); - e_meeting_time_selector_alloc_named_color (mts, "blue", &mts->busy_colors[E_MEETING_TIME_SELECTOR_BUSY_BUSY]); - e_meeting_time_selector_alloc_named_color (mts, "HotPink3", &mts->busy_colors[E_MEETING_TIME_SELECTOR_BUSY_OUT_OF_OFFICE]); - - /* Create the stipple, for attendees with no data. */ - mts->stipple = gdk_bitmap_create_from_data (NULL, (gchar*)stipple_bits, - 8, 8); - - /* Connect handlers to the adjustments in the main canvas, so we can - scroll the other 2 canvases. */ - gtk_signal_connect (GTK_OBJECT (GTK_LAYOUT (mts->display_main)->hadjustment), "value_changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_hadjustment_changed), mts); - gtk_signal_connect (GTK_OBJECT (GTK_LAYOUT (mts->display_main)->vadjustment), "value_changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_vadjustment_changed), mts); - gtk_signal_connect (GTK_OBJECT (GTK_LAYOUT (mts->display_main)->vadjustment), "changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_vadjustment_changed), mts); - - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_ensure_meeting_time_shown (mts); - e_meeting_time_selector_update_start_date_edit (mts); - e_meeting_time_selector_update_end_date_edit (mts); - e_meeting_time_selector_update_date_popup_menus (mts); -} - - -/* This adds a color to the color key beneath the main display. If color is - NULL, it displays the No Info stipple instead. */ -static void -e_meeting_time_selector_add_key_color (EMeetingTimeSelector * mts, - GtkWidget *hbox, - gchar *label_text, GdkColor *color) -{ - GtkWidget *child_hbox, *darea, *label; - - child_hbox = gtk_hbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (hbox), child_hbox, TRUE, TRUE, 0); - gtk_widget_show (child_hbox); - - darea = gtk_drawing_area_new (); - gtk_box_pack_start (GTK_BOX (child_hbox), darea, FALSE, FALSE, 0); - gtk_object_set_user_data (GTK_OBJECT (darea), mts); - gtk_widget_set_usize (darea, 14, 14); - gtk_widget_show (darea); - - label = gtk_label_new (label_text); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (child_hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - - gtk_signal_connect (GTK_OBJECT (darea), "expose_event", - GTK_SIGNAL_FUNC (e_meeting_time_selector_expose_key_color), - color); -} - - -static gint -e_meeting_time_selector_expose_title_bar (GtkWidget *widget, - GdkEventExpose *event, - gpointer data) -{ - EMeetingTimeSelector * mts; - GdkFont *font; - - mts = E_MEETING_TIME_SELECTOR (data); - - gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL, - GTK_SHADOW_OUT, 0, 0, - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH + 1, - widget->allocation.height); - gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL, - GTK_SHADOW_OUT, - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH + 1, 0, - widget->allocation.width - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH - 1, - widget->allocation.height); - - font = widget->style->font; - gdk_draw_string (widget->window, font, - widget->style->fg_gc[GTK_STATE_NORMAL], - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH + 4, - 4 + font->ascent, _("All Attendees")); - - return FALSE; -} - - -static gint -e_meeting_time_selector_expose_key_color (GtkWidget *darea, - GdkEventExpose *event, - GdkColor *color) -{ - EMeetingTimeSelector * mts; - GdkGC *gc; - gint width, height; - - mts = gtk_object_get_user_data (GTK_OBJECT (darea)); - gc = mts->color_key_gc; - width = darea->allocation.width; - height = darea->allocation.height; - - gtk_draw_shadow (darea->style, darea->window, GTK_STATE_NORMAL, - GTK_SHADOW_IN, 0, 0, width, height); - - if (color) { - gdk_gc_set_foreground (gc, color); - gdk_draw_rectangle (darea->window, gc, TRUE, 1, 1, - width - 2, height - 2); - } else { - gdk_gc_set_foreground (gc, &mts->grid_color); - gdk_gc_set_background (gc, &mts->stipple_bg_color); - gdk_gc_set_stipple (gc, mts->stipple); - gdk_gc_set_fill (gc, GDK_OPAQUE_STIPPLED); - gdk_draw_rectangle (darea->window, gc, TRUE, 1, 1, - width - 2, height - 2); - gdk_gc_set_fill (gc, GDK_SOLID); - } - - return TRUE; -} - - -static void -e_meeting_time_selector_alloc_named_color (EMeetingTimeSelector * mts, - const char *name, GdkColor *c) -{ - int failed; - - g_return_if_fail (name != NULL); - g_return_if_fail (c != NULL); - - gdk_color_parse (name, c); - c->pixel = 0; - c->pixel = gdk_color_context_get_pixel (mts->color_context, - c->red, c->green, c->blue, - &failed); - if (failed) - g_warning ("Failed to allocate color: %s\n", name); -} - - -static void -e_meeting_time_selector_options_menu_detacher (GtkWidget *widget, - GtkMenu *menu) -{ - EMeetingTimeSelector *mts; - - g_return_if_fail (widget != NULL); - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (widget)); - - mts = E_MEETING_TIME_SELECTOR (widget); - g_return_if_fail (mts->options_menu == (GtkWidget*) menu); - - mts->options_menu = NULL; -} - - -static void -e_meeting_time_selector_autopick_menu_detacher (GtkWidget *widget, - GtkMenu *menu) -{ - EMeetingTimeSelector *mts; - - g_return_if_fail (widget != NULL); - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (widget)); - - mts = E_MEETING_TIME_SELECTOR (widget); - g_return_if_fail (mts->autopick_menu == (GtkWidget*) menu); - - mts->autopick_menu = NULL; -} - - -GtkWidget * -e_meeting_time_selector_new (void) -{ - GtkWidget *mts; - - mts = GTK_WIDGET (gtk_type_new (e_meeting_time_selector_get_type ())); - - return mts; -} - - -static void -e_meeting_time_selector_destroy (GtkObject *object) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorAttendee *attendee; - gint row; - - mts = E_MEETING_TIME_SELECTOR (object); - - e_meeting_time_selector_remove_timeout (mts); - - gdk_color_context_free (mts->color_context); - gdk_bitmap_unref (mts->stipple); - - for (row = 0; row < mts->attendees->len; row++) { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - g_free (attendee->name); - g_array_free (attendee->busy_periods, TRUE); - } - - g_array_free (mts->attendees, TRUE); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (*GTK_OBJECT_CLASS (parent_class)->destroy)(object); -} - - -static void -e_meeting_time_selector_realize (GtkWidget *widget) -{ - EMeetingTimeSelector *mts; - - if (GTK_WIDGET_CLASS (parent_class)->realize) - (*GTK_WIDGET_CLASS (parent_class)->realize)(widget); - - mts = E_MEETING_TIME_SELECTOR (widget); - - mts->color_key_gc = gdk_gc_new (widget->window); -} - - -static void -e_meeting_time_selector_unrealize (GtkWidget *widget) -{ - EMeetingTimeSelector *mts; - - mts = E_MEETING_TIME_SELECTOR (widget); - - gdk_gc_unref (mts->color_key_gc); - mts->color_key_gc = NULL; - - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (*GTK_WIDGET_CLASS (parent_class)->unrealize)(widget); -} - - -static void -e_meeting_time_selector_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorTime saved_time; - GdkFont *font; - gint hour, max_hour_width; - - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (*GTK_WIDGET_CLASS (parent_class)->style_set)(widget, previous_style); - - mts = E_MEETING_TIME_SELECTOR (widget); - font = widget->style->font; - - /* Calculate the widths of the hour strings in the style's font. */ - max_hour_width = 0; - for (hour = 0; hour < 24; hour++) { - mts->hour_widths[hour] = gdk_string_width (font, EMeetingTimeSelectorHours[hour]); - max_hour_width = MAX (max_hour_width, mts->hour_widths[hour]); - } - - mts->row_height = font->ascent + font->descent - + E_MEETING_TIME_SELECTOR_TEXT_Y_PAD * 2 + 1; - mts->col_width = max_hour_width + 4; - - e_meeting_time_selector_save_position (mts, &saved_time); - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_restore_position (mts, &saved_time); - - gtk_widget_set_usize (mts->display_top, -1, mts->row_height * 3); - gtk_widget_set_usize (mts->attendees_title_bar, -1, mts->row_height); - - GTK_LAYOUT (mts->display_main)->hadjustment->step_increment = mts->col_width; - GTK_LAYOUT (mts->display_main)->vadjustment->step_increment = mts->row_height; -} - - -/* This draws a shadow around the top display and main display. */ -static gint -e_meeting_time_selector_expose_event (GtkWidget *widget, - GdkEventExpose *event) -{ - EMeetingTimeSelector *mts; - - mts = E_MEETING_TIME_SELECTOR (widget); - - e_meeting_time_selector_draw_shadow (mts); - - if (GTK_WIDGET_CLASS (parent_class)->expose_event) - (*GTK_WIDGET_CLASS (parent_class)->expose_event)(widget, event); - - return FALSE; -} - - -static void -e_meeting_time_selector_draw (GtkWidget *widget, - GdkRectangle *area) -{ - EMeetingTimeSelector *mts; - - mts = E_MEETING_TIME_SELECTOR (widget); - - e_meeting_time_selector_draw_shadow (mts); - - if (GTK_WIDGET_CLASS (parent_class)->draw) - (*GTK_WIDGET_CLASS (parent_class)->draw)(widget, area); -} - - -static void -e_meeting_time_selector_draw_shadow (EMeetingTimeSelector *mts) -{ - GtkWidget *widget; - gint x, y, w, h; - - widget = GTK_WIDGET (mts); - - /* Draw the shadow around the attendees title bar and list. */ - x = mts->attendees_title_bar->allocation.x - 2; - y = mts->attendees_title_bar->allocation.y - 2; - w = mts->attendees_title_bar->allocation.width + 4; - h = mts->attendees_title_bar->allocation.height + mts->attendees_list->allocation.height + 4; - - gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL, - GTK_SHADOW_IN, x, y, w, h); - - /* Draw the shadow around the graphical displays. */ - x = mts->display_top->allocation.x - 2; - y = mts->display_top->allocation.y - 2; - w = mts->display_top->allocation.width + 4; - h = mts->display_top->allocation.height + mts->display_main->allocation.height + 4; - - gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL, - GTK_SHADOW_IN, x, y, w, h); -} - - -/* When the main canvas scrolls, we scroll the other canvases. */ -static void -e_meeting_time_selector_hadjustment_changed (GtkAdjustment *adjustment, - EMeetingTimeSelector *mts) -{ - GtkAdjustment *adj; - - adj = GTK_LAYOUT (mts->display_top)->hadjustment; - if (adj->value != adjustment->value) { - adj->value = adjustment->value; - gtk_adjustment_value_changed (adj); - } -} - - -static void -e_meeting_time_selector_vadjustment_changed (GtkAdjustment *adjustment, - EMeetingTimeSelector *mts) -{ - GtkAdjustment *adj; - - adj = GTK_LAYOUT (mts->attendees_list)->vadjustment; - if (adj->value != adjustment->value) { - adj->value = adjustment->value; - gtk_adjustment_value_changed (adj); - } -} - - -void -e_meeting_time_selector_get_meeting_time (EMeetingTimeSelector *mts, - gint *start_year, - gint *start_month, - gint *start_day, - gint *start_hour, - gint *start_minute, - gint *end_year, - gint *end_month, - gint *end_day, - gint *end_hour, - gint *end_minute) -{ - *start_year = g_date_year (&mts->meeting_start_time.date); - *start_month = g_date_month (&mts->meeting_start_time.date); - *start_day = g_date_day (&mts->meeting_start_time.date); - *start_hour = mts->meeting_start_time.hour; - *start_minute = mts->meeting_start_time.minute; - - *end_year = g_date_year (&mts->meeting_end_time.date); - *end_month = g_date_month (&mts->meeting_end_time.date); - *end_day = g_date_day (&mts->meeting_end_time.date); - *end_hour = mts->meeting_end_time.hour; - *end_minute = mts->meeting_end_time.minute; -} - - -gboolean -e_meeting_time_selector_set_meeting_time (EMeetingTimeSelector *mts, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute) -{ - g_return_val_if_fail (IS_E_MEETING_TIME_SELECTOR (mts), FALSE); - - /* Check the dates are valid. */ - if (!g_date_valid_dmy (start_day, start_month, start_year) - || !g_date_valid_dmy (end_day, end_month, end_year) - || start_hour < 0 || start_hour > 23 - || end_hour < 0 || end_hour > 23 - || start_minute < 0 || start_minute > 59 - || end_minute < 0 || end_minute > 59) - return FALSE; - - g_date_set_dmy (&mts->meeting_start_time.date, start_day, start_month, - start_year); - mts->meeting_start_time.hour = start_hour; - mts->meeting_start_time.minute = start_minute; - g_date_set_dmy (&mts->meeting_end_time.date, end_day, end_month, - end_year); - mts->meeting_end_time.hour = end_hour; - mts->meeting_end_time.minute = end_minute; - - mts->meeting_positions_valid = FALSE; - - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - - /* Set the times in the GnomeDateEdit widgets. */ - e_meeting_time_selector_update_start_date_edit (mts); - e_meeting_time_selector_update_end_date_edit (mts); - - return TRUE; -} - - -void -e_meeting_time_selector_set_working_hours_only (EMeetingTimeSelector *mts, - gboolean working_hours_only) -{ - EMeetingTimeSelectorTime saved_time; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - - if (mts->working_hours_only == working_hours_only) - return; - - mts->working_hours_only = working_hours_only; - - e_meeting_time_selector_save_position (mts, &saved_time); - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_restore_position (mts, &saved_time); - - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - e_meeting_time_selector_update_date_popup_menus (mts); -} - - -void -e_meeting_time_selector_set_working_hours (EMeetingTimeSelector *mts, - gint day_start_hour, - gint day_start_minute, - gint day_end_hour, - gint day_end_minute) -{ - EMeetingTimeSelectorTime saved_time; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - - if (mts->day_start_hour == day_start_hour - && mts->day_start_minute == day_start_minute - && mts->day_end_hour == day_end_hour - && mts->day_end_minute == day_end_minute) - return; - - mts->day_start_hour = day_start_hour; - mts->day_start_minute = day_start_minute; - mts->day_end_hour = day_end_hour; - mts->day_end_minute = day_end_minute; - - e_meeting_time_selector_save_position (mts, &saved_time); - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_restore_position (mts, &saved_time); - - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - e_meeting_time_selector_update_date_popup_menus (mts); -} - - -void -e_meeting_time_selector_set_zoomed_out (EMeetingTimeSelector *mts, - gboolean zoomed_out) -{ - EMeetingTimeSelectorTime saved_time; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - - if (mts->zoomed_out == zoomed_out) - return; - - mts->zoomed_out = zoomed_out; - - e_meeting_time_selector_save_position (mts, &saved_time); - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_restore_position (mts, &saved_time); - - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); -} - - -EMeetingTimeSelectorAutopickOption -e_meeting_time_selector_get_autopick_option (EMeetingTimeSelector *mts) -{ - if (GTK_CHECK_MENU_ITEM (mts->autopick_all_item)->active) - return E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_RESOURCES; - if (GTK_CHECK_MENU_ITEM (mts->autopick_all_people_one_resource_item)->active) - return E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_ONE_RESOURCE; - if (GTK_CHECK_MENU_ITEM (mts->autopick_required_people_item)->active) - return E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE; - return E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE; -} - - -void -e_meeting_time_selector_set_autopick_option (EMeetingTimeSelector *mts, - EMeetingTimeSelectorAutopickOption autopick_option) -{ - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - - switch (autopick_option) { - case E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_RESOURCES: - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mts->autopick_all_item), TRUE); - break; - case E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_ONE_RESOURCE: - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mts->autopick_all_people_one_resource_item), TRUE); - break; - case E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE: - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mts->autopick_required_people_item), TRUE); - break; - case E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE: - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mts->autopick_required_people_one_resource_item), TRUE); - break; - } -} - - -/* Adds an attendee to the list, returning the row. The data is meant for - something like an address book id, though if the user edits the name this - will become invalid. We'll probably have to handle address book lookup - ourself. */ -gint -e_meeting_time_selector_attendee_add (EMeetingTimeSelector *mts, - gchar *attendee_name, - gpointer data) -{ - EMeetingTimeSelectorAttendee attendee; - gint list_width, item_width; - GdkFont *font; - - g_return_val_if_fail (IS_E_MEETING_TIME_SELECTOR (mts), -1); - g_return_val_if_fail (attendee_name != NULL, -1); - - attendee.name = g_strdup (attendee_name); - attendee.type = E_MEETING_TIME_SELECTOR_REQUIRED_PERSON; - attendee.has_calendar_info = FALSE; - attendee.send_meeting_to = TRUE; - g_date_clear (&attendee.busy_periods_start.date, 1); - attendee.busy_periods_start.hour = 0; - attendee.busy_periods_start.minute = 0; - g_date_clear (&attendee.busy_periods_end.date, 1); - attendee.busy_periods_end.hour = 0; - attendee.busy_periods_end.minute = 0; - attendee.busy_periods = g_array_new (FALSE, FALSE, - sizeof (EMeetingTimeSelectorPeriod)); - attendee.busy_periods_sorted = TRUE; - attendee.longest_period_in_days = 0; - attendee.data = data; - - /* Add to the list on the left. */ - list_width = GTK_WIDGET (mts->attendees_list)->allocation.width; - item_width = MAX (1, list_width - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH - E_MEETING_TIME_SELECTOR_TEXT_X_PAD * 2); - font = GTK_WIDGET (mts)->style->font; - attendee.text_item = gnome_canvas_item_new - (GNOME_CANVAS_GROUP (GNOME_CANVAS (mts->attendees_list)->root), - e_text_get_type (), - "font_gdk", font, - "anchor", GTK_ANCHOR_NW, - "clip", TRUE, - "max_lines", 1, - "editable", TRUE, - "text", attendee_name ? attendee_name : "", - "clip_width", (gdouble) item_width, - "clip_height", (gdouble) font->ascent + font->descent, - "draw_background", FALSE, - NULL); - - e_canvas_item_move_absolute(attendee.text_item, - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH - + E_MEETING_TIME_SELECTOR_TEXT_X_PAD, - mts->attendees->len * mts->row_height + 1 - + E_MEETING_TIME_SELECTOR_TEXT_Y_PAD); -#if 0 - gnome_canvas_item_hide (attendee.text_item); -#endif - - gtk_signal_connect (GTK_OBJECT (attendee.text_item), "event", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_text_item_event), - mts); - - g_array_append_val (mts->attendees, attendee); - - /* Update the scroll region. */ - e_meeting_time_selector_update_attendees_list_scroll_region (mts); - e_meeting_time_selector_update_main_canvas_scroll_region (mts); - - /* Redraw the canvases. */ - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - - - return mts->attendees->len - 1; -} - - -gint -e_meeting_time_selector_attendee_find_by_name (EMeetingTimeSelector *mts, - gchar *attendee_name, - gint start_row) -{ - EMeetingTimeSelectorAttendee *attendee; - gint row; - - g_return_val_if_fail (IS_E_MEETING_TIME_SELECTOR (mts), -1); - g_return_val_if_fail (start_row >= 0, -1); - g_return_val_if_fail (start_row < mts->attendees->len, -1); - - for (row = start_row; row < mts->attendees->len; row++) { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - if (!strcmp (attendee->name, attendee_name)) - return row; - } - - return -1; -} - - -gint -e_meeting_time_selector_attendee_find_by_data (EMeetingTimeSelector *mts, - gpointer data, - gint start_row) -{ - EMeetingTimeSelectorAttendee *attendee; - gint row; - - g_return_val_if_fail (IS_E_MEETING_TIME_SELECTOR (mts), -1); - g_return_val_if_fail (start_row >= 0, -1); - g_return_val_if_fail (start_row < mts->attendees->len, -1); - - for (row = start_row; row < mts->attendees->len; row++) { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - if (attendee->data == data) - return row; - } - - return -1; -} - - -void -e_meeting_time_selector_attendee_remove (EMeetingTimeSelector *mts, - gint row) -{ - EMeetingTimeSelectorAttendee *attendee; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - g_return_if_fail (row >= 0); - g_return_if_fail (row < mts->attendees->len); - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - - g_free (attendee->name); - g_array_free (attendee->busy_periods, TRUE); - - /* Destroy the GtkEntry in the list. */ - gtk_object_destroy (GTK_OBJECT (attendee->text_item)); - - g_array_remove_index (mts->attendees, row); - - /* Update the positions of all the other GtkEntry widgets. */ - e_meeting_time_selector_update_attendees_list_positions (mts); - - e_meeting_time_selector_update_attendees_list_scroll_region (mts); - e_meeting_time_selector_update_main_canvas_scroll_region (mts); - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); -} - - -void -e_meeting_time_selector_attendee_set_type (EMeetingTimeSelector *mts, - gint row, - EMeetingTimeSelectorAttendeeType type) -{ - EMeetingTimeSelectorAttendee *attendee; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - g_return_if_fail (row >= 0); - g_return_if_fail (row < mts->attendees->len); - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - attendee->type = type; -} - - -void -e_meeting_time_selector_attendee_set_has_calendar_info (EMeetingTimeSelector *mts, - gint row, - gboolean has_calendar_info) -{ - EMeetingTimeSelectorAttendee *attendee; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - g_return_if_fail (row >= 0); - g_return_if_fail (row < mts->attendees->len); - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - attendee->has_calendar_info = has_calendar_info; -} - - -void -e_meeting_time_selector_attendee_set_send_meeting_to (EMeetingTimeSelector *mts, - gint row, - gboolean send_meeting_to) -{ - EMeetingTimeSelectorAttendee *attendee; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - g_return_if_fail (row >= 0); - g_return_if_fail (row < mts->attendees->len); - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - attendee->send_meeting_to = send_meeting_to; -} - - -gboolean -e_meeting_time_selector_attendee_set_busy_range (EMeetingTimeSelector *mts, - gint row, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute) -{ - EMeetingTimeSelectorAttendee *attendee; - - g_return_val_if_fail (IS_E_MEETING_TIME_SELECTOR (mts), FALSE); - g_return_val_if_fail (row >= 0, FALSE); - g_return_val_if_fail (row < mts->attendees->len, FALSE); - - /* Check the dates are valid. */ - if (!g_date_valid_dmy (start_day, start_month, start_year)) - return FALSE; - if (!g_date_valid_dmy (end_day, end_month, end_year)) - return FALSE; - if (start_hour < 0 || start_hour > 23) - return FALSE; - if (end_hour < 0 || end_hour > 23) - return FALSE; - if (start_minute < 0 || start_minute > 59) - return FALSE; - if (end_minute < 0 || end_minute > 59) - return FALSE; - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - - g_date_clear (&attendee->busy_periods_start.date, 1); - g_date_clear (&attendee->busy_periods_end.date, 1); - g_date_set_dmy (&attendee->busy_periods_start.date, - start_day, start_month, start_year); - g_date_set_dmy (&attendee->busy_periods_end.date, - end_day, end_month, end_year); - attendee->busy_periods_start.hour = start_hour; - attendee->busy_periods_start.minute = start_minute; - attendee->busy_periods_end.hour = end_hour; - attendee->busy_periods_end.minute = end_minute; - - return TRUE; -} - - -/* Clears all busy times for the given attendee. */ -void -e_meeting_time_selector_attendee_clear_busy_periods (EMeetingTimeSelector *mts, - gint row) -{ - EMeetingTimeSelectorAttendee *attendee; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - g_return_if_fail (row >= 0); - g_return_if_fail (row < mts->attendees->len); - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - - g_array_set_size (attendee->busy_periods, 0); - attendee->busy_periods_sorted = TRUE; - attendee->longest_period_in_days = 0; -} - - -/* Adds one busy time for the given attendee. It returns FALSE if the date - or time is invalid. Months and days count from 1. */ -gboolean -e_meeting_time_selector_attendee_add_busy_period (EMeetingTimeSelector *mts, - gint row, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute, - EMeetingTimeSelectorBusyType busy_type) -{ - EMeetingTimeSelectorAttendee *attendee; - EMeetingTimeSelectorPeriod period; - gint period_in_days; - - g_return_val_if_fail (IS_E_MEETING_TIME_SELECTOR (mts), FALSE); - g_return_val_if_fail (row >= 0, FALSE); - g_return_val_if_fail (row < mts->attendees->len, FALSE); - g_return_val_if_fail (busy_type >= 0, FALSE); - g_return_val_if_fail (busy_type < E_MEETING_TIME_SELECTOR_BUSY_LAST, FALSE); - - /* Check the dates are valid. */ - if (!g_date_valid_dmy (start_day, start_month, start_year)) - return FALSE; - if (!g_date_valid_dmy (end_day, end_month, end_year)) - return FALSE; - if (start_hour < 0 || start_hour > 23) - return FALSE; - if (end_hour < 0 || end_hour > 23) - return FALSE; - if (start_minute < 0 || start_minute > 59) - return FALSE; - if (end_minute < 0 || end_minute > 59) - return FALSE; - - g_date_clear (&period.start.date, 1); - g_date_clear (&period.end.date, 1); - g_date_set_dmy (&period.start.date, start_day, start_month, start_year); - g_date_set_dmy (&period.end.date, end_day, end_month, end_year); - period.start.hour = start_hour; - period.start.minute = start_minute; - period.end.hour = end_hour; - period.end.minute = end_minute; - period.busy_type = busy_type; - - /* Check that the start time is before or equal to the end time. */ - if (e_meeting_time_selector_compare_times (&period.start, &period.end) > 0) - return FALSE; - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - g_array_append_val (attendee->busy_periods, period); - attendee->has_calendar_info = TRUE; - attendee->busy_periods_sorted = FALSE; - - period_in_days = g_date_julian (&period.end.date) - g_date_julian (&period.start.date) + 1; - attendee->longest_period_in_days = MAX (attendee->longest_period_in_days, period_in_days); - - return TRUE; -} - - -void -e_meeting_time_selector_attendee_ensure_periods_sorted (EMeetingTimeSelector *mts, - EMeetingTimeSelectorAttendee *attendee) -{ - if (attendee->busy_periods_sorted) - return; - - qsort (attendee->busy_periods->data, attendee->busy_periods->len, - sizeof (EMeetingTimeSelectorPeriod), - e_meeting_time_selector_compare_period_starts); - attendee->busy_periods_sorted = TRUE; -} - - -/* This compares two time periods, using their end times. */ -static gint -e_meeting_time_selector_compare_period_starts (const void *arg1, - const void *arg2) -{ - EMeetingTimeSelectorPeriod *period1, *period2; - - period1 = (EMeetingTimeSelectorPeriod *) arg1; - period2 = (EMeetingTimeSelectorPeriod *) arg2; - - return e_meeting_time_selector_compare_times (&period1->start, - &period2->start); -} - - -/* This compares two time periods, using start and end times, mainly to see if - they overlap at all. If they overlap it returns 0. Or -1 if arg1 < arg2. - Or 1 if arg1 > arg2. */ -/* Currently unused. */ -#if 0 -static gint -e_meeting_time_selector_compare_periods (const void *arg1, - const void *arg2) -{ - EMeetingTimeSelectorPeriod *period1, *period2; - - period1 = (EMeetingTimeSelectorPeriod *) arg1; - period2 = (EMeetingTimeSelectorPeriod *) arg2; - - /* If period 2 starts after period 1 ends, return 1. */ - if (e_meeting_time_selector_compare_times (&period2->start, &period1->end) >= 0) - return 1; - - /* If period 1 starts after period 2 ends, return -1. */ - if (e_meeting_time_selector_compare_times (&period1->start, &period2->end) >= 0) - return -1; - - /* They must overlap so return 0. */ - return 0; -} -#endif - - -static gint -e_meeting_time_selector_compare_times (EMeetingTimeSelectorTime *time1, - EMeetingTimeSelectorTime *time2) -{ - gint day_comparison; - - day_comparison = g_date_compare (&time1->date, - &time2->date); - if (day_comparison != 0) - return day_comparison; - - if (time1->hour < time2->hour) - return -1; - if (time1->hour > time2->hour) - return 1; - - if (time1->minute < time2->minute) - return -1; - if (time1->minute > time2->minute) - return 1; - - /* The start times are exactly the same. */ - return 0; -} - - -/* - * DEBUGGING ROUTINES - functions to output various bits of data. - */ - -#ifdef E_MEETING_TIME_SELECTOR_DEBUG - -/* Debugging function to dump information on all attendees. */ -void -e_meeting_time_selector_dump (EMeetingTimeSelector *mts) -{ - EMeetingTimeSelectorAttendee *attendee; - EMeetingTimeSelectorPeriod *period; - gint row, period_num; - gchar buffer[128]; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - - g_print ("\n\nAttendee Information:\n"); - - for (row = 0; row < mts->attendees->len; row++) { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - g_print ("Attendee: %s\n", attendee->name); - g_print (" Longest Busy Period: %i days\n", - attendee->longest_period_in_days); - - e_meeting_time_selector_attendee_ensure_periods_sorted (mts, attendee); -#if 1 - for (period_num = 0; - period_num < attendee->busy_periods->len; - period_num++) { - period = &g_array_index (attendee->busy_periods, - EMeetingTimeSelectorPeriod, - period_num); - - /* These are just for debugging so don't need i18n. */ - g_date_strftime (buffer, sizeof (buffer), - "%A, %B %d, %Y", &period->start.date); - g_print (" Start: %s %i:%02i\n", buffer, - period->start.hour, period->start.minute); - - g_date_strftime (buffer, sizeof (buffer), - "%A, %B %d, %Y", &period->end.date); - g_print (" End : %s %i:%02i\n", buffer, - period->end.hour, period->end.minute); - } -#endif - } - -} - - -/* This formats a EMeetingTimeSelectorTime in a string and returns it. - Note that it uses a static buffer. */ -gchar* -e_meeting_time_selector_dump_time (EMeetingTimeSelectorTime *mtstime) -{ - static gchar buffer[128]; - - gchar buffer2[128]; - - /* This is just for debugging so doesn't need i18n. */ - g_date_strftime (buffer, sizeof (buffer), "%A, %B %d, %Y", - &mtstime->date); - sprintf (buffer2, " at %i:%02i", (gint) mtstime->hour, - (gint) mtstime->minute); - strcat (buffer, buffer2); - - return buffer; -} - - -/* This formats a GDate in a string and returns it. - Note that it uses a static buffer. */ -gchar* -e_meeting_time_selector_dump_date (GDate *date) -{ - static gchar buffer[128]; - - /* This is just for debugging so doesn't need i18n. */ - g_date_strftime (buffer, sizeof (buffer), "%A, %B %d, %Y", date); - return buffer; -} - -#endif /* E_MEETING_TIME_SELECTOR_DEBUG */ - - -static void -e_meeting_time_selector_on_invite_others_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - - -} - - -static void -e_meeting_time_selector_on_options_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - gtk_menu_popup (GTK_MENU (mts->options_menu), NULL, NULL, - e_meeting_time_selector_options_menu_position_callback, - mts, 1, GDK_CURRENT_TIME); -} - - -static void -e_meeting_time_selector_options_menu_position_callback (GtkMenu *menu, - gint *x, - gint *y, - gpointer user_data) -{ - EMeetingTimeSelector *mts; - GtkRequisition menu_requisition; - gint max_x, max_y; - - mts = E_MEETING_TIME_SELECTOR (user_data); - - /* Calculate our preferred position. */ - gdk_window_get_origin (mts->options_button->window, x, y); - *y += mts->options_button->allocation.height; - - /* Now make sure we are on the screen. */ - gtk_widget_size_request (mts->options_menu, &menu_requisition); - max_x = MAX (0, gdk_screen_width () - menu_requisition.width); - max_y = MAX (0, gdk_screen_height () - menu_requisition.height); - *x = CLAMP (*x, 0, max_x); - *y = CLAMP (*y, 0, max_y); -} - - -static void -e_meeting_time_selector_on_update_free_busy (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - - /* Make sure the menu pops down, which doesn't happen by default if - keyboard accelerators are used. */ - if (GTK_WIDGET_VISIBLE (mts->options_menu)) - gtk_menu_popdown (GTK_MENU (mts->options_menu)); -} - - -static void -e_meeting_time_selector_on_autopick_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - gtk_menu_popup (GTK_MENU (mts->autopick_menu), NULL, NULL, - e_meeting_time_selector_autopick_menu_position_callback, - mts, 1, GDK_CURRENT_TIME); -} - - -static void -e_meeting_time_selector_autopick_menu_position_callback (GtkMenu *menu, - gint *x, - gint *y, - gpointer user_data) -{ - EMeetingTimeSelector *mts; - GtkRequisition menu_requisition; - gint max_x, max_y; - - mts = E_MEETING_TIME_SELECTOR (user_data); - - /* Calculate our preferred position. */ - gdk_window_get_origin (mts->autopick_button->window, x, y); - *y += mts->autopick_button->allocation.height; - - /* Now make sure we are on the screen. */ - gtk_widget_size_request (mts->autopick_menu, &menu_requisition); - max_x = MAX (0, gdk_screen_width () - menu_requisition.width); - max_y = MAX (0, gdk_screen_height () - menu_requisition.height); - *x = CLAMP (*x, 0, max_x); - *y = CLAMP (*y, 0, max_y); -} - - -static void -e_meeting_time_selector_on_autopick_option_toggled (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - /* Make sure the menu pops down, which doesn't happen by default if - keyboard accelerators are used. */ - if (GTK_WIDGET_VISIBLE (mts->autopick_menu)) - gtk_menu_popdown (GTK_MENU (mts->autopick_menu)); -} - - -static void -e_meeting_time_selector_on_prev_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - e_meeting_time_selector_autopick (mts, FALSE); -} - - -static void -e_meeting_time_selector_on_next_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - e_meeting_time_selector_autopick (mts, TRUE); -} - - -/* This tries to find the previous or next meeting time for which all - attendees will be available. */ -static void -e_meeting_time_selector_autopick (EMeetingTimeSelector *mts, - gboolean forward) -{ - EMeetingTimeSelectorTime start_time, end_time, *resource_free; - EMeetingTimeSelectorAttendee *attendee; - EMeetingTimeSelectorPeriod *period; - EMeetingTimeSelectorAutopickOption autopick_option; - gint duration_days, duration_hours, duration_minutes, row; - gboolean meeting_time_ok, skip_optional = FALSE; - gboolean need_one_resource = FALSE, found_resource; - - /* Get the current meeting duration in days + hours + minutes. */ - e_meeting_time_selector_calculate_time_difference (&mts->meeting_start_time, &mts->meeting_end_time, &duration_days, &duration_hours, &duration_minutes); - - /* Find the first appropriate start time. */ - start_time = mts->meeting_start_time; - if (forward) - e_meeting_time_selector_find_nearest_interval (mts, &start_time, &end_time, duration_days, duration_hours, duration_minutes); - else - e_meeting_time_selector_find_nearest_interval_backward (mts, &start_time, &end_time, duration_days, duration_hours, duration_minutes); - - /* Determine if we can skip optional people and if we only need one - resource based on the autopick option. */ - autopick_option = e_meeting_time_selector_get_autopick_option (mts); - if (autopick_option == E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE - || autopick_option == E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE) - skip_optional = TRUE; - if (autopick_option == E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_ONE_RESOURCE - || autopick_option == E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE) - need_one_resource = TRUE; - - /* Keep moving forward or backward until we find a possible meeting - time. */ - for (;;) { - meeting_time_ok = TRUE; - found_resource = FALSE; - resource_free = NULL; - - /* Step through each attendee, checking if the meeting time - intersects one of the attendees busy periods. */ - for (row = 0; row < mts->attendees->len; row++) { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, - row); - - /* Skip optional people if they don't matter. */ - if (skip_optional && attendee->type == E_MEETING_TIME_SELECTOR_OPTIONAL_PERSON) - continue; - - period = e_meeting_time_selector_find_time_clash (mts, attendee, &start_time, &end_time); - - if (need_one_resource && attendee->type == E_MEETING_TIME_SELECTOR_RESOURCE) { - if (period) { - /* We want to remember the closest - prev/next time that one resource is - available, in case we don't find any - free resources. */ - if (forward) { - if (!resource_free || e_meeting_time_selector_compare_times (resource_free, &period->end) > 0) - resource_free = &period->end; - } else { - if (!resource_free || e_meeting_time_selector_compare_times (resource_free, &period->start) < 0) - resource_free = &period->start; - } - - } else { - found_resource = TRUE; - } - } else if (period) { - /* Skip the period which clashed. */ - if (forward) { - start_time = period->end; - } else { - start_time = period->start; - e_meeting_time_selector_adjust_time (&start_time, -duration_days, -duration_hours, -duration_minutes); - } - meeting_time_ok = FALSE; - break; - } - } - - /* Check that we found one resource if necessary. If not, skip - to the closest time that a resource is free. Note that if - there are no resources, resource_free will never get set, - so we assume the meeting time is OK. */ - if (meeting_time_ok && need_one_resource && !found_resource - && resource_free) { - if (forward) { - start_time = *resource_free; - } else { - start_time = *resource_free; - e_meeting_time_selector_adjust_time (&start_time, -duration_days, -duration_hours, -duration_minutes); - } - meeting_time_ok = FALSE; - } - - if (meeting_time_ok) { - mts->meeting_start_time = start_time; - mts->meeting_end_time = end_time; - mts->meeting_positions_valid = FALSE; - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - - /* Make sure the time is shown. */ - e_meeting_time_selector_ensure_meeting_time_shown (mts); - - /* Set the times in the GnomeDateEdit widgets. */ - e_meeting_time_selector_update_start_date_edit (mts); - e_meeting_time_selector_update_end_date_edit (mts); - return; - } - - /* Move forward to the next possible interval. */ - if (forward) - e_meeting_time_selector_find_nearest_interval (mts, &start_time, &end_time, duration_days, duration_hours, duration_minutes); - else - e_meeting_time_selector_find_nearest_interval_backward (mts, &start_time, &end_time, duration_days, duration_hours, duration_minutes); - } -} - - -static void -e_meeting_time_selector_calculate_time_difference (EMeetingTimeSelectorTime *start, - EMeetingTimeSelectorTime *end, - gint *days, - gint *hours, - gint *minutes) -{ - *days = g_date_julian (&end->date) - g_date_julian (&start->date); - *hours = end->hour - start->hour; - *minutes = end->minute - start->minute; - if (*minutes < 0) { - *minutes += 60; - *hours = *hours - 1; - } - if (*hours < 0) { - *hours += 24; - *days = *days - 1; - } -} - - -/* This moves the given time forward to the next suitable start of a meeting. - If zoomed_out is set, this means every hour. If not every half-hour. */ -static void -e_meeting_time_selector_find_nearest_interval (EMeetingTimeSelector *mts, - EMeetingTimeSelectorTime *start_time, - EMeetingTimeSelectorTime *end_time, - gint days, gint hours, gint mins) -{ - gint minutes_shown; - gboolean set_to_start_of_working_day = FALSE; - - if (mts->zoomed_out) { - start_time->hour++; - start_time->minute = 0; - } else { - start_time->minute += 30; - start_time->minute -= start_time->minute % 30; - } - e_meeting_time_selector_fix_time_overflows (start_time); - - *end_time = *start_time; - e_meeting_time_selector_adjust_time (end_time, days, hours, mins); - - /* Check if the interval is less than a day as seen in the display. - If it isn't we don't worry about the working day. */ - if (!mts->working_hours_only || days > 0) - return; - minutes_shown = (mts->day_end_hour - mts->day_start_hour) * 60; - minutes_shown += mts->day_end_minute - mts->day_start_minute; - if (hours * 60 + mins > minutes_shown) - return; - - /* If the meeting time finishes past the end of the working day, move - onto the start of the next working day. If the meeting time starts - before the working day, move it on as well. */ - if (start_time->hour > mts->day_end_hour - || (start_time->hour == mts->day_end_hour - && start_time->minute > mts->day_end_minute) - || end_time->hour > mts->day_end_hour - || (end_time->hour == mts->day_end_hour - && end_time->minute > mts->day_end_minute)) { - g_date_add_days (&start_time->date, 1); - set_to_start_of_working_day = TRUE; - } else if (start_time->hour < mts->day_start_hour - || (start_time->hour == mts->day_start_hour - && start_time->minute < mts->day_start_minute)) { - set_to_start_of_working_day = TRUE; - } - - if (set_to_start_of_working_day) { - start_time->hour = mts->day_start_hour; - start_time->minute = mts->day_start_minute; - - if (mts->zoomed_out) { - if (start_time->minute > 0) { - start_time->hour++; - start_time->minute = 0; - } - } else { - start_time->minute += 29; - start_time->minute -= start_time->minute % 30; - } - e_meeting_time_selector_fix_time_overflows (start_time); - - *end_time = *start_time; - e_meeting_time_selector_adjust_time (end_time, days, hours, mins); - } -} - - -/* This moves the given time backward to the next suitable start of a meeting. - If zoomed_out is set, this means every hour. If not every half-hour. */ -static void -e_meeting_time_selector_find_nearest_interval_backward (EMeetingTimeSelector *mts, - EMeetingTimeSelectorTime *start_time, - EMeetingTimeSelectorTime *end_time, - gint days, gint hours, gint mins) -{ - gint new_hour, minutes_shown; - gboolean set_to_end_of_working_day = FALSE; - - new_hour = start_time->hour; - if (mts->zoomed_out) { - if (start_time->minute == 0) - new_hour--; - start_time->minute = 0; - } else { - if (start_time->minute == 0) { - start_time->minute = 30; - new_hour--; - } else if (start_time->minute <= 30) - start_time->minute = 0; - else - start_time->minute = 30; - } - if (new_hour < 0) { - new_hour += 24; - g_date_subtract_days (&start_time->date, 1); - } - start_time->hour = new_hour; - - *end_time = *start_time; - e_meeting_time_selector_adjust_time (end_time, days, hours, mins); - - /* Check if the interval is less than a day as seen in the display. - If it isn't we don't worry about the working day. */ - if (!mts->working_hours_only || days > 0) - return; - minutes_shown = (mts->day_end_hour - mts->day_start_hour) * 60; - minutes_shown += mts->day_end_minute - mts->day_start_minute; - if (hours * 60 + mins > minutes_shown) - return; - - /* If the meeting time finishes past the end of the working day, move - back to the end of the working day. If the meeting time starts - before the working day, move it back to the end of the previous - working day. */ - if (start_time->hour > mts->day_end_hour - || (start_time->hour == mts->day_end_hour - && start_time->minute > mts->day_end_minute) - || end_time->hour > mts->day_end_hour - || (end_time->hour == mts->day_end_hour - && end_time->minute > mts->day_end_minute)) { - set_to_end_of_working_day = TRUE; - } else if (start_time->hour < mts->day_start_hour - || (start_time->hour == mts->day_start_hour - && start_time->minute < mts->day_start_minute)) { - g_date_subtract_days (&end_time->date, 1); - set_to_end_of_working_day = TRUE; - } - - if (set_to_end_of_working_day) { - end_time->hour = mts->day_end_hour; - end_time->minute = mts->day_end_minute; - *start_time = *end_time; - e_meeting_time_selector_adjust_time (start_time, -days, -hours, -mins); - - if (mts->zoomed_out) { - start_time->minute = 0; - } else { - start_time->minute -= start_time->minute % 30; - } - - *end_time = *start_time; - e_meeting_time_selector_adjust_time (end_time, days, hours, mins); - } -} - - -/* This adds on the given days, hours & minutes to a EMeetingTimeSelectorTime. - It is used to calculate the end of a period given a start & duration. - Days, hours & minutes can be negative, to move backwards, but they should - be within normal ranges, e.g. hours should be between -23 and 23. */ -static void -e_meeting_time_selector_adjust_time (EMeetingTimeSelectorTime *mtstime, - gint days, gint hours, gint minutes) -{ - gint new_hours, new_minutes; - - /* We have to handle negative values for hous and minutes here, since - EMeetingTimeSelectorTime uses guint8s to store them. */ - new_minutes = mtstime->minute + minutes; - if (new_minutes < 0) { - new_minutes += 60; - hours -= 1; - } - - new_hours = mtstime->hour + hours; - if (new_hours < 0) { - new_hours += 24; - days -= 1; - } - - g_date_add_days (&mtstime->date, days); - mtstime->hour = new_hours; - mtstime->minute = new_minutes; - - e_meeting_time_selector_fix_time_overflows (mtstime); -} - - -/* This looks for any busy period of the given attendee which clashes with - the start and end time. It uses a binary search. */ -static EMeetingTimeSelectorPeriod* -e_meeting_time_selector_find_time_clash (EMeetingTimeSelector *mts, - EMeetingTimeSelectorAttendee *attendee, - EMeetingTimeSelectorTime *start_time, - EMeetingTimeSelectorTime *end_time) -{ - EMeetingTimeSelectorPeriod *period; - gint period_num; - - period_num = e_meeting_time_selector_find_first_busy_period (mts, attendee, &start_time->date); - - if (period_num == -1) - return NULL; - - /* Step forward through the busy periods until we find a clash or we - go past the end_time. */ - while (period_num < attendee->busy_periods->len) { - period = &g_array_index (attendee->busy_periods, - EMeetingTimeSelectorPeriod, - period_num); - - /* If the period starts at or after the end time, there is no - clash and we are finished. The busy periods are sorted by - their start times, so all the rest will be later. */ - if (e_meeting_time_selector_compare_times (&period->start, - end_time) >= 0) - return NULL; - - /* If the period ends after the start time, we have found a - clash. From the above test we already know the busy period - isn't completely after the meeting time. */ - if (e_meeting_time_selector_compare_times (&period->end, - start_time) > 0) { - return period; - } - - period_num++; - } - - return NULL; -} - - -/* This subtracts the attendees longest_period_in_days from the given date, - and does a binary search of the attendee's busy periods array to find the - first one which could possible end on the given day or later. - If none are found it returns -1. */ -gint -e_meeting_time_selector_find_first_busy_period (EMeetingTimeSelector *mts, - EMeetingTimeSelectorAttendee *attendee, - GDate *date) -{ - EMeetingTimeSelectorPeriod *period; - gint lower, upper, middle = 0, cmp = 0; - GDate tmp_date; - - /* Make sure the busy periods have been sorted. */ - e_meeting_time_selector_attendee_ensure_periods_sorted (mts, attendee); - - /* Calculate the first day which could have a busy period which - continues onto our given date. */ - tmp_date = *date; - g_date_subtract_days (&tmp_date, attendee->longest_period_in_days); - - /* We want the first busy period which starts on tmp_date. */ - lower = 0; - upper = attendee->busy_periods->len; - - if (upper == 0) - return -1; - - while (lower < upper) { - middle = (lower + upper) >> 1; - - period = &g_array_index (attendee->busy_periods, - EMeetingTimeSelectorPeriod, middle); - - cmp = g_date_compare (&tmp_date, &period->start.date); - - if (cmp == 0) - break; - else if (cmp < 0) - upper = middle; - else - lower = middle + 1; - } - - /* There may be several busy periods on the same day so we step - backwards to the first one. */ - if (cmp == 0) { - while (middle > 0) { - period = &g_array_index (attendee->busy_periods, - EMeetingTimeSelectorPeriod, middle - 1); - if (g_date_compare (&tmp_date, &period->start.date) != 0) - break; - middle--; - } - } else if (cmp > 0) { - /* This means we couldn't find a period on the given day, and - the last one we looked at was before it, so if there are - any more periods after this one we return it. */ - middle++; - if (attendee->busy_periods->len <= middle) - return -1; - } - - return middle; -} - - -static void -e_meeting_time_selector_on_zoomed_out_toggled (GtkWidget *menuitem, - EMeetingTimeSelector *mts) -{ - /* Make sure the menu pops down, which doesn't happen by default if - keyboard accelerators are used. */ - if (GTK_WIDGET_VISIBLE (mts->options_menu)) - gtk_menu_popdown (GTK_MENU (mts->options_menu)); - - e_meeting_time_selector_set_zoomed_out (mts, GTK_CHECK_MENU_ITEM (menuitem)->active); -} - - -static void -e_meeting_time_selector_on_working_hours_toggled (GtkWidget *menuitem, - EMeetingTimeSelector *mts) -{ - /* Make sure the menu pops down, which doesn't happen by default if - keyboard accelerators are used. */ - if (GTK_WIDGET_VISIBLE (mts->options_menu)) - gtk_menu_popdown (GTK_MENU (mts->options_menu)); - - e_meeting_time_selector_set_working_hours_only (mts, GTK_CHECK_MENU_ITEM (menuitem)->active); -} - - -/* This recalculates day_width, first_hour_shown and last_hour_shown. */ -static void -e_meeting_time_selector_recalc_grid (EMeetingTimeSelector *mts) -{ - if (mts->working_hours_only) { - mts->first_hour_shown = mts->day_start_hour; - mts->last_hour_shown = mts->day_end_hour; - if (mts->day_end_minute != 0) - mts->last_hour_shown += 1; - } else { - mts->first_hour_shown = 0; - mts->last_hour_shown = 24; - } - - /* In the brief view we use the nearest hours divisible by 3. */ - if (mts->zoomed_out) { - mts->first_hour_shown -= mts->first_hour_shown % 3; - mts->last_hour_shown += 2; - mts->last_hour_shown -= mts->last_hour_shown % 3; - } - - mts->day_width = mts->col_width * (mts->last_hour_shown - mts->first_hour_shown); - if (mts->zoomed_out) - mts->day_width /= 3; - - /* Add one pixel for the extra vertical grid line. */ - mts->day_width++; - - gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->display_top), - 0, 0, - mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN, - mts->row_height * 3); - e_meeting_time_selector_update_main_canvas_scroll_region (mts); - - e_meeting_time_selector_recalc_date_format (mts); - mts->meeting_positions_valid = FALSE; -} - - -/* This saves the first visible time in the given EMeetingTimeSelectorTime. */ -static void -e_meeting_time_selector_save_position (EMeetingTimeSelector *mts, - EMeetingTimeSelectorTime *mtstime) -{ - gint scroll_x, scroll_y; - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main), - &scroll_x, &scroll_y); - e_meeting_time_selector_calculate_time (mts, scroll_x, mtstime); -} - - -/* This restores a saved position. */ -static void -e_meeting_time_selector_restore_position (EMeetingTimeSelector *mts, - EMeetingTimeSelectorTime *mtstime) -{ - gint scroll_x, scroll_y, new_scroll_x; - - new_scroll_x = e_meeting_time_selector_calculate_time_position (mts, - mtstime); - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main), - &scroll_x, &scroll_y); - gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_main), - new_scroll_x, scroll_y); -} - - -/* This returns the x pixel coords of the meeting time in the entire scroll - region. It recalculates them if they have been marked as invalid. - If it returns FALSE then no meeting time is set or the meeting time is - not visible in the current scroll area. */ -gboolean -e_meeting_time_selector_get_meeting_time_positions (EMeetingTimeSelector *mts, - gint *start_x, - gint *end_x) -{ - if (mts->meeting_positions_valid) { - if (mts->meeting_positions_in_scroll_area) { - *start_x = mts->meeting_start_x; - *end_x = mts->meeting_end_x; - return TRUE; - } else { - return FALSE; - } - } - - mts->meeting_positions_valid = TRUE; - - /* Check if the days aren't in our current range. */ - if (g_date_compare (&mts->meeting_start_time.date, &mts->last_date_shown) > 0 - || g_date_compare (&mts->meeting_end_time.date, &mts->first_date_shown) < 0) { - mts->meeting_positions_in_scroll_area = FALSE; - return FALSE; - } - - mts->meeting_positions_in_scroll_area = TRUE; - *start_x = mts->meeting_start_x = e_meeting_time_selector_calculate_time_position (mts, &mts->meeting_start_time); - *end_x = mts->meeting_end_x = e_meeting_time_selector_calculate_time_position (mts, &mts->meeting_end_time); - - return TRUE; -} - - -/* This recalculates the date format to used, by computing the width of the - longest date strings in the widget's font and seeing if they fit. */ -static void -e_meeting_time_selector_recalc_date_format (EMeetingTimeSelector *mts) -{ - /* An array of dates, one for each month in the year 2000. They must - all be Sundays. */ - static const int days[12] = { 23, 20, 19, 23, 21, 18, - 23, 20, 17, 22, 19, 24 }; - GDate date; - gint max_date_width, longest_weekday_width, longest_month_width, width; - gint day, longest_weekday, month, longest_month; - gchar buffer[128]; - GdkFont *font; - - font = GTK_WIDGET (mts)->style->font; - - /* Calculate the maximum date width we can fit into the display. */ - max_date_width = mts->day_width - 2; - - /* Find the biggest full weekday name. We start on a particular - Monday and go through seven days. */ - g_date_clear (&date, 1); - g_date_set_dmy (&date, 3, 1, 2000); /* Monday 3rd Jan 2000. */ - longest_weekday_width = 0; - longest_weekday = G_DATE_MONDAY; - for (day = G_DATE_MONDAY; day <= G_DATE_SUNDAY; day++) { - g_date_strftime (buffer, sizeof (buffer), "%A", &date); - width = gdk_string_width (font, buffer); - if (width > longest_weekday_width) { - longest_weekday = day; - longest_weekday_width = width; - } - g_date_add_days (&date, 1); - } - - /* Now find the biggest month name. */ - longest_month_width = 0; - longest_month = G_DATE_JANUARY; - for (month = G_DATE_JANUARY; month <= G_DATE_DECEMBER; month++) { - g_date_set_month (&date, month); - g_date_strftime (buffer, sizeof (buffer), "%B", &date); - width = gdk_string_width (font, buffer); - if (width > longest_month_width) { - longest_month = month; - longest_month_width = width; - } - } - - /* See if we can use the full date. We want to use a date with a - month day > 20 and also the longest weekday. We use a - pre-calculated array of days for each month and add on the - weekday (which is 1 (Mon) to 7 (Sun). */ - g_date_set_dmy (&date, days[longest_month - 1] + longest_weekday, - longest_month, 2000); - /* This is a strftime() format string %A = full weekday name, - %B = full month name, %d = month day, %Y = full year. */ - g_date_strftime (buffer, sizeof (buffer), _("%A, %B %d, %Y"), &date); - - g_print ("longest_month: %i longest_weekday: %i date: %s\n", - longest_month, longest_weekday, buffer); - - if (gdk_string_width (font, buffer) < max_date_width) { - mts->date_format = E_MEETING_TIME_SELECTOR_DATE_FULL; - return; - } - - /* Now try it with abbreviated weekday names. */ - longest_weekday_width = 0; - longest_weekday = G_DATE_MONDAY; - g_date_set_dmy (&date, 3, 1, 2000); /* Monday 3rd Jan 2000. */ - for (day = G_DATE_MONDAY; day <= G_DATE_SUNDAY; day++) { - g_date_strftime (buffer, sizeof (buffer), "%a", &date); - width = gdk_string_width (font, buffer); - if (width > longest_weekday_width) { - longest_weekday = day; - longest_weekday_width = width; - } - g_date_add_days (&date, 1); - } - - g_date_set_dmy (&date, days[longest_month - 1] + longest_weekday, - longest_month, 2000); - /* This is a strftime() format string %a = abbreviated weekday name, - %m = month number, %d = month day, %Y = full year. */ - g_date_strftime (buffer, sizeof (buffer), _("%a %m/%d/%Y"), &date); - - g_print ("longest_month: %i longest_weekday: %i date: %s\n", - longest_month, longest_weekday, buffer); - - if (gdk_string_width (font, buffer) < max_date_width) - mts->date_format = E_MEETING_TIME_SELECTOR_DATE_ABBREVIATED_DAY; - else - mts->date_format = E_MEETING_TIME_SELECTOR_DATE_SHORT; -} - - -/* Turn off the background of the canvas windows. This reduces flicker - considerably when scrolling. (Why isn't it in GnomeCanvas?). */ -static void -e_meeting_time_selector_on_canvas_realized (GtkWidget *widget, - EMeetingTimeSelector *mts) -{ - gdk_window_set_back_pixmap (GTK_LAYOUT (widget)->bin_window, - NULL, FALSE); -} - - -/* This is called when the meeting start time GnomeDateEdit is changed, - either via the "date_changed". "time_changed" or "activate" signals on one - of the GtkEntry widgets. So don't use the widget parameter since it may be - one of the child GtkEntry widgets. */ -static void -e_meeting_time_selector_on_start_time_changed (GtkWidget *widget, - EMeetingTimeSelector *mts) -{ - gint duration_days, duration_hours, duration_minutes; - EMeetingTimeSelectorTime mtstime; - time_t newtime; - struct tm *newtime_tm; - - newtime = gnome_date_edit_get_date (GNOME_DATE_EDIT (mts->start_date_edit)); - newtime_tm = localtime (&newtime); - g_date_clear (&mtstime.date, 1); - g_date_set_time (&mtstime.date, newtime); - mtstime.hour = newtime_tm->tm_hour; - mtstime.minute = newtime_tm->tm_min; - - /* If the time hasn't changed, just return. */ - if (e_meeting_time_selector_compare_times (&mtstime, &mts->meeting_start_time) == 0) - return; - - /* Calculate the current meeting duration. */ - e_meeting_time_selector_calculate_time_difference (&mts->meeting_start_time, &mts->meeting_end_time, &duration_days, &duration_hours, &duration_minutes); - - /* Set the new start time. */ - mts->meeting_start_time = mtstime; - - /* Update the end time so the meeting duration stays the same. */ - mts->meeting_end_time = mts->meeting_start_time; - e_meeting_time_selector_adjust_time (&mts->meeting_end_time, duration_days, duration_hours, duration_minutes); - e_meeting_time_selector_update_end_date_edit (mts); - - mts->meeting_positions_valid = FALSE; - e_meeting_time_selector_ensure_meeting_time_shown (mts); - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); -} - - -/* This is called when the meeting end time GnomeDateEdit is changed, - either via the "date_changed", "time_changed" or "activate" signals on one - of the GtkEntry widgets. So don't use the widget parameter since it may be - one of the child GtkEntry widgets. */ -static void -e_meeting_time_selector_on_end_time_changed (GtkWidget *widget, - EMeetingTimeSelector *mts) -{ - EMeetingTimeSelectorTime mtstime; - time_t newtime; - struct tm *newtime_tm; - - newtime = gnome_date_edit_get_date (GNOME_DATE_EDIT (mts->end_date_edit)); - newtime_tm = localtime (&newtime); - g_date_clear (&mtstime.date, 1); - g_date_set_time (&mtstime.date, newtime); - mtstime.hour = newtime_tm->tm_hour; - mtstime.minute = newtime_tm->tm_min; - - /* If the time hasn't changed, just return. */ - if (e_meeting_time_selector_compare_times (&mtstime, &mts->meeting_end_time) == 0) - return; - - /* Set the new end time. */ - mts->meeting_end_time = mtstime; - - /* If the start time is after the end time, set it to the same time. */ - if (e_meeting_time_selector_compare_times (&mtstime, &mts->meeting_start_time) < 0) { - /* We set it first, before updating the widget, so the signal - handler will just return. */ - mts->meeting_start_time = mtstime; - e_meeting_time_selector_update_start_date_edit (mts); - } - - mts->meeting_positions_valid = FALSE; - e_meeting_time_selector_ensure_meeting_time_shown (mts); - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); -} - - -/* This updates the ranges shown in the GnomeDateEdit popup menus, according - to working_hours_only etc. */ -static void -e_meeting_time_selector_update_date_popup_menus (EMeetingTimeSelector *mts) -{ - GnomeDateEdit *start_edit, *end_edit; - gint low_hour, high_hour; - - start_edit = GNOME_DATE_EDIT (mts->start_date_edit); - end_edit = GNOME_DATE_EDIT (mts->end_date_edit); - - if (mts->working_hours_only) { - low_hour = mts->day_start_hour; - high_hour = mts->day_end_hour; - } else { - low_hour = 0; - high_hour = 23; - } - - gnome_date_edit_set_popup_range (start_edit, low_hour, high_hour); - gnome_date_edit_set_popup_range (end_edit, low_hour, high_hour); -} - - -static void -e_meeting_time_selector_on_canvas_size_allocate (GtkWidget *widget, - GtkAllocation *allocation, - EMeetingTimeSelector *mts) -{ - e_meeting_time_selector_update_main_canvas_scroll_region (mts); - - e_meeting_time_selector_ensure_meeting_time_shown (mts); -} - - -static void -e_meeting_time_selector_on_attendees_list_size_allocate (GtkWidget *widget, - GtkAllocation *allocation, - EMeetingTimeSelector *mts) -{ - e_meeting_time_selector_update_attendees_list_scroll_region (mts); - e_meeting_time_selector_update_attendees_list_positions (mts); -} - - -/* This updates the list canvas scroll region according to the number of - attendees. If the total height needed is less than the height of the canvas, - we must use the height of the canvas, or it causes problems. */ -static void -e_meeting_time_selector_update_attendees_list_scroll_region (EMeetingTimeSelector *mts) -{ - gint height, canvas_width, canvas_height; - - height = mts->row_height * mts->attendees->len; - canvas_width = GTK_WIDGET (mts->attendees_list)->allocation.width; - canvas_height = GTK_WIDGET (mts->attendees_list)->allocation.height; - - height = MAX (height, canvas_height); - - gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->attendees_list), - 0, 0, - canvas_width, - height); -} - - -/* This updates the canvas scroll regions according to the number of attendees. - If the total height needed is less than the height of the canvas, we must - use the height of the canvas, or it causes problems. */ -static void -e_meeting_time_selector_update_main_canvas_scroll_region (EMeetingTimeSelector *mts) -{ - gint height, canvas_height, list_width; - - height = mts->row_height * (mts->attendees->len + 1); - canvas_height = GTK_WIDGET (mts->display_main)->allocation.height; - list_width = GTK_WIDGET (mts->attendees_list)->allocation.width; - - height = MAX (height, canvas_height); - - gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->attendees_list), - 0, 0, - list_width, - height); - gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->display_main), - 0, 0, - mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN, - height); -} - - -/* This changes the meeting time based on the given x coordinate and whether - we are dragging the start or end bar. It returns the new position, which - will be swapped if the start bar is dragged past the end bar or vice versa. - It make sure the meeting time is never dragged outside the visible canvas - area. */ -void -e_meeting_time_selector_drag_meeting_time (EMeetingTimeSelector *mts, - gint x) -{ - EMeetingTimeSelectorTime first_time, last_time, drag_time, *time_to_set; - gint scroll_x, scroll_y, canvas_width; - gboolean set_both_times = FALSE; - - /* Get the x coords of visible part of the canvas. */ - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main), - &scroll_x, &scroll_y); - canvas_width = mts->display_main->allocation.width; - - /* Save the x coordinate for the timeout handler. */ - mts->last_drag_x = (x < scroll_x) ? x - scroll_x - : x - scroll_x - canvas_width + 1; - - /* Check if the mouse is off the edge of the canvas. */ - if (x < scroll_x || x > scroll_x + canvas_width) { - /* If we haven't added a timeout function, add one. */ - if (mts->auto_scroll_timeout_id == 0) { - mts->auto_scroll_timeout_id = g_timeout_add (60, e_meeting_time_selector_timeout_handler, mts); - mts->scroll_count = 0; - - /* Call the handler to start scrolling now. */ - e_meeting_time_selector_timeout_handler (mts); - return; - } - } else { - e_meeting_time_selector_remove_timeout (mts); - } - - /* Calculate the minimum & maximum times we can use, based on the - scroll offsets and whether zoomed_out is set. */ - e_meeting_time_selector_calculate_time (mts, scroll_x, &first_time); - e_meeting_time_selector_calculate_time (mts, scroll_x + canvas_width - 1, - &last_time); - if (mts->zoomed_out) { - if (first_time.minute > 30) - first_time.hour++; - first_time.minute = 0; - last_time.minute = 0; - } else { - first_time.minute += 15; - first_time.minute -= first_time.minute % 30; - last_time.minute -= last_time.minute % 30; - } - e_meeting_time_selector_fix_time_overflows (&first_time); - e_meeting_time_selector_fix_time_overflows (&last_time); - - /* Calculate the time from x coordinate. */ - e_meeting_time_selector_calculate_time (mts, x, &drag_time); - - /* Calculate the nearest half-hour or hour, depending on whether - zoomed_out is set. */ - if (mts->zoomed_out) { - if (drag_time.minute > 30) - drag_time.hour++; - drag_time.minute = 0; - } else { - drag_time.minute += 15; - drag_time.minute -= drag_time.minute % 30; - } - e_meeting_time_selector_fix_time_overflows (&drag_time); - - /* Now make sure we are between first_time & last_time. */ - if (e_meeting_time_selector_compare_times (&drag_time, &first_time) < 0) - drag_time = first_time; - if (e_meeting_time_selector_compare_times (&drag_time, &last_time) > 0) - drag_time = last_time; - - /* Set the meeting start or end time to drag_time. */ - if (mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - time_to_set = &mts->meeting_start_time; - else - time_to_set = &mts->meeting_end_time; - - /* If the time is unchanged, just return. */ - if (e_meeting_time_selector_compare_times (time_to_set, &drag_time) == 0) - return; - - *time_to_set = drag_time; - - /* Check if the start time and end time need to be switched. */ - if (e_meeting_time_selector_compare_times (&mts->meeting_start_time, - &mts->meeting_end_time) > 0) { - drag_time = mts->meeting_start_time; - mts->meeting_start_time = mts->meeting_end_time; - mts->meeting_end_time = drag_time; - - if (mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_END; - else - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_START; - - set_both_times = TRUE; - } - - /* Mark the calculated positions as invalid. */ - mts->meeting_positions_valid = FALSE; - - /* Redraw the canvases. */ - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - - /* Set the times in the GnomeDateEdit widgets. */ - if (set_both_times - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - e_meeting_time_selector_update_start_date_edit (mts); - - if (set_both_times - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END) - e_meeting_time_selector_update_end_date_edit (mts); -} - - -/* This is the timeout function which handles auto-scrolling when the user is - dragging one of the meeting time vertical bars outside the left or right - edge of the canvas. */ -static gboolean -e_meeting_time_selector_timeout_handler (gpointer data) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorTime drag_time, *time_to_set; - gint scroll_x, max_scroll_x, scroll_y, canvas_width; - gint scroll_speed, scroll_offset; - gboolean set_both_times = FALSE; - - mts = E_MEETING_TIME_SELECTOR (data); - - GDK_THREADS_ENTER (); - - /* Return if we don't need to scroll yet. */ - if (mts->scroll_count-- > 0) { - GDK_THREADS_LEAVE (); - return TRUE; - } - - /* Get the x coords of visible part of the canvas. */ - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main), - &scroll_x, &scroll_y); - canvas_width = mts->display_main->allocation.width; - - /* Calculate the scroll delay, between 0 and MAX_SCROLL_SPEED. */ - scroll_speed = abs (mts->last_drag_x / E_MEETING_TIME_SELECTOR_SCROLL_INCREMENT_WIDTH); - scroll_speed = MIN (scroll_speed, - E_MEETING_TIME_SELECTOR_MAX_SCROLL_SPEED); - - /* Reset the scroll count. */ - mts->scroll_count = E_MEETING_TIME_SELECTOR_MAX_SCROLL_SPEED - scroll_speed; - - /* Calculate how much we need to scroll. */ - if (mts->last_drag_x >= 0) - scroll_offset = mts->col_width; - else - scroll_offset = -mts->col_width; - - scroll_x += scroll_offset; - max_scroll_x = (mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN) - - canvas_width; - scroll_x = CLAMP (scroll_x, 0, max_scroll_x); - - /* Calculate the minimum or maximum visible time in the canvas, which - we will now set the dragged time to. */ - if (scroll_offset > 0) { - e_meeting_time_selector_calculate_time (mts, - scroll_x + canvas_width - 1, - &drag_time); - if (mts->zoomed_out) { - drag_time.minute = 0; - } else { - drag_time.minute -= drag_time.minute % 30; - } - } else { - e_meeting_time_selector_calculate_time (mts, scroll_x, - &drag_time); - if (mts->zoomed_out) { - if (drag_time.minute > 30) - drag_time.hour++; - drag_time.minute = 0; - } else { - drag_time.minute += 15; - drag_time.minute -= drag_time.minute % 30; - } - } - e_meeting_time_selector_fix_time_overflows (&drag_time); - - /* Set the meeting start or end time to drag_time. */ - if (mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - time_to_set = &mts->meeting_start_time; - else - time_to_set = &mts->meeting_end_time; - - /* If the time is unchanged, just return. */ - if (e_meeting_time_selector_compare_times (time_to_set, &drag_time) == 0) { - GDK_THREADS_LEAVE (); - return TRUE; - } - - *time_to_set = drag_time; - - /* Check if the start time and end time need to be switched. */ - if (e_meeting_time_selector_compare_times (&mts->meeting_start_time, &mts->meeting_end_time) > 0) { - drag_time = mts->meeting_start_time; - mts->meeting_start_time = mts->meeting_end_time; - mts->meeting_end_time = drag_time; - - if (mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_END; - else - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_START; - - set_both_times = TRUE; - } - - /* Mark the calculated positions as invalid. */ - mts->meeting_positions_valid = FALSE; - - /* Set the times in the GnomeDateEdit widgets. */ - if (set_both_times - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - e_meeting_time_selector_update_start_date_edit (mts); - - if (set_both_times - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END) - e_meeting_time_selector_update_end_date_edit (mts); - - /* Redraw the canvases. We freeze and thaw the layouts so that they - get redrawn completely. Otherwise the pixels get scrolled left or - right which is not good for us (since our vertical bars have been - moved) and causes flicker. */ - gtk_layout_freeze (GTK_LAYOUT (mts->display_main)); - gtk_layout_freeze (GTK_LAYOUT (mts->display_top)); - gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_main), - scroll_x, scroll_y); - gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_top), - scroll_x, scroll_y); - gtk_layout_thaw (GTK_LAYOUT (mts->display_main)); - gtk_layout_thaw (GTK_LAYOUT (mts->display_top)); - - GDK_THREADS_LEAVE (); - return TRUE; -} - - -/* This removes our auto-scroll timeout function, if we have one installed. */ -void -e_meeting_time_selector_remove_timeout (EMeetingTimeSelector *mts) -{ - if (mts->auto_scroll_timeout_id) { - g_source_remove (mts->auto_scroll_timeout_id); - mts->auto_scroll_timeout_id = 0; - } -} - - -/* This updates the GnomeDateEdit widget displaying the meeting start time. */ -static void -e_meeting_time_selector_update_start_date_edit (EMeetingTimeSelector *mts) -{ - struct tm start_tm; - time_t start_time_t; - - g_date_to_struct_tm (&mts->meeting_start_time.date, &start_tm); - start_tm.tm_hour = mts->meeting_start_time.hour; - start_tm.tm_min = mts->meeting_start_time.minute; - start_time_t = mktime (&start_tm); - gnome_date_edit_set_time (GNOME_DATE_EDIT (mts->start_date_edit), - start_time_t); -} - - -/* This updates the GnomeDateEdit widget displaying the meeting end time. */ -static void -e_meeting_time_selector_update_end_date_edit (EMeetingTimeSelector *mts) -{ - struct tm end_tm; - time_t end_time_t; - - g_date_to_struct_tm (&mts->meeting_end_time.date, &end_tm); - end_tm.tm_hour = mts->meeting_end_time.hour; - end_tm.tm_min = mts->meeting_end_time.minute; - end_time_t = mktime (&end_tm); - gnome_date_edit_set_time (GNOME_DATE_EDIT (mts->end_date_edit), - end_time_t); -} - - -/* This ensures that the meeting time is shown on screen, by scrolling the - canvas and possibly by changing the range of dates shown in the canvas. */ -static void -e_meeting_time_selector_ensure_meeting_time_shown (EMeetingTimeSelector *mts) -{ - gint start_x, end_x, scroll_x, scroll_y, canvas_width; - gint new_scroll_x; - gboolean fits_in_canvas; - - /* Check if we need to change the range of dates shown. */ - if (g_date_compare (&mts->meeting_start_time.date, - &mts->first_date_shown) < 0 - || g_date_compare (&mts->meeting_end_time.date, - &mts->last_date_shown) > 0) { - e_meeting_time_selector_update_dates_shown (mts); - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - } - - /* If all of the meeting time is visible, just return. */ - e_meeting_time_selector_get_meeting_time_positions (mts, &start_x, - &end_x); - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main), - &scroll_x, &scroll_y); - canvas_width = mts->display_main->allocation.width; - if (start_x > scroll_x && end_x <= scroll_x + canvas_width) - return; - - fits_in_canvas = end_x - start_x < canvas_width ? TRUE : FALSE; - - /* If the meeting is not entirely visible, either center it if it is - smaller than the canvas, or show the start of it if it is big. */ - if (fits_in_canvas) { - new_scroll_x = (start_x + end_x - canvas_width) / 2; - } else { - new_scroll_x = start_x; - } - gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_main), - new_scroll_x, scroll_y); -} - - -/* This updates the range of dates shown in the canvas, to make sure that the - currently selected meeting time is in the range. */ -static void -e_meeting_time_selector_update_dates_shown (EMeetingTimeSelector *mts) -{ - mts->first_date_shown = mts->meeting_start_time.date; - g_date_subtract_days (&mts->first_date_shown, 60); - - mts->last_date_shown = mts->first_date_shown; - g_date_add_days (&mts->last_date_shown, E_MEETING_TIME_SELECTOR_DAYS_SHOWN - 1); -} - - -/* This checks if the time's hour is over 24 or its minute is over 60 and if - so it updates the day/hour appropriately. Note that hours and minutes are - stored in guint8's so they can't overflow by much. */ -void -e_meeting_time_selector_fix_time_overflows (EMeetingTimeSelectorTime *mtstime) -{ - gint hours_to_add, days_to_add; - - hours_to_add = mtstime->minute / 60; - if (hours_to_add > 0) { - mtstime->minute -= hours_to_add * 60; - mtstime->hour += hours_to_add; - } - - days_to_add = mtstime->hour / 24; - if (days_to_add > 0) { - mtstime->hour -= days_to_add * 24; - g_date_add_days (&mtstime->date, days_to_add); - } -} - - -static void -e_meeting_time_selector_update_attendees_list_positions (EMeetingTimeSelector *mts) -{ - EMeetingTimeSelectorAttendee *attendee; - gint list_width, item_width; - gint row; - GdkFont *font; - - list_width = GTK_WIDGET (mts->attendees_list)->allocation.width; - item_width = MAX (1, list_width - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH - E_MEETING_TIME_SELECTOR_TEXT_X_PAD * 2); - font = GTK_WIDGET (mts)->style->font; - for (row = 0; row < mts->attendees->len; row++) { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - - gnome_canvas_item_set - (attendee->text_item, - "font_gdk", font, - "clip_width", (gdouble) item_width, - "clip_height", (gdouble) (font->ascent - + font->descent), - NULL); - - e_canvas_item_move_absolute (attendee->text_item, - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH - + E_MEETING_TIME_SELECTOR_TEXT_X_PAD, - row * mts->row_height + 1 + E_MEETING_TIME_SELECTOR_TEXT_Y_PAD); - - gnome_canvas_item_show (attendee->text_item); - } -} - - -/* - * CONVERSION ROUTINES - functions to convert between different coordinate - * spaces and dates. - */ - -/* This takes an x pixel coordinate within the entire canvas scroll region and - returns the date in which it falls. If day_position is not NULL it also - returns the x coordinate within the date, relative to the visible part of - the canvas. It is used when painting the days in the item_draw function. - Note that it must handle negative x coordinates in case we are dragging off - the edge of the canvas. */ -void -e_meeting_time_selector_calculate_day_and_position (EMeetingTimeSelector *mts, - gint x, - GDate *date, - gint *day_position) -{ - gint days_from_first_shown; - - *date = mts->first_date_shown; - - if (x >= 0) { - days_from_first_shown = x / mts->day_width; - g_date_add_days (date, days_from_first_shown); - if (day_position) - *day_position = - x % mts->day_width; - } else { - days_from_first_shown = -x / mts->day_width + 1; - g_date_subtract_days (date, days_from_first_shown); - if (day_position) - *day_position = -mts->day_width - x % mts->day_width; - } -} - - -/* This takes an x pixel coordinate within a day, and converts it to hours - and minutes, depending on working_hours_only and zoomed_out. */ -void -e_meeting_time_selector_convert_day_position_to_hours_and_mins (EMeetingTimeSelector *mts, gint day_position, guint8 *hours, guint8 *minutes) -{ - if (mts->zoomed_out) - day_position *= 3; - - /* Calculate the hours & minutes from the first displayed. */ - *hours = day_position / mts->col_width; - *minutes = (day_position % mts->col_width) * 60 / mts->col_width; - - /* Now add on the first hour shown. */ - *hours += mts->first_hour_shown; -} - - -/* This takes an x pixel coordinate within the entire canvas scroll region and - returns the time in which it falls. Note that it won't be extremely - accurate since hours may only be a few pixels wide in the display. - With zoomed_out set each pixel may represent 5 minutes or more, depending - on how small the font is. */ -void -e_meeting_time_selector_calculate_time (EMeetingTimeSelector *mts, - gint x, - EMeetingTimeSelectorTime *time) -{ - gint day_position; - - /* First get the day and the x position within the day. */ - e_meeting_time_selector_calculate_day_and_position (mts, x, &time->date, - NULL); - - /* Now convert the day_position into an hour and minute. */ - if (x >= 0) - day_position = x % mts->day_width; - else - day_position = mts->day_width + x % mts->day_width; - - e_meeting_time_selector_convert_day_position_to_hours_and_mins (mts, day_position, &time->hour, &time->minute); -} - - -/* This takes a EMeetingTimeSelectorTime and calculates the x pixel coordinate - within the entire canvas scroll region. It is used to draw the selected - meeting time and all the busy periods. */ -gint -e_meeting_time_selector_calculate_time_position (EMeetingTimeSelector *mts, - EMeetingTimeSelectorTime *mtstime) -{ - gint x, date_offset, day_offset; - - /* Calculate the number of days since the first date shown in the - entire canvas scroll region. */ - date_offset = g_date_julian (&mtstime->date) - g_date_julian (&mts->first_date_shown); - - /* Calculate the x pixel coordinate of the start of the day. */ - x = date_offset * mts->day_width; - - /* Add on the hours and minutes, depending on whether zoomed_out and - working_hours_only are set. */ - day_offset = (mtstime->hour - mts->first_hour_shown) * 60 - + mtstime->minute; - /* The day width includes an extra vertical grid line so subtract 1. */ - day_offset *= (mts->day_width - 1); - day_offset /= (mts->last_hour_shown - mts->first_hour_shown) * 60; - - /* Clamp the day_offset in case the time isn't actually visible. */ - x += CLAMP (day_offset, 0, mts->day_width); - - return x; -} - - -static gboolean -e_meeting_time_selector_on_text_item_event (GnomeCanvasItem *item, - GdkEvent *event, - EMeetingTimeSelector *mts) -{ - EMeetingTimeSelectorAttendee *attendee; - gint row, min; - ETextEventProcessor *event_processor = NULL; - ETextEventProcessorCommand command; - GtkAdjustment *adj; - gchar *text; - gboolean empty = FALSE; - - switch (event->type) { - case GDK_KEY_PRESS: - if (event && event->key.keyval == GDK_Return) { - row = e_meeting_time_selector_find_row_from_text_item (mts, item); - g_return_val_if_fail (row != -1, FALSE); - - if (row == mts->attendees->len - 1) - row = e_meeting_time_selector_attendee_add (mts, "", NULL); - else - row++; - - /* Make sure the item is visible. */ - adj = GTK_LAYOUT (mts->display_main)->vadjustment; - min = ((row + 1) * mts->row_height) - adj->page_size; - if (adj->value < min) { - adj->value = min; - gtk_adjustment_value_changed (adj); - } - - attendee = &g_array_index (mts->attendees, EMeetingTimeSelectorAttendee, row); - e_canvas_item_grab_focus (attendee->text_item, TRUE); - - /* Try to move the cursor to the end of the text. */ - gtk_object_get (GTK_OBJECT (attendee->text_item), - "event_processor", &event_processor, - NULL); - if (event_processor) { - command.action = E_TEP_MOVE; - command.position = E_TEP_END_OF_BUFFER; - gtk_signal_emit_by_name (GTK_OBJECT (event_processor), - "command", &command); - } - - /* Stop the signal last or we will also stop any - other events getting to the EText item. */ - gtk_signal_emit_stop_by_name (GTK_OBJECT (item), - "event"); - return TRUE; - } - break; - case GDK_FOCUS_CHANGE: - if (!event->focus_change.in) { - gtk_object_get (GTK_OBJECT (item), - "text", &text, - NULL); - if (!text || !text[0]) - empty = TRUE; - g_free (text); - - if (empty) { - row = e_meeting_time_selector_find_row_from_text_item (mts, item); - g_return_val_if_fail (row != -1, FALSE); - e_meeting_time_selector_attendee_remove (mts, - row); - } - } - break; - default: - break; - } - - return FALSE; -} - - -static gint -e_meeting_time_selector_find_row_from_text_item (EMeetingTimeSelector *mts, - GnomeCanvasItem *item) -{ - EMeetingTimeSelectorAttendee *attendee; - gint row; - - for (row = 0; row < mts->attendees->len; row++) { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - if (attendee->text_item == item) - return row; - } - - return -1; -} - diff --git a/widgets/meeting-time-sel/e-meeting-time-sel.h b/widgets/meeting-time-sel/e-meeting-time-sel.h deleted file mode 100644 index 0cfe7685b4..0000000000 --- a/widgets/meeting-time-sel/e-meeting-time-sel.h +++ /dev/null @@ -1,521 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Helix Code, 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 - */ -#ifndef _E_MEETING_TIME_SELECTOR_H_ -#define _E_MEETING_TIME_SELECTOR_H_ - -#include <glib.h> -#include <gtk/gtkaccelgroup.h> -#include <gtk/gtktable.h> -#include <gtk/gtkwidget.h> -#include <libgnomeui/gnome-canvas.h> -#include <gal/e-text/e-text.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EMeetingTimeSelector displays a list of attendees for a meeting and a - * graphical summary of the times which they are free and busy, allowing the - * user to select an appropriate time for a meeting. - */ - -/* Define this to include the debugging functions. */ -#undef E_MEETING_TIME_SELECTOR_DEBUG - -/* This is the width of the icon column in the attendees list. */ -#define E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH 24 - -#define E_MEETING_TIME_SELECTOR_TEXT_Y_PAD 3 -#define E_MEETING_TIME_SELECTOR_TEXT_X_PAD 2 - -/* These specify the type of attendee. Either a person or a resource (e.g. a - meeting room). These are used for the Autopick options, where the user can - ask for a time when, for example, all people and one resource are free. - The default is E_MEETING_TIME_SELECTOR_REQUIRED_PERSON. */ -typedef enum -{ - E_MEETING_TIME_SELECTOR_REQUIRED_PERSON, - E_MEETING_TIME_SELECTOR_OPTIONAL_PERSON, - E_MEETING_TIME_SELECTOR_RESOURCE -} EMeetingTimeSelectorAttendeeType; - - -/* These are used to specify whether an attendee is free or busy at a - particular time. We'll probably replace this with a global calendar type. - These should be ordered in increasing order of preference. Higher precedence - busy periods will be painted over lower precedence ones. These are also - used as for loop counters, so they should start at 0 and be ordered. */ -typedef enum -{ - E_MEETING_TIME_SELECTOR_BUSY_TENTATIVE = 0, - E_MEETING_TIME_SELECTOR_BUSY_OUT_OF_OFFICE = 1, - E_MEETING_TIME_SELECTOR_BUSY_BUSY = 2, - - E_MEETING_TIME_SELECTOR_BUSY_LAST = 3 -} EMeetingTimeSelectorBusyType; - - -/* This is used to specify the format used when displaying the dates. - The full format is like 'Sunday, September 12, 1999'. The abbreviated format - is like 'Sun 12/9/99'. The short format is like '12/9/99'. The actual - format used is determined in e_meeting_time_selector_style_set(), once we - know the font being used. */ -typedef enum -{ - E_MEETING_TIME_SELECTOR_DATE_FULL, - E_MEETING_TIME_SELECTOR_DATE_ABBREVIATED_DAY, - E_MEETING_TIME_SELECTOR_DATE_SHORT -} EMeetingTimeSelectorDateFormat; - - -/* This is used to specify a position regarding the vertical bars around the - current meeting time, so we know which one is being dragged. */ -typedef enum -{ - E_MEETING_TIME_SELECTOR_POS_NONE, - E_MEETING_TIME_SELECTOR_POS_START, - E_MEETING_TIME_SELECTOR_POS_END -} EMeetingTimeSelectorPosition; - - -/* This is used to specify the autopick option, which determines how we choose - the previous/next appropriate meeting time. */ -typedef enum -{ - E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_RESOURCES, - E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_ONE_RESOURCE, - E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE, - E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE -} EMeetingTimeSelectorAutopickOption; - - -/* This is our representation of a time. We use a GDate to store the day, - and guint8s for the hours and minutes. */ -typedef struct _EMeetingTimeSelectorTime EMeetingTimeSelectorTime; -struct _EMeetingTimeSelectorTime -{ - GDate date; - guint8 hour; - guint8 minute; -}; - - -/* This represents a busy period. */ -typedef struct _EMeetingTimeSelectorPeriod EMeetingTimeSelectorPeriod; -struct _EMeetingTimeSelectorPeriod -{ - EMeetingTimeSelectorTime start; - EMeetingTimeSelectorTime end; - EMeetingTimeSelectorBusyType busy_type; -}; - - -/* This contains information on one attendee. */ -typedef struct _EMeetingTimeSelectorAttendee EMeetingTimeSelectorAttendee; -struct _EMeetingTimeSelectorAttendee -{ - gchar *name; - - /* The type of attendee, e.g. a person or a resource. */ - EMeetingTimeSelectorAttendeeType type; - - /* This is TRUE if the attendee has calendar information available. - It is set to TRUE when a busy period is added, but can also be set - to TRUE explicitly to indicate that the attendee has calendar - information available, but no current busy periods. If it is FALSE - then a diagonal stipple pattern is used to fill the entire row in - the main graphical display. */ - gboolean has_calendar_info; - - /* This is TRUE if the meeting request is sent to this attendee. */ - gboolean send_meeting_to; - - /* This is the period for which free/busy data for the attendee is - available. */ - EMeetingTimeSelectorTime busy_periods_start; - EMeetingTimeSelectorTime busy_periods_end; - - /* This is an array of EMeetingTimeSelectorPeriod elements. When it is - updated busy_periods_sorted is set to FALSE, and if a function - needs them sorted, it should call this to re-sort them if needed: - e_meeting_time_selector_attendee_ensure_periods_sorted(). Note that - they are sorted by the start times. */ - GArray *busy_periods; - gboolean busy_periods_sorted; - - /* This holds the length of the longest busy period in days, rounded - up. It is used to determine where to start looking in the - busy_periods array. If we didn't use this we'd have to go through - most of the busy_periods array every time we wanted to paint part - of the display. */ - gint longest_period_in_days; - - /* This is the canvas text item where the name is edited. */ - GnomeCanvasItem *text_item; - - /* This is supposed to be something like an address book id. */ - gpointer data; -}; - -/* An array of hour strings, "0:00" .. "23:00". */ -extern const gchar *EMeetingTimeSelectorHours[24]; - - -#define E_MEETING_TIME_SELECTOR(obj) GTK_CHECK_CAST (obj, e_meeting_time_selector_get_type (), EMeetingTimeSelector) -#define E_MEETING_TIME_SELECTOR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_meeting_time_selector_get_type (), EMeetingTimeSelectorClass) -#define IS_E_MEETING_TIME_SELECTOR(obj) GTK_CHECK_TYPE (obj, e_meeting_time_selector_get_type ()) - - -typedef struct _EMeetingTimeSelector EMeetingTimeSelector; -typedef struct _EMeetingTimeSelectorClass EMeetingTimeSelectorClass; - -struct _EMeetingTimeSelector -{ - /* We subclass a GtkTable which makes it easy to add extra widgets - if neccesary. */ - GtkTable table; - - /* - * User Interface stuff - widgets, colors etc. - */ - - /* This contains our keyboard accelerators, which need to be added to - the toplevel window. */ - GtkAccelGroup *accel_group; - - /* The vbox in the top-left corner, containing the 'All Attendees' - title bar packed at the end. Extra widgets can be added here - with PACK_START if necessary. */ - GtkWidget *attendees_title_bar_vbox; - - /* The 'All Attendees' title bar above the list of attendees. */ - GtkWidget *attendees_title_bar; - - /* The list of attendees. */ - GtkWidget *attendees_list; - - /* The canvas displaying the dates, times, and the summary - 'All Attendees' free/busy display. */ - GtkWidget *display_top; - - /* The canvas containing the free/busy displays of individual - attendees. This is separate from display_top since it also scrolls - vertically. */ - GtkWidget *display_main; - - /* This is the 'Options' button & menu. */ - GtkWidget *options_button; - GtkWidget *options_menu; - - /* This is the 'Autopick' button, menu & radio menu items. */ - GtkWidget *autopick_button; - GtkWidget *autopick_menu; - GtkWidget *autopick_all_item; - GtkWidget *autopick_all_people_one_resource_item; - GtkWidget *autopick_required_people_item; - GtkWidget *autopick_required_people_one_resource_item; - - /* The horizontal scrollbar which scrolls display_top & display_main.*/ - GtkWidget *hscrollbar; - - /* The vertical scrollbar which scrolls attendees & display_main. */ - GtkWidget *vscrollbar; - - /* The 2 GnomeDateEdit widgets for the meeting start & end times. */ - GtkWidget *start_date_edit; - GtkWidget *end_date_edit; - - /* Colors. */ - GdkColorContext *color_context; - GdkColor bg_color; - GdkColor all_attendees_bg_color; - GdkColor meeting_time_bg_color; - GdkColor stipple_bg_color; - GdkColor attendee_list_bg_color; - GdkColor grid_color; - GdkColor grid_shadow_color; - GdkColor grid_unused_color; - GdkColor busy_colors[E_MEETING_TIME_SELECTOR_BUSY_LAST]; - - /* The stipple used for attendees with no data. */ - GdkPixmap *stipple; - - /* GC for drawing the color key. */ - GdkGC *color_key_gc; - - /* Width of the hours strings (e.g. "1:00") in the current font. */ - gint hour_widths[24]; - - /* Whether we are using the full, abbreviated or short date format. */ - EMeetingTimeSelectorDateFormat date_format; - - - /* - * Attendee Data. - */ - - /* This is an array of EMeetingTimeSelectorAttendee elements. */ - GArray *attendees; - - - /* - * Option Settings. - */ - - /* If this is TRUE we only show hours between day_start_hour and - day_end_hour, defaults to TRUE (9am-6pm). */ - gboolean working_hours_only; - gint day_start_hour; - gint day_start_minute; - gint day_end_hour; - gint day_end_minute; - - /* If TRUE, view is compressed, with one cell for every 3 hours rather - than every hour. Defaults to FALSE. */ - gboolean zoomed_out; - - - /* - * Internal Data. - */ - - /* These are the first & last dates shown in the current scroll area. - We show E_MEETING_TIME_SELECTOR_DAYS_SHOWN days at a time. */ - GDate first_date_shown; - GDate last_date_shown; - - /* This is the current selection of the meeting time. */ - EMeetingTimeSelectorTime meeting_start_time; - EMeetingTimeSelectorTime meeting_end_time; - - /* These are the x pixel coordinates in the entire scroll region of - the start and end times. Set to meeting_positions_valid to FALSE to - invalidate. They will then be recomputed when needed. Always access - with e_meeting_time_selector_get_meeting_time_positions(). */ - gint meeting_positions_valid; - gint meeting_positions_in_scroll_area; - gint meeting_start_x; - gint meeting_end_x; - - /* These are the width and height of the cells, including the grid - lines which are displayed on the right and top or bottom of cells.*/ - gint row_height; - gint col_width; - - /* This is the width of a day in the display, which depends on - col_width, working_hours_only and zoomed_out. */ - gint day_width; - - /* These are the first and last hour of each day we display, depending - on working_hours_only and zoomed_out. */ - gint first_hour_shown; - gint last_hour_shown; - - /* The id of the source function for auto-scroll timeouts. */ - guint auto_scroll_timeout_id; - - /* This specifies if we are dragging one of the vertical bars around - the meeting time. */ - EMeetingTimeSelectorPosition dragging_position; - - /* The last x coordinate of the mouse, relative to either the left or - right edge of the canvas. Used in the auto_scroll_timeout function - to determine which way to scroll and how fast. */ - gint last_drag_x; - - /* This is used to determine the delay between scrolls. */ - gint scroll_count; -}; - - -struct _EMeetingTimeSelectorClass -{ - GtkTableClass parent_class; -}; - - -/* - * PUBLIC INTERFACE - note that this interface will probably change, when I - * know where the data is coming from. This is mainly just for testing for now. - */ - -GtkType e_meeting_time_selector_get_type (void); -GtkWidget* e_meeting_time_selector_new (void); - -/* This returns the currently selected meeting time. - Note that months are 1-12 and days are 1-31. The start time is guaranteed to - be before or equal to the end time. You may want to check if they are equal - if that if it is a problem. */ -void e_meeting_time_selector_get_meeting_time (EMeetingTimeSelector *mts, - gint *start_year, - gint *start_month, - gint *start_day, - gint *start_hour, - gint *start_minute, - gint *end_year, - gint *end_month, - gint *end_day, - gint *end_hour, - gint *end_minute); - -/* This sets the meeting time, returning TRUE if it is valid. */ -gboolean e_meeting_time_selector_set_meeting_time (EMeetingTimeSelector *mts, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute); - -void e_meeting_time_selector_set_working_hours_only (EMeetingTimeSelector *mts, - gboolean working_hours_only); -void e_meeting_time_selector_set_working_hours (EMeetingTimeSelector *mts, - gint day_start_hour, - gint day_start_minute, - gint day_end_hour, - gint day_end_minute); - -void e_meeting_time_selector_set_zoomed_out (EMeetingTimeSelector *mts, - gboolean zoomed_out); - -EMeetingTimeSelectorAutopickOption e_meeting_time_selector_get_autopick_option (EMeetingTimeSelector *mts); -void e_meeting_time_selector_set_autopick_option (EMeetingTimeSelector *mts, - EMeetingTimeSelectorAutopickOption autopick_option); - -/* Adds an attendee to the list, returning the row. The data is meant for - something like an address book id, though if the user edits the name this - will become invalid. We'll probably have to handle address book lookup - ourself. */ -gint e_meeting_time_selector_attendee_add (EMeetingTimeSelector *mts, - gchar *attendee_name, - gpointer data); -gint e_meeting_time_selector_attendee_find_by_name (EMeetingTimeSelector *mts, - gchar *attendee_name, - gint start_row); -gint e_meeting_time_selector_attendee_find_by_data (EMeetingTimeSelector *mts, - gpointer data, - gint start_row); -void e_meeting_time_selector_attendee_remove (EMeetingTimeSelector *mts, - gint row); - -void e_meeting_time_selector_attendee_set_type (EMeetingTimeSelector *mts, - gint row, - EMeetingTimeSelectorAttendeeType type); -void e_meeting_time_selector_attendee_set_has_calendar_info (EMeetingTimeSelector *mts, - gint row, - gboolean has_calendar_info); -void e_meeting_time_selector_attendee_set_send_meeting_to (EMeetingTimeSelector *mts, - gint row, - gboolean send_meeting_to); - -gboolean e_meeting_time_selector_attendee_set_busy_range (EMeetingTimeSelector *mts, - gint row, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute); - - -/* Clears all busy times for the given attendee. */ -void e_meeting_time_selector_attendee_clear_busy_periods (EMeetingTimeSelector *mts, - gint row); -/* Adds one busy time for the given attendee. */ -gboolean e_meeting_time_selector_attendee_add_busy_period (EMeetingTimeSelector *mts, - gint row, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute, - EMeetingTimeSelectorBusyType busy_type); - - - -/* - * INTERNAL ROUTINES - functions to communicate with the canvas items within - * the EMeetingTimeSelector. - */ - -/* This returns the x pixel coordinates of the meeting start and end times, - in the entire canvas scroll area. If it returns FALSE, then the meeting - time isn't in the current scroll area (which shouldn't really happen). */ -gboolean e_meeting_time_selector_get_meeting_time_positions (EMeetingTimeSelector *mts, - gint *start_x, - gint *end_x); - -void e_meeting_time_selector_drag_meeting_time (EMeetingTimeSelector *mts, - gint x); - -void e_meeting_time_selector_remove_timeout (EMeetingTimeSelector *mts); - -void e_meeting_time_selector_fix_time_overflows (EMeetingTimeSelectorTime *mtstime); - -gint e_meeting_time_selector_find_first_busy_period (EMeetingTimeSelector *mts, - EMeetingTimeSelectorAttendee *attendee, - GDate *date); - -/* Makes sure the busy periods are sorted, so we can do binary searches. */ -void e_meeting_time_selector_attendee_ensure_periods_sorted (EMeetingTimeSelector *mts, - EMeetingTimeSelectorAttendee *attendee); - -void e_meeting_time_selector_calculate_day_and_position (EMeetingTimeSelector *mts, - gint x, - GDate *date, - gint *day_position); -void e_meeting_time_selector_convert_day_position_to_hours_and_mins (EMeetingTimeSelector *mts, gint day_position, guint8 *hours, guint8 *minutes); -void e_meeting_time_selector_calculate_time (EMeetingTimeSelector *mts, - gint x, - EMeetingTimeSelectorTime *time); -gint e_meeting_time_selector_calculate_time_position (EMeetingTimeSelector *mts, - EMeetingTimeSelectorTime *mtstime); - -/* Debugging function to dump information on all attendees. */ -#ifdef E_MEETING_TIME_SELECTOR_DEBUG -void e_meeting_time_selector_dump (EMeetingTimeSelector *mts); -gchar* e_meeting_time_selector_dump_time (EMeetingTimeSelectorTime *mtstime); -gchar* e_meeting_time_selector_dump_date (GDate *date); -#endif /* E_MEETING_TIME_SELECTOR_DEBUG */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_MEETING_TIME_SELECTOR_H_ */ diff --git a/widgets/meeting-time-sel/test-meeting-time-sel.c b/widgets/meeting-time-sel/test-meeting-time-sel.c deleted file mode 100644 index 78fdbf3b98..0000000000 --- a/widgets/meeting-time-sel/test-meeting-time-sel.c +++ /dev/null @@ -1,252 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Helix Code, 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 - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <time.h> -#include <glib.h> -#include <gtk/gtkmain.h> -#include <gdk_imlib.h> -#include <libgnome/gnome-defs.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-init.h> -#include <libgnomeui/gnome-stock.h> -#include "e-meeting-time-sel.h" - -void add_random_attendee_test_data (EMeetingTimeSelector *mts); -void add_simple_attendee_test_data (EMeetingTimeSelector *mts); -gint get_random_int (gint max); - -int -main (int argc, char *argv[]) -{ - GtkWidget *window, *mts; - gint i; - - gnome_init ("test-meeting-time-selector", "0.1", argc, argv); - - gtk_widget_push_visual (gdk_imlib_get_visual ()); - gtk_widget_push_colormap (gdk_imlib_get_colormap ()); - - window = gnome_dialog_new ("Plan a Meeting", "Make Meeting", - GNOME_STOCK_BUTTON_CLOSE, NULL); - gtk_window_set_default_size (GTK_WINDOW (window), 600, 400); - gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE); - - mts = e_meeting_time_selector_new (); - gtk_container_add (GTK_CONTAINER (GNOME_DIALOG (window)->vbox), mts); - gtk_window_add_accel_group (GTK_WINDOW (window), - E_MEETING_TIME_SELECTOR (mts)->accel_group); - gtk_widget_show (mts); - - gtk_widget_pop_visual (); - gtk_widget_pop_colormap (); - - i = 0; -#if 1 - for (i = 0; i < 20; i++) { - add_random_attendee_test_data (E_MEETING_TIME_SELECTOR (mts)); - } - - if (!e_meeting_time_selector_attendee_set_busy_range (E_MEETING_TIME_SELECTOR (mts), 3, - 2000, 5, 1, 14, 0, - 2000, 11, 1, 11, 30)) - g_print ("Error setting busy range\n"); - -#else - for (i = 0; i < 1; i++) { - add_simple_attendee_test_data (E_MEETING_TIME_SELECTOR (mts)); - } -#endif - -#if 0 - e_meeting_time_selector_dump (E_MEETING_TIME_SELECTOR (mts)); -#endif - - gnome_dialog_run (GNOME_DIALOG (window)); - - gtk_main (); - return 0; -} - - -/* Adds an attendee and a lot of random busy periods. The periods start 60 - days before the current date and extend over 365 days, to match the range - that EMeetingTimeSelector currently displays. We generate a time_t and an - interval and then convert them into a struct tm which provides everything - we need. */ -void -add_random_attendee_test_data (EMeetingTimeSelector *mts) -{ - gchar buffer[128], *name; - gint row, num_periods, busy_period, random_num, duration; - EMeetingTimeSelectorAttendeeType type; - EMeetingTimeSelectorBusyType busy_type; - time_t range_start; - time_t period_start; - time_t period_end; - struct tm *tmp_tm; - struct tm tm1; - struct tm tm2; - - /* Determine the type of attendee. */ - random_num = get_random_int (10); - if (random_num < 4) { - type = E_MEETING_TIME_SELECTOR_REQUIRED_PERSON; - name = "Req. Attendee"; - } else if (random_num < 7) { - type = E_MEETING_TIME_SELECTOR_OPTIONAL_PERSON; - name = "Opt. Attendee"; - } else { - type = E_MEETING_TIME_SELECTOR_RESOURCE; - name = "Resource"; - } - - sprintf (buffer, "%s %i", name, mts->attendees->len + 1); - row = e_meeting_time_selector_attendee_add (mts, buffer, NULL); - e_meeting_time_selector_attendee_set_type (mts, row, type); - - /* Don't send the meeting request to some attendees. */ - if (get_random_int (10) <= 2) - e_meeting_time_selector_attendee_set_send_meeting_to (mts, row, - FALSE); - - /* Some attendees have no calendar information. */ - if (get_random_int (10) == 2) - return; - - range_start = time (NULL) - 61 * 24 * 60 * 60; - num_periods = get_random_int (1000); -#if 0 - g_print ("num_periods: %i\n", num_periods); -#endif - for (busy_period = 0; busy_period < num_periods; busy_period++) { - - period_start = range_start + get_random_int (365 * 24 * 60 * 60); - - /* Make busy periods mainly 30 mins to a few hours, with a - couple of week/fortnight periods as well. */ - random_num = get_random_int (10000); - if (random_num < 2000) - duration = 30; - else if (random_num < 5000) - duration = 60; - else if (random_num < 7500) - duration = 90; - else if (random_num < 9995) - duration = 120; - else if (random_num < 9998) - duration = 60 * 24 * 7; - else - duration = 60 * 24 * 14; -#if 0 - g_print ("random_num: %i, duration: %i\n", - random_num, duration); -#endif - period_end = period_start + duration * 60; - - tmp_tm = localtime (&period_start); - tm1 = *tmp_tm; - tmp_tm = localtime (&period_end); - tm2 = *tmp_tm; - - /* A hack to avoid daylight-saving time problems. */ - if (tm2.tm_hour == tm1.tm_hour && tm2.tm_min < tm1.tm_min) - tm2.tm_hour++; - - busy_type = get_random_int (E_MEETING_TIME_SELECTOR_BUSY_LAST); - - if (!e_meeting_time_selector_attendee_add_busy_period (mts, row, tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday, tm1.tm_hour, tm1.tm_min, tm2.tm_year + 1900, tm2.tm_mon + 1, tm2.tm_mday, tm2.tm_hour, tm2.tm_min, busy_type)) - { - g_print ("Invalid busy period %i/%i/%i %i:%i to %i/%i/%i %i:%i\n", tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday, tm1.tm_hour, tm1.tm_min, tm2.tm_year + 1900, tm2.tm_mon + 1, tm2.tm_mday, tm2.tm_hour, tm2.tm_min); - g_print ("random_num: %i, duration: %i\n", - random_num, duration); - } - } -} - - -/* Returns a random integer between 0 and max - 1. */ -gint -get_random_int (gint max) -{ - gint random_num; - - random_num = (int) (max * (rand () / (RAND_MAX + 1.0))); -#if 0 - g_print ("Random num (%i): %i\n", max, random_num); -#endif - return random_num; -} - - -void -add_simple_attendee_test_data (EMeetingTimeSelector *mts) -{ - gint row; - - row = e_meeting_time_selector_attendee_add (mts, "John Smith", NULL); - if (!e_meeting_time_selector_attendee_add_busy_period (mts, row, - 1999, 11, 7, 14, 30, - 1999, 11, 7, 16, 30, - E_MEETING_TIME_SELECTOR_BUSY_BUSY)) - g_warning ("Invalid busy period"); - - e_meeting_time_selector_attendee_add_busy_period (mts, row, - 1999, 11, 7, 10, 30, - 1999, 11, 7, 11, 30, - E_MEETING_TIME_SELECTOR_BUSY_OUT_OF_OFFICE); - e_meeting_time_selector_attendee_add_busy_period (mts, row, - 1999, 11, 4, 10, 30, - 1999, 11, 7, 11, 30, - E_MEETING_TIME_SELECTOR_BUSY_BUSY); - row = e_meeting_time_selector_attendee_add (mts, "Dave Jones", NULL); - e_meeting_time_selector_attendee_add_busy_period (mts, row, - 1999, 11, 7, 15, 30, - 1999, 11, 7, 18, 30, - E_MEETING_TIME_SELECTOR_BUSY_TENTATIVE); - e_meeting_time_selector_attendee_add_busy_period (mts, row, - 1999, 11, 7, 11, 00, - 1999, 11, 7, 12, 00, - E_MEETING_TIME_SELECTOR_BUSY_BUSY); - - row = e_meeting_time_selector_attendee_add (mts, "Andrew Carlisle", NULL); - e_meeting_time_selector_attendee_set_send_meeting_to (mts, row, FALSE); - - row = e_meeting_time_selector_attendee_add (mts, "Michael Cain", NULL); - e_meeting_time_selector_attendee_add_busy_period (mts, row, - 1999, 11, 7, 15, 30, - 1999, 11, 7, 18, 30, - E_MEETING_TIME_SELECTOR_BUSY_TENTATIVE); - e_meeting_time_selector_attendee_add_busy_period (mts, row, - 1999, 11, 7, 12, 30, - 1999, 11, 7, 13, 30, - E_MEETING_TIME_SELECTOR_BUSY_OUT_OF_OFFICE); - e_meeting_time_selector_attendee_add_busy_period (mts, row, - 1999, 11, 7, 11, 00, - 1999, 11, 7, 12, 00, - E_MEETING_TIME_SELECTOR_BUSY_TENTATIVE); -} diff --git a/widgets/menus/.cvsignore b/widgets/menus/.cvsignore deleted file mode 100644 index 7708c3d120..0000000000 --- a/widgets/menus/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -Makefile -libmenus.la -Makefile.in -.deps -.libs -.pure -*.o -*.lo diff --git a/widgets/menus/Makefile.am b/widgets/menus/Makefile.am deleted file mode 100644 index 500f0672fc..0000000000 --- a/widgets/menus/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -noinst_LTLIBRARIES = libmenus.la - -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets/menus \ - $(EXTRA_GNOME_CFLAGS) \ - -DG_LOG_DOMAIN=\"menus\" - -libmenus_la_SOURCES = \ - gal-view-menus.c \ - gal-view-menus.h diff --git a/widgets/menus/gal-view-menus.c b/widgets/menus/gal-view-menus.c deleted file mode 100644 index ac99ae1793..0000000000 --- a/widgets/menus/gal-view-menus.c +++ /dev/null @@ -1,301 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * gal-view-menus.c: Deploy a GalViewCollection in the menus. - * - * Author: - * Chris Lahey <clahey@helixcode.com> - * - * (C) 2000, 2001 Ximian, Inc. - */ -#include <config.h> - -#include "gal-view-menus.h" - -#include <stdlib.h> -#include <gtk/gtksignal.h> -#include <gnome-xml/parser.h> -#include <gnome-xml/xmlmemory.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnome/gnome-i18n.h> -#include <gal/util/e-util.h> -#include <gal/util/e-xml-utils.h> -#include <gal/menus/gal-define-views-dialog.h> -#include <gal/widgets/e-unicode.h> - -struct _GalViewMenusPrivate { - GalViewCollection *collection; - int collection_changed_id; - BonoboUIVerb *verbs; - BonoboUIComponent *component; -}; - -#define PARENT_TYPE (gtk_object_get_type()) - -static GtkObjectClass *gvm_parent_class; -static void collection_changed (GalViewCollection *collection, - GalViewMenus *gvm); - -#define d(x) - -typedef struct { - GalViewCollection *collection; - GalView *view; -} CollectionAndView; - -static void -free_verbs (GalViewMenus *gvm) -{ - BonoboUIVerb *verbs; - if (gvm->priv->verbs) { - for (verbs = gvm->priv->verbs + 1; verbs->cname; verbs++) { - CollectionAndView *cnv; - - if (gvm->priv->component) - bonobo_ui_component_remove_verb(gvm->priv->component, verbs->cname); - - cnv = verbs->user_data; - g_free(verbs->cname); - - gtk_object_unref(GTK_OBJECT(cnv->collection)); - gtk_object_unref(GTK_OBJECT(cnv->view)); - g_free(cnv); - } - g_free(gvm->priv->verbs); - } - gvm->priv->verbs = NULL; -} - -static void -remove_xml (GalViewMenus *gvm) -{ -} - -static void -gvm_destroy (GtkObject *object) -{ - GalViewMenus *gvm = GAL_VIEW_MENUS (object); - - if (gvm->priv->collection && gvm->priv->collection_changed_id != 0) { - gtk_signal_disconnect(GTK_OBJECT(gvm->priv->collection), gvm->priv->collection_changed_id); - } - - if (gvm->priv->collection) - gtk_object_unref(GTK_OBJECT(gvm->priv->collection)); - free_verbs(gvm); - remove_xml(gvm); - g_free(gvm->priv); - gvm->priv = NULL; - - GTK_OBJECT_CLASS (gvm_parent_class)->destroy (object); -} - -static void -gvm_class_init (GtkObjectClass *klass) -{ - gvm_parent_class = gtk_type_class (PARENT_TYPE); - - klass->destroy = gvm_destroy; -} - -static void -gvm_init (GalViewMenus *gvm) -{ - gvm->priv = g_new(GalViewMenusPrivate, 1); - gvm->priv->collection = NULL; - gvm->priv->collection_changed_id = 0; - gvm->priv->verbs = NULL; - gvm->priv->component = NULL; -} - -E_MAKE_TYPE(gal_view_menus, "GalViewMenus", GalViewMenus, gvm_class_init, gvm_init, PARENT_TYPE); - -GalViewMenus * -gal_view_menus_new (GalViewCollection *collection) -{ - GalViewMenus *gvm = gtk_type_new (GAL_VIEW_MENUS_TYPE); - - gal_view_menus_construct(gvm, collection); - - return gvm; -} - -GalViewMenus * -gal_view_menus_construct (GalViewMenus *gvm, - GalViewCollection *collection) -{ - if (collection) - gtk_object_ref(GTK_OBJECT(collection)); - gvm->priv->collection = collection; - - gtk_signal_connect(GTK_OBJECT(collection), "changed", - GTK_SIGNAL_FUNC(collection_changed), gvm); - return gvm; -} - -static void -dialog_clicked(GtkWidget *dialog, int button, GalViewMenus *menus) -{ - if (button == 0) { - gal_view_collection_save(menus->priv->collection); - } - gnome_dialog_close(GNOME_DIALOG(dialog)); -} - -static void -define_views(BonoboUIComponent *component, - GalViewMenus *menus, - char *cname) -{ - GtkWidget *dialog = gal_define_views_dialog_new(menus->priv->collection); - gtk_signal_connect(GTK_OBJECT(dialog), "clicked", - GTK_SIGNAL_FUNC(dialog_clicked), menus); - gtk_widget_show(dialog); -} - -static char * -build_menus(GalViewMenus *menus) -{ - BonoboUINode *root, *menu, *submenu, *place, *menuitem; - char *xml; - xmlChar *string; - int length; - int i; - GalViewCollection *collection = menus->priv->collection; - - root = bonobo_ui_node_new("Root"); - menu = bonobo_ui_node_new_child(root, "menu"); - - submenu = bonobo_ui_node_new_child(menu, "submenu"); - bonobo_ui_node_set_attr(submenu, "name", "View"); - - place = bonobo_ui_node_new_child(submenu, "placeholder"); - bonobo_ui_node_set_attr(place, "name", "ViewBegin"); - - submenu = bonobo_ui_node_new_child(place, "submenu"); - bonobo_ui_node_set_attr(submenu, "name", "CurrentView"); - bonobo_ui_node_set_attr(submenu, "_label", N_("_Current View")); - - length = gal_view_collection_get_count(collection); - for (i = 0; i < length; i++) { - char *verb; - char *label; - GalViewCollectionItem *item = gal_view_collection_get_view_item(collection, i); - menuitem = bonobo_ui_node_new_child(submenu, "menuitem"); - bonobo_ui_node_set_attr(menuitem, "name", item->id); - - /* bonobo displays this string so it must be in locale */ - label = e_utf8_to_locale_string(item->title); - /* All labels are bonobo_ui_util_decode_str()ed, - * so even translated label must be set with _label */ - bonobo_ui_node_set_attr(menuitem, "_label", label); - g_free(label); - - verb = g_strdup_printf("DefineViews:%s", item->id); - bonobo_ui_node_set_attr(menuitem, "verb", verb); - g_free(verb); - } - - menuitem = bonobo_ui_node_new_child(submenu, "separator"); - - menuitem = bonobo_ui_node_new_child(submenu, "menuitem"); - bonobo_ui_node_set_attr(menuitem, "name", "DefineViews"); - bonobo_ui_node_set_attr(menuitem, "_label", N_("Define Views")); - bonobo_ui_node_set_attr(menuitem, "verb", "DefineViews"); - - string = bonobo_ui_node_to_string(root, TRUE); - xml = g_strdup(string); - bonobo_ui_node_free_string(string); - - bonobo_ui_node_free(root); - - d(g_print (xml)); - - return xml; -} - -static void -show_view(BonoboUIComponent *component, - gpointer user_data, - const char *cname) -{ - CollectionAndView *cnv = user_data; - gal_view_collection_display_view(cnv->collection, cnv->view); -} - -static BonoboUIVerb * -build_verbs (GalViewMenus *menus) -{ - GalViewCollection *collection = menus->priv->collection; - int count = gal_view_collection_get_count(collection); - BonoboUIVerb *verbs = g_new(BonoboUIVerb, count + 2); - BonoboUIVerb *verb; - int i; - - verb = verbs; - verb->cname = g_strdup("DefineViews"); - verb->cb = (BonoboUIVerbFn) define_views; - verb->user_data = menus; - verb->dummy = NULL; - verb ++; - for (i = 0; i < count; i++) { - CollectionAndView *cnv; - GalViewCollectionItem *item = gal_view_collection_get_view_item(collection, i); - - cnv = g_new(CollectionAndView, 1); - cnv->view = item->view; - cnv->collection = collection; - - gtk_object_ref(GTK_OBJECT(cnv->view)); - gtk_object_ref(GTK_OBJECT(cnv->collection)); - - verb->cname = g_strdup_printf("DefineViews:%s", item->id); - verb->cb = show_view; - verb->user_data = cnv; - verb->dummy = NULL; - verb++; - } - - verb->cname = NULL; - verb->cb = NULL; - verb->user_data = NULL; - verb->dummy = NULL; - verb++; - - return verbs; -} - -static void -build_stuff (GalViewMenus *gvm, - CORBA_Environment *ev) -{ - char *xml; - - remove_xml(gvm); - xml = build_menus(gvm); - bonobo_ui_component_set_translate(gvm->priv->component, "/", xml, ev); - g_free(xml); - - free_verbs(gvm); - gvm->priv->verbs = build_verbs(gvm); - bonobo_ui_component_add_verb_list(gvm->priv->component, gvm->priv->verbs); -} - -void gal_view_menus_apply (GalViewMenus *gvm, - BonoboUIComponent *component, - CORBA_Environment *ev) -{ - gvm->priv->component = component; - - build_stuff (gvm, ev); -} - -static void -collection_changed (GalViewCollection *collection, - GalViewMenus *gvm) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - build_stuff(gvm, &ev); - CORBA_exception_free (&ev); -} diff --git a/widgets/menus/gal-view-menus.h b/widgets/menus/gal-view-menus.h deleted file mode 100644 index 21b302771c..0000000000 --- a/widgets/menus/gal-view-menus.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -#ifndef _GAL_VIEW_MENUS_H_ -#define _GAL_VIEW_MENUS_H_ - -#include <gtk/gtkobject.h> -#include <gnome-xml/tree.h> -#include <bonobo/bonobo-ui-component.h> -#include <gal/menus/gal-view-collection.h> - -#define GAL_VIEW_MENUS_TYPE (gal_view_menus_get_type ()) -#define GAL_VIEW_MENUS(o) (GTK_CHECK_CAST ((o), GAL_VIEW_MENUS_TYPE, GalViewMenus)) -#define GAL_VIEW_MENUS_CLASS(k) (GTK_CHECK_CLASS_CAST((k), GAL_VIEW_MENUS_TYPE, GalViewMenusClass)) -#define GAL_IS_VIEW_MENUS(o) (GTK_CHECK_TYPE ((o), GAL_VIEW_MENUS_TYPE)) -#define GAL_IS_VIEW_MENUS_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), GAL_VIEW_MENUS_TYPE)) - -typedef struct _GalViewMenusPrivate GalViewMenusPrivate; - -typedef struct { - GtkObject base; - GalViewMenusPrivate *priv; -} GalViewMenus; - -typedef struct { - GtkObjectClass parent_class; -} GalViewMenusClass; - -GtkType gal_view_menus_get_type (void); -GalViewMenus *gal_view_menus_new (GalViewCollection *collection); -GalViewMenus *gal_view_menus_construct (GalViewMenus *menus, - GalViewCollection *collection); - -void gal_view_menus_apply (GalViewMenus *menus, - BonoboUIComponent *component, - CORBA_Environment *ev); - -#endif /* _GAL_VIEW_MENUS_H_ */ diff --git a/widgets/misc/.cvsignore b/widgets/misc/.cvsignore deleted file mode 100644 index f7ea0db71c..0000000000 --- a/widgets/misc/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.libs -.pure -Makefile -Makefile.in -*.lo -*.la -test-title-bar -test-calendar -test-dateedit -test-dropdown-button
\ No newline at end of file diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog deleted file mode 100644 index 92e92a21b2..0000000000 --- a/widgets/misc/ChangeLog +++ /dev/null @@ -1,470 +0,0 @@ -2001-05-07 Gediminas Paulauskas <menesis@delfi.lt> - - * misc/e-filter-bar.h: xgettext does not find N_() in #defines. So - created fake enum. Also removed spaces before "..." - -2001-04-24 Kjartan Maraas <kmaraas@gnome.org> - - * e-calendar-item.c, e-calendar.c, e-cell-date-edit.c, - e-clipped-label.c, e-dateedit.c, e-dropdown-button: - Added #include <glib.h> and moved corresponding local headers - to the top. - -2001-04-15 Federico Mena Quintero <federico@ximian.com> - - * e-search-bar.c (e_search_bar_get_option_choice): New function, - because it is ridiculous to have to hunt down object arguments to - fetch values. - (e_search_bar_get_text): Likewise. - (impl_get_arg): Use the functions above so that we have to - maintain only one version of the getters. - -2001-04-04 Kjartan Maraas <kmaraas@gnome.org> - - * e-calendar.c: More header fixes. - * e-cell-date-edit.c: Same. - * e-dateedit.[ch]: Same. - * e-title-bar.c: Same here. - * e-search-bar.c: More header fixes. - * test-calendar.c: Same here. - -2001-03-29 Kjartan Maraas <kmaraas@gnome.org> - - * e-dropdown-button.c: Replace #include <gtk/gtk.h> - * e-dropdown-button.h: Remove #include <gnome.h> - * e-filter-bar.c: Replace #include <gtk/gtk.h> - * e-filter-bar.h: Replace #include <gtk/gtk.h> - * e-messagebox.c: Add #includes to count for removed <gnome.h> in - e-messagebox.h: - * e-messagebox.h: Replace #include <gnome.h> - * e-search-bar.c: Replace #include <gnome.h> - * e-search-bar.h: Same here - * test-calendar.c: Remove #include <gnome.h> - * test-dateedit.c: Replace #include <gnome.h> - * test-dropdown-button.c: Same here. - * test-title-bar.c: Same here. - -2001-03-22 Jeffrey Stedfast <fejj@ximian.com> - - * e-filter-bar.c (rule_editor_clicked): Validate the filter rule. - -2001-03-18 Damon Chaplin <damon@ximian.com> - - * e-cell-date-edit.c (e_cell_date_edit_show_time_invalid_warning): - use gnome_dialog_run() to make the warning dialog modal. Also created - a better warning message showing the format expected. - Also used e_time_format_time() to format all times. - -2001-03-15 Not Zed <NotZed@Ximian.com> - - * e-filter-bar.c (menubar_activated): If we click on the edit - menu, then bring up a rule editor. If the user adds/removes rules - though, they are neither saved, nor added to the menu's. sigh. - -2001-03-04 Damon Chaplin <damon@ximian.com> - - * e-cell-date-edit.c: pretty much working now. - -2001-03-01 Not Zed <NotZed@Ximian.com> - - * e-filter-bar.c: New type of search bar that interacts with - filter contexts to save filters etc. Still probably needs a - little cleanpu. - -2001-02-28 Not Zed <NotZed@Ximian.com> - - * e-search-bar.c (add_dropdown): Save the dropdown menu in the - struct too. Sigh, this is only so we can scan its content later, - ick. - (e_search_bar_set_menu_sensitive): New function to se tthe - sentisitivty of menyu items based on id. - (find_id): New function to find the row and widget for a specific - id. - (add_option): Renamed to set_option. - (add_dropdown): Renamed to set_dropdown. - (add_dropdown): ?New function to add a single item. - (set_dropdown): Call add_dropdown to add each item. - (e_search_bar_add_menu): New public function to add a single item. - -2001-02-27 Not Zed <NotZed@Ximian.com> - - * Makefile.am (libemiscwidgets_a_SOURCES): Added filter-bar.[ch]. - - * e-search-bar.c (class_init): Init virtual functions. - (e_search_bar_set_option): - (e_search_bar_set_menu): virtualise calling. - (e_search_bar_construct): Call virtual functions to setup menus. - - * e-search-bar.h (struct _ESearchBarClass): Virtualise - add_dropdown/add_option, so certain base options can be created. - -2001-02-25 Damon Chaplin <damon@ximian.com> - - * e-cell-date-edit.[hc]: new files to implement an ECell for showing - and editing dates & times. (Unfinished) - - * Makefile.am (libemiscwidgets_a_SOURCES): added e-cell-date-edit.[hc] - -2001-02-24 Not Zed <NotZed@Ximian.com> - - * e-search-bar.c (add_dropdown): Move the event box into the - esb->dropdown_holder. Changed so it can be called again on the - same esb, to rebuild the menu. - (e_search_bar_set_menu): New function to (re)set the menu. - (add_option): Setup so it can be re-called to rebuild the option - list. - (e_search_bar_set_option): New function to build the menu's. - -2001-02-05 Jeffrey Stedfast <fejj@ximian.com> - - * .cvsignore: Ignore test-dropdown-button - -2001-01-28 Ettore Perazzoli <ettore@ximian.com> - - * e-search-bar.c (add_spacer): Make the spacer 4 pixels wider. - (add_dropdown): Put the dropdown button into an event box with a - 1-pixel border, so that we match the [Hardcoded! Stupid GTK+!] - border around the option menu. - -2001-01-28 Ettore Perazzoli <ettore@ximian.com> - - * e-dropdown-button.c (menu_deactivate_cb): New function to change - the state of the toggle button when the pop-up menu disappears. - (impl_clicked): Removed. - (impl_button_press_event): New, implementation for - `::button_press_event'. Pop-up the menu, and toggle the button. - (class_init): Override `::button_press_event' with - `impl_button_press_event'; don't override `::clicked' anymore. - - * e-dropdown-button.h, e-dropdown-button.c: Derive from - `GtkToggleButton', instead of plain `GtkButton'. - -2001-01-27 Ettore Perazzoli <ettore@ximian.com> - - * e-search-bar.c (add_dropdown): Make the dropdown button - non-focusable. - -2001-01-27 Ettore Perazzoli <ettore@ximian.com> - - * e-search-bar.c (e_search_bar_init): Don't create the widgets - here. - (e_search_bar_construct): New. Do it here instead. - (e_search_bar_new): Call it. Added preconditions. - (esb_pack_menubar): Removed. - (add_dropdown): New. - (add_option): New. - (add_entry): New. - (e_search_bar_construct): Use `add_dropdown()', `add_option()', - `add_entry()'. - (class_init): Renamed from `e_seearch_bar_class_init'. - (init): Renamed from `e_search_bar_init'. - (impl_destroy): Renamed from `e_search_bar_destroy'. - (emit_menu_activated): Renamed from `esb_menu_activated'. - (emit_query_changed): Renamed from `esb_query_changed'. - (menubar_activated_cb): Renamed from `esb_menubar_activated'. - (option_activated_cb): Renamed from `esb_option_activated'. - (esb_entry_activated): Renamed from `esb_entry_activated'. - (impl_set_arg): Renamed from `e_search_bar_set_arg'. - (impl_get_arg): Renamed from `e_search_bar_get_arg'. - - * e-search-bar.h (struct _ESearchBar): Removed member `menubar'; - replaced it with `dropdown'. - -2001-01-27 Ettore Perazzoli <ettore@ximian.com> - - * e-dropdown-button.c (e_dropdown_button_construct): Removed - @ui_info and @data args. Obviously I am not very smart at this - time of the night. - (e_dropdown_button_new): Likewise. - -2001-01-27 Ettore Perazzoli <ettore@ximian.com> - - * e-dropdown-button.c, e-dropdown-button.h: New. - -2001-01-25 Damon Chaplin <damon@ximian.com> - - * e-calendar-item.[hc]: e_calendar_item_get_date_range() now returns - a boolean, which is FALSE if no dates are currently shown. - Plus a couple of minor sanity checks. - -2001-01-19 Federico Mena Quintero <federico@ximian.com> - - * e-calendar.c (e_calendar_init): Unset the GTK_CAN_FOCUS flag on - the ECalendar. - (e_calendar_focus_in): Removed function since it did nothing. - (e_calendar_focus_out): Likewise. - (e_calendar_key_press): Likewise. - (e_calendar_init): Turn off the GTK_CAN_FOCUS flag for both arrow - buttons. - -2001-01-17 Federico Mena Quintero <federico@ximian.com> - - * e-calendar-item.c (e_calendar_item_set_max_days_sel): Make zero - the minimum number of days that can be specified. - (e_calendar_item_set_arg): We do need an update when the maximum - number of selected days is changed. - (e_calendar_item_set_max_days_sel): Request an update of the - canvas item. - (e_calendar_item_button_press): Do not start selecting days if the - max_days_selected is less than 1. - -2001-01-17 Jeffrey Stedfast <fejj@ximian.com> - - * e-messagebox.c (e_message_box_get_id): Oops. Delete this. I - never meant for this to get commit'd. - -2001-01-17 JP Rosevear <jpr@ximian.com> - - * e-messagebox.c (e_message_box_get_id): Dont remove the function, give - it the proper name - -2001-01-17 Ettore Perazzoli <ettore@ximian.com> - - * e-messagebox.c (e_message_box_get_checkbox): Remove the version - returning `const char *' as of course it doesn't compile. Please - compile before committing. - -2001-01-17 Jeffrey Stedfast <fejj@ximian.com> - - * Makefile.am: Added e-messagebox to the build. - - * e-messagebox.[c,h]: Added a new messagebox window that contains - a checkbox for "Don't show me this again." - -2001-01-16 Jason Leach <jasonleach@usa.net> - - * e-search-bar.[ch]: Moved here from $(toplevel)/filter. - -2000-12-22 JP Rosevear <jpr@helixcode.com> - - * e-calendar-item.h: add prototypes - - * e-calendar-item.c (e_calendar_item_init): Set max_days_selected to - 1 and days_to_start_week_selection to -1 as documented in header - (e_calendar_item_set_arg): use new accessor methods - (e_calendar_item_get_arg): ditto - (e_calendar_item_get_max_days_sel): accessor - (e_calendar_item_set_max_days_sel): ditto - (e_calendar_item_get_days_start_week_sel): ditto - (e_calendar_item_set_days_start_week_sel): ditto - (e_calendar_item_class_init): add display_popup argument - (e_calendar_item_init): initialize display_popup member - (e_calendar_item_get_arg): get display_popup member - (e_calendar_item_set_arg): set display_popup member - (e_calendar_item_button_press): only show the popup menu if the - member is set - (e_calendar_item_get_display_popup): acessor - (e_calendar_item_set_display_popup): ditto - -2000-12-14 Federico Mena Quintero <federico@helixcode.com> - - * e-dateedit.h: #include <time.h> - -2000-12-08 JP Rosevear <jpr@helixcode.com> - - * e-calendar.c (e_calendar_destroy): Call the parent class destroyer - as well - -2000-10-26 Damon Chaplin <damon@helixcode.com> - - * e-dateedit.[hc]: updated to emit "changed" when appropriate, which - turned out to be amazingly difficult :( - Also added e_date_edit_get/set_date() to get/set just the date. - Added e_date_edit_date_is_valid() & e_date_edit_time_is_valid() so - you can check if the user has tried to enter an invalid date. - (All the get_date/time functions return the last valid date entered.) - - * test-dateedit.c: updated a bit. - -2000-11-02 Federico Mena Quintero <federico@helixcode.com> - - * e-dateedit.h (EDateEditClass): Removed the "time_changed" - signal, since it was never being emitted in the first place. Time - values *are* both date and time together anyways, so whenever one - changes we should notify about the whole date/time value being - changed. - Renamed the remaining "date_changed" signal to just "changed". - - * e-dateedit.c (e_date_edit_class_init): Do not create the - "time_changed" signal; rename the other one to "changed". - (set_time): Moved the core functionality from - e_date_edit_set_time() to here. This function just sets the - widgets' values without emitting any signals. - (e_date_edit_set_time): Emit the "changed" signal unconditionally. - This is to be consistent with the rest of the GTK+ widgets, and it - actually makes writing client code easier. - (e_date_edit_new): Use set_time(). - (on_date_popup_now_button_clicked): Do not emit the signal here. - (on_date_popup_none_button_clicked): Likewise. - (e_date_edit_set_time_of_day): Emit the signal, since we do not - call e_date_edit_set_time(). - -2000-10-30 Kjartan Maraas <kmaraas@gnome.org> - - * e-calendar-item.c: #include <string.h> to get rid of warning. - * e-clipped-label.c: Same here. - -2000-10-27 Federico Mena Quintero <federico@helixcode.com> - - * e-dateedit.c (e_date_edit_destroy): Do not unref the cal_popup - since we already destroyed it. - -2000-10-11 Damon Chaplin <damon@helixcode.com> - - * e-calendar-item.c (e_calendar_item_recalc_sizes): fixed to - recalculate min_cell_width/height in case the show_week_numbers option - is changed. - - * e-dateedit.c: added support for hiding the date field, and added - get/set_time_of_day() functions to get/set just the time. - -2000-09-30 Damon Chaplin <damon@helixcode.com> - - * e-calendar-item.c: - * e-dateedit.c: better i18n of strftime strings. - -2000-09-29 Ettore Perazzoli <ettore@helixcode.com> - - * e-title-bar.c: New member `pin_gtk_pixmap' in - `ETitleBarPrivate'. Signal "close_button_clicked" renamed to - "button_clicked". Signal "title_button_press_event" renamed to - "label_button_press_event". - (init): Init new members. - (close_button_realize_cb): Create the pin pixmap. Call - `show_and_hide_pixmaps_according_to_mode()'. - (e_title_bar_show_close_button): Renamed to - `e_title_bar_show_button'. - (e_title_bar_get_button_mode): New. - (e_title_bar_set_button_mode): New. - -2000-09-23 Damon Chaplin <damon@helixcode.com> - - * e-calendar.c: use pixmaps instead of GtkArrows to look better. - Also set the canvas window's background when realized so that we can - set the button reliefs to none. - -2000-09-22 Damon Chaplin <damon@helixcode.com> - - * test-dateedit.c: updated a bit, adding a few EDateEdits with - different options. - - * e-calendar-item.c (e_calendar_item_set_selection): aborted any - current selection operation and initialize all of the selection fields. - (e_calendar_item_unmap): new function to abort any current selection - operation. Otherwise GnomeCanvas gets in a muddle about grabs. - - * e-dateedit.c: marked some strftime()/strptime() format strings for - translation and used "%m/%d/%Y" instead of "%x" so we get the complete - year number. Also changed e_date_edit_get_time() so it returns -2 if - it can't parse the date or time, and -1 if it is explicitly set to - None. - (e_date_edit_parse_date): new function to parse the date string and - add on the current century if a year of 0-99 is entered. - -2000-09-21 Damon Chaplin <damon@helixcode.com> - - * e-dateedit.c (on_date_button_clicked): only check return of strptime - for NULL. It should now select the correct day set in the popup. - - * e-calendar.c: - * e-calendar-item.c: - * test-calendar.c: removed support for buttons within the ECalendar. - It is cleaner to add them outside it, as EDateEdit does. - -2000-09-18 Dan Winship <danw@helixcode.com> - - * e-dateedit.c (_XOPEN_SOURCE): set this to 4 to specify how much - X/Open we want with that. - -2000-09-18 Christopher James Lahey <clahey@helixcode.com> - - * Makefile.am: Added $(EXTRA_GNOME_CFLAGS) and - $(EXTRA_GNOME_LIBS). Removed unneeded libraries. - - * e-calendar-item.c, e-calendar.c, e-calendar.h, e-title-bar.c: - Fixed the #include lines to deal properly with gal. - - * e-scroll-frame.c, e-scroll-frame.h: Moved to gal. - -2000-09-11 Damon Chaplin <damon@helixcode.com> - - * Makefile.am (libemiscwidgets_a_SOURCES): added e-dateedit.[hc] - and the test-dateedit app. - - * e-dateedit.[hc]: new widget to use instead of GnomeDateEdit. It - uses the new ECalendar widget for the calendar and also supports - "None", "Today" and "Now" buttons, and goes away with a single click. - - * test-dateedit.c: app to test the EDateEdit widget. - - * e-calendar-item.c: updated to support the EDateEdit better, - mainly by adding the "move_selection_when_moving" arg so we can turn - it off to keep the same day selected when changing the months shown. - -2000-09-05 Damon Chaplin <damon@helixcode.com> - - * e-calendar-item.c (e_calendar_item_draw_month): make sure we get - the start_weekday since we need it for draw_days(). Fixes a drawing - bug. - -2000-08-31 Damon Chaplin <damon@helixcode.com> - - * e-calendar-item.c (e_calendar_item_button_press): - (e_calendar_item_button_release): grab/ungrab the pointer so we - always get the button_release event. - -2000-08-30 Damon Chaplin <damon@helixcode.com> - - * e-calendar-item.[hc]: - * e-calendar.[hc]: Updated. - -2000-08-10 Christopher James Lahey <clahey@helixcode.com> - - * e-calendar-item.c, e-calendar.c: Fixed some warnings. - -2000-07-25 Damon Chaplin <damon@helixcode.com> - - * e-calendar-item.h: - * e-calendar.[hc]: new widget and canvas item to replace GtkCalendar. - Not quite finished yet. - -2000-07-21 Ettore Perazzoli <ettore@helixcode.com> - - * e-title-bar.c (e_title_bar_set_title): We have a `EClippedLabel', - not a `GtkLabel' here: use the right function to change the text. - -2000-07-12 Christopher James Lahey <clahey@helixcode.com> - - * e-scroll-frame.c: Tried rearranging the casts to try for a more - correct computation. - -2000-07-08 Dan Winship <danw@helixcode.com> - - * e-scroll-frame.c (e_scroll_frame_add): comment out true but - confused warning about non-scrollable widgets until Chris and/or - Federico fix this correctly. - (e_scroll_frame_size_allocate): If the available space for the - child is less than the width/height of the frame, give the child - an allocation of 0 rather than some small negative number cast to - unsigned. - -2000-07-05 Dan Winship <danw@helixcode.com> - - * Makefile.am (INCLUDES): Set G_LOG_DOMAIN=__FILE__ rather than - "e-title-bar" in all three widgets. - -2000-06-13 Anders Carlsson <andersca@gnu.org> - - * e-scroll-frame.c (e_scroll_frame_button_press): Control does - horizontal scrolling, a la gimp. - -2000-06-11 Anders Carlsson <andersca@gnu.org> - - * e-scroll-frame.c (e_scroll_frame_button_press): Add support - for mouse wheel scrolling in EScrollFrame. - -2000-06-10 Ettore Perazzoli <ettore@helixcode.com> - - * e-title-bar.c (close_button_realize_cb): Unref the pixmap and - the mask. - diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am deleted file mode 100644 index 401aac64a0..0000000000 --- a/widgets/misc/Makefile.am +++ /dev/null @@ -1,78 +0,0 @@ -# FIXME we use the EClippedLabel widget from EShortcutBar. Probably -# it should be moved somewhere else. - -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets/shortcut-bar \ - $(EXTRA_GNOME_CFLAGS) \ - -DG_LOG_DOMAIN=__FILE__ - -noinst_LIBRARIES = \ - libemiscwidgets.a - -libemiscwidgets_a_SOURCES = \ - e-calendar.c \ - e-calendar.h \ - e-calendar-item.c \ - e-calendar-item.h \ - e-cell-date-edit.c \ - e-cell-date-edit.h \ - e-clipped-label.c \ - e-clipped-label.h \ - e-dateedit.c \ - e-dateedit.h \ - e-dropdown-button.c \ - e-dropdown-button.h \ - e-filter-bar.c \ - e-filter-bar.h \ - e-messagebox.c \ - e-messagebox.h \ - e-search-bar.c \ - e-search-bar.h \ - e-title-bar.c \ - e-title-bar.h - -noinst_PROGRAMS = \ - test-calendar \ - test-dateedit \ - test-dropdown-button \ - test-title-bar - -# test-calendar - -test_calendar_SOURCES = \ - test-calendar.c - -test_calendar_LDADD = \ - ./libemiscwidgets.a \ - ../../e-util/libeutil.la \ - $(EXTRA_GNOME_LIBS) - -# test-dateedit - -test_dateedit_SOURCES = \ - test-dateedit.c - -test_dateedit_LDADD = \ - ./libemiscwidgets.a \ - ../../e-util/libeutil.la \ - $(EXTRA_GNOME_LIBS) - -# test-dropdown-button - -test_dropdown_button_SOURCES = \ - test-dropdown-button.c - -test_dropdown_button_LDADD = \ - ./libemiscwidgets.a \ - $(EXTRA_GNOME_LIBS) - -# test-title-bar - -test_title_bar_SOURCES = \ - test-title-bar.c - -test_title_bar_LDADD = \ - ./libemiscwidgets.a \ - $(EXTRA_GNOME_LIBS) - diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c deleted file mode 100644 index e17bf6aa62..0000000000 --- a/widgets/misc/e-calendar-item.c +++ /dev/null @@ -1,2886 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 2000, Helix Code, 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 - */ - -/* - * ECalendarItem - canvas item displaying a calendar. - */ - -#include <config.h> - -#include "e-calendar-item.h" - -#include <time.h> -#include <string.h> -#include <glib.h> -#include <gtk/gtkmain.h> -#include <gtk/gtkmenu.h> -#include <gtk/gtkmenuitem.h> -#include <gtk/gtksignal.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <gal/util/e-util.h> - -/* - * These are the padding sizes between various pieces of the calendar. - */ - -/* The minimum padding around the numbers in each cell/day. */ -#define E_CALENDAR_ITEM_MIN_CELL_XPAD 4 -#define E_CALENDAR_ITEM_MIN_CELL_YPAD 0 - -/* Vertical padding. */ -#define E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS 1 -#define E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS 0 -#define E_CALENDAR_ITEM_YPAD_ABOVE_CELLS 1 -#define E_CALENDAR_ITEM_YPAD_BELOW_CELLS 2 - -/* Horizontal padding in the heading bars. */ -#define E_CALENDAR_ITEM_XPAD_BEFORE_MONTH_NAME_WITH_BUTTON 16 -#define E_CALENDAR_ITEM_XPAD_BEFORE_MONTH_NAME 3 -#define E_CALENDAR_ITEM_XPAD_AFTER_MONTH_NAME 3 -#define E_CALENDAR_ITEM_XPAD_AFTER_MONTH_NAME_WITH_BUTTON 16 - -/* Horizontal padding in the month displays. */ -#define E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS 4 -#define E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS 2 -#define E_CALENDAR_ITEM_XPAD_BEFORE_CELLS 1 -#define E_CALENDAR_ITEM_XPAD_AFTER_CELLS 4 - -/* The number of rows & columns of days in each month. */ -#define E_CALENDAR_ROWS_PER_MONTH 6 -#define E_CALENDAR_COLS_PER_MONTH 7 - -static const int e_calendar_item_days_in_month[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -#define DAYS_IN_MONTH(year, month) \ - e_calendar_item_days_in_month[month] + (((month) == 1 \ - && ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))) ? 1 : 0) - - -static void e_calendar_item_class_init (ECalendarItemClass *class); -static void e_calendar_item_init (ECalendarItem *calitem); -static void e_calendar_item_destroy (GtkObject *o); -static void e_calendar_item_get_arg (GtkObject *o, - GtkArg *arg, - guint arg_id); -static void e_calendar_item_set_arg (GtkObject *o, - GtkArg *arg, - guint arg_id); -static void e_calendar_item_realize (GnomeCanvasItem *item); -static void e_calendar_item_unrealize (GnomeCanvasItem *item); -static void e_calendar_item_unmap (GnomeCanvasItem *item); -static void e_calendar_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags); -static void e_calendar_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height); -static void e_calendar_item_draw_month (ECalendarItem *calitem, - GdkDrawable *drawable, - int x, - int y, - int width, - int height, - int row, - int col); -static void e_calendar_item_draw_day_numbers (ECalendarItem *calitem, - GdkDrawable *drawable, - int width, - int height, - int row, - int col, - int year, - int month, - int start_weekday, - gint cells_x, - gint cells_y); -static double e_calendar_item_point (GnomeCanvasItem *item, - double x, - double y, - int cx, - int cy, - GnomeCanvasItem **actual_item); -static gint e_calendar_item_event (GnomeCanvasItem *item, - GdkEvent *event); -static gboolean e_calendar_item_button_press (ECalendarItem *calitem, - GdkEvent *event); -static gboolean e_calendar_item_button_release (ECalendarItem *calitem, - GdkEvent *event); -static gboolean e_calendar_item_motion (ECalendarItem *calitem, - GdkEvent *event); - -static gboolean e_calendar_item_convert_position_to_day (ECalendarItem *calitem, - gint x, - gint y, - gboolean round_empty_positions, - gint *month_offset, - gint *day, - gboolean *entire_week); -static void e_calendar_item_get_month_info (ECalendarItem *calitem, - gint row, - gint col, - gint *first_day_offset, - gint *days_in_month, - gint *days_in_prev_month); -static void e_calendar_item_recalc_sizes(ECalendarItem *calitem); - -static gint e_calendar_item_get_week_number (ECalendarItem *calitem, - gint day, - gint month, - gint year); - -static void e_calendar_item_get_day_style (ECalendarItem *calitem, - gint year, - gint month, - gint day, - gint day_style, - gboolean today, - gboolean prev_or_next_month, - gboolean selected, - gboolean has_focus, - gboolean drop_target, - GdkColor **bg_color, - GdkColor **fg_color, - GdkColor **box_color, - gboolean *bold); -static void e_calendar_item_check_selection_end (ECalendarItem *calitem, - gint start_month, - gint start_day, - gint *end_month, - gint *end_day); -static void e_calendar_item_check_selection_start(ECalendarItem *calitem, - gint *start_month, - gint *start_day, - gint end_month, - gint end_day); -static void e_calendar_item_normalize_date (ECalendarItem *calitem, - gint *year, - gint *month); -static void e_calendar_item_add_days_to_selection(ECalendarItem *calitem, - gint days); -static void e_calendar_item_round_up_selection (ECalendarItem *calitem, - gint *month_offset, - gint *day); -static void e_calendar_item_round_down_selection (ECalendarItem *calitem, - gint *month_offset, - gint *day); -static gint e_calendar_item_get_inclusive_days (ECalendarItem *calitem, - gint start_month_offset, - gint start_day, - gint end_month_offset, - gint end_day); -static void e_calendar_item_ensure_valid_day (ECalendarItem *calitem, - gint *month_offset, - gint *day); -static gboolean e_calendar_item_ensure_days_visible (ECalendarItem *calitem, - gint start_year, - gint start_month, - gint start_day, - gint end_year, - gint end_month, - gint end_day); -static void e_calendar_item_show_popup_menu (ECalendarItem *calitem, - GdkEventButton *event, - gint month_offset); -static void e_calendar_item_on_menu_item_activate(GtkWidget *menuitem, - ECalendarItem *calitem); -static void e_calendar_item_position_menu (GtkMenu *menu, - gint *x, - gint *y, - gpointer user_data); -static void e_calendar_item_date_range_changed (ECalendarItem *calitem); -static void e_calendar_item_queue_signal_emission (ECalendarItem *calitem); -static gboolean e_calendar_item_signal_emission_idle_cb (gpointer data); - -/* Our arguments. */ -enum { - ARG_0, - ARG_YEAR, - ARG_MONTH, - ARG_X1, - ARG_Y1, - ARG_X2, - ARG_Y2, - ARG_FONT, - ARG_WEEK_NUMBER_FONT, - ARG_ROW_HEIGHT, - ARG_COLUMN_WIDTH, - ARG_MINIMUM_ROWS, - ARG_MINIMUM_COLUMNS, - ARG_MAXIMUM_ROWS, - ARG_MAXIMUM_COLUMNS, - ARG_WEEK_START_DAY, - ARG_SHOW_WEEK_NUMBERS, - ARG_MAXIMUM_DAYS_SELECTED, - ARG_DAYS_TO_START_WEEK_SELECTION, - ARG_MOVE_SELECTION_WHEN_MOVING, - ARG_ROUND_SELECTION_WHEN_MOVING, - ARG_DISPLAY_POPUP -}; - -enum { - DATE_RANGE_CHANGED, - SELECTION_CHANGED, - LAST_SIGNAL -}; - - -static GnomeCanvasItemClass *parent_class; -static guint e_calendar_item_signals[LAST_SIGNAL] = { 0 }; - - -E_MAKE_TYPE (e_calendar_item, "ECalendarItem", ECalendarItem, - e_calendar_item_class_init, e_calendar_item_init, - GNOME_TYPE_CANVAS_ITEM) - - -static void -e_calendar_item_class_init (ECalendarItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type()); - - object_class = (GtkObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - gtk_object_add_arg_type ("ECalendarItem::year", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_YEAR); - gtk_object_add_arg_type ("ECalendarItem::month", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_MONTH); - gtk_object_add_arg_type ("ECalendarItem::x1", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, - ARG_X1); - gtk_object_add_arg_type ("ECalendarItem::y1", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, - ARG_Y1); - gtk_object_add_arg_type ("ECalendarItem::x2", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, - ARG_X2); - gtk_object_add_arg_type ("ECalendarItem::y2", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, - ARG_Y2); - gtk_object_add_arg_type ("ECalendarItem::font", - GTK_TYPE_GDK_FONT, GTK_ARG_READWRITE, - ARG_FONT); - gtk_object_add_arg_type ("ECalendarItem::week_number_font", - GTK_TYPE_GDK_FONT, GTK_ARG_READWRITE, - ARG_WEEK_NUMBER_FONT); - gtk_object_add_arg_type ("ECalendarItem::row_height", - GTK_TYPE_INT, GTK_ARG_READABLE, - ARG_ROW_HEIGHT); - gtk_object_add_arg_type ("ECalendarItem::column_width", - GTK_TYPE_INT, GTK_ARG_READABLE, - ARG_COLUMN_WIDTH); - gtk_object_add_arg_type ("ECalendarItem::minimum_rows", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_MINIMUM_ROWS); - gtk_object_add_arg_type ("ECalendarItem::minimum_columns", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_MINIMUM_COLUMNS); - gtk_object_add_arg_type ("ECalendarItem::maximum_rows", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_MAXIMUM_ROWS); - gtk_object_add_arg_type ("ECalendarItem::maximum_columns", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_MAXIMUM_COLUMNS); - gtk_object_add_arg_type ("ECalendarItem::week_start_day", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_WEEK_START_DAY); - gtk_object_add_arg_type ("ECalendarItem::show_week_numbers", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, - ARG_SHOW_WEEK_NUMBERS); - gtk_object_add_arg_type ("ECalendarItem::maximum_days_selected", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_MAXIMUM_DAYS_SELECTED); - gtk_object_add_arg_type ("ECalendarItem::days_to_start_week_selection", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_DAYS_TO_START_WEEK_SELECTION); - gtk_object_add_arg_type ("ECalendarItem::move_selection_when_moving", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, - ARG_MOVE_SELECTION_WHEN_MOVING); - gtk_object_add_arg_type ("ECalendarItem::round_selection_when_moving", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, - ARG_ROUND_SELECTION_WHEN_MOVING); - gtk_object_add_arg_type ("ECalendarItem::display_popup", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, - ARG_DISPLAY_POPUP); - - e_calendar_item_signals[DATE_RANGE_CHANGED] = - gtk_signal_new ("date_range_changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (ECalendarItemClass, date_range_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - e_calendar_item_signals[SELECTION_CHANGED] = - gtk_signal_new ("selection_changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (ECalendarItemClass, selection_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, e_calendar_item_signals, - LAST_SIGNAL); - - - object_class->destroy = e_calendar_item_destroy; - object_class->get_arg = e_calendar_item_get_arg; - object_class->set_arg = e_calendar_item_set_arg; - - /* GnomeCanvasItem method overrides */ - item_class->realize = e_calendar_item_realize; - item_class->unrealize = e_calendar_item_unrealize; - item_class->unmap = e_calendar_item_unmap; - item_class->update = e_calendar_item_update; - item_class->draw = e_calendar_item_draw; - item_class->point = e_calendar_item_point; - item_class->event = e_calendar_item_event; - - class->date_range_changed = NULL; - class->selection_changed = NULL; -} - - -static void -e_calendar_item_init (ECalendarItem *calitem) -{ - struct tm *tmp_tm; - time_t t; - - /* Set the default time to the current month. */ - t = time (NULL); - tmp_tm = localtime (&t); - calitem->year = tmp_tm->tm_year + 1900; - calitem->month = tmp_tm->tm_mon; - - calitem->styles = NULL; - - calitem->min_cols = 1; - calitem->min_rows = 1; - calitem->max_cols = -1; - calitem->max_rows = -1; - - calitem->rows = 0; - calitem->cols = 0; - - calitem->show_week_numbers = FALSE; - calitem->week_start_day = 0; - calitem->expand = TRUE; - calitem->max_days_selected = 1; - calitem->days_to_start_week_selection = -1; - calitem->move_selection_when_moving = TRUE; - calitem->round_selection_when_moving = FALSE; - calitem->display_popup = TRUE; - - calitem->x1 = 0.0; - calitem->y1 = 0.0; - calitem->x2 = 0.0; - calitem->y2 = 0.0; - - calitem->selection_set = FALSE; - - calitem->selection_changed = FALSE; - calitem->date_range_changed = FALSE; - - calitem->style_callback = NULL; - calitem->style_callback_destroy = NULL; - - /* Translators: These are the first characters of each day of the - week, 'M' for 'Monday', 'T' for Tuesday etc. */ - calitem->days = _("MTWTFSS"); - - calitem->signal_emission_idle_id = 0; -} - - -static void -e_calendar_item_destroy (GtkObject *o) -{ - ECalendarItem *calitem; - - calitem = E_CALENDAR_ITEM (o); - - e_calendar_item_set_style_callback (calitem, NULL, NULL, NULL); - - g_free (calitem->styles); - - if (calitem->signal_emission_idle_id != 0) { - g_source_remove (calitem->signal_emission_idle_id); - calitem->signal_emission_idle_id = 0; - } - - if (calitem->old_font) - gdk_font_unref (calitem->old_font); - if (calitem->old_week_number_font) - gdk_font_unref (calitem->old_week_number_font); -} - - -static void -e_calendar_item_get_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - ECalendarItem *calitem; - - item = GNOME_CANVAS_ITEM (o); - calitem = E_CALENDAR_ITEM (o); - - switch (arg_id) { - case ARG_YEAR: - GTK_VALUE_INT (*arg) = calitem->year; - break; - case ARG_MONTH: - GTK_VALUE_INT (*arg) = calitem->month; - break; - case ARG_X1: - GTK_VALUE_DOUBLE (*arg) = calitem->x1; - break; - case ARG_Y1: - GTK_VALUE_DOUBLE (*arg) = calitem->y1; - break; - case ARG_X2: - GTK_VALUE_DOUBLE (*arg) = calitem->x2; - break; - case ARG_Y2: - GTK_VALUE_DOUBLE (*arg) = calitem->y2; - break; - case ARG_FONT: - GTK_VALUE_BOXED (*arg) = calitem->font; - break; - case ARG_WEEK_NUMBER_FONT: - GTK_VALUE_BOXED (*arg) = calitem->week_number_font; - break; - case ARG_ROW_HEIGHT: - e_calendar_item_recalc_sizes (calitem); - GTK_VALUE_INT (*arg) = calitem->min_month_height; - break; - case ARG_COLUMN_WIDTH: - e_calendar_item_recalc_sizes (calitem); - GTK_VALUE_INT (*arg) = calitem->min_month_width; - break; - case ARG_MINIMUM_ROWS: - GTK_VALUE_INT (*arg) = calitem->min_rows; - break; - case ARG_MINIMUM_COLUMNS: - GTK_VALUE_INT (*arg) = calitem->min_cols; - break; - case ARG_MAXIMUM_ROWS: - GTK_VALUE_INT (*arg) = calitem->max_rows; - break; - case ARG_MAXIMUM_COLUMNS: - GTK_VALUE_INT (*arg) = calitem->max_cols; - break; - case ARG_WEEK_START_DAY: - GTK_VALUE_INT (*arg) = calitem->week_start_day; - break; - case ARG_SHOW_WEEK_NUMBERS: - GTK_VALUE_BOOL (*arg) = calitem->show_week_numbers; - break; - case ARG_MAXIMUM_DAYS_SELECTED: - GTK_VALUE_INT (*arg) = e_calendar_item_get_max_days_sel (calitem); - break; - case ARG_DAYS_TO_START_WEEK_SELECTION: - GTK_VALUE_INT (*arg) = e_calendar_item_get_days_start_week_sel (calitem); - break; - case ARG_MOVE_SELECTION_WHEN_MOVING: - GTK_VALUE_BOOL (*arg) = calitem->move_selection_when_moving; - break; - case ARG_ROUND_SELECTION_WHEN_MOVING: - GTK_VALUE_BOOL (*arg) = calitem->round_selection_when_moving; - break; - case ARG_DISPLAY_POPUP: - GTK_VALUE_BOOL (*arg) = e_calendar_item_get_display_popup (calitem); - break; - default: - g_warning ("Invalid arg"); - } -} - - -static void -e_calendar_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - ECalendarItem *calitem; - GdkFont *font; - gboolean need_update = FALSE; - gdouble dvalue; - gint ivalue; - gboolean bvalue; - - item = GNOME_CANVAS_ITEM (o); - calitem = E_CALENDAR_ITEM (o); - - switch (arg_id){ - case ARG_YEAR: - ivalue = GTK_VALUE_INT (*arg); - e_calendar_item_set_first_month (calitem, ivalue, - calitem->month); - break; - case ARG_MONTH: - ivalue = GTK_VALUE_INT (*arg); - e_calendar_item_set_first_month (calitem, calitem->year, - ivalue); - break; - case ARG_X1: - dvalue = GTK_VALUE_DOUBLE (*arg); - if (calitem->x1 != dvalue) { - calitem->x1 = dvalue; - need_update = TRUE; - } - break; - case ARG_Y1: - dvalue = GTK_VALUE_DOUBLE (*arg); - if (calitem->y1 != dvalue) { - calitem->y1 = dvalue; - need_update = TRUE; - } - break; - case ARG_X2: - dvalue = GTK_VALUE_DOUBLE (*arg); - if (calitem->x2 != dvalue) { - calitem->x2 = dvalue; - need_update = TRUE; - } - break; - case ARG_Y2: - dvalue = GTK_VALUE_DOUBLE (*arg); - if (calitem->y2 != dvalue) { - calitem->y2 = dvalue; - need_update = TRUE; - } - break; - case ARG_FONT: - font = GTK_VALUE_BOXED (*arg); - if (calitem->font != font) { - if (calitem->font) - gdk_font_unref (calitem->font); - calitem->font = font; - if (font) - gdk_font_ref (font); - need_update = TRUE; - } - break; - case ARG_WEEK_NUMBER_FONT: - font = GTK_VALUE_BOXED (*arg); - if (calitem->week_number_font != font) { - if (calitem->week_number_font) - gdk_font_unref (calitem->week_number_font); - calitem->week_number_font = font; - if (font) - gdk_font_ref (font); - need_update = TRUE; - } - break; - case ARG_MINIMUM_ROWS: - ivalue = GTK_VALUE_INT (*arg); - ivalue = MAX (1, ivalue); - if (calitem->min_rows != ivalue) { - calitem->min_rows = ivalue; - need_update = TRUE; - } - break; - case ARG_MINIMUM_COLUMNS: - ivalue = GTK_VALUE_INT (*arg); - ivalue = MAX (1, ivalue); - if (calitem->min_cols != ivalue) { - calitem->min_cols = ivalue; - need_update = TRUE; - } - break; - case ARG_MAXIMUM_ROWS: - ivalue = GTK_VALUE_INT (*arg); - if (calitem->max_rows != ivalue) { - calitem->max_rows = ivalue; - need_update = TRUE; - } - break; - case ARG_MAXIMUM_COLUMNS: - ivalue = GTK_VALUE_INT (*arg); - if (calitem->max_cols != ivalue) { - calitem->max_cols = ivalue; - need_update = TRUE; - } - break; - case ARG_WEEK_START_DAY: - ivalue = GTK_VALUE_INT (*arg); - if (calitem->week_start_day != ivalue) { - calitem->week_start_day = ivalue; - need_update = TRUE; - } - break; - case ARG_SHOW_WEEK_NUMBERS: - bvalue = GTK_VALUE_BOOL (*arg); - if (calitem->show_week_numbers != bvalue) { - calitem->show_week_numbers = bvalue; - need_update = TRUE; - } - break; - case ARG_MAXIMUM_DAYS_SELECTED: - ivalue = GTK_VALUE_INT (*arg); - e_calendar_item_set_max_days_sel (calitem, ivalue); - break; - case ARG_DAYS_TO_START_WEEK_SELECTION: - ivalue = GTK_VALUE_INT (*arg); - e_calendar_item_set_days_start_week_sel (calitem, ivalue); - break; - case ARG_MOVE_SELECTION_WHEN_MOVING: - bvalue = GTK_VALUE_BOOL (*arg); - calitem->move_selection_when_moving = bvalue; - break; - case ARG_ROUND_SELECTION_WHEN_MOVING: - bvalue = GTK_VALUE_BOOL (*arg); - calitem->round_selection_when_moving = bvalue; - break; - case ARG_DISPLAY_POPUP: - bvalue = GTK_VALUE_BOOL (*arg); - e_calendar_item_set_display_popup (calitem, bvalue); - break; - default: - g_warning ("Invalid arg"); - } - - if (need_update) { - gnome_canvas_item_request_update (item); - } -} - - -static void -e_calendar_item_realize (GnomeCanvasItem *item) -{ - ECalendarItem *calitem; - GdkColormap *colormap; - gboolean success[E_CALENDAR_ITEM_COLOR_LAST]; - gint nfailed; - - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->realize) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->realize) (item); - - calitem = E_CALENDAR_ITEM (item); - - colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - - calitem->colors[E_CALENDAR_ITEM_COLOR_TODAY_BOX].red = 65535; - calitem->colors[E_CALENDAR_ITEM_COLOR_TODAY_BOX].green = 0; - calitem->colors[E_CALENDAR_ITEM_COLOR_TODAY_BOX].blue = 0; - - calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG].red = 65535; - calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG].green = 65535; - calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG].blue = 65535; - - calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG].red = 47000; - calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG].green = 47000; - calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG].blue = 48000; - - calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG].red = 47000; - calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG].green = 47000; - calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG].blue = 48000; - - nfailed = gdk_colormap_alloc_colors (colormap, calitem->colors, - E_CALENDAR_ITEM_COLOR_LAST, FALSE, - TRUE, success); - if (nfailed) - g_warning ("Failed to allocate all colors"); -} - - -static void -e_calendar_item_unrealize (GnomeCanvasItem *item) -{ - ECalendarItem *calitem; - GdkColormap *colormap; - gint i; - - calitem = E_CALENDAR_ITEM (item); - - colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - - for (i = 0; i < E_CALENDAR_ITEM_COLOR_LAST; i++) - gdk_colors_free (colormap, &calitem->colors[i].pixel, 1, 0); - - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize) (item); -} - - -static void -e_calendar_item_unmap (GnomeCanvasItem *item) -{ - ECalendarItem *calitem; - - calitem = E_CALENDAR_ITEM (item); - - if (calitem->selecting) { - gnome_canvas_item_ungrab (item, GDK_CURRENT_TIME); - calitem->selecting = FALSE; - } - - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->unmap) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->unmap) (item); -} - - -static void -e_calendar_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags) -{ - ECalendarItem *calitem; - GtkStyle *style; - GdkFont *font; - gint char_height, width, height, space, space_per_cal, space_per_cell; - gint rows, cols, xthickness, ythickness; - - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags); - - calitem = E_CALENDAR_ITEM (item); - style = GTK_WIDGET (item->canvas)->style; - xthickness = style->klass->xthickness; - ythickness = style->klass->ythickness; - - item->x1 = calitem->x1; - item->y1 = calitem->y1; - item->x2 = calitem->x2 >= calitem->x1 ? calitem->x2 : calitem->x1; - item->y2 = calitem->y2 >= calitem->y1 ? calitem->y2 : calitem->y1; - - /* - * Calculate the new layout of the calendar. - */ - - /* Make sure the minimum row width & cell height and the widths of - all the digits and characters are up to date. */ - e_calendar_item_recalc_sizes (calitem); - - /* Calculate how many rows & cols we can fit in. */ - width = item->x2 - item->x1; - height = item->y2 - item->y1; - - width -= xthickness * 2; - height -= ythickness * 2; - - if (calitem->min_month_height == 0) - rows = 1; - else - rows = height / calitem->min_month_height; - rows = MAX (rows, calitem->min_rows); - if (calitem->max_rows > 0) - rows = MIN (rows, calitem->max_rows); - - if (calitem->min_month_width == 0) - cols = 1; - else - cols = width / calitem->min_month_width; - cols = MAX (cols, calitem->min_cols); - if (calitem->max_cols > 0) - cols = MIN (cols, calitem->max_cols); - - if (rows != calitem->rows || cols != calitem->cols) - e_calendar_item_date_range_changed (calitem); - - calitem->rows = rows; - calitem->cols = cols; - - /* Split up the empty space according to the configuration. - If the calendar is set to expand, we divide the space between the - cells and the spaces around the calendar, otherwise we place the - calendars in the center of the available area. */ - - font = calitem->font; - if (!font) - font = style->font; - char_height = font->ascent + font->descent; - - calitem->month_width = calitem->min_month_width; - calitem->month_height = calitem->min_month_height; - calitem->cell_width = calitem->max_digit_width * 2 - + E_CALENDAR_ITEM_MIN_CELL_XPAD; - calitem->cell_height = char_height - + E_CALENDAR_ITEM_MIN_CELL_YPAD; - calitem->month_tpad = 0; - calitem->month_bpad = 0; - calitem->month_lpad = 0; - calitem->month_rpad = 0; - - space = height - calitem->rows * calitem->month_height; - if (space > 0) { - space_per_cal = space / calitem->rows; - calitem->month_height += space_per_cal; - - if (calitem->expand) { - space_per_cell = space_per_cal / E_CALENDAR_ROWS_PER_MONTH; - calitem->cell_height += space_per_cell; - space_per_cal -= space_per_cell * E_CALENDAR_ROWS_PER_MONTH; - } - - calitem->month_tpad = space_per_cal / 2; - calitem->month_bpad = space_per_cal - calitem->month_tpad; - } - - space = width - calitem->cols * calitem->month_width; - if (space > 0) { - space_per_cal = space / calitem->cols; - calitem->month_width += space_per_cal; - space -= space_per_cal * calitem->cols; - - if (calitem->expand) { - space_per_cell = space_per_cal / E_CALENDAR_COLS_PER_MONTH; - calitem->cell_width += space_per_cell; - space_per_cal -= space_per_cell * E_CALENDAR_COLS_PER_MONTH; - } - - calitem->month_lpad = space_per_cal / 2; - calitem->month_rpad = space_per_cal - calitem->month_lpad; - } - - space = MAX (0, space); - calitem->x_offset = space / 2; - - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, - item->x2, item->y2); -} - - -/* - * DRAWING ROUTINES - functions to paint the canvas item. - */ - -static void -e_calendar_item_draw (GnomeCanvasItem *canvas_item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height) -{ - ECalendarItem *calitem; - GtkStyle *style; - GdkFont *font; - GdkGC *base_gc, *bg_gc; - gint char_height, row, col, row_y, bar_height, col_x; - gint xthickness, ythickness; - -#if 0 - g_print ("In e_calendar_item_draw %i,%i %ix%i\n", - x, y, width, height); -#endif - calitem = E_CALENDAR_ITEM (canvas_item); - style = GTK_WIDGET (canvas_item->canvas)->style; - font = calitem->font; - if (!font) - font = style->font; - char_height = font->ascent + font->descent; - xthickness = style->klass->xthickness; - ythickness = style->klass->ythickness; - base_gc = style->base_gc[GTK_STATE_NORMAL]; - bg_gc = style->bg_gc[GTK_STATE_NORMAL]; - - /* Clear the entire background. */ - gdk_draw_rectangle (drawable, base_gc, TRUE, - calitem->x1 - x, calitem->y1 - y, - calitem->x2 - calitem->x1 + 1, - calitem->y2 - calitem->y1 + 1); - - /* Draw the shadow around the entire item. */ - gtk_draw_shadow (style, drawable, - GTK_STATE_NORMAL, GTK_SHADOW_IN, - calitem->x1 - x, calitem->y1 - y, - calitem->x2 - calitem->x1 + 1, - calitem->y2 - calitem->y1 + 1); - - row_y = canvas_item->y1 + ythickness; - bar_height = ythickness * 2 - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME + char_height - + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME; - - for (row = 0; row < calitem->rows; row++) { - /* Draw the background for the title bars and the shadow around - it, and the vertical lines between columns. */ - - gdk_draw_rectangle (drawable, bg_gc, TRUE, - calitem->x1 + xthickness - x, row_y - y, - calitem->x2 - calitem->x1 + 1 - - xthickness * 2, - bar_height); - - gtk_draw_shadow (style, drawable, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - calitem->x1 + xthickness - x, row_y - y, - calitem->x2 - calitem->x1 + 1 - - xthickness * 2, - bar_height); - - - for (col = 0; col < calitem->cols; col++) { - if (col != 0) { - col_x = calitem->x1 + calitem->x_offset - + calitem->month_width * col; - gtk_draw_vline (style, drawable, - GTK_STATE_NORMAL, - row_y + ythickness + 1 - y, - row_y + bar_height - - ythickness - 2 - y, - col_x - 1 - x); - } - - - e_calendar_item_draw_month (calitem, drawable, x, y, - width, height, row, col); - } - - row_y += calitem->month_height; - } -} - - -static void -e_calendar_item_draw_month (ECalendarItem *calitem, - GdkDrawable *drawable, - int x, - int y, - int width, - int height, - int row, - int col) -{ - GnomeCanvasItem *item; - GtkWidget *widget; - GtkStyle *style; - GdkFont *font; - GdkGC *fg_gc; - struct tm tmp_tm; - GdkRectangle clip_rect; - gint char_height, xthickness, ythickness, start_weekday; - gint year, month; - gint month_x, month_y, month_w, month_h; - gint min_x, max_x, text_x, text_y; - gint day, day_index, cells_x, cells_y, min_cell_width, text_width; - gint clip_width, clip_height; - gchar buffer[64]; - -#if 0 - g_print ("In e_calendar_item_draw_month: %i,%i %ix%i row:%i col:%i\n", - x, y, width, height, row, col); -#endif - item = GNOME_CANVAS_ITEM (calitem); - widget = GTK_WIDGET (item->canvas); - style = widget->style; - font = calitem->font; - if (!font) - font = style->font; - char_height = font->ascent + font->descent; - xthickness = style->klass->xthickness; - ythickness = style->klass->ythickness; - fg_gc = style->fg_gc[GTK_STATE_NORMAL]; - - /* Calculate the top-left position of the entire month display. */ - month_x = item->x1 + xthickness + calitem->x_offset - + col * calitem->month_width - x; - month_w = item->x2 - item->x1 - xthickness * 2; - month_w = MIN (month_w, calitem->month_width); - month_y = item->y1 + ythickness + row * calitem->month_height - y; - month_h = item->y2 - item->y1 - ythickness * 2; - month_h = MIN (month_h, calitem->month_height); - - /* Just return if the month is outside the given area. */ - if (month_x >= width || month_x + calitem->month_width <= 0 - || month_y >= height || month_y + calitem->month_height <= 0) - return; - - month = calitem->month + row * calitem->cols + col; - year = calitem->year + month / 12; - month %= 12; - - /* Draw the month name & year, with clipping. Note that the top row - needs extra space around it for the buttons. */ - if (row == 0 && col == 0) - min_x = E_CALENDAR_ITEM_XPAD_BEFORE_MONTH_NAME_WITH_BUTTON; - else - min_x = E_CALENDAR_ITEM_XPAD_BEFORE_MONTH_NAME; - - max_x = month_w; - if (row == 0 && col == calitem->cols - 1) - max_x -= E_CALENDAR_ITEM_XPAD_AFTER_MONTH_NAME_WITH_BUTTON; - else - max_x -= E_CALENDAR_ITEM_XPAD_AFTER_MONTH_NAME; - - text_y = month_y + style->klass->ythickness - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME; - clip_rect.x = month_x + min_x; - clip_rect.x = MAX (0, clip_rect.x); - clip_rect.y = MAX (0, text_y); - - memset (&tmp_tm, 0, sizeof (tmp_tm)); - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = 1; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - start_weekday = (tmp_tm.tm_wday + 6) % 7; - - if (month_x + max_x - clip_rect.x > 0) { - clip_rect.width = month_x + max_x - clip_rect.x; - clip_rect.height = text_y + char_height - clip_rect.y; - gdk_gc_set_clip_rectangle (fg_gc, &clip_rect); - - /* This is a strftime() format. %B = Month name, %Y = Year. */ - strftime (buffer, sizeof (buffer), _("%B %Y"), &tmp_tm); - - /* Ideally we place the text centered in the month, but we - won't go to the left of the minimum x position. */ - text_width = gdk_string_width (font, buffer); - text_x = (calitem->month_width - text_width) / 2; - text_x = MAX (min_x, text_x); - - gdk_draw_string (drawable, font, fg_gc, - month_x + text_x, text_y + font->ascent, buffer); - } - - /* Set the clip rectangle for the main month display. */ - clip_rect.x = MAX (0, month_x); - clip_rect.y = MAX (0, month_y); - clip_width = month_x + month_w - clip_rect.x; - clip_height = month_y + month_h - clip_rect.y; - - if (clip_width <= 0 || clip_height <= 0) - return; - - clip_rect.width = clip_width; - clip_rect.height = clip_height; - - gdk_gc_set_clip_rectangle (fg_gc, &clip_rect); - - - /* Draw the day initials across the top of the month. */ - min_cell_width = calitem->max_digit_width * 2 - + E_CALENDAR_ITEM_MIN_CELL_XPAD; - - cells_x = month_x + E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS + calitem->month_lpad - + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS; - if (calitem->show_week_numbers) - cells_x += calitem->max_week_number_digit_width * 2 - + E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS + 1; - text_x = cells_x + calitem->cell_width - - (calitem->cell_width - min_cell_width) / 2; - text_x -= E_CALENDAR_ITEM_MIN_CELL_XPAD / 2; - text_y = month_y + ythickness * 2 - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME - + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS + calitem->month_tpad; - - cells_y = text_y + char_height - + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1 - + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS; - - text_y += font->ascent; - day_index = calitem->week_start_day; - for (day = 0; day < 7; day++) { - gdk_draw_text (drawable, font, fg_gc, - text_x - calitem->day_widths[day_index], text_y, - &calitem->days[day_index], 1); - text_x += calitem->cell_width; - day_index++; - if (day_index == 7) - day_index = 0; - } - - - /* Draw the horizontal line beneath the day initials. */ - gdk_draw_line (drawable, fg_gc, - cells_x - E_CALENDAR_ITEM_XPAD_BEFORE_CELLS, - cells_y - E_CALENDAR_ITEM_YPAD_ABOVE_CELLS - 1, - cells_x + E_CALENDAR_COLS_PER_MONTH * calitem->cell_width - 1, - cells_y - E_CALENDAR_ITEM_YPAD_ABOVE_CELLS - 1); - - e_calendar_item_draw_day_numbers (calitem, drawable, width, height, - row, col, year, month, start_weekday, - cells_x, cells_y); - - /* Draw the vertical line after the week number. */ - if (calitem->show_week_numbers) { - gdk_draw_line (drawable, fg_gc, - cells_x - E_CALENDAR_ITEM_XPAD_BEFORE_CELLS - 1, - cells_y - E_CALENDAR_ITEM_YPAD_ABOVE_CELLS - 1, - cells_x - E_CALENDAR_ITEM_XPAD_BEFORE_CELLS - 1, - cells_y + E_CALENDAR_ROWS_PER_MONTH * calitem->cell_height - 1); - } - - gdk_gc_set_clip_rectangle (fg_gc, NULL); -} - - -static void -e_calendar_item_draw_day_numbers (ECalendarItem *calitem, - GdkDrawable *drawable, - int width, - int height, - int row, - int col, - int year, - int month, - int start_weekday, - gint cells_x, - gint cells_y) -{ - GnomeCanvasItem *item; - GtkWidget *widget; - GtkStyle *style; - GdkFont *font, *wkfont; - GdkGC *fg_gc; - GdkColor *bg_color, *fg_color, *box_color; - struct tm *today_tm; - time_t t; - gint char_height, min_cell_width, min_cell_height; - gint day_num, drow, dcol, day_x, day_y; - gint text_x, text_y; - gint num_chars, digit; - gint week_num, mon, days_from_week_start; - gint years[3], months[3], days_in_month[3]; - gboolean today, selected, has_focus = FALSE, drop_target = FALSE; - gboolean bold, draw_day, finished = FALSE; - gint today_year, today_month, today_mday, month_offset; - gchar buffer[2]; - gint day_style = 0; - - item = GNOME_CANVAS_ITEM (calitem); - widget = GTK_WIDGET (item->canvas); - style = widget->style; - font = calitem->font; - if (!font) - font = style->font; - wkfont = calitem->week_number_font; - if (!wkfont) - wkfont = font; - fg_gc = style->fg_gc[GTK_STATE_NORMAL]; - char_height = font->ascent + font->descent; - - min_cell_width = calitem->max_digit_width * 2 - + E_CALENDAR_ITEM_MIN_CELL_XPAD; - min_cell_height = char_height + E_CALENDAR_ITEM_MIN_CELL_YPAD; - - /* Calculate the number of days in the previous, current, and next - months. */ - years[0] = years[1] = years[2] = year; - months[0] = month - 1; - months[1] = month; - months[2] = month + 1; - if (months[0] == -1) { - months[0] = 11; - years[0]--; - } - if (months[2] == 12) { - months[2] = 0; - years[2]++; - } - - days_in_month[0] = DAYS_IN_MONTH (years[0], months[0]); - days_in_month[1] = DAYS_IN_MONTH (years[1], months[1]); - days_in_month[2] = DAYS_IN_MONTH (years[2], months[2]); - - /* Mon 0 is the previous month, which we may show the end of. Mon 1 is - the current month, and mon 2 is the next month. */ - mon = 0; - - month_offset = row * calitem->cols + col - 1; - day_num = days_in_month[0]; - days_from_week_start = (start_weekday + 7 - calitem->week_start_day) - % 7; - /* For the top-left month we show the end of the previous month, and - if the new month starts on the first day of the week we show a - complete week from the previous month. */ - if (days_from_week_start == 0) { - if (row == 0 && col == 0) { - day_num -= 6; - } else { - mon++; - month_offset++; - day_num = 1; - } - } else { - day_num -= days_from_week_start - 1; - } - - /* Get today's date, so we can highlight it. */ - t = time (NULL); - today_tm = localtime (&t); - today_year = today_tm->tm_year + 1900; - today_month = today_tm->tm_mon; - today_mday = today_tm->tm_mday; - - /* We usually skip the last days of the previous month (mon = 0), - except for the top-left month displayed. */ - draw_day = (mon == 1 || (row == 0 && col == 0)); - - for (drow = 0; drow < 6; drow++) { - /* Draw the week number. */ - if (calitem->show_week_numbers) { - week_num = e_calendar_item_get_week_number (calitem, - day_num, - months[mon], - years[mon]); - - text_x = cells_x - E_CALENDAR_ITEM_XPAD_BEFORE_CELLS - 1 - - E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS; - text_y = cells_y + drow * calitem->cell_height + - + (calitem->cell_height - min_cell_height + 1) / 2; - - num_chars = 0; - if (week_num >= 10) { - digit = week_num / 10; - text_x -= calitem->week_number_digit_widths[digit]; - buffer[num_chars++] = digit + '0'; - } - - digit = week_num % 10; - text_x -= calitem->week_number_digit_widths[digit]; - buffer[num_chars++] = digit + '0'; - - gdk_gc_set_foreground (fg_gc, - &style->fg[GTK_STATE_NORMAL]); - gdk_draw_text (drawable, wkfont, fg_gc, - text_x, text_y + font->ascent, - buffer, num_chars); - } - - for (dcol = 0; dcol < 7; dcol++) { - if (draw_day) { - day_x = cells_x + dcol * calitem->cell_width; - day_y = cells_y + drow * calitem->cell_height; - - today = years[mon] == today_year - && months[mon] == today_month - && day_num == today_mday; - - selected = calitem->selection_set - && (calitem->selection_start_month_offset < month_offset - || (calitem->selection_start_month_offset == month_offset - && calitem->selection_start_day <= day_num)) - && (calitem->selection_end_month_offset > month_offset - || (calitem->selection_end_month_offset == month_offset - && calitem->selection_end_day >= day_num)); - - if (calitem->styles) - day_style = calitem->styles[(month_offset + 1) * 32 + day_num]; - - /* Get the colors & style to use for the day.*/ - if (calitem->style_callback) - (*calitem->style_callback) - (calitem, - years[mon], - months[mon], - day_num, - day_style, - today, - mon != 1, - selected, - has_focus, - drop_target, - &bg_color, - &fg_color, - &box_color, - &bold, - calitem->style_callback_data); - else - e_calendar_item_get_day_style - (calitem, - years[mon], - months[mon], - day_num, - day_style, - today, - mon != 1, - selected, - has_focus, - drop_target, - &bg_color, - &fg_color, - &box_color, - &bold); - - /* Draw the background, if set. */ - if (bg_color) { - gdk_gc_set_foreground (fg_gc, bg_color); - gdk_draw_rectangle (drawable, fg_gc, - TRUE, - day_x, day_y, - calitem->cell_width, - calitem->cell_height); - } - - /* Draw the box, if set. */ - if (box_color) { - gdk_gc_set_foreground (fg_gc, box_color); - gdk_draw_rectangle (drawable, fg_gc, - FALSE, - day_x, day_y, - calitem->cell_width - 1, - calitem->cell_height - 1); - } - - /* Draw the 1- or 2-digit day number. */ - day_x += calitem->cell_width - (calitem->cell_width - min_cell_width) / 2; - day_x -= E_CALENDAR_ITEM_MIN_CELL_XPAD / 2; - day_y += (calitem->cell_height - min_cell_height + 1) / 2; - day_y += E_CALENDAR_ITEM_MIN_CELL_YPAD / 2; - - num_chars = 0; - if (day_num >= 10) { - digit = day_num / 10; - day_x -= calitem->digit_widths[digit]; - buffer[num_chars++] = digit + '0'; - } - - digit = day_num % 10; - day_x -= calitem->digit_widths[digit]; - buffer[num_chars++] = digit + '0'; - - if (fg_color) { - gdk_gc_set_foreground (fg_gc, - fg_color); - } else { - gdk_gc_set_foreground (fg_gc, - &style->fg[GTK_STATE_NORMAL]); - } - - gdk_draw_text (drawable, font, fg_gc, - day_x, - day_y + font->ascent, - buffer, num_chars); - /* We use a stupid technique for bold. Just - draw it again 1 pixel to the left. */ - if (bold) - gdk_draw_text (drawable, font, fg_gc, - day_x - 1, - day_y + font->ascent, - buffer, num_chars); - } - - /* See if we've reached the end of a month. */ - if (day_num == days_in_month[mon]) { - month_offset++; - mon++; - /* We only draw the start of the next month - for the bottom-right month displayed. */ - if (mon == 2 && (row != calitem->rows - 1 - || col != calitem->cols - 1)) { - /* Set a flag so we exit the loop. */ - finished = TRUE; - break; - } - day_num = 1; - draw_day = TRUE; - } else { - day_num++; - } - } - - /* Exit the loop if the flag is set. */ - if (finished) - break; - } - - /* Reset the foreground color. */ - gdk_gc_set_foreground (fg_gc, &style->fg[GTK_STATE_NORMAL]); -} - - -static gint -e_calendar_item_get_week_number (ECalendarItem *calitem, - gint day, - gint month, - gint year) -{ - GDate tmp_date; - gint weekday, yearday, offset, week_num; - - /* FIXME: check what happens at year boundaries. */ - - g_date_clear (&tmp_date, 1); - g_date_set_dmy (&tmp_date, day, month + 1, year); - - /* This results in a value of 0 (Monday) - 6 (Sunday). */ - weekday = g_date_weekday (&tmp_date) - 1; - - /* Calculate the offset from the start of the week. */ - offset = (calitem->week_start_day + 7 - weekday) % 7; - - /* Calculate the day of the year, from 0 to 365. */ - yearday = g_date_day_of_year (&tmp_date) - 1; - - /* If the week starts on or after 29th December, it is week 1 of the - next year, since there are 4 days in the next year. */ - g_date_subtract_days (&tmp_date, offset); - if (g_date_month (&tmp_date) == 12 && g_date_day (&tmp_date) >= 29) - return 1; - - /* Calculate the week number, from 0. */ - week_num = (yearday - offset) / 7; - - /* If the first week starts on or after Jan 5th, then we need to add - 1 since the previous week will really be the first week. */ - if ((yearday - offset) % 7 >= 4) - week_num++; - - /* Add 1 so week numbers are from 1 to 53. */ - return week_num + 1; -} - - - -/* This is supposed to return the nearest item the the point and the distance. - Since we are the only item we just return ourself and 0 for the distance. - This is needed so that we get button/motion events. */ -static double -e_calendar_item_point (GnomeCanvasItem *item, double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item) -{ - *actual_item = item; - return 0.0; -} - - -static gint -e_calendar_item_event (GnomeCanvasItem *item, GdkEvent *event) -{ - ECalendarItem *calitem; - - calitem = E_CALENDAR_ITEM (item); - - switch (event->type) { - case GDK_BUTTON_PRESS: - return e_calendar_item_button_press (calitem, event); - case GDK_BUTTON_RELEASE: - return e_calendar_item_button_release (calitem, event); - case GDK_MOTION_NOTIFY: - return e_calendar_item_motion (calitem, event); - default: - break; - } - - return FALSE; -} - - - -/* This checks if any fonts have changed, and if so it recalculates the - text sizes and the minimum month size. */ -static void -e_calendar_item_recalc_sizes (ECalendarItem *calitem) -{ - GnomeCanvasItem *canvas_item; - GtkStyle *style; - GdkFont *font, *wkfont; - gchar *digits = "0123456789"; - gint day, digit, max_digit_width, max_week_number_digit_width; - gint char_height, width, min_cell_width, min_cell_height; - - canvas_item = GNOME_CANVAS_ITEM (calitem); - style = GTK_WIDGET (canvas_item->canvas)->style; - - if (!style) - return; - - font = calitem->font; - if (!font) - font = style->font; - wkfont = calitem->week_number_font; - if (!wkfont) - wkfont = font; - - g_return_if_fail (font != NULL); - g_return_if_fail (wkfont != NULL); - - char_height = font->ascent + font->descent; - - /* If both fonts are the same, just return. */ - if (font != calitem->old_font - || wkfont != calitem->old_week_number_font) { - if (calitem->old_font) - gdk_font_unref (calitem->old_font); - calitem->old_font = font; - gdk_font_ref (font); - - if (calitem->old_week_number_font) - gdk_font_unref (calitem->old_week_number_font); - calitem->old_week_number_font = wkfont; - gdk_font_ref (wkfont); - - for (day = 0; day < 7; day++) - calitem->day_widths[day] = gdk_char_width (font, calitem->days[day]); - - max_digit_width = 0; - max_week_number_digit_width = 0; - for (digit = 0; digit < 10; digit++) { - width = gdk_char_width (font, digits[digit]); - calitem->digit_widths[digit] = width; - max_digit_width = MAX (max_digit_width, width); - - if (wkfont) { - width = gdk_char_width (wkfont, digits[digit]); - calitem->week_number_digit_widths[digit] = width; - max_week_number_digit_width = MAX (max_week_number_digit_width, width); - } else { - calitem->week_number_digit_widths[digit] = width; - max_week_number_digit_width = max_digit_width; - } - } - calitem->max_digit_width = max_digit_width; - calitem->max_week_number_digit_width = max_week_number_digit_width; - } - - min_cell_width = calitem->max_digit_width * 2 - + E_CALENDAR_ITEM_MIN_CELL_XPAD; - min_cell_height = char_height + E_CALENDAR_ITEM_MIN_CELL_YPAD; - - calitem->min_month_width = E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS - + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS + min_cell_width * 7 - + E_CALENDAR_ITEM_XPAD_AFTER_CELLS; - if (calitem->show_week_numbers) { - calitem->min_month_width += calitem->max_week_number_digit_width * 2 - + E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS + 1; - } - - calitem->min_month_height = style->klass->ythickness * 2 - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME + char_height - + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME + 1 - + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1 - + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS + min_cell_height * 6 - + E_CALENDAR_ITEM_YPAD_BELOW_CELLS; -} - - -static void -e_calendar_item_get_day_style (ECalendarItem *calitem, - gint year, - gint month, - gint day, - gint day_style, - gboolean today, - gboolean prev_or_next_month, - gboolean selected, - gboolean has_focus, - gboolean drop_target, - GdkColor **bg_color, - GdkColor **fg_color, - GdkColor **box_color, - gboolean *bold) -{ - *bg_color = NULL; - *fg_color = NULL; - *box_color = NULL; - *bold = FALSE; - - if (day_style == 1) - *bold = TRUE; - - if (today) - *box_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_TODAY_BOX]; - - if (prev_or_next_month) - *fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG]; - - if (selected) { - *fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG]; - *bg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG]; - } -} - - - -static gboolean -e_calendar_item_button_press (ECalendarItem *calitem, - GdkEvent *event) -{ - gint month_offset, day; - gboolean all_week, round_up_end = FALSE, round_down_start = FALSE; - - if (event->button.button == 4) - e_calendar_item_set_first_month (calitem, calitem->year, - calitem->month - 1); - else if (event->button.button == 5) - e_calendar_item_set_first_month (calitem, calitem->year, - calitem->month + 1); - - if (!e_calendar_item_convert_position_to_day (calitem, - event->button.x, - event->button.y, - TRUE, - &month_offset, &day, - &all_week)) - return FALSE; - - if (event->button.button == 3 && day == -1 - && e_calendar_item_get_display_popup (calitem)) { - e_calendar_item_show_popup_menu (calitem, - (GdkEventButton*) event, - month_offset); - return TRUE; - } - - if (event->button.button != 1 || day == -1) - return FALSE; - - if (calitem->max_days_selected < 1) - return TRUE; - - if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (calitem), - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - NULL, event->button.time) != 0) - return FALSE; - - calitem->selection_set = TRUE; - calitem->selection_start_month_offset = month_offset; - calitem->selection_start_day = day; - calitem->selection_end_month_offset = month_offset; - calitem->selection_end_day = day; - - calitem->selection_real_start_month_offset = month_offset; - calitem->selection_real_start_day = day; - - calitem->selection_from_full_week = FALSE; - calitem->selecting = TRUE; - calitem->selection_dragging_end = TRUE; - - if (all_week) { - calitem->selection_from_full_week = TRUE; - round_up_end = TRUE; - } - - if (calitem->days_to_start_week_selection == 1) { - round_down_start = TRUE; - round_up_end = TRUE; - } - - /* Don't round up or down if we can't select a week or more. */ - if (calitem->max_days_selected < 7) { - round_down_start = FALSE; - round_up_end = FALSE; - } - - if (round_up_end) - e_calendar_item_round_up_selection (calitem, &calitem->selection_end_month_offset, &calitem->selection_end_day); - - if (round_down_start) - e_calendar_item_round_down_selection (calitem, &calitem->selection_start_month_offset, &calitem->selection_start_day); - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); - - return TRUE; -} - - -static gboolean -e_calendar_item_button_release (ECalendarItem *calitem, - GdkEvent *event) -{ - if (!calitem->selecting) - return FALSE; - - gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (calitem), - event->button.time); - - calitem->selecting = FALSE; - - /* If the user selects the grayed dates before the first month or - after the last month, we move backwards or forwards one month. - The set_month() call should take care of updating the selection. */ - if (calitem->selection_end_month_offset == -1) - e_calendar_item_set_first_month (calitem, calitem->year, - calitem->month - 1); - else if (calitem->selection_start_month_offset == calitem->rows * calitem->cols) - e_calendar_item_set_first_month (calitem, calitem->year, - calitem->month + 1); - - calitem->selection_changed = TRUE; - e_calendar_item_queue_signal_emission (calitem); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); - - return FALSE; -} - - -static gboolean -e_calendar_item_motion (ECalendarItem *calitem, - GdkEvent *event) -{ - gint start_month, start_day, end_month, end_day, month_offset, day; - gint tmp_month, tmp_day, days_in_selection; - gboolean all_week, round_up_end = FALSE, round_down_start = FALSE; - - if (!calitem->selecting) - return FALSE; - - if (!e_calendar_item_convert_position_to_day (calitem, - event->button.x, - event->button.y, - TRUE, - &month_offset, &day, - &all_week)) - return FALSE; - - if (day == -1) - return FALSE; - - if (calitem->selection_dragging_end) { - start_month = calitem->selection_real_start_month_offset; - start_day = calitem->selection_real_start_day; - end_month = month_offset; - end_day = day; - } else { - start_month = month_offset; - start_day = day; - end_month = calitem->selection_real_start_month_offset; - end_day = calitem->selection_real_start_day; - } - - if (start_month > end_month || (start_month == end_month - && start_day > end_day)) { - tmp_month = start_month; - tmp_day = start_day; - start_month = end_month; - start_day = end_day; - end_month = tmp_month; - end_day = tmp_day; - - calitem->selection_dragging_end = !calitem->selection_dragging_end; - } - - if (calitem->days_to_start_week_selection > 0) { - days_in_selection = e_calendar_item_get_inclusive_days (calitem, start_month, start_day, end_month, end_day); - if (days_in_selection >= calitem->days_to_start_week_selection) { - round_down_start = TRUE; - round_up_end = TRUE; - } - } - - /* If we are over a week number and we are dragging the end of the - selection, we round up to the end of this week. */ - if (all_week && calitem->selection_dragging_end) - round_up_end = TRUE; - - /* If the selection was started from a week number and we are dragging - the start of the selection, we need to round up the end to include - all of the original week selected. */ - if (calitem->selection_from_full_week - && !calitem->selection_dragging_end) - round_up_end = TRUE; - - /* Don't round up or down if we can't select a week or more. */ - if (calitem->max_days_selected < 7) { - round_down_start = FALSE; - round_up_end = FALSE; - } - - if (round_up_end) - e_calendar_item_round_up_selection (calitem, &end_month, - &end_day); - if (round_down_start) - e_calendar_item_round_down_selection (calitem, &start_month, - &start_day); - - - /* Check we don't go over the maximum number of days to select. */ - if (calitem->selection_dragging_end) { - e_calendar_item_check_selection_end (calitem, - start_month, - start_day, - &end_month, - &end_day); - } else { - e_calendar_item_check_selection_start (calitem, - &start_month, - &start_day, - end_month, - end_day); - } - - if (start_month == calitem->selection_start_month_offset - && start_day == calitem->selection_start_day - && end_month == calitem->selection_end_month_offset - && end_day == calitem->selection_end_day) - return FALSE; - - calitem->selection_start_month_offset = start_month; - calitem->selection_start_day = start_day; - calitem->selection_end_month_offset = end_month; - calitem->selection_end_day = end_day; - - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); - - return TRUE; -} - - -static void -e_calendar_item_check_selection_end (ECalendarItem *calitem, - gint start_month, - gint start_day, - gint *end_month, - gint *end_day) -{ - gint year, month, max_month, max_day, days_in_month; - - if (calitem->max_days_selected <= 0) - return; - - year = calitem->year; - month = calitem->month + start_month; - e_calendar_item_normalize_date (calitem, &year, &month); - - max_month = start_month; - max_day = start_day + calitem->max_days_selected - 1; - - for (;;) { - days_in_month = DAYS_IN_MONTH (year, month); - if (max_day <= days_in_month) - break; - max_month++; - month++; - if (month == 12) { - year++; - month = 0; - } - max_day -= days_in_month; - } - - if (*end_month > max_month) { - *end_month = max_month; - *end_day = max_day; - } else if (*end_month == max_month && *end_day > max_day) { - *end_day = max_day; - } -} - - -static void -e_calendar_item_check_selection_start (ECalendarItem *calitem, - gint *start_month, - gint *start_day, - gint end_month, - gint end_day) -{ - gint year, month, min_month, min_day, days_in_month; - - if (calitem->max_days_selected <= 0) - return; - - year = calitem->year; - month = calitem->month + end_month; - e_calendar_item_normalize_date (calitem, &year, &month); - - min_month = end_month; - min_day = end_day - calitem->max_days_selected + 1; - - while (min_day <= 0) { - min_month--; - month--; - if (month == -1) { - year--; - month = 11; - } - days_in_month = DAYS_IN_MONTH (year, month); - min_day += days_in_month; - } - - if (*start_month < min_month) { - *start_month = min_month; - *start_day = min_day; - } else if (*start_month == min_month && *start_day < min_day) { - *start_day = min_day; - } -} - - -/* Converts a position within the item to a month & day. - The month returned is 0 for the top-left month displayed. - If the position is over the month heading -1 is returned for the day. - If the position is over a week number the first day of the week is returned - and entire_week is set to TRUE. - It returns FALSE if the position is completely outside all months. */ -static gboolean -e_calendar_item_convert_position_to_day (ECalendarItem *calitem, - gint event_x, - gint event_y, - gboolean round_empty_positions, - gint *month_offset, - gint *day, - gboolean *entire_week) -{ - GnomeCanvasItem *item; - GtkWidget *widget; - GtkStyle *style; - gint xthickness, ythickness, char_height; - gint x, y, row, col, cells_x, cells_y, day_row, day_col; - gint first_day_offset, days_in_month, days_in_prev_month; - gint week_num_x1, week_num_x2; - - item = GNOME_CANVAS_ITEM (calitem); - widget = GTK_WIDGET (item->canvas); - style = widget->style; - char_height = style->font->ascent + style->font->descent; - xthickness = style->klass->xthickness; - ythickness = style->klass->ythickness; - - *entire_week = FALSE; - - x = event_x - xthickness - calitem->x_offset; - y = event_y - ythickness; - - if (x < 0 || y < 0) - return FALSE; - - row = y / calitem->month_height; - col = x / calitem->month_width; - - if (row >= calitem->rows || col >= calitem->cols) - return FALSE; - - *month_offset = row * calitem->cols + col; - - x = x % calitem->month_width; - y = y % calitem->month_height; - - if (y < ythickness * 2 + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME) { - *day = -1; - return TRUE; - } - - cells_y = ythickness * 2 + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME - + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS + calitem->month_tpad - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1 - + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS; - y -= cells_y; - if (y < 0) - return FALSE; - day_row = y / calitem->cell_height; - if (day_row >= E_CALENDAR_ROWS_PER_MONTH) - return FALSE; - - week_num_x1 = E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS + calitem->month_lpad; - - if (calitem->show_week_numbers) { - week_num_x2 = week_num_x1 - + calitem->max_week_number_digit_width * 2; - if (x >= week_num_x1 && x < week_num_x2) - *entire_week = TRUE; - cells_x = week_num_x2 + E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS + 1; - } else { - cells_x = week_num_x1; - } - - if (*entire_week) { - day_col = 0; - } else { - cells_x += E_CALENDAR_ITEM_XPAD_BEFORE_CELLS; - x -= cells_x; - if (x < 0) - return FALSE; - day_col = x / calitem->cell_width; - if (day_col >= E_CALENDAR_COLS_PER_MONTH) - return FALSE; - } - - *day = day_row * E_CALENDAR_COLS_PER_MONTH + day_col; - - e_calendar_item_get_month_info (calitem, row, col, &first_day_offset, - &days_in_month, &days_in_prev_month); - if (*day < first_day_offset) { - if (*entire_week || (row == 0 && col == 0)) { - (*month_offset)--; - *day = days_in_prev_month + 1 - first_day_offset - + *day; - return TRUE; - } else if (round_empty_positions) { - *day = first_day_offset; - } else { - return FALSE; - } - } - - *day -= first_day_offset - 1; - - if (*day > days_in_month) { - if (row == calitem->rows - 1 && col == calitem->cols - 1) { - (*month_offset)++; - *day -= days_in_month; - return TRUE; - } else if (round_empty_positions) { - *day = days_in_month; - } else { - return FALSE; - } - } - - return TRUE; -} - - -static void -e_calendar_item_get_month_info (ECalendarItem *calitem, - gint row, - gint col, - gint *first_day_offset, - gint *days_in_month, - gint *days_in_prev_month) -{ - gint year, month, start_weekday, first_day_of_month; - struct tm tmp_tm = { 0 }; - - month = calitem->month + row * calitem->cols + col; - year = calitem->year + month / 12; - month = month % 12; - - *days_in_month = DAYS_IN_MONTH (year, month); - if (month == 0) - *days_in_prev_month = DAYS_IN_MONTH (year - 1, 11); - else - *days_in_prev_month = DAYS_IN_MONTH (year, month - 1); - - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = 1; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - - /* Convert to 0 (Monday) to 6 (Sunday). */ - start_weekday = (tmp_tm.tm_wday + 6) % 7; - - first_day_of_month = (start_weekday + 7 - calitem->week_start_day) % 7; - - if (row == 0 && col == 0 && first_day_of_month == 0) - *first_day_offset = 7; - else - *first_day_offset = first_day_of_month; -} - - -void -e_calendar_item_get_first_month(ECalendarItem *calitem, - gint *year, - gint *month) -{ - *year = calitem->year; - *month = calitem->month; -} - - -/* This also handles values of month < 0 or > 11 by updating the year. */ -void -e_calendar_item_set_first_month(ECalendarItem *calitem, - gint year, - gint month) -{ - gint new_year, new_month, months_diff, num_months; - gint old_days_in_selection, new_days_in_selection; - - new_year = year; - new_month = month; - e_calendar_item_normalize_date (calitem, &new_year, &new_month); - - if (calitem->year == new_year && calitem->month == new_month) - return; - - /* Update the selection. */ - num_months = calitem->rows * calitem->cols; - months_diff = (new_year - calitem->year) * 12 - + new_month - calitem->month; - - if (calitem->selection_set) { - if (!calitem->move_selection_when_moving - || (calitem->selection_start_month_offset - months_diff >= 0 - && calitem->selection_end_month_offset - months_diff < num_months)) { - calitem->selection_start_month_offset -= months_diff; - calitem->selection_end_month_offset -= months_diff; - calitem->selection_real_start_month_offset -= months_diff; - - calitem->year = new_year; - calitem->month = new_month; - } else { - old_days_in_selection = e_calendar_item_get_inclusive_days (calitem, calitem->selection_start_month_offset, calitem->selection_start_day, calitem->selection_end_month_offset, calitem->selection_end_day); - - /* Make sure the selection will be displayed. */ - if (calitem->selection_start_month_offset < 0 - || calitem->selection_start_month_offset >= num_months) { - calitem->selection_end_month_offset -= calitem->selection_start_month_offset; - calitem->selection_start_month_offset = 0; - } - - /* We want to ensure that the same number of days are - selected after we have moved the selection. */ - calitem->year = new_year; - calitem->month = new_month; - - e_calendar_item_ensure_valid_day (calitem, &calitem->selection_start_month_offset, &calitem->selection_start_day); - e_calendar_item_ensure_valid_day (calitem, &calitem->selection_end_month_offset, &calitem->selection_end_day); - - if (calitem->round_selection_when_moving) { - e_calendar_item_round_down_selection (calitem, &calitem->selection_start_month_offset, &calitem->selection_start_day); - } - - new_days_in_selection = e_calendar_item_get_inclusive_days (calitem, calitem->selection_start_month_offset, calitem->selection_start_day, calitem->selection_end_month_offset, calitem->selection_end_day); - - if (old_days_in_selection != new_days_in_selection) - e_calendar_item_add_days_to_selection (calitem, old_days_in_selection - new_days_in_selection); - - /* Flag that we need to emit the "selection_changed" - signal. We don't want to emit it here since setting - the "year" and "month" args would result in 2 - signals emitted. */ - calitem->selection_changed = TRUE; - } - } else { - calitem->year = new_year; - calitem->month = new_month; - } - - e_calendar_item_date_range_changed (calitem); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); -} - -/* Get the maximum number of days selectable */ -gint -e_calendar_item_get_max_days_sel (ECalendarItem *calitem) -{ - return calitem->max_days_selected; -} - - -/* Set the maximum number of days selectable */ -void -e_calendar_item_set_max_days_sel (ECalendarItem *calitem, - gint days) -{ - calitem->max_days_selected = MAX (0, days); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); -} - - -/* Get the maximum number of days before whole weeks are selected */ -gint -e_calendar_item_get_days_start_week_sel(ECalendarItem *calitem) -{ - return calitem->days_to_start_week_selection; -} - - -/* Set the maximum number of days before whole weeks are selected */ -void -e_calendar_item_set_days_start_week_sel(ECalendarItem *calitem, - gint days) -{ - calitem->days_to_start_week_selection = days; -} - -gboolean -e_calendar_item_get_display_popup (ECalendarItem *calitem) -{ - return calitem->display_popup; -} - - -void -e_calendar_item_set_display_popup (ECalendarItem *calitem, - gboolean display) -{ - calitem->display_popup = display; -} - - -/* This will make sure that the given year & month are valid, i.e. if month - is < 0 or > 11 the year and month will be updated accordingly. */ -static void -e_calendar_item_normalize_date (ECalendarItem *calitem, - gint *year, - gint *month) -{ - if (*month >= 0) { - *year += *month / 12; - *month = *month % 12; - } else { - *year += *month / 12 - 1; - *month = *month % 12; - if (*month != 0) - *month += 12; - } -} - - -/* Adds or subtracts days from the selection. It is used when we switch months - and the selection extends past the end of a month but we want to keep the - number of days selected the same. days should not be more than 30. */ -static void -e_calendar_item_add_days_to_selection (ECalendarItem *calitem, - gint days) -{ - gint year, month, days_in_month; - - year = calitem->year; - month = calitem->month + calitem->selection_end_month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - - calitem->selection_end_day += days; - if (calitem->selection_end_day <= 0) { - month--; - e_calendar_item_normalize_date (calitem, &year, &month); - calitem->selection_end_month_offset--; - calitem->selection_end_day += DAYS_IN_MONTH (year, month); - } else { - days_in_month = DAYS_IN_MONTH (year, month); - if (calitem->selection_end_day > days_in_month) { - calitem->selection_end_month_offset++; - calitem->selection_end_day -= days_in_month; - } - } -} - - -/* Gets the range of dates actually shown. Months are 0 to 11. - This also includes the last days of the previous month and the first days - of the following month, which are normally shown in gray. - It returns FALSE if no dates are currently shown. */ -gboolean -e_calendar_item_get_date_range (ECalendarItem *calitem, - gint *start_year, - gint *start_month, - gint *start_day, - gint *end_year, - gint *end_month, - gint *end_day) -{ - gint first_day_offset, days_in_month, days_in_prev_month; - - if (calitem->rows == 0 || calitem->cols == 0) - return FALSE; - - /* Calculate the first day shown. This will be one of the greyed-out - days before the first full month begins. */ - e_calendar_item_get_month_info (calitem, 0, 0, &first_day_offset, - &days_in_month, &days_in_prev_month); - *start_year = calitem->year; - *start_month = calitem->month - 1; - if (*start_month == -1) { - (*start_year)--; - *start_month = 11; - } - *start_day = days_in_prev_month + 1 - first_day_offset; - - - /* Calculate the last day shown. This will be one of the greyed-out - days after the last full month ends. */ - e_calendar_item_get_month_info (calitem, calitem->rows - 1, - calitem->cols - 1, &first_day_offset, - &days_in_month, &days_in_prev_month); - *end_month = calitem->month + calitem->rows * calitem->cols; - *end_year = calitem->year + *end_month / 12; - *end_month %= 12; - *end_day = E_CALENDAR_ROWS_PER_MONTH * E_CALENDAR_COLS_PER_MONTH - - first_day_offset - days_in_month; - - return TRUE; -} - - -/* Simple way to mark days so they appear bold. - A more flexible interface may be added later. */ -void -e_calendar_item_clear_marks (ECalendarItem *calitem) -{ - GnomeCanvasItem *item; - - item = GNOME_CANVAS_ITEM (calitem); - - g_free (calitem->styles); - calitem->styles = NULL; - - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, - item->x2, item->y2); -} - - -void -e_calendar_item_mark_day (ECalendarItem *calitem, - gint year, - gint month, - gint day, - guint8 day_style) -{ - gint month_offset; - - month_offset = (year - calitem->year) * 12 + month - calitem->month; - if (month_offset < -1 || month_offset > calitem->rows * calitem->cols) - return; - - if (!calitem->styles) - calitem->styles = g_new0 (guint8, (calitem->rows * calitem->cols + 2) * 32); - - calitem->styles[(month_offset + 1) * 32 + day] = day_style; -} - - -void -e_calendar_item_mark_days (ECalendarItem *calitem, - gint start_year, - gint start_month, - gint start_day, - gint end_year, - gint end_month, - gint end_day, - guint8 day_style) -{ - gint month_offset, end_month_offset, day; - - month_offset = (start_year - calitem->year) * 12 + start_month - - calitem->month; - day = start_day; - if (month_offset > calitem->rows * calitem->cols) - return; - if (month_offset < -1) { - month_offset = -1; - day = 1; - } - - end_month_offset = (end_year - calitem->year) * 12 + end_month - - calitem->month; - if (end_month_offset < -1) - return; - if (end_month_offset > calitem->rows * calitem->cols) { - end_month_offset = calitem->rows * calitem->cols; - end_day = 31; - } - - if (month_offset > end_month_offset) - return; - - if (!calitem->styles) - calitem->styles = g_new0 (guint8, (calitem->rows * calitem->cols + 2) * 32); - - for (;;) { - if (month_offset == end_month_offset && day > end_day) - break; - - calitem->styles[(month_offset + 1) * 32 + day] = day_style; - - day++; - if (day == 32) { - month_offset++; - day = 1; - if (month_offset > end_month_offset) - break; - } - } -} - - -/* Rounds up the given day to the end of the week. */ -static void -e_calendar_item_round_up_selection (ECalendarItem *calitem, - gint *month_offset, - gint *day) -{ - gint year, month, weekday, days, days_in_month; - struct tm tmp_tm = { 0 }; - - year = calitem->year; - month = calitem->month + *month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = *day; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - - /* Convert to 0 (Monday) to 6 (Sunday). */ - weekday = (tmp_tm.tm_wday + 6) % 7; - - /* Calculate how many days to the end of the row. */ - days = (calitem->week_start_day + 6 - weekday) % 7; - - *day += days; - days_in_month = DAYS_IN_MONTH (year, month); - if (*day > days_in_month) { - (*month_offset)++; - *day -= days_in_month; - } -} - - -/* Rounds down the given day to the start of the week. */ -static void -e_calendar_item_round_down_selection (ECalendarItem *calitem, - gint *month_offset, - gint *day) -{ - gint year, month, weekday, days, days_in_month; - struct tm tmp_tm = { 0 }; - - year = calitem->year; - month = calitem->month + *month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = *day; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - - /* Convert to 0 (Monday) to 6 (Sunday). */ - weekday = (tmp_tm.tm_wday + 6) % 7; - - /* Calculate how many days to the start of the row. */ - days = (weekday + 7 - calitem->week_start_day) % 7; - - *day -= days; - if (*day <= 0) { - month--; - if (month == -1) { - year--; - month = 11; - } - days_in_month = DAYS_IN_MONTH (year, month); - (*month_offset)--; - *day += days_in_month; - } -} - - -static gint -e_calendar_item_get_inclusive_days (ECalendarItem *calitem, - gint start_month_offset, - gint start_day, - gint end_month_offset, - gint end_day) -{ - gint start_year, start_month, end_year, end_month, days = 0; - - start_year = calitem->year; - start_month = calitem->month + start_month_offset; - e_calendar_item_normalize_date (calitem, &start_year, &start_month); - - end_year = calitem->year; - end_month = calitem->month + end_month_offset; - e_calendar_item_normalize_date (calitem, &end_year, &end_month); - - while (start_year < end_year || start_month < end_month) { - days += DAYS_IN_MONTH (start_year, start_month); - start_month++; - if (start_month == 12) { - start_year++; - start_month = 0; - } - } - - days += end_day - start_day + 1; - - return days; -} - - -/* If the day is off the end of the month it is set to the last day of the - month. */ -static void -e_calendar_item_ensure_valid_day (ECalendarItem *calitem, - gint *month_offset, - gint *day) -{ - gint year, month, days_in_month; - - year = calitem->year; - month = calitem->month + *month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - - days_in_month = DAYS_IN_MONTH (year, month); - if (*day > days_in_month) - *day = days_in_month; -} - - -gboolean -e_calendar_item_get_selection (ECalendarItem *calitem, - GDate *start_date, - GDate *end_date) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - - g_date_clear (start_date, 1); - g_date_clear (end_date, 1); - - if (!calitem->selection_set) - return FALSE; - - start_year = calitem->year; - start_month = calitem->month + calitem->selection_start_month_offset; - e_calendar_item_normalize_date (calitem, &start_year, &start_month); - start_day = calitem->selection_start_day; - - end_year = calitem->year; - end_month = calitem->month + calitem->selection_end_month_offset; - e_calendar_item_normalize_date (calitem, &end_year, &end_month); - end_day = calitem->selection_end_day; - - g_date_set_dmy (start_date, start_day, start_month + 1, start_year); - g_date_set_dmy (end_date, end_day, end_month + 1, end_year); - - return TRUE; -} - - -void -e_calendar_item_set_selection (ECalendarItem *calitem, - GDate *start_date, - GDate *end_date) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - gint new_start_month_offset, new_start_day; - gint new_end_month_offset, new_end_day; - gboolean need_update; - - g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); - - /* If the user is in the middle of a selection, we must abort it. */ - if (calitem->selecting) { - gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (calitem), - GDK_CURRENT_TIME); - calitem->selecting = FALSE; - } - - /* If start_date is NULL, we clear the selection without changing the - month shown. */ - if (start_date == NULL) { - calitem->selection_set = FALSE; - calitem->selection_changed = TRUE; - e_calendar_item_queue_signal_emission (calitem); - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); - return; - } - - if (end_date == NULL) - end_date = start_date; - - g_return_if_fail (g_date_compare (start_date, end_date) <= 0); - - start_year = g_date_year (start_date); - start_month = g_date_month (start_date) - 1; - start_day = g_date_day (start_date); - end_year = g_date_year (end_date); - end_month = g_date_month (end_date) - 1; - end_day = g_date_day (end_date); - - need_update = e_calendar_item_ensure_days_visible (calitem, - start_year, - start_month, - start_day, - end_year, - end_month, - end_day); - - new_start_month_offset = (start_year - calitem->year) * 12 - + start_month - calitem->month; - new_start_day = start_day; - - /* This may go outside the visible months, but we don't care. */ - new_end_month_offset = (end_year - calitem->year) * 12 - + end_month - calitem->month; - new_end_day = end_day; - - - if (!calitem->selection_set - || calitem->selection_start_month_offset != new_start_month_offset - || calitem->selection_start_day != new_start_day - || calitem->selection_end_month_offset != new_end_month_offset - || calitem->selection_end_day != new_end_day) { - need_update = TRUE; - calitem->selection_changed = TRUE; - e_calendar_item_queue_signal_emission (calitem); - calitem->selection_set = TRUE; - calitem->selection_start_month_offset = new_start_month_offset; - calitem->selection_start_day = new_start_day; - calitem->selection_end_month_offset = new_end_month_offset; - calitem->selection_end_day = new_end_day; - - calitem->selection_real_start_month_offset = new_start_month_offset; - calitem->selection_real_start_day = new_start_day; - calitem->selection_from_full_week = FALSE; - } - - if (need_update) - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); -} - - -/* This tries to ensure that the given time range is visible. If the range - given is longer than we can show, only the start of it will be visible. - Note that this will not update the selection. That should be done somewhere - else. It returns TRUE if the visible range has been changed. */ -static gboolean -e_calendar_item_ensure_days_visible (ECalendarItem *calitem, - gint start_year, - gint start_month, - gint start_day, - gint end_year, - gint end_month, - gint end_day) -{ - gint current_end_year, current_end_month; - gint months_shown, months; - gint first_day_offset, days_in_month, days_in_prev_month; - gboolean need_update = FALSE; - - months_shown = calitem->rows * calitem->cols; - months = (end_year - start_year) * 12 + end_month - start_month; - - /* Calculate the range of months currently displayed. */ - current_end_year = calitem->year; - current_end_month = calitem->month + months_shown - 1; - e_calendar_item_normalize_date (calitem, ¤t_end_year, - ¤t_end_month); - - /* Try to ensure that the end month is shown. */ - if (end_year > current_end_year - || (end_year == current_end_year - && end_month > current_end_month)) { - need_update = TRUE; - calitem->year = end_year; - calitem->month = end_month - months_shown + 1; - e_calendar_item_normalize_date (calitem, &calitem->year, - &calitem->month); - } - - /* Now try to ensure that the start month is shown. We do this after - the end month so that the start month will always be shown. */ - if (start_year < calitem->year - || (start_year == calitem->year - && start_month < calitem->month)) { - need_update = TRUE; - - /* First we see if the start of the selection will fit in the - leftover days of the month before the first one shown. */ - calitem->year = start_year; - calitem->month = start_month + 1; - e_calendar_item_normalize_date (calitem, &calitem->year, - &calitem->month); - - e_calendar_item_get_month_info (calitem, 0, 0, - &first_day_offset, - &days_in_month, - &days_in_prev_month); - - if (start_day <= days_in_prev_month - first_day_offset) { - calitem->year = start_year; - calitem->month = start_month; - } - } - - if (need_update) - e_calendar_item_date_range_changed (calitem); - - return need_update; -} - - -static void -e_calendar_item_show_popup_menu (ECalendarItem *calitem, - GdkEventButton *event, - gint month_offset) -{ - GtkWidget *menu, *submenu, *menuitem; - gint year, month; - gchar buffer[64]; - struct tm tmp_tm; - - menu = gtk_menu_new (); - - for (year = calitem->year - 2; year <= calitem->year + 2; year++) { - g_snprintf (buffer, 64, "%i", year); - menuitem = gtk_menu_item_new_with_label (buffer); - gtk_widget_show (menuitem); - gtk_container_add (GTK_CONTAINER (menu), menuitem); - - submenu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); - - gtk_object_set_data (GTK_OBJECT (submenu), "year", - GINT_TO_POINTER (year)); - gtk_object_set_data (GTK_OBJECT (submenu), "month_offset", - GINT_TO_POINTER (month_offset)); - - for (month = 0; month < 12; month++) { - memset (&tmp_tm, 0, sizeof (tmp_tm)); - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = 1; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - /* This is a strftime() format. %B = Month name, %Y = Year. */ - strftime (buffer, sizeof (buffer), _("%B %Y"), &tmp_tm); - - menuitem = gtk_menu_item_new_with_label (buffer); - gtk_widget_show (menuitem); - gtk_container_add (GTK_CONTAINER (submenu), menuitem); - - gtk_object_set_data (GTK_OBJECT (menuitem), "month", - GINT_TO_POINTER (month)); - - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (e_calendar_item_on_menu_item_activate), calitem); - } - } - - /* Run the menu modal so we can destroy it after. */ - gtk_signal_connect (GTK_OBJECT (menu), "deactivate", - GTK_SIGNAL_FUNC (gtk_main_quit), NULL); - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, - e_calendar_item_position_menu, calitem, - event->button, event->time); - gtk_grab_add (menu); - gtk_main (); - gtk_grab_remove (menu); - gtk_widget_destroy (menu); -} - - -static void -e_calendar_item_on_menu_item_activate (GtkWidget *menuitem, - ECalendarItem *calitem) -{ - gint year, month_offset, month; - - year = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menuitem->parent), "year")); - month_offset = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menuitem->parent), "month_offset")); - month = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menuitem), "month")); - - month -= month_offset; - e_calendar_item_normalize_date (calitem, &year, &month); - e_calendar_item_set_first_month (calitem, year, month); -} - - -static void -e_calendar_item_position_menu (GtkMenu *menu, - gint *x, - gint *y, - gpointer user_data) -{ - GtkRequisition requisition; - gint screen_width, screen_height; - - gtk_widget_get_child_requisition (GTK_WIDGET (menu), &requisition); - - *x -= 2; - *y -= requisition.height / 2; - - screen_width = gdk_screen_width (); - screen_height = gdk_screen_height (); - - *x = CLAMP (*x, 0, screen_width - requisition.width); - *y = CLAMP (*y, 0, screen_height - requisition.height); -} - - -/* Sets the function to call to get the colors to use for a particular day. */ -void -e_calendar_item_set_style_callback (ECalendarItem *calitem, - ECalendarItemStyleCallback cb, - gpointer data, - GtkDestroyNotify destroy) -{ - g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); - - if (calitem->style_callback_data) - (*calitem->style_callback_destroy) (calitem->style_callback_data); - - calitem->style_callback = cb; - calitem->style_callback_data = data; - calitem->style_callback_destroy = destroy; -} - - -static void -e_calendar_item_date_range_changed (ECalendarItem *calitem) -{ - g_free (calitem->styles); - calitem->styles = NULL; - calitem->date_range_changed = TRUE; - e_calendar_item_queue_signal_emission (calitem); -} - - -static void -e_calendar_item_queue_signal_emission (ECalendarItem *calitem) -{ - if (calitem->signal_emission_idle_id == 0) { - calitem->signal_emission_idle_id = g_idle_add_full (G_PRIORITY_HIGH, e_calendar_item_signal_emission_idle_cb, calitem, NULL); - } -} - - -static gboolean -e_calendar_item_signal_emission_idle_cb (gpointer data) -{ - ECalendarItem *calitem; - - g_return_val_if_fail (E_IS_CALENDAR_ITEM (data), FALSE); - - GDK_THREADS_ENTER (); - - calitem = E_CALENDAR_ITEM (data); - - calitem->signal_emission_idle_id = 0; - - if (calitem->date_range_changed) { - gtk_signal_emit (GTK_OBJECT (calitem), - e_calendar_item_signals[DATE_RANGE_CHANGED]); - calitem->date_range_changed = FALSE; - } - - if (calitem->selection_changed) { - gtk_signal_emit (GTK_OBJECT (calitem), - e_calendar_item_signals[SELECTION_CHANGED]); - calitem->selection_changed = FALSE; - } - - GDK_THREADS_LEAVE (); - return FALSE; -} - diff --git a/widgets/misc/e-calendar-item.h b/widgets/misc/e-calendar-item.h deleted file mode 100644 index 0e655cf355..0000000000 --- a/widgets/misc/e-calendar-item.h +++ /dev/null @@ -1,320 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 2000, Helix Code, 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 - */ -#ifndef _E_CALENDAR_ITEM_H_ -#define _E_CALENDAR_ITEM_H_ - -#include <libgnomeui/gnome-canvas.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * ECalendarItem - canvas item displaying a calendar. - */ - -#define E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME 1 -#define E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME 1 - -/* Used to mark days as bold in e_calendar_item_mark_day(). */ -#define E_CALENDAR_ITEM_MARK_BOLD 1 - - -/* These index our colors array. */ -typedef enum -{ - E_CALENDAR_ITEM_COLOR_TODAY_BOX, - E_CALENDAR_ITEM_COLOR_SELECTION_FG, - E_CALENDAR_ITEM_COLOR_SELECTION_BG, - E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG, - - E_CALENDAR_ITEM_COLOR_LAST -} ECalendarItemColors; - -typedef struct _ECalendarItem ECalendarItem; -typedef struct _ECalendarItemClass ECalendarItemClass; - -typedef void (*ECalendarItemStyleCallback) (ECalendarItem *calitem, - gint year, - gint month, - gint day, - gint day_style, - gboolean today, - gboolean prev_or_next_month, - gboolean selected, - gboolean has_focus, - gboolean drop_target, - GdkColor **bg_color, - GdkColor **fg_color, - GdkColor **box_color, - gboolean *bold, - gpointer data); - - -#define E_CALENDAR_ITEM(obj) (GTK_CHECK_CAST((obj), \ - e_calendar_item_get_type (), ECalendarItem)) -#define E_CALENDAR_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k),\ - e_calendar_item_get_type ())) -#define E_IS_CALENDAR_ITEM(o) (GTK_CHECK_TYPE((o), \ - e_calendar_item_get_type ())) - -struct _ECalendarItem -{ - GnomeCanvasItem canvas_item; - - /* The year & month of the first calendar being displayed. */ - gint year; - gint month; /* 0 to 11 */ - - /* Points to an array of styles, one char for each day. We use 32 - chars for each month, with n + 2 months, where n is the number of - complete months shown (since we show some days before the first - month and after the last month grayes out). - A value of 0 is the default, and 1 is bold. */ - guint8 *styles; - - /* - * Options. - */ - - /* The minimum & maximum number of rows & columns of months. - If the maximum values are -1 then there is no maximum. - The minimum valies default to 1. The maximum values to -1. */ - gint min_rows; - gint min_cols; - gint max_rows; - gint max_cols; - - /* The actual number of rows & columns of months. */ - gint rows; - gint cols; - - /* Whether we show week nubers. */ - gboolean show_week_numbers; - - /* The first day of the week, 0 (Monday) to 6 (Sunday). */ - gint week_start_day; - - /* Whether the cells expand to fill extra space. */ - gboolean expand; - - /* The maximum number of days that can be selected. Defaults to 1. */ - gint max_days_selected; - - /* The number of days selected before we switch to selecting whole - weeks, or -1 if we never switch. Defaults to -1. */ - gint days_to_start_week_selection; - - /* Whether the selection is moved when we move back/forward one month. - Used for things like the EDateEdit which only want the selection to - be changed when the user explicitly selects a day. */ - gboolean move_selection_when_moving; - - /* Whether the selection is rounded down to the nearest week when we - move back/forward one month. Used for the week view. */ - gboolean round_selection_when_moving; - - /* Whether to display the pop-up, TRUE by default */ - gboolean display_popup; - - /* - * Internal stuff. - */ - - /* Bounds of item. */ - gdouble x1, y1, x2, y2; - - /* The minimum size of each month, based on the fonts used. */ - gint min_month_width; - gint min_month_height; - - /* The actual size of each month, after dividing extra space. */ - gint month_width; - gint month_height; - - /* The offset to the left edge of the first calendar. */ - gint x_offset; - - /* The padding around each calendar month. */ - gint month_lpad, month_rpad; - gint month_tpad, month_bpad; - - /* The size of each cell. */ - gint cell_width; - gint cell_height; - - /* The current selection. The month offsets are from 0, which is the - top-left calendar month view. Note that -1 is used for the last days - from the previous month. The days are real month days. */ - gboolean selecting; - gboolean selection_dragging_end; - gboolean selection_from_full_week; - gboolean selection_set; - gint selection_start_month_offset; - gint selection_start_day; - gint selection_end_month_offset; - gint selection_end_day; - gint selection_real_start_month_offset; - gint selection_real_start_day; - - /* The first character of each day of the week, e.g. 'MTWTFSS'. */ - gchar *days; - - /* Widths of the day characters. */ - gint day_widths[7]; - - /* Widths of the digits, '0' .. '9'. */ - gint digit_widths[10]; - gint max_digit_width; - gint week_number_digit_widths[10]; - gint max_week_number_digit_width; - - /* Fonts for drawing text. If font isn't set it uses the font from the - canvas widget. If week_number_font isn't set it uses font. */ - GdkFont *font, *old_font; - GdkFont *week_number_font, *old_week_number_font; - - ECalendarItemStyleCallback style_callback; - gpointer style_callback_data; - GtkDestroyNotify style_callback_destroy; - - /* Colors for drawing. */ - GdkColor colors[E_CALENDAR_ITEM_COLOR_LAST]; - - /* Our idle handler for emitting signals. */ - gint signal_emission_idle_id; - - /* A flag to indicate that the selection or date range has changed. - When set the idle function will emit the signal and reset it to - FALSE. This is so we don't emit it several times when args are set - etc. */ - gboolean selection_changed; - gboolean date_range_changed; -}; - -struct _ECalendarItemClass -{ - GnomeCanvasItemClass parent_class; - - void (* date_range_changed) (ECalendarItem *calitem); - void (* selection_changed) (ECalendarItem *calitem); -}; - - -GtkType e_calendar_item_get_type (void); - -/* FIXME: months are 0-11 throughout, but 1-12 may be better. */ - -void e_calendar_item_get_first_month (ECalendarItem *calitem, - gint *year, - gint *month); -void e_calendar_item_set_first_month (ECalendarItem *calitem, - gint year, - gint month); - -/* Get the maximum number of days selectable */ -gint e_calendar_item_get_max_days_sel (ECalendarItem *calitem); - -/* Set the maximum number of days selectable */ -void e_calendar_item_set_max_days_sel (ECalendarItem *calitem, - gint days); - -/* Get the maximum number of days selectable */ -gint e_calendar_item_get_days_start_week_sel(ECalendarItem *calitem); - -/* Get the maximum number of days before whole weeks are selected */ -void e_calendar_item_set_days_start_week_sel(ECalendarItem *calitem, - gint days); - -/* Set the maximum number of days before whole weeks are selected */ -gboolean e_calendar_item_get_display_popup (ECalendarItem *calitem); - -/* Get the maximum number of days before whole weeks are selected */ -void e_calendar_item_set_display_popup (ECalendarItem *calitem, - gboolean display); - -/* Set the maximum number of days before whole weeks are selected */ -gint e_calendar_item_get_days_start_week_sel(ECalendarItem *calitem); - -/* Set the maximum number of days selectable */ -void e_calendar_item_set_days_start_week_sel(ECalendarItem *calitem, - gint days); - -/* Gets the range of dates actually shown. Months are 0 to 11. - This also includes the last days of the previous month and the first days - of the following month, which are normally shown in gray. - It returns FALSE if no dates are currently shown. */ -gboolean e_calendar_item_get_date_range (ECalendarItem *calitem, - gint *start_year, - gint *start_month, - gint *start_day, - gint *end_year, - gint *end_month, - gint *end_day); - -/* Returns the selected date range. It returns FALSE if no days are currently - selected. */ -gboolean e_calendar_item_get_selection (ECalendarItem *calitem, - GDate *start_date, - GDate *end_date); -/* Sets the selected date range, and changes the date range shown so at least - the start of the selection is shown. If start_date is NULL it clears the - selection. */ -void e_calendar_item_set_selection (ECalendarItem *calitem, - GDate *start_date, - GDate *end_date); - -/* Marks a particular day. Passing E_CALENDAR_ITEM_MARK_BOLD as the day style - will result in the day being shown as bold by default. The style callback - could support more day_styles, or the style callback could determine the - colors itself, without needing to mark days. */ -void e_calendar_item_clear_marks (ECalendarItem *calitem); -void e_calendar_item_mark_day (ECalendarItem *calitem, - gint year, - gint month, - gint day, - guint8 day_style); - -/* Mark a range of days. Any days outside the currently shown range are - ignored. */ -void e_calendar_item_mark_days (ECalendarItem *calitem, - gint start_year, - gint start_month, - gint start_day, - gint end_year, - gint end_month, - gint end_day, - guint8 day_style); - -/* Sets the function to call to get the colors to use for a particular day. */ -void e_calendar_item_set_style_callback (ECalendarItem *calitem, - ECalendarItemStyleCallback cb, - gpointer data, - GtkDestroyNotify destroy); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_CALENDAR_ITEM_H_ */ diff --git a/widgets/misc/e-calendar.c b/widgets/misc/e-calendar.c deleted file mode 100644 index b0cc00a13f..0000000000 --- a/widgets/misc/e-calendar.c +++ /dev/null @@ -1,604 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 2000, Helix Code, 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 - */ - -/* - * ECalendar - displays a table of monthly calendars, allowing highlighting - * and selection of one or more days. Like GtkCalendar with more features. - * Most of the functionality is in the ECalendarItem canvas item, though - * we also add GnomeCanvasWidget buttons to go to the previous/next month and - * to got to the current day. - */ - -#include <config.h> - -#include "e-calendar.h" - -#include <glib.h> -#include <gtk/gtkbutton.h> -#include <gtk/gtkmain.h> -#include <gtk/gtkpixmap.h> -#include <gtk/gtksignal.h> -#include <libgnomeui/gnome-canvas-widget.h> -#include <gal/util/e-util.h> - -#define E_CALENDAR_SMALL_FONT \ - "-adobe-utopia-regular-r-normal-*-*-100-*-*-p-*-iso8859-*" -#define E_CALENDAR_SMALL_FONT_FALLBACK \ - "-adobe-helvetica-medium-r-normal-*-*-80-*-*-p-*-iso8859-*" - -/* The space between the arrow buttons and the edge of the widget. */ -#define E_CALENDAR_ARROW_BUTTON_X_PAD 2 -#define E_CALENDAR_ARROW_BUTTON_Y_PAD 0 - -/* Vertical padding. The padding above the button includes the space for the - horizontal line. */ -#define E_CALENDAR_YPAD_ABOVE_LOWER_BUTTONS 4 -#define E_CALENDAR_YPAD_BELOW_LOWER_BUTTONS 3 - -/* Horizontal padding inside & between buttons. */ -#define E_CALENDAR_IXPAD_BUTTONS 4 -#define E_CALENDAR_XPAD_BUTTONS 8 - -/* The time between steps when the prev/next buttons is pressed, in 1/1000ths - of a second, and the number of timeouts we skip before we start - automatically moving back/forward. */ -#define E_CALENDAR_AUTO_MOVE_TIMEOUT 150 -#define E_CALENDAR_AUTO_MOVE_TIMEOUT_DELAY 2 - -static char * left_arrow_xpm[] = { - "7 7 3 1", - " c None", - ". c #949594", - "+ c #000000", - " .+", - " .+++", - " .+++++", - "+++++++", - " .+++++", - " .+++", - " .+" -}; - -static char * right_arrow_xpm[] = { - "7 7 3 1", - " c None", - ". c #949594", - "+ c #000000", - "+. ", - "+++. ", - "+++++. ", - "+++++++", - "+++++. ", - "+++. ", - "+. " -}; - - -static void e_calendar_class_init (ECalendarClass *class); -static void e_calendar_init (ECalendar *cal); -static void e_calendar_destroy (GtkObject *object); -static void e_calendar_realize (GtkWidget *widget); -static void e_calendar_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static void e_calendar_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void e_calendar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void e_calendar_draw (GtkWidget *widget, - GdkRectangle *area); -static gint e_calendar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static void e_calendar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time); - -static void e_calendar_on_prev_pressed (ECalendar *cal); -static void e_calendar_on_prev_released (ECalendar *cal); -static void e_calendar_on_next_pressed (ECalendar *cal); -static void e_calendar_on_next_released (ECalendar *cal); - -static void e_calendar_start_auto_move (ECalendar *cal, - gboolean moving_forward); -static gboolean e_calendar_auto_move_handler (gpointer data); -static void e_calendar_stop_auto_move (ECalendar *cal); - -static GnomeCanvasClass *parent_class; -static GtkLayoutClass *grandparent_class; - -E_MAKE_TYPE (e_calendar, "ECalendar", ECalendar, - e_calendar_class_init, e_calendar_init, E_CANVAS_TYPE) - - -static void -e_calendar_class_init (ECalendarClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - parent_class = gtk_type_class (E_CANVAS_TYPE); - grandparent_class = gtk_type_class (GTK_TYPE_LAYOUT); - - object_class->destroy = e_calendar_destroy; - - widget_class->realize = e_calendar_realize; - widget_class->style_set = e_calendar_style_set; - widget_class->size_request = e_calendar_size_request; - widget_class->size_allocate = e_calendar_size_allocate; - widget_class->draw = e_calendar_draw; - widget_class->drag_motion = e_calendar_drag_motion; - widget_class->drag_leave = e_calendar_drag_leave; -} - - -static void -e_calendar_init (ECalendar *cal) -{ - GnomeCanvasGroup *canvas_group; - GdkFont *small_font; - GtkWidget *button, *pixmap; - GdkColormap *colormap; - GdkPixmap *gdk_pixmap; - GdkBitmap *gdk_mask; - - GTK_WIDGET_UNSET_FLAGS (cal, GTK_CAN_FOCUS); - - /* Create the small font. */ - small_font = gdk_font_load (E_CALENDAR_SMALL_FONT); - if (!small_font) - small_font = gdk_font_load (E_CALENDAR_SMALL_FONT_FALLBACK); - if (!small_font) - g_warning ("Couldn't load font"); - - canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (cal)->root); - - cal->calitem = E_CALENDAR_ITEM (gnome_canvas_item_new (canvas_group, - e_calendar_item_get_type (), - "week_number_font", small_font, - NULL)); - - if (small_font) - gdk_font_unref (small_font); - - - /* Create the arrow buttons to move to the previous/next month. */ - button = gtk_button_new (); - GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS); - gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); - gtk_widget_show (button); - gtk_signal_connect_object (GTK_OBJECT (button), "pressed", - GTK_SIGNAL_FUNC (e_calendar_on_prev_pressed), - GTK_OBJECT (cal)); - gtk_signal_connect_object (GTK_OBJECT (button), "released", - GTK_SIGNAL_FUNC (e_calendar_on_prev_released), - GTK_OBJECT (cal)); - - colormap = gtk_widget_get_colormap (GTK_WIDGET (cal)); - gdk_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, - &gdk_mask, NULL, - left_arrow_xpm); - pixmap = gtk_pixmap_new (gdk_pixmap, gdk_mask); - gtk_widget_show (pixmap); - gdk_pixmap_unref (gdk_pixmap); - gdk_bitmap_unref (gdk_mask); - gtk_container_add (GTK_CONTAINER (button), pixmap); - - cal->prev_item = gnome_canvas_item_new (canvas_group, - gnome_canvas_widget_get_type (), - "widget", button, - NULL); - - button = gtk_button_new (); - GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS); - gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); - gtk_widget_show (button); - gtk_signal_connect_object (GTK_OBJECT (button), "pressed", - GTK_SIGNAL_FUNC (e_calendar_on_next_pressed), - GTK_OBJECT (cal)); - gtk_signal_connect_object (GTK_OBJECT (button), "released", - GTK_SIGNAL_FUNC (e_calendar_on_next_released), - GTK_OBJECT (cal)); - - gdk_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, - &gdk_mask, NULL, - right_arrow_xpm); - pixmap = gtk_pixmap_new (gdk_pixmap, gdk_mask); - gtk_widget_show (pixmap); - gdk_pixmap_unref (gdk_pixmap); - gdk_bitmap_unref (gdk_mask); - gtk_container_add (GTK_CONTAINER (button), pixmap); - - cal->next_item = gnome_canvas_item_new (canvas_group, - gnome_canvas_widget_get_type (), - "widget", button, - NULL); - - cal->min_rows = 1; - cal->min_cols = 1; - cal->max_rows = -1; - cal->max_cols = -1; - - cal->timeout_id = 0; -} - - -/** - * e_calendar_new: - * @Returns: a new #ECalendar. - * - * Creates a new #ECalendar. - **/ -GtkWidget * -e_calendar_new (void) -{ - GtkWidget *cal; - - cal = gtk_type_new (e_calendar_get_type ()); - - return cal; -} - - -static void -e_calendar_destroy (GtkObject *object) -{ - ECalendar *cal; - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_CALENDAR (object)); - - cal = E_CALENDAR (object); - - if (cal->timeout_id != 0) { - gtk_timeout_remove (cal->timeout_id); - cal->timeout_id = 0; - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -static void -e_calendar_realize (GtkWidget *widget) -{ - (*GTK_WIDGET_CLASS (parent_class)->realize) (widget); - - /* Set the background of the canvas window to the normal color, - or the arrow buttons are not displayed properly. */ - gdk_window_set_background (GTK_LAYOUT (widget)->bin_window, - &widget->style->bg[GTK_STATE_NORMAL]); -} - - -static void -e_calendar_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (*GTK_WIDGET_CLASS (parent_class)->style_set) (widget, - previous_style); - - /* Set the background of the canvas window to the normal color, - or the arrow buttons are not displayed properly. */ - if (GTK_WIDGET_REALIZED (widget->parent)) - gdk_window_set_background (GTK_LAYOUT (widget)->bin_window, - &widget->style->bg[GTK_STATE_NORMAL]); -} - - -static void -e_calendar_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - ECalendar *cal; - GtkStyle *style; - gint col_width, row_height, width, height; - - cal = E_CALENDAR (widget); - style = GTK_WIDGET (cal)->style; - - gtk_object_get (GTK_OBJECT (cal->calitem), - "row_height", &row_height, - "column_width", &col_width, - NULL); - - height = row_height * cal->min_rows; - width = col_width * cal->min_cols; - - requisition->width = width + style->klass->xthickness * 2; - requisition->height = height + style->klass->ythickness * 2; -} - - -static void -e_calendar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - ECalendar *cal; - GdkFont *font; - gdouble old_x2, old_y2, new_x2, new_y2; - gdouble xthickness, ythickness, arrow_button_size; - - cal = E_CALENDAR (widget); - font = widget->style->font; - xthickness = widget->style->klass->xthickness; - ythickness = widget->style->klass->ythickness; - - (*GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation); - - /* Set the scroll region to its allocated size, if changed. */ - gnome_canvas_get_scroll_region (GNOME_CANVAS (cal), - NULL, NULL, &old_x2, &old_y2); - new_x2 = widget->allocation.width - 1; - new_y2 = widget->allocation.height - 1; - if (old_x2 != new_x2 || old_y2 != new_y2) - gnome_canvas_set_scroll_region (GNOME_CANVAS (cal), - 0, 0, new_x2, new_y2); - - /* Take off space for line & buttons if shown. */ - gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem), - "x1", 0.0, - "y1", 0.0, - "x2", new_x2, - "y2", new_y2, - NULL); - - - /* Position the arrow buttons. */ - arrow_button_size = font->ascent + font->descent - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME - - E_CALENDAR_ARROW_BUTTON_Y_PAD * 2; - - gnome_canvas_item_set (cal->prev_item, - "x", xthickness * 2 - + E_CALENDAR_ARROW_BUTTON_X_PAD, - "y", ythickness * 2 - + E_CALENDAR_ARROW_BUTTON_Y_PAD, - "width", arrow_button_size, - "height", arrow_button_size, - NULL); - - gnome_canvas_item_set (cal->next_item, - "x", new_x2 + 1 - xthickness * 2 - - E_CALENDAR_ARROW_BUTTON_X_PAD - - arrow_button_size, - "y", ythickness * 2 - + E_CALENDAR_ARROW_BUTTON_Y_PAD, - "width", arrow_button_size, - "height", arrow_button_size, - NULL); -} - - -static void -e_calendar_draw (GtkWidget *widget, - GdkRectangle *area) -{ - ECalendar *cal; - - cal = E_CALENDAR (widget); - - (*GTK_WIDGET_CLASS (parent_class)->draw) (widget, area); - - /* GnomeCanvas bug workaround to draw the GnomeCanvasWidgets. */ -#if 0 - (*GTK_WIDGET_CLASS (grandparent_class)->draw) (widget, area); -#endif -} - - -void -e_calendar_set_minimum_size (ECalendar *cal, - gint rows, - gint cols) -{ - g_return_if_fail (E_IS_CALENDAR (cal)); - - cal->min_rows = rows; - cal->min_cols = cols; - - gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem), - "minimum_rows", rows, - "minimum_columns", cols, - NULL); - - gtk_widget_queue_resize (GTK_WIDGET (cal)); -} - - -void -e_calendar_set_maximum_size (ECalendar *cal, - gint rows, - gint cols) -{ - g_return_if_fail (E_IS_CALENDAR (cal)); - - cal->max_rows = rows; - cal->max_cols = cols; - - gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem), - "maximum_rows", rows, - "maximum_columns", cols, - NULL); - - gtk_widget_queue_resize (GTK_WIDGET (cal)); -} - - -/* Returns the border size on each side of the month displays. */ -void -e_calendar_get_border_size (ECalendar *cal, - gint *top, - gint *bottom, - gint *left, - gint *right) -{ - GtkStyle *style; - - g_return_if_fail (E_IS_CALENDAR (cal)); - - style = GTK_WIDGET (cal)->style; - - if (style) { - *top = style->klass->ythickness; - *bottom = style->klass->ythickness; - *left = style->klass->xthickness; - *right = style->klass->xthickness; - } else { - *top = *bottom = *left = *right = 0; - } -} - - -static void -e_calendar_on_prev_pressed (ECalendar *cal) -{ - e_calendar_start_auto_move (cal, FALSE); -} - - -static void -e_calendar_on_next_pressed (ECalendar *cal) -{ - e_calendar_start_auto_move (cal, TRUE); -} - - -static void -e_calendar_start_auto_move (ECalendar *cal, - gboolean moving_forward) -{ - ECalendarItem *calitem; - gint offset; - - if (cal->timeout_id == 0) { - cal->timeout_id = g_timeout_add (E_CALENDAR_AUTO_MOVE_TIMEOUT, - e_calendar_auto_move_handler, - cal); - } - cal->timeout_delay = E_CALENDAR_AUTO_MOVE_TIMEOUT_DELAY; - cal->moving_forward = moving_forward; - - calitem = cal->calitem; - offset = cal->moving_forward ? 1 : -1; - e_calendar_item_set_first_month (calitem, calitem->year, - calitem->month + offset); -} - - -static gboolean -e_calendar_auto_move_handler (gpointer data) -{ - ECalendar *cal; - ECalendarItem *calitem; - gint offset; - - g_return_val_if_fail (E_IS_CALENDAR (data), FALSE); - - cal = E_CALENDAR (data); - calitem = cal->calitem; - - GDK_THREADS_ENTER (); - - if (cal->timeout_delay > 0) { - cal->timeout_delay--; - } else { - offset = cal->moving_forward ? 1 : -1; - e_calendar_item_set_first_month (calitem, calitem->year, - calitem->month + offset); - } - - GDK_THREADS_LEAVE (); - return TRUE; -} - - -static void -e_calendar_on_prev_released (ECalendar *cal) -{ - e_calendar_stop_auto_move (cal); -} - - -static void -e_calendar_on_next_released (ECalendar *cal) -{ - e_calendar_stop_auto_move (cal); -} - - -static void -e_calendar_stop_auto_move (ECalendar *cal) -{ - if (cal->timeout_id != 0) { - gtk_timeout_remove (cal->timeout_id); - cal->timeout_id = 0; - } -} - - -static gint -e_calendar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - ECalendar *cal; - - g_return_val_if_fail (E_IS_CALENDAR (widget), FALSE); - - cal = E_CALENDAR (widget); - -#if 0 - g_print ("In e_calendar_drag_motion\n"); -#endif - - return FALSE; -} - - -static void -e_calendar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time) -{ - ECalendar *cal; - - g_return_if_fail (E_IS_CALENDAR (widget)); - - cal = E_CALENDAR (widget); - -#if 0 - g_print ("In e_calendar_drag_leave\n"); -#endif -} - diff --git a/widgets/misc/e-calendar.h b/widgets/misc/e-calendar.h deleted file mode 100644 index 417b90d630..0000000000 --- a/widgets/misc/e-calendar.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 2000, Helix Code, 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 - */ -#ifndef _E_CALENDAR_H_ -#define _E_CALENDAR_H_ - -#include <gtk/gtkwidget.h> -#include <gal/widgets/e-canvas.h> -#include "e-calendar-item.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * ECalendar - displays a table of monthly calendars, allowing highlighting - * and selection of one or more days. Like GtkCalendar with more features. - * Most of the functionality is in the ECalendarItem canvas item, though - * we also add GnomeCanvasWidget buttons to go to the previous/next month and - * to got to the current day. - */ - -#define E_CALENDAR(obj) GTK_CHECK_CAST (obj, e_calendar_get_type (), ECalendar) -#define E_CALENDAR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_calendar_get_type (), ECalendarClass) -#define E_IS_CALENDAR(obj) GTK_CHECK_TYPE (obj, e_calendar_get_type ()) - - -typedef struct _ECalendar ECalendar; -typedef struct _ECalendarClass ECalendarClass; - -struct _ECalendar -{ - ECanvas canvas; - - ECalendarItem *calitem; - - GnomeCanvasItem *prev_item; - GnomeCanvasItem *next_item; - - gint min_rows; - gint min_cols; - - gint max_rows; - gint max_cols; - - /* These are all used when the prev/next buttons are held down. - moving_forward is TRUE if we are moving forward in time, i.e. the - next button is pressed. */ - gint timeout_id; - gint timeout_delay; - gboolean moving_forward; -}; - -struct _ECalendarClass -{ - ECanvasClass parent_class; -}; - - -GtkType e_calendar_get_type (void); -GtkWidget* e_calendar_new (void); - -void e_calendar_set_minimum_size (ECalendar *cal, - gint rows, - gint cols); -void e_calendar_set_maximum_size (ECalendar *cal, - gint rows, - gint cols); - -/* Returns the border size on each side of the month displays. */ -void e_calendar_get_border_size (ECalendar *cal, - gint *top, - gint *bottom, - gint *left, - gint *right); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_CALENDAR_H_ */ diff --git a/widgets/misc/e-cell-date-edit.c b/widgets/misc/e-cell-date-edit.c deleted file mode 100644 index 7cd54891f7..0000000000 --- a/widgets/misc/e-cell-date-edit.c +++ /dev/null @@ -1,875 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2001, Ximian, 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 - */ - -/* - * ECellDateEdit - a subclass of ECellPopup used to show a date with a popup - * window to edit it. - */ - -#include <config.h> - -#include "e-cell-date-edit.h" - -#include <string.h> -#include <time.h> -#include <glib.h> -#include <gdk/gdkkeysyms.h> -#include <gal/util/e-util.h> -#include <gal/e-table/e-table-item.h> -#include <libgnomeui/gnome-messagebox.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnome/gnome-i18n.h> -#include "e-util/e-time-utils.h" -/* This depends on ECalendar which is why I didn't put it in gal. */ -#include "e-calendar.h" - -static void e_cell_date_edit_class_init (GtkObjectClass *object_class); -static void e_cell_date_edit_init (ECellDateEdit *ecde); -static void e_cell_date_edit_destroy (GtkObject *object); -static void e_cell_date_edit_get_arg (GtkObject *o, - GtkArg *arg, - guint arg_id); -static void e_cell_date_edit_set_arg (GtkObject *o, - GtkArg *arg, - guint arg_id); - -static gint e_cell_date_edit_do_popup (ECellPopup *ecp, - GdkEvent *event); -static void e_cell_date_edit_set_popup_values (ECellDateEdit *ecde); -static void e_cell_date_edit_select_matching_time(ECellDateEdit *ecde, - char *time); -static void e_cell_date_edit_show_popup (ECellDateEdit *ecde); -static void e_cell_date_edit_get_popup_pos (ECellDateEdit *ecde, - gint *x, - gint *y, - gint *height, - gint *width); - -static void e_cell_date_edit_rebuild_time_list (ECellDateEdit *ecde); - -static int e_cell_date_edit_key_press (GtkWidget *popup_window, - GdkEventKey *event, - ECellDateEdit *ecde); -static void e_cell_date_edit_on_ok_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_show_time_invalid_warning (ECellDateEdit *ecde); -static void e_cell_date_edit_on_now_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_on_none_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_on_today_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_update_cell (ECellDateEdit *ecde, - char *text); -static void e_cell_date_edit_on_time_selected (GtkList *list, - ECellDateEdit *ecde); -static void e_cell_date_edit_hide_popup (ECellDateEdit *ecde); - -/* Our arguments. */ -enum { - ARG_0, - ARG_SHOW_TIME, - ARG_SHOW_NOW_BUTTON, - ARG_SHOW_TODAY_BUTTON, - ARG_ALLOW_NO_DATE_SET, - ARG_USE_24_HOUR_FORMAT, - ARG_LOWER_HOUR, - ARG_UPPER_HOUR -}; - -static ECellPopupClass *parent_class; - - -E_MAKE_TYPE (e_cell_date_edit, "ECellDateEdit", ECellDateEdit, - e_cell_date_edit_class_init, e_cell_date_edit_init, - e_cell_popup_get_type()); - - -static void -e_cell_date_edit_class_init (GtkObjectClass *object_class) -{ - ECellPopupClass *ecpc = (ECellPopupClass *) object_class; - - gtk_object_add_arg_type ("ECellDateEdit::show_time", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, - ARG_SHOW_TIME); - gtk_object_add_arg_type ("ECellDateEdit::show_now_button", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, - ARG_SHOW_NOW_BUTTON); - gtk_object_add_arg_type ("ECellDateEdit::show_today_button", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, - ARG_SHOW_TODAY_BUTTON); - gtk_object_add_arg_type ("ECellDateEdit::allow_no_date_set", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, - ARG_ALLOW_NO_DATE_SET); - gtk_object_add_arg_type ("ECellDateEdit::use_24_hour_format", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, - ARG_USE_24_HOUR_FORMAT); - gtk_object_add_arg_type ("ECellDateEdit::lower_hour", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_LOWER_HOUR); - gtk_object_add_arg_type ("ECellDateEdit::upper_hour", - GTK_TYPE_INT, GTK_ARG_READWRITE, - ARG_UPPER_HOUR); - - object_class->destroy = e_cell_date_edit_destroy; - object_class->get_arg = e_cell_date_edit_get_arg; - object_class->set_arg = e_cell_date_edit_set_arg; - - ecpc->popup = e_cell_date_edit_do_popup; - - parent_class = gtk_type_class (e_cell_popup_get_type ()); -} - - -static void -e_cell_date_edit_init (ECellDateEdit *ecde) -{ - GtkWidget *frame, *vbox, *hbox, *vbox2; - GtkWidget *scrolled_window, *list, *bbox; - GtkWidget *now_button, *today_button, *none_button, *ok_button; - - ecde->lower_hour = 0; - ecde->upper_hour = 24; - ecde->use_24_hour_format = TRUE; - ecde->need_time_list_rebuild = TRUE; - ecde->freeze_count = 0; - - /* We create one popup window for the ECell, since there will only - ever be one popup in use at a time. */ - ecde->popup_window = gtk_window_new (GTK_WINDOW_POPUP); - - gtk_window_set_policy (GTK_WINDOW (ecde->popup_window), - TRUE, TRUE, FALSE); - - frame = gtk_frame_new (NULL); - gtk_container_add (GTK_CONTAINER (ecde->popup_window), frame); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); - gtk_widget_show (frame); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (frame), vbox); - gtk_widget_show (vbox); - - hbox = gtk_hbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - gtk_widget_show (hbox); - - ecde->calendar = e_calendar_new (); - gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (ecde->calendar)->calitem), - "move_selection_when_moving", FALSE, - NULL); - gtk_box_pack_start (GTK_BOX (hbox), ecde->calendar, TRUE, TRUE, 0); - gtk_widget_show (ecde->calendar); - - vbox2 = gtk_vbox_new (FALSE, 2); - gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0); - gtk_widget_show (vbox2); - - ecde->time_entry = gtk_entry_new (); - gtk_widget_set_usize (ecde->time_entry, 50, -1); - gtk_box_pack_start (GTK_BOX (vbox2), ecde->time_entry, - FALSE, FALSE, 0); - gtk_widget_show (ecde->time_entry); - - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_box_pack_start (GTK_BOX (vbox2), scrolled_window, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), - GTK_POLICY_NEVER, - GTK_POLICY_ALWAYS); - gtk_widget_show (scrolled_window); - - list = gtk_list_new (); - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), list); - gtk_container_set_focus_vadjustment (GTK_CONTAINER (list), - gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window))); - gtk_widget_show (list); - ecde->time_list = list; - gtk_signal_connect (GTK_OBJECT (list), "selection-changed", - GTK_SIGNAL_FUNC (e_cell_date_edit_on_time_selected), - ecde); - - bbox = gtk_hbutton_box_new (); - gtk_container_set_border_width (GTK_CONTAINER (bbox), 4); - gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 2); - gtk_button_box_set_child_ipadding (GTK_BUTTON_BOX (bbox), 2, 0); - gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), 0, 0); - gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0); - gtk_widget_show (bbox); - - now_button = gtk_button_new_with_label (_("Now")); - gtk_container_add (GTK_CONTAINER (bbox), now_button); - gtk_widget_show (now_button); - gtk_signal_connect (GTK_OBJECT (now_button), "clicked", - GTK_SIGNAL_FUNC (e_cell_date_edit_on_now_clicked), - ecde); - ecde->now_button = now_button; - - today_button = gtk_button_new_with_label (_("Today")); - gtk_container_add (GTK_CONTAINER (bbox), today_button); - gtk_widget_show (today_button); - gtk_signal_connect (GTK_OBJECT (today_button), "clicked", - GTK_SIGNAL_FUNC (e_cell_date_edit_on_today_clicked), - ecde); - ecde->today_button = today_button; - - none_button = gtk_button_new_with_label (_("None")); - gtk_container_add (GTK_CONTAINER (bbox), none_button); - gtk_widget_show (none_button); - gtk_signal_connect (GTK_OBJECT (none_button), "clicked", - GTK_SIGNAL_FUNC (e_cell_date_edit_on_none_clicked), - ecde); - ecde->none_button = none_button; - - ok_button = gtk_button_new_with_label (_("OK")); - gtk_container_add (GTK_CONTAINER (bbox), ok_button); - gtk_widget_show (ok_button); - gtk_signal_connect (GTK_OBJECT (ok_button), "clicked", - GTK_SIGNAL_FUNC (e_cell_date_edit_on_ok_clicked), - ecde); - - - gtk_signal_connect (GTK_OBJECT (ecde->popup_window), - "key_press_event", - GTK_SIGNAL_FUNC (e_cell_date_edit_key_press), - ecde); -} - - -/** - * e_cell_date_edit_new: - * - * Creates a new ECellDateEdit renderer. - * - * Returns: an ECellDateEdit object. - */ -ECell * -e_cell_date_edit_new (void) -{ - ECellDateEdit *ecde = gtk_type_new (e_cell_date_edit_get_type ()); - - return (ECell*) ecde; -} - - -/* - * GtkObject::destroy method - */ -static void -e_cell_date_edit_destroy (GtkObject *object) -{ - ECellDateEdit *ecde = E_CELL_DATE_EDIT (object); - - gtk_widget_unref (ecde->popup_window); - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - - -static void -e_cell_date_edit_get_arg (GtkObject *o, - GtkArg *arg, - guint arg_id) -{ - ECellDateEdit *ecde; - - ecde = E_CELL_DATE_EDIT (o); - - switch (arg_id) { - case ARG_SHOW_TIME: - GTK_VALUE_BOOL (*arg) = GTK_WIDGET_VISIBLE (ecde->time_entry) ? TRUE : FALSE; - break; - case ARG_SHOW_NOW_BUTTON: - GTK_VALUE_BOOL (*arg) = GTK_WIDGET_VISIBLE (ecde->now_button) ? TRUE : FALSE; - break; - case ARG_SHOW_TODAY_BUTTON: - GTK_VALUE_BOOL (*arg) = GTK_WIDGET_VISIBLE (ecde->today_button) ? TRUE : FALSE; - break; - case ARG_ALLOW_NO_DATE_SET: - GTK_VALUE_BOOL (*arg) = GTK_WIDGET_VISIBLE (ecde->none_button) ? TRUE : FALSE; - break; - case ARG_USE_24_HOUR_FORMAT: - GTK_VALUE_BOOL (*arg) = ecde->use_24_hour_format; - break; - case ARG_LOWER_HOUR: - GTK_VALUE_INT (*arg) = ecde->lower_hour; - break; - case ARG_UPPER_HOUR: - GTK_VALUE_INT (*arg) = ecde->upper_hour; - break; - default: - g_warning ("Invalid arg"); - } -} - - -static void -e_cell_date_edit_set_arg (GtkObject *o, - GtkArg *arg, - guint arg_id) -{ - ECellDateEdit *ecde; - gint ivalue; - gboolean bvalue; - - ecde = E_CELL_DATE_EDIT (o); - - switch (arg_id){ - case ARG_SHOW_TIME: - bvalue = GTK_VALUE_BOOL (*arg); - if (bvalue) { - gtk_widget_show (ecde->time_entry); - gtk_widget_show (ecde->time_list); - } else { - gtk_widget_hide (ecde->time_entry); - gtk_widget_hide (ecde->time_list); - } - break; - case ARG_SHOW_NOW_BUTTON: - bvalue = GTK_VALUE_BOOL (*arg); - if (bvalue) { - gtk_widget_show (ecde->now_button); - } else { - gtk_widget_hide (ecde->now_button); - } - break; - case ARG_SHOW_TODAY_BUTTON: - bvalue = GTK_VALUE_BOOL (*arg); - if (bvalue) { - gtk_widget_show (ecde->today_button); - } else { - gtk_widget_hide (ecde->today_button); - } - break; - case ARG_ALLOW_NO_DATE_SET: - bvalue = GTK_VALUE_BOOL (*arg); - if (bvalue) { - gtk_widget_show (ecde->none_button); - } else { - /* FIXME: What if we have no date set now. */ - gtk_widget_hide (ecde->none_button); - } - break; - case ARG_USE_24_HOUR_FORMAT: - bvalue = GTK_VALUE_BOOL (*arg); - if (ecde->use_24_hour_format != bvalue) { - ecde->use_24_hour_format = bvalue; - ecde->need_time_list_rebuild = TRUE; - } - break; - case ARG_LOWER_HOUR: - ivalue = GTK_VALUE_INT (*arg); - ivalue = CLAMP (ivalue, 0, 24); - if (ecde->lower_hour != ivalue) { - ecde->lower_hour = ivalue; - ecde->need_time_list_rebuild = TRUE; - } - break; - case ARG_UPPER_HOUR: - ivalue = GTK_VALUE_INT (*arg); - ivalue = CLAMP (ivalue, 0, 24); - if (ecde->upper_hour != ivalue) { - ecde->upper_hour = ivalue; - ecde->need_time_list_rebuild = TRUE; - } - break; - default: - g_warning ("Invalid arg"); - } - -#if 0 - if (ecde->need_time_list_rebuild && ecde->freeze_count == 0) - e_cell_date_edit_rebuild_time_list (ecde); -#endif -} - - -static gint -e_cell_date_edit_do_popup (ECellPopup *ecp, - GdkEvent *event) -{ - ECellDateEdit *ecde = E_CELL_DATE_EDIT (ecp); - guint32 time; - - e_cell_date_edit_show_popup (ecde); - e_cell_date_edit_set_popup_values (ecde); - - if (event->type == GDK_BUTTON_PRESS) { - time = event->button.time; - } else { - time = event->key.time; - } - - gtk_grab_add (ecde->popup_window); - - return TRUE; -} - - -static void -e_cell_date_edit_set_popup_values (ECellDateEdit *ecde) -{ - ECellPopup *ecp = E_CELL_POPUP (ecde); - ECellView *ecv = (ECellView*) ecp->popup_cell_view; - ETableItem *eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view); - ETableCol *ecol; - char *cell_text; - ETimeParseStatus status; - struct tm date_tm; - GDate date; - ECalendarItem *calitem; - char buffer[64]; - - ecol = e_table_header_get_column (eti->header, ecp->popup_view_col); - cell_text = e_table_model_value_at (ecv->e_table_model, - ecol->col_idx, ecp->popup_row); - - status = e_time_parse_date_and_time (cell_text, &date_tm); - - /* If there is no date and time set, or the date is invalid, we clear - the selections, else we select the appropriate date & time. */ - calitem = E_CALENDAR_ITEM (E_CALENDAR (ecde->calendar)->calitem); - if (status == E_TIME_PARSE_NONE || status == E_TIME_PARSE_INVALID) { - gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), ""); - e_calendar_item_set_selection (calitem, NULL, NULL); - gtk_list_unselect_all (GTK_LIST (ecde->time_list)); - } else { - e_time_format_time (&date_tm, ecde->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), buffer); - - g_date_clear (&date, 1); - g_date_set_dmy (&date, date_tm.tm_mday, date_tm.tm_mon + 1, - date_tm.tm_year + 1900); - e_calendar_item_set_selection (calitem, &date, &date); - - e_cell_date_edit_select_matching_time (ecde, buffer); - } -} - - -static void -e_cell_date_edit_select_matching_time (ECellDateEdit *ecde, - char *time) -{ - GtkList *list; - GtkWidget *listitem, *label; - GList *elem; - gboolean found = FALSE; - char *list_item_text; - - list = GTK_LIST (ecde->time_list); - elem = list->children; - while (elem) { - listitem = GTK_WIDGET (elem->data); - label = GTK_BIN (listitem)->child; - gtk_label_get (GTK_LABEL (label), &list_item_text); - - if (!strcmp (list_item_text, time)) { - found = TRUE; - gtk_list_select_child (list, listitem); - break; - } - - elem = elem->next; - } - - if (!found) - gtk_list_unselect_all (list); -} - - -static void -e_cell_date_edit_show_popup (ECellDateEdit *ecde) -{ - gint x, y, width, height, old_width, old_height; - - if (ecde->need_time_list_rebuild) - e_cell_date_edit_rebuild_time_list (ecde); - - /* This code is practically copied from GtkCombo. */ - old_width = ecde->popup_window->allocation.width; - old_height = ecde->popup_window->allocation.height; - - e_cell_date_edit_get_popup_pos (ecde, &x, &y, &height, &width); - - gtk_widget_set_uposition (ecde->popup_window, x, y); - gtk_widget_set_usize (ecde->popup_window, width, height); - gtk_widget_realize (ecde->popup_window); - gdk_window_resize (ecde->popup_window->window, width, height); - gtk_widget_show (ecde->popup_window); - - /* Set the focus to the first widget. */ - gtk_widget_grab_focus (ecde->time_entry); - - E_CELL_POPUP (ecde)->popup_shown = TRUE; -} - - -/* Calculates the size and position of the popup window (like GtkCombo). */ -static void -e_cell_date_edit_get_popup_pos (ECellDateEdit *ecde, - gint *x, - gint *y, - gint *height, - gint *width) -{ - ECellPopup *ecp = E_CELL_POPUP (ecde); - ETableItem *eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view); - GtkWidget *canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas); - GtkRequisition popup_requisition; - gint avail_height, screen_width, column_width, row_height; - double x1, y1; - - gdk_window_get_origin (canvas->window, x, y); - - x1 = e_table_header_col_diff (eti->header, 0, eti->editing_col + 1); - y1 = e_table_item_row_diff (eti, 0, eti->editing_row + 1); - column_width = e_table_header_col_diff (eti->header, eti->editing_col, - eti->editing_col + 1); - row_height = e_table_item_row_diff (eti, eti->editing_row, - eti->editing_row + 1); - gnome_canvas_item_i2w (GNOME_CANVAS_ITEM (eti), &x1, &y1); - - *x += x1; - /* The ETable positions don't include the grid lines, I think, so we - add 1. */ - *y += y1 + 1; - - avail_height = gdk_screen_height () - *y; - - /* We'll use the entire screen width if needed, but we save space for - the vertical scrollbar in case we need to show that. */ - screen_width = gdk_screen_width (); - - gtk_widget_size_request (ecde->popup_window, &popup_requisition); - - /* Calculate the desired width. */ - *width = popup_requisition.width; - - /* Use at least the same width as the column. */ - if (*width < column_width) - *width = column_width; - - /* Check if it fits in the available height. */ - if (popup_requisition.height > avail_height) { - /* It doesn't fit, so we see if we have the minimum space - needed. */ - if (*y - row_height > avail_height) { - /* We don't, so we show the popup above the cell - instead of below it. */ - avail_height = *y - row_height; - *y -= (popup_requisition.height + row_height); - if (*y < 0) - *y = 0; - } - } - - /* We try to line it up with the right edge of the column, but we don't - want it to go off the edges of the screen. */ - if (*x > screen_width) - *x = screen_width; - *x -= *width; - if (*x < 0) - *x = 0; - - *height = popup_requisition.height; -} - - -/* This handles key press events in the popup window. If the Escape key is - pressed we hide the popup, and do not change the cell contents. */ -static int -e_cell_date_edit_key_press (GtkWidget *popup_window, - GdkEventKey *event, - ECellDateEdit *ecde) -{ - g_print ("In e_cell_date_edit_key_press\n"); - - /* If the Escape key is pressed we hide the popup. */ - if (event->keyval != GDK_Escape) - return FALSE; - - e_cell_date_edit_hide_popup (ecde); - - return TRUE; -} - - -/* Clears the time list and rebuilds it using the lower_hour, upper_hour - and use_24_hour_format settings. */ -static void -e_cell_date_edit_rebuild_time_list (ECellDateEdit *ecde) -{ - GtkList *list; - GtkWidget *listitem; - char buffer[40], *format; - struct tm tmp_tm; - gint hour, min; - - list = GTK_LIST (ecde->time_list); - - gtk_list_clear_items (list, 0, -1); - - /* Fill the struct tm with some sane values. */ - tmp_tm.tm_year = 2000; - tmp_tm.tm_mon = 0; - tmp_tm.tm_mday = 1; - tmp_tm.tm_sec = 0; - tmp_tm.tm_isdst = 0; - - for (hour = ecde->lower_hour; hour <= ecde->upper_hour; hour++) { - - /* We don't want to display midnight at the end, since that is - really in the next day. */ - if (hour == 24) - break; - - /* We want to finish on upper_hour, with min == 0. */ - for (min = 0; - min == 0 || (min < 60 && hour != ecde->upper_hour); - min += 30) { - tmp_tm.tm_hour = hour; - tmp_tm.tm_min = min; - e_time_format_time (&tmp_tm, ecde->use_24_hour_format, - FALSE, buffer, sizeof (buffer)); - listitem = gtk_list_item_new_with_label (buffer); - gtk_widget_show (listitem); - gtk_container_add (GTK_CONTAINER (list), listitem); - } - } - - ecde->need_time_list_rebuild = FALSE; -} - - -static void -e_cell_date_edit_on_ok_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - ECalendarItem *calitem; - GDate start_date, end_date; - gboolean day_selected; - struct tm date_tm; - char buffer[64], *text; - ETimeParseStatus status; - - calitem = E_CALENDAR_ITEM (E_CALENDAR (ecde->calendar)->calitem); - day_selected = e_calendar_item_get_selection (calitem, &start_date, - &end_date); - - text = gtk_entry_get_text (GTK_ENTRY (ecde->time_entry)); - status = e_time_parse_time (text, &date_tm); - if (status == E_TIME_PARSE_INVALID) { - e_cell_date_edit_show_time_invalid_warning (ecde); - return; - } - - if (day_selected) { - date_tm.tm_year = g_date_year (&start_date) - 1900; - date_tm.tm_mon = g_date_month (&start_date) - 1; - date_tm.tm_mday = g_date_day (&start_date); - /* We need to call this to set the weekday. */ - mktime (&date_tm); - e_time_format_date_and_time (&date_tm, - ecde->use_24_hour_format, - TRUE, FALSE, - buffer, sizeof (buffer)); - } else { - buffer[0] = '\0'; - } - - e_cell_date_edit_update_cell (ecde, buffer); - e_cell_date_edit_hide_popup (ecde); -} - - -static void -e_cell_date_edit_show_time_invalid_warning (ECellDateEdit *ecde) -{ - GtkWidget *dialog; - struct tm date_tm; - char buffer[64], *message; - - /* Create a useful error message showing the correct format. */ - date_tm.tm_year = 100; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = 1; - date_tm.tm_min = 30; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - e_time_format_time (&date_tm, ecde->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - message = g_strdup_printf (_("The time must be in the format: %s"), - buffer); - - dialog = gnome_message_box_new (message, GNOME_MESSAGE_BOX_ERROR, - GNOME_STOCK_BUTTON_OK, NULL); - /* FIXME: Fix transient settings - I'm not sure it works with popup - windows. Maybe we need to use a normal window without decorations.*/ - gtk_window_set_transient_for (GTK_WINDOW (dialog), - GTK_WINDOW (ecde->popup_window)); - gnome_dialog_run (GNOME_DIALOG (dialog)); - - g_free (message); -} - - -static void -e_cell_date_edit_on_now_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - struct tm *tmp_tm; - time_t t; - char buffer[64]; - - g_print ("In e_cell_date_edit_on_now_clicked\n"); - - t = time (NULL); - tmp_tm = localtime (&t); - e_time_format_date_and_time (tmp_tm, - ecde->use_24_hour_format, - TRUE, FALSE, - buffer, sizeof (buffer)); - - e_cell_date_edit_update_cell (ecde, buffer); - e_cell_date_edit_hide_popup (ecde); -} - - -static void -e_cell_date_edit_on_none_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - g_print ("In e_cell_date_edit_on_none_clicked\n"); - - e_cell_date_edit_update_cell (ecde, ""); - e_cell_date_edit_hide_popup (ecde); -} - - -static void -e_cell_date_edit_on_today_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - struct tm *tmp_tm; - time_t t; - char buffer[64]; - - g_print ("In e_cell_date_edit_on_today_clicked\n"); - - t = time (NULL); - tmp_tm = localtime (&t); - tmp_tm->tm_hour = 0; - tmp_tm->tm_min = 0; - tmp_tm->tm_sec = 0; - e_time_format_date_and_time (tmp_tm, - ecde->use_24_hour_format, - FALSE, FALSE, - buffer, sizeof (buffer)); - - e_cell_date_edit_update_cell (ecde, buffer); - e_cell_date_edit_hide_popup (ecde); -} - - -static void -e_cell_date_edit_update_cell (ECellDateEdit *ecde, - char *text) -{ - ECellPopup *ecp = E_CELL_POPUP (ecde); - ECellView *ecv = (ECellView*) ecp->popup_cell_view; - ETableItem *eti = E_TABLE_ITEM (ecv->e_table_item_view); - ETableCol *ecol; - gchar *old_text; - - /* Compare the new text with the existing cell contents. */ - ecol = e_table_header_get_column (eti->header, ecp->popup_view_col); - old_text = e_table_model_value_at (ecv->e_table_model, - ecol->col_idx, ecp->popup_row); - - /* If they are different, update the cell contents. */ - if (strcmp (old_text, text)) { - e_table_model_set_value_at (ecv->e_table_model, - ecol->col_idx, ecp->popup_row, - text); - } -} - - -static void -e_cell_date_edit_on_time_selected (GtkList *list, - ECellDateEdit *ecde) -{ - GtkWidget *listitem, *label; - char *list_item_text; - - g_print ("In e_cell_date_edit_on_time_selected\n"); - - if (!list->selection) - return; - - listitem = list->selection->data; - label = GTK_BIN (listitem)->child; - gtk_label_get (GTK_LABEL (label), &list_item_text); - gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), list_item_text); -} - - -static void -e_cell_date_edit_hide_popup (ECellDateEdit *ecde) -{ - gtk_grab_remove (ecde->popup_window); - gtk_widget_hide (ecde->popup_window); - E_CELL_POPUP (ecde)->popup_shown = FALSE; -} - - -/* These freeze and thaw the rebuilding of the time list. They are useful when - setting several properties which result in rebuilds of the list, e.g. the - lower_hour, upper_hour and use_24_hour_format properties. */ -void -e_cell_date_edit_freeze (ECellDateEdit *ecde) -{ - g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde)); - - ecde->freeze_count++; -} - - -void -e_cell_date_edit_thaw (ECellDateEdit *ecde) -{ - g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde)); - - if (ecde->freeze_count > 0) { - ecde->freeze_count--; - - if (ecde->freeze_count == 0) - e_cell_date_edit_rebuild_time_list (ecde); - } -} - diff --git a/widgets/misc/e-cell-date-edit.h b/widgets/misc/e-cell-date-edit.h deleted file mode 100644 index f3f8beb02b..0000000000 --- a/widgets/misc/e-cell-date-edit.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2001, Ximian, 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 - */ - -/* - * ECellDateEdit - a subclass of ECellPopup used to show a date with a popup - * window to edit it. - */ - -#ifndef _E_CELL_DATE_EDIT_H_ -#define _E_CELL_DATE_EDIT_H_ - -#include <gal/e-table/e-cell-popup.h> - -#define E_CELL_DATE_EDIT_TYPE (e_cell_date_edit_get_type ()) -#define E_CELL_DATE_EDIT(o) (GTK_CHECK_CAST ((o), E_CELL_DATE_EDIT_TYPE, ECellDateEdit)) -#define E_CELL_DATE_EDIT_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_CELL_DATE_EDIT_TYPE, ECellDateEditClass)) -#define E_IS_CELL_DATE_EDIT(o) (GTK_CHECK_TYPE ((o), E_CELL_DATE_EDIT_TYPE)) -#define E_IS_CELL_DATE_EDIT_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CELL_DATE_EDIT_TYPE)) - - -typedef struct { - ECellPopup parent; - - GtkWidget *popup_window; - GtkWidget *calendar; - GtkWidget *time_entry; - GtkWidget *time_list; - - GtkWidget *now_button; - GtkWidget *today_button; - GtkWidget *none_button; - - /* This is the range of hours we show in the time list. */ - gint lower_hour; - gint upper_hour; - - /* TRUE if we use 24-hour format for the time list and entry. */ - gboolean use_24_hour_format; - - /* This is TRUE if we need to rebuild the list of times. */ - gboolean need_time_list_rebuild; - - /* The freeze count for rebuilding the time list. We only rebuild when - this is 0. */ - gint freeze_count; -} ECellDateEdit; - -typedef struct { - ECellPopupClass parent_class; -} ECellDateEditClass; - - -GtkType e_cell_date_edit_get_type (void); -ECell *e_cell_date_edit_new (void); - - -/* These freeze and thaw the rebuilding of the time list. They are useful when - setting several properties which result in rebuilds of the list, e.g. the - lower_hour, upper_hour and use_24_hour_format properties. */ -void e_cell_date_edit_freeze (ECellDateEdit *ecde); -void e_cell_date_edit_thaw (ECellDateEdit *ecde); - -#endif /* _E_CELL_DATE_EDIT_H_ */ diff --git a/widgets/misc/e-clipped-label.c b/widgets/misc/e-clipped-label.c deleted file mode 100644 index 8675b544dd..0000000000 --- a/widgets/misc/e-clipped-label.c +++ /dev/null @@ -1,384 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 1999, Helix Code, 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 - */ - -/* - * This is similar to GtkLabel but clips itself and displays '...' if it - * can't fit inside its allocated area. The intended use is for inside buttons - * that are a fixed size. The GtkLabel would normally display only the middle - * part of the text, which doesn't look very good. This only supports one line - * of text (so no wrapping/justification), without underlined characters. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-clipped-label.h" - -#include <math.h> -#include <string.h> - -#include <glib.h> -#include <gdk/gdki18n.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> - - -static void e_clipped_label_class_init (EClippedLabelClass *class); -static void e_clipped_label_init (EClippedLabel *label); -static void e_clipped_label_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void e_clipped_label_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gint e_clipped_label_expose (GtkWidget *widget, - GdkEventExpose *event); -static void e_clipped_label_recalc_chars_displayed (EClippedLabel *label); -static void e_clipped_label_destroy (GtkObject *object); - - -static GtkMiscClass *parent_class; - -/* This is the string to draw when the label is clipped, e.g. '...'. */ -static gchar *e_clipped_label_ellipsis; - -/* Flags used in chars_displayed field. Must be negative. */ -#define E_CLIPPED_LABEL_NEED_RECALC -1 -#define E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL -2 - - -GtkType -e_clipped_label_get_type (void) -{ - static GtkType e_clipped_label_type = 0; - - if (!e_clipped_label_type){ - GtkTypeInfo e_clipped_label_info = { - "EClippedLabel", - sizeof (EClippedLabel), - sizeof (EClippedLabelClass), - (GtkClassInitFunc) e_clipped_label_class_init, - (GtkObjectInitFunc) e_clipped_label_init, - NULL, /* reserved 1 */ - NULL, /* reserved 2 */ - (GtkClassInitFunc) NULL - }; - - parent_class = gtk_type_class (GTK_TYPE_MISC); - e_clipped_label_type = gtk_type_unique (GTK_TYPE_MISC, - &e_clipped_label_info); - } - - return e_clipped_label_type; -} - - -static void -e_clipped_label_class_init (EClippedLabelClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - /* Method override */ - widget_class->size_request = e_clipped_label_size_request; - widget_class->size_allocate = e_clipped_label_size_allocate; - widget_class->expose_event = e_clipped_label_expose; - - object_class->destroy = e_clipped_label_destroy; - - e_clipped_label_ellipsis = _("..."); -} - - -static void -e_clipped_label_init (EClippedLabel *label) -{ - GTK_WIDGET_SET_FLAGS (label, GTK_NO_WINDOW); - - label->label = NULL; - label->label_wc = NULL; - label->chars_displayed = E_CLIPPED_LABEL_NEED_RECALC; -} - - -/** - * e_clipped_label_new: - * - * @text: The label text. - * @Returns: A new #EClippedLabel. - * - * Creates a new #EClippedLabel with the given text. - **/ -GtkWidget * -e_clipped_label_new (const gchar *text) -{ - GtkWidget *label; - - label = GTK_WIDGET (gtk_type_new (e_clipped_label_get_type ())); - - if (text && *text) - e_clipped_label_set_text (E_CLIPPED_LABEL (label), text); - - return label; -} - - -static void -e_clipped_label_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - EClippedLabel *label; - GdkFont *font; - - g_return_if_fail (E_IS_CLIPPED_LABEL (widget)); - g_return_if_fail (requisition != NULL); - - label = E_CLIPPED_LABEL (widget); - font = widget->style->font; - - requisition->width = 0; - requisition->height = font->ascent + font->descent - + 2 * GTK_MISC (widget)->ypad; -} - - -static void -e_clipped_label_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - EClippedLabel *label; - - label = E_CLIPPED_LABEL (widget); - - widget->allocation = *allocation; - - /* Flag that we need to recalculate how many characters to display. */ - label->chars_displayed = E_CLIPPED_LABEL_NEED_RECALC; -} - - -static gint -e_clipped_label_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - EClippedLabel *label; - GtkMisc *misc; - gint x, y; - GdkFont *font; - gchar *tmp_str, tmp_ch; - - g_return_val_if_fail (E_IS_CLIPPED_LABEL (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - label = E_CLIPPED_LABEL (widget); - misc = GTK_MISC (widget); - font = widget->style->font; - - /* If the label isn't visible or has no text, just return. */ - if (!GTK_WIDGET_VISIBLE (widget) || !GTK_WIDGET_MAPPED (widget) - || !label->label || (*label->label == '\0')) - return TRUE; - - /* Recalculate the number of characters displayed, if necessary. */ - if (label->chars_displayed == E_CLIPPED_LABEL_NEED_RECALC) - e_clipped_label_recalc_chars_displayed (label); - - /* - * GC Clipping - */ - gdk_gc_set_clip_rectangle (widget->style->white_gc, - &event->area); - gdk_gc_set_clip_rectangle (widget->style->fg_gc[widget->state], - &event->area); - - y = floor (widget->allocation.y + (gint)misc->ypad - + (((gint)widget->allocation.height - 2 * (gint)misc->ypad - - (gint)font->ascent - font->descent) - * misc->yalign) + 0.5) + font->ascent; - - if (label->chars_displayed == E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL) { - x = floor (widget->allocation.x + (gint)misc->xpad - + (((gint)widget->allocation.width - - (gint)label->label_width - 2 * (gint)misc->xpad) - * misc->xalign) + 0.5); - - gtk_paint_string (widget->style, widget->window, widget->state, - &event->area, widget, "label", - x, y, label->label); - } else { - x = widget->allocation.x + (gint)misc->xpad; - - tmp_ch = label->label_wc[label->chars_displayed]; - label->label_wc[label->chars_displayed] = '\0'; - tmp_str = gdk_wcstombs (label->label_wc); - if (tmp_str) { - gtk_paint_string (widget->style, widget->window, - widget->state, &event->area, - widget, "label", - x, y, tmp_str); - g_free (tmp_str); - } - label->label_wc[label->chars_displayed] = tmp_ch; - - x = widget->allocation.x + (gint)misc->xpad - + label->ellipsis_x; - gtk_paint_string (widget->style, widget->window, widget->state, - &event->area, widget, "label", - x, y, e_clipped_label_ellipsis); - } - - gdk_gc_set_clip_mask (widget->style->white_gc, NULL); - gdk_gc_set_clip_mask (widget->style->fg_gc[widget->state], NULL); - - return TRUE; -} - - -static void -e_clipped_label_destroy (GtkObject *object) -{ - EClippedLabel *label; - - g_return_if_fail (E_IS_CLIPPED_LABEL (object)); - - label = E_CLIPPED_LABEL(object); - - g_free (label->label); - g_free (label->label_wc); -} - - -/** - * e_clipped_label_get_text: - * - * @label: An #EClippedLabel. - * @Return: The label text. - * - * Returns the label text, or NULL. - **/ -gchar* -e_clipped_label_get_text (EClippedLabel *label) -{ - g_return_val_if_fail (E_IS_CLIPPED_LABEL (label), NULL); - - return label->label; -} - - -/** - * e_clipped_label_set_text: - * - * @label: An #EClippedLabel. - * @text: The new label text. - * - * Sets the label text. - **/ -void -e_clipped_label_set_text (EClippedLabel *label, - const gchar *text) -{ - gint len; - - g_return_if_fail (E_IS_CLIPPED_LABEL (label)); - - if (label->label != text || !label->label || !text - || strcmp (label->label, text)) { - g_free (label->label); - g_free (label->label_wc); - label->label = NULL; - label->label_wc = NULL; - - if (text) { - label->label = g_strdup (text); - len = strlen (text); - label->label_wc = g_new (GdkWChar, len + 1); - label->wc_len = gdk_mbstowcs (label->label_wc, - label->label, len + 1); - label->label_wc[label->wc_len] = '\0'; - } - - /* Reset the number of characters displayed, so it is - recalculated when needed. */ - label->chars_displayed = E_CLIPPED_LABEL_NEED_RECALC; - - /* We don't queue a resize, since the label should not affect - the widget size, but we queue a draw. */ - gtk_widget_queue_draw (GTK_WIDGET (label)); - } -} - - -static void -e_clipped_label_recalc_chars_displayed (EClippedLabel *label) -{ - GdkFont *font; - gint max_width, width, ch, last_width; - - font = GTK_WIDGET (label)->style->font; - - max_width = GTK_WIDGET (label)->allocation.width - - 2 * GTK_MISC (label)->xpad; - - if (!label->label) { - label->chars_displayed = 0; - return; - } - - /* See if the entire label fits in the allocated width. */ - label->label_width = gdk_string_width (font, label->label); - if (label->label_width <= max_width) { - label->chars_displayed = E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL; - return; - } - - /* Calculate the width of the ellipsis string. */ - max_width -= gdk_string_measure (font, e_clipped_label_ellipsis); - - if (max_width <= 0) { - label->chars_displayed = 0; - label->ellipsis_x = 0; - return; - } - - /* Step through the wide-char label, adding on the widths of the - characters, until we can't fit any more in. */ - width = last_width = 0; - for (ch = 0; ch < label->wc_len; ch++) { - width += gdk_char_width_wc (font, label->label_wc[ch]); - - if (width > max_width) { - label->chars_displayed = ch; - label->ellipsis_x = last_width; - return; - } - - last_width = width; - } - - g_warning ("Clipped label width not exceeded as expected"); - label->chars_displayed = E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL; -} - diff --git a/widgets/misc/e-clipped-label.h b/widgets/misc/e-clipped-label.h deleted file mode 100644 index a21ceadeca..0000000000 --- a/widgets/misc/e-clipped-label.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 1999, Helix Code, 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 - */ - -/* - * This is similar to GtkLabel but clips itself and displays '...' if it - * can't fit inside its allocated area. The intended use is for inside buttons - * that are a fixed size. The GtkLabel would normally display only the middle - * part of the text, which doesn't look very good. This only supports one line - * of text (so no wrapping/justification), without underlined characters. - */ -#ifndef _E_CLIPPED_LABEL_H_ -#define _E_CLIPPED_LABEL_H_ - -#include <gtk/gtkmisc.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define E_CLIPPED_LABEL(obj) GTK_CHECK_CAST (obj, e_clipped_label_get_type (), EClippedLabel) -#define E_CLIPPED_LABEL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_clipped_label_get_type (), EClippedLabelClass) -#define E_IS_CLIPPED_LABEL(obj) GTK_CHECK_TYPE (obj, e_clipped_label_get_type ()) - - -typedef struct _EClippedLabel EClippedLabel; -typedef struct _EClippedLabelClass EClippedLabelClass; - -struct _EClippedLabel -{ - GtkMisc misc; - - gchar *label; - GdkWChar *label_wc; - - /* This is the number of wide characters in the label. */ - gint wc_len; - - /* This is the width of the entire label string, in pixels. */ - gint label_width; - - /* This is the number of characters we can fit in, or - E_CLIPPED_LABEL_NEED_RECALC if it needs to be recalculated, or - E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL to show the entire label. */ - gint chars_displayed; - - /* This is the x position to display the ellipsis string, e.g. '...', - relative to the start of the label. */ - gint ellipsis_x; -}; - -struct _EClippedLabelClass -{ - GtkMiscClass parent_class; -}; - - -GtkType e_clipped_label_get_type (void); -GtkWidget* e_clipped_label_new (const gchar *text); - -gchar* e_clipped_label_get_text (EClippedLabel *label); -void e_clipped_label_set_text (EClippedLabel *label, - const gchar *text); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_CLIPPED_LABEL_H_ */ diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c deleted file mode 100644 index af8c968f50..0000000000 --- a/widgets/misc/e-dateedit.c +++ /dev/null @@ -1,1733 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 2000, Helix Code, Inc. - * - * Based on the GnomeDateEdit, part of the Gnome Library. - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * - * 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 - */ - -/* - * EDateEdit - a widget based on GnomeDateEdit to provide a date & optional - * time field with popups for entering a date. - */ - -/* We need this for strptime. */ -#define _XOPEN_SOURCE 4 - -#include <config.h> - -#include "e-dateedit.h" - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtkarrow.h> -#include <gtk/gtkbbox.h> -#include <gtk/gtkcombo.h> -#include <gtk/gtkdrawingarea.h> -#include <gtk/gtkentry.h> -#include <gtk/gtkframe.h> -#include <gtk/gtkhbbox.h> -#include <gtk/gtklabel.h> -#include <gtk/gtklist.h> -#include <gtk/gtkmenu.h> -#include <gtk/gtkmenuitem.h> -#include <gtk/gtkoptionmenu.h> -#include <gtk/gtkwindow.h> -#include <gtk/gtkmain.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkvbox.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include "e-calendar.h" - - - -struct _EDateEditPrivate { - GtkWidget *date_entry; - GtkWidget *date_button; - - GtkWidget *space; - - GtkWidget *time_combo; - - GtkWidget *cal_popup; - GtkWidget *calendar; - GtkWidget *now_button; - GtkWidget *today_button; - GtkWidget *none_button; /* This will only be visible if a - 'None' date/time is permitted. */ - - gboolean show_date; - gboolean show_time; - gboolean use_24_hour_format; - - /* This is the range of hours we show in the time popup. */ - gint lower_hour; - gint upper_hour; - - /* This indicates whether the last date committed was invalid. - (A date is committed by hitting Return, moving the keyboard focus, - or selecting a date in the popup). Note that this only indicates - that the date couldn't be parsed. A date set to 'None' is valid - here, though e_date_edit_date_is_valid() will return FALSE if an - empty date isn't actually permitted. */ - gboolean date_is_valid; - - /* This is the last valid date which was set. If the date was set to - 'None' or empty, date_set_to_none will be TRUE and the other fields - are undefined, so don't use them. */ - gboolean date_set_to_none; - gint year; - gint month; - gint day; - - /* This indicates whether the last time committed was invalid. - (A time is committed by hitting Return, moving the keyboard focus, - or selecting a time in the popup). Note that this only indicates - that the time couldn't be parsed. An empty/None time is valid - here, though e_date_edit_time_is_valid() will return FALSE if an - empty time isn't actually permitted. */ - gboolean time_is_valid; - - /* This is the last valid time which was set. If the time was set to - 'None' or empty, time_set_to_none will be TRUE and the other fields - are undefined, so don't use them. */ - gboolean time_set_to_none; - gint hour; - gint minute; -}; - -enum { - CHANGED, - LAST_SIGNAL -}; - - -static gint date_edit_signals [LAST_SIGNAL] = { 0 }; - - -static void e_date_edit_class_init (EDateEditClass *class); -static void e_date_edit_init (EDateEdit *dedit); -static void create_children (EDateEdit *dedit); -static void e_date_edit_destroy (GtkObject *object); -static void e_date_edit_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); - -static gint on_date_entry_key_press (GtkWidget *widget, - GdkEventKey *event, - EDateEdit *dedit); -static void on_date_button_clicked (GtkWidget *widget, - EDateEdit *dedit); -static void e_date_edit_show_date_popup (EDateEdit *dedit); -static void position_date_popup (EDateEdit *dedit); -static void on_date_popup_none_button_clicked (GtkWidget *button, - EDateEdit *dedit); -static void on_date_popup_today_button_clicked (GtkWidget *button, - EDateEdit *dedit); -static void on_date_popup_now_button_clicked (GtkWidget *button, - EDateEdit *dedit); -static gint on_date_popup_delete_event (GtkWidget *widget, - EDateEdit *dedit); -static gint on_date_popup_key_press (GtkWidget *widget, - GdkEventKey *event, - EDateEdit *dedit); -static gint on_date_popup_button_press (GtkWidget *widget, - GdkEventButton *event, - gpointer data); -static void on_date_popup_date_selected (ECalendarItem *calitem, - EDateEdit *dedit); -static void hide_date_popup (EDateEdit *dedit); -static void rebuild_time_popup (EDateEdit *dedit); -static gboolean field_set_to_none (char *text); -static gboolean e_date_edit_parse_date (EDateEdit *dedit, - char *date_text, - struct tm *date_tm); -static gboolean e_date_edit_parse_time (EDateEdit *dedit, - gchar *time_text, - struct tm *time_tm); -static void on_date_edit_time_selected (GtkList *list, - EDateEdit *dedit); -static gint on_time_entry_key_press (GtkWidget *widget, - GdkEventKey *event, - EDateEdit *dedit); -static gint on_date_entry_focus_out (GtkEntry *entry, - GdkEventFocus *event, - EDateEdit *dedit); -static gint on_time_entry_focus_out (GtkEntry *entry, - GdkEventFocus *event, - EDateEdit *dedit); -static void e_date_edit_update_date_entry (EDateEdit *dedit); -static void e_date_edit_update_time_entry (EDateEdit *dedit); -static void e_date_edit_update_time_combo_state (EDateEdit *dedit); -static void e_date_edit_check_date_changed (EDateEdit *dedit); -static void e_date_edit_check_time_changed (EDateEdit *dedit); -static gboolean e_date_edit_set_date_internal (EDateEdit *dedit, - gboolean valid, - gboolean none, - gint year, - gint month, - gint day); -static gboolean e_date_edit_set_time_internal (EDateEdit *dedit, - gboolean valid, - gboolean none, - gint hour, - gint minute); - - -static GtkHBoxClass *parent_class; - -/** - * e_date_edit_get_type: - * - * Returns the GtkType for the EDateEdit widget - */ -guint -e_date_edit_get_type (void) -{ - static guint date_edit_type = 0; - - if (!date_edit_type){ - GtkTypeInfo date_edit_info = { - "EDateEdit", - sizeof (EDateEdit), - sizeof (EDateEditClass), - (GtkClassInitFunc) e_date_edit_class_init, - (GtkObjectInitFunc) e_date_edit_init, - NULL, - NULL, - }; - - date_edit_type = gtk_type_unique (gtk_hbox_get_type (), &date_edit_info); - } - - return date_edit_type; -} - - -static void -e_date_edit_class_init (EDateEditClass *class) -{ - GtkObjectClass *object_class = (GtkObjectClass *) class; - GtkContainerClass *container_class = (GtkContainerClass *) class; - - object_class = (GtkObjectClass*) class; - - parent_class = gtk_type_class (gtk_hbox_get_type ()); - - date_edit_signals [CHANGED] = - gtk_signal_new ("changed", - GTK_RUN_FIRST, object_class->type, - GTK_SIGNAL_OFFSET (EDateEditClass, - changed), - gtk_signal_default_marshaller, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, date_edit_signals, - LAST_SIGNAL); - - object_class->destroy = e_date_edit_destroy; - - container_class->forall = e_date_edit_forall; - - class->changed = NULL; -} - - -static void -e_date_edit_init (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - - dedit->priv = priv = g_new0 (EDateEditPrivate, 1); - - priv->show_date = TRUE; - priv->show_time = TRUE; - priv->use_24_hour_format = TRUE; - - priv->lower_hour = 0; - priv->upper_hour = 24; - - priv->date_is_valid = TRUE; - priv->date_set_to_none = TRUE; - priv->time_is_valid = TRUE; - priv->time_set_to_none = TRUE; - - create_children (dedit); - - /* Set it to the current time. */ - e_date_edit_set_time (dedit, 0); -} - - -/** - * e_date_edit_new: - * - * Description: Creates a new #EDateEdit widget which can be used - * to provide an easy to use way for entering dates and times. - * - * Returns: a new #EDateEdit widget. - */ -GtkWidget * -e_date_edit_new (void) -{ - EDateEdit *dedit; - - dedit = gtk_type_new (e_date_edit_get_type ()); - - return GTK_WIDGET (dedit); -} - - -static void -create_children (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - ECalendar *calendar; - GtkWidget *frame, *arrow; - GtkWidget *vbox, *bbox; - - priv = dedit->priv; - - priv->date_entry = gtk_entry_new (); - gtk_widget_set_usize (priv->date_entry, 90, 0); - gtk_box_pack_start (GTK_BOX (dedit), priv->date_entry, FALSE, TRUE, 0); - - gtk_signal_connect (GTK_OBJECT (priv->date_entry), "key_press_event", - (GtkSignalFunc) on_date_entry_key_press, - dedit); - gtk_signal_connect_after (GTK_OBJECT (priv->date_entry), - "focus_out_event", - (GtkSignalFunc) on_date_entry_focus_out, - dedit); - - priv->date_button = gtk_button_new (); - gtk_signal_connect (GTK_OBJECT (priv->date_button), "clicked", - GTK_SIGNAL_FUNC (on_date_button_clicked), dedit); - gtk_box_pack_start (GTK_BOX (dedit), priv->date_button, - FALSE, FALSE, 0); - - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT); - gtk_container_add (GTK_CONTAINER (priv->date_button), arrow); - gtk_widget_show (arrow); - - if (priv->show_date) { - gtk_widget_show (priv->date_entry); - gtk_widget_show (priv->date_button); - } - - /* This is just to create a space between the date & time parts. */ - priv->space = gtk_drawing_area_new (); - gtk_box_pack_start (GTK_BOX (dedit), priv->space, FALSE, FALSE, 2); - - - priv->time_combo = gtk_combo_new (); - gtk_widget_set_usize (GTK_COMBO (priv->time_combo)->entry, 90, 0); - gtk_box_pack_start (GTK_BOX (dedit), priv->time_combo, FALSE, TRUE, 0); - rebuild_time_popup (dedit); - - gtk_signal_connect (GTK_OBJECT (GTK_COMBO (priv->time_combo)->entry), - "key_press_event", - (GtkSignalFunc) on_time_entry_key_press, - dedit); - gtk_signal_connect_after (GTK_OBJECT (GTK_COMBO (priv->time_combo)->entry), - "focus_out_event", - (GtkSignalFunc) on_time_entry_focus_out, - dedit); - gtk_signal_connect_after (GTK_OBJECT (GTK_COMBO (priv->time_combo)->list), - "selection_changed", - (GtkSignalFunc) on_date_edit_time_selected, - dedit); - - if (priv->show_time) - gtk_widget_show (priv->time_combo); - - if (priv->show_date && priv->show_time) - gtk_widget_show (priv->space); - - priv->cal_popup = gtk_window_new (GTK_WINDOW_POPUP); - gtk_widget_set_events (priv->cal_popup, - gtk_widget_get_events (priv->cal_popup) - | GDK_KEY_PRESS_MASK); - gtk_signal_connect (GTK_OBJECT (priv->cal_popup), "delete_event", - (GtkSignalFunc) on_date_popup_delete_event, - dedit); - gtk_signal_connect (GTK_OBJECT (priv->cal_popup), "key_press_event", - (GtkSignalFunc) on_date_popup_key_press, - dedit); - gtk_signal_connect (GTK_OBJECT (priv->cal_popup), "button_press_event", - (GtkSignalFunc) on_date_popup_button_press, - dedit); - gtk_window_set_policy (GTK_WINDOW (priv->cal_popup), - FALSE, FALSE, TRUE); - - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); - gtk_container_add (GTK_CONTAINER (priv->cal_popup), frame); - gtk_widget_show (frame); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (frame), vbox); - gtk_widget_show (vbox); - - priv->calendar = e_calendar_new (); - calendar = E_CALENDAR (priv->calendar); - gnome_canvas_item_set (GNOME_CANVAS_ITEM (calendar->calitem), - "maximum_days_selected", 1, - "move_selection_when_moving", FALSE, - NULL); - - gtk_signal_connect (GTK_OBJECT (calendar->calitem), - "selection_changed", - GTK_SIGNAL_FUNC (on_date_popup_date_selected), dedit); - - gtk_box_pack_start (GTK_BOX (vbox), priv->calendar, FALSE, FALSE, 0); - gtk_widget_show (priv->calendar); - - bbox = gtk_hbutton_box_new (); - gtk_container_set_border_width (GTK_CONTAINER (bbox), 4); - gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 2); - gtk_button_box_set_child_ipadding (GTK_BUTTON_BOX (bbox), 2, 0); - gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), 0, 0); - gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0); - gtk_widget_show (bbox); - - priv->now_button = gtk_button_new_with_label (_("Now")); - gtk_container_add (GTK_CONTAINER (bbox), priv->now_button); - gtk_widget_show (priv->now_button); - gtk_signal_connect (GTK_OBJECT (priv->now_button), "clicked", - GTK_SIGNAL_FUNC (on_date_popup_now_button_clicked), dedit); - - priv->today_button = gtk_button_new_with_label (_("Today")); - gtk_container_add (GTK_CONTAINER (bbox), priv->today_button); - gtk_widget_show (priv->today_button); - gtk_signal_connect (GTK_OBJECT (priv->today_button), "clicked", - GTK_SIGNAL_FUNC (on_date_popup_today_button_clicked), dedit); - - /* Note that we don't show this here, since by default a 'None' date - is not permitted. */ - priv->none_button = gtk_button_new_with_label (_("None")); - gtk_container_add (GTK_CONTAINER (bbox), priv->none_button); - gtk_signal_connect (GTK_OBJECT (priv->none_button), "clicked", - GTK_SIGNAL_FUNC (on_date_popup_none_button_clicked), dedit); -} - - -static void -e_date_edit_destroy (GtkObject *object) -{ - EDateEdit *dedit; - - g_return_if_fail (E_IS_DATE_EDIT (object)); - - dedit = E_DATE_EDIT (object); - - gtk_widget_destroy (dedit->priv->cal_popup); - dedit->priv->cal_popup = NULL; - - g_free (dedit->priv); - dedit->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -static void -e_date_edit_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - g_return_if_fail (E_IS_DATE_EDIT (container)); - g_return_if_fail (callback != NULL); - - /* Let GtkBox handle the internal widgets if needed. */ - if (include_internals) { - if (GTK_CONTAINER_CLASS (parent_class)->forall) - (* GTK_CONTAINER_CLASS (parent_class)->forall) - (container, include_internals, - callback, callback_data); - } -} - - -/** - * e_date_edit_get_time: - * @dedit: an #EDateEdit widget. - * @the_time: returns the last valid time entered. - * @Returns: the last valid time entered, or -1 if the time is not set. - * - * Returns the last valid time entered. If empty times are valid, by calling - * e_date_edit_set_allow_no_date_set(), then it may return -1. - * - * Note that the last time entered may actually have been invalid. You can - * check this with e_date_edit_time_is_valid(). - */ -time_t -e_date_edit_get_time (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - struct tm tmp_tm = { 0 }; - - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), -1); - - priv = dedit->priv; - - /* Try to parse any new value now. */ - e_date_edit_check_date_changed (dedit); - e_date_edit_check_time_changed (dedit); - - if (priv->date_set_to_none) - return -1; - - tmp_tm.tm_year = priv->year; - tmp_tm.tm_mon = priv->month; - tmp_tm.tm_mday = priv->day; - - if (!priv->show_time || priv->time_set_to_none) { - tmp_tm.tm_hour = 0; - tmp_tm.tm_min = 0; - } else { - tmp_tm.tm_hour = priv->hour; - tmp_tm.tm_min = priv->minute; - } - tmp_tm.tm_sec = 0; - tmp_tm.tm_isdst = -1; - - return mktime (&tmp_tm); -} - - -/** - * e_date_edit_set_time: - * @dedit: the EDateEdit widget - * @the_time: The time and date that should be set on the widget - * - * Description: Changes the displayed date and time in the EDateEdit - * widget to be the one represented by @the_time. If @the_time is 0 - * then current time is used. If it is -1, then the date is set to None. - */ -void -e_date_edit_set_time (EDateEdit *dedit, - time_t the_time) -{ - EDateEditPrivate *priv; - struct tm *tmp_tm; - gboolean date_changed = FALSE, time_changed = FALSE; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (the_time == -1) { - date_changed = e_date_edit_set_date_internal (dedit, TRUE, - TRUE, 0, 0, 0); - time_changed = e_date_edit_set_time_internal (dedit, TRUE, - TRUE, 0, 0); - } else { - if (the_time == 0) - the_time = time (NULL); - - tmp_tm = localtime (&the_time); - - date_changed = e_date_edit_set_date_internal (dedit, TRUE, - FALSE, - tmp_tm->tm_year, - tmp_tm->tm_mon, - tmp_tm->tm_mday); - time_changed = e_date_edit_set_time_internal (dedit, TRUE, - FALSE, - tmp_tm->tm_hour, - tmp_tm->tm_min); - } - - e_date_edit_update_date_entry (dedit); - e_date_edit_update_time_entry (dedit); - e_date_edit_update_time_combo_state (dedit); - - /* Emit the signals if the date and/or time has actually changed. */ - if (date_changed || time_changed) - gtk_signal_emit (GTK_OBJECT (dedit), - date_edit_signals [CHANGED]); -} - - -/** - * e_date_edit_get_date: - * @dedit: an #EDateEdit widget. - * @year: returns the year set. - * @month: returns the month set (1 - 12). - * @day: returns the day set (1 - 31). - * @Returns: TRUE if a time was set, or FALSE if the field is empty or 'None'. - * - * Returns the last valid date entered into the date field. - */ -gboolean -e_date_edit_get_date (EDateEdit *dedit, - gint *year, - gint *month, - gint *day) -{ - EDateEditPrivate *priv; - - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - priv = dedit->priv; - - /* Try to parse any new value now. */ - e_date_edit_check_date_changed (dedit); - - if (priv->date_set_to_none) - return FALSE; - - *year = priv->year + 1900; - *month = priv->month + 1; - *day = priv->day; - - return TRUE; -} - - -/** - * e_date_edit_set_date: - * @dedit: an #EDateEdit widget. - * @year: the year to set. - * @month: the month to set (1 - 12). - * @day: the day to set (1 - 31). - * - * Sets the date in the date field. - */ -void -e_date_edit_set_date (EDateEdit *dedit, - gint year, - gint month, - gint day) -{ - EDateEditPrivate *priv; - gboolean date_changed = FALSE; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - date_changed = e_date_edit_set_date_internal (dedit, TRUE, FALSE, - year - 1900, month - 1, - day); - - e_date_edit_update_date_entry (dedit); - e_date_edit_update_time_combo_state (dedit); - - /* Emit the signals if the date has actually changed. */ - if (date_changed) - gtk_signal_emit (GTK_OBJECT (dedit), - date_edit_signals [CHANGED]); -} - - -/** - * e_date_edit_get_time_of_day: - * @dedit: an #EDateEdit widget. - * @hour: returns the hour set. - * @minute: returns the minute set. - * @Returns: TRUE if a time was set, or FALSE if the field is empty or 'None'. - * - * Returns the last valid time entered into the time field. - */ -gboolean -e_date_edit_get_time_of_day (EDateEdit *dedit, - gint *hour, - gint *minute) -{ - EDateEditPrivate *priv; - - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - priv = dedit->priv; - - /* Try to parse any new value now. */ - e_date_edit_check_time_changed (dedit); - - if (priv->time_set_to_none) - return FALSE; - - *hour = priv->hour; - *minute = priv->minute; - - return TRUE; -} - - -/** - * e_date_edit_set_time_of_day: - * @dedit: an #EDateEdit widget. - * @hour: the hour to set. - * @minute: the minute to set. - * - * Description: Sets the time in the time field. - */ -void -e_date_edit_set_time_of_day (EDateEdit *dedit, - gint hour, - gint minute) -{ - EDateEditPrivate *priv; - gboolean time_changed = FALSE; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (priv->time_set_to_none - || priv->hour != hour - || priv->minute != minute) { - priv->time_set_to_none = FALSE; - priv->hour = hour; - priv->minute = minute; - time_changed = TRUE; - } - - e_date_edit_update_time_entry (dedit); - - if (time_changed) - gtk_signal_emit (GTK_OBJECT (dedit), - date_edit_signals [CHANGED]); -} - - -/** - * e_date_edit_get_show_date: - * @dedit: an #EDateEdit widget. - * @Returns: Whether the date field is shown. - * - * Description: Returns TRUE if the date field is currently shown. - */ -gboolean -e_date_edit_get_show_date (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE); - - return dedit->priv->show_date; -} - - -/** - * e_date_edit_set_show_date: - * @dedit: an #EDateEdit widget. - * @show_time: TRUE if the date field should be shown. - * - * Description: Specifies whether the date field should be shown. The date - * field would be hidden if only a time needed to be entered. - */ -void -e_date_edit_set_show_date (EDateEdit *dedit, - gboolean show_date) -{ - EDateEditPrivate *priv; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (priv->show_date == show_date) - return; - - priv->show_date = show_date; - - if (show_date) { - gtk_widget_show (priv->date_entry); - gtk_widget_show (priv->date_button); - } else { - gtk_widget_hide (priv->date_entry); - gtk_widget_hide (priv->date_button); - } - - e_date_edit_update_time_combo_state (dedit); - - if (priv->show_date && priv->show_time) - gtk_widget_show (priv->space); - else - gtk_widget_hide (priv->space); -} - - -/** - * e_date_edit_get_show_time: - * @dedit: an #EDateEdit widget - * @Returns: Whether the time field is shown. - * - * Description: Returns TRUE if the time field is currently shown. - */ -gboolean -e_date_edit_get_show_time (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE); - - return dedit->priv->show_time; -} - - -/** - * e_date_edit_set_show_time: - * @dedit: an #EDateEdit widget - * @show_time: TRUE if the time field should be shown. - * - * Description: Specifies whether the time field should be shown. The time - * field would be hidden if only a date needed to be entered. - */ -void -e_date_edit_set_show_time (EDateEdit *dedit, - gboolean show_time) -{ - EDateEditPrivate *priv; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (priv->show_time == show_time) - return; - - priv->show_time = show_time; - - if (show_time) { - gtk_widget_show (priv->time_combo); - } else { - gtk_widget_hide (priv->time_combo); - gtk_widget_hide (priv->now_button); - } - - if (priv->show_date && priv->show_time) - gtk_widget_show (priv->space); - else - gtk_widget_hide (priv->space); -} - - -/** - * e_date_edit_get_week_start_day: - * @dedit: an #EDateEdit widget - * @Returns: the week start day, from 0 (Sunday) to 6 (Saturday). - * - * Description: Returns the week start day currently used in the calendar - * popup. - */ -gint -e_date_edit_get_week_start_day (EDateEdit *dedit) -{ - gint week_start_day; - - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), 1); - - gtk_object_get (GTK_OBJECT (E_CALENDAR (dedit->priv->calendar)->calitem), - "week_start_day", &week_start_day, - NULL); - - return week_start_day; -} - - -/** - * e_date_edit_set_week_start_day: - * @dedit: an #EDateEdit widget - * @week_start_day: the week start day, from 0 (Sunday) to 6 (Saturday). - * - * Description: Sets the week start day to use in the calendar popup. - */ -void -e_date_edit_set_week_start_day (EDateEdit *dedit, - gint week_start_day) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem), - "week_start_day", week_start_day, - NULL); -} - - -/* Whether we show week numbers in the date popup. */ -gboolean -e_date_edit_get_show_week_numbers (EDateEdit *dedit) -{ - gboolean show_week_numbers; - - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - gtk_object_get (GTK_OBJECT (E_CALENDAR (dedit->priv->calendar)->calitem), - "show_week_numbers", &show_week_numbers, - NULL); - - return show_week_numbers; -} - - -void -e_date_edit_set_show_week_numbers (EDateEdit *dedit, - gboolean show_week_numbers) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem), - "show_week_numbers", show_week_numbers, - NULL); -} - - -/* Whether we use 24 hour format in the time field & popup. */ -gboolean -e_date_edit_get_use_24_hour_format (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE); - - return dedit->priv->use_24_hour_format; -} - - -void -e_date_edit_set_use_24_hour_format (EDateEdit *dedit, - gboolean use_24_hour_format) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - if (dedit->priv->use_24_hour_format == use_24_hour_format) - return; - - dedit->priv->use_24_hour_format = use_24_hour_format; - - rebuild_time_popup (dedit); - - e_date_edit_update_time_entry (dedit); -} - - -/* Whether we allow the date to be set to 'None'. e_date_edit_get_time() will - return (time_t) -1 in this case. */ -gboolean -e_date_edit_get_allow_no_date_set (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - return GTK_WIDGET_VISIBLE (dedit->priv->none_button); -} - - -void -e_date_edit_set_allow_no_date_set (EDateEdit *dedit, - gboolean allow_no_date_set) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - if (allow_no_date_set) { - gtk_widget_show (dedit->priv->none_button); - } else { - gtk_widget_hide (dedit->priv->none_button); - - /* If the date is showing, we make sure it isn't 'None' (we - don't really mind if the time is empty), else if just the - time is showing we make sure it isn't 'None'. */ - if (dedit->priv->show_date) { - if (dedit->priv->date_set_to_none) - e_date_edit_set_time (dedit, time (NULL)); - } else { - if (dedit->priv->time_set_to_none) - e_date_edit_set_time (dedit, time (NULL)); - } - } -} - - -/* The range of time to show in the time combo popup. */ -void -e_date_edit_get_time_popup_range (EDateEdit *dedit, - gint *lower_hour, - gint *upper_hour) -{ - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - *lower_hour = dedit->priv->lower_hour; - *upper_hour = dedit->priv->upper_hour; -} - - -void -e_date_edit_set_time_popup_range (EDateEdit *dedit, - gint lower_hour, - gint upper_hour) -{ - EDateEditPrivate *priv; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - priv = dedit->priv; - - if (priv->lower_hour == lower_hour - && priv->upper_hour == upper_hour) - return; - - priv->lower_hour = lower_hour; - priv->upper_hour = upper_hour; - - rebuild_time_popup (dedit); - - /* Setting the combo list items seems to mess up the time entry, so - we set it again. We have to reset it to its last valid time. */ - priv->time_is_valid = TRUE; - e_date_edit_update_time_entry (dedit); -} - - -/* The arrow button beside the date field has been clicked, so we show the - popup with the ECalendar in. */ -static void -on_date_button_clicked (GtkWidget *widget, - EDateEdit *dedit) -{ - e_date_edit_show_date_popup (dedit); -} - - -static void -e_date_edit_show_date_popup (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - ECalendar *calendar; - struct tm mtm; - gchar *date_text; - GDate selected_day; - gboolean clear_selection = FALSE; - - priv = dedit->priv; - calendar = E_CALENDAR (priv->calendar); - - date_text = gtk_entry_get_text (GTK_ENTRY (priv->date_entry)); - if (field_set_to_none (date_text) - || !e_date_edit_parse_date (dedit, date_text, &mtm)) - clear_selection = TRUE; - - if (clear_selection) { - e_calendar_item_set_selection (calendar->calitem, NULL, NULL); - } else { - g_date_clear (&selected_day, 1); - g_date_set_dmy (&selected_day, mtm.tm_mday, mtm.tm_mon + 1, - mtm.tm_year + 1900); - e_calendar_item_set_selection (calendar->calitem, - &selected_day, NULL); - } - - /* FIXME: Hack. Change ECalendarItem so it doesn't queue signal - emissions. */ - calendar->calitem->selection_changed = FALSE; - - position_date_popup (dedit); - gtk_widget_show (priv->cal_popup); - gtk_widget_grab_focus (priv->cal_popup); - gtk_grab_add (priv->cal_popup); - gdk_pointer_grab (priv->cal_popup->window, TRUE, - (GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_POINTER_MOTION_MASK), - NULL, NULL, GDK_CURRENT_TIME); -} - - -/* This positions the date popup below and to the left of the arrow button, - just before it is shown. */ -static void -position_date_popup (EDateEdit *dedit) -{ - gint x, y; - gint bwidth, bheight; - GtkRequisition req; - gint screen_width, screen_height; - - gtk_widget_size_request (dedit->priv->cal_popup, &req); - - gdk_window_get_origin (dedit->priv->date_button->window, &x, &y); - gdk_window_get_size (dedit->priv->date_button->window, - &bwidth, &bheight); - - screen_width = gdk_screen_width (); - screen_height = gdk_screen_height (); - - x += bwidth - req.width; - y += bheight; - - x = CLAMP (x, 0, MAX (0, screen_width - req.width)); - y = CLAMP (y, 0, MAX (0, screen_height - req.height)); - - gtk_widget_set_uposition (dedit->priv->cal_popup, x, y); -} - - -/* A date has been selected in the date popup, so we set the date field - and hide the popup. */ -static void -on_date_popup_date_selected (ECalendarItem *calitem, - EDateEdit *dedit) -{ - EDateEditPrivate *priv; - GDate start_date, end_date; - - priv = dedit->priv; - - hide_date_popup (dedit); - - if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) - return; - - e_date_edit_set_date (dedit, g_date_year (&start_date), - g_date_month (&start_date), - g_date_day (&start_date)); -} - - -static void -on_date_popup_now_button_clicked (GtkWidget *button, - EDateEdit *dedit) -{ - hide_date_popup (dedit); - e_date_edit_set_time (dedit, time (NULL)); -} - - -static void -on_date_popup_today_button_clicked (GtkWidget *button, - EDateEdit *dedit) -{ - struct tm *tmp_tm; - time_t t; - - hide_date_popup (dedit); - - t = time (NULL); - tmp_tm = localtime (&t); - - e_date_edit_set_date (dedit, tmp_tm->tm_year + 1900, - tmp_tm->tm_mon + 1, tmp_tm->tm_mday); -} - - -static void -on_date_popup_none_button_clicked (GtkWidget *button, - EDateEdit *dedit) -{ - hide_date_popup (dedit); - e_date_edit_set_time (dedit, -1); -} - - -/* A key has been pressed while the date popup is showing. If it is the Escape - key we hide the popup. */ -static gint -on_date_popup_key_press (GtkWidget *widget, - GdkEventKey *event, - EDateEdit *dedit) -{ - if (event->keyval != GDK_Escape) - return FALSE; - - gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event"); - hide_date_popup (dedit); - - return TRUE; -} - - -/* A mouse button has been pressed while the date popup is showing. - Any button press events used to select days etc. in the popup will have - have been handled elsewhere, so here we just hide the popup. - (This function is yanked from gtkcombo.c) */ -static gint -on_date_popup_button_press (GtkWidget *widget, - GdkEventButton *event, - gpointer data) -{ - EDateEdit *dedit; - GtkWidget *child; - - dedit = data; - - child = gtk_get_event_widget ((GdkEvent *) event); - - /* We don't ask for button press events on the grab widget, so - * if an event is reported directly to the grab widget, it must - * be on a window outside the application (and thus we remove - * the popup window). Otherwise, we check if the widget is a child - * of the grab widget, and only remove the popup window if it - * is not. - */ - if (child != widget) { - while (child) { - if (child == widget) - return FALSE; - child = child->parent; - } - } - - hide_date_popup (dedit); - - return TRUE; -} - - -/* A delete event has been received for the date popup, so we hide it and - return TRUE so it doesn't get destroyed. */ -static gint -on_date_popup_delete_event (GtkWidget *widget, - EDateEdit *dedit) -{ - hide_date_popup (dedit); - return TRUE; -} - - -/* Hides the date popup, removing any grabs. */ -static void -hide_date_popup (EDateEdit *dedit) -{ - gtk_widget_hide (dedit->priv->cal_popup); - gtk_grab_remove (dedit->priv->cal_popup); - gdk_pointer_ungrab (GDK_CURRENT_TIME); -} - - -/* Clears the time popup and rebuilds it using the lower_hour, upper_hour - and use_24_hour_format settings. */ -static void -rebuild_time_popup (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - GtkList *list; - GtkWidget *listitem; - char buffer[40], *format; - struct tm tmp_tm; - gint hour, min; - - priv = dedit->priv; - - list = GTK_LIST (GTK_COMBO (priv->time_combo)->list); - - gtk_list_clear_items (list, 0, -1); - - /* Fill the struct tm with some sane values. */ - tmp_tm.tm_year = 2000; - tmp_tm.tm_mon = 0; - tmp_tm.tm_mday = 1; - tmp_tm.tm_sec = 0; - tmp_tm.tm_isdst = 0; - - for (hour = priv->lower_hour; hour <= priv->upper_hour; hour++) { - - /* We don't want to display midnight at the end, since that is - really in the next day. */ - if (hour == 24) - break; - - /* We want to finish on upper_hour, with min == 0. */ - for (min = 0; - min == 0 || (min < 60 && hour != priv->upper_hour); - min += 30) { - tmp_tm.tm_hour = hour; - tmp_tm.tm_min = min; - - if (priv->use_24_hour_format) - /* This is a strftime() format. %H = hour (0-23), %M = minute. */ - format = _("%H:%M"); - else - /* This is a strftime() format. %I = hour (1-12), %M = minute, %p = am/pm string. */ - format = _("%I:%M %p"); - - strftime (buffer, sizeof (buffer), format, &tmp_tm); - - listitem = gtk_list_item_new_with_label (buffer); - gtk_widget_show (listitem); - gtk_container_add (GTK_CONTAINER (list), listitem); - } - } -} - - -static gboolean -e_date_edit_parse_date (EDateEdit *dedit, - gchar *date_text, - struct tm *date_tm) -{ - struct tm *tmp_tm; - time_t t; - - /* This is a strptime() format for a short date. %m = month, - %d = day of month, %Y = year (all digits). */ - if (!strptime (date_text, _("%m/%d/%Y"), date_tm)) - return FALSE; - - /* If the user entered a 2-digit year we use the current century. */ - if (date_tm->tm_year < 0) { - t = time (NULL); - tmp_tm = localtime (&t); - - /* This should convert it into a value from 0 to 99. */ - date_tm->tm_year += 1900; - - /* Now add on the century. */ - date_tm->tm_year += tmp_tm->tm_year - (tmp_tm->tm_year % 100); - } - - return TRUE; -} - - -static gboolean -e_date_edit_parse_time (EDateEdit *dedit, - gchar *time_text, - struct tm *time_tm) -{ - gchar *format; - - if (field_set_to_none (time_text)) { - time_tm->tm_hour = 0; - time_tm->tm_min = 0; - return TRUE; - } - - if (dedit->priv->use_24_hour_format) - /* This is a strptime() format. %H = hour (0-23), %M = minute. */ - format = _("%H:%M"); - else - /* This is a strptime() format. %I = hour (1-12), %M = minute, %p = am/pm string. */ - format = _("%I:%M %p"); - - if (!strptime (time_text, format, time_tm)) - return FALSE; - - return TRUE; -} - - -/* Returns TRUE if the string is empty or is "None" in the current locale. - It ignores whitespace. */ -static gboolean -field_set_to_none (char *text) -{ - char *pos, *none_string; - - pos = text; - while (isspace (*pos)) - pos++; - - none_string = _("None"); - - if (*pos == '\0' || !strncmp (pos, none_string, strlen (none_string))) - return TRUE; - return FALSE; -} - - -static void -on_date_edit_time_selected (GtkList *list, - EDateEdit *dedit) -{ - GtkWidget *toplevel; - - /* We only want to emit signals when an item is selected explicitly, - not when it is selected by the silly combo update thing. */ - if (!list->selection) - return; - - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (list)); - if (!GTK_WIDGET_MAPPED (toplevel)) - return; - - e_date_edit_check_time_changed (dedit); -} - - -static gint -on_date_entry_key_press (GtkWidget *widget, - GdkEventKey *event, - EDateEdit *dedit) -{ - if (event->state & GDK_MOD1_MASK - && (event->keyval == GDK_Up || event->keyval == GDK_Down - || event->keyval == GDK_Return)) { - gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), - "key_press_event"); - e_date_edit_show_date_popup (dedit); - return TRUE; - } - - /* If the user hits the return key emit a "date_changed" signal if - needed. But let the signal carry on. */ - if (event->keyval == GDK_Return) { - e_date_edit_check_date_changed (dedit); - return FALSE; - } - - return FALSE; -} - - -static gint -on_time_entry_key_press (GtkWidget *widget, - GdkEventKey *event, - EDateEdit *dedit) -{ - /* I'd like to use Alt+Up/Down for popping up the list, like Win32, - but the combo steals any Up/Down keys, so we use Alt+Return. */ -#if 0 - if (event->state & GDK_MOD1_MASK - && (event->keyval == GDK_Up || event->keyval == GDK_Down)) { -#else - if (event->state & GDK_MOD1_MASK && event->keyval == GDK_Return) { -#endif - gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), - "key_press_event"); - gtk_signal_emit_by_name (GTK_OBJECT (GTK_COMBO (dedit->priv->time_combo)->entry), "activate"); - return TRUE; - } - - /* Stop the return key from emitting the activate signal, and check - if we need to emit a "time_changed" signal. */ - if (event->keyval == GDK_Return) { - gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), - "key_press_event"); - e_date_edit_check_time_changed (dedit); - return TRUE; - } - - return FALSE; -} - - -static gint -on_date_entry_focus_out (GtkEntry *entry, - GdkEventFocus *event, - EDateEdit *dedit) -{ - e_date_edit_check_date_changed (dedit); - return FALSE; -} - - -static gint -on_time_entry_focus_out (GtkEntry *entry, - GdkEventFocus *event, - EDateEdit *dedit) -{ - e_date_edit_check_time_changed (dedit); - return FALSE; -} - - -/* This sets the text in the date entry according to the current settings. */ -static void -e_date_edit_update_date_entry (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - char buffer[40]; - struct tm tmp_tm = { 0 }; - - priv = dedit->priv; - - if (priv->date_set_to_none || !priv->date_is_valid) { - gtk_entry_set_text (GTK_ENTRY (priv->date_entry), _("None")); - } else { - tmp_tm.tm_year = priv->year; - tmp_tm.tm_mon = priv->month; - tmp_tm.tm_mday = priv->day; - tmp_tm.tm_isdst = -1; - - /* This is a strftime() format for a short date. %m = month, - %d = day of month, %Y = year (all digits). */ - strftime (buffer, sizeof (buffer), _("%m/%d/%Y"), &tmp_tm); - gtk_entry_set_text (GTK_ENTRY (priv->date_entry), buffer); - } -} - - -/* This sets the text in the time entry according to the current settings. */ -static void -e_date_edit_update_time_entry (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - char buffer[40], *format; - struct tm tmp_tm = { 0 }; - - priv = dedit->priv; - - if (priv->time_set_to_none || !priv->time_is_valid) { - gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->time_combo)->entry), ""); - } else { - /* Set these to reasonable values just in case. */ - tmp_tm.tm_year = 2000; - tmp_tm.tm_mon = 0; - tmp_tm.tm_mday = 1; - - tmp_tm.tm_hour = priv->hour; - tmp_tm.tm_min = priv->minute; - - tmp_tm.tm_sec = 0; - tmp_tm.tm_isdst = -1; - - if (priv->use_24_hour_format) - /* This is a strftime() format. %H = hour (0-23), %M = minute. */ - format = _("%H:%M"); - else - /* This is a strftime() format. %I = hour (1-12), %M = minute, %p = am/pm string. */ - format = _("%I:%M %p"); - - strftime (buffer, sizeof (buffer), format, &tmp_tm); - gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->time_combo)->entry), - buffer); - } -} - - -static void -e_date_edit_update_time_combo_state (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - gchar *text; - - priv = dedit->priv; - - /* If the date entry is currently shown, and it is set to None, - clear the time entry and disable the time combo, else enable it. */ - if (priv->show_date && priv->date_set_to_none) { - text = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (priv->time_combo)->entry)); - if (text[0]) - gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->time_combo)->entry), ""); - gtk_widget_set_sensitive (priv->time_combo, FALSE); - } else { - gtk_widget_set_sensitive (priv->time_combo, TRUE); - } -} - - -/* Parses the date, and if it is different from the current settings it - updates the settings and emits a "date_changed" signal. */ -static void -e_date_edit_check_date_changed (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - gchar *date_text; - struct tm tmp_tm; - gboolean none = FALSE, valid = TRUE, date_changed; - - priv = dedit->priv; - - date_text = gtk_entry_get_text (GTK_ENTRY (priv->date_entry)); - if (field_set_to_none (date_text)) - none = TRUE; - else if (!e_date_edit_parse_date (dedit, date_text, &tmp_tm)) - valid = FALSE; - - date_changed = e_date_edit_set_date_internal (dedit, valid, none, - tmp_tm.tm_year, - tmp_tm.tm_mon, - tmp_tm.tm_mday); - - if (date_changed) - gtk_signal_emit (GTK_OBJECT (dedit), - date_edit_signals [CHANGED]); -} - - -/* Parses the time, and if it is different from the current settings it - updates the settings and emits a "time_changed" signal. */ -static void -e_date_edit_check_time_changed (EDateEdit *dedit) -{ - EDateEditPrivate *priv; - gchar *time_text; - struct tm tmp_tm; - gboolean none = FALSE, valid = TRUE, time_changed; - - priv = dedit->priv; - - time_text = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (priv->time_combo)->entry)); - if (field_set_to_none (time_text)) - none = TRUE; - else if (!e_date_edit_parse_time (dedit, time_text, &tmp_tm)) - valid = FALSE; - - time_changed = e_date_edit_set_time_internal (dedit, valid, none, - tmp_tm.tm_hour, - tmp_tm.tm_min); - - if (time_changed) - gtk_signal_emit (GTK_OBJECT (dedit), - date_edit_signals [CHANGED]); -} - - -/** - * e_date_edit_date_is_valid: - * @dedit: an #EDateEdit widget. - * @Returns: TRUE if the last date entered was valid. - * - * Returns TRUE if the last date entered was valid. - * - * Note that if this returns FALSE, you can still use e_date_edit_get_time() - * or e_date_edit_get_date() to get the last time or date entered which was - * valid. - */ -gboolean -e_date_edit_date_is_valid (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - if (!dedit->priv->date_is_valid) - return FALSE; - - /* If the date is empty/None and that isn't permitted, return FALSE. */ - if (dedit->priv->date_set_to_none - && !e_date_edit_get_allow_no_date_set (dedit)) - return FALSE; - - return TRUE; -} - - -/** - * e_date_edit_time_is_valid: - * @dedit: an #EDateEdit widget. - * @Returns: TRUE if the last time entered was valid. - * - * Returns TRUE if the last time entered was valid. - * - * Note that if this returns FALSE, you can still use e_date_edit_get_time() - * or e_date_edit_get_time_of_day() to get the last time or time of the day - * entered which was valid. - */ -gboolean -e_date_edit_time_is_valid (EDateEdit *dedit) -{ - g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - - if (!dedit->priv->time_is_valid) - return FALSE; - - /* If the time is empty and that isn't permitted, return FALSE. - Note that we don't mind an empty time if the date field is shown - - in that case we just assume 0:00. */ - if (dedit->priv->time_set_to_none && !dedit->priv->show_date - && !e_date_edit_get_allow_no_date_set (dedit)) - return FALSE; - - return TRUE; -} - - -static gboolean -e_date_edit_set_date_internal (EDateEdit *dedit, - gboolean valid, - gboolean none, - gint year, - gint month, - gint day) -{ - EDateEditPrivate *priv; - gboolean date_changed = FALSE; - - priv = dedit->priv; - - if (!valid) { - /* Date is invalid. */ - if (priv->date_is_valid) { - priv->date_is_valid = FALSE; - date_changed = TRUE; - } - } else if (none) { - /* Date has been set to 'None'. */ - if (!priv->date_is_valid - || !priv->date_set_to_none) { - priv->date_is_valid = TRUE; - priv->date_set_to_none = TRUE; - date_changed = TRUE; - } - } else { - /* Date has been set to a specific date. */ - if (!priv->date_is_valid - || priv->date_set_to_none - || priv->year != year - || priv->month != month - || priv->day != day) { - priv->date_is_valid = TRUE; - priv->date_set_to_none = FALSE; - priv->year = year; - priv->month = month; - priv->day = day; - date_changed = TRUE; - } - } - - return date_changed; -} - - -static gboolean -e_date_edit_set_time_internal (EDateEdit *dedit, - gboolean valid, - gboolean none, - gint hour, - gint minute) -{ - EDateEditPrivate *priv; - gboolean time_changed = FALSE; - - priv = dedit->priv; - - if (!valid) { - /* Time is invalid. */ - if (priv->time_is_valid) { - priv->time_is_valid = FALSE; - time_changed = TRUE; - } - } else if (none) { - /* Time has been set to empty/'None'. */ - if (!priv->time_is_valid - || !priv->time_set_to_none) { - priv->time_is_valid = TRUE; - priv->time_set_to_none = TRUE; - time_changed = TRUE; - } - } else { - /* Time has been set to a specific time. */ - if (!priv->time_is_valid - || priv->time_set_to_none - || priv->hour != hour - || priv->minute != minute) { - priv->time_is_valid = TRUE; - priv->time_set_to_none = FALSE; - priv->hour = hour; - priv->minute = minute; - time_changed = TRUE; - } - } - - return time_changed; -} diff --git a/widgets/misc/e-dateedit.h b/widgets/misc/e-dateedit.h deleted file mode 100644 index a83690844f..0000000000 --- a/widgets/misc/e-dateedit.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 2000, Helix Code, Inc. - * - * Based on the GnomeDateEdit, part of the Gnome Library. - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * - * 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 - */ - -/* - * EDateEdit - a widget based on GnomeDateEdit to provide a date & optional - * time field with popups for entering a date. - * - * It emits a "changed" signal when the date and/or time has changed. - * You can check if the last date or time entered was invalid by - * calling e_date_edit_date_is_valid() and e_date_edit_time_is_valid(). - * - * Note that when the user types in a date or time, it will only emit the - * signals when the user presses the return key or switches the keyboard - * focus to another widget, or you call one of the _get_time/date functions. - */ - -#ifndef __E_DATE_EDIT_H_ -#define __E_DATE_EDIT_H_ - -#include <time.h> -#include <glib.h> -#include <gtk/gtkhbox.h> -#include <gtk/gtkwidget.h> -#include <libgnome/gnome-defs.h> - -BEGIN_GNOME_DECLS - - -#define E_TYPE_DATE_EDIT (e_date_edit_get_type ()) -#define E_DATE_EDIT(obj) (GTK_CHECK_CAST ((obj), E_TYPE_DATE_EDIT, EDateEdit)) -#define E_DATE_EDIT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_DATE_EDIT, EDateEditClass)) -#define E_IS_DATE_EDIT(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_DATE_EDIT)) -#define E_IS_DATE_EDIT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_DATE_EDIT)) - - -typedef struct _EDateEdit EDateEdit; -typedef struct _EDateEditPrivate EDateEditPrivate; -typedef struct _EDateEditClass EDateEditClass; - -struct _EDateEdit { - GtkHBox hbox; - - /*< private >*/ - EDateEditPrivate *priv; -}; - -struct _EDateEditClass { - GtkHBoxClass parent_class; - - void (* changed) (EDateEdit *dedit); -}; - -guint e_date_edit_get_type (void); -GtkWidget* e_date_edit_new (void); - -/* Returns TRUE if the last date and time set were valid. The date and time - are only set when the user hits Return or switches keyboard focus, or - selects a date or time from the popup. */ -gboolean e_date_edit_date_is_valid (EDateEdit *dedit); -gboolean e_date_edit_time_is_valid (EDateEdit *dedit); - -/* Returns the last valid date & time set, or -1 if the date & time was set to - 'None' and this is permitted via e_date_edit_set_allow_no_date_set. */ -time_t e_date_edit_get_time (EDateEdit *dedit); -void e_date_edit_set_time (EDateEdit *dedit, - time_t the_time); - -/* This returns the last valid date set, without the time. It returns TRUE - if a date is set, or FALSE if the date is set to 'None' and this is - permitted via e_date_edit_set_allow_no_date_set. */ -gboolean e_date_edit_get_date (EDateEdit *dedit, - gint *year, - gint *month, - gint *day); -void e_date_edit_set_date (EDateEdit *dedit, - gint year, - gint month, - gint day); - -/* This returns the last valid time set, without the date. It returns TRUE - if a time is set, or FALSE if the time is set to 'None' and this is - permitted via e_date_edit_set_allow_no_date_set. */ -gboolean e_date_edit_get_time_of_day (EDateEdit *dedit, - gint *hour, - gint *minute); -void e_date_edit_set_time_of_day (EDateEdit *dedit, - gint hour, - gint minute); - -/* Whether we show the date field. */ -gboolean e_date_edit_get_show_date (EDateEdit *dedit); -void e_date_edit_set_show_date (EDateEdit *dedit, - gboolean show_date); - -/* Whether we show the time field. */ -gboolean e_date_edit_get_show_time (EDateEdit *dedit); -void e_date_edit_set_show_time (EDateEdit *dedit, - gboolean show_time); - -/* The week start day, used in the date popup. 0 (Mon) to 6 (Sun). */ -gint e_date_edit_get_week_start_day (EDateEdit *dedit); -void e_date_edit_set_week_start_day (EDateEdit *dedit, - gint week_start_day); - -/* Whether we show week numbers in the date popup. */ -gboolean e_date_edit_get_show_week_numbers (EDateEdit *dedit); -void e_date_edit_set_show_week_numbers (EDateEdit *dedit, - gboolean show_week_numbers); - -/* Whether we use 24 hour format in the time field & popup. */ -gboolean e_date_edit_get_use_24_hour_format (EDateEdit *dedit); -void e_date_edit_set_use_24_hour_format (EDateEdit *dedit, - gboolean use_24_hour_format); - -/* Whether we allow the date to be set to 'None'. e_date_edit_get_time() will - return (time_t) -1 in this case. */ -gboolean e_date_edit_get_allow_no_date_set (EDateEdit *dedit); -void e_date_edit_set_allow_no_date_set (EDateEdit *dedit, - gboolean allow_no_date_set); - -/* The range of time to show in the time combo popup. */ -void e_date_edit_get_time_popup_range (EDateEdit *dedit, - gint *lower_hour, - gint *upper_hour); -void e_date_edit_set_time_popup_range (EDateEdit *dedit, - gint lower_hour, - gint upper_hour); - -END_GNOME_DECLS - -#endif diff --git a/widgets/misc/e-dropdown-button.c b/widgets/misc/e-dropdown-button.c deleted file mode 100644 index 334cab878f..0000000000 --- a/widgets/misc/e-dropdown-button.c +++ /dev/null @@ -1,252 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-dropdown-menu.c - * - * Copyright (C) 2001 Ximian, 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. - * - * Authors: - * Ettore Perazzoli <ettore@ximian.com> - * Damon Chaplin <damon@ximian.com> - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-dropdown-button.h" - - -#include <stdio.h> -#include <gtk/gtkarrow.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkwidget.h> -#include <libgnomeui/gnome-popup-menu.h> -#include <gal/util/e-util.h> - - -struct _EDropdownButtonPrivate { - GtkAccelGroup *accel_group; - GtkWidget *menu; -}; - -#define PARENT_TYPE gtk_toggle_button_get_type () -static GtkToggleButtonClass *parent_class = NULL; - - -/* Callback to position the pop-up menu. */ - -static void -menu_position_cb (GtkMenu *menu, - int *x, - int *y, - void *data) -{ - EDropdownButton *dropdown_button; - EDropdownButtonPrivate *priv; - GtkRequisition menu_requisition; - int max_x, max_y; - - dropdown_button = E_DROPDOWN_BUTTON (data); - priv = dropdown_button->priv; - - /* Calculate our preferred position. */ - gdk_window_get_origin (GTK_WIDGET (dropdown_button)->window, x, y); - *y += GTK_WIDGET (dropdown_button)->allocation.height; - - /* Now make sure we are on the screen. */ - gtk_widget_size_request (GTK_WIDGET (priv->menu), &menu_requisition); - max_x = MAX (0, gdk_screen_width () - menu_requisition.width); - max_y = MAX (0, gdk_screen_height () - menu_requisition.height); - - *x = CLAMP (*x, 0, max_x); - *y = CLAMP (*y, 0, max_y); -} - -/* Callback for the "deactivate" signal on the pop-up menu. This is used so - that we unset the state of the toggle button when the pop-up menu - disappears. */ - -static int -menu_deactivate_cb (GtkMenuShell *menu_shell, - void *data) -{ - EDropdownButton *dropdown_button; - - puts (__FUNCTION__); - - dropdown_button = E_DROPDOWN_BUTTON (data); - - gtk_button_clicked (GTK_BUTTON (dropdown_button)); - return TRUE; -} - - -/* GtkObject methods. */ - -static void -impl_destroy (GtkObject *object) -{ - EDropdownButton *dropdown_button; - EDropdownButtonPrivate *priv; - - dropdown_button = E_DROPDOWN_BUTTON (object); - priv = dropdown_button->priv; - - gtk_accel_group_unref (priv->accel_group); - gtk_widget_destroy (priv->menu); - - g_free (priv); -} - - -/* GtkWidget methods. */ - -static int -impl_button_press_event (GtkWidget *widget, - GdkEventButton *event) -{ - EDropdownButton *dropdown_button; - EDropdownButtonPrivate *priv; - GtkStateType new_state; - - dropdown_button = E_DROPDOWN_BUTTON (widget); - priv = dropdown_button->priv; - - gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, - menu_position_cb, dropdown_button, - 1, GDK_CURRENT_TIME); - - gnome_popup_menu_do_popup (GTK_WIDGET (priv->menu), menu_position_cb, dropdown_button, - event, NULL); - - if (! GTK_WIDGET_HAS_FOCUS (widget)) - gtk_widget_grab_focus (widget); - - gtk_button_clicked (GTK_BUTTON (widget)); - - return TRUE; -} - - -static void -class_init (EDropdownButtonClass *klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = GTK_OBJECT_CLASS (klass); - widget_class = GTK_WIDGET_CLASS (klass); - - object_class->destroy = impl_destroy; - - widget_class->button_press_event = impl_button_press_event; - - parent_class = gtk_type_class (PARENT_TYPE); -} - - -static void -init (EDropdownButton *dropdown_button) -{ - EDropdownButtonPrivate *priv; - - priv = g_new (EDropdownButtonPrivate, 1); - priv->accel_group = gtk_accel_group_new (); - priv->menu = NULL; - - dropdown_button->priv = priv; -} - - -/** - * e_dropdown_button_construct: - * @dropdown_button: A pointer to an %EDropdownButton object - * @label_text: Text to display in the button - * @menu: The menu to pop up when the button is pressed - * - * Construct the @dropdown_button with the specified @label_text and the - * associated @menu. - **/ -void -e_dropdown_button_construct (EDropdownButton *dropdown_button, - const char *label_text, - GtkMenu *menu) -{ - EDropdownButtonPrivate *priv; - GtkWidget *hbox; - GtkWidget *arrow; - GtkWidget *label; - unsigned int accel_key; - - g_return_if_fail (dropdown_button != NULL); - g_return_if_fail (E_IS_DROPDOWN_BUTTON (dropdown_button)); - g_return_if_fail (label_text != NULL); - g_return_if_fail (menu != NULL); - g_return_if_fail (GTK_IS_MENU (menu)); - - priv = dropdown_button->priv; - - hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (dropdown_button), hbox); - gtk_widget_show (hbox); - - label = gtk_label_new (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (label), label_text); - gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - gtk_widget_add_accelerator (GTK_WIDGET (dropdown_button), "clicked", - priv->accel_group, accel_key, GDK_MOD1_MASK, 0); - - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT); - gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 2); - gtk_widget_show (arrow); - - priv->menu = GTK_WIDGET (menu); - - gtk_signal_connect_while_alive (GTK_OBJECT (priv->menu), "deactivate", - GTK_SIGNAL_FUNC (menu_deactivate_cb), - dropdown_button, GTK_OBJECT (dropdown_button)); -} - -/** - * e_dropdown_button_new: - * @label_text: Text to display in the button - * @menu: The menu to pop up when the button is pressed - * - * Create a new dropdown button. When the button is clicked, the specified - * @menu will be popped up. - * - * Return value: A pointer to the newly created %EDropdownButton. - **/ -GtkWidget * -e_dropdown_button_new (const char *label_text, - GtkMenu *menu) -{ - GtkWidget *widget; - - g_return_val_if_fail (label_text != NULL, NULL); - g_return_val_if_fail (menu != NULL, NULL); - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - widget = gtk_type_new (e_dropdown_button_get_type ()); - - e_dropdown_button_construct (E_DROPDOWN_BUTTON (widget), label_text, menu); - return widget; -} - - -E_MAKE_TYPE (e_dropdown_button, "EDropdownButton", EDropdownButton, class_init, init, PARENT_TYPE) diff --git a/widgets/misc/e-dropdown-button.h b/widgets/misc/e-dropdown-button.h deleted file mode 100644 index 6aa92d0bd8..0000000000 --- a/widgets/misc/e-dropdown-button.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-dropdown-menu.h - * - * Copyright (C) 2001 Ximian, 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: Ettore Perazzoli - */ - -#ifndef _E_DROPDOWN_BUTTON_H_ -#define _E_DROPDOWN_BUTTON_H_ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtktogglebutton.h> -#include <gtk/gtkmenu.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_DROPDOWN_BUTTON (e_dropdown_button_get_type ()) -#define E_DROPDOWN_BUTTON(obj) (GTK_CHECK_CAST ((obj), E_TYPE_DROPDOWN_BUTTON, EDropdownButton)) -#define E_DROPDOWN_BUTTON_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_DROPDOWN_BUTTON, EDropdownButtonClass)) -#define E_IS_DROPDOWN_BUTTON(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_DROPDOWN_BUTTON)) -#define E_IS_DROPDOWN_BUTTON_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_DROPDOWN_BUTTON)) - - -typedef struct _EDropdownButton EDropdownButton; -typedef struct _EDropdownButtonPrivate EDropdownButtonPrivate; -typedef struct _EDropdownButtonClass EDropdownButtonClass; - -struct _EDropdownButton { - GtkToggleButton parent; - - EDropdownButtonPrivate *priv; -}; - -struct _EDropdownButtonClass { - GtkToggleButtonClass parent_class; -}; - - -GtkType e_dropdown_button_get_type (void); -void e_dropdown_button_construct (EDropdownButton *dropdown_button, - const char *label_text, - GtkMenu *menu); -GtkWidget *e_dropdown_button_new (const char *label_text, - GtkMenu *menu); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_DROPDOWN_BUTTON_H_ */ diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c deleted file mode 100644 index 2a84912d62..0000000000 --- a/widgets/misc/e-filter-bar.c +++ /dev/null @@ -1,472 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-search-bar.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: - * Michael Zucchi <notzed@ximian.com> - * - * This library 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 library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> - -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-stock.h> - -#include "e-dropdown-button.h" -#include "e-filter-bar.h" -#include "filter/rule-editor.h" - -#include <gal/widgets/e-unicode.h> -#include <gal/widgets/e-gui-utils.h> - -#define d(x) - - -enum { - LAST_SIGNAL -}; - -/*static gint esb_signals [LAST_SIGNAL] = { 0, };*/ - -static ESearchBarClass *parent_class = NULL; - -/* The arguments we take */ -enum { - ARG_0, - ARG_QUERY, -}; - - -/* Callbacks. */ - -/* rule editor thingy */ -static void rule_editor_destroyed(GtkWidget *w, EFilterBar *efb) -{ - efb->save_dialogue = NULL; - e_search_bar_set_menu_sensitive((ESearchBar *)efb, E_FILTERBAR_SAVE_ID, TRUE); -} - -/* FIXME: need to update the popup menu to match any edited rules, sigh */ -static void full_rule_editor_clicked(GtkWidget *w, int button, void *data) -{ - EFilterBar *efb = data; - - switch (button) { - case 0: - rule_context_save(efb->context, efb->userrules); - case 1: - default: - gnome_dialog_close((GnomeDialog *)w); - case -1: - } -} - -static void rule_editor_clicked(GtkWidget *w, int button, void *data) -{ - EFilterBar *efb = data; - ESearchBarItem item; - FilterRule *rule; - - switch(button) { - case 0: - rule = gtk_object_get_data((GtkObject *)w, "rule"); - if (rule) { - if (!filter_rule_validate (rule)) - return; - - item.text = rule->name; - item.id = efb->menu_base + efb->menu_rules->len; - - g_ptr_array_add(efb->menu_rules, rule); - - rule_context_add_rule(efb->context, rule); - /* FIXME: check return */ - rule_context_save(efb->context, efb->userrules); - e_search_bar_add_menu((ESearchBar *)efb, &item); - } - case 1: - gnome_dialog_close((GnomeDialog *)w); - break; - case -1: - } -} - -static void rule_advanced_clicked(GtkWidget *w, int button, void *data) -{ - EFilterBar *efb = data; - FilterRule *rule; - - switch(button) { - case 0: /* 'ok' */ - case 1: - rule = gtk_object_get_data((GtkObject *)w, "rule"); - if (rule) { - efb->current_query = rule; - gtk_object_ref((GtkObject *)rule); - gtk_signal_emit_by_name((GtkObject *)efb, "query_changed"); - } - if (button == 1) - rule_editor_clicked(w, 0, data); - case 2: - gnome_dialog_close((GnomeDialog *)w); - break; - case -1: - } -} - -static void -menubar_activated (ESearchBar *esb, int id, void *data) -{ - EFilterBar *efb = (EFilterBar *)esb; - - switch(id) { - case E_FILTERBAR_RESET_ID: - d(printf("Reset menu\n")); - efb->current_query = NULL; - gtk_object_set((GtkObject *)esb, "option_choice", efb->option_base, NULL); - gtk_object_set((GtkObject *)esb, "text", NULL, NULL); - gtk_widget_set_sensitive(esb->entry, TRUE); - break; - case E_FILTERBAR_EDIT_ID: - if (!efb->save_dialogue) { - GnomeDialog *gd; - - gd = (GnomeDialog *)rule_editor_new(efb->context, FILTER_SOURCE_INCOMING); - gtk_signal_connect((GtkObject *)gd, "clicked", full_rule_editor_clicked, efb); - gtk_signal_connect((GtkObject *)gd, "destroy", rule_editor_destroyed, efb); - gtk_widget_show((GtkWidget *)gd); - } - break; - case E_FILTERBAR_SAVE_ID: - if (efb->current_query && !efb->save_dialogue) { - GtkWidget *w; - GnomeDialog *gd; - FilterRule *rule; - - rule = filter_rule_clone(efb->current_query, efb->context); - - w = filter_rule_get_widget(rule, efb->context); - filter_rule_set_source(rule, FILTER_SOURCE_INCOMING); - gd = (GnomeDialog *)gnome_dialog_new(_("Save Search"), - GNOME_STOCK_BUTTON_OK, - GNOME_STOCK_BUTTON_CANCEL, - NULL); - efb->save_dialogue = (GtkWidget *)gd; - gnome_dialog_set_default (gd, 0); - - gtk_window_set_policy(GTK_WINDOW(gd), FALSE, TRUE, FALSE); - /*gtk_window_set_default_size (GTK_WINDOW (gd), 500, 500);*/ - gtk_box_pack_start((GtkBox *)gd->vbox, w, TRUE, TRUE, 0); - gtk_widget_show((GtkWidget *)gd); - gtk_object_ref((GtkObject *)rule); - gtk_object_set_data_full((GtkObject *)gd, "rule", rule, (GtkDestroyNotify)gtk_object_unref); - gtk_signal_connect((GtkObject *)gd, "clicked", rule_editor_clicked, efb); - gtk_signal_connect((GtkObject *)gd, "destroy", rule_editor_destroyed, efb); - - e_search_bar_set_menu_sensitive(esb, E_FILTERBAR_SAVE_ID, FALSE); - gtk_widget_set_sensitive(esb->entry, FALSE); - - gtk_widget_show((GtkWidget *)gd); - } - - d(printf("Save menu\n")); - break; - default: - if (id >= efb->menu_base && id < efb->menu_base + efb->menu_rules->len) { - GString *out = g_string_new(""); - d(printf("Selected rule: %s\n", ((FilterRule *)efb->menu_rules->pdata[id - efb->menu_base])->name)); - filter_rule_build_code(efb->menu_rules->pdata[id - efb->menu_base], out); - d(printf("query: '%s'\n", out->str)); - g_string_free(out, 1); - - efb->current_query = (FilterRule *)efb->menu_rules->pdata[id - efb->menu_base]; - efb->setquery = TRUE; - gtk_object_set((GtkObject *)esb, "option_choice", E_FILTERBAR_ADVANCED_ID, NULL); - - gtk_widget_set_sensitive(esb->entry, FALSE); - } else { - gtk_widget_set_sensitive(esb->entry, TRUE); - return; - } - } - - gtk_signal_emit_stop_by_name((GtkObject *)esb, "menu_activated"); -} - -static void -option_changed (ESearchBar *esb, void *data) -{ - EFilterBar *efb = (EFilterBar *)esb; - int id = esb->option_choice; - char *query; - - d(printf("option changed, id = %d\n", id)); - - switch(id) { - case E_FILTERBAR_ADVANCED_ID: { - d(printf("Advanced search!\n")); - - if (!efb->save_dialogue && !efb->setquery) { - GtkWidget *w; - GnomeDialog *gd; - FilterRule *rule; - - if (efb->current_query) - rule = filter_rule_clone(efb->current_query, efb->context); - else - rule = filter_rule_new(); - - w = filter_rule_get_widget(rule, efb->context); - filter_rule_set_source(rule, FILTER_SOURCE_INCOMING); - gd = (GnomeDialog *)gnome_dialog_new(_("Advanced Search"), - GNOME_STOCK_BUTTON_OK, - _("Save"), - GNOME_STOCK_BUTTON_CANCEL, - NULL); - efb->save_dialogue = (GtkWidget *)gd; - gnome_dialog_set_default (gd, 0); - - gtk_window_set_policy(GTK_WINDOW(gd), FALSE, TRUE, FALSE); - /*gtk_window_set_default_size (GTK_WINDOW (gd), 500, 500);*/ - gtk_box_pack_start((GtkBox *)gd->vbox, w, TRUE, TRUE, 0); - gtk_widget_show((GtkWidget *)gd); - gtk_object_ref((GtkObject *)rule); - gtk_object_set_data_full((GtkObject *)gd, "rule", rule, (GtkDestroyNotify)gtk_object_unref); - gtk_signal_connect((GtkObject *)gd, "clicked", rule_advanced_clicked, efb); - gtk_signal_connect((GtkObject *)gd, "destroy", rule_editor_destroyed, efb); - - e_search_bar_set_menu_sensitive(esb, E_FILTERBAR_SAVE_ID, FALSE); - gtk_widget_set_sensitive(esb->entry, FALSE); - - gtk_widget_show((GtkWidget *)gd); - } - } break; - default: - if (id >= efb->option_base && id < efb->option_base + efb->option_rules->len) { - efb->current_query = (FilterRule *)efb->option_rules->pdata[id - efb->option_base]; - if (efb->config) { - gtk_object_get((GtkObject *)esb, "text", &query, NULL); - efb->config(efb, efb->current_query, id, query, efb->config_data); - g_free(query); - } - gtk_widget_set_sensitive(esb->entry, TRUE); - } else { - gtk_widget_set_sensitive(esb->entry, FALSE); - efb->current_query = NULL; - } - } - efb->setquery = FALSE; -} - -static GArray *build_items(ESearchBar *esb, ESearchBarItem *items, int type, int *start, GPtrArray *rules) -{ - FilterRule *rule = NULL; - EFilterBar *efb = (EFilterBar *)esb; - int id = 0, i; - GArray *menu = g_array_new(FALSE, FALSE, sizeof(ESearchBarItem)); - ESearchBarItem item; - char *source; - - /* find a unique starting point for the id's of our items */ - for (i=0;items[i].id != -1;i++) { - if (items[i].id >= id) - id = items[i].id+1; - } - - /* add the user menus */ - g_array_append_vals(menu, items, i); - - *start = id; - - if (type == 0) { - /* and add ours */ - item.id = 0; - item.text = NULL; - g_array_append_vals(menu, &item, 1); - source = FILTER_SOURCE_INCOMING; - } else { - source = FILTER_SOURCE_DEMAND; - } - - while ( (rule = rule_context_next_rule(efb->context, rule, source)) ) { - item.id = id++; - item.text = rule->name; - g_array_append_vals(menu, &item, 1); - g_ptr_array_add(rules, rule); - } - - /* always add on the advanced menu */ - if (type == 1) { - ESearchBarItem advanced_item = E_FILTERBAR_ADVANCED; - g_array_append_vals(menu, &advanced_item, 1); - } - - item.id = -1; - item.text = NULL; - g_array_append_vals(menu, &item, 1); - - return menu; -} - -/* Virtual methods */ -static void -set_menu(ESearchBar *esb, ESearchBarItem *items) -{ - GArray *menu; - EFilterBar *efb = (EFilterBar *)esb; - - g_ptr_array_set_size(efb->menu_rules, 0); - menu = build_items(esb, items, 0, &efb->menu_base, efb->menu_rules); - ((ESearchBarClass *)parent_class)->set_menu(esb, (ESearchBarItem *)menu->data); - g_array_free(menu, TRUE); -} - -static void -set_option(ESearchBar *esb, ESearchBarItem *items) -{ - GArray *menu; - EFilterBar *efb = (EFilterBar *)esb; - - g_ptr_array_set_size(efb->option_rules, 0); - menu = build_items(esb, items, 1, &efb->option_base, efb->option_rules); - ((ESearchBarClass *)parent_class)->set_option(esb, (ESearchBarItem *)menu->data); - g_array_free(menu, TRUE); -} - - -/* GtkObject methods. */ - -static void -impl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - EFilterBar *efb = E_FILTER_BAR(object); - - switch (arg_id) { - case ARG_QUERY: - if (efb->current_query) { - GString *out = g_string_new(""); - - filter_rule_build_code(efb->current_query, out); - GTK_VALUE_STRING(*arg) = out->str; - g_string_free(out, FALSE); - } else { - GTK_VALUE_STRING(*arg) = NULL; - } - break; - } -} - - -static void -class_init (EFilterBarClass *klass) -{ - GtkObjectClass *object_class; - ESearchBarClass *esb_class = (ESearchBarClass *)klass; - - object_class = GTK_OBJECT_CLASS(klass); - - parent_class = gtk_type_class(e_search_bar_get_type()); - - object_class->get_arg = impl_get_arg; - - esb_class->set_menu = set_menu; - esb_class->set_option = set_option; - - gtk_object_add_arg_type ("EFilterBar::query", GTK_TYPE_STRING, GTK_ARG_READABLE, ARG_QUERY); - -#if 0 - esb_signals [QUERY_CHANGED] = - gtk_signal_new ("query_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EFilterBarClass, query_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - esb_signals [MENU_ACTIVATED] = - gtk_signal_new ("menu_activated", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EFilterBarClass, menu_activated), - gtk_marshal_NONE__INT, - GTK_TYPE_NONE, 1, GTK_TYPE_INT); - - gtk_object_class_add_signals (object_class, esb_signals, LAST_SIGNAL); -#endif -} - -static void -init (EFilterBar *efb) -{ - gtk_signal_connect((GtkObject *)efb, "menu_activated", menubar_activated, NULL); - gtk_signal_connect((GtkObject *)efb, "query_changed", option_changed, NULL); - - efb->menu_rules = g_ptr_array_new(); - efb->option_rules = g_ptr_array_new(); -} - - -/* Object construction. */ - -EFilterBar *e_filter_bar_new (RuleContext *context, const char *systemrules, const char *userrules, EFilterBarConfigRule config, void *data) -{ - EFilterBar *bar; - ESearchBarItem item = { NULL, -1 }; - - bar = gtk_type_new(e_filter_bar_get_type()); - - bar->context = context; - gtk_object_ref((GtkObject *)context); - bar->systemrules = g_strdup(systemrules); - bar->userrules = g_strdup(userrules); - rule_context_load(context, systemrules, userrules); - - bar->config = config; - bar->config_data = data; - - e_search_bar_construct((ESearchBar *)bar, &item, &item); - - return bar; -} - -GtkType -e_filter_bar_get_type (void) -{ - static GtkType type = 0; - - if (!type) { - static const GtkTypeInfo info = { - "EFilterBar", - sizeof (EFilterBar), - sizeof (EFilterBarClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (e_search_bar_get_type (), &info); - } - - return type; -} - diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h deleted file mode 100644 index c6777630e8..0000000000 --- a/widgets/misc/e-filter-bar.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-filter-bar.h - * Copyright (C) 2001 Ximian Inc. - * Author: Michael Zucchi <notzed@ximian.com> - * - * This library 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 library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#ifndef __E_FILTER_BAR_H__ -#define __E_FILTER_BAR_H__ - -#include <gtk/gtkobject.h> -#include <gtk/gtkwidget.h> -#include "e-search-bar.h" - -#include "filter/rule-context.h" -#include "filter/filter-rule.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -/* EFilterBar - A filter rule driven search bar. - * - * The following arguments are available: - * - * name type read/write description - * --------------------------------------------------------------------------------- - * query string R String representing query. - */ - -#define E_FILTER_BAR_TYPE (e_filter_bar_get_type ()) -#define E_FILTER_BAR(obj) (GTK_CHECK_CAST ((obj), E_FILTER_BAR_TYPE, EFilterBar)) -#define E_FILTER_BAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_FILTER_BAR_TYPE, EFilterBarClass)) -#define E_IS_FILTER_BAR(obj) (GTK_CHECK_TYPE ((obj), E_FILTER_BAR_TYPE)) -#define E_IS_FILTER_BAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_FILTER_BAR_TYPE)) - -typedef struct _EFilterBar EFilterBar; -typedef struct _EFilterBarClass EFilterBarClass; - -typedef void (*EFilterBarConfigRule)(EFilterBar *, FilterRule *rule, int id, const char *query, void *data); - -struct _EFilterBar -{ - ESearchBar parent; - - int menu_base, option_base; - GPtrArray *menu_rules, *option_rules; - - GtkWidget *save_dialogue; /* current save dialogue (so we dont pop up multiple ones) */ - - FilterRule *current_query; /* as it says */ - int setquery; /* true when we're setting a query directly to advanced, so dont popup the dialogue */ - - RuleContext *context; - char *systemrules; - char *userrules; - - EFilterBarConfigRule config; - void *config_data; -}; - -struct _EFilterBarClass -{ - ESearchBarClass parent_class; -}; - -/* "preset" items */ -enum { - /* preset menu options */ - E_FILTERBAR_RESET_ID = -2, - E_FILTERBAR_SAVE_ID = -3, - E_FILTERBAR_EDIT_ID = -4, - - /* preset option options */ - E_FILTERBAR_ADVANCED_ID = -5, - - E_FILTERBAR_LAST_ID = -6, -}; - -#define E_FILTERBAR_SAVE { N_("Save As..."), E_FILTERBAR_SAVE_ID } -#define E_FILTERBAR_RESET { N_("Show All"), E_FILTERBAR_RESET_ID } -#define E_FILTERBAR_EDIT { N_("Edit..."), E_FILTERBAR_EDIT_ID } -#define E_FILTERBAR_ADVANCED { N_("Advanced..."), E_FILTERBAR_ADVANCED_ID } - -#ifdef JUST_FOR_TRANSLATORS -const char * strings[] = { - N_("Save As..."), - N_("Show All"), - N_("Edit..."), - N_("Advanced...") -}; -#endif - - -GtkType e_filter_bar_get_type (void); -EFilterBar*e_filter_bar_new (RuleContext *, const char *sys, const char *user, EFilterBarConfigRule config, void *data); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __E_FILTER_BAR_H__ */ diff --git a/widgets/misc/e-messagebox.c b/widgets/misc/e-messagebox.c deleted file mode 100644 index 6549476e1d..0000000000 --- a/widgets/misc/e-messagebox.c +++ /dev/null @@ -1,356 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Original Author: Jay Painter - * Modified: Jeffrey Stedfast - * - * 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 Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#include <config.h> -#include <stdarg.h> -#include <string.h> /* for strcmp */ - -#include <glib.h> -#include <gtk/gtkalignment.h> -#include <gtk/gtkcheckbutton.h> -#include <gtk/gtkhbox.h> -#include <gtk/gtklabel.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-triggers.h> -#include <libgnome/gnome-util.h> -#include <libgnomeui/gnome-pixmap.h> -#include <libgnomeui/gnome-uidefs.h> -#include "e-messagebox.h" - -#define E_MESSAGE_BOX_WIDTH 425 -#define E_MESSAGE_BOX_HEIGHT 125 - -struct _EMessageBoxPrivate { - GtkWidget *label; - GtkWidget *checkbox; -}; - -static void e_message_box_class_init (EMessageBoxClass *klass); -static void e_message_box_init (EMessageBox *messagebox); -static void e_message_box_destroy (GtkObject *object); -static void e_message_box_finalize (GtkObject *object); - -static GnomeDialogClass *parent_class; - -GtkType -e_message_box_get_type (void) -{ - static GtkType message_box_type = 0; - - if (!message_box_type) { - GtkTypeInfo message_box_info = { - "EMessageBox", - sizeof (EMessageBox), - sizeof (EMessageBoxClass), - (GtkClassInitFunc) e_message_box_class_init, - (GtkObjectInitFunc) e_message_box_init, - NULL, - NULL - }; - - message_box_type = gtk_type_unique (gnome_dialog_get_type (), &message_box_info); - } - - return message_box_type; -} - -static void -e_message_box_class_init (EMessageBoxClass *klass) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *)klass; - parent_class = gtk_type_class (gnome_dialog_get_type ()); - - object_class->destroy = e_message_box_destroy; - object_class->finalize = e_message_box_finalize; -} - -static void -e_message_box_init (EMessageBox *message_box) -{ - message_box->_priv = g_new0 (EMessageBoxPrivate, 1); -} - -static void -e_message_box_destroy (GtkObject *object) -{ - /* remember, destroy can be run multiple times! */ - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void -e_message_box_finalize (GtkObject *object) -{ - EMessageBox *mbox = E_MESSAGE_BOX (object); - - g_free (mbox->_priv); - mbox->_priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->finalize) - (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); -} - -/** - * e_message_box_construct: - * @messagebox: The message box to construct - * @message: The message to be displayed. - * @message_box_type: The type of the message - * @buttons: a NULL terminated array with the buttons to insert. - * - * For language bindings or subclassing, from C use #e_message_box_new or - * #e_message_box_newv - * - * Returns: - */ -void -e_message_box_construct (EMessageBox *messagebox, - const gchar *message, - const gchar *message_box_type, - const gchar **buttons) -{ - GtkWidget *hbox; - GtkWidget *pixmap = NULL; - GtkWidget *alignment; - char *s; - GtkStyle *style; - const gchar* title = NULL; - gint i = 0; - - g_return_if_fail (messagebox != NULL); - g_return_if_fail (E_IS_MESSAGE_BOX (messagebox)); - g_return_if_fail (message != NULL); - g_return_if_fail (message_box_type != NULL); - - style = gtk_widget_get_style (GTK_WIDGET (messagebox)); - - /* Make noises, basically */ - gnome_triggers_vdo (message, message_box_type, NULL); - - if (strcmp (E_MESSAGE_BOX_INFO, message_box_type) == 0) { - title = _("Information"); - s = gnome_unconditional_pixmap_file("gnome-info.png"); - if (s) { - pixmap = gnome_pixmap_new_from_file (s); - g_free(s); - } - } else if (strcmp (E_MESSAGE_BOX_WARNING, message_box_type) == 0) { - title = _("Warning"); - s = gnome_unconditional_pixmap_file ("gnome-warning.png"); - if (s) { - pixmap = gnome_pixmap_new_from_file (s); - g_free (s); - } - } else if (strcmp (E_MESSAGE_BOX_ERROR, message_box_type) == 0) { - title = _("Error"); - s = gnome_unconditional_pixmap_file ("gnome-error"); - if (s) { - pixmap = gnome_pixmap_new_from_file (s); - g_free(s); - } - } else if (strcmp (E_MESSAGE_BOX_QUESTION, message_box_type) == 0) { - title = _("Question"); - s = gnome_unconditional_pixmap_file ("gnome-question.png"); - if (s) { - pixmap = gnome_pixmap_new_from_file (s); - g_free (s); - } - } else { - title = _("Message"); - } - - g_assert (title != NULL); - - gtk_window_set_title (GTK_WINDOW (messagebox), title); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (messagebox)->vbox), - hbox, TRUE, TRUE, 10); - gtk_widget_show (hbox); - - if ((pixmap == NULL) || (GNOME_PIXMAP (pixmap)->pixmap == NULL)) { - if (pixmap) - gtk_widget_destroy (pixmap); - s = gnome_unconditional_pixmap_file ("gnome-default.png"); - if (s) { - pixmap = gnome_pixmap_new_from_file (s); - g_free (s); - } else - pixmap = NULL; - } - if (pixmap) { - gtk_box_pack_start (GTK_BOX (hbox), pixmap, FALSE, TRUE, 0); - gtk_widget_show (pixmap); - } - - messagebox->_priv->label = gtk_label_new (message); - gtk_label_set_justify (GTK_LABEL (messagebox->_priv->label), GTK_JUSTIFY_LEFT); - gtk_label_set_line_wrap (GTK_LABEL (messagebox->_priv->label), TRUE); - gtk_misc_set_padding (GTK_MISC (messagebox->_priv->label), GNOME_PAD, 0); - gtk_box_pack_start (GTK_BOX (hbox), messagebox->_priv->label, TRUE, TRUE, 0); - gtk_widget_show (messagebox->_priv->label); - - /* Add some extra space on the right to balance the pixmap */ - if (pixmap) { - alignment = gtk_alignment_new (0., 0., 0., 0.); - gtk_widget_set_usize (alignment, GNOME_PAD, -1); - gtk_widget_show (alignment); - - gtk_box_pack_start (GTK_BOX (hbox), alignment, FALSE, FALSE, 0); - } - - /* Add the "Don't show this message again." checkbox */ - messagebox->_priv->checkbox = gtk_check_button_new_with_label (_("Don't show this message again.")); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (messagebox)->vbox), - messagebox->_priv->checkbox, TRUE, TRUE, 10); - gtk_widget_show (messagebox->_priv->checkbox); - - if (buttons) { - while (buttons[i]) { - gnome_dialog_append_button (GNOME_DIALOG (messagebox), - buttons[i]); - i++; - }; - } - - if (GNOME_DIALOG (messagebox)->buttons) - gtk_widget_grab_focus (g_list_last (GNOME_DIALOG (messagebox)->buttons)->data); - - gnome_dialog_set_close (GNOME_DIALOG (messagebox), TRUE); -} - -/** - * e_message_box_new: - * @message: The message to be displayed. - * @message_box_type: The type of the message - * @...: A NULL terminated list of strings to use in each button. - * - * Creates a dialog box of type @message_box_type with @message. A number - * of buttons are inserted on it. You can use the GNOME stock identifiers - * to create gnome-stock-buttons. - * - * Returns a widget that has the dialog box. - */ -GtkWidget* -e_message_box_new (const gchar *message, - const gchar *message_box_type, ...) -{ - va_list ap; - EMessageBox *message_box; - - g_return_val_if_fail (message != NULL, NULL); - g_return_val_if_fail (message_box_type != NULL, NULL); - - va_start (ap, message_box_type); - - message_box = gtk_type_new (e_message_box_get_type ()); - - e_message_box_construct (message_box, message, message_box_type, NULL); - - /* we need to add buttons by hand here */ - while (TRUE) { - gchar * button_name; - - button_name = va_arg (ap, gchar *); - - if (button_name == NULL) { - break; - } - - gnome_dialog_append_button (GNOME_DIALOG (message_box), button_name); - } - - va_end (ap); - - gtk_widget_grab_focus (g_list_last (GNOME_DIALOG (message_box)->buttons)->data); - - return GTK_WIDGET (message_box); -} - -/** - * e_message_box_newv: - * @message: The message to be displayed. - * @message_box_type: The type of the message - * @buttons: a NULL terminated array with the buttons to insert. - * - * Creates a dialog box of type @message_box_type with @message. A number - * of buttons are inserted on it, the messages come from the @buttons array. - * You can use the GNOME stock identifiers to create gnome-stock-buttons. - * The buttons array can be NULL if you wish to add buttons yourself later. - * - * Returns a widget that has the dialog box. - */ -GtkWidget* -e_message_box_newv (const gchar *message, - const gchar *message_box_type, - const gchar **buttons) -{ - EMessageBox *message_box; - - g_return_val_if_fail (message != NULL, NULL); - g_return_val_if_fail (message_box_type != NULL, NULL); - - message_box = gtk_type_new (e_message_box_get_type ()); - - e_message_box_construct (message_box, message, - message_box_type, buttons); - - return GTK_WIDGET (message_box); -} - - -/** - * e_message_box_get_label: - * @messagebox: The message box to work on - * - * Gets the label widget of the message box. You should use this - * function instead of using the structure directly. - * - * Returns: the widget of the label with the message */ -GtkWidget * -e_message_box_get_label (EMessageBox *messagebox) -{ - g_return_val_if_fail (messagebox != NULL, NULL); - g_return_val_if_fail (E_IS_MESSAGE_BOX (messagebox), NULL); - - return messagebox->_priv->label; -} - - -/** - * e_message_box_get_checkbox: - * @messagebox: The message box to work on - * - * Gets the checkbox widget of the message box. You should use this - * function instead of using the structure directly. - * - * Returns: the checkbox widget */ -GtkWidget * -e_message_box_get_checkbox (EMessageBox *messagebox) -{ - g_return_val_if_fail (messagebox != NULL, NULL); - g_return_val_if_fail (E_IS_MESSAGE_BOX (messagebox), NULL); - - return messagebox->_priv->checkbox; -} diff --git a/widgets/misc/e-messagebox.h b/widgets/misc/e-messagebox.h deleted file mode 100644 index 11a4026848..0000000000 --- a/widgets/misc/e-messagebox.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Original Author: Jay Painter - * Modified: Jeffrey Stedfast - * - * 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 Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#ifndef __E_MESSAGE_BOX_H__ -#define __E_MESSAGE_BOX_H__ - -#include <glib.h> -#include <gtk/gtkwidget.h> -#include <libgnomeui/gnome-dialog.h> - -BEGIN_GNOME_DECLS - -#define E_TYPE_MESSAGE_BOX (e_message_box_get_type ()) -#define E_MESSAGE_BOX(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MESSAGE_BOX, EMessageBox)) -#define E_MESSAGE_BOX_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MESSAGE_BOX, EMessageBoxClass)) -#define E_IS_MESSAGE_BOX(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MESSAGE_BOX)) -#define E_IS_MESSAGE_BOX_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_MESSAGE_BOX)) -#define E_MESSAGE_BOX_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), E_TYPE_MESSAGE_BOX, EMessageBoxClass)) - - -#define E_MESSAGE_BOX_INFO "info" -#define E_MESSAGE_BOX_WARNING "warning" -#define E_MESSAGE_BOX_ERROR "error" -#define E_MESSAGE_BOX_QUESTION "question" -#define E_MESSAGE_BOX_GENERIC "generic" - - -typedef struct _EMessageBox EMessageBox; -typedef struct _EMessageBoxPrivate EMessageBoxPrivate; -typedef struct _EMessageBoxClass EMessageBoxClass; -typedef struct _EMessageBoxButton EMessageBoxButton; - -struct _EMessageBox -{ - GnomeDialog dialog; - /*< private >*/ - EMessageBoxPrivate *_priv; -}; - -struct _EMessageBoxClass -{ - GnomeDialogClass parent_class; -}; - - -guint e_message_box_get_type (void) G_GNUC_CONST; -GtkWidget* e_message_box_new (const gchar *message, - const gchar *messagebox_type, - ...); - -GtkWidget* e_message_box_newv (const gchar *message, - const gchar *messagebox_type, - const gchar **buttons); - -void e_message_box_construct (EMessageBox *messagebox, - const gchar *message, - const gchar *messagebox_type, - const gchar **buttons); - -GtkWidget *e_message_box_get_label (EMessageBox *messagebox); - -GtkWidget *e_message_box_get_checkbox (EMessageBox *messagebox); - -END_GNOME_DECLS - -#endif /* __E_MESSAGE_BOX_H__ */ diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c deleted file mode 100644 index 4d563208a2..0000000000 --- a/widgets/misc/e-search-bar.c +++ /dev/null @@ -1,525 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-search-bar.c - * - * Copyright (C) 2000, 2001 Ximian, Inc. - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * Ettore Perazzoli <ettore@ximian.com> - * - * This library 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 library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> - -#include <stdio.h> /* printf */ -#include <gtk/gtkdrawingarea.h> -#include <gtk/gtkeventbox.h> -#include <gtk/gtkmenuitem.h> -#include <gtk/gtkoptionmenu.h> - -#include <gal/widgets/e-unicode.h> -#include <gal/widgets/e-gui-utils.h> - -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> - -#include "e-search-bar.h" -#include "e-dropdown-button.h" - - -enum { - QUERY_CHANGED, - MENU_ACTIVATED, - - LAST_SIGNAL -}; - -static gint esb_signals [LAST_SIGNAL] = { 0, }; - -static GtkHBoxClass *parent_class = NULL; - -/* The arguments we take */ -enum { - ARG_0, - ARG_OPTION_CHOICE, - ARG_TEXT, -}; - - -/* Signals. */ - -static void -emit_query_changed (ESearchBar *esb) -{ - gtk_signal_emit(GTK_OBJECT (esb), - esb_signals [QUERY_CHANGED]); -} - -static void -emit_menu_activated (ESearchBar *esb, int item) -{ - gtk_signal_emit(GTK_OBJECT (esb), - esb_signals [MENU_ACTIVATED], - item); -} - - -/* Callbacks. */ - -static void -menubar_activated_cb (GtkWidget *widget, ESearchBar *esb) -{ - int id; - - id = GPOINTER_TO_INT(gtk_object_get_data (GTK_OBJECT (widget), "EsbMenuId")); - - emit_menu_activated(esb, id); -} - -static void -option_activated_cb (GtkWidget *widget, - ESearchBar *esb) -{ - int id; - - id = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "EsbChoiceId")); - - esb->option_choice = id; - emit_query_changed (esb); -} - -static void -entry_activated_cb (GtkWidget *widget, - ESearchBar *esb) -{ - emit_query_changed (esb); -} - - -/* Widgetry creation. */ - -static void add_dropdown(ESearchBar *esb, ESearchBarItem *items) -{ - GtkWidget *menu = esb->dropdown_menu; - GtkWidget *item; - - if (items->text) { - char *str; - str = _(items->text); - if (str == items->text) { - /* It may be english string, or utf8 rule name */ - item = e_utf8_gtk_menu_item_new_with_label (GTK_MENU (menu), str); - } else - item = gtk_menu_item_new_with_label (str); - } - else - item = gtk_menu_item_new(); - - gtk_widget_show(item); - gtk_menu_append (GTK_MENU (menu), item); - gtk_object_set_data (GTK_OBJECT (item), "EsbMenuId", GINT_TO_POINTER(items->id)); - gtk_signal_connect (GTK_OBJECT (item), "activate", - GTK_SIGNAL_FUNC (menubar_activated_cb), - esb); -} - -static void -set_dropdown (ESearchBar *esb, - ESearchBarItem *items) -{ - GtkWidget *menu; - GtkWidget *dropdown; - int i; - - menu = esb->dropdown_menu = gtk_menu_new (); - for (i = 0; items[i].id != -1; i++) - add_dropdown(esb, items+i); - - gtk_widget_show_all (menu); - - dropdown = e_dropdown_button_new (_("Sear_ch"), GTK_MENU (menu)); - GTK_WIDGET_UNSET_FLAGS (dropdown, GTK_CAN_FOCUS); - gtk_widget_show (dropdown); - - if (esb->dropdown_holder == NULL) { - - /* So, GtkOptionMenu is stupid; it adds a 1-pixel-wide empty border - around the button for no reason. So we add a 1-pixel-wide border - around the button as well, by using an event box. */ - - esb->dropdown_holder = gtk_event_box_new (); - gtk_container_set_border_width (GTK_CONTAINER (esb->dropdown_holder), 1); - esb->dropdown = dropdown; - gtk_container_add (GTK_CONTAINER (esb->dropdown_holder), esb->dropdown); - gtk_widget_show (esb->dropdown_holder); - - gtk_box_pack_start(GTK_BOX(esb), esb->dropdown_holder, FALSE, FALSE, 0); - } else { - gtk_widget_destroy(esb->dropdown); - esb->dropdown = dropdown; - gtk_container_add (GTK_CONTAINER (esb->dropdown_holder), esb->dropdown); - } -} - -static void -set_option(ESearchBar *esb, ESearchBarItem *items) -{ - GtkWidget *menu; - GtkRequisition dropdown_requisition; - GtkRequisition option_requisition; - int i; - - if (esb->option) { - gtk_widget_destroy(esb->option_menu); - } else { - esb->option = gtk_option_menu_new(); - gtk_widget_show(esb->option); - gtk_box_pack_start(GTK_BOX(esb), esb->option, FALSE, FALSE, 0); - } - - esb->option_menu = menu = gtk_menu_new (); - for (i = 0; items[i].id != -1; i++) { - GtkWidget *item; - - if (items[i].text) { - char *str; - str = _(items[i].text); - if (str == items[i].text) { - /* It may be english string, or utf8 rule name */ - item = e_utf8_gtk_menu_item_new_with_label (GTK_MENU (menu), str); - } else - item = gtk_menu_item_new_with_label (str); - } - else - item = gtk_menu_item_new(); - - gtk_menu_append (GTK_MENU (menu), item); - - gtk_object_set_data (GTK_OBJECT (item), "EsbChoiceId", GINT_TO_POINTER(items[i].id)); - - gtk_signal_connect (GTK_OBJECT (item), "activate", - GTK_SIGNAL_FUNC (option_activated_cb), - esb); - } - gtk_widget_show_all (menu); - - gtk_option_menu_set_menu (GTK_OPTION_MENU (esb->option), menu); - gtk_option_menu_set_history (GTK_OPTION_MENU (esb->option), 0); - - gtk_widget_set_sensitive (esb->option, TRUE); - - /* Set the minimum height of this widget to that of the dropdown - button, for a better look. */ - g_assert (esb->dropdown != NULL); - - gtk_widget_size_request (esb->dropdown, &dropdown_requisition); - gtk_widget_size_request (esb->option, &option_requisition); - - gtk_container_set_border_width (GTK_CONTAINER (esb->dropdown), GTK_CONTAINER (esb->option)->border_width); -} - -static void -add_entry (ESearchBar *esb) -{ - esb->entry = gtk_entry_new(); - gtk_signal_connect (GTK_OBJECT (esb->entry), "activate", - GTK_SIGNAL_FUNC (entry_activated_cb), esb); - gtk_widget_show(esb->entry); - gtk_box_pack_start(GTK_BOX(esb), esb->entry, TRUE, TRUE, 0); -} - -static void -add_spacer (ESearchBar *esb) -{ - GtkWidget *spacer; - - spacer = gtk_drawing_area_new(); - gtk_widget_show(spacer); - gtk_box_pack_start(GTK_BOX(esb), spacer, FALSE, FALSE, 0); - - gtk_widget_set_usize(spacer, 19, 1); -} - -static int -find_id(GtkWidget *menu, int idin, const char *type, GtkWidget **widget) -{ - GList *l = GTK_MENU_SHELL(menu)->children; - int row = -1, i = 0, id; - - if (widget) - *widget = NULL; - while (l) { - id = GPOINTER_TO_INT(gtk_object_get_data(l->data, type)); - printf("comparing id %d to query %d\n", id, idin); - if (id == idin) { - row = i; - if (widget) - *widget = l->data; - break; - } - i++; - l = l->next; - } - return row; -} - - -/* GtkObject methods. */ - -static void -impl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - ESearchBar *esb = E_SEARCH_BAR(object); - - switch (arg_id) { - case ARG_OPTION_CHOICE: - GTK_VALUE_ENUM (*arg) = e_search_bar_get_option_choice (esb); - break; - - case ARG_TEXT: - GTK_VALUE_STRING (*arg) = e_search_bar_get_text (esb); - break; - - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -static void -impl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - ESearchBar *esb = E_SEARCH_BAR(object); - int row; - - switch (arg_id) { - case ARG_OPTION_CHOICE: - esb->option_choice = GTK_VALUE_ENUM(*arg); - row = find_id(esb->option_menu, esb->option_choice, "EsbChoiceId", NULL); - if (row == -1) - row = 0; - gtk_option_menu_set_history (GTK_OPTION_MENU (esb->option), row); - emit_query_changed (esb); - break; - - case ARG_TEXT: - e_utf8_gtk_editable_set_text(GTK_EDITABLE(esb->entry), GTK_VALUE_STRING (*arg)); - emit_query_changed (esb); - break; - - default: - break; - } -} - -static void -impl_destroy (GtkObject *object) -{ - if (GTK_OBJECT_CLASS(parent_class)->destroy) - GTK_OBJECT_CLASS(parent_class)->destroy (object); -} - - -static void -class_init (ESearchBarClass *klass) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS(klass); - - parent_class = gtk_type_class (gtk_hbox_get_type ()); - - object_class->set_arg = impl_set_arg; - object_class->get_arg = impl_get_arg; - object_class->destroy = impl_destroy; - - klass->set_menu = set_dropdown; - klass->set_option = set_option; - - gtk_object_add_arg_type ("ESearchBar::option_choice", GTK_TYPE_ENUM, - GTK_ARG_READWRITE, ARG_OPTION_CHOICE); - gtk_object_add_arg_type ("ESearchBar::text", GTK_TYPE_STRING, - GTK_ARG_READWRITE, ARG_TEXT); - - esb_signals [QUERY_CHANGED] = - gtk_signal_new ("query_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (ESearchBarClass, query_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - esb_signals [MENU_ACTIVATED] = - gtk_signal_new ("menu_activated", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (ESearchBarClass, menu_activated), - gtk_marshal_NONE__INT, - GTK_TYPE_NONE, 1, GTK_TYPE_INT); - - gtk_object_class_add_signals (object_class, esb_signals, LAST_SIGNAL); -} - -static void -init (ESearchBar *esb) -{ - esb->dropdown = NULL; - esb->option = NULL; - esb->entry = NULL; - - esb->option_choice = 0; -} - - -/* Object construction. */ - -void -e_search_bar_construct (ESearchBar *search_bar, - ESearchBarItem *menu_items, - ESearchBarItem *option_items) -{ - g_return_if_fail (search_bar != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (menu_items != NULL); - g_return_if_fail (option_items != NULL); - - gtk_box_set_spacing (GTK_BOX (search_bar), 1); - - e_search_bar_set_menu(search_bar, menu_items); - - e_search_bar_set_option(search_bar, option_items); - - add_entry (search_bar); - - add_spacer (search_bar); -} - -void -e_search_bar_set_menu(ESearchBar *search_bar, ESearchBarItem *menu_items) -{ - g_return_if_fail (search_bar != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (menu_items != NULL); - - ((ESearchBarClass *)((GtkObject *)search_bar)->klass)->set_menu(search_bar, menu_items); -} - -void -e_search_bar_add_menu(ESearchBar *search_bar, ESearchBarItem *menu_item) -{ - g_return_if_fail (search_bar != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (menu_item != NULL); - - add_dropdown(search_bar, menu_item); -} - -void -e_search_bar_set_option(ESearchBar *search_bar, ESearchBarItem *option_items) -{ - g_return_if_fail (search_bar != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (option_items != NULL); - - ((ESearchBarClass *)((GtkObject *)search_bar)->klass)->set_option(search_bar, option_items); -} - -GtkWidget * -e_search_bar_new (ESearchBarItem *menu_items, - ESearchBarItem *option_items) -{ - GtkWidget *widget; - - g_return_val_if_fail (menu_items != NULL, NULL); - g_return_val_if_fail (option_items != NULL, NULL); - - widget = GTK_WIDGET (gtk_type_new (e_search_bar_get_type ())); - - e_search_bar_construct (E_SEARCH_BAR (widget), menu_items, option_items); - - return widget; -} - -void -e_search_bar_set_menu_sensitive(ESearchBar *esb, int id, gboolean state) -{ - int row; - GtkWidget *widget; - - row = find_id(esb->dropdown_menu, id, "EsbMenuId", &widget); - if (row != -1) - gtk_widget_set_sensitive(widget, state); -} - -GtkType -e_search_bar_get_type (void) -{ - static GtkType type = 0; - - if (!type) { - static const GtkTypeInfo info = { - "ESearchBar", - sizeof (ESearchBar), - sizeof (ESearchBarClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (gtk_hbox_get_type (), &info); - } - - return type; -} - -/** - * e_search_bar_get_option_choice: - * @search_bar: A search bar. - * - * Queries the currently selected item in the options menu of a search bar. - * - * Return value: Identifier of the selected item in the options menu. - **/ -int -e_search_bar_get_option_choice (ESearchBar *search_bar) -{ - g_return_val_if_fail (search_bar != NULL, -1); - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1); - - return search_bar->option_choice; -} - -/** - * e_search_bar_get_text: - * @search_bar: A search bar. - * - * Queries the text of the entry line in a search bar. - * - * Return value: The text string that is in the entry line of the search bar. - * This must be freed using g_free(). - **/ -char * -e_search_bar_get_text (ESearchBar *search_bar) -{ - g_return_val_if_fail (search_bar != NULL, NULL); - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - return e_utf8_gtk_editable_get_text (GTK_EDITABLE (search_bar->entry)); -} diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h deleted file mode 100644 index 8b262a0f4f..0000000000 --- a/widgets/misc/e-search-bar.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-search-bar.h - * Copyright (C) 2000 Helix Code, Inc. - * Author: Chris Lahey <clahey@helixcode.com> - * - * This library 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 library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#ifndef __E_SEARCH_BAR_H__ -#define __E_SEARCH_BAR_H__ - -#include <gtk/gtkhbox.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -/* ESearchBar - A card displaying information about a contact. - * - * The following arguments are available: - * - * name type read/write description - * --------------------------------------------------------------------------------- - * option_choice int RW Which option choice is currently selected. - * text string RW Text in the entry box. - */ - -#define E_SEARCH_BAR_TYPE (e_search_bar_get_type ()) -#define E_SEARCH_BAR(obj) (GTK_CHECK_CAST ((obj), E_SEARCH_BAR_TYPE, ESearchBar)) -#define E_SEARCH_BAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_SEARCH_BAR_TYPE, ESearchBarClass)) -#define E_IS_SEARCH_BAR(obj) (GTK_CHECK_TYPE ((obj), E_SEARCH_BAR_TYPE)) -#define E_IS_SEARCH_BAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_SEARCH_BAR_TYPE)) - -typedef struct { - char *text; - int id; -} ESearchBarItem; - -typedef struct _ESearchBar ESearchBar; -typedef struct _ESearchBarClass ESearchBarClass; - -struct _ESearchBar -{ - GtkHBox parent; - - /* item specific fields */ - GtkWidget *dropdown; - GtkWidget *option; - GtkWidget *entry; - - /* PRIVATE */ - GtkWidget *dropdown_holder; /* holds the dropdown */ - GtkWidget *option_menu; - GtkWidget *dropdown_menu; - - int option_choice; -}; - -struct _ESearchBarClass -{ - GtkHBoxClass parent_class; - - void (*set_menu) (ESearchBar *, ESearchBarItem *); - void (*set_option) (ESearchBar *, ESearchBarItem *); - - void (*query_changed) (ESearchBar *search); - void (*menu_activated) (ESearchBar *search, int item); -}; - - -GtkType e_search_bar_get_type (void); -void e_search_bar_set_menu (ESearchBar *search_bar, ESearchBarItem *menu_items); -void e_search_bar_add_menu (ESearchBar *search_bar, ESearchBarItem *menu_item); - -void e_search_bar_set_option (ESearchBar *search_bar, ESearchBarItem *option_items); -void e_search_bar_construct (ESearchBar *search_bar, - ESearchBarItem *menu_items, - ESearchBarItem *option_items); -GtkWidget *e_search_bar_new (ESearchBarItem *menu_items, - ESearchBarItem *option_items); - -void e_search_bar_set_menu_sensitive(ESearchBar *search_bar, int id, gboolean state); - -int e_search_bar_get_option_choice (ESearchBar *search_bar); -char *e_search_bar_get_text (ESearchBar *search_bar); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __E_SEARCH_BAR_H__ */ diff --git a/widgets/misc/e-title-bar.c b/widgets/misc/e-title-bar.c deleted file mode 100644 index 8ca6885ccf..0000000000 --- a/widgets/misc/e-title-bar.c +++ /dev/null @@ -1,402 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-title-bar.c - * - * Copyright (C) 2000 Helix Code, 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: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtkbox.h> -#include <gtk/gtkbutton.h> -#include <gtk/gtkhbox.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkpixmap.h> -#include <gtk/gtksignal.h> -#include <gtk/gtktypeutils.h> - -#include <gal/util/e-util.h> -#include "e-clipped-label.h" - -#include "e-title-bar.h" - - -enum { - LABEL_BUTTON_PRESS_EVENT, - BUTTON_CLICKED, - LAST_SIGNAL -}; -static guint signals[LAST_SIGNAL] = { 0 }; - - -/* The pixmaps. */ - -static char *close_xpm[] = { - "12 12 2 1", - " c none", - ". c #000000000000", - " ", - " .. .. ", - " ... ... ", - " ... ... ", - " ...... ", - " .... ", - " .... ", - " ...... ", - " ... ... ", - " ... ... ", - " .. .. ", - " " -}; - -static char *pin_xpm[] = { - "16 16 33 1", - " c None", - ". c #000000", - "+ c #74744D", - "@ c #B2B279", - "# c #6C6C46", - "$ c #CACA9C", - "% c #F4F4AD", - "& c #85855A", - "* c #B1B175", - "= c #9A9A66", - "- c #A9A98A", - "; c #B0B07B", - "> c #535353", - ", c #818181", - "' c #B7B7B7", - ") c #D8D8D8", - "! c #FFFFFF", - "~ c #EBEBA1", - "{ c #8A8A75", - "] c #9F9F76", - "^ c #9E9E75", - "/ c #8A8A66", - "( c #979770", - "_ c #6B6B46", - ": c #28281A", - "< c #505034", - "[ c #666645", - "} c #61614D", - "| c #818155", - "1 c #4A4A31", - "2 c #4D4D34", - "3 c #6C6C48", - "4 c #5D5D3E", - " ", - " ", - " ", - " . . ", - " .. .+. ", - " .@...#$. ", - " ......%&*=-;. ", - ".>,')!.~{]^/(. ", - " ......_:<[}|. ", - " .1...23. ", - " .. .4. ", - " . . ", - " ", - " ", - " ", - " " -}; - - -#define PARENT_TYPE GTK_TYPE_FRAME -static GtkFrameClass *parent_class = NULL; - -struct _ETitleBarPrivate { - ETitleBarButtonMode button_mode; - GtkWidget *label; - GtkWidget *button; - GtkWidget *close_gtk_pixmap; - GtkWidget *pin_gtk_pixmap; -}; - - -/* Mode handling. We put both the close and pin GtkPixmaps into an hbox in the - button, and hide one of them according to the mode. */ - -static void -show_and_hide_pixmaps_according_to_mode (ETitleBar *title_bar) -{ - ETitleBarPrivate *priv; - - priv = title_bar->priv; - - if (priv->close_gtk_pixmap == NULL || priv->pin_gtk_pixmap == NULL) - return; - - switch (priv->button_mode) { - case E_TITLE_BAR_BUTTON_MODE_PIN: - gtk_widget_hide (priv->close_gtk_pixmap); - gtk_widget_show (priv->pin_gtk_pixmap); - break; - case E_TITLE_BAR_BUTTON_MODE_CLOSE: - gtk_widget_hide (priv->pin_gtk_pixmap); - gtk_widget_show (priv->close_gtk_pixmap); - break; - default: - g_assert_not_reached (); - } -} - - -/* Child signal callbacks. */ - -static void -button_realize_cb (GtkWidget *widget, - gpointer data) -{ - GdkPixmap *close_pixmap; - GdkBitmap *close_mask; - GdkPixmap *pin_pixmap; - GdkBitmap *pin_mask; - GtkWidget *hbox; - ETitleBar *title_bar; - ETitleBarPrivate *priv; - - title_bar = E_TITLE_BAR (data); - priv = title_bar->priv; - - if (priv->close_gtk_pixmap != NULL) - return; - - close_pixmap = gdk_pixmap_create_from_xpm_d (GTK_WIDGET (priv->button)->window, - &close_mask, NULL, close_xpm); - priv->close_gtk_pixmap = gtk_pixmap_new (close_pixmap, close_mask); - - pin_pixmap = gdk_pixmap_create_from_xpm_d (GTK_WIDGET (priv->button)->window, - &pin_mask, NULL, pin_xpm); - priv->pin_gtk_pixmap = gtk_pixmap_new (pin_pixmap, pin_mask); - - hbox = gtk_hbox_new (TRUE, 0); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (hbox), priv->pin_gtk_pixmap, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (hbox), priv->close_gtk_pixmap, TRUE, TRUE, 0); - - gtk_container_add (GTK_CONTAINER (priv->button), hbox); - - gdk_pixmap_unref (close_pixmap); - gdk_bitmap_unref (close_mask); - gdk_pixmap_unref (pin_pixmap); - gdk_bitmap_unref (pin_mask); - - show_and_hide_pixmaps_according_to_mode (title_bar); -} - -static void -button_clicked_cb (GtkButton *button, - gpointer data) -{ - ETitleBar *title_bar; - - title_bar = E_TITLE_BAR (data); - - gtk_signal_emit (GTK_OBJECT (title_bar), signals[BUTTON_CLICKED]); -} - -static void -label_button_press_event_cb (GtkWidget *widget, - GdkEventButton *event, - gpointer data) -{ - ETitleBar *title_bar; - - title_bar = E_TITLE_BAR (data); - - gtk_signal_emit (GTK_OBJECT (title_bar), signals[LABEL_BUTTON_PRESS_EVENT], event); -} - - -/* GtkObject methods. */ - -static void -destroy (GtkObject *object) -{ - ETitleBar *title_bar; - ETitleBarPrivate *priv; - - title_bar = E_TITLE_BAR (object); - priv = title_bar->priv; - - g_free (priv); - - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -static void -class_init (ETitleBarClass *klass) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass*) klass; - object_class->destroy = destroy; - - parent_class = gtk_type_class (gtk_frame_get_type ()); - - signals[LABEL_BUTTON_PRESS_EVENT] = - gtk_signal_new ("label_button_press_event", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (ETitleBarClass, label_button_press_event), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_GDK_EVENT); - - signals[BUTTON_CLICKED] = - gtk_signal_new ("button_clicked", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (ETitleBarClass, button_clicked), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); -} - -static void -init (ETitleBar *title_bar) -{ - ETitleBarPrivate *priv; - - priv = g_new (ETitleBarPrivate, 1); - - priv->button_mode = E_TITLE_BAR_BUTTON_MODE_CLOSE; - priv->label = NULL; - priv->button = NULL; - priv->close_gtk_pixmap = NULL; - priv->pin_gtk_pixmap = NULL; - - title_bar->priv = priv; -} - - -void -e_title_bar_construct (ETitleBar *title_bar, - const char *title) -{ - ETitleBarPrivate *priv; - GtkWidget *hbox; - - g_return_if_fail (title_bar != NULL); - g_return_if_fail (E_IS_TITLE_BAR (title_bar)); - - priv = title_bar->priv; - - priv->label = e_clipped_label_new (title); - gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.5); - gtk_widget_show (priv->label); - - priv->button = gtk_button_new (); - GTK_WIDGET_UNSET_FLAGS (priv->button, GTK_CAN_FOCUS); - gtk_container_set_border_width (GTK_CONTAINER (priv->button), 1); - gtk_button_set_relief (GTK_BUTTON (priv->button), GTK_RELIEF_NONE); - gtk_widget_show (priv->button); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (hbox), priv->label, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (hbox), priv->button, FALSE, TRUE, 1); - gtk_widget_show (hbox); - - gtk_container_add (GTK_CONTAINER (title_bar), hbox); - - gtk_signal_connect (GTK_OBJECT (priv->button), "realize", - GTK_SIGNAL_FUNC (button_realize_cb), title_bar); - gtk_signal_connect (GTK_OBJECT (priv->button), "clicked", - GTK_SIGNAL_FUNC (button_clicked_cb), title_bar); - gtk_signal_connect (GTK_OBJECT (priv->label), "button_press_event", - GTK_SIGNAL_FUNC (label_button_press_event_cb), title_bar); -} - -GtkWidget * -e_title_bar_new (const char *title) -{ - ETitleBar *title_bar; - - title_bar = gtk_type_new (e_title_bar_get_type ()); - - e_title_bar_construct (title_bar, title); - - return GTK_WIDGET (title_bar); -} - - -void -e_title_bar_set_title (ETitleBar *title_bar, - const char *title) -{ - g_return_if_fail (title_bar != NULL); - g_return_if_fail (E_IS_TITLE_BAR (title_bar)); - - e_clipped_label_set_text (E_CLIPPED_LABEL (title_bar->priv->label), title); -} - -void -e_title_bar_show_button (ETitleBar *title_bar, - gboolean show) -{ - ETitleBarPrivate *priv; - - g_return_if_fail (title_bar != NULL); - g_return_if_fail (E_IS_TITLE_BAR (title_bar)); - - priv = title_bar->priv; - - if (show) - gtk_widget_show (priv->button); - else - gtk_widget_hide (priv->button); -} - -void -e_title_bar_set_button_mode (ETitleBar *title_bar, - ETitleBarButtonMode button_mode) -{ - ETitleBarPrivate *priv; - - g_return_if_fail (title_bar != NULL); - g_return_if_fail (E_IS_TITLE_BAR (title_bar)); - g_return_if_fail (button_mode == E_TITLE_BAR_BUTTON_MODE_CLOSE - || button_mode == E_TITLE_BAR_BUTTON_MODE_PIN); - - priv = title_bar->priv; - - if (priv->button_mode == button_mode) - return; - - priv->button_mode = button_mode; - show_and_hide_pixmaps_according_to_mode (title_bar); -} - -ETitleBarButtonMode -e_title_bar_get_button_mode (ETitleBar *title_bar) -{ - g_return_val_if_fail (title_bar != NULL, E_TITLE_BAR_BUTTON_MODE_CLOSE); - g_return_val_if_fail (E_IS_TITLE_BAR (title_bar), E_TITLE_BAR_BUTTON_MODE_CLOSE); - - return title_bar->priv->button_mode; -} - - -E_MAKE_TYPE (e_title_bar, "ETitleBar", ETitleBar, class_init, init, PARENT_TYPE) diff --git a/widgets/misc/e-title-bar.h b/widgets/misc/e-title-bar.h deleted file mode 100644 index f91e76c889..0000000000 --- a/widgets/misc/e-title-bar.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-title-bar.h - * - * Copyright (C) 2000 Helix Code, 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: Ettore Perazzoli - */ - -#ifndef __E_TITLE_BAR_H__ -#define __E_TITLE_BAR_H__ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtkframe.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_TITLE_BAR (e_title_bar_get_type ()) -#define E_TITLE_BAR(obj) (GTK_CHECK_CAST ((obj), E_TYPE_TITLE_BAR, ETitleBar)) -#define E_TITLE_BAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_TITLE_BAR, ETitleBarClass)) -#define E_IS_TITLE_BAR(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_TITLE_BAR)) -#define E_IS_TITLE_BAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_TITLE_BAR)) - - -enum _ETitleBarButtonMode { - E_TITLE_BAR_BUTTON_MODE_PIN, - E_TITLE_BAR_BUTTON_MODE_CLOSE -}; -typedef enum _ETitleBarButtonMode ETitleBarButtonMode; - -typedef struct _ETitleBar ETitleBar; -typedef struct _ETitleBarPrivate ETitleBarPrivate; -typedef struct _ETitleBarClass ETitleBarClass; - -struct _ETitleBar { - GtkFrame parent; - - ETitleBarPrivate *priv; -}; - -struct _ETitleBarClass { - GtkFrameClass parent_class; - - /* Signals. */ - - void (* label_button_press_event) (ETitleBar *title_bar, GdkEventButton *event); - void (* button_clicked) (ETitleBar *title_bar); -}; - - -GtkType e_title_bar_get_type (void); -void e_title_bar_construct (ETitleBar *title_bar, - const char *title); -GtkWidget *e_title_bar_new (const char *title); -void e_title_bar_set_title (ETitleBar *title_bar, - const char *title); -void e_title_bar_show_button (ETitleBar *title_bar, - gboolean show); -void e_title_bar_set_button_mode (ETitleBar *title_bar, - ETitleBarButtonMode button_mode); -ETitleBarButtonMode e_title_bar_get_button_mode (ETitleBar *title_bar); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __E_TITLE_BAR_H__ */ diff --git a/widgets/misc/test-calendar.c b/widgets/misc/test-calendar.c deleted file mode 100644 index 735633424f..0000000000 --- a/widgets/misc/test-calendar.c +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 2000, Helix Code, 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 - */ - -/* - * test-calendar - tests the ECalendar widget. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtkdnd.h> -#include <gtk/gtkmain.h> -#include <gtk/gtkvbox.h> -#include <libgnomeui/gnome-app.h> -#include <libgnomeui/gnome-init.h> -#include "e-calendar.h" - -/* Drag and Drop stuff. */ -enum { - TARGET_SHORTCUT -}; -static GtkTargetEntry target_table[] = { - { "E-SHORTCUT", 0, TARGET_SHORTCUT } -}; -static guint n_targets = sizeof(target_table) / sizeof(target_table[0]); - - -static void on_date_range_changed (ECalendarItem *calitem); -static void on_selection_changed (ECalendarItem *calitem); -static void get_day_style (ECalendarItem *calitem, - gint year, - gint month, - gint day, - gint day_style, - gboolean today, - gboolean prev_or_next_month, - gboolean selected, - gboolean has_focus, - gboolean drop_target, - GdkColor **bg_color, - GdkColor **fg_color, - GdkColor **box_color, - gboolean *bold, - gpointer data); - -static void -delete_event_cb (GtkWidget *widget, - GdkEventAny *event, - gpointer data) -{ - gtk_main_quit (); -} - -int -main (int argc, char **argv) -{ - GtkWidget *app; - GtkWidget *cal; - GtkWidget *vbox; - ECalendarItem *calitem; - - gnome_init ("test-calendar", "0.0", argc, argv); - - app = gnome_app_new ("Test", "Test"); - gtk_window_set_default_size (GTK_WINDOW (app), 400, 400); - gtk_window_set_policy (GTK_WINDOW (app), FALSE, TRUE, FALSE); - gtk_container_set_border_width (GTK_CONTAINER (app), 8); - - gtk_signal_connect (GTK_OBJECT (app), "delete_event", - GTK_SIGNAL_FUNC (delete_event_cb), NULL); - - cal = e_calendar_new (); - e_calendar_set_minimum_size (E_CALENDAR (cal), 1, 1); - calitem = E_CALENDAR (cal)->calitem; - gtk_widget_show (cal); - e_calendar_item_set_style_callback (calitem, get_day_style, - NULL, NULL); - - gtk_signal_connect (GTK_OBJECT (calitem), "date_range_changed", - GTK_SIGNAL_FUNC (on_date_range_changed), NULL); - gtk_signal_connect (GTK_OBJECT (calitem), "selection_changed", - GTK_SIGNAL_FUNC (on_selection_changed), NULL); - - - gtk_drag_dest_set (cal, - GTK_DEST_DEFAULT_ALL, - target_table, n_targets, - GDK_ACTION_COPY | GDK_ACTION_MOVE); - - - vbox = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), cal, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - gnome_app_set_contents (GNOME_APP (app), vbox); - gtk_widget_show (app); - - gtk_main (); - - return 0; -} - - -static void -on_date_range_changed (ECalendarItem *calitem) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - - e_calendar_item_get_date_range (calitem, - &start_year, &start_month, &start_day, - &end_year, &end_month, &end_day); - - g_print ("Date range changed (D/M/Y): %i/%i/%i - %i/%i/%i\n", - start_day, start_month + 1, start_year, - end_day, end_month + 1, end_year); - - /* These days should appear bold. Remember month is 0 to 11. */ - e_calendar_item_mark_day (calitem, 2000, 7, 26, /* 26th Aug 2000. */ - E_CALENDAR_ITEM_MARK_BOLD); - e_calendar_item_mark_day (calitem, 2000, 8, 13, /* 13th Sep 2000. */ - E_CALENDAR_ITEM_MARK_BOLD); -} - - -static void -on_selection_changed (ECalendarItem *calitem) -{ - GDate start_date, end_date; - - e_calendar_item_get_selection (calitem, &start_date, &end_date); - - g_print ("Selection changed (D/M/Y): %i/%i/%i - %i/%i/%i\n", - g_date_day (&start_date), - g_date_month (&start_date), - g_date_year (&start_date), - g_date_day (&end_date), - g_date_month (&end_date), - g_date_year (&end_date)); -} - - -static void -get_day_style (ECalendarItem *calitem, - gint year, - gint month, - gint day, - gint day_style, - gboolean today, - gboolean prev_or_next_month, - gboolean selected, - gboolean has_focus, - gboolean drop_target, - GdkColor **bg_color, - GdkColor **fg_color, - GdkColor **box_color, - gboolean *bold, - gpointer data) -{ - *bg_color = NULL; - *fg_color = NULL; - *box_color = NULL; - *bold = FALSE; - -#if 1 - - if (day_style == 1) - *bold = TRUE; - - if (today) - *box_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_TODAY_BOX]; - - if (prev_or_next_month) - *fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG]; - - if (selected) { - *fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG]; - *bg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG]; - } - -#else - - if (day_style == 1) - *bold = TRUE; - - if (today) - *box_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG]; - - if (prev_or_next_month) - *fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_TODAY_BOX]; - - if (selected) { - *fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG]; - *bg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG]; - } - -#endif -} diff --git a/widgets/misc/test-dateedit.c b/widgets/misc/test-dateedit.c deleted file mode 100644 index 74b10b8c8b..0000000000 --- a/widgets/misc/test-dateedit.c +++ /dev/null @@ -1,284 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 2000, Helix Code, 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 - */ - -/* - * test-dateedit - tests the EDateEdit widget. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <gtk/gtkbutton.h> -#include <gtk/gtkmain.h> -#include <gtk/gtktable.h> -#include <gtk/gtkwindow.h> -#include <libgnomeui/gnome-app.h> -#include <libgnomeui/gnome-init.h> -#include "e-dateedit.h" - -static void delete_event_cb (GtkWidget *widget, - GdkEventAny *event, - GtkWidget *app); -static void on_get_date_clicked (GtkWidget *button, - EDateEdit *dedit); -static void on_toggle_24_hour_clicked (GtkWidget *button, - EDateEdit *dedit); -static void on_changed (EDateEdit *dedit, - gchar *name); -#if 0 -static void on_date_changed (EDateEdit *dedit, - gchar *name); -static void on_time_changed (EDateEdit *dedit, - gchar *name); -#endif - -int -main (int argc, char **argv) -{ - GtkWidget *app; - EDateEdit *dedit; - GtkWidget *table, *button; - - gnome_init ("test-dateedit", "0.0", argc, argv); - - app = gnome_app_new ("Test", "Test"); - gtk_window_set_default_size (GTK_WINDOW (app), 300, 200); - gtk_window_set_policy (GTK_WINDOW (app), FALSE, TRUE, TRUE); - gtk_container_set_border_width (GTK_CONTAINER (app), 8); - - gtk_signal_connect (GTK_OBJECT (app), "delete_event", - GTK_SIGNAL_FUNC (delete_event_cb), app); - - table = gtk_table_new (3, 3, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_table_set_col_spacings (GTK_TABLE (table), 4); - gtk_widget_show (table); - gnome_app_set_contents (GNOME_APP (app), table); - - /* EDateEdit 1. */ - dedit = E_DATE_EDIT (e_date_edit_new ()); - gtk_table_attach (GTK_TABLE (table), (GtkWidget*) dedit, - 0, 1, 0, 1, GTK_FILL, GTK_EXPAND, 0, 0); - gtk_widget_show ((GtkWidget*) (dedit)); - -#if 0 - gtk_signal_connect (GTK_OBJECT (dedit), "date_changed", - GTK_SIGNAL_FUNC (on_date_changed), "1"); - gtk_signal_connect (GTK_OBJECT (dedit), "time_changed", - GTK_SIGNAL_FUNC (on_time_changed), "1"); -#else - gtk_signal_connect (GTK_OBJECT (dedit), "changed", - GTK_SIGNAL_FUNC (on_changed), "1"); -#endif - - button = gtk_button_new_with_label ("Print Date"); - gtk_table_attach (GTK_TABLE (table), button, - 1, 2, 0, 1, 0, 0, 0, 0); - gtk_widget_show (button); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (on_get_date_clicked), dedit); - - /* EDateEdit 2. */ - dedit = E_DATE_EDIT (e_date_edit_new ()); - gtk_table_attach (GTK_TABLE (table), (GtkWidget*) dedit, - 0, 1, 1, 2, GTK_FILL, GTK_EXPAND, 0, 0); - gtk_widget_show ((GtkWidget*) (dedit)); - e_date_edit_set_week_start_day (dedit, 1); - e_date_edit_set_show_week_numbers (dedit, TRUE); - e_date_edit_set_use_24_hour_format (dedit, FALSE); - e_date_edit_set_time_popup_range (dedit, 8, 18); - e_date_edit_set_show_time (dedit, FALSE); - -#if 0 - gtk_signal_connect (GTK_OBJECT (dedit), "date_changed", - GTK_SIGNAL_FUNC (on_date_changed), "2"); - gtk_signal_connect (GTK_OBJECT (dedit), "time_changed", - GTK_SIGNAL_FUNC (on_time_changed), "2"); -#else - gtk_signal_connect (GTK_OBJECT (dedit), "changed", - GTK_SIGNAL_FUNC (on_changed), "2"); -#endif - - button = gtk_button_new_with_label ("Print Date"); - gtk_table_attach (GTK_TABLE (table), button, - 1, 2, 1, 2, 0, 0, 0, 0); - gtk_widget_show (button); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (on_get_date_clicked), dedit); - - /* EDateEdit 3. */ - dedit = E_DATE_EDIT (e_date_edit_new ()); - gtk_table_attach (GTK_TABLE (table), (GtkWidget*) dedit, - 0, 1, 2, 3, GTK_FILL, GTK_EXPAND, 0, 0); - gtk_widget_show ((GtkWidget*) (dedit)); - e_date_edit_set_week_start_day (dedit, 1); - e_date_edit_set_show_week_numbers (dedit, TRUE); - e_date_edit_set_use_24_hour_format (dedit, FALSE); - e_date_edit_set_time_popup_range (dedit, 8, 18); - e_date_edit_set_allow_no_date_set (dedit, TRUE); - -#if 0 - gtk_signal_connect (GTK_OBJECT (dedit), "date_changed", - GTK_SIGNAL_FUNC (on_date_changed), "3"); - gtk_signal_connect (GTK_OBJECT (dedit), "time_changed", - GTK_SIGNAL_FUNC (on_time_changed), "3"); -#else - gtk_signal_connect (GTK_OBJECT (dedit), "changed", - GTK_SIGNAL_FUNC (on_changed), "3"); -#endif - - button = gtk_button_new_with_label ("Print Date"); - gtk_table_attach (GTK_TABLE (table), button, - 1, 2, 2, 3, 0, 0, 0, 0); - gtk_widget_show (button); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (on_get_date_clicked), dedit); - - button = gtk_button_new_with_label ("Toggle 24-hour"); - gtk_table_attach (GTK_TABLE (table), button, - 2, 3, 2, 3, 0, 0, 0, 0); - gtk_widget_show (button); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (on_toggle_24_hour_clicked), - dedit); - - gtk_widget_show (app); - - gtk_main (); - - return 0; -} - - -static void -delete_event_cb (GtkWidget *widget, - GdkEventAny *event, - GtkWidget *app) -{ - gtk_widget_destroy (app); - - gtk_main_quit (); -} - - -static void -on_get_date_clicked (GtkWidget *button, - EDateEdit *dedit) -{ - time_t t; - - t = e_date_edit_get_time (dedit); - if (t == -1) - g_print ("Time: None\n"); - else - g_print ("Time: %s", ctime (&t)); - - if (!e_date_edit_date_is_valid (dedit)) - g_print (" Date invalid\n"); - - if (!e_date_edit_time_is_valid (dedit)) - g_print (" Time invalid\n"); -} - - -static void -on_toggle_24_hour_clicked (GtkWidget *button, - EDateEdit *dedit) -{ - e_date_edit_set_use_24_hour_format (dedit, !e_date_edit_get_use_24_hour_format (dedit)); -} - - -#if 0 -static void -on_date_changed (EDateEdit *dedit, - gchar *name) -{ - gint year, month, day; - - if (e_date_edit_date_is_valid (dedit)) { - if (e_date_edit_get_date (dedit, &year, &month, &day)) { - g_print ("Date %s changed to: %i/%i/%i (M/D/Y)\n", - name, month, day, year); - } else { - g_print ("Date %s changed to: None\n", name); - } - } else { - g_print ("Date %s changed to: Not Valid\n", name); - } -} - - -static void -on_time_changed (EDateEdit *dedit, - gchar *name) -{ - gint hour, minute; - - if (e_date_edit_time_is_valid (dedit)) { - if (e_date_edit_get_time_of_day (dedit, &hour, &minute)) { - g_print ("Time %s changed to: %02i:%02i\n", name, - hour, minute); - } else { - g_print ("Time %s changed to: None\n", name); - } - } else { - g_print ("Time %s changed to: Not Valid\n", name); - } -} -#endif - - -static void -on_changed (EDateEdit *dedit, - gchar *name) -{ - gint year, month, day, hour, minute; - - g_print ("Date %s changed ", name); - - if (e_date_edit_date_is_valid (dedit)) { - if (e_date_edit_get_date (dedit, &year, &month, &day)) { - g_print ("M/D/Y: %i/%i/%i", month, day, year); - } else { - g_print ("None"); - } - } else { - g_print ("Date Invalid"); - } - - if (e_date_edit_time_is_valid (dedit)) { - if (e_date_edit_get_time_of_day (dedit, &hour, &minute)) { - g_print (" %02i:%02i\n", hour, minute); - } else { - g_print (" None\n"); - } - } else { - g_print (" Time Invalid\n"); - } -} - - diff --git a/widgets/misc/test-dropdown-button.c b/widgets/misc/test-dropdown-button.c deleted file mode 100644 index 259e344bcb..0000000000 --- a/widgets/misc/test-dropdown-button.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-dropdown-menu.c - * - * Copyright (C) 2001 Ximian, 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. - * - * Authors: - * Ettore Perazzoli <ettore@ximian.com> - * Damon Chaplin <damon@ximian.com> - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <glib.h> -#include <gtk/gtkmain.h> -#include <gtk/gtkmenu.h> -#include <gtk/gtkwindow.h> -#include <libgnomeui/gnome-app.h> -#include <libgnomeui/gnome-app-helper.h> -#include <libgnomeui/gnome-init.h> -#include <libgnomeui/gnome-stock.h> -#include "e-dropdown-button.h" - - -/* (The following is shameless stolen from `testgnome.c'. */ - -static void -item_activated (GtkWidget *widget, - void *data) -{ - printf ("%s activated.\n", (char *) data); -} - -static GnomeUIInfo ui_info[] = { - { GNOME_APP_UI_ITEM, "_New", "Create a new file", item_activated, "file/new", NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_NEW, 'n', GDK_CONTROL_MASK, NULL }, - { GNOME_APP_UI_ITEM, "_Open...", "Open an existing file", item_activated, "file/open", NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, 'o', GDK_CONTROL_MASK, NULL }, - { GNOME_APP_UI_ITEM, "_Save", "Save the current file", item_activated, "file/save", NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE, 's', GDK_CONTROL_MASK, NULL }, - { GNOME_APP_UI_ITEM, "Save _as...", "Save the current file with a new name", item_activated, "file/save as", NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE_AS, 0, 0, NULL }, - - GNOMEUIINFO_SEPARATOR, - - { GNOME_APP_UI_ITEM, "_Print...", "Print the current file", item_activated, "file/print", NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PRINT, 'p', GDK_CONTROL_MASK, NULL }, - - GNOMEUIINFO_SEPARATOR, - - { GNOME_APP_UI_ITEM, "_Close", "Close the current file", item_activated, "file/close", NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_CLOSE, 0, 0, NULL }, - { GNOME_APP_UI_ITEM, "E_xit", "Exit the program", item_activated, "file/exit", NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_EXIT, 'q', GDK_CONTROL_MASK, NULL }, - GNOMEUIINFO_END -}; - - -int -main (int argc, char **argv) -{ - GtkWidget *window; - GtkWidget *menu; - GtkWidget *dropdown_button; - - gnome_init ("test-dropdown-button", "0.0", argc, argv); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size (GTK_WINDOW (window), 1, 1); - - menu = gtk_menu_new (); - - gnome_app_fill_menu (GTK_MENU_SHELL (menu), ui_info, NULL, TRUE, 0); - - dropdown_button = e_dropdown_button_new ("Me_nu", GTK_MENU (menu)); - gtk_container_add (GTK_CONTAINER (window), dropdown_button); - - gtk_widget_show (window); - gtk_widget_show (dropdown_button); - - gtk_main (); - - return 0; -} diff --git a/widgets/misc/test-title-bar.c b/widgets/misc/test-title-bar.c deleted file mode 100644 index 2cbd392e49..0000000000 --- a/widgets/misc/test-title-bar.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-title-bar.c - * - * Copyright (C) 2000 Helix Code, 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: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtkbox.h> -#include <gtk/gtkmain.h> -#include <gtk/gtktext.h> -#include <gtk/gtkvbox.h> -#include <libgnomeui/gnome-app.h> -#include <libgnomeui/gnome-init.h> -#include "e-title-bar.h" - -static void -delete_event_cb (GtkWidget *widget, - GdkEventAny *event, - gpointer data) -{ - gtk_main_quit (); -} - -int -main (int argc, char **argv) -{ - GtkWidget *app; - GtkWidget *title_bar; - GtkWidget *text; - GtkWidget *vbox; - - gnome_init ("test-title-bar", "0.0", argc, argv); - - app = gnome_app_new ("Test", "Test"); - gtk_window_set_default_size (GTK_WINDOW (app), 400, 400); - gtk_window_set_policy (GTK_WINDOW (app), FALSE, TRUE, FALSE); - - gtk_signal_connect (GTK_OBJECT (app), "delete_event", GTK_SIGNAL_FUNC (delete_event_cb), NULL); - - title_bar = e_title_bar_new ("This is a very annoyingly long title bar"); - gtk_widget_show (title_bar); - - text = gtk_text_new (NULL, NULL); - gtk_widget_show (text); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), title_bar, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), text, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - gnome_app_set_contents (GNOME_APP (app), vbox); - gtk_widget_show (app); - - gtk_main (); - - return 0; -} diff --git a/widgets/table/e-table-example-1.c b/widgets/table/e-table-example-1.c deleted file mode 100644 index bac91c3060..0000000000 --- a/widgets/table/e-table-example-1.c +++ /dev/null @@ -1,286 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* This code is GPL. */ -#include <stdio.h> -#include <string.h> -#include <gdk-pixbuf/gdk-pixbuf.h> - -#include "gal/e-util/e-cursors.h" -#include "e-table-simple.h" -#include "e-table-header.h" -#include "e-table-header-item.h" -#include "e-table-item.h" -#include "e-cell-text.h" -#include "e-cell-checkbox.h" -#include "e-table.h" - -#include "table-test.h" - -/* - * One way in which we make it simpler to build an ETableModel is through - * the ETableSimple class. Instead of creating your own ETableModel - * class, you simply create a new object of the ETableSimple class. You - * give it a bunch of functions that act as callbacks. - * - * You also get to pass a void * to ETableSimple and it gets passed to - * your callbacks. This would be for having multiple models of the same - * type. This is just an example though, so we statically define all the - * data and ignore the void *data parameter. - * - * In our example we will be creating a table model with 6 columns and 10 - * rows. This corresponds to having 6 different types of information and - * 10 different sets of data in our database. - * - * The headers will be hard coded, as will be the example data. - * - */ - -/* - * There are two different meanings to the word "column". The first is - * the model column. A model column corresponds to a specific type of - * data. This is very much like the usage in a database table where a - * column is a field in the database. - * - * The second type of column is a view column. A view column - * corresponds to a visually displayed column. Each view column - * corresponds to a specific model column, though a model column may - * have any number of view columns associated with it, from zero to - * greater than one. - * - * Also, a view column doesn't necessarily depend on only one model - * column. In some cases, the view column renderer can be given a - * reference to another column to get extra information about its - * display. -*/ - -#define ROWS 10 -#define COLS 4 - -#define IMPORTANCE_COLUMN 4 -#define COLOR_COLUMN 5 - -/* - * Here we define the initial layout of the table. This is an xml - * format that allows you to change the initial ordering of the - * columns or to do sorting or grouping initially. This specification - * shows all 5 columns, but moves the importance column nearer to the - * front. It also sorts by the "Full Name" column (ascending.) - * Sorting and grouping take the model column as their arguments - * (sorting is specified by the "column" argument to the leaf elemnt. - */ - -#define INITIAL_SPEC "<ETableSpecification> \ - <columns-shown> \ - <column> 0 </column> \ - <column> 4 </column> \ - <column> 1 </column> \ - <column> 2 </column> \ - <column> 3 </column> \ - </columns-shown> \ - <grouping> <leaf column=\"1\" ascending=\"true\"/> </grouping> \ -</ETableSpecification>" - -char *headers [COLS] = { - "Email", - "Full Name", - "Address", - "Phone" -}; - -/* - * Virtual Column list: - * 0 Email - * 1 Full Name - * 2 Address - * 3 Phone - */ - -char *table_data [ROWS] [COLS]; - -/* - * ETableSimple callbacks - * These are the callbacks that define the behavior of our custom model. - */ - -/* - * Since our model is a constant size, we can just return its size in - * the column and row count fields. - */ - -/* This function returns the number of columns in our ETableModel. */ -static int -my_col_count (ETableModel *etc, void *data) -{ - return COLS; -} - -/* This function returns the number of rows in our ETableModel. */ -static int -my_row_count (ETableModel *etc, void *data) -{ - return ROWS; -} - -/* This function returns the value at a particular point in our ETableModel. */ -static void * -my_value_at (ETableModel *etc, int col, int row, void *data) -{ - return (void *) table_data [row] [col]; -} - -/* This function sets the value at a particular point in our ETableModel. */ -static void -my_set_value_at (ETableModel *etc, int col, int row, const void *val, void *data) -{ - g_free (table_data [row] [col]); - table_data [row] [col] = g_strdup (val); -} - -/* This function returns whether a particular cell is editable. */ -static gboolean -my_is_cell_editable (ETableModel *etc, int col, int row, void *data) -{ - return TRUE; -} - -/* This function duplicates the value passed to it. */ -static void * -my_duplicate_value (ETableModel *etc, int col, const void *value, void *data) -{ - return g_strdup (value); -} - -/* This function frees the value passed to it. */ -static void -my_free_value (ETableModel *etc, int col, void *value, void *data) -{ - g_free (value); -} - -/* This function creates an empty value. */ -static void * -my_initialize_value (ETableModel *etc, int col, void *data) -{ - return g_strdup (""); -} - -/* This function reports if a value is empty. */ -static gboolean -my_value_is_empty (ETableModel *etc, int col, const void *value, void *data) -{ - return !(value && *(char *)value); -} - -/* This function reports if a value is empty. */ -static char * -my_value_to_string (ETableModel *etc, int col, const void *value, void *data) -{ - return g_strdup(value); -} - -/* We create a window containing our new table. */ -static void -create_table (void) -{ - GtkWidget *e_table, *window, *frame; - ECell *cell_left_just; - ETableHeader *e_table_header; - int i, j; - ETableModel *e_table_model = NULL; - - /* First we fill in the simple data. */ - for (i = 0; i < ROWS; i++){ - for (j = 0; j < COLS; j++) - table_data [i] [j] = g_strdup (""); - } - /* Next we create our model. This uses the functions we defined - earlier. */ - e_table_model = e_table_simple_new ( - my_col_count, my_row_count, my_value_at, - my_set_value_at, my_is_cell_editable, - my_duplicate_value, my_free_value, - my_initialize_value, my_value_is_empty, - my_value_to_string, - NULL); - /* - * Next we create a header. The ETableHeader is used in two - * different way. The first is the full_header. This is the - * list of possible columns in the view. The second use is - * completely internal. Many of the ETableHeader functions are - * for that purpose. The only functions we really need are - * e_table_header_new and e_table_header_add_col. - * - * First we create the header. - */ - e_table_header = e_table_header_new (); - - /* - * Next we have to build renderers for all of the columns. - * Since all our columns are text columns, we can simply use - * the same renderer over and over again. If we had different - * types of columns, we could use a different renderer for - * each column. - */ - cell_left_just = e_cell_text_new (e_table_model, NULL, GTK_JUSTIFY_LEFT); - - /* - * Next we create a column object for each view column and add - * them to the header. We don't create a column object for - * the importance column since it will not be shown. - */ - for (i = 0; i < COLS; i++) { - /* Create the column. */ - ETableCol *ecol = e_table_col_new ( - i, headers [i], - 1.0, 20, cell_left_just, - g_str_compare, TRUE); - /* Add it to the header. */ - e_table_header_add_column (e_table_header, ecol, i); - } - - /* - * Here we create a window for our new table. This window - * will get shown and the person will be able to test their - * item. - */ - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - - /* This frame is simply to get a bevel around our table. */ - frame = gtk_frame_new (NULL); - - /* - * Here we create the table. We give it the three pieces of - * the table we've created, the header, the model, and the - * initial layout. It does the rest. - */ - e_table = e_table_new (e_table_header, e_table_model, INITIAL_SPEC); - - /* Build the gtk widget hierarchy. */ - gtk_container_add (GTK_CONTAINER (frame), e_table); - gtk_container_add (GTK_CONTAINER (window), frame); - - /* Size the initial window. */ - gtk_widget_set_usize (window, 200, 200); - - /* Show it all. */ - gtk_widget_show_all (window); -} - -/* This is the main function which just initializes gnome and call our create_table function */ - -int -main (int argc, char *argv []) -{ - gnome_init ("TableExample", "TableExample", argc, argv); - e_cursors_init (); - - gtk_widget_push_visual (gdk_rgb_get_visual ()); - gtk_widget_push_colormap (gdk_rgb_get_cmap ()); - - create_table (); - - gtk_main (); - - e_cursors_shutdown (); - return 0; -} - |