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 | |
12 | static GtkWidget *window = NULL; |
13 | |
14 | /* Create a simple object that holds the data for the different views */ |
15 | typedef struct _FileBrowserView FileBrowserView; |
16 | struct _FileBrowserView |
17 | { |
18 | GObject parent_instance; |
19 | |
20 | GtkListItemFactory *factory; |
21 | char *icon_name; |
22 | char *title; |
23 | GtkOrientation orientation; |
24 | }; |
25 | |
26 | enum { |
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 ()) |
37 | G_MODULE_EXPORT |
38 | G_DECLARE_FINAL_TYPE (FileBrowserView, file_browser_view, FILE_BROWSER, VIEW, GObject); |
39 | |
40 | G_DEFINE_TYPE (FileBrowserView, file_browser_view, G_TYPE_OBJECT); |
41 | static GParamSpec *properties[N_PROPS] = { NULL, }; |
42 | |
43 | static void |
44 | file_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 | |
75 | static void |
76 | file_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 | |
109 | static void |
110 | file_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 | |
121 | static void |
122 | file_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 | |
159 | static void file_browser_view_init (FileBrowserView *self) |
160 | { |
161 | } |
162 | |
163 | G_MODULE_EXPORT char * |
164 | filebrowser_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 | |
173 | G_MODULE_EXPORT char * |
174 | filebrowser_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 | |
183 | G_MODULE_EXPORT char * |
184 | filebrowser_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 | |
193 | G_MODULE_EXPORT GIcon * |
194 | filebrowser_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 | |
210 | G_MODULE_EXPORT void |
211 | filebrowser_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 | |
223 | G_MODULE_EXPORT void |
224 | filebrowser_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 | |
237 | GtkWidget * |
238 | do_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 | |