/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* Evolution calendar - Commands for the calendar GUI control * * Copyright (C) 1998 The Free Software Foundation * Copyright (C) 2000 Ximian, Inc. * Copyright (C) 2000 Ximian, Inc. * * Authors: Miguel de Icaza * Federico Mena-Quintero * Seth Alves * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "shell/Evolution.h" #include "calendar-commands.h" #include "calendar-config.h" #include "gnome-cal.h" #include "goto.h" #include "print.h" #include "dialogs/cal-prefs-dialog.h" #include "itip-utils.h" #include "evolution-shell-component-utils.h" /* A list of all of the calendars started */ static GList *all_calendars = NULL; /* We have one global preferences dialog. */ static CalPrefsDialog *preferences_dialog = NULL; /* Callback for the new appointment command */ static void new_appointment_cb (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); gnome_calendar_new_appointment (gcal); } static void new_event_cb (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; time_t dtstart, dtend; gcal = GNOME_CALENDAR (data); gnome_calendar_get_current_time_range (gcal, &dtstart, &dtend); gnome_calendar_new_appointment_for (gcal, dtstart, dtend, TRUE); } /* Prints the calendar at its current view and time range */ static void print (GnomeCalendar *gcal, gboolean preview) { time_t start; GnomeCalendarViewType view_type; PrintView print_view; gnome_calendar_get_current_time_range (gcal, &start, NULL); view_type = gnome_calendar_get_view (gcal); switch (view_type) { case GNOME_CAL_DAY_VIEW: print_view = PRINT_VIEW_DAY; break; case GNOME_CAL_WORK_WEEK_VIEW: case GNOME_CAL_WEEK_VIEW: print_view = PRINT_VIEW_WEEK; break; case GNOME_CAL_MONTH_VIEW: print_view = PRINT_VIEW_MONTH; break; default: g_assert_not_reached (); return; } print_calendar (gcal, preview, start, print_view); } /* File/Print callback */ static void file_print_cb (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); print (gcal, FALSE); } static void file_print_preview_cb (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); print (gcal, TRUE); } /* This iterates over each calendar telling them to update their config settings. */ void update_all_config_settings (void) { GList *l; for (l = all_calendars; l; l = l->next) gnome_calendar_update_config_settings (GNOME_CALENDAR (l->data), FALSE); } /* 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 (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); set_clock_cursor (gcal); gnome_calendar_previous (gcal); set_normal_cursor (gcal); } static void next_clicked (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); set_clock_cursor (gcal); gnome_calendar_next (gcal); set_normal_cursor (gcal); } void calendar_goto_today (GnomeCalendar *gcal) { set_clock_cursor (gcal); gnome_calendar_goto_today (gcal); set_normal_cursor (gcal); } static void today_clicked (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); calendar_goto_today (gcal); } static void goto_clicked (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); goto_dialog (gcal); } static void show_day_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW, FALSE, TRUE); } static void show_work_week_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); gnome_calendar_set_view (gcal, GNOME_CAL_WORK_WEEK_VIEW, FALSE, TRUE); } static void show_week_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); gnome_calendar_set_view (gcal, GNOME_CAL_WEEK_VIEW, FALSE, TRUE); } static void show_month_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); gnome_calendar_set_view (gcal, GNOME_CAL_MONTH_VIEW, FALSE, TRUE); } static void new_calendar_cmd (BonoboUIComponent *uic, gpointer data, const char *path) { new_calendar (); } 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 */ #ifndef NO_WARNINGS #warning "FIXME: find out who owns this calendar and use that name" #endif /* new_calendar ("Somebody", gtk_file_selection_get_filename (fs)); */ gtk_widget_destroy (GTK_WIDGET (fs)); } } static void open_calendar_cmd (BonoboUIComponent *uic, gpointer data, const char *path) { 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)); g_free(fname); gtk_main_quit (); } static gint close_save (GtkWidget *w) { gtk_main_quit (); return TRUE; } static void save_as_calendar_cmd (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; GtkFileSelection *fs; gcal = GNOME_CALENDAR (data); fs = GTK_FILE_SELECTION (gtk_file_selection_new (_("Save calendar"))); gtk_object_set_user_data (GTK_OBJECT (fs), gcal); 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 preferences_cmd (BonoboUIComponent *uic, gpointer data, const char *path) { if (!preferences_dialog) preferences_dialog = cal_prefs_dialog_new (); else cal_prefs_dialog_show (preferences_dialog); } static void cut_event_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); set_clock_cursor (gcal); gnome_calendar_cut_clipboard (gcal); set_normal_cursor (gcal); } static void copy_event_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); set_clock_cursor (gcal); gnome_calendar_copy_clipboard (gcal); set_normal_cursor (gcal); } static void paste_event_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) { GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); set_clock_cursor (gcal); gnome_calendar_paste_clipboard (gcal); set_normal_cursor (gcal); } static void publish_freebusy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) { GnomeCalendar *gcal; CalClient *client; CalClientGetStatus status; CalComponent *comp; time_t start, end; gcal = GNOME_CALENDAR (data); gnome_calendar_get_current_time_range (gcal, &start, &end); client = gnome_calendar_get_cal_client (gcal); status = cal_client_get_free_busy (client, start, end, &comp); if (status == CAL_CLIENT_GET_SUCCESS) itip_send_comp (CAL_COMPONENT_METHOD_PUBLISH, comp); } /* Does a queryInterface on the control's parent control frame for the ShellView interface */ static GNOME_Evolution_ShellView get_shell_view_interface (BonoboControl *control) { Bonobo_ControlFrame control_frame; GNOME_Evolution_ShellView shell_view; CORBA_Environment ev; control_frame = bonobo_control_get_control_frame (control); g_assert (control_frame != CORBA_OBJECT_NIL); CORBA_exception_init (&ev); shell_view = Bonobo_Unknown_queryInterface (control_frame, "IDL:GNOME/Evolution/ShellView:1.0", &ev); if (ev._major != CORBA_NO_EXCEPTION) { g_message ("get_shell_view_interface(): " "Could not queryInterface() on the control frame"); shell_view = CORBA_OBJECT_NIL; goto out; } CORBA_exception_free (&ev); out: return shell_view; } /* Clears the folder bar label on the shell view */ static void clear_folder_bar_label (BonoboControl *control) { GNOME_Evolution_ShellView shell_view; CORBA_Environment ev; shell_view = get_shell_view_interface (control); if (shell_view == CORBA_OBJECT_NIL) return; CORBA_exception_init (&ev); GNOME_Evolution_ShellView_setFolderBarLabel (shell_view, "", &ev); if (ev._major != CORBA_NO_EXCEPTION) g_message ("clear_folder_bar_label(): Could not set the folder bar label"); CORBA_exception_free (&ev); } static BonoboUIVerb verbs [] = { BONOBO_UI_VERB ("CalendarNew", new_calendar_cmd), BONOBO_UI_VERB ("CalendarOpen", open_calendar_cmd), BONOBO_UI_VERB ("CalendarSaveAs", save_as_calendar_cmd), BONOBO_UI_VERB ("CalendarPrint", file_print_cb), BONOBO_UI_VERB ("CalendarPrintPreview", file_print_preview_cb), BONOBO_UI_VERB ("EditNewAppointment", new_appointment_cb), BONOBO_UI_VERB ("EditNewEvent", new_event_cb), BONOBO_UI_VERB ("CalendarPreferences", preferences_cmd), BONOBO_UI_VERB ("CutEvent", cut_event_cmd), BONOBO_UI_VERB ("CopyEvent", copy_event_cmd), BONOBO_UI_VERB ("PasteEvent", paste_event_cmd), BONOBO_UI_VERB ("PublishFreeBusy", publish_freebusy_cmd), BONOBO_UI_VERB ("CalendarPrev", previous_clicked), BONOBO_UI_VERB ("CalendarToday", today_clicked), BONOBO_UI_VERB ("CalendarNext", next_clicked), BONOBO_UI_VERB ("CalendarGoto", goto_clicked), BONOBO_UI_VERB ("ShowDayView", show_day_view_clicked), BONOBO_UI_VERB ("ShowWorkWeekView", show_work_week_view_clicked), BONOBO_UI_VERB ("ShowWeekView", show_week_view_clicked), BONOBO_UI_VERB ("ShowMonthView", show_month_view_clicked), BONOBO_UI_VERB_END }; static EPixmap pixmaps [] = { E_PIXMAP ("/menu/File/New/NewFirstItem/CalendarNew", "new_appointment.xpm"), E_PIXMAP ("/menu/File/Print/Print", "print.xpm"), E_PIXMAP ("/menu/File/Print/Print Preview", "print-preview.xpm"), E_PIXMAP ("/menu/Actions/Component/CalendarNew", "new_appointment.xpm"), E_PIXMAP ("/menu/Tools/Component/CalendarPreferences", "configure_16_calendar.xpm"), E_PIXMAP ("/Toolbar/New", "buttons/new_appointment.png"), E_PIXMAP ("/Toolbar/DayView", "buttons/dayview.xpm"), E_PIXMAP ("/Toolbar/WorkWeekView", "buttons/workweekview.xpm"), E_PIXMAP ("/Toolbar/WeekView", "buttons/weekview.xpm"), E_PIXMAP ("/Toolbar/MonthView", "buttons/monthview.xpm"), E_PIXMAP_END }; void calendar_control_activate (BonoboControl *control, GnomeCalendar *gcal) { Bonobo_UIContainer remote_uih; BonoboUIComponent *uic; uic = bonobo_control_get_ui_component (control); g_assert (uic != NULL); remote_uih = bonobo_control_get_remote_ui_container (control); bonobo_ui_component_set_container (uic, remote_uih); bonobo_object_release_unref (remote_uih, NULL); #if 0 /* FIXME: Need to update this to use new Bonobo ui stuff somehow. Also need radio buttons really. */ /* Note that these indices should correspond with the button indices in the gnome_toolbar_view_buttons UIINFO struct. */ gnome_calendar_set_view_buttons (cal, gnome_toolbar_view_buttons[0].widget, gnome_toolbar_view_buttons[1].widget, gnome_toolbar_view_buttons[2].widget, gnome_toolbar_view_buttons[3].widget); /* This makes the appropriate radio button in the toolbar active. */ gnome_calendar_update_view_buttons (cal); #endif bonobo_ui_component_add_verb_list_with_data (uic, verbs, gcal); bonobo_ui_component_freeze (uic, NULL); bonobo_ui_util_set_ui (uic, EVOLUTION_DATADIR, "evolution-calendar.xml", "evolution-calendar"); e_pixmaps_update (uic, pixmaps); gnome_calendar_setup_view_menus (gcal, uic); bonobo_ui_component_thaw (uic, NULL); /* Show the dialog for setting the timezone if the user hasn't chosen a default timezone already. */ calendar_config_check_timezone_set (); clear_folder_bar_label (control); } void calendar_control_deactivate (BonoboControl *control, GnomeCalendar *gcal) { BonoboUIComponent *uic = bonobo_control_get_ui_component (control); g_assert (uic != NULL); gnome_calendar_discard_view_menus (gcal); bonobo_ui_component_rm (uic, "/", NULL); bonobo_ui_component_unset_container (uic); } /* Removes a calendar from our list of all calendars when it is destroyed. */ static void on_calendar_destroyed (GnomeCalendar *gcal) { all_calendars = g_list_remove (all_calendars, gcal); } GnomeCalendar * new_calendar (void) { GtkWidget *gcal; gcal = gnome_calendar_new (); if (!gcal) { gnome_warning_dialog (_("Could not create the calendar view. Please check your " "ORBit and OAF setup.")); return NULL; } gtk_signal_connect (GTK_OBJECT (gcal), "destroy", GTK_SIGNAL_FUNC (on_calendar_destroyed), NULL); all_calendars = g_list_prepend (all_calendars, gcal); return GNOME_CALENDAR (gcal); }