/* * Copyright (C) 2004-2006 Jimmy Do * * 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 #endif #include "start-timer-dialog.h" #include #include #include "add-preset-dialog.h" #include "layout-utils.h" #include "presets-manager.h" typedef struct { guint duration; gchar *name; } StartTimerStoredInfo; static void dialog_set_duration (GtkWidget *start_timer_dialog, guint duration) { GtkWidget *spin_hours, *spin_minutes, *spin_seconds; guint num_hours, num_minutes, num_seconds; g_assert (start_timer_dialog); g_assert (duration >= 0); spin_hours = g_object_get_data (G_OBJECT (start_timer_dialog), "spin-hours"); spin_minutes = g_object_get_data (G_OBJECT (start_timer_dialog), "spin-minutes"); spin_seconds = g_object_get_data (G_OBJECT (start_timer_dialog), "spin-seconds"); num_hours = (guint)(duration / 3600); num_minutes = (guint)((duration - (num_hours * 3600)) / 60); num_seconds = (guint)(duration - (num_hours * 3600) - (num_minutes * 60)); g_assert (num_hours >= 0); g_assert (num_minutes >= 0); g_assert (num_seconds >= 0); g_assert (num_hours <= MAX_NUM_HOURS); g_assert (num_minutes <= 59); g_assert (num_seconds <= 59); gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_hours), num_hours); gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_minutes), num_minutes); gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_seconds), num_seconds); } static void dialog_set_name (GtkWidget *start_timer_dialog, const gchar *name) { GtkWidget *name_entry; g_assert (start_timer_dialog); g_assert (name); name_entry = g_object_get_data (G_OBJECT (start_timer_dialog), "name-entry"); g_assert (name_entry); gtk_entry_set_text (GTK_ENTRY (name_entry), name); } static void load_selected_preset (TimerApplet *timer_applet) { /* Update hours, minutes, and seconds spin buttons, * and update name entry. */ GtkTreeRowReference *selected_preset; gchar *name; guint duration; g_assert (timer_applet); g_assert (timer_applet->start_timer_dialog); g_assert (timer_applet->start_timer_presets_manager_widget); selected_preset = presets_manager_get_selected_preset (timer_applet->start_timer_presets_manager_widget); g_assert (selected_preset); gloo_presets_get_name_and_duration (timer_applet->gloo_presets, selected_preset, &name, &duration); dialog_set_duration (timer_applet->start_timer_dialog, duration); dialog_set_name (timer_applet->start_timer_dialog, name); g_free (name); name = NULL; } static void handle_ok_clicked (TimerApplet *timer_applet) { gchar *preset_name; guint timer_duration; g_assert (timer_applet); g_assert (timer_applet->start_timer_dialog); gtk_widget_hide (timer_applet->start_timer_dialog); preset_name = NULL; { GtkWidget *spin_hours, *spin_minutes, *spin_seconds; GtkWidget *name_entry; gint num_hours, num_minutes, num_seconds; GtkWidget *start_timer_dialog; start_timer_dialog = timer_applet->start_timer_dialog; spin_hours = g_object_get_data (G_OBJECT (start_timer_dialog), "spin-hours"); spin_minutes = g_object_get_data (G_OBJECT (start_timer_dialog), "spin-minutes"); spin_seconds = g_object_get_data (G_OBJECT (start_timer_dialog), "spin-seconds"); name_entry = g_object_get_data (G_OBJECT (start_timer_dialog), "name-entry"); g_assert (spin_hours); g_assert (spin_minutes); g_assert (spin_seconds); g_assert(name_entry); /* Make the spin buttons update/validate themselves before we try to fetch * their values. This is necessary when the user starts the timer by using * the "Start Timer" button's keyboard mnemonic (as opposed to clicking on * the button or pressing the Enter key) while currently inside a spin button. * Without this explicit update, the fetched value will not be the value * currently entered in the spin button if the user has just edited its value. */ gtk_spin_button_update (GTK_SPIN_BUTTON (spin_hours)); gtk_spin_button_update (GTK_SPIN_BUTTON (spin_minutes)); gtk_spin_button_update (GTK_SPIN_BUTTON (spin_seconds)); num_hours = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin_hours)); num_minutes = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin_minutes)); num_seconds = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin_seconds)); preset_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (name_entry))); g_assert (preset_name); timer_duration = num_hours * 3600 + num_minutes * 60 + num_seconds; /* Store the entered values so that we can default to them the next time * the user opens up this dialog box. This lets us return to these values * even if the user opens the dialog, enters new values, and then presses Cancel. */ { panel_applet_gconf_set_string (timer_applet->applet, "last_used_name", preset_name, NULL); panel_applet_gconf_set_int (timer_applet->applet, "last_used_duration", timer_duration, NULL); } } timer_applet_start_timer (timer_applet, preset_name, timer_duration); g_assert (preset_name); g_free (preset_name); preset_name = NULL; } static void handle_cancel_clicked (TimerApplet *timer_applet) { g_assert (timer_applet->start_timer_dialog); gtk_widget_hide (timer_applet->start_timer_dialog); } static void on_dialog_response (GtkDialog *dialog, gint response_id, TimerApplet *timer_applet) { switch (response_id) { case GTK_RESPONSE_OK: handle_ok_clicked (timer_applet); break; case GTK_RESPONSE_CANCEL: handle_cancel_clicked (timer_applet); break; } } static void on_load_preset_clicked (GtkWidget *button, TimerApplet *timer_applet) { g_assert (timer_applet); load_selected_preset (timer_applet); } static void on_selection_empty (GtkWidget *presets_manager) { GtkWidget *load_preset_button; load_preset_button = g_object_get_data (G_OBJECT (presets_manager), "load-preset-button"); g_object_set (G_OBJECT (load_preset_button), "sensitive", FALSE, NULL); } static void on_selection_not_empty (GtkWidget *presets_manager) { GtkWidget *load_preset_button; load_preset_button = g_object_get_data (G_OBJECT (presets_manager), "load-preset-button"); g_object_set (G_OBJECT (load_preset_button), "sensitive", TRUE, NULL); } static void on_preset_added (GtkWidget *presets_manager, gchar *preset_name, guint preset_duration, gpointer user_data) { TimerApplet *timer_applet; GtkTreeRowReference *new_row_ref; timer_applet = (TimerApplet *)user_data; g_assert (timer_applet != NULL); new_row_ref = gloo_presets_add_preset (timer_applet->gloo_presets, preset_name, (guint)preset_duration); presets_manager_select_row (presets_manager, new_row_ref); } static void on_preset_edited (GtkWidget *presets_manager, GtkTreeRowReference *row_ref, gchar *preset_name, guint preset_duration, gpointer user_data) { TimerApplet *timer_applet; timer_applet = (TimerApplet *)user_data; g_assert (timer_applet != NULL); gloo_presets_update_preset (timer_applet->gloo_presets, row_ref, preset_name, preset_duration); /* Cause update of spin buttons */ presets_manager_select_row (presets_manager, row_ref); } static void on_preset_deleted (GtkWidget *presets_manager, GtkTreeRowReference *row_ref, gpointer user_data) { TimerApplet *timer_applet; timer_applet = (TimerApplet *)user_data; g_assert (timer_applet != NULL); gloo_presets_remove_preset (timer_applet->gloo_presets, row_ref); } static void on_preset_activated (GtkTreeView *tree_view, GtkTreePath *tree_path, GtkTreeViewColumn *tree_col, TimerApplet *timer_applet) { load_selected_preset (timer_applet); } void start_timer_dialog_create (TimerApplet *timer_applet) { GtkWidget *dialog; GtkWidget *main_vbox; GtkWidget *ok_button; dialog = gtk_dialog_new_with_buttons (_("Start Timer"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("S_tart Timer"), GTK_RESPONSE_OK); g_object_set (G_OBJECT (dialog), "has-separator", FALSE, "border-width", 0, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); timer_applet->start_timer_dialog = dialog; gtk_widget_ensure_style (dialog); main_vbox = gtk_vbox_new (FALSE, 18); g_object_set (G_OBJECT (main_vbox), "border-width", 12, NULL); g_object_set (G_OBJECT (GTK_DIALOG (dialog)->vbox), "border-width", 0, NULL); g_object_set (G_OBJECT (GTK_DIALOG (dialog)->action_area), "border-width", 12, NULL); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_vbox, TRUE, TRUE, 0); /* Add section for manually-entering a countdown time */ { GtkWidget *input_widgets_vbox; GtkWidget *duration_chooser; GtkWidget *name_entry_row; input_widgets_vbox = gtk_vbox_new (FALSE, 12); duration_chooser = create_duration_chooser (); { GtkWidget *hours_spin; GtkWidget *minutes_spin; GtkWidget *seconds_spin; hours_spin = duration_chooser_get_hours_spin (duration_chooser); minutes_spin = duration_chooser_get_minutes_spin (duration_chooser); seconds_spin = duration_chooser_get_seconds_spin (duration_chooser); g_object_set_data (G_OBJECT (dialog), "spin-hours", hours_spin); g_object_set_data (G_OBJECT (dialog), "spin-minutes", minutes_spin); g_object_set_data (G_OBJECT (dialog), "spin-seconds", seconds_spin); } { GtkSizeGroup *size_group; GtkWidget *name_label; GtkWidget *name_entry; size_group = duration_chooser_get_labels_size_group (duration_chooser); name_label = gtk_label_new (_("_Name:")); name_entry = gtk_entry_new (); g_object_set_data (G_OBJECT (dialog), "name-entry", name_entry); g_object_set (G_OBJECT (name_label), "xalign", 0.0, "use-underline", TRUE, NULL); g_object_set (G_OBJECT (name_entry), "activates-default", TRUE, NULL); gtk_size_group_add_widget (size_group, name_label); name_entry_row = gtk_hbox_new (FALSE, 6); gtk_box_pack_start (GTK_BOX (name_entry_row), name_label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (name_entry_row), name_entry, TRUE, TRUE, 0); gtk_widget_show (name_label); gtk_widget_show (name_entry); } gtk_box_pack_start (GTK_BOX (input_widgets_vbox), duration_chooser, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (input_widgets_vbox), name_entry_row, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), input_widgets_vbox, FALSE, FALSE, 0); gtk_widget_show (name_entry_row); gtk_widget_show (duration_chooser); gtk_widget_show (input_widgets_vbox); } /* Add section for presets */ { GtkWidget *presets_label; GtkWidget *presets_group; GtkWidget *presets_manager_widget; GtkWidget *load_preset_button; presets_label = gtk_label_new (_("Presets")); g_object_set (G_OBJECT (presets_label), "use-markup", TRUE, "use-underline", TRUE, "xalign", 0.0, NULL); load_preset_button = gtk_button_new_with_mnemonic (_("_Load Selected Preset")); /* Desensitize button until a preset is selected */ g_object_set (G_OBJECT (load_preset_button), "sensitive", FALSE, NULL); g_signal_connect (G_OBJECT (load_preset_button), "clicked", G_CALLBACK (on_load_preset_clicked), timer_applet); presets_group = create_group_box (presets_label); presets_manager_widget = presets_manager_new (GTK_TREE_MODEL (timer_applet->gloo_presets)); timer_applet->start_timer_presets_manager_widget = presets_manager_widget; presets_manager_set_preset_handlers (presets_manager_widget, on_preset_added, timer_applet, on_preset_edited, timer_applet, on_preset_deleted, timer_applet); g_object_set_data (G_OBJECT (presets_manager_widget), "ok-button", ok_button); g_object_set_data (G_OBJECT (presets_manager_widget), "load-preset-button", load_preset_button); presets_manager_set_selection_change_handlers (presets_manager_widget, on_selection_empty, on_selection_not_empty); { GtkWidget *presets_manager_tree_view; presets_manager_tree_view = presets_manager_get_tree_view (presets_manager_widget); g_signal_connect (G_OBJECT (presets_manager_tree_view), "row-activated", G_CALLBACK (on_preset_activated), timer_applet); } g_assert (timer_applet->start_timer_presets_manager_widget); group_box_add_row_full (presets_group, presets_manager_widget, TRUE, TRUE); group_box_add_row (presets_group, load_preset_button); gtk_box_pack_start (GTK_BOX (main_vbox), presets_group, TRUE, TRUE, 0); gtk_widget_show (presets_label); gtk_widget_show (presets_manager_widget); gtk_widget_show (load_preset_button); gtk_widget_show (presets_group); } g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (on_dialog_response), timer_applet); g_signal_connect (G_OBJECT (dialog), "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL); gtk_widget_show (main_vbox); } void start_timer_dialog_open (TimerApplet *timer_applet) { gchar *timer_name; guint timer_duration; timer_name = panel_applet_gconf_get_string (timer_applet->applet, "last_used_name", NULL); timer_duration = panel_applet_gconf_get_int (timer_applet->applet, "last_used_duration", NULL); /* Schema should ensure that timer_name is not NULL, but we'll be nice and handle NULL anyway. */ if (timer_name == NULL) { timer_name = g_strdup (""); } start_timer_dialog_open_with_name_and_duration (timer_applet, timer_name, timer_duration); g_free (timer_name); timer_name = NULL; } void start_timer_dialog_open_with_name_and_duration (TimerApplet *timer_applet, const gchar *timer_name, guint timer_duration) { g_assert (timer_applet != NULL); g_assert (timer_name != NULL); g_assert (timer_duration >= 0); dialog_set_name (timer_applet->start_timer_dialog, timer_name); dialog_set_duration (timer_applet->start_timer_dialog, timer_duration); gtk_widget_show (timer_applet->start_timer_dialog); }