Index: thunar/thunar-chooser-button.c =================================================================== --- thunar/thunar-chooser-button.c (revision 28974) +++ thunar/thunar-chooser-button.c (working copy) @@ -41,24 +41,28 @@ -static void thunar_chooser_button_class_init (ThunarChooserButtonClass *klass); -static void thunar_chooser_button_init (ThunarChooserButton *chooser_button); -static void thunar_chooser_button_finalize (GObject *object); -static void thunar_chooser_button_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_chooser_button_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void thunar_chooser_button_activate (ThunarChooserButton *chooser_button, - GtkWidget *item); -static void thunar_chooser_button_activate_other (ThunarChooserButton *chooser_button); -static void thunar_chooser_button_file_changed (ThunarChooserButton *chooser_button, - ThunarFile *file); -static void thunar_chooser_button_pressed (ThunarChooserButton *chooser_button, - GtkWidget *button); +static void thunar_chooser_button_class_init (ThunarChooserButtonClass *klass); +static void thunar_chooser_button_init (ThunarChooserButton *chooser_button); +static void thunar_chooser_button_finalize (GObject *object); +static void thunar_chooser_button_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_chooser_button_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static gboolean thunar_chooser_button_scroll_event (GtkWidget *widget, + GdkEventScroll *event); +static gint thunar_chooser_button_sort_applications (gconstpointer a, + gconstpointer b); +static void thunar_chooser_button_activate (ThunarChooserButton *chooser_button, + GtkWidget *item); +static void thunar_chooser_button_activate_other (ThunarChooserButton *chooser_button); +static void thunar_chooser_button_file_changed (ThunarChooserButton *chooser_button, + ThunarFile *file); +static void thunar_chooser_button_pressed (ThunarChooserButton *chooser_button, + GtkWidget *button); @@ -118,7 +122,8 @@ static void thunar_chooser_button_class_init (ThunarChooserButtonClass *klass) { - GObjectClass *gobject_class; + GObjectClass *gobject_class; + GtkWidgetClass *gtkwidget_class; /* determine the parent type class */ thunar_chooser_button_parent_class = g_type_class_peek_parent (klass); @@ -127,6 +132,9 @@ gobject_class->finalize = thunar_chooser_button_finalize; gobject_class->get_property = thunar_chooser_button_get_property; gobject_class->set_property = thunar_chooser_button_set_property; + + gtkwidget_class = GTK_WIDGET_CLASS (klass); + gtkwidget_class->scroll_event = thunar_chooser_button_scroll_event; /** * ThunarChooserButton:file: @@ -245,6 +253,91 @@ +static gboolean +thunar_chooser_button_scroll_event (GtkWidget *widget, + GdkEventScroll *event) +{ + ThunarChooserButton *chooser_button = THUNAR_CHOOSER_BUTTON (widget); + ThunarVfsMimeApplication *default_application, *application; + ThunarVfsMimeInfo *info; + GList *applications, *lp; + GError *error = NULL; + + /* verify that we still have a valid file */ + if (G_UNLIKELY (chooser_button->file != NULL)) + { + /* determine the mime info for the file */ + info = thunar_file_get_mime_info (chooser_button->file); + + /* determine the default application for that mime info */ + default_application = thunar_vfs_mime_database_get_default_application (chooser_button->database, info); + if (G_LIKELY (default_application != NULL)) + { + /* determine all applications that claim to be able to handle the file */ + applications = thunar_vfs_mime_database_get_applications (chooser_button->database, info); + + /* sort the list alphabetically, because by default application is always + * on the head of the list */ + applications = g_list_sort (applications, thunar_chooser_button_sort_applications); + + for (lp = applications; lp != NULL; lp = lp->next) + { + /* check if this is the currently set application */ + if (G_UNLIKELY (lp->data == default_application)) + { + /* get the previous or next application, based on the event */ + if (event->direction == GDK_SCROLL_UP) + application = lp->prev != NULL ? lp->prev->data : NULL; + else if (event->direction == GDK_SCROLL_DOWN) + application = lp->next != NULL ? lp->next->data : NULL; + else + continue; + + if (G_LIKELY (application != NULL)) + { + /* try to set application as default for this kind of file */ + if (!thunar_vfs_mime_database_set_default_application (chooser_button->database, info, application, &error)) + { + /* tell the user that it didn't work */ + thunar_dialogs_show_error (GTK_WIDGET (chooser_button), error, _("Failed to set default application for \"%s\""), + thunar_file_get_display_name (chooser_button->file)); + g_error_free (error); + } + else + { + /* emit "changed" on the file, so everybody updates its state */ + thunar_file_changed (chooser_button->file); + } + } + } + + /* release the application */ + g_object_unref (G_OBJECT (lp->data)); + } + + /* release the applications list */ + g_list_free (applications); + + /* release the default application */ + g_object_unref (G_OBJECT (default_application)); + } + } + + return FALSE; +} + + + +static gint +thunar_chooser_button_sort_applications (gconstpointer a, + gconstpointer b) +{ + return g_utf8_collate (thunar_vfs_mime_handler_get_name (THUNAR_VFS_MIME_HANDLER (a)), + thunar_vfs_mime_handler_get_name (THUNAR_VFS_MIME_HANDLER (b))); +} + + + static void thunar_chooser_button_activate (ThunarChooserButton *chooser_button, GtkWidget *item) @@ -451,13 +544,18 @@ /* determine all applications that claim to be able to handle the file */ applications = thunar_vfs_mime_database_get_applications (chooser_button->database, info); - /* make sure the default application comes first */ + /* remove the default application from the list */ lp = g_list_find (applications, default_application); if (G_LIKELY (lp != NULL)) { applications = g_list_delete_link (applications, lp); g_object_unref (G_OBJECT (default_application)); } + + /* sort all other applications by name */ + applications = g_list_sort (applications, thunar_chooser_button_sort_applications); + + /* make sure the default application comes first */ applications = g_list_prepend (applications, default_application); /* allocate a new popup menu */