Port to the use of GFile instead of URIs and merge gio document loader and saver
into document loader and saver
This commit is contained in:
@@ -535,6 +535,7 @@ init_bookmarks (XedFileBookmarksStore * model)
|
||||
{
|
||||
if (**line)
|
||||
{
|
||||
GFile *location;
|
||||
gchar *pos;
|
||||
gchar *name;
|
||||
|
||||
@@ -553,10 +554,12 @@ init_bookmarks (XedFileBookmarksStore * model)
|
||||
|
||||
/* the bookmarks file should contain valid
|
||||
* URIs, but paranoia is good */
|
||||
if (xed_utils_is_valid_uri (*line))
|
||||
location = g_file_new_for_uri (*line);
|
||||
if (xed_utils_is_valid_location (location))
|
||||
{
|
||||
added |= add_bookmark (model, name, *line);
|
||||
}
|
||||
g_object_unref (location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -844,14 +847,14 @@ xed_file_bookmarks_store_new (void)
|
||||
return model;
|
||||
}
|
||||
|
||||
gchar *
|
||||
xed_file_bookmarks_store_get_uri (XedFileBookmarksStore *model,
|
||||
GtkTreeIter *iter)
|
||||
GFile *
|
||||
xed_file_bookmarks_store_get_location (XedFileBookmarksStore *model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GObject * obj;
|
||||
GFile * file = NULL;
|
||||
GObject *obj;
|
||||
GFile *file = NULL;
|
||||
guint flags;
|
||||
gchar * ret = NULL;
|
||||
GFile *ret = NULL;
|
||||
gboolean isfs;
|
||||
|
||||
g_return_val_if_fail (XED_IS_FILE_BOOKMARKS_STORE (model), NULL);
|
||||
@@ -884,7 +887,7 @@ xed_file_bookmarks_store_get_uri (XedFileBookmarksStore *model,
|
||||
|
||||
if (file)
|
||||
{
|
||||
ret = g_file_get_uri (file);
|
||||
ret = g_file_dup (file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
|
@@ -25,13 +25,13 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define XED_TYPE_FILE_BOOKMARKS_STORE (xed_file_bookmarks_store_get_type ())
|
||||
#define XED_FILE_BOOKMARKS_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStore))
|
||||
#define XED_FILE_BOOKMARKS_STORE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStore const))
|
||||
#define XED_TYPE_FILE_BOOKMARKS_STORE (xed_file_bookmarks_store_get_type ())
|
||||
#define XED_FILE_BOOKMARKS_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStore))
|
||||
#define XED_FILE_BOOKMARKS_STORE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStore const))
|
||||
#define XED_FILE_BOOKMARKS_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStoreClass))
|
||||
#define XED_IS_FILE_BOOKMARKS_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_FILE_BOOKMARKS_STORE))
|
||||
#define XED_IS_FILE_BOOKMARKS_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_FILE_BOOKMARKS_STORE))
|
||||
#define XED_IS_FILE_BOOKMARKS_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_FILE_BOOKMARKS_STORE))
|
||||
#define XED_FILE_BOOKMARKS_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStoreClass))
|
||||
#define XED_FILE_BOOKMARKS_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStoreClass))
|
||||
|
||||
typedef struct _XedFileBookmarksStore XedFileBookmarksStore;
|
||||
typedef struct _XedFileBookmarksStoreClass XedFileBookmarksStoreClass;
|
||||
@@ -76,13 +76,13 @@ struct _XedFileBookmarksStoreClass
|
||||
GtkTreeStoreClass parent_class;
|
||||
};
|
||||
|
||||
GType xed_file_bookmarks_store_get_type (void) G_GNUC_CONST;
|
||||
void _xed_file_bookmarks_store_register_type (GTypeModule *type_module);
|
||||
GType xed_file_bookmarks_store_get_type (void) G_GNUC_CONST;
|
||||
void _xed_file_bookmarks_store_register_type (GTypeModule *type_module);
|
||||
|
||||
XedFileBookmarksStore *xed_file_bookmarks_store_new (void);
|
||||
gchar *xed_file_bookmarks_store_get_uri (XedFileBookmarksStore * model,
|
||||
GtkTreeIter * iter);
|
||||
void xed_file_bookmarks_store_refresh (XedFileBookmarksStore * model);
|
||||
GFile *xed_file_bookmarks_store_get_location (XedFileBookmarksStore * model,
|
||||
GtkTreeIter * iter);
|
||||
void xed_file_bookmarks_store_refresh (XedFileBookmarksStore * model);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __XED_FILE_BOOKMARKS_STORE_H__ */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
VOID:UINT,STRING
|
||||
VOID:STRING,STRING
|
||||
VOID:OBJECT,OBJECT
|
||||
BOOL:OBJECT,POINTER
|
||||
BOOL:POINTER
|
||||
BOOL:VOID
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -68,9 +68,9 @@ enum
|
||||
PROP_WINDOW
|
||||
};
|
||||
|
||||
static void on_uri_activated_cb (XedFileBrowserWidget *widget,
|
||||
gchar const *uri,
|
||||
XedWindow *window);
|
||||
static void on_location_activated_cb (XedFileBrowserWidget *widget,
|
||||
GFile *location,
|
||||
XedWindow *window);
|
||||
static void on_error_cb (XedFileBrowserWidget *widget,
|
||||
guint code,
|
||||
gchar const *message,
|
||||
@@ -85,8 +85,8 @@ static void on_filter_mode_changed_cb (XedFileBrowserStore *model,
|
||||
GParamSpec *param,
|
||||
XedFileBrowserPlugin *plugin);
|
||||
static void on_rename_cb (XedFileBrowserStore *model,
|
||||
const gchar *olduri,
|
||||
const gchar *newuri,
|
||||
GFile *oldfile,
|
||||
GFile *newfile,
|
||||
XedWindow *window);
|
||||
static void on_filter_pattern_changed_cb (XedFileBrowserWidget *widget,
|
||||
GParamSpec *param,
|
||||
@@ -229,25 +229,28 @@ restore_default_location (XedFileBrowserPlugin *plugin)
|
||||
remote = g_settings_get_boolean (priv->onload_settings, "enable-remote");
|
||||
|
||||
if (root != NULL && *root != '\0') {
|
||||
GFile *file;
|
||||
GFile *rootfile;
|
||||
GFile *vrootfile;
|
||||
|
||||
file = g_file_new_for_uri (root);
|
||||
rootfile = g_file_new_for_uri (root);
|
||||
vrootfile = g_file_new_for_uri (virtual_root);
|
||||
|
||||
if (remote || g_file_is_native (file))
|
||||
if (remote || g_file_is_native (rootfile))
|
||||
{
|
||||
if (virtual_root != NULL && *virtual_root != '\0')
|
||||
{
|
||||
prepare_auto_root (plugin);
|
||||
xed_file_browser_widget_set_root_and_virtual_root (priv->tree_widget, root, virtual_root);
|
||||
xed_file_browser_widget_set_root_and_virtual_root (priv->tree_widget, rootfile, vrootfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
prepare_auto_root (plugin);
|
||||
xed_file_browser_widget_set_root (priv->tree_widget, root, TRUE);
|
||||
xed_file_browser_widget_set_root (priv->tree_widget, rootfile, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
g_object_unref (rootfile);
|
||||
g_object_unref (vrootfile);
|
||||
}
|
||||
|
||||
g_free (root);
|
||||
@@ -317,16 +320,11 @@ set_root_from_doc (XedFileBrowserPlugin *plugin,
|
||||
|
||||
if (parent != NULL)
|
||||
{
|
||||
gchar * root;
|
||||
|
||||
root = g_file_get_uri (parent);
|
||||
|
||||
xed_file_browser_widget_set_root (priv->tree_widget,
|
||||
root,
|
||||
parent,
|
||||
TRUE);
|
||||
|
||||
g_object_unref (parent);
|
||||
g_free (root);
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
@@ -352,7 +350,6 @@ on_action_open_terminal (GtkAction *action,
|
||||
{
|
||||
XedFileBrowserPluginPrivate *priv = plugin->priv;
|
||||
gchar *terminal;
|
||||
gchar *wd = NULL;
|
||||
gchar *local;
|
||||
gchar *argv[2];
|
||||
GFile *file;
|
||||
@@ -367,18 +364,16 @@ on_action_open_terminal (GtkAction *action,
|
||||
}
|
||||
|
||||
store = xed_file_browser_widget_get_browser_store (priv->tree_widget);
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, XED_FILE_BROWSER_STORE_COLUMN_URI, &wd, -1);
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &file, -1);
|
||||
|
||||
if (wd == NULL)
|
||||
if (file == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
terminal = get_terminal (plugin);
|
||||
|
||||
file = g_file_new_for_uri (wd);
|
||||
local = g_file_get_path (file);
|
||||
g_object_unref (file);
|
||||
|
||||
argv[0] = terminal;
|
||||
argv[1] = NULL;
|
||||
@@ -393,7 +388,6 @@ on_action_open_terminal (GtkAction *action,
|
||||
NULL);
|
||||
|
||||
g_free (terminal);
|
||||
g_free (wd);
|
||||
g_free (local);
|
||||
}
|
||||
|
||||
@@ -406,7 +400,7 @@ on_selection_changed_cb (GtkTreeSelection *selection,
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
gboolean sensitive;
|
||||
gchar *uri;
|
||||
GFile *location;
|
||||
|
||||
tree_view = GTK_TREE_VIEW (xed_file_browser_widget_get_browser_view (priv->tree_widget));
|
||||
model = gtk_tree_view_get_model (tree_view);
|
||||
@@ -420,10 +414,9 @@ on_selection_changed_cb (GtkTreeSelection *selection,
|
||||
|
||||
if (sensitive)
|
||||
{
|
||||
gtk_tree_model_get (model, &iter, XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, -1);
|
||||
gtk_tree_model_get (model, &iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1);
|
||||
|
||||
sensitive = xed_utils_uri_has_file_scheme (uri);
|
||||
g_free (uri);
|
||||
sensitive = xed_utils_location_has_file_scheme (location);
|
||||
}
|
||||
|
||||
gtk_action_set_sensitive (gtk_action_group_get_action (priv->single_selection_action_group, "OpenTerminal"), sensitive);
|
||||
@@ -550,8 +543,8 @@ xed_file_browser_plugin_activate (XedWindowActivatable *activatable)
|
||||
priv->settings = g_settings_new (FILE_BROWSER_SCHEMA);
|
||||
priv->onload_settings = g_settings_new (FILE_BROWSER_ONLOAD_SCHEMA);
|
||||
|
||||
g_signal_connect (priv->tree_widget, "uri-activated",
|
||||
G_CALLBACK (on_uri_activated_cb), priv->window);
|
||||
g_signal_connect (priv->tree_widget, "location-activated",
|
||||
G_CALLBACK (on_location_activated_cb), priv->window);
|
||||
|
||||
g_signal_connect (priv->tree_widget, "error",
|
||||
G_CALLBACK (on_error_cb), plugin);
|
||||
@@ -652,11 +645,11 @@ xed_file_browser_plugin_class_finalize (XedFileBrowserPluginClass *klass)
|
||||
|
||||
/* Callbacks */
|
||||
static void
|
||||
on_uri_activated_cb (XedFileBrowserWidget *tree_widget,
|
||||
gchar const *uri,
|
||||
XedWindow *window)
|
||||
on_location_activated_cb (XedFileBrowserWidget *tree_widget,
|
||||
GFile *location,
|
||||
XedWindow *window)
|
||||
{
|
||||
xed_commands_load_uri (window, uri, NULL, 0);
|
||||
xed_commands_load_location (window, location, NULL, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -764,41 +757,33 @@ on_filter_mode_changed_cb (XedFileBrowserStore *model,
|
||||
|
||||
static void
|
||||
on_rename_cb (XedFileBrowserStore *store,
|
||||
const gchar *olduri,
|
||||
const gchar *newuri,
|
||||
XedWindow *window)
|
||||
GFile *oldfile,
|
||||
GFile *newfile,
|
||||
XedWindow *window)
|
||||
{
|
||||
XedApp *app;
|
||||
GList *documents;
|
||||
GList *item;
|
||||
XedDocument *doc;
|
||||
GFile *docfile;
|
||||
GFile *oldfile;
|
||||
GFile *newfile;
|
||||
gchar *uri;
|
||||
|
||||
/* Find all documents and set its uri to newuri where it matches olduri */
|
||||
app = xed_app_get_default ();
|
||||
documents = xed_app_get_documents (app);
|
||||
|
||||
oldfile = g_file_new_for_uri (olduri);
|
||||
newfile = g_file_new_for_uri (newuri);
|
||||
|
||||
for (item = documents; item; item = item->next)
|
||||
{
|
||||
doc = XED_DOCUMENT (item->data);
|
||||
uri = xed_document_get_uri (doc);
|
||||
docfile = xed_document_get_location (doc);
|
||||
|
||||
if (!uri)
|
||||
if (!docfile)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
docfile = g_file_new_for_uri (uri);
|
||||
|
||||
if (g_file_equal (docfile, oldfile))
|
||||
{
|
||||
xed_document_set_uri (doc, newuri);
|
||||
xed_document_set_location (doc, newfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -812,24 +797,18 @@ on_rename_cb (XedFileBrowserStore *store,
|
||||
the prefix oldfile */
|
||||
|
||||
g_object_unref (docfile);
|
||||
g_free (uri);
|
||||
|
||||
docfile = g_file_get_child (newfile, relative);
|
||||
uri = g_file_get_uri (docfile);
|
||||
|
||||
xed_document_set_uri (doc, uri);
|
||||
xed_document_set_location (doc, docfile);
|
||||
}
|
||||
|
||||
g_free (relative);
|
||||
}
|
||||
|
||||
g_free (uri);
|
||||
g_object_unref (docfile);
|
||||
}
|
||||
|
||||
g_object_unref (oldfile);
|
||||
g_object_unref (newfile);
|
||||
|
||||
g_list_free (documents);
|
||||
}
|
||||
|
||||
@@ -861,8 +840,9 @@ on_virtual_root_changed_cb (XedFileBrowserStore *store,
|
||||
XedFileBrowserPlugin *plugin)
|
||||
{
|
||||
XedFileBrowserPluginPrivate *priv = plugin->priv;
|
||||
gchar * root;
|
||||
gchar * virtual_root;
|
||||
GFile *root;
|
||||
GFile *virtual_root;
|
||||
gchar *uri_root = NULL;
|
||||
|
||||
root = xed_file_browser_store_get_root (store);
|
||||
|
||||
@@ -870,25 +850,35 @@ on_virtual_root_changed_cb (XedFileBrowserStore *store,
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
uri_root = g_file_get_uri (root);
|
||||
g_object_unref (root);
|
||||
}
|
||||
|
||||
g_settings_set_string (priv->onload_settings, "root", root);
|
||||
g_settings_set_string (priv->onload_settings, "root", uri_root);
|
||||
g_free (uri_root);
|
||||
|
||||
virtual_root = xed_file_browser_store_get_virtual_root (store);
|
||||
|
||||
if (!virtual_root)
|
||||
{
|
||||
/* Set virtual to same as root then */
|
||||
g_settings_set_string (priv->onload_settings, "virtual-root", root);
|
||||
g_settings_set_string (priv->onload_settings, "virtual-root", uri_root);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_settings_set_string (priv->onload_settings, "virtual-root", virtual_root);
|
||||
gchar *uri_vroot;
|
||||
|
||||
uri_vroot = g_file_get_uri (virtual_root);
|
||||
|
||||
g_settings_set_string (priv->onload_settings, "virtual-root", uri_vroot);
|
||||
|
||||
g_free (uri_vroot);
|
||||
g_object_unref (virtual_root);
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (XED_WINDOW (priv->window), G_CALLBACK (on_tab_added_cb), plugin);
|
||||
|
||||
g_free (root);
|
||||
g_free (virtual_root);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -905,23 +895,27 @@ on_tab_added_cb (XedWindow *window,
|
||||
if (open)
|
||||
{
|
||||
XedDocument *doc;
|
||||
gchar *uri;
|
||||
GFile *location;
|
||||
|
||||
doc = xed_tab_get_document (tab);
|
||||
uri = xed_document_get_uri (doc);
|
||||
location = xed_document_get_location (doc);
|
||||
|
||||
if (uri != NULL && xed_utils_uri_has_file_scheme (uri))
|
||||
if (location != NULL)
|
||||
{
|
||||
prepare_auto_root (plugin);
|
||||
set_root_from_doc (plugin, doc);
|
||||
load_default = FALSE;
|
||||
if (xed_utils_location_has_file_scheme (location))
|
||||
{
|
||||
prepare_auto_root (plugin);
|
||||
set_root_from_doc (plugin, doc);
|
||||
load_default = FALSE;
|
||||
}
|
||||
g_object_unref (location);
|
||||
}
|
||||
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
if (load_default)
|
||||
{
|
||||
restore_default_location (plugin);
|
||||
}
|
||||
|
||||
/* Disconnect this signal, it's only called once */
|
||||
g_signal_handlers_disconnect_by_func (window, G_CALLBACK (on_tab_added_cb), plugin);
|
||||
@@ -932,12 +926,12 @@ get_filename_from_path (GtkTreeModel *model,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gchar *uri;
|
||||
GFile *location;
|
||||
|
||||
gtk_tree_model_get_iter (model, &iter, path);
|
||||
gtk_tree_model_get (model, &iter, XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, -1);
|
||||
gtk_tree_model_get (model, &iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1);
|
||||
|
||||
return xed_file_browser_utils_uri_basename (uri);
|
||||
return xed_file_browser_utils_file_basename (location);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@@ -81,7 +81,7 @@ struct _AsyncNode
|
||||
|
||||
typedef struct {
|
||||
XedFileBrowserStore *model;
|
||||
gchar *virtual_root;
|
||||
GFile *virtual_root;
|
||||
GMountOperation *operation;
|
||||
GCancellable *cancellable;
|
||||
} MountInfo;
|
||||
@@ -267,16 +267,13 @@ static void
|
||||
set_gvalue_from_node (GValue *value,
|
||||
FileBrowserNode *node)
|
||||
{
|
||||
gchar * uri;
|
||||
|
||||
if (node == NULL || !node->file)
|
||||
if (node == NULL)
|
||||
{
|
||||
g_value_set_string (value, NULL);
|
||||
g_value_set_object (value, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
uri = g_file_get_uri (node->file);
|
||||
g_value_take_string (value, uri);
|
||||
g_value_set_object (value, node->file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,17 +332,17 @@ xed_file_browser_store_class_init (XedFileBrowserStoreClass * klass)
|
||||
object_class->set_property = xed_file_browser_store_set_property;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ROOT,
|
||||
g_param_spec_string ("root",
|
||||
g_param_spec_object ("root",
|
||||
"Root",
|
||||
"The root uri",
|
||||
NULL,
|
||||
"The root location",
|
||||
G_TYPE_FILE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_VIRTUAL_ROOT,
|
||||
g_param_spec_string ("virtual-root",
|
||||
g_param_spec_object ("virtual-root",
|
||||
"Virtual Root",
|
||||
"The virtual root uri",
|
||||
NULL,
|
||||
"The virtual root location",
|
||||
G_TYPE_FILE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_FILTER_MODE,
|
||||
@@ -394,10 +391,10 @@ xed_file_browser_store_class_init (XedFileBrowserStoreClass * klass)
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (XedFileBrowserStoreClass,
|
||||
rename), NULL, NULL,
|
||||
xed_file_browser_marshal_VOID__STRING_STRING,
|
||||
xed_file_browser_marshal_VOID__OBJECT_OBJECT,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING);
|
||||
G_TYPE_FILE,
|
||||
G_TYPE_FILE);
|
||||
model_signals[BEGIN_REFRESH] =
|
||||
g_signal_new ("begin-refresh",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
@@ -420,9 +417,9 @@ xed_file_browser_store_class_init (XedFileBrowserStoreClass * klass)
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (XedFileBrowserStoreClass,
|
||||
unload), NULL, NULL,
|
||||
g_cclosure_marshal_VOID__STRING,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_STRING);
|
||||
G_TYPE_FILE);
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (XedFileBrowserStorePrivate));
|
||||
}
|
||||
@@ -464,7 +461,7 @@ xed_file_browser_store_init (XedFileBrowserStore * obj)
|
||||
{
|
||||
obj->priv = XED_FILE_BROWSER_STORE_GET_PRIVATE (obj);
|
||||
|
||||
obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_URI] = G_TYPE_STRING;
|
||||
obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_LOCATION] = G_TYPE_FILE;
|
||||
obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_NAME] = G_TYPE_STRING;
|
||||
obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_FLAGS] = G_TYPE_UINT;
|
||||
obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_ICON] = GDK_TYPE_PIXBUF;
|
||||
@@ -713,7 +710,7 @@ xed_file_browser_store_get_value (GtkTreeModel *tree_model,
|
||||
|
||||
switch (column)
|
||||
{
|
||||
case XED_FILE_BROWSER_STORE_COLUMN_URI:
|
||||
case XED_FILE_BROWSER_STORE_COLUMN_LOCATION:
|
||||
set_gvalue_from_node (value, node);
|
||||
break;
|
||||
case XED_FILE_BROWSER_STORE_COLUMN_NAME:
|
||||
@@ -1013,7 +1010,7 @@ xed_file_browser_store_drag_data_get (GtkTreeDragSource *drag_source,
|
||||
GtkSelectionData *selection_data)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gchar *uri;
|
||||
GFile *location;
|
||||
gchar *uris[2] = {0, };
|
||||
gboolean ret;
|
||||
|
||||
@@ -1022,14 +1019,14 @@ xed_file_browser_store_drag_data_get (GtkTreeDragSource *drag_source,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter, XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, -1);
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1);
|
||||
|
||||
g_assert (uri);
|
||||
g_assert (location);
|
||||
|
||||
uris[0] = uri;
|
||||
uris[0] = g_file_get_uri (location);
|
||||
ret = gtk_selection_data_set_uris (selection_data, uris);
|
||||
|
||||
g_free (uri);
|
||||
g_free (uris[0]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1448,8 +1445,6 @@ static void
|
||||
file_browser_node_free (XedFileBrowserStore *model,
|
||||
FileBrowserNode *node)
|
||||
{
|
||||
gchar *uri;
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
return;
|
||||
@@ -1485,10 +1480,7 @@ file_browser_node_free (XedFileBrowserStore *model,
|
||||
|
||||
if (node->file)
|
||||
{
|
||||
uri = g_file_get_uri (node->file);
|
||||
g_signal_emit (model, model_signals[UNLOAD], 0, uri);
|
||||
|
||||
g_free (uri);
|
||||
g_signal_emit (model, model_signals[UNLOAD], 0, node->file);
|
||||
g_object_unref (node->file);
|
||||
}
|
||||
|
||||
@@ -2940,14 +2932,14 @@ unique_new_name (GFile *directory,
|
||||
|
||||
static XedFileBrowserStoreResult
|
||||
model_root_mounted (XedFileBrowserStore *model,
|
||||
gchar const *virtual_root)
|
||||
GFile *virtual_root)
|
||||
{
|
||||
model_check_dummy (model, model->priv->root);
|
||||
g_object_notify (G_OBJECT (model), "root");
|
||||
|
||||
if (virtual_root != NULL)
|
||||
{
|
||||
return xed_file_browser_store_set_virtual_root_from_string (model, virtual_root);
|
||||
return xed_file_browser_store_set_virtual_root_from_location (model, virtual_root);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3028,7 +3020,7 @@ mount_cb (GFile *file,
|
||||
|
||||
static XedFileBrowserStoreResult
|
||||
model_mount_root (XedFileBrowserStore *model,
|
||||
gchar const *virtual_root)
|
||||
GFile *virtual_root)
|
||||
{
|
||||
GFileInfo *info;
|
||||
GError *error = NULL;
|
||||
@@ -3049,7 +3041,7 @@ model_mount_root (XedFileBrowserStore *model,
|
||||
|
||||
mount_info = g_new(MountInfo, 1);
|
||||
mount_info->model = model;
|
||||
mount_info->virtual_root = g_strdup (virtual_root);
|
||||
mount_info->virtual_root = g_file_dup (virtual_root);
|
||||
|
||||
/* FIXME: we should be setting the correct window */
|
||||
mount_info->operation = gtk_mount_operation_new (NULL);
|
||||
@@ -3085,7 +3077,7 @@ model_mount_root (XedFileBrowserStore *model,
|
||||
|
||||
/* Public */
|
||||
XedFileBrowserStore *
|
||||
xed_file_browser_store_new (gchar const *root)
|
||||
xed_file_browser_store_new (GFile *root)
|
||||
{
|
||||
XedFileBrowserStore *obj = XED_FILE_BROWSER_STORE (g_object_new (XED_TYPE_FILE_BROWSER_STORE, NULL));
|
||||
|
||||
@@ -3156,56 +3148,52 @@ xed_file_browser_store_set_virtual_root (XedFileBrowserStore *model,
|
||||
}
|
||||
|
||||
XedFileBrowserStoreResult
|
||||
xed_file_browser_store_set_virtual_root_from_string (XedFileBrowserStore *model,
|
||||
gchar const *root)
|
||||
xed_file_browser_store_set_virtual_root_from_location (XedFileBrowserStore *model,
|
||||
GFile *root)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE);
|
||||
|
||||
file = g_file_new_for_uri (root);
|
||||
if (file == NULL)
|
||||
if (root == NULL)
|
||||
{
|
||||
g_warning ("Invalid uri (%s)", root);
|
||||
gchar *uri;
|
||||
|
||||
uri = g_file_get_uri (root);
|
||||
g_warning ("Invalid uri (%s)", uri);
|
||||
g_free (uri);
|
||||
return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE;
|
||||
}
|
||||
|
||||
/* Check if uri is already the virtual root */
|
||||
if (model->priv->virtual_root && g_file_equal (model->priv->virtual_root->file, file))
|
||||
if (model->priv->virtual_root && g_file_equal (model->priv->virtual_root->file, root))
|
||||
{
|
||||
g_object_unref (file);
|
||||
return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE;
|
||||
}
|
||||
|
||||
/* Check if uri is the root itself */
|
||||
if (g_file_equal (model->priv->root->file, file))
|
||||
if (g_file_equal (model->priv->root->file, root))
|
||||
{
|
||||
g_object_unref (file);
|
||||
|
||||
/* Always clear the model before altering the nodes */
|
||||
model_clear (model, FALSE);
|
||||
set_virtual_root_from_node (model, model->priv->root);
|
||||
return XED_FILE_BROWSER_STORE_RESULT_OK;
|
||||
}
|
||||
|
||||
if (!g_file_has_prefix (file, model->priv->root->file))
|
||||
if (!g_file_has_prefix (root, model->priv->root->file))
|
||||
{
|
||||
gchar *str, *str1;
|
||||
|
||||
str = g_file_get_parse_name (model->priv->root->file);
|
||||
str1 = g_file_get_parse_name (file);
|
||||
str1 = g_file_get_parse_name (root);
|
||||
|
||||
g_warning ("Virtual root (%s) is not below actual root (%s)", str1, str);
|
||||
|
||||
g_free (str);
|
||||
g_free (str1);
|
||||
|
||||
g_object_unref (file);
|
||||
return XED_FILE_BROWSER_STORE_RESULT_ERROR;
|
||||
}
|
||||
|
||||
set_virtual_root_from_file (model, file);
|
||||
g_object_unref (file);
|
||||
set_virtual_root_from_file (model, root);
|
||||
|
||||
return XED_FILE_BROWSER_STORE_RESULT_OK;
|
||||
}
|
||||
@@ -3298,11 +3286,9 @@ xed_file_browser_store_cancel_mount_operation (XedFileBrowserStore *store)
|
||||
|
||||
XedFileBrowserStoreResult
|
||||
xed_file_browser_store_set_root_and_virtual_root (XedFileBrowserStore *model,
|
||||
gchar const *root,
|
||||
gchar const *virtual_root)
|
||||
GFile *root,
|
||||
GFile *virtual_root)
|
||||
{
|
||||
GFile * file = NULL;
|
||||
GFile * vfile = NULL;
|
||||
FileBrowserNode * node;
|
||||
gboolean equal = FALSE;
|
||||
|
||||
@@ -3313,38 +3299,22 @@ xed_file_browser_store_set_root_and_virtual_root (XedFileBrowserStore *model,
|
||||
return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE;
|
||||
}
|
||||
|
||||
if (root != NULL)
|
||||
{
|
||||
file = g_file_new_for_uri (root);
|
||||
}
|
||||
|
||||
if (root != NULL && model->priv->root != NULL)
|
||||
{
|
||||
equal = g_file_equal (file, model->priv->root->file);
|
||||
equal = g_file_equal (root, model->priv->root->file);
|
||||
|
||||
if (equal && virtual_root == NULL)
|
||||
{
|
||||
g_object_unref (file);
|
||||
return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
if (virtual_root)
|
||||
{
|
||||
vfile = g_file_new_for_uri (virtual_root);
|
||||
|
||||
if (equal && g_file_equal (vfile, model->priv->virtual_root->file))
|
||||
if (equal && g_file_equal (virtual_root, model->priv->virtual_root->file))
|
||||
{
|
||||
if (file)
|
||||
{
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
g_object_unref (vfile);
|
||||
return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE;
|
||||
}
|
||||
|
||||
g_object_unref (vfile);
|
||||
}
|
||||
|
||||
/* make sure to cancel any previous mount operations */
|
||||
@@ -3357,12 +3327,10 @@ xed_file_browser_store_set_root_and_virtual_root (XedFileBrowserStore *model,
|
||||
model->priv->root = NULL;
|
||||
model->priv->virtual_root = NULL;
|
||||
|
||||
if (file != NULL)
|
||||
if (root != NULL)
|
||||
{
|
||||
/* Create the root node */
|
||||
node = file_browser_node_dir_new (model, file, NULL);
|
||||
|
||||
g_object_unref (file);
|
||||
node = file_browser_node_dir_new (model, root, NULL);
|
||||
|
||||
model->priv->root = node;
|
||||
return model_mount_root (model, virtual_root);
|
||||
@@ -3378,13 +3346,13 @@ xed_file_browser_store_set_root_and_virtual_root (XedFileBrowserStore *model,
|
||||
|
||||
XedFileBrowserStoreResult
|
||||
xed_file_browser_store_set_root (XedFileBrowserStore *model,
|
||||
gchar const *root)
|
||||
GFile *root)
|
||||
{
|
||||
g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE);
|
||||
return xed_file_browser_store_set_root_and_virtual_root (model, root, NULL);
|
||||
}
|
||||
|
||||
gchar *
|
||||
GFile *
|
||||
xed_file_browser_store_get_root (XedFileBrowserStore * model)
|
||||
{
|
||||
g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), NULL);
|
||||
@@ -3395,11 +3363,11 @@ xed_file_browser_store_get_root (XedFileBrowserStore * model)
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_file_get_uri (model->priv->root->file);
|
||||
return g_file_dup (model->priv->root->file);
|
||||
}
|
||||
}
|
||||
|
||||
gchar *
|
||||
GFile *
|
||||
xed_file_browser_store_get_virtual_root (XedFileBrowserStore *model)
|
||||
{
|
||||
g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), NULL);
|
||||
@@ -3410,7 +3378,7 @@ xed_file_browser_store_get_virtual_root (XedFileBrowserStore *model)
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_file_get_uri (model->priv->virtual_root->file);
|
||||
return g_file_dup (model->priv->virtual_root->file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3573,8 +3541,6 @@ xed_file_browser_store_rename (XedFileBrowserStore *model,
|
||||
GFile *parent;
|
||||
GFile *previous;
|
||||
GError *err = NULL;
|
||||
gchar *olduri;
|
||||
gchar *newuri;
|
||||
GtkTreePath *path;
|
||||
|
||||
g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE);
|
||||
@@ -3628,14 +3594,9 @@ xed_file_browser_store_rename (XedFileBrowserStore *model,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
olduri = g_file_get_uri (previous);
|
||||
newuri = g_file_get_uri (node->file);
|
||||
|
||||
g_signal_emit (model, model_signals[RENAME], 0, olduri, newuri);
|
||||
g_signal_emit (model, model_signals[RENAME], 0, previous, node->file);
|
||||
|
||||
g_object_unref (previous);
|
||||
g_free (olduri);
|
||||
g_free (newuri);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ typedef enum
|
||||
{
|
||||
XED_FILE_BROWSER_STORE_COLUMN_ICON = 0,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_NAME,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_URI,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_LOCATION,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_FLAGS,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_EMBLEM,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_NUM
|
||||
@@ -106,28 +106,28 @@ struct _XedFileBrowserStoreClass {
|
||||
gboolean (*no_trash) (XedFileBrowserStore *model,
|
||||
GList *files);
|
||||
void (*rename) (XedFileBrowserStore *model,
|
||||
const gchar *olduri,
|
||||
const gchar *newuri);
|
||||
GFile *oldfile,
|
||||
GFile *newfile);
|
||||
void (*begin_refresh) (XedFileBrowserStore *model);
|
||||
void (*end_refresh) (XedFileBrowserStore *model);
|
||||
void (*unload) (XedFileBrowserStore *model,
|
||||
const gchar *uri);
|
||||
GFile *location);
|
||||
};
|
||||
|
||||
GType xed_file_browser_store_get_type (void) G_GNUC_CONST;
|
||||
void _xed_file_browser_store_register_type (GTypeModule *type_module);
|
||||
|
||||
XedFileBrowserStore *xed_file_browser_store_new (gchar const *root);
|
||||
XedFileBrowserStore *xed_file_browser_store_new (GFile *root);
|
||||
|
||||
XedFileBrowserStoreResult xed_file_browser_store_set_root_and_virtual_root (XedFileBrowserStore *model,
|
||||
gchar const *root,
|
||||
gchar const *virtual_root);
|
||||
GFile *root,
|
||||
GFile *virtual_root);
|
||||
XedFileBrowserStoreResult xed_file_browser_store_set_root (XedFileBrowserStore *model,
|
||||
gchar const *root);
|
||||
GFile *root);
|
||||
XedFileBrowserStoreResult xed_file_browser_store_set_virtual_root (XedFileBrowserStore *model,
|
||||
GtkTreeIter *iter);
|
||||
XedFileBrowserStoreResult xed_file_browser_store_set_virtual_root_from_string (XedFileBrowserStore *model,
|
||||
gchar const *root);
|
||||
XedFileBrowserStoreResult xed_file_browser_store_set_virtual_root_from_location (XedFileBrowserStore *model,
|
||||
GFile *root);
|
||||
XedFileBrowserStoreResult xed_file_browser_store_set_virtual_root_up (XedFileBrowserStore *model);
|
||||
XedFileBrowserStoreResult xed_file_browser_store_set_virtual_root_top (XedFileBrowserStore *model);
|
||||
|
||||
@@ -135,8 +135,8 @@ gboolean xed_file_browser_store_get_iter_virtual_root (XedFileBrowserStore *mode
|
||||
GtkTreeIter *iter);
|
||||
gboolean xed_file_browser_store_get_iter_root (XedFileBrowserStore *model,
|
||||
GtkTreeIter *iter);
|
||||
gchar * xed_file_browser_store_get_root (XedFileBrowserStore *model);
|
||||
gchar * xed_file_browser_store_get_virtual_root (XedFileBrowserStore *model);
|
||||
GFile * xed_file_browser_store_get_root (XedFileBrowserStore *model);
|
||||
GFile * xed_file_browser_store_get_virtual_root (XedFileBrowserStore *model);
|
||||
|
||||
gboolean xed_file_browser_store_iter_equal (XedFileBrowserStore *model,
|
||||
GtkTreeIter *iter1,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* xed-file-bookmarks-store.c - Xed plugin providing easy file access
|
||||
* xed-file-bookmarks-store.c - Xed plugin providing easy file access
|
||||
* from the sidepanel
|
||||
*
|
||||
* Copyright (C) 2006 - Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
static GdkPixbuf *
|
||||
process_icon_pixbuf (GdkPixbuf * pixbuf,
|
||||
gchar const * name,
|
||||
gint size,
|
||||
gchar const * name,
|
||||
gint size,
|
||||
GError * error)
|
||||
{
|
||||
GdkPixbuf * scale;
|
||||
@@ -36,11 +36,11 @@ process_icon_pixbuf (GdkPixbuf * pixbuf,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
|
||||
if (pixbuf && gdk_pixbuf_get_width (pixbuf) > size) {
|
||||
scale = gdk_pixbuf_scale_simple (pixbuf,
|
||||
size,
|
||||
size,
|
||||
scale = gdk_pixbuf_scale_simple (pixbuf,
|
||||
size,
|
||||
size,
|
||||
GDK_INTERP_BILINEAR);
|
||||
g_object_unref (pixbuf);
|
||||
pixbuf = scale;
|
||||
@@ -59,10 +59,10 @@ xed_file_browser_utils_pixbuf_from_theme (gchar const * name,
|
||||
|
||||
gtk_icon_size_lookup (size, &width, NULL);
|
||||
|
||||
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
|
||||
name,
|
||||
width,
|
||||
0,
|
||||
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
|
||||
name,
|
||||
width,
|
||||
0,
|
||||
&error);
|
||||
|
||||
pixbuf = process_icon_pixbuf (pixbuf, name, width, error);
|
||||
@@ -84,7 +84,7 @@ xed_file_browser_utils_pixbuf_from_icon (GIcon * icon,
|
||||
|
||||
theme = gtk_icon_theme_get_default ();
|
||||
gtk_icon_size_lookup (size, &width, NULL);
|
||||
|
||||
|
||||
info = gtk_icon_theme_lookup_by_gicon (theme,
|
||||
icon,
|
||||
width,
|
||||
@@ -92,10 +92,10 @@ xed_file_browser_utils_pixbuf_from_icon (GIcon * icon,
|
||||
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
|
||||
ret = gtk_icon_info_load_icon (info, NULL);
|
||||
gtk_icon_info_free (info);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -107,12 +107,12 @@ xed_file_browser_utils_pixbuf_from_file (GFile * file,
|
||||
GFileInfo * info;
|
||||
GdkPixbuf * ret = NULL;
|
||||
|
||||
info = g_file_query_info (file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_ICON,
|
||||
info = g_file_query_info (file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_ICON,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
@@ -121,35 +121,22 @@ xed_file_browser_utils_pixbuf_from_file (GFile * file,
|
||||
ret = xed_file_browser_utils_pixbuf_from_icon (icon, size);
|
||||
|
||||
g_object_unref (info);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar *
|
||||
xed_file_browser_utils_file_basename (GFile * file)
|
||||
{
|
||||
gchar *uri;
|
||||
gchar *ret;
|
||||
|
||||
uri = g_file_get_uri (file);
|
||||
ret = xed_file_browser_utils_uri_basename (uri);
|
||||
g_free (uri);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar *
|
||||
xed_file_browser_utils_uri_basename (gchar const * uri)
|
||||
{
|
||||
return xed_utils_basename_for_display (uri);
|
||||
return xed_utils_basename_for_display (file);
|
||||
}
|
||||
|
||||
gboolean
|
||||
xed_file_browser_utils_confirmation_dialog (XedWindow * window,
|
||||
GtkMessageType type,
|
||||
gchar const *message,
|
||||
gchar const *secondary,
|
||||
gchar const * button_stock,
|
||||
gchar const *secondary,
|
||||
gchar const * button_stock,
|
||||
gchar const * button_label)
|
||||
{
|
||||
GtkWidget *dlg;
|
||||
@@ -177,18 +164,18 @@ xed_file_browser_utils_confirmation_dialog (XedWindow * window,
|
||||
|
||||
/* Add custom button */
|
||||
button = gtk_button_new_from_stock (button_stock);
|
||||
|
||||
|
||||
if (button_label) {
|
||||
gtk_button_set_use_stock (GTK_BUTTON (button), FALSE);
|
||||
gtk_button_set_label (GTK_BUTTON (button), button_label);
|
||||
}
|
||||
|
||||
|
||||
gtk_widget_show (button);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_dialog_add_action_widget (GTK_DIALOG (dlg),
|
||||
button,
|
||||
GTK_RESPONSE_OK);
|
||||
|
||||
|
||||
ret = gtk_dialog_run (GTK_DIALOG (dlg));
|
||||
gtk_widget_destroy (dlg);
|
||||
|
||||
|
@@ -13,13 +13,12 @@ GdkPixbuf *xed_file_browser_utils_pixbuf_from_file (GFile * file,
|
||||
GtkIconSize size);
|
||||
|
||||
gchar * xed_file_browser_utils_file_basename (GFile * file);
|
||||
gchar * xed_file_browser_utils_uri_basename (gchar const * uri);
|
||||
|
||||
gboolean xed_file_browser_utils_confirmation_dialog (XedWindow * window,
|
||||
GtkMessageType type,
|
||||
gchar const *message,
|
||||
gchar const *secondary,
|
||||
gchar const * button_stock,
|
||||
gchar const *secondary,
|
||||
gchar const * button_stock,
|
||||
gchar const * button_label);
|
||||
|
||||
#endif /* __XED_FILE_BROWSER_UTILS_H__ */
|
||||
|
@@ -99,7 +99,7 @@ static void on_end_refresh (XedFileBrowserStore *model,
|
||||
XedFileBrowserView *view);
|
||||
|
||||
static void on_unload (XedFileBrowserStore *model,
|
||||
gchar const *uri,
|
||||
GFile *location,
|
||||
XedFileBrowserView *view);
|
||||
|
||||
static void on_row_inserted (XedFileBrowserStore *model,
|
||||
@@ -135,46 +135,32 @@ xed_file_browser_view_finalize (GObject *object)
|
||||
|
||||
static void
|
||||
add_expand_state (XedFileBrowserView *view,
|
||||
gchar const *uri)
|
||||
GFile *location)
|
||||
{
|
||||
GFile * file;
|
||||
|
||||
if (!uri)
|
||||
if (!location)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
|
||||
if (view->priv->expand_state)
|
||||
{
|
||||
g_hash_table_insert (view->priv->expand_state, file, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_unref (file);
|
||||
g_hash_table_insert (view->priv->expand_state, location, g_object_ref (location));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
remove_expand_state (XedFileBrowserView *view,
|
||||
gchar const *uri)
|
||||
GFile *location)
|
||||
{
|
||||
GFile * file;
|
||||
|
||||
if (!uri)
|
||||
if (!location)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
|
||||
if (view->priv->expand_state)
|
||||
{
|
||||
g_hash_table_remove (view->priv->expand_state, file);
|
||||
g_hash_table_remove (view->priv->expand_state, location);
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -183,7 +169,7 @@ row_expanded (GtkTreeView *tree_view,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (tree_view);
|
||||
gchar *uri;
|
||||
GFile *location;
|
||||
|
||||
if (GTK_TREE_VIEW_CLASS (xed_file_browser_view_parent_class)->row_expanded)
|
||||
{
|
||||
@@ -197,10 +183,9 @@ row_expanded (GtkTreeView *tree_view,
|
||||
|
||||
if (view->priv->restore_expand_state)
|
||||
{
|
||||
gtk_tree_model_get (view->priv->model, iter, XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, -1);
|
||||
gtk_tree_model_get (view->priv->model, iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1);
|
||||
|
||||
add_expand_state (view, uri);
|
||||
g_free (uri);
|
||||
add_expand_state (view, location);
|
||||
}
|
||||
|
||||
_xed_file_browser_store_iter_expanded (XED_FILE_BROWSER_STORE (view->priv->model), iter);
|
||||
@@ -212,7 +197,7 @@ row_collapsed (GtkTreeView *tree_view,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (tree_view);
|
||||
gchar * uri;
|
||||
GFile *location;
|
||||
|
||||
if (GTK_TREE_VIEW_CLASS (xed_file_browser_view_parent_class)->row_collapsed)
|
||||
{
|
||||
@@ -226,10 +211,9 @@ row_collapsed (GtkTreeView *tree_view,
|
||||
|
||||
if (view->priv->restore_expand_state)
|
||||
{
|
||||
gtk_tree_model_get (view->priv->model, iter, XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, -1);
|
||||
gtk_tree_model_get (view->priv->model, iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1);
|
||||
|
||||
remove_expand_state (view, uri);
|
||||
g_free (uri);
|
||||
remove_expand_state (view, location);
|
||||
}
|
||||
|
||||
_xed_file_browser_store_iter_collapsed (XED_FILE_BROWSER_STORE (view->priv->model), iter);
|
||||
@@ -766,7 +750,7 @@ fill_expand_state (XedFileBrowserView *view,
|
||||
{
|
||||
GtkTreePath * path;
|
||||
GtkTreeIter child;
|
||||
gchar * uri;
|
||||
GFile *location;
|
||||
|
||||
if (!gtk_tree_model_iter_has_child (view->priv->model, iter))
|
||||
{
|
||||
@@ -779,12 +763,11 @@ fill_expand_state (XedFileBrowserView *view,
|
||||
{
|
||||
gtk_tree_model_get (view->priv->model,
|
||||
iter,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_URI,
|
||||
&uri,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_LOCATION,
|
||||
&location,
|
||||
-1);
|
||||
|
||||
add_expand_state (view, uri);
|
||||
g_free (uri);
|
||||
add_expand_state (view, location);
|
||||
}
|
||||
|
||||
if (gtk_tree_model_iter_children (view->priv->model, &child, iter))
|
||||
@@ -1273,7 +1256,7 @@ on_end_refresh (XedFileBrowserStore *model,
|
||||
|
||||
static void
|
||||
on_unload (XedFileBrowserStore *model,
|
||||
gchar const *uri,
|
||||
GFile *location,
|
||||
XedFileBrowserView *view)
|
||||
{
|
||||
/* Don't remove the expand state if we are refreshing */
|
||||
@@ -1282,7 +1265,7 @@ on_unload (XedFileBrowserStore *model,
|
||||
return;
|
||||
}
|
||||
|
||||
remove_expand_state (view, uri);
|
||||
remove_expand_state (view, location);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1290,33 +1273,28 @@ restore_expand_state (XedFileBrowserView *view,
|
||||
XedFileBrowserStore *model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gchar *uri;
|
||||
GFile *file;
|
||||
GFile *location;
|
||||
GtkTreePath *path;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (model),
|
||||
iter,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_URI,
|
||||
&uri,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_LOCATION,
|
||||
&location,
|
||||
-1);
|
||||
|
||||
if (!uri)
|
||||
if (!location)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
|
||||
|
||||
if (g_hash_table_lookup (view->priv->expand_state, file))
|
||||
if (g_hash_table_lookup (view->priv->expand_state, location))
|
||||
{
|
||||
gtk_tree_view_expand_row (GTK_TREE_VIEW (view), path, FALSE);
|
||||
}
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
g_object_unref (file);
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -80,7 +80,7 @@ enum
|
||||
/* Signals */
|
||||
enum
|
||||
{
|
||||
URI_ACTIVATED,
|
||||
LOCATION_ACTIVATED,
|
||||
ERROR,
|
||||
CONFIRM_DELETE,
|
||||
CONFIRM_NO_TRASH,
|
||||
@@ -433,14 +433,14 @@ xed_file_browser_widget_class_init (XedFileBrowserWidgetClass * klass)
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
|
||||
signals[URI_ACTIVATED] =
|
||||
g_signal_new ("uri-activated",
|
||||
signals[LOCATION_ACTIVATED] =
|
||||
g_signal_new ("location-activated",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (XedFileBrowserWidgetClass,
|
||||
uri_activated), NULL, NULL,
|
||||
g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1,
|
||||
G_TYPE_STRING);
|
||||
location_activated), NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
|
||||
G_TYPE_FILE);
|
||||
signals[ERROR] =
|
||||
g_signal_new ("error", G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
@@ -1060,22 +1060,18 @@ add_bookmark_hash (XedFileBrowserWidget * obj,
|
||||
GtkTreeModel *model;
|
||||
GdkPixbuf * pixbuf;
|
||||
gchar * name;
|
||||
gchar * uri;
|
||||
GFile * file;
|
||||
GFile * location;
|
||||
NameIcon * item;
|
||||
|
||||
model = GTK_TREE_MODEL (obj->priv->bookmarks_store);
|
||||
|
||||
uri = xed_file_bookmarks_store_get_uri (obj->priv->
|
||||
location = xed_file_bookmarks_store_get_location (obj->priv->
|
||||
bookmarks_store,
|
||||
iter);
|
||||
|
||||
if (uri == NULL)
|
||||
if (location == NULL)
|
||||
return;
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
g_free (uri);
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
XED_FILE_BOOKMARKS_STORE_COLUMN_ICON,
|
||||
&pixbuf,
|
||||
@@ -1087,7 +1083,7 @@ add_bookmark_hash (XedFileBrowserWidget * obj,
|
||||
item->icon = pixbuf;
|
||||
|
||||
g_hash_table_insert (obj->priv->bookmarks_hash,
|
||||
file,
|
||||
location,
|
||||
item);
|
||||
}
|
||||
|
||||
@@ -1581,8 +1577,6 @@ jump_to_location (XedFileBrowserWidget * obj, GList * item,
|
||||
GList *(*iter_func) (GList *);
|
||||
GtkWidget *menu_from;
|
||||
GtkWidget *menu_to;
|
||||
gchar *root;
|
||||
gchar *virtual_root;
|
||||
|
||||
if (!obj->priv->locations)
|
||||
return;
|
||||
@@ -1643,15 +1637,9 @@ jump_to_location (XedFileBrowserWidget * obj, GList * item,
|
||||
loc = (Location *) (obj->priv->current_location->data);
|
||||
|
||||
/* Set the new root + virtual root */
|
||||
root = g_file_get_uri (loc->root);
|
||||
virtual_root = g_file_get_uri (loc->virtual_root);
|
||||
|
||||
xed_file_browser_widget_set_root_and_virtual_root (obj,
|
||||
root,
|
||||
virtual_root);
|
||||
|
||||
g_free (root);
|
||||
g_free (virtual_root);
|
||||
loc->root,
|
||||
loc->virtual_root);
|
||||
|
||||
obj->priv->changing_location = FALSE;
|
||||
}
|
||||
@@ -1840,8 +1828,8 @@ xed_file_browser_widget_show_files (XedFileBrowserWidget * obj)
|
||||
|
||||
void
|
||||
xed_file_browser_widget_set_root_and_virtual_root (XedFileBrowserWidget *obj,
|
||||
gchar const *root,
|
||||
gchar const *virtual_root)
|
||||
GFile *root,
|
||||
GFile *virtual_root)
|
||||
{
|
||||
XedFileBrowserStoreResult result;
|
||||
|
||||
@@ -1860,12 +1848,10 @@ xed_file_browser_widget_set_root_and_virtual_root (XedFileBrowserWidget *obj,
|
||||
|
||||
void
|
||||
xed_file_browser_widget_set_root (XedFileBrowserWidget * obj,
|
||||
gchar const *root,
|
||||
GFile *root,
|
||||
gboolean virtual_root)
|
||||
{
|
||||
GFile *file;
|
||||
GFile *parent;
|
||||
gchar *str;
|
||||
|
||||
if (!virtual_root) {
|
||||
xed_file_browser_widget_set_root_and_virtual_root (obj,
|
||||
@@ -1877,16 +1863,11 @@ xed_file_browser_widget_set_root (XedFileBrowserWidget * obj,
|
||||
if (!root)
|
||||
return;
|
||||
|
||||
file = g_file_new_for_uri (root);
|
||||
parent = get_topmost_file (file);
|
||||
str = g_file_get_uri (parent);
|
||||
parent = get_topmost_file (root);
|
||||
|
||||
xed_file_browser_widget_set_root_and_virtual_root
|
||||
(obj, str, root);
|
||||
(obj, parent, root);
|
||||
|
||||
g_free (str);
|
||||
|
||||
g_object_unref (file);
|
||||
g_object_unref (parent);
|
||||
}
|
||||
|
||||
@@ -2113,7 +2094,6 @@ activate_mount (XedFileBrowserWidget *widget,
|
||||
GMount *mount)
|
||||
{
|
||||
GFile *root;
|
||||
gchar *uri;
|
||||
|
||||
if (!mount)
|
||||
{
|
||||
@@ -2135,11 +2115,9 @@ activate_mount (XedFileBrowserWidget *widget,
|
||||
}
|
||||
|
||||
root = g_mount_get_root (mount);
|
||||
uri = g_file_get_uri (root);
|
||||
|
||||
xed_file_browser_widget_set_root (widget, uri, FALSE);
|
||||
xed_file_browser_widget_set_root (widget, root, FALSE);
|
||||
|
||||
g_free (uri);
|
||||
g_object_unref (root);
|
||||
}
|
||||
|
||||
@@ -2370,7 +2348,7 @@ bookmark_open (XedFileBrowserWidget *obj,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gchar *uri;
|
||||
GFile *location;
|
||||
gint flags;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
@@ -2392,11 +2370,11 @@ bookmark_open (XedFileBrowserWidget *obj,
|
||||
return;
|
||||
}
|
||||
|
||||
uri =
|
||||
xed_file_bookmarks_store_get_uri
|
||||
location =
|
||||
xed_file_bookmarks_store_get_location
|
||||
(XED_FILE_BOOKMARKS_STORE (model), iter);
|
||||
|
||||
if (uri) {
|
||||
if (location) {
|
||||
/* here we check if the bookmark is a mount point, or if it
|
||||
is a remote bookmark. If that's the case, we will set the
|
||||
root to the uri of the bookmark and not try to set the
|
||||
@@ -2405,18 +2383,18 @@ bookmark_open (XedFileBrowserWidget *obj,
|
||||
if ((flags & XED_FILE_BOOKMARKS_STORE_IS_MOUNT) ||
|
||||
(flags & XED_FILE_BOOKMARKS_STORE_IS_REMOTE_BOOKMARK)) {
|
||||
xed_file_browser_widget_set_root (obj,
|
||||
uri,
|
||||
location,
|
||||
FALSE);
|
||||
} else {
|
||||
xed_file_browser_widget_set_root (obj,
|
||||
uri,
|
||||
location,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
g_object_unref (location);
|
||||
} else {
|
||||
g_warning ("No uri!");
|
||||
}
|
||||
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2424,19 +2402,17 @@ file_open (XedFileBrowserWidget *obj,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gchar *uri;
|
||||
GFile *location;
|
||||
gint flags;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_URI, &uri,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location,
|
||||
-1);
|
||||
|
||||
if (!FILE_IS_DIR (flags) && !FILE_IS_DUMMY (flags)) {
|
||||
g_signal_emit (obj, signals[URI_ACTIVATED], 0, uri);
|
||||
g_signal_emit (obj, signals[LOCATION_ACTIVATED], 0, location);
|
||||
}
|
||||
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2446,17 +2422,20 @@ directory_open (XedFileBrowserWidget *obj,
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
GError *error = NULL;
|
||||
gchar *uri = NULL;
|
||||
GFile *location;
|
||||
XedFileBrowserStoreFlag flags;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_URI, &uri,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location,
|
||||
-1);
|
||||
|
||||
if (FILE_IS_DIR (flags)) {
|
||||
if (FILE_IS_DIR (flags) && location) {
|
||||
gchar *uri;
|
||||
result = TRUE;
|
||||
|
||||
uri = g_file_get_uri (location);
|
||||
|
||||
if (!gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (obj)), uri, GDK_CURRENT_TIME, &error)) {
|
||||
g_signal_emit (obj, signals[ERROR], 0,
|
||||
XED_FILE_BROWSER_ERROR_OPEN_DIRECTORY,
|
||||
@@ -2465,9 +2444,9 @@ directory_open (XedFileBrowserWidget *obj,
|
||||
g_error_free (error);
|
||||
error = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (uri);
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -2514,8 +2493,7 @@ on_virtual_root_changed (XedFileBrowserStore * model,
|
||||
XedFileBrowserWidget * obj)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gchar *uri;
|
||||
gchar *root_uri;
|
||||
GFile *location;
|
||||
GtkTreeIter root;
|
||||
GtkAction *action;
|
||||
Location *loc;
|
||||
@@ -2529,8 +2507,8 @@ on_virtual_root_changed (XedFileBrowserStore * model,
|
||||
|
||||
if (xed_file_browser_store_get_iter_virtual_root (model, &iter)) {
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
|
||||
XED_FILE_BROWSER_STORE_COLUMN_URI,
|
||||
&uri, -1);
|
||||
XED_FILE_BROWSER_STORE_COLUMN_LOCATION,
|
||||
&location, -1);
|
||||
|
||||
if (xed_file_browser_store_get_iter_root (model, &root)) {
|
||||
if (!obj->priv->changing_location) {
|
||||
@@ -2538,14 +2516,9 @@ on_virtual_root_changed (XedFileBrowserStore * model,
|
||||
if (obj->priv->current_location)
|
||||
clear_next_locations (obj);
|
||||
|
||||
root_uri =
|
||||
xed_file_browser_store_get_root
|
||||
(model);
|
||||
|
||||
loc = g_new (Location, 1);
|
||||
loc->root = g_file_new_for_uri (root_uri);
|
||||
loc->virtual_root = g_file_new_for_uri (uri);
|
||||
g_free (root_uri);
|
||||
loc->root = xed_file_browser_store_get_root (model);
|
||||
loc->virtual_root = g_object_ref (location);
|
||||
|
||||
if (obj->priv->current_location) {
|
||||
/* Add current location to the menu so we can go back
|
||||
@@ -2614,7 +2587,6 @@ on_virtual_root_changed (XedFileBrowserStore * model,
|
||||
}
|
||||
|
||||
check_current_item (obj, TRUE);
|
||||
g_free (uri);
|
||||
} else {
|
||||
g_message ("NO!");
|
||||
}
|
||||
@@ -2694,7 +2666,6 @@ on_combo_changed (GtkComboBox * combo, XedFileBrowserWidget * obj)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
guint id;
|
||||
gchar * uri;
|
||||
GFile * file;
|
||||
|
||||
if (!gtk_combo_box_get_active_iter (combo, &iter))
|
||||
@@ -2713,11 +2684,8 @@ on_combo_changed (GtkComboBox * combo, XedFileBrowserWidget * obj)
|
||||
(obj->priv->combo_model), &iter,
|
||||
COLUMN_FILE, &file, -1);
|
||||
|
||||
uri = g_file_get_uri (file);
|
||||
xed_file_browser_store_set_virtual_root_from_string
|
||||
(obj->priv->file_store, uri);
|
||||
xed_file_browser_store_set_virtual_root_from_location (obj->priv->file_store, file);
|
||||
|
||||
g_free (uri);
|
||||
g_object_unref (file);
|
||||
break;
|
||||
}
|
||||
@@ -2902,22 +2870,19 @@ on_bookmarks_row_deleted (GtkTreeModel * model,
|
||||
XedFileBrowserWidget *obj)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gchar * uri;
|
||||
GFile * file;
|
||||
GFile *location;
|
||||
|
||||
if (!gtk_tree_model_get_iter (model, &iter, path))
|
||||
return;
|
||||
|
||||
uri = xed_file_bookmarks_store_get_uri (obj->priv->bookmarks_store, &iter);
|
||||
location = xed_file_bookmarks_store_get_location (obj->priv->bookmarks_store, &iter);
|
||||
|
||||
if (!uri)
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
g_hash_table_remove (obj->priv->bookmarks_hash, file);
|
||||
g_hash_table_remove (obj->priv->bookmarks_hash, location);
|
||||
|
||||
g_object_unref (file);
|
||||
g_free (uri);
|
||||
g_object_unref (location);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -58,8 +58,8 @@ struct _XedFileBrowserWidgetClass
|
||||
GtkBoxClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (*uri_activated) (XedFileBrowserWidget * widget,
|
||||
gchar const *uri);
|
||||
void (*location_activated) (XedFileBrowserWidget * widget,
|
||||
GFile *location);
|
||||
void (*error) (XedFileBrowserWidget * widget,
|
||||
guint code,
|
||||
gchar const *message);
|
||||
@@ -79,12 +79,12 @@ void xed_file_browser_widget_show_bookmarks (XedFileBrowserWidget * obj);
|
||||
void xed_file_browser_widget_show_files (XedFileBrowserWidget * obj);
|
||||
|
||||
void xed_file_browser_widget_set_root (XedFileBrowserWidget * obj,
|
||||
gchar const *root,
|
||||
GFile *root,
|
||||
gboolean virtual_root);
|
||||
void
|
||||
xed_file_browser_widget_set_root_and_virtual_root (XedFileBrowserWidget * obj,
|
||||
gchar const *root,
|
||||
gchar const *virtual_root);
|
||||
GFile *root,
|
||||
GFile *virtual_root);
|
||||
|
||||
gboolean
|
||||
xed_file_browser_widget_get_selected_directory (XedFileBrowserWidget * obj,
|
||||
|
Reference in New Issue
Block a user