X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkprinteroptionwidget.c;h=44c54adf7c5f265fb7f8bc9abd4191847cecbd64;hb=HEAD;hp=fdc2e1dac55209389c771b80e717935acc2640c2;hpb=b16c97369910edbbed33f82f76fdb213fd08a8ea;p=~andy%2Fgtk diff --git a/gtk/gtkprinteroptionwidget.c b/gtk/gtkprinteroptionwidget.c index fdc2e1dac..44c54adf7 100644 --- a/gtk/gtkprinteroptionwidget.c +++ b/gtk/gtkprinteroptionwidget.c @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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. + * License along with this library. If not, see . */ #include "config.h" @@ -28,13 +26,13 @@ #include "gtkcelllayout.h" #include "gtkcellrenderertext.h" #include "gtkcombobox.h" -#include "gtkfilechooserbutton.h" +#include "gtkfilechooserdialog.h" #include "gtkimage.h" #include "gtklabel.h" #include "gtkliststore.h" #include "gtkradiobutton.h" #include "gtkstock.h" -#include "gtktable.h" +#include "gtkgrid.h" #include "gtktogglebutton.h" #include "gtkorientable.h" #include "gtkprivate.h" @@ -44,25 +42,37 @@ #define GTK_PRINTER_OPTION_WIDGET_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINTER_OPTION_WIDGET, GtkPrinterOptionWidgetPrivate)) +/* This defines the max file length that the file chooser + * button should display. The total length will be + * FILENAME_LENGTH_MAX+3 because the truncated name is prefixed + * with "...". + */ +#define FILENAME_LENGTH_MAX 27 + static void gtk_printer_option_widget_finalize (GObject *object); static void deconstruct_widgets (GtkPrinterOptionWidget *widget); -static void construct_widgets (GtkPrinterOptionWidget *widget); -static void update_widgets (GtkPrinterOptionWidget *widget); +static void construct_widgets (GtkPrinterOptionWidget *widget); +static void update_widgets (GtkPrinterOptionWidget *widget); + +static gchar *trim_long_filename (const gchar *filename); struct GtkPrinterOptionWidgetPrivate { GtkPrinterOption *source; gulong source_changed_handler; - + GtkWidget *check; GtkWidget *combo; GtkWidget *entry; GtkWidget *image; GtkWidget *label; GtkWidget *info_label; - GtkWidget *filechooser; GtkWidget *box; + GtkWidget *button; + + /* the last location for save to file, that the user selected */ + gchar *last_location; }; enum { @@ -88,7 +98,7 @@ static void gtk_printer_option_widget_get_property (GObject *object, GValue *value, GParamSpec *pspec); static gboolean gtk_printer_option_widget_mnemonic_activate (GtkWidget *widget, - gboolean group_cycling); + gboolean group_cycling); static void gtk_printer_option_widget_class_init (GtkPrinterOptionWidgetClass *class) @@ -203,6 +213,8 @@ gtk_printer_option_widget_mnemonic_activate (GtkWidget *widget, return gtk_widget_mnemonic_activate (priv->combo, group_cycling); if (priv->entry) return gtk_widget_mnemonic_activate (priv->entry, group_cycling); + if (priv->button) + return gtk_widget_mnemonic_activate (priv->button, group_cycling); return FALSE; } @@ -366,8 +378,8 @@ combo_box_set (GtkWidget *combo, gtk_tree_model_foreach (model, set_cb, &set_data); } -static char * -combo_box_get (GtkWidget *combo) +static gchar * +combo_box_get (GtkWidget *combo, gboolean *custom) { GtkTreeModel *model; gchar *value; @@ -377,7 +389,41 @@ combo_box_get (GtkWidget *combo) value = NULL; if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) - gtk_tree_model_get (model, &iter, VALUE_COLUMN, &value, -1); + { + gtk_tree_model_get (model, &iter, VALUE_COLUMN, &value, -1); + *custom = FALSE; + } + else + { + if (gtk_combo_box_get_has_entry (GTK_COMBO_BOX (combo))) + { + value = g_strdup (gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo))))); + *custom = TRUE; + } + + if (!value || !gtk_tree_model_get_iter_first (model, &iter)) + return value; + + /* If the user entered an item from the dropdown list manually, return + * the non-custom option instead. */ + do + { + gchar *val, *name; + gtk_tree_model_get (model, &iter, VALUE_COLUMN, &val, + NAME_COLUMN, &name, -1); + if (g_str_equal (value, name)) + { + *custom = FALSE; + g_free (name); + g_free (value); + return val; + } + + g_free (val); + g_free (name); + } + while (gtk_tree_model_iter_next (model, &iter)); + } return value; } @@ -406,14 +452,6 @@ deconstruct_widgets (GtkPrinterOptionWidget *widget) priv->entry = NULL; } - /* make sure entry and combo are destroyed first */ - /* as we use the two of them to create the filechooser */ - if (priv->filechooser) - { - gtk_widget_destroy (priv->filechooser); - priv->filechooser = NULL; - } - if (priv->image) { gtk_widget_destroy (priv->image); @@ -446,64 +484,100 @@ check_toggled_cb (GtkToggleButton *toggle_button, } static void -filesave_changed_cb (GtkWidget *button, - GtkPrinterOptionWidget *widget) +dialog_response_callback (GtkDialog *dialog, + gint response_id, + GtkPrinterOptionWidget *widget) { GtkPrinterOptionWidgetPrivate *priv = widget->priv; - gchar *uri, *file; - gchar *directory; + gchar *uri = NULL; + gchar *new_location = NULL; - file = g_filename_from_utf8 (gtk_entry_get_text (GTK_ENTRY (priv->entry)), - -1, NULL, NULL, NULL); - if (file == NULL) - return; + if (response_id == GTK_RESPONSE_ACCEPT) + { + gchar *filename; + gchar *filename_utf8; + gchar *filename_short; + + new_location = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog)); + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL); + filename_short = trim_long_filename (filename_utf8); + gtk_button_set_label (GTK_BUTTON (priv->button), filename_short); + g_free (filename_short); + g_free (filename_utf8); + g_free (filename); + } - /* combine the value of the chooser with the value of the entry */ - g_signal_handler_block (priv->source, priv->source_changed_handler); + gtk_widget_destroy (GTK_WIDGET (dialog)); - directory = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (priv->combo)); + if (new_location) + uri = new_location; + else + uri = priv->last_location; - if ((g_uri_parse_scheme (file) == NULL) && (directory != NULL)) + if (uri) { - if (g_path_is_absolute (file)) - uri = g_filename_to_uri (file, NULL, NULL); - else - { - gchar *path; + gtk_printer_option_set (priv->source, uri); + emit_changed (widget); + } -#ifdef G_OS_UNIX - if (file[0] == '~' && file[1] == '/') - { - path = g_build_filename (g_get_home_dir (), file + 2, NULL); - } - else -#endif - { - path = g_build_filename (directory, file, NULL); - } + g_free (new_location); + g_free (priv->last_location); + priv->last_location = NULL; - uri = g_filename_to_uri (path, NULL, NULL); + /* unblock the handler which was blocked in the filesave_choose_cb function */ + g_signal_handler_unblock (priv->source, priv->source_changed_handler); +} - g_free (path); - } - } - else +static void +filesave_choose_cb (GtkWidget *button, + GtkPrinterOptionWidget *widget) +{ + GtkPrinterOptionWidgetPrivate *priv = widget->priv; + gchar *last_location = NULL; + GtkWidget *dialog; + GtkWindow *toplevel; + + /* this will be unblocked in the dialog_response_callback function */ + g_signal_handler_block (priv->source, priv->source_changed_handler); + + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget))); + dialog = gtk_file_chooser_dialog_new (_("Select a filename"), + toplevel, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("_Select"), GTK_RESPONSE_ACCEPT, + NULL); + + /* The confirmation dialog will appear, when the user clicks print */ + gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), FALSE); + + /* select the current filename in the dialog */ + if (priv->source != NULL) { - if (g_uri_parse_scheme (file) != NULL) - uri = g_strdup (file); - else - uri = g_build_path ("/", gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (priv->combo)), file, NULL); + priv->last_location = last_location = g_strdup (priv->source->value); + if (last_location) + { + GFile *file; + gchar *basename; + gchar *basename_utf8; + + gtk_file_chooser_select_uri (GTK_FILE_CHOOSER (dialog), last_location); + file = g_file_new_for_uri (last_location); + basename = g_file_get_basename (file); + basename_utf8 = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL); + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), basename_utf8); + g_free (basename_utf8); + g_free (basename); + g_object_unref (file); + } } - - if (uri) - gtk_printer_option_set (priv->source, uri); - g_free (uri); - g_free (file); - g_free (directory); - - g_signal_handler_unblock (priv->source, priv->source_changed_handler); - emit_changed (widget); + g_signal_connect (dialog, "response", + G_CALLBACK (dialog_response_callback), widget); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + gtk_window_present (GTK_WINDOW (dialog)); } static gchar * @@ -558,25 +632,29 @@ combo_changed_cb (GtkWidget *combo, gchar *value; gchar *filtered_val = NULL; gboolean changed; + gboolean custom = TRUE; g_signal_handler_block (priv->source, priv->source_changed_handler); - value = combo_box_get (combo); + value = combo_box_get (combo, &custom); - /* handle some constraints */ - switch (priv->source->type) + /* Handle constraints if the user entered a custom value. */ + if (custom) { - case GTK_PRINTER_OPTION_TYPE_PICKONE_PASSCODE: - filtered_val = filter_numeric (value, FALSE, FALSE, &changed); - break; - case GTK_PRINTER_OPTION_TYPE_PICKONE_INT: - filtered_val = filter_numeric (value, TRUE, FALSE, &changed); - break; - case GTK_PRINTER_OPTION_TYPE_PICKONE_REAL: - filtered_val = filter_numeric (value, TRUE, TRUE, &changed); - break; - default: - break; + switch (priv->source->type) + { + case GTK_PRINTER_OPTION_TYPE_PICKONE_PASSCODE: + filtered_val = filter_numeric (value, FALSE, FALSE, &changed); + break; + case GTK_PRINTER_OPTION_TYPE_PICKONE_INT: + filtered_val = filter_numeric (value, TRUE, FALSE, &changed); + break; + case GTK_PRINTER_OPTION_TYPE_PICKONE_REAL: + filtered_val = filter_numeric (value, TRUE, TRUE, &changed); + break; + default: + break; + } } if (filtered_val) @@ -727,12 +805,11 @@ construct_widgets (GtkPrinterOptionWidget *widget) gtk_entry_set_visibility (entry, FALSE); } } - for (i = 0; i < source->num_choices; i++) - combo_box_append (priv->combo, - source->choices_display[i], - source->choices[i]); + combo_box_append (priv->combo, + source->choices_display[i], + source->choices[i]); gtk_widget_show (priv->combo); gtk_box_pack_start (GTK_BOX (widget), priv->combo, TRUE, TRUE, 0); g_signal_connect (priv->combo, "changed", G_CALLBACK (combo_changed_cb), widget); @@ -749,11 +826,16 @@ construct_widgets (GtkPrinterOptionWidget *widget) gtk_widget_show (priv->box); gtk_box_pack_start (GTK_BOX (widget), priv->box, TRUE, TRUE, 0); for (i = 0; i < source->num_choices; i++) - group = alternative_append (priv->box, - source->choices_display[i], - source->choices[i], - widget, - group); + { + group = alternative_append (priv->box, + source->choices_display[i], + source->choices[i], + widget, + group); + /* for mnemonic activation */ + if (i == 0) + priv->button = group->data; + } if (source->display_text) { @@ -780,55 +862,16 @@ construct_widgets (GtkPrinterOptionWidget *widget) break; case GTK_PRINTER_OPTION_TYPE_FILESAVE: - { - GtkWidget *label; - - priv->filechooser = gtk_table_new (2, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (priv->filechooser), 6); - gtk_table_set_col_spacings (GTK_TABLE (priv->filechooser), 12); - - /* TODO: make this a gtkfilechooserentry once we move to GTK */ - priv->entry = gtk_entry_new (); - priv->combo = gtk_file_chooser_button_new (_("Select a folder"), - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); - - g_object_set (priv->combo, "local-only", FALSE, NULL); - gtk_entry_set_activates_default (GTK_ENTRY (priv->entry), - gtk_printer_option_get_activates_default (source)); + priv->button = gtk_button_new (); + gtk_widget_show (priv->button); + gtk_box_pack_start (GTK_BOX (widget), priv->button, TRUE, TRUE, 0); + g_signal_connect (priv->button, "clicked", G_CALLBACK (filesave_choose_cb), widget); - label = gtk_label_new_with_mnemonic (_("_Name:")); - gtk_widget_set_halign (label, GTK_ALIGN_START); - gtk_widget_set_valign (label, GTK_ALIGN_CENTER); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->entry); - - gtk_table_attach (GTK_TABLE (priv->filechooser), label, - 0, 1, 0, 1, GTK_FILL, 0, - 0, 0); - - gtk_table_attach (GTK_TABLE (priv->filechooser), priv->entry, - 1, 2, 0, 1, GTK_FILL, 0, - 0, 0); - - label = gtk_label_new_with_mnemonic (_("_Save in folder:")); - gtk_widget_set_halign (label, GTK_ALIGN_START); - gtk_widget_set_valign (label, GTK_ALIGN_CENTER); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->combo); - - gtk_table_attach (GTK_TABLE (priv->filechooser), label, - 0, 1, 1, 2, GTK_FILL, 0, - 0, 0); - - gtk_table_attach (GTK_TABLE (priv->filechooser), priv->combo, - 1, 2, 1, 2, GTK_FILL, 0, - 0, 0); - - gtk_widget_show_all (priv->filechooser); - gtk_box_pack_start (GTK_BOX (widget), priv->filechooser, TRUE, TRUE, 0); - - g_signal_connect (priv->entry, "changed", G_CALLBACK (filesave_changed_cb), widget); + text = g_strdup_printf ("%s:", source->display_text); + priv->label = gtk_label_new_with_mnemonic (text); + g_free (text); + gtk_widget_show (priv->label); - g_signal_connect (priv->combo, "selection-changed", G_CALLBACK (filesave_changed_cb), widget); - } break; case GTK_PRINTER_OPTION_TYPE_INFO: @@ -852,6 +895,45 @@ construct_widgets (GtkPrinterOptionWidget *widget) gtk_box_pack_start (GTK_BOX (widget), priv->image, FALSE, FALSE, 0); } +/** + * If the filename exceeds FILENAME_LENGTH_MAX, then trim it and replace + * the first three letters with three dots. + */ +static gchar * +trim_long_filename (const gchar *filename) +{ + const gchar *home; + gint len, offset; + gchar *result; + + home = g_get_home_dir (); + if (g_str_has_prefix (filename, home)) + { + gchar *homeless_filename; + + offset = g_utf8_strlen (home, -1); + len = g_utf8_strlen (filename, -1); + homeless_filename = g_utf8_substring (filename, offset, len); + result = g_strconcat ("~", homeless_filename, NULL); + g_free (homeless_filename); + } + else + result = g_strdup (filename); + + len = g_utf8_strlen (result, -1); + if (len > FILENAME_LENGTH_MAX) + { + gchar *suffix; + + suffix = g_utf8_substring (result, len - FILENAME_LENGTH_MAX, len); + g_free (result); + result = g_strconcat ("...", suffix, NULL); + g_free (suffix); + } + + return result; +} + static void update_widgets (GtkPrinterOptionWidget *widget) { @@ -883,30 +965,46 @@ update_widgets (GtkPrinterOptionWidget *widget) case GTK_PRINTER_OPTION_TYPE_STRING: gtk_entry_set_text (GTK_ENTRY (priv->entry), source->value); break; + case GTK_PRINTER_OPTION_TYPE_PICKONE_PASSWORD: + case GTK_PRINTER_OPTION_TYPE_PICKONE_PASSCODE: + case GTK_PRINTER_OPTION_TYPE_PICKONE_REAL: + case GTK_PRINTER_OPTION_TYPE_PICKONE_INT: + case GTK_PRINTER_OPTION_TYPE_PICKONE_STRING: + { + GtkEntry *entry; + + entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (priv->combo))); + if (gtk_printer_option_has_choice (source, source->value)) + combo_box_set (priv->combo, source->value); + else + gtk_entry_set_text (entry, source->value); + + break; + } case GTK_PRINTER_OPTION_TYPE_FILESAVE: { - gchar *filename = g_filename_from_uri (source->value, NULL, NULL); + gchar *text; + gchar *filename; + + filename = g_filename_from_uri (source->value, NULL, NULL); if (filename != NULL) { - gchar *basename, *dirname, *text; + text = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL); + if (text != NULL) + { + gchar *short_filename; - basename = g_path_get_basename (filename); - dirname = g_path_get_dirname (filename); - text = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL); + short_filename = trim_long_filename (text); + gtk_button_set_label (GTK_BUTTON (priv->button), short_filename); + g_free (short_filename); + } - if (text != NULL) - gtk_entry_set_text (GTK_ENTRY (priv->entry), text); - if (g_path_is_absolute (dirname)) - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (priv->combo), - dirname); g_free (text); - g_free (basename); - g_free (dirname); g_free (filename); } - else - gtk_entry_set_text (GTK_ENTRY (priv->entry), source->value); - break; + else + gtk_button_set_label (GTK_BUTTON (priv->button), source->value); + break; } case GTK_PRINTER_OPTION_TYPE_INFO: gtk_label_set_text (GTK_LABEL (priv->info_label), source->value); @@ -940,6 +1038,6 @@ gtk_printer_option_widget_get_value (GtkPrinterOptionWidget *widget) if (priv->source) return priv->source->value; - + return ""; }