1/* Lists/File browser
2 * #Keywords: GListModel
3 *
4 * This demo shows off the different layouts that are quickly achievable
5 * with GtkListview and GtkGridView by implementing a file browser with
6 * different views.
7 */
8
9#include <glib/gi18n.h>
10#include <gtk/gtk.h>
11
12static GtkWidget *window = NULL;
13
14/* Create a simple object that holds the data for the different views */
15typedef struct _FileBrowserView FileBrowserView;
16struct _FileBrowserView
17{
18 GObject parent_instance;
19
20 GtkListItemFactory *factory;
21 char *icon_name;
22 char *title;
23 GtkOrientation orientation;
24};
25
26enum {
27 PROP_0,
28 PROP_FACTORY,
29 PROP_ICON_NAME,
30 PROP_TITLE,
31 PROP_ORIENTATION,
32
33 N_PROPS
34};
35
36#define FILE_BROWSER_TYPE_VIEW (file_browser_view_get_type ())
37G_MODULE_EXPORT
38G_DECLARE_FINAL_TYPE (FileBrowserView, file_browser_view, FILE_BROWSER, VIEW, GObject);
39
40G_DEFINE_TYPE (FileBrowserView, file_browser_view, G_TYPE_OBJECT);
41static GParamSpec *properties[N_PROPS] = { NULL, };
42
43static void
44file_browser_view_get_property (GObject *object,
45 guint property_id,
46 GValue *value,
47 GParamSpec *pspec)
48{
49 FileBrowserView *self = FILE_BROWSER_VIEW (ptr: object);
50
51 switch (property_id)
52 {
53 case PROP_FACTORY:
54 g_value_set_object (value, v_object: self->factory);
55 break;
56
57 case PROP_ICON_NAME:
58 g_value_set_string (value, v_string: self->icon_name);
59 break;
60
61 case PROP_TITLE:
62 g_value_set_string (value, v_string: self->title);
63 break;
64
65 case PROP_ORIENTATION:
66 g_value_set_enum (value, v_enum: self->orientation);
67 break;
68
69 default:
70 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
71 break;
72 }
73}
74
75static void
76file_browser_view_set_property (GObject *object,
77 guint prop_id,
78 const GValue *value,
79 GParamSpec *pspec)
80{
81 FileBrowserView *self = FILE_BROWSER_VIEW (ptr: object);
82
83 switch (prop_id)
84 {
85 case PROP_FACTORY:
86 g_set_object (&self->factory, g_value_get_object (value));
87 break;
88
89 case PROP_ICON_NAME:
90 g_free (mem: self->icon_name);
91 self->icon_name = g_value_dup_string (value);
92 break;
93
94 case PROP_TITLE:
95 g_free (mem: self->title);
96 self->title = g_value_dup_string (value);
97 break;
98
99 case PROP_ORIENTATION:
100 self->orientation = g_value_get_enum (value);
101 break;
102
103 default:
104 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
105 break;
106 }
107}
108
109static void
110file_browser_view_finalize (GObject *object)
111{
112 FileBrowserView *self = FILE_BROWSER_VIEW (ptr: object);
113
114 g_object_unref (object: self->factory);
115 g_free (mem: self->icon_name);
116 g_free (mem: self->title);
117
118 G_OBJECT_CLASS (file_browser_view_parent_class)->dispose (object);
119}
120
121static void
122file_browser_view_class_init (FileBrowserViewClass *klass)
123{
124 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
125
126 gobject_class->get_property = file_browser_view_get_property;
127 gobject_class->set_property = file_browser_view_set_property;
128 gobject_class->finalize = file_browser_view_finalize;
129
130 properties[PROP_FACTORY] =
131 g_param_spec_object (name: "factory",
132 nick: "factory",
133 blurb: "factory to use in the main view",
134 GTK_TYPE_LIST_ITEM_FACTORY,
135 flags: G_PARAM_READWRITE);
136 properties[PROP_ICON_NAME] =
137 g_param_spec_string (name: "icon-name",
138 nick: "icon name",
139 blurb: "icon to display for selecting this view",
140 NULL,
141 flags: G_PARAM_READWRITE);
142 properties[PROP_TITLE] =
143 g_param_spec_string (name: "title",
144 nick: "title",
145 blurb: "title to display for selecting this view",
146 NULL,
147 flags: G_PARAM_READWRITE);
148 properties[PROP_ORIENTATION] =
149 g_param_spec_enum (name: "orientation",
150 nick: "orientation",
151 blurb: "orientation of the view",
152 enum_type: GTK_TYPE_ORIENTATION,
153 default_value: GTK_ORIENTATION_VERTICAL,
154 flags: G_PARAM_READWRITE);
155
156 g_object_class_install_properties (oclass: gobject_class, n_pspecs: N_PROPS, pspecs: properties);
157}
158
159static void file_browser_view_init (FileBrowserView *self)
160{
161}
162
163G_MODULE_EXPORT char *
164filebrowser_get_display_name (GObject *object,
165 GFileInfo *info)
166{
167 if (!info)
168 return NULL;
169
170 return g_strdup (str: g_file_info_get_attribute_string (info, attribute: "standard::display-name"));
171}
172
173G_MODULE_EXPORT char *
174filebrowser_get_content_type (GObject *object,
175 GFileInfo *info)
176{
177 if (!info)
178 return NULL;
179
180 return g_strdup (str: g_file_info_get_attribute_string (info, attribute: "standard::content-type"));
181}
182
183G_MODULE_EXPORT char *
184filebrowser_get_size (GObject *object,
185 GFileInfo *info)
186{
187 if (!info)
188 return NULL;
189
190 return g_format_size (size: g_file_info_get_attribute_uint64 (info, attribute: "standard::size"));
191}
192
193G_MODULE_EXPORT GIcon *
194filebrowser_get_icon (GObject *object,
195 GFileInfo *info)
196{
197 GIcon *icon;
198
199 if (info)
200 icon = G_ICON (g_file_info_get_attribute_object (info, "standard::icon"));
201 else
202 icon = NULL;
203
204 if (icon)
205 g_object_ref (icon);
206
207 return icon;
208}
209
210G_MODULE_EXPORT void
211filebrowser_up_clicked_cb (GtkButton *button,
212 GtkDirectoryList *list)
213{
214 GFile *file;
215
216 file = g_file_get_parent (file: gtk_directory_list_get_file (self: list));
217 if (file == NULL)
218 return;
219
220 gtk_directory_list_set_file (self: list, file);
221}
222
223G_MODULE_EXPORT void
224filebrowser_view_activated_cb (GtkGridView *view,
225 guint pos,
226 GtkDirectoryList *list)
227{
228 GFileInfo *info;
229
230 info = g_list_model_get_item (list: G_LIST_MODEL (ptr: gtk_grid_view_get_model (self: view)), position: pos);
231 if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
232 gtk_directory_list_set_file (self: list, G_FILE (g_file_info_get_attribute_object (info, "standard::file")));
233
234 g_object_unref (object: info);
235}
236
237GtkWidget *
238do_listview_filebrowser (GtkWidget *do_widget)
239{
240 if (!window)
241 {
242 GtkWidget *view;
243 GtkBuilder *builder;
244 GtkDirectoryList *dirlist;
245 GFile *file;
246 char *cwd;
247 GtkCssProvider *provider;
248
249 provider = gtk_css_provider_new ();
250 gtk_css_provider_load_from_resource (css_provider: provider, resource_path: "/listview_filebrowser/listview_filebrowser.css");
251 gtk_style_context_add_provider_for_display (display: gdk_display_get_default (),
252 GTK_STYLE_PROVIDER (provider),
253 priority: 800);
254 g_object_unref (object: provider);
255
256 builder = gtk_builder_new_from_resource (resource_path: "/listview_filebrowser/listview_filebrowser.ui");
257 window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
258 gtk_window_set_display (GTK_WINDOW (window),
259 display: gtk_widget_get_display (widget: do_widget));
260 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *) &window);
261
262 /* Create the model and fill it with the contents of the current directory */
263 cwd = g_get_current_dir ();
264 file = g_file_new_for_path (path: cwd);
265 g_free (mem: cwd);
266 dirlist = GTK_DIRECTORY_LIST (ptr: gtk_builder_get_object (builder, name: "dirlist"));
267 gtk_directory_list_set_file (self: dirlist, file);
268 g_object_unref (object: file);
269
270 /* grab focus in the view */
271 view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
272 gtk_widget_grab_focus (widget: view);
273
274 g_object_unref (object: builder);
275 }
276
277 if (!gtk_widget_get_visible (widget: window))
278 gtk_widget_show (widget: window);
279 else
280 gtk_window_destroy (GTK_WINDOW (window));
281
282 return window;
283}
284

source code of gtk/demos/gtk-demo/listview_filebrowser.c