Files
evolution/calendar/main.c
Federico Mena Quintero ca082de77a Added get_uids() method to get a list of UIDs based on object types.
2000-02-08  Federico Mena Quintero  <federico@helixcode.com>

	* evolution-calendar.idl (Cal): Added get_uids() method to get a
	list of UIDs based on object types.

	* cal-backend.c (cal_backend_get_uids): Implemented get_uids() in
	the backend.

	* cal.c (Cal_get_uids): Implemented get_uids() method.

	* cal-client.c (cal_client_get_uids): Implemented client-side
	function.

	* cal-util.c (cal_obj_instance_list_free): Doh.  Free the list,
	not the last link.
	(cal_obj_uid_list_free): New function to free a list of UIDs.

	* GnomeCal.idl (Repository): Removed unused method
	get_object_by_id_list().  This is just for cleanup purposes and to
	remind me exactly of what needs to be moved over to
	evolution-calendar.idl.
	(Repository): Removed unused get_objects() method.

	* corba-cal.c (init_calendar_repo_class): Removed the unused
	get_objects method.

	* calobj.h (CalObjFindStatus): New status value enumeration for
	the find function.

	* calobj.c (ical_object_find_in_string): New function to parse a
	complete calendar and find a calendar object in it.  This should
	be used instead ical_object_new_from_string() in the future.

	* evolution-calendar.idl (CalObjInstance): Added an uid field.
	Now the idea is that whenever calendar object strings are passed
	around, their UIDs are passed along with them so that the actual
	object can be pulled from the whole VCAL object using its UID to
	identify it.

	* cal-util.h (CalObjInstance): Added uid field.

	* cal-util.c (cal_obj_instance_list_free): Free the UIDs.

	* cal-backend.c (build_event_list): Store the object's UID in the
	instance structure.

	* cal.c (Cal_get_events_in_range): Copy the UID field to the CORBA
	structure.

	* cal-client.c (cal_client_get_events_in_range): Copy the UID
	field from the CORBA structure.

	* main.c (gnome_cal_file_menu): Removed unfinished html-month stuff.

	* Makefile.am (gnomecal_SOURCES): Removed html-month.c.

	* gnome-cal.c: #include "alarm.h"
	(mail_notify): Made static.

	* alarm.h: #include "calobj.h"

	* corba-cal-factory.h (init_corba_server): Fixed prototype.

	* quick-view.c (create_items_for_event): Made static.

	* gncal-todo.c (column_resized): Made static.

	* layout.c (find_index): Made static.

svn path=/trunk/; revision=1699
2000-02-09 08:04:33 +00:00

1045 lines
26 KiB
C

