diff options
-rw-r--r-- | gtk/Makefile.am | 1 | ||||
-rw-r--r-- | gtk/gtk.gresource.xml | 1 | ||||
-rw-r--r-- | gtk/gtkfilechooserbutton.c | 105 | ||||
-rw-r--r-- | gtk/gtkfilechooserbutton.ui | 120 | ||||
-rw-r--r-- | gtk/tests/templates.c | 16 |
5 files changed, 165 insertions, 78 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am index dd34bb9be2..dc4f8a0281 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -1103,6 +1103,7 @@ COMPOSITE_TEMPLATES = \ gtkcolorchooserdialog.ui \ gtkcoloreditor.ui \ gtkdialog.ui \ + gtkfilechooserbutton.ui \ gtkfilechooserdefault.ui \ gtkfilechooserdialog.ui \ gtkfontchooserdialog.ui \ diff --git a/gtk/gtk.gresource.xml b/gtk/gtk.gresource.xml index 0e40d07b0a..bdc844a8d9 100644 --- a/gtk/gtk.gresource.xml +++ b/gtk/gtk.gresource.xml @@ -18,6 +18,7 @@ <file compressed="true">gtkcolorchooserdialog.ui</file> <file compressed="true">gtkcoloreditor.ui</file> <file compressed="true">gtkdialog.ui</file> + <file compressed="true">gtkfilechooserbutton.ui</file> <file compressed="true">gtkfilechooserdefault.ui</file> <file compressed="true">gtkfilechooserdialog.ui</file> <file compressed="true">gtkfontchooserdialog.ui</file> diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c index a2c37c87cc..86403d650c 100644 --- a/gtk/gtkfilechooserbutton.c +++ b/gtk/gtkfilechooserbutton.c @@ -130,7 +130,10 @@ enum LAST_SIGNAL }; -/* TreeModel Columns */ +/* TreeModel Columns + * + * keep in line with the store defined in gtkfilechooserbutton.ui + */ enum { ICON_COLUMN, @@ -182,7 +185,6 @@ struct _GtkFileChooserButtonPrivate GFile *selection_while_inactive; GFile *current_folder_while_inactive; - gulong combo_box_changed_id; gulong fs_volumes_changed_id; gulong fs_bookmarks_changed_id; @@ -465,6 +467,23 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class) _gtk_file_chooser_install_properties (gobject_class); + /* Bind class to template + */ + gtk_widget_class_set_template_from_resource (widget_class, + "/org/gtk/libgtk/gtkfilechooserbutton.ui"); + + gtk_widget_class_bind_child (widget_class, GtkFileChooserButtonPrivate, model); + gtk_widget_class_bind_child (widget_class, GtkFileChooserButtonPrivate, button); + gtk_widget_class_bind_child (widget_class, GtkFileChooserButtonPrivate, image); + gtk_widget_class_bind_child (widget_class, GtkFileChooserButtonPrivate, label); + gtk_widget_class_bind_child (widget_class, GtkFileChooserButtonPrivate, combo_box); + gtk_widget_class_bind_child (widget_class, GtkFileChooserButtonPrivate, icon_cell); + gtk_widget_class_bind_child (widget_class, GtkFileChooserButtonPrivate, name_cell); + + gtk_widget_class_bind_callback (widget_class, button_clicked_cb); + gtk_widget_class_bind_callback (widget_class, combo_box_changed_cb); + gtk_widget_class_bind_callback (widget_class, combo_box_notify_popup_shown_cb); + g_type_class_add_private (class, sizeof (GtkFileChooserButtonPrivate)); } @@ -472,7 +491,6 @@ static void gtk_file_chooser_button_init (GtkFileChooserButton *button) { GtkFileChooserButtonPrivate *priv; - GtkWidget *box, *image, *sep; GtkTargetList *target_list; priv = button->priv = G_TYPE_INSTANCE_GET_PRIVATE (button, @@ -482,70 +500,8 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button) priv->icon_size = FALLBACK_ICON_SIZE; priv->focus_on_click = TRUE; - /* Button */ - priv->button = gtk_button_new (); - g_signal_connect (priv->button, "clicked", - G_CALLBACK (button_clicked_cb), button); - gtk_box_pack_start (GTK_BOX (button), priv->button, TRUE, TRUE, 0); - gtk_widget_set_halign (priv->button, GTK_ALIGN_FILL); - gtk_widget_show (priv->button); - - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); - gtk_container_add (GTK_CONTAINER (priv->button), box); - gtk_widget_show (box); - - priv->image = gtk_image_new (); - gtk_box_pack_start (GTK_BOX (box), priv->image, FALSE, FALSE, 0); - gtk_widget_show (priv->image); - - priv->label = gtk_label_new (_(FALLBACK_DISPLAY_NAME)); - gtk_label_set_ellipsize (GTK_LABEL (priv->label), PANGO_ELLIPSIZE_END); - gtk_widget_set_halign (priv->label, GTK_ALIGN_START); - gtk_widget_set_valign (priv->label, GTK_ALIGN_CENTER); - gtk_box_pack_start (GTK_BOX (box), priv->label, TRUE, TRUE, 0); - //gtk_container_add (GTK_CONTAINER (box), priv->label); - gtk_widget_show (priv->label); - - sep = gtk_separator_new (GTK_ORIENTATION_VERTICAL); - gtk_box_pack_start (GTK_BOX (box), sep, FALSE, FALSE, 0); - gtk_widget_show (sep); - - image = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU); - gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0); - gtk_widget_show (image); - - /* Combo Box */ - /* Keep in sync with columns enum, line 88 */ - priv->model = - GTK_TREE_MODEL (gtk_list_store_new (NUM_COLUMNS, - GDK_TYPE_PIXBUF, /* ICON_COLUMN */ - G_TYPE_STRING, /* DISPLAY_NAME_COLUMN */ - G_TYPE_CHAR, /* TYPE_COLUMN */ - G_TYPE_POINTER /* DATA_COLUMN (Volume || Path) */, - G_TYPE_BOOLEAN /* IS_FOLDER_COLUMN */, - G_TYPE_POINTER /* CANCELLABLE_COLUMN */)); - - priv->combo_box = gtk_combo_box_new (); - priv->combo_box_changed_id = g_signal_connect (priv->combo_box, "changed", - G_CALLBACK (combo_box_changed_cb), button); - - g_signal_connect (priv->combo_box, "notify::popup-shown", - G_CALLBACK (combo_box_notify_popup_shown_cb), button); - - gtk_box_pack_start (GTK_BOX (button), priv->combo_box, TRUE, TRUE, 0); - gtk_widget_set_halign (priv->combo_box, GTK_ALIGN_FILL); - - priv->icon_cell = gtk_cell_renderer_pixbuf_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->combo_box), - priv->icon_cell, FALSE); - gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (priv->combo_box), - priv->icon_cell, "pixbuf", ICON_COLUMN); - - priv->name_cell = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->combo_box), - priv->name_cell, TRUE); - gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (priv->combo_box), - priv->name_cell, "text", DISPLAY_NAME_COLUMN); + gtk_widget_init_template (GTK_WIDGET (button)); + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (priv->combo_box), priv->name_cell, name_cell_data_func, NULL, NULL); @@ -1124,12 +1080,6 @@ gtk_file_chooser_button_destroy (GtkWidget *widget) priv->change_icon_theme_cancellables = NULL; } - if (priv->model) - { - g_object_unref (priv->model); - priv->model = NULL; - } - if (priv->filter_model) { g_object_unref (priv->filter_model); @@ -2398,9 +2348,9 @@ select_combo_box_row_no_notify (GtkFileChooserButton *button, int pos) gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (priv->filter_model), &filter_iter, &iter); - g_signal_handler_block (priv->combo_box, priv->combo_box_changed_id); + g_signal_handlers_block_by_func (priv->combo_box, combo_box_changed_cb, button); gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->combo_box), &filter_iter); - g_signal_handler_unblock (priv->combo_box, priv->combo_box_changed_id); + g_signal_handlers_unblock_by_func (priv->combo_box, combo_box_changed_cb, button); } static void @@ -2457,11 +2407,10 @@ update_combo_box (GtkFileChooserButton *button) if (row_found) { - g_signal_handler_block (priv->combo_box, priv->combo_box_changed_id); + g_signal_handlers_block_by_func (priv->combo_box, combo_box_changed_cb, button); gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->combo_box), &iter); - g_signal_handler_unblock (priv->combo_box, - priv->combo_box_changed_id); + g_signal_handlers_unblock_by_func (priv->combo_box, combo_box_changed_cb, button); } } while (!row_found && gtk_tree_model_iter_next (priv->filter_model, &iter)); diff --git a/gtk/gtkfilechooserbutton.ui b/gtk/gtkfilechooserbutton.ui new file mode 100644 index 0000000000..342e8081ea --- /dev/null +++ b/gtk/gtkfilechooserbutton.ui @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="gtk30"> + <!-- interface-requires gtk+ 3.10 --> + <template class="GtkFileChooserButton" parent="GtkBox"> + <property name="can_focus">False</property> + <child> + <object class="GtkButton" id="button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <signal name="clicked" handler="button_clicked_cb" swapped="no"/> + <child> + <object class="GtkBox" id="box2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">4</property> + <child> + <object class="GtkImage" id="image"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-missing-image</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="valign">center</property> + <property name="label" translatable="yes">(None)</property> + <property name="ellipsize">end</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkSeparator" id="separator1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkImage" id="open_file_icon"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-open</property> + <property name="icon_size">1</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combo_box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <signal name="changed" handler="combo_box_changed_cb" swapped="no"/> + <signal name="notify::popup-shown" handler="combo_box_notify_popup_shown_cb" swapped="no"/> + <child> + <object class="GtkCellRendererPixbuf" id="icon_cell"/> + <attributes> + <attribute name="pixbuf">0</attribute> + </attributes> + </child> + <child> + <object class="GtkCellRendererText" id="name_cell"/> + <attributes> + <attribute name="text">1</attribute> + </attributes> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </template> + <object class="GtkListStore" id="model"> + <columns> + <!-- column-name icon --> + <column type="GdkPixbuf"/> + <!-- column-name display-name --> + <column type="gchararray"/> + <!-- column-name type --> + <column type="gchar"/> + <!-- column-name data --> + <column type="gpointer"/> + <!-- column-name is-folder --> + <column type="gboolean"/> + <!-- column-name cancelable --> + <column type="gpointer"/> + </columns> + </object> +</interface> diff --git a/gtk/tests/templates.c b/gtk/tests/templates.c index 834d183a43..8816f80b2a 100644 --- a/gtk/tests/templates.c +++ b/gtk/tests/templates.c @@ -231,6 +231,21 @@ test_file_chooser_dialog_basic (void) } static void +test_file_chooser_button_basic (void) +{ + GtkWidget *widget; + + g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL); + + widget = gtk_file_chooser_button_new ("Choose a file !", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); + g_assert (GTK_IS_FILE_CHOOSER_BUTTON (widget)); + g_timeout_add (100, main_loop_quit_cb, NULL); + gtk_main(); + + gtk_widget_destroy (widget); +} + +static void test_font_chooser_widget_basic (void) { GtkWidget *widget; @@ -308,6 +323,7 @@ main (int argc, char **argv) g_test_add_func ("/Template/GtkColorChooserDialog/Basic", test_color_chooser_dialog_basic); g_test_add_func ("/Template/GtkFileChooserWidget/Basic", test_file_chooser_widget_basic); g_test_add_func ("/Template/GtkFileChooserDialog/Basic", test_file_chooser_dialog_basic); + g_test_add_func ("/Template/GtkFileChooserButton/Basic", test_file_chooser_button_basic); g_test_add_func ("/Template/GtkFontChooserWidget/Basic", test_font_chooser_widget_basic); g_test_add_func ("/Template/GtkFontChooserDialog/Basic", test_font_chooser_dialog_basic); g_test_add_func ("/Template/GtkRecentChooserWidget/Basic", test_recent_chooser_widget_basic); |