/* * 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 "add-preset-dialog.h" #include "layout-utils.h" #include /* for _() macro */ #include typedef struct { GtkWidget *name_entry; GtkWidget *duration_spin_hours; GtkWidget *duration_spin_minutes; GtkWidget *duration_spin_seconds; GtkWidget *ok_button; GtkTreeRowReference *editing_preset; /* original name of preset being edited */ gchar *orig_name; NameValidator name_is_valid; gpointer name_validator_data; PresetAddedCallback added_cb; gpointer added_cb_data; PresetEditedCallback edited_cb; gpointer edited_cb_data; } AddPresetDialogPrivate; static void handle_ok_clicked (GtkWidget *add_preset_dialog) { AddPresetDialogPrivate *priv_data; gchar *input_name; guint input_duration; gint hours, minutes, seconds; priv_data = g_object_get_data (G_OBJECT (add_preset_dialog), "private-data"); g_assert (priv_data); input_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv_data->name_entry))); /* Name should always be valid when "OK" is clicked because the button is only * sensitive when the field contains a valid name. * NOTE: Might still need to handle when user pastes text into field */ g_assert (priv_data->name_is_valid (input_name, priv_data->orig_name, priv_data->name_validator_data)); hours = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv_data->duration_spin_hours)); minutes = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv_data->duration_spin_minutes)); seconds = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv_data->duration_spin_seconds)); input_duration = (hours * 3600) + (minutes * 60) + seconds; if (priv_data->editing_preset) { if (priv_data->edited_cb) { priv_data->edited_cb (add_preset_dialog, priv_data->editing_preset, input_name, input_duration, priv_data->edited_cb_data); } } else { if (priv_data->added_cb) { priv_data->added_cb (add_preset_dialog, input_name, input_duration, priv_data->added_cb_data); } } gtk_widget_hide (add_preset_dialog); } static void handle_cancel_clicked (GtkWidget *add_preset_dialog) { g_assert (add_preset_dialog); gtk_widget_hide (add_preset_dialog); } static void on_dialog_response (GtkDialog *dialog, gint response, gpointer user_data) { switch (response) { case GTK_RESPONSE_OK: handle_ok_clicked (GTK_WIDGET (dialog)); break; case GTK_RESPONSE_CANCEL: handle_cancel_clicked (GTK_WIDGET (dialog)); break; } } static gboolean on_add_preset_dialog_delete (GtkWidget *dialog, GdkEvent *event, gpointer data) { gtk_widget_hide (dialog); return TRUE; } static void on_entry_changed (GtkEditable *editable, GtkWidget *add_preset_dialog) { AddPresetDialogPrivate *priv_data; const gchar *entry_text; int num_chars; priv_data = g_object_get_data (G_OBJECT (add_preset_dialog), "private-data"); g_assert (priv_data); g_assert (priv_data->name_is_valid); entry_text = gtk_entry_get_text (GTK_ENTRY (editable)); num_chars = strlen (entry_text); if (!priv_data->name_is_valid (entry_text, priv_data->orig_name, priv_data->name_validator_data)) { g_object_set (G_OBJECT (priv_data->ok_button), "sensitive", FALSE, NULL); } else { g_object_set (G_OBJECT (priv_data->ok_button), "sensitive", TRUE, NULL); } } GtkWidget * add_preset_dialog_new (NameValidator name_validator, gpointer user_data) { AddPresetDialogPrivate *priv_data; GtkWidget *main_vbox; GtkWidget *add_preset_dialog; priv_data = g_new0 (AddPresetDialogPrivate, 1); priv_data->name_is_valid = name_validator; priv_data->name_validator_data = user_data; add_preset_dialog = gtk_dialog_new_with_buttons ("", NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); g_object_set (G_OBJECT (add_preset_dialog), "has-separator", FALSE, "border-width", 0, NULL); { GtkWidget *ok_button; ok_button = gtk_dialog_add_button (GTK_DIALOG (add_preset_dialog), GTK_STOCK_OK, GTK_RESPONSE_OK); priv_data->ok_button = ok_button; } gtk_dialog_set_default_response (GTK_DIALOG (add_preset_dialog), GTK_RESPONSE_OK); gtk_widget_ensure_style (add_preset_dialog); main_vbox = gtk_vbox_new (FALSE, 18); g_object_set (G_OBJECT (main_vbox), "border-width", 12, NULL); gtk_widget_show (main_vbox); g_object_set (G_OBJECT (GTK_DIALOG (add_preset_dialog)->vbox), "border-width", 0, NULL); g_object_set (G_OBJECT (GTK_DIALOG (add_preset_dialog)->action_area), "border-width", 12, NULL); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (add_preset_dialog)->vbox), main_vbox, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (add_preset_dialog), "response", G_CALLBACK (on_dialog_response), NULL); g_signal_connect (G_OBJECT (add_preset_dialog), "delete-event", G_CALLBACK (on_add_preset_dialog_delete), NULL); g_object_set_data (G_OBJECT (add_preset_dialog), "private-data", priv_data); { GtkWidget *group_label; GtkWidget *name_group; GtkWidget *entry; group_label = gtk_label_new (_("_Name")); entry = gtk_entry_new (); g_object_set (G_OBJECT (group_label), "use-markup", TRUE, "use-underline", TRUE, "mnemonic-widget", entry, "xalign", 0.0, NULL); name_group = create_group_box (group_label); gtk_widget_show (group_label); group_box_add_row (name_group, entry); gtk_widget_show (entry); priv_data->name_entry = entry; gtk_box_pack_start (GTK_BOX (main_vbox), name_group, FALSE, FALSE, 0); gtk_widget_show (name_group); g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK (on_entry_changed), add_preset_dialog); } { GtkWidget *group_label; GtkWidget *duration_group; GtkWidget *duration_chooser; group_label = gtk_label_new (_("_Duration")); duration_chooser = create_duration_chooser (); priv_data->duration_spin_hours = duration_chooser_get_hours_spin (duration_chooser); priv_data->duration_spin_minutes = duration_chooser_get_minutes_spin (duration_chooser); priv_data->duration_spin_seconds = duration_chooser_get_seconds_spin (duration_chooser); g_object_set (G_OBJECT (group_label), "use-markup", TRUE, "use-underline", TRUE, "mnemonic-widget", priv_data->duration_spin_hours, "xalign", 0.0, NULL); duration_group = create_group_box (group_label); gtk_widget_show (group_label); group_box_add_row (duration_group, duration_chooser); gtk_widget_show (duration_chooser); gtk_box_pack_start (GTK_BOX (main_vbox), duration_group, FALSE, FALSE, 0); gtk_widget_show (duration_group); } priv_data->editing_preset = NULL; priv_data->orig_name = NULL; gtk_widget_show (main_vbox); return add_preset_dialog; } /* If editing a preset, preset_name should be equal to the currently-selected preset's name */ void add_preset_dialog_open (GtkWidget *add_preset_dialog, gchar *dialog_title, gchar *preset_name, guint preset_duration, GtkTreeRowReference *editing_preset) { GtkWidget *name_entry; GtkWidget *duration_spin_hours; GtkWidget *duration_spin_minutes; GtkWidget *duration_spin_seconds; GtkWidget *ok_button; AddPresetDialogPrivate *priv_data; priv_data = g_object_get_data (G_OBJECT (add_preset_dialog), "private-data"); g_assert (priv_data); name_entry = priv_data->name_entry; duration_spin_hours = priv_data->duration_spin_hours; duration_spin_minutes = priv_data->duration_spin_minutes; duration_spin_seconds = priv_data->duration_spin_seconds; ok_button = priv_data->ok_button; g_assert (name_entry); g_assert (duration_spin_hours); g_assert (duration_spin_minutes); g_assert (duration_spin_seconds); g_assert (ok_button); gtk_entry_set_text (GTK_ENTRY (name_entry), preset_name); g_object_set (G_OBJECT (name_entry), "has-focus", TRUE, NULL); { gint hours, minutes, seconds; hours = preset_duration / 3600; minutes = (preset_duration - (hours * 3600)) / 60; seconds = preset_duration - (hours * 3600) - (minutes * 60); gtk_spin_button_set_value (GTK_SPIN_BUTTON (duration_spin_hours), hours); gtk_spin_button_set_value (GTK_SPIN_BUTTON (duration_spin_minutes), minutes); gtk_spin_button_set_value (GTK_SPIN_BUTTON (duration_spin_seconds), seconds); } gtk_window_set_title (GTK_WINDOW (add_preset_dialog), dialog_title); if (priv_data->orig_name) { g_free (priv_data->orig_name); priv_data->orig_name = NULL; } priv_data->editing_preset = editing_preset; if (editing_preset) { priv_data->orig_name = g_strdup (preset_name); } /* priv_data->name_is_valid() will ignore priv_data->orig_name * if orig_name is NULL */ if (priv_data->name_is_valid (gtk_entry_get_text (GTK_ENTRY (name_entry)), priv_data->orig_name, priv_data->name_validator_data)) { g_object_set (G_OBJECT (ok_button), "sensitive", TRUE, NULL); } else { g_object_set (G_OBJECT (ok_button), "sensitive", FALSE, NULL); } gtk_widget_show (add_preset_dialog); } void add_preset_dialog_set_handlers (GtkWidget *add_preset_dialog, PresetAddedCallback added_cb, gpointer user_data1, PresetEditedCallback edited_cb, gpointer user_data2) { AddPresetDialogPrivate *priv_data; priv_data = g_object_get_data (G_OBJECT (add_preset_dialog), "private-data"); g_assert (priv_data); priv_data->added_cb = added_cb; priv_data->added_cb_data = user_data1; priv_data->edited_cb = edited_cb; priv_data->edited_cb_data = user_data2; }