/*
* Main file for the GNOME Calendar program
* Copyright (C) 1998 the Free Software Foundation
*
* Authors:
* Miguel de Icaza (miguel@kernel.org)
* Federico Mena (federico@nuclecu.unam.mx)
*/
#include <config.h>
#include <gnome.h>
#include <libgnorba/gnorba.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "calendar.h"
#include "alarm.h"
#include "eventedit.h"
#include "gnome-cal.h"
#include "main.h"
#include "timeutil.h"
#include "corba-cal-factory.h"
#define COOKIE_USER_HOME_DIR ((char *) -1)
/* The username, used to set the `owner' field of the event */
char *user_name;
/* The full user name from the Gecos field */
char *full_name;
/* The user's default calendar file */
char *user_calendar_file;
/* a gnome-config string prefix that can be used to access the calendar config info */
char *calendar_settings;
/* Day begin, day end parameters */
int day_begin, day_end;
/* Whether weeks starts on Sunday or Monday */
int week_starts_on_monday;
/* If true, do not show our top level window */
int startup_hidden = 0;
/* If true, enable debug output for alarms */
int debug_alarms = 0;
/* The array of color properties -- keep in sync with the enumeration defined in main.h. The color
* values specified here are the defaults for the program.
*/
struct color_prop color_props[] = {
{ 0x3e72, 0x35ec, 0x8ba2, N_("Outline:"), "/calendar/Colors/outline" },
{ 0xffff, 0xffff, 0xffff, N_("Headings:"), "/calendar/Colors/headings" },
{ 0xf26c, 0xecec, 0xbbe7, N_("Empty days:"), "/calendar/Colors/empty_bg" },
{ 0xfc1e, 0xf87f, 0x5f80, N_("Appointments:"), "/calendar/Colors/mark_bg" },
{ 0xd364, 0xc6b7, 0x7969, N_("Highlighted day:"), "/calendar/Colors/prelight_bg" },
{ 0x01f0, 0x01f0, 0x01f0, N_("Day numbers:"), "/calendar/Colors/day_fg" },
{ 0x0000, 0x0000, 0xffff, N_("Current day's number:"), "/calendar/Colors/current_fg" },
{ 0xbbbb, 0xbbbb, 0x0000, N_("To-Do item that is not yet due:"), "/calendar/Colors/todo_not_yet" },
{ 0xdddd, 0xbbbb, 0x0000, N_("To-Do item that is due today:"), "/calendar/Colors/todo_today" },
{ 0xbbbb, 0xdddd, 0x0000, N_("To-Do item that is overdue:"), "/calendar/Colors/todo_overdue" }
};
/* Number of active calendars */
int active_calendars = 0;
/* A list of all of the calendars started */
GList *all_calendars = NULL;
/* For dumping part of a calendar */
static time_t from_t, to_t;
/* File to load instead of the user default's file */
static char *load_file;
/* If set, show events for the specified date and quit */
static int show_events;
/* If set, show todo items quit */
static int show_todo;
/* If set, beep on display alarms */
gboolean beep_on_display = 0;
/* If true, timeout the beeper on audio alarms */
gboolean enable_aalarm_timeout = 0;
guint audio_alarm_timeout = 0;
const guint MAX_AALARM_TIMEOUT = 3600;
const guint MAX_SNOOZE_SECS = 3600;
gboolean enable_snooze = 0;
guint snooze_secs = 60;
/* Default values for alarms */
CalendarAlarm alarm_defaults[4] = {
{ ALARM_MAIL, 0, 15, ALARM_MINUTES },
{ ALARM_PROGRAM, 0, 15, ALARM_MINUTES },
{ ALARM_DISPLAY, 0, 15, ALARM_MINUTES },
{ ALARM_AUDIO, 0, 15, ALARM_MINUTES }
};
static void
init_username (void)
{
user_name = g_strdup(g_get_user_name());
full_name = g_strdup(g_get_real_name());
}
static int
range_check_hour (int hour)
{
if (hour < 0)
hour = 0;
else if (hour >= 24)
hour = 23;
return hour;
}
static void
init_default_alarms (void)
{
int i;
gboolean def;
alarm_defaults [ALARM_DISPLAY].type = ALARM_DISPLAY;
alarm_defaults [ALARM_AUDIO].type = ALARM_AUDIO;
alarm_defaults [ALARM_PROGRAM].type = ALARM_PROGRAM;
alarm_defaults [ALARM_MAIL].type = ALARM_MAIL;
for (i = 0; i < 4; i++) {
switch (alarm_defaults [i].type) {
case ALARM_DISPLAY:
gnome_config_push_prefix ("/calendar/alarms/def_disp_");
break;
case ALARM_AUDIO:
gnome_config_push_prefix ("/calendar/alarms/def_audio_");
break;
case ALARM_PROGRAM:
gnome_config_push_prefix ("/calendar/alarms/def_prog_");
break;
case ALARM_MAIL:
gnome_config_push_prefix ("/calendar/alarms/def_mail_");
break;
}
alarm_defaults[i].enabled = gnome_config_get_int ("enabled=0");
if (alarm_defaults[i].type != ALARM_MAIL) {
alarm_defaults[i].count = gnome_config_get_int ("count=15");
alarm_defaults[i].units = gnome_config_get_int ("units=0");
} else {
alarm_defaults[i].count = gnome_config_get_int ("count=1");
alarm_defaults[i].count = gnome_config_get_int ("count=2");
}
alarm_defaults[i].data = gnome_config_get_string_with_default ("data=",
&def);
if (def)
alarm_defaults[i].data = NULL;
gnome_config_pop_prefix ();
}
}
/*
* Initializes the calendar internal variables, loads defaults
*/
static void
init_calendar (void)
{
int i;
char *cspec, *color;
char *str;
init_username ();
user_calendar_file = g_concat_dir_and_file (gnome_util_user_home (), ".gnome/user-cal.vcf");
gnome_config_push_prefix (calendar_settings);
/* Read calendar settings */
day_begin = range_check_hour (gnome_config_get_int ("/calendar/Calendar/Day start=8"));
day_end = range_check_hour (gnome_config_get_int ("/calendar/Calendar/Day end=17"));
am_pm_flag = gnome_config_get_bool ("/calendar/Calendar/AM PM flag=0");
week_starts_on_monday = gnome_config_get_bool ("/calendar/Calendar/Week starts on Monday=0");
if (day_end < day_begin){
day_begin = 8;
day_end = 17;
}
/* Read color settings */
for (i = 0; i < COLOR_PROP_LAST; i++) {
cspec = build_color_spec (color_props[i].r, color_props[i].g, color_props[i].b);
str = g_strconcat (color_props[i].key, "=", cspec, NULL);
color = gnome_config_get_string (str);
parse_color_spec (color, &color_props[i].r, &color_props[i].g, &color_props[i].b);
g_free (str);
g_free (color);
}
/* read todolist settings */
todo_show_time_remaining = gnome_config_get_bool("/calendar/Todo/show_time_remain");
todo_show_due_date = gnome_config_get_bool("/calendar/Todo/show_due_date");
todo_item_dstatus_highlight_overdue = gnome_config_get_bool("/calendar/Todo/highlight_overdue");
todo_item_dstatus_highlight_due_today = gnome_config_get_bool("/calendar/Todo/highlight_due_today");
todo_item_dstatus_highlight_not_due_yet = gnome_config_get_bool("/calendar/Todo/highlight_not_due_yet");
todo_current_sort_column = gnome_config_get_int("/calendar/Todo/sort_column");
todo_current_sort_type = gnome_config_get_int("/calendar/Todo/sort_type");
todo_show_priority = gnome_config_get_bool("/calendar/Todo/show_priority");
/* read alarm settings */
beep_on_display = gnome_config_get_bool ("/calendar/alarms/beep_on_display=FALSE");
enable_aalarm_timeout = gnome_config_get_bool ("/calendar/alarms/enable_audio_timeout=FALSE");
audio_alarm_timeout = gnome_config_get_int ("/calendar/alarms/audio_alarm_timeout=60");
if (audio_alarm_timeout < 1)
audio_alarm_timeout = 1;
if (audio_alarm_timeout > MAX_AALARM_TIMEOUT)
audio_alarm_timeout = MAX_AALARM_TIMEOUT;
enable_snooze = gnome_config_get_bool ("/calendar/alarms/enable_snooze=FALSE");
snooze_secs = gnome_config_get_int ("/calendar/alarms/snooze_secs=300");
if (snooze_secs < 1)
snooze_secs = 1;
if (snooze_secs > MAX_SNOOZE_SECS)
snooze_secs = MAX_SNOOZE_SECS;
init_default_alarms ();
/* Done */
gnome_config_pop_prefix ();
}
static void save_calendar_cmd (GtkWidget *widget, void *data);
static void
about_calendar_cmd (GtkWidget *widget, void *data)
{
GtkWidget *about;
const gchar *authors[] = {
"Miguel de Icaza (miguel@kernel.org)",
"Federico Mena (federico@gimp.org)",
"Arturo Espinosa (arturo@nuclecu.unam.mx)",
"Russell Steinthal (rms39@columbia.edu)",
NULL
};
about = gnome_about_new (_("Gnome Calendar"), VERSION,
"(C) 1998 the Free Software Foundation",
authors,
_("The GNOME personal calendar and schedule manager."),
NULL);
gtk_window_set_modal (GTK_WINDOW (about), TRUE);
gnome_dialog_set_close (GNOME_DIALOG (about), TRUE);
gtk_widget_show (about);
}
static void
display_objedit (GtkWidget *widget, GnomeCalendar *gcal)
{
GtkWidget *ee;
iCalObject *ico;
/* Default to the day the user is looking at */
ico = ical_new ("", user_name, "");
ico->new = 1;
ico->dtstart = time_add_minutes (gcal->current_display, day_begin * 60);
ico->dtend = time_add_minutes (ico->dtstart, day_begin * 60 + 30 );
ee = event_editor_new (gcal, ico);
gtk_widget_show (ee);
}
static void
display_objedit_today (GtkWidget *widget, GnomeCalendar *gcal)
{
GtkWidget *ee;
ee = event_editor_new (gcal, NULL);
gtk_widget_show (ee);
}
GnomeCalendar *
gnome_calendar_locate (const char *pathname)
{
GList *l;
if (pathname == NULL || pathname [0] == 0)
pathname = user_calendar_file;
for (l = all_calendars; l; l = l->next){
GnomeCalendar *gcal = l->data;
if (strcmp (gcal->cal->filename, pathname) == 0){
return gcal;
}
}
return NULL;
}
static void
close_cmd (GtkWidget *widget, GnomeCalendar *gcal)
{
all_calendars = g_list_remove (all_calendars, gcal);
if (gcal->cal->modified){
if (!gcal->cal->filename)
save_calendar_cmd (widget, gcal);
else
calendar_save (gcal->cal, gcal->cal->filename);
}
gtk_widget_destroy (GTK_WIDGET (gcal));
active_calendars--;
if (active_calendars == 0){
unregister_calendar_services ();
gtk_main_quit ();
}
}
void
time_format_changed (void)
{
GList *l;
for (l = all_calendars; l; l = l->next)
gnome_calendar_time_format_changed (GNOME_CALENDAR (l->data));
}
void
colors_changed (void)
{
GList *l;
for (l = all_calendars; l; l = l->next)
gnome_calendar_colors_changed (GNOME_CALENDAR (l->data));
}
void
todo_properties_changed(void)
{
GList *l;
for (l = all_calendars; l; l = l->next)
gnome_calendar_todo_properties_changed (GNOME_CALENDAR (l->data));
}
static void
quit_cmd (void)
{
while (all_calendars){
GnomeCalendar *cal = GNOME_CALENDAR (all_calendars->data);
close_cmd (GTK_WIDGET (cal), cal);
}
}
/* Sets a clock cursor for the specified calendar window */
static void
set_clock_cursor (GnomeCalendar *gcal)
{
GdkCursor *cursor;
cursor = gdk_cursor_new (GDK_WATCH);
gdk_window_set_cursor (GTK_WIDGET (gcal)->window, cursor);
gdk_cursor_destroy (cursor);
gdk_flush ();
}
/* Resets the normal cursor for the specified calendar window */
static void
set_normal_cursor (GnomeCalendar *gcal)
{
gdk_window_set_cursor (GTK_WIDGET (gcal)->window, NULL);
gdk_flush ();
}
static void
previous_clicked (GtkWidget *widget, GnomeCalendar *gcal)
{
set_clock_cursor (gcal);
gnome_calendar_previous (gcal);
set_normal_cursor (gcal);
}
static void
next_clicked (GtkWidget *widget, GnomeCalendar *gcal)
{
set_clock_cursor (gcal);
gnome_calendar_next (gcal);
set_normal_cursor (gcal);
}
static void
today_clicked (GtkWidget *widget, GnomeCalendar *gcal)
{
set_clock_cursor (gcal);
gnome_calendar_goto_today (gcal);
set_normal_cursor (gcal);
}
static void
goto_clicked (GtkWidget *widget, GnomeCalendar *gcal)
{
goto_dialog (gcal);
}
static void
new_calendar_cmd (GtkWidget *widget, void *data)
{
new_calendar (full_name, NULL, NULL, NULL, FALSE);
}
static void
open_ok (GtkWidget *widget, GtkFileSelection *fs)
{
GtkWidget *error_dialog;
int ret;
if(!g_file_exists (gtk_file_selection_get_filename (fs))) {
error_dialog = gnome_message_box_new (
_("File not found"),
GNOME_MESSAGE_BOX_ERROR,
GNOME_STOCK_BUTTON_OK,
NULL);
gnome_dialog_set_parent (GNOME_DIALOG (error_dialog), GTK_WINDOW (fs));
ret = gnome_dialog_run (GNOME_DIALOG (error_dialog));
} else {
/* FIXME: find out who owns this calendar and use that name */
new_calendar ("Somebody", gtk_file_selection_get_filename (fs), NULL, NULL, FALSE);
gtk_widget_destroy (GTK_WIDGET (fs));
}
}
static void
open_calendar_cmd (GtkWidget *widget, void *data)
{
GtkFileSelection *fs;
fs = GTK_FILE_SELECTION (gtk_file_selection_new (_("Open calendar")));
gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked",
(GtkSignalFunc) open_ok,
fs);
gtk_signal_connect_object (GTK_OBJECT (fs->cancel_button), "clicked",
(GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT (fs));
gtk_widget_show (GTK_WIDGET (fs));
gtk_grab_add (GTK_WIDGET (fs)); /* Yes, it is modal, so sue me */
}
static void
save_ok (GtkWidget *widget, GtkFileSelection *fs)
{
GnomeCalendar *gcal;
gchar *fname;
gcal = GNOME_CALENDAR (gtk_object_get_user_data (GTK_OBJECT (fs)));
gtk_window_set_wmclass (GTK_WINDOW (gcal), "gnomecal", "gnomecal");
fname = g_strdup (gtk_file_selection_get_filename (fs));
calendar_save (gcal->cal, fname);
g_free(fname);
gtk_main_quit ();
}
static gint
close_save (GtkWidget *w)
{
gtk_main_quit ();
return TRUE;
}
static void
save_as_calendar_cmd (GtkWidget *widget, void *data)
{
GtkFileSelection *fs;
fs = GTK_FILE_SELECTION (gtk_file_selection_new (_("Save calendar")));
gtk_object_set_user_data (GTK_OBJECT (fs), data);
gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked",
(GtkSignalFunc) save_ok,
fs);
gtk_signal_connect_object (GTK_OBJECT (fs->cancel_button), "clicked",
(GtkSignalFunc) close_save,
GTK_OBJECT (fs));
gtk_signal_connect_object (GTK_OBJECT (fs), "delete_event",
GTK_SIGNAL_FUNC (close_save),
GTK_OBJECT (fs));
gtk_widget_show (GTK_WIDGET (fs));
gtk_grab_add (GTK_WIDGET (fs)); /* Yes, it is modal, so sue me even more */
gtk_main ();
gtk_widget_destroy (GTK_WIDGET (fs));
}
static void
properties_cmd (GtkWidget *widget, GtkWidget *gcal)
{
properties (gcal);
}
static void
save_calendar_cmd (GtkWidget *widget, void *data)
{
GnomeCalendar *gcal = data;
if (gcal->cal->filename){
struct stat s;
if (stat (gcal->cal->filename, &s) == -1){
if (errno == ENOENT)
calendar_save (gcal->cal, gcal->cal->filename);
return;
}
if (s.st_mtime != gcal->cal->file_time){
GtkWidget *box;
char *str;
int b;
str = g_strdup_printf (
_("File %s has changed since it was loaded\nContinue?"),
gcal->cal->filename);
box = gnome_message_box_new (str, GNOME_MESSAGE_BOX_INFO,
GNOME_STOCK_BUTTON_YES,
GNOME_STOCK_BUTTON_NO,
NULL);
g_free (str);
gnome_dialog_set_default (GNOME_DIALOG (box), 1);
b = gnome_dialog_run (GNOME_DIALOG (box));
if (b != 0)
return;
}
calendar_save (gcal->cal, gcal->cal->filename);
} else
save_as_calendar_cmd (widget, data);
}
/*
* Saves @gcal if it is the default calendar
*/
void
save_default_calendar (GnomeCalendar *gcal)
{
if (!gcal->cal->filename)
return;
save_calendar_cmd (NULL, gcal);
}
static GnomeUIInfo gnome_cal_file_menu [] = {
GNOMEUIINFO_MENU_NEW_ITEM(N_("_New calendar"),
N_("Create a new calendar"),
new_calendar_cmd, NULL),
GNOMEUIINFO_MENU_OPEN_ITEM(open_calendar_cmd, NULL),
GNOMEUIINFO_MENU_SAVE_ITEM(save_calendar_cmd, NULL),
GNOMEUIINFO_MENU_SAVE_AS_ITEM(save_as_calendar_cmd, NULL),
GNOMEUIINFO_SEPARATOR,
GNOMEUIINFO_MENU_CLOSE_ITEM(close_cmd, NULL),
GNOMEUIINFO_MENU_EXIT_ITEM(quit_cmd, NULL),
GNOMEUIINFO_END
};
static GnomeUIInfo gnome_cal_edit_menu [] = {
{ GNOME_APP_UI_ITEM, N_("_New appointment..."),
N_("Create a new appointment"), display_objedit, NULL, NULL,
GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_NEW, 0, 0, NULL },
{ GNOME_APP_UI_ITEM, N_("New appointment for _today..."),
N_("Create a new appointment for today"),
display_objedit_today, NULL, NULL,
GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_NEW, 0, 0, NULL },
GNOMEUIINFO_END
};
static GnomeUIInfo gnome_cal_help_menu [] = {
GNOMEUIINFO_HELP ("gnomecal"),
GNOMEUIINFO_MENU_ABOUT_ITEM(about_calendar_cmd, NULL),
GNOMEUIINFO_END
};
static GnomeUIInfo gnome_cal_settings_menu [] = {
GNOMEUIINFO_MENU_PREFERENCES_ITEM(properties_cmd, NULL),
GNOMEUIINFO_END
};
static GnomeUIInfo gnome_cal_menu [] = {
GNOMEUIINFO_MENU_FILE_TREE(gnome_cal_file_menu),
GNOMEUIINFO_MENU_EDIT_TREE(gnome_cal_edit_menu),
GNOMEUIINFO_MENU_SETTINGS_TREE(gnome_cal_settings_menu),
GNOMEUIINFO_MENU_HELP_TREE(gnome_cal_help_menu),
GNOMEUIINFO_END
};
static GnomeUIInfo gnome_toolbar [] = {
GNOMEUIINFO_ITEM_STOCK (N_("New"), N_("Create a new appointment"), display_objedit, GNOME_STOCK_PIXMAP_NEW),
GNOMEUIINFO_SEPARATOR,
GNOMEUIINFO_ITEM_STOCK (N_("Prev"), N_("Go back in time"), previous_clicked, GNOME_STOCK_PIXMAP_BACK),
GNOMEUIINFO_ITEM_STOCK (N_("Today"), N_("Go to present time"), today_clicked, GNOME_STOCK_PIXMAP_HOME),
GNOMEUIINFO_ITEM_STOCK (N_("Next"), N_("Go forward in time"), next_clicked, GNOME_STOCK_PIXMAP_FORWARD),
GNOMEUIINFO_SEPARATOR,
GNOMEUIINFO_ITEM_STOCK (N_("Go to"), N_("Go to a specific date"), goto_clicked, GNOME_STOCK_PIXMAP_JUMP_TO),
GNOMEUIINFO_END
};
static void
setup_menu (GtkWidget *gcal)
{
gnome_app_create_menus_with_data (GNOME_APP (gcal), gnome_cal_menu, gcal);
gnome_app_create_toolbar_with_data (GNOME_APP (gcal), gnome_toolbar, gcal);
gnome_app_install_menu_hints(GNOME_APP(gcal), gnome_cal_menu);
}
static void
setup_appbar (GtkWidget *gcal)
{
GtkWidget *appbar;
appbar = gnome_appbar_new (FALSE, TRUE, GNOME_PREFERENCES_USER);
gnome_app_set_statusbar (GNOME_APP (gcal), GTK_WIDGET (appbar));
}
static gint
calendar_close_event (GtkWidget *widget, GdkEvent *event, GnomeCalendar *gcal)
{
close_cmd (widget, gcal);
return TRUE;
}
GnomeCalendar *
new_calendar (char *full_name, char *calendar_file, char *geometry, char *page, gboolean hidden)
{
GtkWidget *toplevel;
char title[128];
int xpos, ypos, width, height;
/* i18n: This "%s%s" indicates possession. Languages where the order is
* the inverse should translate it to "%2$s%1$s".
*/
g_snprintf(title, 128, _("%s%s"), full_name, _("'s calendar"));
toplevel = gnome_calendar_new (title);
if (gnome_parse_geometry (geometry, &xpos, &ypos, &width, &height)){
if (xpos != -1)
gtk_widget_set_uposition (toplevel, xpos, ypos);
#if 0
if (width != -1)
gtk_widget_set_usize (toplevel, width, 600);
#endif
}
#if 0
gtk_widget_set_usize (toplevel, width, 600);
#endif
setup_appbar (toplevel);
setup_menu (toplevel);
if (page)
gnome_calendar_set_view (GNOME_CALENDAR (toplevel), page);
if (calendar_file && g_file_exists (calendar_file))
gnome_calendar_load (GNOME_CALENDAR (toplevel), calendar_file);
else
GNOME_CALENDAR (toplevel)->cal->filename = g_strdup (calendar_file);
gtk_signal_connect (GTK_OBJECT (toplevel), "delete_event",
GTK_SIGNAL_FUNC(calendar_close_event), toplevel);
active_calendars++;
all_calendars = g_list_prepend (all_calendars, toplevel);
if (hidden){
GnomeWinState state;
/* Realize the toplevel window to prevent a segfault */
gtk_widget_realize (toplevel);
state = gnome_win_hints_get_state (toplevel);
state |= WIN_STATE_MINIMIZED;
gnome_win_hints_set_state (toplevel, state);
}
gtk_widget_show (toplevel);
return GNOME_CALENDAR (toplevel);
}
static void
process_dates (void)
{
if (!from_t)
from_t = time_day_begin (time (NULL));
if (!to_t || to_t < from_t)
to_t = time_add_day (from_t, 1);
}
enum {
GEOMETRY_KEY = -1,
USERFILE_KEY = -2,
VIEW_KEY = -3,
HIDDEN_KEY = -4,
TODO_KEY = -5,
DEBUG_KEY = -6
};
/* Lists used to startup various GnomeCalendars */
static GList *start_calendars;
static GList *start_geometries;
static GList *start_views;
static int
same_day (struct tm *a, struct tm *b)
{
return (a->tm_mday == b->tm_mday &&
a->tm_mon == b->tm_mon &&
a->tm_year == b->tm_year);
}
static void
dump_events (void)
{
Calendar *cal;
GList *l;
char *s;
time_t now = time (NULL);
struct tm today = *localtime (&now);
process_dates ();
init_calendar ();
cal = calendar_new (full_name, CALENDAR_INIT_ALARMS);
s = calendar_load (cal, load_file ? load_file : user_calendar_file);
if (s){
printf ("error: %s\n", s);
exit (1);
}
l = calendar_get_events_in_range (cal, from_t, to_t);
for (; l; l = l->next){
char start [80], end [80];
CalendarObject *co = l->data;
struct tm ts, te;
char *format;
ts = *localtime (&co->ev_start);
te = *localtime (&co->ev_end);
if (same_day (&today, &ts))
format = N_("%H:%M");
else
format = N_("%A %b %d, %H:%M");
strftime (start, sizeof (start), _(format), &ts);
if (!same_day (&ts, &te))
format = N_("%A %b %d, %H:%M");
strftime (end, sizeof (start), _(format), &te);
printf ("%s -- %s\n", start, end);
printf (" %s\n", co->ico->summary);
}
calendar_destroy_event_list (l);
calendar_destroy (cal);
exit (0);
}
static void
dump_todo (void)
{
Calendar *cal;
GList *l;
char *s;
process_dates ();
init_calendar ();
cal = calendar_new (full_name, CALENDAR_INIT_ALARMS);
s = calendar_load (cal, load_file ? load_file : user_calendar_file);
if (s){
printf ("error: %s\n", s);
exit (1);
}
for (l = cal->todo; l; l = l->next){
iCalObject *object = l->data;
if (object->type != ICAL_TODO)
continue;
printf ("[%s]: %s\n", object->organizer, object->summary);
}
calendar_destroy (cal);
exit (0);
}
extern time_t get_date ();
static void
parse_an_arg (poptContext ctx,
enum poptCallbackReason reason,
const struct poptOption *opt,
char *arg, void *data)
{
switch (opt->val){
case 'f':
from_t = get_date (arg, NULL);
break;
case 't':
to_t = get_date (arg, NULL);
break;
case GEOMETRY_KEY:
start_geometries = g_list_append (start_geometries, arg);
break;
case USERFILE_KEY:
/* This is a special key that tells the program to load
* the user's calendar file. This allows session management
* to work even if the User's home directory changes location
* (ie, on a networked setup).
*/
arg = COOKIE_USER_HOME_DIR;
/* fall through */
break;
case VIEW_KEY:
start_views = g_list_append (start_views, arg);
break;
case 'F':
start_calendars = g_list_append (start_calendars, arg);
break;
case TODO_KEY:
show_todo = 1;
break;
case 'e':
show_events = 1;
break;
case HIDDEN_KEY:
startup_hidden = 1;
break;
case DEBUG_KEY:
if (!g_strcasecmp (arg, "alarms"))
debug_alarms = 1;
break;
default:
}
}
static const struct poptOption options [] = {
{ NULL, '\0', POPT_ARG_CALLBACK, parse_an_arg, 0, NULL, NULL },
{ "events", 'e', POPT_ARG_NONE, NULL, 'e', N_("Show events and quit"),
NULL },
{ "todo", 0, POPT_ARG_NONE, NULL, TODO_KEY, N_("Show TO-DO items and quit"),
NULL },
{ "from", 'f', POPT_ARG_STRING, NULL, 'f', N_("Specifies start date [for --events]"), N_("DATE") },
{ "file", 'F', POPT_ARG_STRING, NULL, 'F', N_("File to load calendar from"), N_("FILE") },
{ "userfile", '\0', POPT_ARG_NONE, NULL, USERFILE_KEY, N_("Load the user calendar"), NULL },
{ "geometry", '\0', POPT_ARG_STRING, NULL, GEOMETRY_KEY, N_("Geometry for starting up"), N_("GEOMETRY") },
{ "view", '\0', POPT_ARG_STRING, NULL, VIEW_KEY, N_("The startup view mode (dayview, weekview, monthview, yearview)"), N_("VIEW") },
{ "to", 't', POPT_ARG_STRING, NULL, 't', N_("Specifies ending date [for --events]"), N_("DATE") },
{ "hidden", 0, POPT_ARG_NONE, NULL, HIDDEN_KEY, N_("If used, starts in iconic mode"), NULL },
{ "debug", 'd', POPT_ARG_STRING, NULL, DEBUG_KEY, N_("Enable debugging output of TYPE (alarms)"), N_("TYPE") },
{ NULL, '\0', 0, NULL, 0}
};
static void
session_die (void)
{
quit_cmd ();
}
/*
* Save the session callback
*/
static int
session_save_state (GnomeClient *client, gint phase, GnomeRestartStyle save_style, gint shutdown,
GnomeInteractStyle interact_style, gint fast, gpointer client_data)
{
char *sess_id;
char **argv = (char **) g_malloc (sizeof (char *) * ((active_calendars * 6) + 3));
GList *l, *free_list = 0;
int i;
sess_id = gnome_client_get_id (client);
argv [0] = client_data;
for (i = 1, l = all_calendars; l; l = l->next){
GnomeCalendar *gcal = GNOME_CALENDAR (l->data);
char *geometry;
geometry = gnome_geometry_string (GTK_WIDGET (gcal)->window);
if (strcmp (gcal->cal->filename, user_calendar_file) == 0)
argv [i++] = "--userfile";
else {
argv [i++] = "--file";
argv [i++] = gcal->cal->filename;
}
argv [i++] = "--geometry";
argv [i++] = geometry;
argv [i++] = "--view";
argv [i++] = gnome_calendar_get_current_view_name (gcal);
free_list = g_list_append (free_list, geometry);
calendar_save (gcal->cal, gcal->cal->filename);
}
argv [i] = NULL;
gnome_client_set_clone_command (client, i, argv);
gnome_client_set_restart_command (client, i, argv);
for (l = free_list; l; l = l->next)
g_free (l->data);
g_list_free (free_list);
return 1;
}
int
main(int argc, char *argv[])
{
GnomeClient *client;
CORBA_Environment ev;
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
textdomain (PACKAGE);
CORBA_exception_init (&ev);
gnome_CORBA_init_with_popt_table (
"calendar", VERSION, &argc, argv,
options, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev);
orb = gnome_CORBA_ORB ();
poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references (orb, "RootPOA", &ev);
if (ev._major == CORBA_NO_EXCEPTION){
init_corba_server ();
}
if (show_events)
dump_events ();
if (show_todo)
dump_todo ();
client = gnome_master_client ();
if (client){
gtk_signal_connect (GTK_OBJECT (client), "save_yourself",
GTK_SIGNAL_FUNC (session_save_state), argv [0]);
gtk_signal_connect (GTK_OBJECT (client), "die",
GTK_SIGNAL_FUNC (session_die), NULL);
}
process_dates ();
alarm_init ();
init_calendar ();
/*
* Load all of the calendars specifies in the command line with
* the geometry specificied -if any-
*/
if (start_calendars){
GList *p, *g, *v;
char *title;
p = start_calendars;
g = start_geometries;
v = start_views;
while (p){
char *file = p->data;
char *geometry = g ? g->data : NULL;
char *page_name = v ? v->data : NULL;
if (file == COOKIE_USER_HOME_DIR)
file = user_calendar_file;
if (strcmp (file, user_calendar_file) == 0)
title = full_name;
else
title = file;
new_calendar (title, file, geometry, page_name, startup_hidden);
p = p->next;
if (g)
g = g->next;
if (v)
v = v->next;
}
g_list_free (p);
} else {
char *geometry = start_geometries ? start_geometries->data : NULL;
char *page_name = start_views ? start_views->data : NULL;
new_calendar (full_name, user_calendar_file, geometry, page_name, startup_hidden);
}
gtk_main ();
return 0;
}