[gtk+/open-with-dialog: 14/21] open-with: first attempt to split the dialog into a widget + interface
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/open-with-dialog: 14/21] open-with: first attempt to split the dialog into a widget + interface
- Date: Wed, 17 Nov 2010 23:10:46 +0000 (UTC)
commit 7782df63502d93b3d4182545d3f0ff581244c520
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Wed Nov 17 19:28:48 2010 +0100
open-with: first attempt to split the dialog into a widget + interface
Like GtkFileChooser does; GtkOpenWith is a generic interface, which is
now implemented by both GtkOpenWithDialog and GtkOpenWithWidget (and in
the future also by GtkOpenWithComboBox).
gtk/Makefile.am | 5 +
gtk/gtk.h | 2 +
gtk/gtkenums.h | 7 +
gtk/gtkopenwith.c | 68 +++
gtk/gtkopenwith.h | 53 ++
gtk/gtkopenwithdialog.c | 1284 +++++++---------------------------------------
gtk/gtkopenwithdialog.h | 21 +-
gtk/gtkopenwithprivate.h | 46 ++
gtk/gtkopenwithwidget.c | 793 ++++++++++++++++++++++++++++
gtk/gtkopenwithwidget.h | 82 +++
tests/testopenwith.c | 34 +-
11 files changed, 1253 insertions(+), 1142 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index c7a907a..27f783d 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -246,7 +246,9 @@ gtk_public_h_sources = \
gtkmountoperation.h \
gtknotebook.h \
gtkoffscreenwindow.h \
+ gtkopenwith.h \
gtkopenwithdialog.h \
+ gtkopenwithwidget.h \
gtkorientable.h \
gtkpagesetup.h \
gtkpaned.h \
@@ -373,6 +375,7 @@ gtk_private_h_sources = \
gtkmenuprivate.h \
gtkmnemonichash.h \
gtkmountoperationprivate.h \
+ gtkopenwithprivate.h \
gtkpango.h \
gtkpathbar.h \
gtkplugprivate.h \
@@ -516,6 +519,8 @@ gtk_base_c_sources = \
gtkmountoperation.c \
gtknotebook.c \
gtkoffscreenwindow.c \
+ gtkopenwith.c \
+ gtkopenwithwidget.c \
gtkopenwithdialog.c \
gtkorientable.c \
gtkpagesetup.c \
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 5cfcba2..fa823ae 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -129,7 +129,9 @@
#include <gtk/gtkmountoperation.h>
#include <gtk/gtknotebook.h>
#include <gtk/gtkoffscreenwindow.h>
+#include <gtk/gtkopenwith.h>
#include <gtk/gtkopenwithdialog.h>
+#include <gtk/gtkopenwithwidget.h>
#include <gtk/gtkorientable.h>
#include <gtk/gtkpagesetup.h>
#include <gtk/gtkpapersize.h>
diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h
index 9fd47d7..3523699 100644
--- a/gtk/gtkenums.h
+++ b/gtk/gtkenums.h
@@ -565,6 +565,13 @@ typedef enum
} GtkScrollablePolicy;
+typedef enum
+{
+ GTK_OPEN_WITH_WIDGET_SHOW_MODE_RECOMMENDED,
+ GTK_OPEN_WITH_WIDGET_SHOW_MODE_ALL,
+ GTK_OPEN_WITH_WIDGET_SHOW_MODE_HEADINGS
+} GtkOpenWithWidgetShowMode;
+
G_END_DECLS
diff --git a/gtk/gtkopenwith.c b/gtk/gtkopenwith.c
new file mode 100644
index 0000000..e5123b0
--- /dev/null
+++ b/gtk/gtkopenwith.c
@@ -0,0 +1,68 @@
+/*
+ * gtkopenwith.c: open-with interface
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi redhat com>
+ */
+
+#include <config.h>
+
+#include "gtkopenwith.h"
+
+#include "gtkintl.h"
+#include "gtkopenwithprivate.h"
+#include "gtkwidget.h"
+
+#include <glib.h>
+
+G_DEFINE_INTERFACE (GtkOpenWith, gtk_open_with, GTK_TYPE_WIDGET);
+
+static void
+gtk_open_with_default_init (GtkOpenWithIface *iface)
+{
+ GParamSpec *pspec;
+
+ pspec = g_param_spec_string ("content-type",
+ P_("Content type"),
+ P_("The content type used by the open with object"),
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_interface_install_property (iface, pspec);
+}
+
+gchar *
+gtk_open_with_get_content_type (GtkOpenWith *self)
+{
+ gchar *retval = NULL;
+
+ g_return_val_if_fail (GTK_IS_OPEN_WITH (self), NULL);
+
+ g_object_get (self,
+ "content-type", &retval,
+ NULL);
+
+ return retval;
+}
+
+GAppInfo *
+gtk_open_with_get_app_info (GtkOpenWith *self)
+{
+ return GTK_OPEN_WITH_GET_IFACE (self)->get_app_info (self);
+}
diff --git a/gtk/gtkopenwith.h b/gtk/gtkopenwith.h
new file mode 100644
index 0000000..09bca2f
--- /dev/null
+++ b/gtk/gtkopenwith.h
@@ -0,0 +1,53 @@
+/*
+ * gtkopenwith.h: open-with interface
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi redhat com>
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_OPEN_WITH_H__
+#define __GTK_OPEN_WITH_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_OPEN_WITH\
+ (gtk_open_with_get_type ())
+#define GTK_OPEN_WITH(obj)\
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_OPEN_WITH, GtkOpenWith))
+#define GTK_IS_OPEN_WITH(obj)\
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_OPEN_WITH))
+
+typedef struct _GtkOpenWith GtkOpenWith;
+
+GType gtk_open_with_get_type () G_GNUC_CONST;
+
+GAppInfo * gtk_open_with_get_app_info (GtkOpenWith *self);
+gchar * gtk_open_with_get_content_type (GtkOpenWith *self);
+
+G_END_DECLS
+
+#endif /* __GTK_OPEN_WITH_H__ */
+
diff --git a/gtk/gtkopenwithdialog.c b/gtk/gtkopenwithdialog.c
index 48b48bb..41dada8 100644
--- a/gtk/gtkopenwithdialog.c
+++ b/gtk/gtkopenwithdialog.c
@@ -29,6 +29,8 @@
#include "gtkopenwithdialog.h"
#include "gtkintl.h"
+#include "gtkopenwith.h"
+#include "gtkopenwithprivate.h"
#include <string.h>
#include <glib/gi18n-lib.h>
@@ -38,55 +40,34 @@
#define sure_string(s) ((const char *) ((s) != NULL ? (s) : ""))
struct _GtkOpenWithDialogPrivate {
- GAppInfo *selected_app_info;
-
char *content_type;
GFile *gfile;
GtkOpenWithDialogMode mode;
- GtkOpenWithDialogShowMode show_mode;
- gboolean show_set_as_default_button;
+
+ gboolean use_custom;
GtkWidget *label;
- GtkWidget *entry;
GtkWidget *button;
- GtkWidget *checkbox;
GtkWidget *desc_label;
GtkWidget *open_label;
- GtkWidget *program_list;
- GtkListStore *program_list_store;
- gint add_items_idle_id;
-
- GtkCellRenderer *padding_renderer;
-};
-
-enum {
- COLUMN_APP_INFO,
- COLUMN_GICON,
- COLUMN_NAME,
- COLUMN_COMMENT,
- COLUMN_EXEC,
- COLUMN_HEADING,
- COLUMN_HEADING_TEXT,
- COLUMN_RECOMMENDED,
- NUM_COLUMNS
+ GtkWidget *open_with_widget;
};
enum {
PROP_GFILE = 1,
PROP_CONTENT_TYPE,
PROP_MODE,
- PROP_SHOW_MODE,
- PROP_SHOW_SET_AS_DEFAULT,
N_PROPERTIES
};
#define RESPONSE_REMOVE 1
-static GParamSpec *properties[N_PROPERTIES] = { NULL, };
-
-G_DEFINE_TYPE (GtkOpenWithDialog, gtk_open_with_dialog, GTK_TYPE_DIALOG);
+static void gtk_open_with_dialog_iface_init (GtkOpenWithIface *iface);
+G_DEFINE_TYPE_WITH_CODE (GtkOpenWithDialog, gtk_open_with_dialog, GTK_TYPE_DIALOG,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_OPEN_WITH,
+ gtk_open_with_dialog_iface_init));
static void
show_error_dialog (const gchar *primary,
@@ -117,23 +98,24 @@ show_error_dialog (const gchar *primary,
* 2) The user has permissions to run the file
*/
static gboolean
-check_application (GtkOpenWithDialog *self)
+check_application (GtkOpenWithDialog *self,
+ GAppInfo **app_out)
{
- char *command;
+ const char *command;
char *path = NULL;
char **argv = NULL;
int argc;
GError *error = NULL;
gint retval = TRUE;
+ GAppInfo *info;
command = NULL;
- if (self->priv->selected_app_info != NULL)
- command = g_strdup (g_app_info_get_executable (self->priv->selected_app_info));
- if (command == NULL)
- command = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->priv->entry)));
-
+ info = gtk_open_with_get_app_info (GTK_OPEN_WITH (self->priv->open_with_widget));
+ command = g_app_info_get_executable (info);
+
g_shell_parse_argv (command, &argc, &argv, &error);
+
if (error)
{
show_error_dialog (_("Could not run application"),
@@ -160,128 +142,45 @@ check_application (GtkOpenWithDialog *self)
goto cleanup;
}
+ *app_out = info;
+
cleanup:
g_strfreev (argv);
g_free (path);
- g_free (command);
return retval;
}
-/* Only called for non-desktop files */
-static char *
-get_app_name (const char *commandline,
- GError **error)
-{
- char *basename;
- char *unquoted;
- char **argv;
- int argc;
-
- if (!g_shell_parse_argv (commandline,
- &argc, &argv, error))
- return NULL;
-
- unquoted = g_shell_unquote (argv[0], NULL);
- if (unquoted)
- basename = g_path_get_basename (unquoted);
- else
- basename = g_strdup (argv[0]);
-
- g_free (unquoted);
- g_strfreev (argv);
-
- return basename;
-}
-
-/* This will check if the application the user wanted exists will return that
- * application. If it doesn't exist, it will create one and return that.
- * It also sets the app info as the default for this type.
- */
-static GAppInfo *
+static void
add_or_find_application (GtkOpenWithDialog *self)
{
GAppInfo *app;
- char *app_name;
- const char *commandline;
- GError *error;
- gboolean success, should_set_default;
- char *message;
GList *applications;
- error = NULL;
- app = NULL;
- if (self->priv->selected_app_info)
- {
- app = g_object_ref (self->priv->selected_app_info);
- }
- else
- {
- commandline = gtk_entry_get_text (GTK_ENTRY (self->priv->entry));
- app_name = get_app_name (commandline, &error);
- if (app_name != NULL)
- {
- app = g_app_info_create_from_commandline (commandline,
- app_name,
- G_APP_INFO_CREATE_NONE,
- &error);
- g_free (app_name);
- }
- }
-
+ app = gtk_open_with_get_app_info (GTK_OPEN_WITH (self));
+
if (app == NULL)
{
- message = g_strdup_printf (_("Could not add application to the application database: %s"),
- error->message);
+ /* TODO: better error? */
show_error_dialog (_("Could not add application"),
- message,
+ NULL,
GTK_WINDOW (self));
- g_free (message);
- g_error_free (error);
- return NULL;
+ return;
}
- should_set_default =
- (self->priv->mode == GTK_OPEN_WITH_DIALOG_MODE_SELECT_DEFAULT) ||
- (self->priv->mode == GTK_OPEN_WITH_DIALOG_MODE_SELECT_ONE &&
- gtk_widget_get_visible (self->priv->checkbox) &&
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->priv->checkbox)));
- success = TRUE;
-
- if (should_set_default)
+ applications = g_app_info_get_all_for_type (self->priv->content_type);
+ if (self->priv->content_type != NULL && applications != NULL)
{
- success = g_app_info_set_as_default_for_type (app,
- self->priv->content_type,
- &error);
+ /* we don't care about reporting errors here */
+ g_app_info_add_supports_type (app,
+ self->priv->content_type,
+ NULL);
}
- else
- {
- applications = g_app_info_get_all_for_type (self->priv->content_type);
- if (self->priv->content_type && applications != NULL)
- {
- /* we don't care about reporting errors here */
- g_app_info_add_supports_type (app,
- self->priv->content_type,
- NULL);
- }
- if (applications != NULL) {
- g_list_free_full (applications, g_object_unref);
- }
- }
+ if (applications != NULL)
+ g_list_free_full (applications, g_object_unref);
- if (!success && should_set_default)
- {
- message = g_strdup_printf (_("Could not set application as the default: %s"),
- error->message);
- show_error_dialog (_("Could not set as default application"),
- message,
- GTK_WINDOW (self));
- g_free (message);
- g_error_free (error);
- }
-
- return app;
+ g_object_unref (app);
}
static void
@@ -289,59 +188,27 @@ gtk_open_with_dialog_response (GtkDialog *dialog,
gint response_id,
gpointer user_data)
{
- GAppInfo *application;
GtkOpenWithDialog *self = GTK_OPEN_WITH_DIALOG (dialog);
switch (response_id)
{
case GTK_RESPONSE_OK:
- if (check_application (self))
- {
- application = add_or_find_application (self);
-
- if (self->priv->selected_app_info != NULL)
- g_object_unref (self->priv->selected_app_info);
-
- self->priv->selected_app_info = g_object_ref (application);
- }
-
+ add_or_find_application (self);
break;
case RESPONSE_REMOVE:
- if (self->priv->selected_app_info != NULL)
- {
- if (g_app_info_delete (self->priv->selected_app_info))
- {
- GtkTreeModel *model;
- GtkTreeIter iter;
- GAppInfo *info, *selected;
-
- selected = self->priv->selected_app_info;
- self->priv->selected_app_info = NULL;
-
- model = GTK_TREE_MODEL (self->priv->program_list_store);
- if (gtk_tree_model_get_iter_first (model, &iter))
- {
- do
- {
- gtk_tree_model_get (model, &iter,
- COLUMN_APP_INFO, &info,
- -1);
- if (info != NULL && g_app_info_equal (selected, info))
- {
- gtk_list_store_remove (self->priv->program_list_store, &iter);
- g_object_unref (info);
- break;
- }
-
- if (info != NULL)
- g_object_unref (info);
- }
- while (gtk_tree_model_iter_next (model, &iter));
- }
-
- g_object_unref (selected);
- }
- }
+ {
+ GAppInfo *info;
+
+ info = gtk_open_with_get_app_info (GTK_OPEN_WITH (self->priv->open_with_widget));
+
+ if (info != NULL)
+ {
+ g_app_info_delete (info);
+ g_object_unref (info);
+ }
+
+ _gtk_open_with_widget_refilter (GTK_OPEN_WITH_WIDGET (self->priv->open_with_widget));
+ }
/* don't forward this signal to other clients in this case */
g_signal_stop_emission_by_name (self, "response");
@@ -353,560 +220,34 @@ gtk_open_with_dialog_response (GtkDialog *dialog,
}
static void
-chooser_response_cb (GtkFileChooser *chooser,
- int response,
- gpointer user_data)
-{
- GtkOpenWithDialog *self = user_data;
-
- if (response == GTK_RESPONSE_OK)
- {
- char *filename;
-
- filename = gtk_file_chooser_get_filename (chooser);
-
- if (filename)
- {
- char *quoted_text;
-
- quoted_text = g_shell_quote (filename);
-
- gtk_entry_set_text (GTK_ENTRY (self->priv->entry),
- quoted_text);
- gtk_editable_set_position (GTK_EDITABLE (self->priv->entry), -1);
- g_free (quoted_text);
- g_free (filename);
- }
- }
-
- gtk_widget_destroy (GTK_WIDGET (chooser));
-}
-
-static void
-browse_clicked_cb (GtkWidget *button,
- gpointer user_data)
-{
- GtkOpenWithDialog *self = user_data;
- GtkWidget *chooser;
-
- chooser = gtk_file_chooser_dialog_new (_("Select an Application"),
- GTK_WINDOW (self),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN,
- GTK_RESPONSE_OK,
- NULL);
- gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE);
- g_signal_connect (chooser, "response",
- G_CALLBACK (chooser_response_cb), self);
- gtk_dialog_set_default_response (GTK_DIALOG (chooser),
- GTK_RESPONSE_OK);
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
- gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser),
- FALSE);
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
- "/usr/bin");
-
- gtk_widget_show (chooser);
-}
-
-static void
-entry_changed_cb (GtkWidget *entry,
- gpointer user_data)
-{
- GtkOpenWithDialog *self = user_data;
-
- /* We are writing in the entry, so we are not using a known appinfo anymore */
- if (self->priv->selected_app_info != NULL)
- {
- g_object_unref (self->priv->selected_app_info);
- self->priv->selected_app_info = NULL;
- }
-
- if (gtk_entry_get_text (GTK_ENTRY (self->priv->entry))[0] == '\000')
- gtk_widget_set_sensitive (self->priv->button, FALSE);
- else
- gtk_widget_set_sensitive (self->priv->button, TRUE);
-}
-
-static gboolean
-gtk_open_with_search_equal_func (GtkTreeModel *model,
- int column,
- const char *key,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- char *normalized_key;
- char *name, *normalized_name;
- char *path, *normalized_path;
- char *basename, *normalized_basename;
- gboolean ret;
-
- if (key != NULL)
- {
- normalized_key = g_utf8_casefold (key, -1);
- g_assert (normalized_key != NULL);
-
- ret = TRUE;
-
- gtk_tree_model_get (model, iter,
- COLUMN_NAME, &name,
- COLUMN_EXEC, &path,
- -1);
-
- if (name != NULL)
- {
- normalized_name = g_utf8_casefold (name, -1);
- g_assert (normalized_name != NULL);
-
- if (strncmp (normalized_name, normalized_key, strlen (normalized_key)) == 0) {
- ret = FALSE;
- }
-
- g_free (normalized_name);
- }
-
- if (ret && path != NULL)
- {
- normalized_path = g_utf8_casefold (path, -1);
- g_assert (normalized_path != NULL);
-
- basename = g_path_get_basename (path);
- g_assert (basename != NULL);
-
- normalized_basename = g_utf8_casefold (basename, -1);
- g_assert (normalized_basename != NULL);
-
- if (strncmp (normalized_path, normalized_key, strlen (normalized_key)) == 0 ||
- strncmp (normalized_basename, normalized_key, strlen (normalized_key)) == 0) {
- ret = FALSE;
- }
-
- g_free (basename);
- g_free (normalized_basename);
- g_free (normalized_path);
- }
-
- g_free (name);
- g_free (path);
- g_free (normalized_key);
-
- return ret;
- }
- else
- {
- return TRUE;
- }
-}
-
-static gint
-gtk_open_with_sort_func (GtkTreeModel *model,
- GtkTreeIter *a,
- GtkTreeIter *b,
- gpointer user_data)
-{
- gboolean a_recommended, b_recommended;
- gchar *a_name, *b_name, *a_casefold, *b_casefold;
- gint retval;
-
- /* this returns:
- * - <0 if a should show before b
- * - =0 if a is the same as b
- * - >0 if a should show after b
- */
-
- gtk_tree_model_get (model, a,
- COLUMN_NAME, &a_name,
- COLUMN_RECOMMENDED, &a_recommended,
- -1);
-
- gtk_tree_model_get (model, b,
- COLUMN_NAME, &b_name,
- COLUMN_RECOMMENDED, &b_recommended,
- -1);
-
- /* the recommended one always wins */
- if (a_recommended && !b_recommended)
- {
- retval = -1;
- goto out;
- }
-
- if (b_recommended && !a_recommended)
- {
- retval = 1;
- goto out;
- }
-
- a_casefold = a_name != NULL ?
- g_utf8_casefold (a_name, -1) : NULL;
- b_casefold = b_name != NULL ?
- g_utf8_casefold (b_name, -1) : NULL;
-
- retval = g_strcmp0 (a_casefold, b_casefold);
-
- g_free (a_casefold);
- g_free (b_casefold);
-
- out:
- g_free (a_name);
- g_free (b_name);
-
- return retval;
-}
-
-static void
-heading_cell_renderer_func (GtkTreeViewColumn *column,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer _user_data)
-{
- gboolean heading;
-
- gtk_tree_model_get (model, iter,
- COLUMN_HEADING, &heading,
- -1);
-
- g_object_set (cell,
- "visible", heading,
- NULL);
-}
-
-static void
-padding_cell_renderer_func (GtkTreeViewColumn *column,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- gboolean heading;
-
- gtk_tree_model_get (model, iter,
- COLUMN_HEADING, &heading,
- -1);
- if (heading)
- g_object_set (cell,
- "visible", FALSE,
- "xpad", 0,
- "ypad", 0,
- NULL);
- else
- g_object_set (cell,
- "visible", TRUE,
- "xpad", 3,
- "ypad", 3,
- NULL);
-}
-
-static gboolean
-gtk_open_with_selection_func (GtkTreeSelection *selection,
- GtkTreeModel *model,
- GtkTreePath *path,
- gboolean path_currently_selected,
- gpointer user_data)
-{
- GtkTreeIter iter;
- gboolean heading;
-
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter,
- COLUMN_HEADING, &heading,
- -1);
-
- return !heading;
-}
-
-static gint
-compare_apps_func (gconstpointer a,
- gconstpointer b)
-{
- return !g_app_info_equal (G_APP_INFO (a), G_APP_INFO (b));
-}
-
-static void
-gtk_open_with_dialog_real_add_items (GtkOpenWithDialog *self)
-{
- GList *all_applications = NULL, *content_type_apps = NULL, *l;
- gboolean heading_added;
- gboolean show_recommended, show_headings, show_all;
-
- if (self->priv->show_mode == GTK_OPEN_WITH_DIALOG_SHOW_MODE_RECOMMENDED)
- {
- show_all = FALSE;
- show_headings = FALSE;
- show_recommended = TRUE;
- }
- else if (self->priv->show_mode == GTK_OPEN_WITH_DIALOG_SHOW_MODE_ALL)
- {
- show_all = TRUE;
- show_headings = FALSE;
- show_recommended = FALSE;
- }
- else
- {
- show_all = TRUE;
- show_headings = TRUE;
- show_recommended = TRUE;
- }
-
- if (show_recommended)
- content_type_apps = g_app_info_get_all_for_type (self->priv->content_type);
-
- if (show_all)
- all_applications = g_app_info_get_all ();
-
- heading_added = FALSE;
-
- for (l = content_type_apps; l != NULL; l = l->next)
- {
- GAppInfo *app = l->data;
- GtkTreeIter iter;
-
- if (!g_app_info_supports_uris (app) &&
- !g_app_info_supports_files (app))
- continue;
-
- if (!heading_added && show_headings)
- {
- gtk_list_store_append (self->priv->program_list_store, &iter);
- gtk_list_store_set (self->priv->program_list_store, &iter,
- COLUMN_HEADING_TEXT, _("Recommended Applications"),
- COLUMN_HEADING, TRUE,
- COLUMN_RECOMMENDED, TRUE,
- -1);
-
- heading_added = TRUE;
- }
-
- gtk_list_store_append (self->priv->program_list_store, &iter);
- gtk_list_store_set (self->priv->program_list_store, &iter,
- COLUMN_APP_INFO, app,
- COLUMN_GICON, g_app_info_get_icon (app),
- COLUMN_NAME, g_app_info_get_display_name (app),
- COLUMN_COMMENT, g_app_info_get_description (app),
- COLUMN_EXEC, g_app_info_get_executable,
- COLUMN_HEADING, FALSE,
- COLUMN_RECOMMENDED, TRUE,
- -1);
- }
-
- heading_added = FALSE;
-
- for (l = all_applications; l != NULL && show_all; l = l->next)
- {
- GAppInfo *app = l->data;
- GtkTreeIter iter;
-
- if (!g_app_info_supports_uris (app) &&
- !g_app_info_supports_files (app))
- continue;
-
- if (content_type_apps != NULL &&
- g_list_find_custom (content_type_apps, app,
- (GCompareFunc) compare_apps_func))
- continue;
-
- if (!heading_added && show_headings)
- {
- gtk_list_store_append (self->priv->program_list_store, &iter);
- gtk_list_store_set (self->priv->program_list_store, &iter,
- COLUMN_HEADING_TEXT, _("Other Applications"),
- COLUMN_HEADING, TRUE,
- COLUMN_RECOMMENDED, FALSE,
- -1);
-
- heading_added = TRUE;
- }
-
- gtk_list_store_append (self->priv->program_list_store, &iter);
- gtk_list_store_set (self->priv->program_list_store, &iter,
- COLUMN_APP_INFO, app,
- COLUMN_GICON, g_app_info_get_icon (app),
- COLUMN_NAME, g_app_info_get_display_name (app),
- COLUMN_COMMENT, g_app_info_get_description (app),
- COLUMN_EXEC, g_app_info_get_executable,
- COLUMN_HEADING, FALSE,
- COLUMN_RECOMMENDED, FALSE,
- -1);
- }
-
- if (content_type_apps != NULL)
- g_list_free_full (content_type_apps, g_object_unref);
-
- if (all_applications != NULL)
- g_list_free_full (all_applications, g_object_unref);
-}
-
-static gboolean
-gtk_open_with_dialog_add_items_idle (gpointer user_data)
-{
- GtkOpenWithDialog *self = user_data;
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
- GtkTreeModel *sort;
-
- /* create list store */
- self->priv->program_list_store = gtk_list_store_new (NUM_COLUMNS,
- G_TYPE_APP_INFO,
- G_TYPE_ICON,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_BOOLEAN,
- G_TYPE_STRING,
- G_TYPE_BOOLEAN);
- sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->priv->program_list_store));
-
- /* populate the dialog */
- gtk_open_with_dialog_real_add_items (self);
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (self->priv->program_list),
- GTK_TREE_MODEL (sort));
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort),
- COLUMN_NAME,
- GTK_SORT_ASCENDING);
- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sort),
- COLUMN_NAME,
- gtk_open_with_sort_func,
- self, NULL);
- gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->priv->program_list),
- gtk_open_with_search_equal_func,
- NULL, NULL);
-
- column = gtk_tree_view_column_new ();
-
- /* initial padding */
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- g_object_set (renderer,
- "xpad", (self->priv->show_mode == GTK_OPEN_WITH_DIALOG_SHOW_MODE_HEADINGS) ? 6 : 0,
- NULL);
- self->priv->padding_renderer = renderer;
-
- /* heading text renderer */
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "text", COLUMN_HEADING_TEXT,
- NULL);
- g_object_set (renderer,
- "weight", PANGO_WEIGHT_BOLD,
- "weight-set", TRUE,
- "ypad", 6,
- "xpad", 0,
- NULL);
- gtk_tree_view_column_set_cell_data_func (column, renderer,
- heading_cell_renderer_func,
- NULL, NULL);
-
- /* padding renderer for non-heading cells */
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_cell_data_func (column, renderer,
- padding_cell_renderer_func,
- NULL, NULL);
-
- /* app icon renderer */
- renderer = gtk_cell_renderer_pixbuf_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "gicon", COLUMN_GICON,
- NULL);
-
- /* app name renderer */
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer, TRUE);
- gtk_tree_view_column_set_attributes (column, renderer,
- "text", COLUMN_NAME,
- NULL);
- gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
- gtk_tree_view_append_column (GTK_TREE_VIEW (self->priv->program_list), column);
-
- self->priv->add_items_idle_id = 0;
-
- return FALSE;
-}
-
-static void
-program_list_selection_changed (GtkTreeSelection *selection,
+widget_application_selected_cb (GtkOpenWithWidget *widget,
+ GAppInfo *app_info,
gpointer user_data)
{
GtkOpenWithDialog *self = user_data;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GAppInfo *info;
-
- if (!gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- gtk_widget_set_sensitive (self->priv->button, FALSE);
- gtk_dialog_set_response_sensitive (GTK_DIALOG (self),
- RESPONSE_REMOVE,
- FALSE);
- return;
- }
-
- info = NULL;
- gtk_tree_model_get (model, &iter,
- COLUMN_APP_INFO, &info,
- -1);
-
- if (info == NULL)
- return;
- gtk_entry_set_text (GTK_ENTRY (self->priv->entry),
- sure_string (g_app_info_get_executable (info)));
gtk_label_set_text (GTK_LABEL (self->priv->desc_label),
- sure_string (g_app_info_get_description (info)));
+ sure_string (g_app_info_get_description (app_info)));
gtk_widget_set_sensitive (self->priv->button, TRUE);
gtk_dialog_set_response_sensitive (GTK_DIALOG (self),
RESPONSE_REMOVE,
- g_app_info_can_delete (info));
-
- if (self->priv->selected_app_info)
- g_object_unref (self->priv->selected_app_info);
+ g_app_info_can_delete (app_info));
- self->priv->selected_app_info = info;
+ self->priv->use_custom = FALSE;
}
static void
-program_list_selection_activated (GtkTreeView *view,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- gpointer user_data)
+widget_application_activated_cb (GtkOpenWithWidget *widget,
+ GAppInfo *app_info,
+ gpointer user_data)
{
GtkOpenWithDialog *self = user_data;
- GtkTreeSelection *selection;
- /* update the entry with the info from the selection */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
- program_list_selection_changed (selection, self);
+ g_print ("app activated\n");
gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
}
-static void
-expander_toggled (GtkWidget *expander,
- gpointer user_data)
-{
- GtkOpenWithDialog *self = user_data;
-
- if (gtk_expander_get_expanded (GTK_EXPANDER (expander)) == TRUE)
- {
- gtk_widget_grab_focus (self->priv->entry);
- gtk_window_resize (GTK_WINDOW (self), 400, 1);
- }
- else
- {
- GtkTreeSelection *selection;
-
- gtk_widget_grab_focus (self->priv->program_list);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
- program_list_selection_changed (selection, self);
- }
-}
-
static char *
get_extension (const char *basename)
{
@@ -923,8 +264,7 @@ get_extension (const char *basename)
static void
set_dialog_properties (GtkOpenWithDialog *self)
{
- char *label, *emname, *name, *extension, *description, *checkbox_text;
- GFileInfo *info;
+ char *label, *emname, *name, *extension, *description;
name = NULL;
extension = NULL;
@@ -937,12 +277,6 @@ set_dialog_properties (GtkOpenWithDialog *self)
name = g_file_get_basename (self->priv->gfile);
emname = g_strdup_printf ("<i>%s</i>", name);
extension = get_extension (name);
- info = g_file_query_info (self->priv->gfile,
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
- 0, NULL, NULL);
- self->priv->content_type = g_strdup (g_file_info_get_content_type (info));
-
- g_object_unref (info);
}
description = g_content_type_get_description (self->priv->content_type);
@@ -958,15 +292,6 @@ set_dialog_properties (GtkOpenWithDialog *self)
{
/* Translators: %s is a filename */
label = g_strdup_printf (_("Open %s with:"), emname);
-
- if (g_content_type_is_unknown (self->priv->content_type))
- /* Translators: the %s is the extension of the file */
- checkbox_text = g_strdup_printf (_("_Remember this application for %s documents"),
- extension);
- else
- /* Translators: %s is a file type description */
- checkbox_text = g_strdup_printf (_("_Remember this application for \"%s\" files"),
- description);
}
else
{
@@ -976,18 +301,7 @@ set_dialog_properties (GtkOpenWithDialog *self)
label = g_strdup_printf (_("Select an application for \"%s\" files:"),
g_content_type_is_unknown (self->priv->content_type) ?
self->priv->content_type : description);
-
- /* Translators: %s is a file type description */
- checkbox_text = g_strdup_printf (_("_Remember this application for \"%s\" files"),
- g_content_type_is_unknown (self->priv->content_type) ?
- self->priv->content_type : description);
}
-
- gtk_button_set_label (GTK_BUTTON (self->priv->checkbox), checkbox_text);
- g_free (checkbox_text);
-
- if (self->priv->show_set_as_default_button)
- gtk_widget_show (self->priv->checkbox);
}
else
{
@@ -1013,7 +327,6 @@ set_dialog_properties (GtkOpenWithDialog *self)
label = g_strdup_printf (_("Open all \"%s\" files with:"), description);
}
- gtk_widget_hide (self->priv->checkbox);
gtk_label_set_text_with_mnemonic (GTK_LABEL (self->priv->open_label),
_("_Select"));
gtk_window_set_title (GTK_WINDOW (self), _("Select default application"));
@@ -1029,6 +342,111 @@ set_dialog_properties (GtkOpenWithDialog *self)
}
static void
+build_dialog_ui (GtkOpenWithDialog *self)
+{
+ GtkWidget *vbox;
+ GtkWidget *vbox2;
+ GtkWidget *label;
+
+ gtk_container_set_border_width (GTK_CONTAINER (self), 5);
+
+ vbox = gtk_vbox_new (FALSE, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
+
+ vbox2 = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (vbox), vbox2, TRUE, TRUE, 0);
+
+ self->priv->label = gtk_label_new ("");
+ gtk_widget_set_halign (self->priv->label, GTK_ALIGN_START);
+ gtk_label_set_line_wrap (GTK_LABEL (self->priv->label), TRUE);
+ gtk_box_pack_start (GTK_BOX (vbox2), self->priv->label,
+ FALSE, FALSE, 0);
+ gtk_widget_show (self->priv->label);
+
+ self->priv->open_with_widget =
+ gtk_open_with_widget_new (self->priv->content_type);
+ g_signal_connect (self->priv->open_with_widget, "application-selected",
+ G_CALLBACK (widget_application_selected_cb), self);
+ g_signal_connect (self->priv->open_with_widget, "application-activated",
+ G_CALLBACK (widget_application_activated_cb), self);
+ gtk_box_pack_start (GTK_BOX (vbox2), self->priv->open_with_widget, TRUE, TRUE, 0);
+ gtk_widget_show (self->priv->open_with_widget);
+
+ self->priv->desc_label = gtk_label_new (_("Select an application to view its description."));
+ gtk_widget_set_halign (self->priv->desc_label, GTK_ALIGN_START);
+ gtk_label_set_justify (GTK_LABEL (self->priv->desc_label), GTK_JUSTIFY_LEFT);
+ gtk_label_set_line_wrap (GTK_LABEL (self->priv->desc_label), TRUE);
+ gtk_label_set_single_line_mode (GTK_LABEL (self->priv->desc_label), FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox2), self->priv->desc_label, FALSE, FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), vbox, TRUE, TRUE, 0);
+ gtk_widget_show_all (vbox);
+
+ gtk_dialog_add_button (GTK_DIALOG (self),
+ GTK_STOCK_REMOVE,
+ RESPONSE_REMOVE);
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (self),
+ RESPONSE_REMOVE,
+ FALSE);
+
+ gtk_dialog_add_button (GTK_DIALOG (self),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+
+ /* Create a custom stock icon */
+ self->priv->button = gtk_button_new ();
+
+ label = gtk_label_new_with_mnemonic (_("_Open"));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (self->priv->button));
+ gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
+ gtk_widget_show (label);
+ self->priv->open_label = label;
+
+ gtk_container_add (GTK_CONTAINER (self->priv->button),
+ self->priv->open_label);
+
+ gtk_widget_show (self->priv->button);
+ gtk_widget_set_can_default (self->priv->button, TRUE);
+
+ gtk_dialog_add_action_widget (GTK_DIALOG (self),
+ self->priv->button, GTK_RESPONSE_OK);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (self),
+ GTK_RESPONSE_OK);
+}
+
+static void
+set_gfile_and_content_type (GtkOpenWithDialog *self,
+ GFile *file)
+{
+ GFileInfo *info;
+
+ if (file == NULL)
+ return;
+
+ self->priv->gfile = g_object_ref (file);
+
+ info = g_file_query_info (self->priv->gfile,
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ 0, NULL, NULL);
+ self->priv->content_type = g_strdup (g_file_info_get_content_type (info));
+
+ g_object_unref (info);
+}
+
+static GAppInfo *
+gtk_open_with_dialog_get_app_info (GtkOpenWith *object)
+{
+ GtkOpenWithDialog *self = GTK_OPEN_WITH_DIALOG (object);
+ GAppInfo *app = NULL;
+
+ if (!check_application (self, &app))
+ return NULL;
+
+ return app;
+}
+
+static void
gtk_open_with_dialog_constructed (GObject *object)
{
GtkOpenWithDialog *self = GTK_OPEN_WITH_DIALOG (object);
@@ -1039,6 +457,7 @@ gtk_open_with_dialog_constructed (GObject *object)
if (G_OBJECT_CLASS (gtk_open_with_dialog_parent_class)->constructed != NULL)
G_OBJECT_CLASS (gtk_open_with_dialog_parent_class)->constructed (object);
+ build_dialog_ui (self);
set_dialog_properties (self);
}
@@ -1047,12 +466,6 @@ gtk_open_with_dialog_finalize (GObject *object)
{
GtkOpenWithDialog *self = GTK_OPEN_WITH_DIALOG (object);
- if (self->priv->add_items_idle_id)
- g_source_remove (self->priv->add_items_idle_id);
-
- if (self->priv->selected_app_info)
- g_object_unref (self->priv->selected_app_info);
-
if (self->priv->gfile)
g_object_unref (self->priv->gfile);
@@ -1072,22 +485,16 @@ gtk_open_with_dialog_set_property (GObject *object,
switch (property_id)
{
case PROP_GFILE:
- self->priv->gfile = g_value_dup_object (value);
+ set_gfile_and_content_type (self, g_value_get_object (value));
break;
case PROP_CONTENT_TYPE:
- self->priv->content_type = g_value_dup_string (value);
+ /* don't try to override a value previously set with the GFile */
+ if (self->priv->content_type == NULL)
+ self->priv->content_type = g_value_dup_string (value);
break;
case PROP_MODE:
self->priv->mode = g_value_get_enum (value);
break;
- case PROP_SHOW_MODE:
- gtk_open_with_dialog_set_show_mode (self,
- g_value_get_enum (value));
- break;
- case PROP_SHOW_SET_AS_DEFAULT:
- gtk_open_with_dialog_set_show_set_as_default_button (self,
- g_value_get_boolean (value));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -1114,12 +521,6 @@ gtk_open_with_dialog_get_property (GObject *object,
case PROP_MODE:
g_value_set_enum (value, self->priv->mode);
break;
- case PROP_SHOW_MODE:
- g_value_set_enum (value, self->priv->show_mode);
- break;
- case PROP_SHOW_SET_AS_DEFAULT:
- g_value_set_boolean (value, self->priv->show_set_as_default_button);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -1127,9 +528,16 @@ gtk_open_with_dialog_get_property (GObject *object,
}
static void
+gtk_open_with_dialog_iface_init (GtkOpenWithIface *iface)
+{
+ iface->get_app_info = gtk_open_with_dialog_get_app_info;
+}
+
+static void
gtk_open_with_dialog_class_init (GtkOpenWithDialogClass *klass)
{
GObjectClass *gobject_class;
+ GParamSpec *pspec;
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = gtk_open_with_dialog_finalize;
@@ -1137,38 +545,14 @@ gtk_open_with_dialog_class_init (GtkOpenWithDialogClass *klass)
gobject_class->get_property = gtk_open_with_dialog_get_property;
gobject_class->constructed = gtk_open_with_dialog_constructed;
- /**
- * GtkOpenWithDialog:gfile:
- *
- * The #GFile for this dialog, or %NULL in case the dialog has
- * been constructed for a content type.
- **/
- properties[PROP_GFILE] =
- g_param_spec_object ("gfile",
- P_("A GFile object"),
- P_("The GFile for this dialog"),
- G_TYPE_FILE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- /**
- * GtkOpenWithDialog:content-type:
- *
- * The content type string for this dialog, or %NULL in case
- * the dialog has been created for a #GFile.
- **/
- properties[PROP_CONTENT_TYPE] =
- g_param_spec_string ("content-type",
- P_("A content type string"),
- P_("The content type for this dialog"),
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
+ g_object_class_override_property (gobject_class, PROP_CONTENT_TYPE, "content-type");
+
/**
* GtkOpenWithDialog:mode:
*
* The #GtkOpenWithDialogMode for this dialog.
**/
- properties[PROP_MODE] =
+ pspec =
g_param_spec_enum ("mode",
P_("The dialog mode"),
P_("The operation mode for this dialog"),
@@ -1176,35 +560,15 @@ gtk_open_with_dialog_class_init (GtkOpenWithDialogClass *klass)
GTK_OPEN_WITH_DIALOG_MODE_SELECT_ONE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
- /**
- * GtkOpenWithDialog::show-mode:
- *
- * The #GtkOpenWithDialogShowMode for this dialog.
- **/
- properties[PROP_SHOW_MODE] =
- g_param_spec_enum ("show-mode",
- P_("The dialog show mode"),
- P_("The show mode for this dialog"),
- GTK_TYPE_OPEN_WITH_DIALOG_SHOW_MODE,
- GTK_OPEN_WITH_DIALOG_SHOW_MODE_HEADINGS,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- /**
- * GtkOpenWithDialog:show-set-as-default:
- *
- * Whether the dialog in #GTK_OPEN_WITH_DIALOG_MODE_SELECT_ONE mode should show
- * a button to remember the choice for the future.
- **/
- properties[PROP_SHOW_SET_AS_DEFAULT] =
- g_param_spec_boolean ("show-set-as-default",
- P_("Whether to show the set as default button"),
- P_("Whether the dialog should show a button to set the application as default"),
- TRUE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (gobject_class, PROP_MODE, pspec);
- g_object_class_install_properties (gobject_class, N_PROPERTIES,
- properties);
+ pspec = g_param_spec_object ("gfile",
+ P_("GFile"),
+ P_("The GFile used by the open with dialog"),
+ G_TYPE_FILE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (gobject_class, PROP_GFILE, pspec);
g_type_class_add_private (klass, sizeof (GtkOpenWithDialogPrivate));
}
@@ -1212,135 +576,9 @@ gtk_open_with_dialog_class_init (GtkOpenWithDialogClass *klass)
static void
gtk_open_with_dialog_init (GtkOpenWithDialog *self)
{
- GtkWidget *hbox;
- GtkWidget *vbox;
- GtkWidget *vbox2;
- GtkWidget *label;
- GtkWidget *button;
- GtkWidget *scrolled_window;
- GtkWidget *expander;
- GtkTreeSelection *selection;
-
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_OPEN_WITH_DIALOG,
GtkOpenWithDialogPrivate);
- gtk_container_set_border_width (GTK_CONTAINER (self), 5);
-
- vbox = gtk_vbox_new (FALSE, 12);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
-
- vbox2 = gtk_vbox_new (FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), vbox2, TRUE, TRUE, 0);
-
- self->priv->label = gtk_label_new ("");
- gtk_widget_set_halign (self->priv->label, GTK_ALIGN_START);
- gtk_label_set_line_wrap (GTK_LABEL (self->priv->label), TRUE);
- gtk_box_pack_start (GTK_BOX (vbox2), self->priv->label,
- FALSE, FALSE, 0);
- gtk_widget_show (self->priv->label);
-
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_widget_set_size_request (scrolled_window, 400, 300);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
- self->priv->program_list = gtk_tree_view_new ();
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self->priv->program_list),
- FALSE);
- gtk_container_add (GTK_CONTAINER (scrolled_window), self->priv->program_list);
- gtk_box_pack_start (GTK_BOX (vbox2), scrolled_window, TRUE, TRUE, 0);
-
- self->priv->desc_label = gtk_label_new (_("Select an application to view its description."));
- gtk_widget_set_halign (self->priv->desc_label, GTK_ALIGN_START);
- gtk_label_set_justify (GTK_LABEL (self->priv->desc_label), GTK_JUSTIFY_LEFT);
- gtk_label_set_line_wrap (GTK_LABEL (self->priv->desc_label), TRUE);
- gtk_label_set_single_line_mode (GTK_LABEL (self->priv->desc_label), FALSE);
- gtk_box_pack_start (GTK_BOX (vbox2), self->priv->desc_label, FALSE, FALSE, 0);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
- gtk_tree_selection_set_select_function (selection, gtk_open_with_selection_func,
- self, NULL);
- g_signal_connect (selection, "changed",
- G_CALLBACK (program_list_selection_changed),
- self);
- g_signal_connect (self->priv->program_list, "row-activated",
- G_CALLBACK (program_list_selection_activated),
- self);
-
- self->priv->add_items_idle_id =
- g_idle_add (gtk_open_with_dialog_add_items_idle, self);
-
- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), vbox, TRUE, TRUE, 0);
- gtk_widget_show_all (vbox);
-
- expander = gtk_expander_new_with_mnemonic (_("_Use a custom command"));
- gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE, FALSE, 0);
- g_signal_connect_after (expander, "activate", G_CALLBACK (expander_toggled), self);
- gtk_widget_show (expander);
-
- hbox = gtk_hbox_new (FALSE, 6);
- gtk_container_add (GTK_CONTAINER (expander), hbox);
- gtk_widget_show (hbox);
-
- self->priv->entry = gtk_entry_new ();
- gtk_entry_set_activates_default (GTK_ENTRY (self->priv->entry), TRUE);
-
- gtk_box_pack_start (GTK_BOX (hbox), self->priv->entry,
- TRUE, TRUE, 0);
- gtk_widget_show (self->priv->entry);
-
- button = gtk_button_new_with_mnemonic (_("_Browse..."));
- g_signal_connect (button, "clicked",
- G_CALLBACK (browse_clicked_cb), self);
- gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
- gtk_widget_show (button);
-
- /* Add remember this application checkbox - only visible in open mode */
- self->priv->checkbox = gtk_check_button_new ();
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->checkbox), TRUE);
- gtk_button_set_use_underline (GTK_BUTTON (self->priv->checkbox), TRUE);
- gtk_box_pack_start (GTK_BOX (vbox), self->priv->checkbox, FALSE, FALSE, 0);
-
- gtk_dialog_add_button (GTK_DIALOG (self),
- GTK_STOCK_REMOVE,
- RESPONSE_REMOVE);
- gtk_dialog_set_response_sensitive (GTK_DIALOG (self),
- RESPONSE_REMOVE,
- FALSE);
-
- gtk_dialog_add_button (GTK_DIALOG (self),
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL);
-
- /* Create a custom stock icon */
- self->priv->button = gtk_button_new ();
-
- /* Hook up the entry to the button */
- gtk_widget_set_sensitive (self->priv->button, FALSE);
- g_signal_connect (self->priv->entry, "changed",
- G_CALLBACK (entry_changed_cb), self);
-
- label = gtk_label_new_with_mnemonic (_("_Open"));
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (self->priv->button));
- gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
- gtk_widget_show (label);
- self->priv->open_label = label;
-
- gtk_container_add (GTK_CONTAINER (self->priv->button),
- self->priv->open_label);
-
- gtk_widget_show (self->priv->button);
- gtk_widget_set_can_default (self->priv->button, TRUE);
-
- gtk_dialog_add_action_widget (GTK_DIALOG (self),
- self->priv->button, GTK_RESPONSE_OK);
-
- gtk_dialog_set_default_response (GTK_DIALOG (self),
- GTK_RESPONSE_OK);
-
/* we can't override the class signal handler here, as it's a RUN_LAST;
* we want our signal handler instead to be executed before any user code.
*/
@@ -1364,25 +602,6 @@ set_parent_and_flags (GtkWidget *dialog,
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
}
-static void
-gtk_open_with_dialog_refilter (GtkOpenWithDialog *self)
-{
- /* if the store is NULL it means the idle handler hasn't run
- * yet, and it will take care of using the right setting itself.
- */
- if (self->priv->program_list_store != NULL)
- {
- gtk_list_store_clear (self->priv->program_list_store);
-
- /* don't add additional xpad if we don't have headings */
- g_object_set (self->priv->padding_renderer,
- "visible", self->priv->show_mode == GTK_OPEN_WITH_DIALOG_SHOW_MODE_HEADINGS,
- NULL);
-
- gtk_open_with_dialog_real_add_items (self);
- }
-}
-
/**
* gtk_open_with_dialog_new:
* @parent: (allow-none): a #GtkWindow, or %NULL
@@ -1460,135 +679,10 @@ gtk_open_with_dialog_new_for_content_type (GtkWindow *parent,
return retval;
}
-/**
- * gtk_open_with_dialog_set_show_mode:
- * @self: a #GtkOpenWithDialog
- * @show_mode: the new show mode for this dialog
- *
- * Sets the mode for the dialog to show the list of applications.
- * See #GtkOpenWithDialogShowMode for more details.
- *
- * Since: 3.0
- **/
-void
-gtk_open_with_dialog_set_show_mode (GtkOpenWithDialog *self,
- GtkOpenWithDialogShowMode show_mode)
-{
- g_return_if_fail (GTK_IS_OPEN_WITH_DIALOG (self));
-
- if (self->priv->show_mode != show_mode)
- {
- self->priv->show_mode = show_mode;
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHOW_MODE]);
-
- gtk_open_with_dialog_refilter (self);
- }
-}
-
-/**
- * gtk_open_with_dialog_get_show_mode:
- * @self: a #GtkOpenWithDialog
- *
- * Returns the current mode for the dialog to show the list of applications.
- * See #GtkOpenWithDialogShowMode for mode details.
- *
- * Returns: a #GtkOpenWithDialogShowMode
- *
- * Since: 3.0
- **/
-GtkOpenWithDialogShowMode
-gtk_open_with_dialog_get_show_mode (GtkOpenWithDialog *self)
-{
- g_return_val_if_fail (GTK_IS_OPEN_WITH_DIALOG (self), FALSE);
-
- return self->priv->show_mode;
-}
-
-/**
- * gtk_open_with_dialog_get_selected_application:
- * @self: a #GtkOpenWithDialog
- *
- * Returns a #GAppInfo for the currently selected application in the dialog,
- * or %NULL if there are none.
- *
- * Returns: (transfer full): a #GAppInfo
- *
- * Since: 3.0
- **/
-GAppInfo *
-gtk_open_with_dialog_get_selected_application (GtkOpenWithDialog *self)
+GtkWidget *
+gtk_open_with_dialog_get_widget (GtkOpenWithDialog *self)
{
g_return_val_if_fail (GTK_IS_OPEN_WITH_DIALOG (self), NULL);
- if (self->priv->selected_app_info != NULL)
- return g_object_ref (self->priv->selected_app_info);
-
- return NULL;
-}
-
-/**
- * gtk_open_with_dialog_set_show_set_as_default_button:
- * @self: a #GtkOpenWithDialog
- * @show_button: whether the button should be visible or not
- *
- * If the dialog is in #GTK_OPEN_WITH_DIALOG_MODE_SELECT_ONE mode,
- * shows a button to set the selected application as default.
- *
- * Since: 3.0
- **/
-void
-gtk_open_with_dialog_set_show_set_as_default_button (GtkOpenWithDialog *self,
- gboolean show_button)
-{
- g_return_if_fail (GTK_IS_OPEN_WITH_DIALOG (self));
-
- if (self->priv->mode == GTK_OPEN_WITH_DIALOG_MODE_SELECT_DEFAULT)
- return;
-
- if (self->priv->show_set_as_default_button != show_button)
- {
- self->priv->show_set_as_default_button = show_button;
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHOW_SET_AS_DEFAULT]);
-
- gtk_widget_set_visible (self->priv->checkbox, show_button);
- }
-}
-
-/**
- * gtk_open_with_dialog_get_show_set_as_default_button:
- * @self: a #GtkOpenWithDialog
- *
- * Returns whether the dialog is showing a button to set the selected
- * application as the default for the provided content type. Note that
- * this always returns %FALSE if the dialog is in #GTK_OPEN_WITH_DIALOG_MODE_SELECT_DEFAULT
- * mode.
- *
- * Returns: %TRUE if the button is visible.
- *
- * Since: 3.0
- **/
-gboolean
-gtk_open_with_dialog_get_show_set_as_default_button (GtkOpenWithDialog *self)
-{
- g_return_val_if_fail (GTK_IS_OPEN_WITH_DIALOG (self), FALSE);
-
- return self->priv->show_set_as_default_button;
-}
-
-/**
- * gtk_open_with_dialog_get_mode:
- * @self: a #GtkOpenWithDialog
- *
- * Returns the current mode of the dialog
- *
- * Returns: the current mode of the dialog
- *
- * Since: 3.0
- */
-GtkOpenWithDialogMode
-gtk_open_with_dialog_get_mode (GtkOpenWithDialog *self)
-{
- g_return_val_if_fail (GTK_IS_OPEN_WITH_DIALOG (self), -1);
-
- return self->priv->mode;
+ return self->priv->open_with_widget;
}
diff --git a/gtk/gtkopenwithdialog.h b/gtk/gtkopenwithdialog.h
index 826e16b..93acb22 100644
--- a/gtk/gtkopenwithdialog.h
+++ b/gtk/gtkopenwithdialog.h
@@ -47,7 +47,6 @@
#define GTK_OPEN_WITH_DIALOG_GET_CLASS(obj)\
(G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_OPEN_WITH_DIALOG, GtkOpenWithDialogClass))
-
typedef struct _GtkOpenWithDialog GtkOpenWithDialog;
typedef struct _GtkOpenWithDialogClass GtkOpenWithDialogClass;
typedef struct _GtkOpenWithDialogPrivate GtkOpenWithDialogPrivate;
@@ -62,9 +61,6 @@ struct _GtkOpenWithDialog {
struct _GtkOpenWithDialogClass {
GtkDialogClass parent_class;
- void (*application_selected) (GtkOpenWithDialog *dialog,
- GAppInfo *application);
-
/* padding for future class expansion */
gpointer padding[16];
};
@@ -78,16 +74,9 @@ struct _GtkOpenWithDialogClass {
*/
typedef enum {
GTK_OPEN_WITH_DIALOG_MODE_SELECT_ONE,
- GTK_OPEN_WITH_DIALOG_MODE_SELECT_DEFAULT,
- GTK_OPEN_WITH_DIALOG_MODE_RADIO,
+ GTK_OPEN_WITH_DIALOG_MODE_SELECT_DEFAULT
} GtkOpenWithDialogMode;
-typedef enum {
- GTK_OPEN_WITH_DIALOG_SHOW_MODE_RECOMMENDED,
- GTK_OPEN_WITH_DIALOG_SHOW_MODE_ALL,
- GTK_OPEN_WITH_DIALOG_SHOW_MODE_HEADINGS
-} GtkOpenWithDialogShowMode;
-
GType gtk_open_with_dialog_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_open_with_dialog_new (GtkWindow *parent,
@@ -99,16 +88,10 @@ GtkWidget * gtk_open_with_dialog_new_for_content_type (GtkWindow *parent,
GtkOpenWithDialogMode mode,
const gchar *content_type);
-void gtk_open_with_dialog_set_show_mode (GtkOpenWithDialog *self,
- GtkOpenWithDialogShowMode show_mode);
-GtkOpenWithDialogShowMode gtk_open_with_dialog_get_show_mode (GtkOpenWithDialog *self);
-
void gtk_open_with_dialog_set_show_set_as_default_button (GtkOpenWithDialog *self,
gboolean show_button);
gboolean gtk_open_with_get_show_set_as_default_button (GtkOpenWithDialog *self);
-GAppInfo * gtk_open_with_dialog_get_selected_application (GtkOpenWithDialog *self);
-
-GtkOpenWithDialogMode gtk_open_with_dialog_get_mode (GtkOpenWithDialog *self);
+GtkWidget * gtk_open_with_dialog_get_widget (GtkOpenWithDialog *self);
#endif /* __GTK_OPEN_WITH_DIALOG_H__ */
diff --git a/gtk/gtkopenwithprivate.h b/gtk/gtkopenwithprivate.h
new file mode 100644
index 0000000..c25b487
--- /dev/null
+++ b/gtk/gtkopenwithprivate.h
@@ -0,0 +1,46 @@
+/*
+ * gtkopenwith.c: open-with interface
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <ccecchi redhat com>
+ */
+
+#ifndef __GTK_OPEN_WITH_PRIVATE_H__
+#define __GTK_OPEN_WITH_PRIVATE_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "gtkopenwithwidget.h"
+
+typedef struct _GtkOpenWithIface GtkOpenWithIface;
+typedef GtkOpenWithIface GtkOpenWithInterface;
+
+#define GTK_OPEN_WITH_GET_IFACE(inst)\
+ (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_OPEN_WITH, GtkOpenWithIface))
+
+struct _GtkOpenWithIface {
+ GTypeInterface base_iface;
+
+ GAppInfo * (* get_app_info) (GtkOpenWith *object);
+};
+
+void _gtk_open_with_widget_refilter (GtkOpenWithWidget *self);
+
+#endif /* __GTK_OPEN_WITH_PRIVATE_H__ */
diff --git a/gtk/gtkopenwithwidget.c b/gtk/gtkopenwithwidget.c
new file mode 100644
index 0000000..fbe10e7
--- /dev/null
+++ b/gtk/gtkopenwithwidget.c
@@ -0,0 +1,793 @@
+/*
+ * gtkopenwithwidget.c: an open-with widget
+ *
+ * Copyright (C) 2004 Novell, Inc.
+ * Copyright (C) 2007, 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Dave Camp <dave novell com>
+ * Alexander Larsson <alexl redhat com>
+ * Cosimo Cecchi <ccecchi redhat com>
+ */
+
+#include <config.h>
+
+#include "gtkopenwithwidget.h"
+
+#include "gtkintl.h"
+#include "gtkmarshalers.h"
+#include "gtkopenwith.h"
+#include "gtkopenwithprivate.h"
+
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+struct _GtkOpenWithWidgetPrivate {
+ GAppInfo *selected_app_info;
+
+ char *content_type;
+ GtkOpenWithWidgetShowMode show_mode;
+
+ GtkWidget *program_list;
+ GtkListStore *program_list_store;
+
+ GtkCellRenderer *padding_renderer;
+};
+
+enum {
+ COLUMN_APP_INFO,
+ COLUMN_GICON,
+ COLUMN_NAME,
+ COLUMN_COMMENT,
+ COLUMN_EXEC,
+ COLUMN_HEADING,
+ COLUMN_HEADING_TEXT,
+ COLUMN_RECOMMENDED,
+ NUM_COLUMNS
+};
+
+
+enum {
+ PROP_CONTENT_TYPE = 1,
+ PROP_GFILE,
+ PROP_SHOW_MODE,
+ N_PROPERTIES
+};
+
+enum {
+ SIGNAL_APPLICATION_SELECTED,
+ SIGNAL_APPLICATION_ACTIVATED,
+ N_SIGNALS
+};
+
+static guint signals[N_SIGNALS] = { 0, };
+
+static void gtk_open_with_widget_iface_init (GtkOpenWithIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkOpenWithWidget, gtk_open_with_widget, GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_OPEN_WITH,
+ gtk_open_with_widget_iface_init));
+
+static void
+refresh_and_emit_app_selected (GtkOpenWithWidget *self,
+ GtkTreeSelection *selection)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GAppInfo *info = NULL;
+ gboolean should_emit = FALSE;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gtk_tree_model_get (model, &iter,
+ COLUMN_APP_INFO, &info,
+ -1);
+ }
+
+ if (info == NULL)
+ return;
+
+ if (self->priv->selected_app_info)
+ {
+ if (!g_app_info_equal (self->priv->selected_app_info, info))
+ {
+ should_emit = TRUE;
+ g_object_unref (self->priv->selected_app_info);
+
+ self->priv->selected_app_info = info;
+ }
+ }
+ else
+ {
+ should_emit = TRUE;
+ self->priv->selected_app_info = info;
+ }
+
+ if (should_emit)
+ g_signal_emit (self, signals[SIGNAL_APPLICATION_SELECTED], 0,
+ self->priv->selected_app_info);
+}
+
+static void
+program_list_selection_activated (GtkTreeView *view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ gpointer user_data)
+{
+ GtkOpenWithWidget *self = user_data;
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
+
+ refresh_and_emit_app_selected (self, selection);
+
+ g_signal_emit (self, signals[SIGNAL_APPLICATION_ACTIVATED], 0,
+ self->priv->selected_app_info);
+}
+
+static gboolean
+gtk_open_with_search_equal_func (GtkTreeModel *model,
+ int column,
+ const char *key,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ char *normalized_key;
+ char *name, *normalized_name;
+ char *path, *normalized_path;
+ char *basename, *normalized_basename;
+ gboolean ret;
+
+ if (key != NULL)
+ {
+ normalized_key = g_utf8_casefold (key, -1);
+ g_assert (normalized_key != NULL);
+
+ ret = TRUE;
+
+ gtk_tree_model_get (model, iter,
+ COLUMN_NAME, &name,
+ COLUMN_EXEC, &path,
+ -1);
+
+ if (name != NULL)
+ {
+ normalized_name = g_utf8_casefold (name, -1);
+ g_assert (normalized_name != NULL);
+
+ if (strncmp (normalized_name, normalized_key, strlen (normalized_key)) == 0) {
+ ret = FALSE;
+ }
+
+ g_free (normalized_name);
+ }
+
+ if (ret && path != NULL)
+ {
+ normalized_path = g_utf8_casefold (path, -1);
+ g_assert (normalized_path != NULL);
+
+ basename = g_path_get_basename (path);
+ g_assert (basename != NULL);
+
+ normalized_basename = g_utf8_casefold (basename, -1);
+ g_assert (normalized_basename != NULL);
+
+ if (strncmp (normalized_path, normalized_key, strlen (normalized_key)) == 0 ||
+ strncmp (normalized_basename, normalized_key, strlen (normalized_key)) == 0) {
+ ret = FALSE;
+ }
+
+ g_free (basename);
+ g_free (normalized_basename);
+ g_free (normalized_path);
+ }
+
+ g_free (name);
+ g_free (path);
+ g_free (normalized_key);
+
+ return ret;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+static gint
+gtk_open_with_sort_func (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer user_data)
+{
+ gboolean a_recommended, b_recommended;
+ gchar *a_name, *b_name, *a_casefold, *b_casefold;
+ gint retval;
+
+ /* this returns:
+ * - <0 if a should show before b
+ * - =0 if a is the same as b
+ * - >0 if a should show after b
+ */
+
+ gtk_tree_model_get (model, a,
+ COLUMN_NAME, &a_name,
+ COLUMN_RECOMMENDED, &a_recommended,
+ -1);
+
+ gtk_tree_model_get (model, b,
+ COLUMN_NAME, &b_name,
+ COLUMN_RECOMMENDED, &b_recommended,
+ -1);
+
+ /* the recommended one always wins */
+ if (a_recommended && !b_recommended)
+ {
+ retval = -1;
+ goto out;
+ }
+
+ if (b_recommended && !a_recommended)
+ {
+ retval = 1;
+ goto out;
+ }
+
+ a_casefold = a_name != NULL ?
+ g_utf8_casefold (a_name, -1) : NULL;
+ b_casefold = b_name != NULL ?
+ g_utf8_casefold (b_name, -1) : NULL;
+
+ retval = g_strcmp0 (a_casefold, b_casefold);
+
+ g_free (a_casefold);
+ g_free (b_casefold);
+
+ out:
+ g_free (a_name);
+ g_free (b_name);
+
+ return retval;
+}
+
+static void
+heading_cell_renderer_func (GtkTreeViewColumn *column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer _user_data)
+{
+ gboolean heading;
+
+ gtk_tree_model_get (model, iter,
+ COLUMN_HEADING, &heading,
+ -1);
+
+ g_object_set (cell,
+ "visible", heading,
+ NULL);
+}
+
+static void
+padding_cell_renderer_func (GtkTreeViewColumn *column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ gboolean heading;
+
+ gtk_tree_model_get (model, iter,
+ COLUMN_HEADING, &heading,
+ -1);
+ if (heading)
+ g_object_set (cell,
+ "visible", FALSE,
+ "xpad", 0,
+ "ypad", 0,
+ NULL);
+ else
+ g_object_set (cell,
+ "visible", TRUE,
+ "xpad", 3,
+ "ypad", 3,
+ NULL);
+}
+
+static gboolean
+gtk_open_with_selection_func (GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gboolean path_currently_selected,
+ gpointer user_data)
+{
+ GtkTreeIter iter;
+ gboolean heading;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter,
+ COLUMN_HEADING, &heading,
+ -1);
+
+ return !heading;
+}
+
+static gint
+compare_apps_func (gconstpointer a,
+ gconstpointer b)
+{
+ return !g_app_info_equal (G_APP_INFO (a), G_APP_INFO (b));
+}
+
+static void
+gtk_open_with_widget_real_add_items (GtkOpenWithWidget *self)
+{
+ GList *all_applications = NULL, *content_type_apps = NULL, *l;
+ gboolean heading_added;
+ gboolean show_recommended, show_headings, show_all;
+
+ if (self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_RECOMMENDED)
+ {
+ show_all = FALSE;
+ show_headings = FALSE;
+ show_recommended = TRUE;
+ }
+ else if (self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_ALL)
+ {
+ show_all = TRUE;
+ show_headings = FALSE;
+ show_recommended = FALSE;
+ }
+ else
+ {
+ show_all = TRUE;
+ show_headings = TRUE;
+ show_recommended = TRUE;
+ }
+
+ if (show_recommended)
+ content_type_apps = g_app_info_get_all_for_type (self->priv->content_type);
+
+ if (show_all)
+ all_applications = g_app_info_get_all ();
+
+ heading_added = FALSE;
+
+ for (l = content_type_apps; l != NULL; l = l->next)
+ {
+ GAppInfo *app = l->data;
+ GtkTreeIter iter;
+
+ if (!g_app_info_supports_uris (app) &&
+ !g_app_info_supports_files (app))
+ continue;
+
+ if (!heading_added && show_headings)
+ {
+ gtk_list_store_append (self->priv->program_list_store, &iter);
+ gtk_list_store_set (self->priv->program_list_store, &iter,
+ COLUMN_HEADING_TEXT, _("Recommended Applications"),
+ COLUMN_HEADING, TRUE,
+ COLUMN_RECOMMENDED, TRUE,
+ -1);
+
+ heading_added = TRUE;
+ }
+
+ gtk_list_store_append (self->priv->program_list_store, &iter);
+ gtk_list_store_set (self->priv->program_list_store, &iter,
+ COLUMN_APP_INFO, app,
+ COLUMN_GICON, g_app_info_get_icon (app),
+ COLUMN_NAME, g_app_info_get_display_name (app),
+ COLUMN_COMMENT, g_app_info_get_description (app),
+ COLUMN_EXEC, g_app_info_get_executable,
+ COLUMN_HEADING, FALSE,
+ COLUMN_RECOMMENDED, TRUE,
+ -1);
+ }
+
+ heading_added = FALSE;
+
+ for (l = all_applications; l != NULL && show_all; l = l->next)
+ {
+ GAppInfo *app = l->data;
+ GtkTreeIter iter;
+
+ if (!g_app_info_supports_uris (app) &&
+ !g_app_info_supports_files (app))
+ continue;
+
+ if (content_type_apps != NULL &&
+ g_list_find_custom (content_type_apps, app,
+ (GCompareFunc) compare_apps_func))
+ continue;
+
+ if (!heading_added && show_headings)
+ {
+ gtk_list_store_append (self->priv->program_list_store, &iter);
+ gtk_list_store_set (self->priv->program_list_store, &iter,
+ COLUMN_HEADING_TEXT, _("Other Applications"),
+ COLUMN_HEADING, TRUE,
+ COLUMN_RECOMMENDED, FALSE,
+ -1);
+
+ heading_added = TRUE;
+ }
+
+ gtk_list_store_append (self->priv->program_list_store, &iter);
+ gtk_list_store_set (self->priv->program_list_store, &iter,
+ COLUMN_APP_INFO, app,
+ COLUMN_GICON, g_app_info_get_icon (app),
+ COLUMN_NAME, g_app_info_get_display_name (app),
+ COLUMN_COMMENT, g_app_info_get_description (app),
+ COLUMN_EXEC, g_app_info_get_executable,
+ COLUMN_HEADING, FALSE,
+ COLUMN_RECOMMENDED, FALSE,
+ -1);
+ }
+
+ if (content_type_apps != NULL)
+ g_list_free_full (content_type_apps, g_object_unref);
+
+ if (all_applications != NULL)
+ g_list_free_full (all_applications, g_object_unref);
+}
+
+static void
+gtk_open_with_widget_add_items (GtkOpenWithWidget *self)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ GtkTreeModel *sort;
+
+ /* create list store */
+ self->priv->program_list_store = gtk_list_store_new (NUM_COLUMNS,
+ G_TYPE_APP_INFO,
+ G_TYPE_ICON,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN);
+ sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->priv->program_list_store));
+
+ /* populate the widget */
+ gtk_open_with_widget_real_add_items (self);
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (self->priv->program_list),
+ GTK_TREE_MODEL (sort));
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort),
+ COLUMN_NAME,
+ GTK_SORT_ASCENDING);
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sort),
+ COLUMN_NAME,
+ gtk_open_with_sort_func,
+ self, NULL);
+ gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->priv->program_list),
+ gtk_open_with_search_equal_func,
+ NULL, NULL);
+
+ column = gtk_tree_view_column_new ();
+
+ /* initial padding */
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ g_object_set (renderer,
+ "xpad", (self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_HEADINGS) ? 6 : 0,
+ NULL);
+ self->priv->padding_renderer = renderer;
+
+ /* heading text renderer */
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "text", COLUMN_HEADING_TEXT,
+ NULL);
+ g_object_set (renderer,
+ "weight", PANGO_WEIGHT_BOLD,
+ "weight-set", TRUE,
+ "ypad", 6,
+ "xpad", 0,
+ NULL);
+ gtk_tree_view_column_set_cell_data_func (column, renderer,
+ heading_cell_renderer_func,
+ NULL, NULL);
+
+ /* padding renderer for non-heading cells */
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer,
+ padding_cell_renderer_func,
+ NULL, NULL);
+
+ /* app icon renderer */
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "gicon", COLUMN_GICON,
+ NULL);
+
+ /* app name renderer */
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "text", COLUMN_NAME,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (self->priv->program_list), column);
+}
+
+static void
+gtk_open_with_widget_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
+
+ switch (property_id)
+ {
+ case PROP_CONTENT_TYPE:
+ self->priv->content_type = g_value_dup_string (value);
+ break;
+ case PROP_SHOW_MODE:
+ gtk_open_with_widget_set_show_mode (self,
+ g_value_get_enum (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_open_with_widget_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
+
+ switch (property_id)
+ {
+ case PROP_CONTENT_TYPE:
+ g_value_set_string (value, self->priv->content_type);
+ break;
+ case PROP_SHOW_MODE:
+ g_value_set_enum (value, self->priv->show_mode);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_open_with_widget_constructed (GObject *object)
+{
+ GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
+
+ g_assert (self->priv->content_type != NULL);
+
+ if (G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->constructed != NULL)
+ G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->constructed (object);
+
+ gtk_open_with_widget_add_items (self);
+}
+
+static void
+gtk_open_with_widget_finalize (GObject *object)
+{
+ GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
+
+ g_free (self->priv->content_type);
+
+ G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->finalize (object);
+}
+
+static void
+gtk_open_with_widget_dispose (GObject *object)
+{
+ GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
+
+ if (self->priv->selected_app_info != NULL)
+ {
+ g_object_unref (self->priv->selected_app_info);
+ self->priv->selected_app_info = NULL;
+ }
+
+ G_OBJECT_CLASS (gtk_open_with_widget_parent_class)->dispose (object);
+}
+
+static void
+gtk_open_with_widget_class_init (GtkOpenWithWidgetClass *klass)
+{
+ GObjectClass *gobject_class;
+ GParamSpec *pspec;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->dispose = gtk_open_with_widget_dispose;
+ gobject_class->finalize = gtk_open_with_widget_finalize;
+ gobject_class->set_property = gtk_open_with_widget_set_property;
+ gobject_class->get_property = gtk_open_with_widget_get_property;
+ gobject_class->constructed = gtk_open_with_widget_constructed;
+
+ g_object_class_override_property (gobject_class, PROP_CONTENT_TYPE, "content-type");
+
+ /**
+ * GtkOpenWithWidget::show-mode:
+ *
+ * The #GtkOpenWithWidgetShowMode for this widget.
+ **/
+ pspec =
+ g_param_spec_enum ("show-mode",
+ P_("The widget show mode"),
+ P_("The show mode for this widget"),
+ GTK_TYPE_OPEN_WITH_WIDGET_SHOW_MODE,
+ GTK_OPEN_WITH_WIDGET_SHOW_MODE_HEADINGS,
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (gobject_class, PROP_SHOW_MODE, pspec);
+
+ signals[SIGNAL_APPLICATION_SELECTED] =
+ g_signal_new ("application-selected",
+ GTK_TYPE_OPEN_WITH_WIDGET,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkOpenWithWidgetClass, application_selected),
+ NULL, NULL,
+ _gtk_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, G_TYPE_APP_INFO);
+
+ signals[SIGNAL_APPLICATION_ACTIVATED] =
+ g_signal_new ("application-activated",
+ GTK_TYPE_OPEN_WITH_WIDGET,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkOpenWithWidgetClass, application_activated),
+ NULL, NULL,
+ _gtk_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, G_TYPE_APP_INFO);
+
+ g_type_class_add_private (klass, sizeof (GtkOpenWithWidgetPrivate));
+}
+
+static void
+gtk_open_with_widget_init (GtkOpenWithWidget *self)
+{
+ GtkWidget *scrolled_window;
+ GtkTreeSelection *selection;
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_OPEN_WITH_WIDGET,
+ GtkOpenWithWidgetPrivate);
+
+ gtk_container_set_border_width (GTK_CONTAINER (self), 5);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_set_size_request (scrolled_window, 400, 300);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+
+ self->priv->program_list = gtk_tree_view_new ();
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self->priv->program_list),
+ FALSE);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), self->priv->program_list);
+ gtk_box_pack_start (GTK_BOX (self), scrolled_window, TRUE, TRUE, 0);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->program_list));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+ gtk_tree_selection_set_select_function (selection, gtk_open_with_selection_func,
+ self, NULL);
+ g_signal_connect_swapped (selection, "changed",
+ G_CALLBACK (refresh_and_emit_app_selected),
+ self);
+ g_signal_connect (self->priv->program_list, "row-activated",
+ G_CALLBACK (program_list_selection_activated),
+ self);
+}
+
+static GAppInfo *
+gtk_open_with_widget_get_app_info (GtkOpenWith *object)
+{
+ GtkOpenWithWidget *self = GTK_OPEN_WITH_WIDGET (object);
+
+ if (self->priv->selected_app_info == NULL)
+ return NULL;
+
+ return g_object_ref (self->priv->selected_app_info);
+}
+
+static void
+gtk_open_with_widget_iface_init (GtkOpenWithIface *iface)
+{
+ iface->get_app_info = gtk_open_with_widget_get_app_info;
+}
+
+void
+_gtk_open_with_widget_refilter (GtkOpenWithWidget *self)
+{
+ if (self->priv->program_list_store != NULL)
+ {
+ gtk_list_store_clear (self->priv->program_list_store);
+
+ /* don't add additional xpad if we don't have headings */
+ g_object_set (self->priv->padding_renderer,
+ "visible", self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_HEADINGS,
+ NULL);
+
+ gtk_open_with_widget_real_add_items (self);
+ }
+}
+
+GtkWidget *
+gtk_open_with_widget_new (const gchar *content_type)
+{
+ return g_object_new (GTK_TYPE_OPEN_WITH_WIDGET,
+ "content-type", content_type,
+ NULL);
+}
+
+/**
+ * gtk_open_with_widget_set_show_mode:
+ * @self: a #GtkOpenWithWidget
+ * @show_mode: the new show mode for this widget
+ *
+ * Sets the mode for the widget to show the list of applications.
+ * See #GtkOpenWithWidgetShowMode for more details.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_open_with_widget_set_show_mode (GtkOpenWithWidget *self,
+ GtkOpenWithWidgetShowMode show_mode)
+{
+ g_return_if_fail (GTK_IS_OPEN_WITH_WIDGET (self));
+
+ if (self->priv->show_mode != show_mode)
+ {
+ self->priv->show_mode = show_mode;
+ g_object_notify (G_OBJECT (self), "show-mode");
+
+ _gtk_open_with_widget_refilter (self);
+ }
+}
+
+/**
+ * gtk_open_with_widget_get_show_mode:
+ * @self: a #GtkOpenWithWidget
+ *
+ * Returns the current mode for the widget to show the list of applications.
+ * See #GtkOpenWithWidgetShowMode for mode details.
+ *
+ * Returns: a #GtkOpenWithWidgetShowMode
+ *
+ * Since: 3.0
+ **/
+GtkOpenWithWidgetShowMode
+gtk_open_with_widget_get_show_mode (GtkOpenWithWidget *self)
+{
+ g_return_val_if_fail (GTK_IS_OPEN_WITH_WIDGET (self), FALSE);
+
+ return self->priv->show_mode;
+}
diff --git a/gtk/gtkopenwithwidget.h b/gtk/gtkopenwithwidget.h
new file mode 100644
index 0000000..4ac1193
--- /dev/null
+++ b/gtk/gtkopenwithwidget.h
@@ -0,0 +1,82 @@
+/*
+ * gtkopenwithwidget.h: an open-with widget
+ *
+ * Copyright (C) 2004 Novell, Inc.
+ * Copyright (C) 2007, 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Dave Camp <dave novell com>
+ * Alexander Larsson <alexl redhat com>
+ * Cosimo Cecchi <ccecchi redhat com>
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_OPEN_WITH_WIDGET_H__
+#define __GTK_OPEN_WITH_WIDGET_H__
+
+#include <gtk/gtkbox.h>
+#include <gio/gio.h>
+
+#define GTK_TYPE_OPEN_WITH_WIDGET\
+ (gtk_open_with_widget_get_type ())
+#define GTK_OPEN_WITH_WIDGET(obj)\
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_OPEN_WITH_WIDGET, GtkOpenWithWidget))
+#define GTK_OPEN_WITH_WIDGET_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_OPEN_WITH_WIDGET, GtkOpenWithWidgetClass))
+#define GTK_IS_OPEN_WITH_WIDGET(obj)\
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_OPEN_WITH_WIDGET))
+#define GTK_IS_OPEN_WITH_WIDGET_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_OPEN_WITH_WIDGET))
+#define GTK_OPEN_WITH_WIDGET_GET_CLASS(obj)\
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_OPEN_WITH_WIDGET, GtkOpenWithWidgetClass))
+
+typedef struct _GtkOpenWithWidget GtkOpenWithWidget;
+typedef struct _GtkOpenWithWidgetClass GtkOpenWithWidgetClass;
+typedef struct _GtkOpenWithWidgetPrivate GtkOpenWithWidgetPrivate;
+
+struct _GtkOpenWithWidget {
+ GtkBox parent;
+
+ /*< private >*/
+ GtkOpenWithWidgetPrivate *priv;
+};
+
+struct _GtkOpenWithWidgetClass {
+ GtkBoxClass parent_class;
+
+ void (* application_selected) (GtkOpenWithWidget *self,
+ GAppInfo *app_info);
+
+ void (* application_activated) (GtkOpenWithWidget *self,
+ GAppInfo *app_info);
+
+ /* padding for future class expansion */
+ gpointer padding[16];
+};
+
+GType gtk_open_with_widget_get_type (void) G_GNUC_CONST;
+
+GtkWidget * gtk_open_with_widget_new (const gchar *content_type);
+
+void gtk_open_with_widget_set_show_mode (GtkOpenWithWidget *self,
+ GtkOpenWithWidgetShowMode show_mode);
+GtkOpenWithWidgetShowMode gtk_open_with_widget_get_show_mode (GtkOpenWithWidget *self);
+
+#endif /* __GTK_OPEN_WITH_WIDGET_H__ */
diff --git a/tests/testopenwith.c b/tests/testopenwith.c
index 7de589a..1686cde 100644
--- a/tests/testopenwith.c
+++ b/tests/testopenwith.c
@@ -25,7 +25,7 @@
static GtkWidget *toplevel;
static GFile *file;
-static GtkWidget *grid, *file_l, *open, *show_mode, *show_set_as_default;
+static GtkWidget *grid, *file_l, *open, *show_mode;
static GtkWidget *radio_file, *radio_file_default, *radio_content, *radio_content_default, *dialog;
static void
@@ -40,7 +40,7 @@ dialog_response (GtkDialog *d,
if (response_id == GTK_RESPONSE_OK)
{
- app_info = gtk_open_with_dialog_get_selected_application (GTK_OPEN_WITH_DIALOG (d));
+ app_info = gtk_open_with_get_app_info (GTK_OPEN_WITH (d));
name = g_app_info_get_name (app_info);
g_print ("Application selected: %s\n", name);
@@ -57,6 +57,7 @@ display_dialog (GtkButton *b,
gboolean use_file = FALSE;
gboolean default_mode = FALSE;
gchar *content_type = NULL;
+ GtkWidget *open_with_widget;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_file)))
{
@@ -105,11 +106,10 @@ display_dialog (GtkButton *b,
content_type);
}
- gtk_open_with_dialog_set_show_mode (GTK_OPEN_WITH_DIALOG (dialog),
+ open_with_widget = gtk_open_with_dialog_get_widget (GTK_OPEN_WITH_DIALOG (dialog));
+ gtk_open_with_widget_set_show_mode (GTK_OPEN_WITH_WIDGET (open_with_widget),
gtk_combo_box_get_active (GTK_COMBO_BOX (show_mode)));
- gtk_open_with_dialog_set_show_set_as_default_button (GTK_OPEN_WITH_DIALOG (dialog),
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_set_as_default)));
gtk_widget_show (dialog);
g_signal_connect (dialog, "response",
@@ -127,27 +127,12 @@ show_mode_changed (GtkComboBox *b,
gint active;
active = gtk_combo_box_get_active (b);
- gtk_open_with_dialog_set_show_mode (GTK_OPEN_WITH_DIALOG (dialog),
+ gtk_open_with_widget_set_show_mode (GTK_OPEN_WITH_WIDGET (gtk_open_with_dialog_get_widget (GTK_OPEN_WITH_DIALOG (dialog))),
active);
}
}
static void
-show_set_as_default_toggled (GtkToggleButton *b,
- gpointer user_data)
-{
- if (dialog != NULL)
- {
- gboolean toggled;
-
- toggled = gtk_toggle_button_get_active (b);
-
- gtk_open_with_dialog_set_show_set_as_default_button (GTK_OPEN_WITH_DIALOG (dialog),
- toggled);
- }
-}
-
-static void
button_clicked (GtkButton *b,
gpointer user_data)
{
@@ -231,13 +216,6 @@ main (int argc,
g_signal_connect (show_mode, "changed",
G_CALLBACK (show_mode_changed), NULL);
- show_set_as_default = gtk_check_button_new_with_label ("Show set as default");
- gtk_grid_attach_next_to (GTK_GRID (grid), show_set_as_default,
- show_mode, GTK_POS_BOTTOM, 1, 1);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_set_as_default), TRUE);
- g_signal_connect (show_set_as_default, "toggled",
- G_CALLBACK (show_set_as_default_toggled), NULL);
-
gtk_container_add (GTK_CONTAINER (toplevel), grid);
gtk_widget_show_all (toplevel);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]