2019-10-18 18:47:48 +00:00
|
|
|
/* Lists/File browser
|
2020-09-13 18:59:33 +00:00
|
|
|
* #Keywords: GListModel
|
2019-10-18 18:47:48 +00:00
|
|
|
*
|
|
|
|
* This demo shows off the different layouts that are quickly achievable
|
2020-05-29 17:25:36 +00:00
|
|
|
* with GtkListview and GtkGridView by implementing a file browser with
|
|
|
|
* different views.
|
2019-10-18 18:47:48 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <glib/gi18n.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
|
|
|
static GtkWidget *window = NULL;
|
|
|
|
|
|
|
|
/* Create a simple object that holds the data for the different views */
|
|
|
|
typedef struct _FileBrowserView FileBrowserView;
|
|
|
|
struct _FileBrowserView
|
|
|
|
{
|
|
|
|
GObject parent_instance;
|
|
|
|
|
|
|
|
GtkListItemFactory *factory;
|
|
|
|
char *icon_name;
|
2020-06-02 03:12:01 +00:00
|
|
|
char *title;
|
2019-10-18 18:47:48 +00:00
|
|
|
GtkOrientation orientation;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
PROP_0,
|
|
|
|
PROP_FACTORY,
|
|
|
|
PROP_ICON_NAME,
|
2020-06-02 03:12:01 +00:00
|
|
|
PROP_TITLE,
|
2019-10-18 18:47:48 +00:00
|
|
|
PROP_ORIENTATION,
|
|
|
|
|
|
|
|
N_PROPS
|
|
|
|
};
|
|
|
|
|
|
|
|
#define FILE_BROWSER_TYPE_VIEW (file_browser_view_get_type ())
|
|
|
|
G_DECLARE_FINAL_TYPE (FileBrowserView, file_browser_view, FILE_BROWSER, VIEW, GObject);
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (FileBrowserView, file_browser_view, G_TYPE_OBJECT);
|
|
|
|
static GParamSpec *properties[N_PROPS] = { NULL, };
|
|
|
|
|
|
|
|
static void
|
|
|
|
file_browser_view_get_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
FileBrowserView *self = FILE_BROWSER_VIEW (object);
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case PROP_FACTORY:
|
|
|
|
g_value_set_object (value, self->factory);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_ICON_NAME:
|
|
|
|
g_value_set_string (value, self->icon_name);
|
|
|
|
break;
|
|
|
|
|
2020-06-02 03:12:01 +00:00
|
|
|
case PROP_TITLE:
|
|
|
|
g_value_set_string (value, self->title);
|
|
|
|
break;
|
|
|
|
|
2019-10-18 18:47:48 +00:00
|
|
|
case PROP_ORIENTATION:
|
|
|
|
g_value_set_enum (value, self->orientation);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
file_browser_view_set_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
FileBrowserView *self = FILE_BROWSER_VIEW (object);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
case PROP_FACTORY:
|
|
|
|
g_set_object (&self->factory, g_value_get_object (value));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_ICON_NAME:
|
|
|
|
g_free (self->icon_name);
|
|
|
|
self->icon_name = g_value_dup_string (value);
|
|
|
|
break;
|
|
|
|
|
2020-06-02 03:12:01 +00:00
|
|
|
case PROP_TITLE:
|
|
|
|
g_free (self->title);
|
|
|
|
self->title = g_value_dup_string (value);
|
|
|
|
break;
|
|
|
|
|
2019-10-18 18:47:48 +00:00
|
|
|
case PROP_ORIENTATION:
|
|
|
|
self->orientation = g_value_get_enum (value);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
file_browser_view_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
FileBrowserView *self = FILE_BROWSER_VIEW (object);
|
|
|
|
|
|
|
|
g_object_unref (self->factory);
|
|
|
|
g_free (self->icon_name);
|
2020-06-02 03:12:01 +00:00
|
|
|
g_free (self->title);
|
2019-10-18 18:47:48 +00:00
|
|
|
|
|
|
|
G_OBJECT_CLASS (file_browser_view_parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
file_browser_view_class_init (FileBrowserViewClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
|
|
|
gobject_class->get_property = file_browser_view_get_property;
|
|
|
|
gobject_class->set_property = file_browser_view_set_property;
|
|
|
|
gobject_class->finalize = file_browser_view_finalize;
|
|
|
|
|
|
|
|
properties[PROP_FACTORY] =
|
|
|
|
g_param_spec_object ("factory",
|
|
|
|
"factory",
|
|
|
|
"factory to use in the main view",
|
|
|
|
GTK_TYPE_LIST_ITEM_FACTORY,
|
|
|
|
G_PARAM_READWRITE);
|
|
|
|
properties[PROP_ICON_NAME] =
|
|
|
|
g_param_spec_string ("icon-name",
|
|
|
|
"icon name",
|
|
|
|
"icon to display for selecting this view",
|
|
|
|
NULL,
|
|
|
|
G_PARAM_READWRITE);
|
2020-06-02 03:12:01 +00:00
|
|
|
properties[PROP_TITLE] =
|
|
|
|
g_param_spec_string ("title",
|
|
|
|
"title",
|
|
|
|
"title to display for selecting this view",
|
|
|
|
NULL,
|
|
|
|
G_PARAM_READWRITE);
|
2019-10-18 18:47:48 +00:00
|
|
|
properties[PROP_ORIENTATION] =
|
|
|
|
g_param_spec_enum ("orientation",
|
|
|
|
"orientation",
|
|
|
|
"orientation of the view",
|
|
|
|
GTK_TYPE_ORIENTATION,
|
|
|
|
GTK_ORIENTATION_VERTICAL,
|
|
|
|
G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void file_browser_view_init (FileBrowserView *self)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
filebrowser_get_display_name (GObject *object,
|
|
|
|
GFileInfo *info)
|
|
|
|
{
|
|
|
|
if (!info)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return g_strdup (g_file_info_get_attribute_string (info, "standard::display-name"));
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
filebrowser_get_content_type (GObject *object,
|
|
|
|
GFileInfo *info)
|
|
|
|
{
|
|
|
|
if (!info)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return g_strdup (g_file_info_get_attribute_string (info, "standard::content-type"));
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
filebrowser_get_size (GObject *object,
|
|
|
|
GFileInfo *info)
|
|
|
|
{
|
|
|
|
if (!info)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return g_format_size (g_file_info_get_attribute_uint64 (info, "standard::size"));
|
|
|
|
}
|
|
|
|
|
|
|
|
GIcon *
|
|
|
|
filebrowser_get_icon (GObject *object,
|
|
|
|
GFileInfo *info)
|
|
|
|
{
|
|
|
|
GIcon *icon;
|
|
|
|
|
|
|
|
if (info)
|
|
|
|
icon = G_ICON (g_file_info_get_attribute_object (info, "standard::icon"));
|
|
|
|
else
|
|
|
|
icon = NULL;
|
|
|
|
|
|
|
|
if (icon)
|
|
|
|
g_object_ref (icon);
|
|
|
|
|
|
|
|
return icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
filebrowser_up_clicked_cb (GtkButton *button,
|
|
|
|
GtkDirectoryList *list)
|
|
|
|
{
|
|
|
|
GFile *file;
|
|
|
|
|
|
|
|
file = g_file_get_parent (gtk_directory_list_get_file (list));
|
|
|
|
if (file == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gtk_directory_list_set_file (list, file);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
filebrowser_view_activated_cb (GtkGridView *view,
|
|
|
|
guint pos,
|
|
|
|
GtkDirectoryList *list)
|
|
|
|
{
|
|
|
|
GFileInfo *info;
|
|
|
|
|
2020-08-31 21:06:48 +00:00
|
|
|
info = g_list_model_get_item (G_LIST_MODEL (gtk_grid_view_get_model (view)), pos);
|
2019-10-18 18:47:48 +00:00
|
|
|
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
|
|
|
|
gtk_directory_list_set_file (list, G_FILE (g_file_info_get_attribute_object (info, "standard::file")));
|
|
|
|
|
|
|
|
g_object_unref (info);
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkWidget *
|
|
|
|
do_listview_filebrowser (GtkWidget *do_widget)
|
|
|
|
{
|
|
|
|
if (!window)
|
|
|
|
{
|
|
|
|
GtkWidget *view;
|
|
|
|
GtkBuilder *builder;
|
|
|
|
GtkDirectoryList *dirlist;
|
|
|
|
GFile *file;
|
|
|
|
char *cwd;
|
2020-06-02 03:12:01 +00:00
|
|
|
GtkCssProvider *provider;
|
|
|
|
|
|
|
|
provider = gtk_css_provider_new ();
|
|
|
|
gtk_css_provider_load_from_resource (provider, "/listview_filebrowser/listview_filebrowser.css");
|
|
|
|
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
|
|
|
GTK_STYLE_PROVIDER (provider),
|
|
|
|
800);
|
|
|
|
g_object_unref (provider);
|
2019-10-18 18:47:48 +00:00
|
|
|
|
|
|
|
builder = gtk_builder_new_from_resource ("/listview_filebrowser/listview_filebrowser.ui");
|
|
|
|
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
|
|
|
gtk_window_set_display (GTK_WINDOW (window),
|
|
|
|
gtk_widget_get_display (do_widget));
|
|
|
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
|
|
|
|
|
|
|
|
/* Create the model and fill it with the contents of the current directory */
|
|
|
|
cwd = g_get_current_dir ();
|
|
|
|
file = g_file_new_for_path (cwd);
|
|
|
|
g_free (cwd);
|
|
|
|
dirlist = GTK_DIRECTORY_LIST (gtk_builder_get_object (builder, "dirlist"));
|
|
|
|
gtk_directory_list_set_file (dirlist, file);
|
|
|
|
g_object_unref (file);
|
|
|
|
|
|
|
|
/* grab focus in the view */
|
|
|
|
view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
|
|
|
|
gtk_widget_grab_focus (view);
|
|
|
|
|
|
|
|
g_object_unref (builder);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!gtk_widget_get_visible (window))
|
|
|
|
gtk_widget_show (window);
|
|
|
|
else
|
|
|
|
gtk_window_destroy (GTK_WINDOW (window));
|
|
|
|
|
|
|
|
return window;
|
|
|
|
}
|