1 /*
2 * Copyright © 2009-2018 Siyan Panayotov <contact@siyanpanayotov.com>
3 *
4 * This file is part of Viewnior.
5 *
6 * Viewnior is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Viewnior is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Viewnior. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <libintl.h>
21 #include <glib/gi18n.h>
22 #define _(String) gettext (String)
23
24 #include <gtk/gtk.h>
25 #include <gio/gio.h>
26 #include <gdk/gdkpixbuf.h>
27 #include "vnr-file.h"
28 #include "vnr-tools.h"
29
30 G_DEFINE_TYPE (VnrFile, vnr_file, G_TYPE_OBJECT);
31
32 GList * supported_mime_types;
33
34 static gint
compare_files(VnrFile * file,char * uri)35 compare_files(VnrFile *file, char *uri)
36 {
37 if(g_strcmp0(uri, file->path) == 0)
38 return 0;
39 else
40 return 1;
41 }
42
43 /* Modified version of eog's eog_image_get_supported_mime_types */
44 static GList *
vnr_file_get_supported_mime_types(void)45 vnr_file_get_supported_mime_types (void)
46 {
47 GSList *format_list, *it;
48 gchar **mime_types;
49 int i;
50
51 if (!supported_mime_types) {
52 format_list = gdk_pixbuf_get_formats ();
53
54 for (it = format_list; it != NULL; it = it->next) {
55 mime_types =
56 gdk_pixbuf_format_get_mime_types ((GdkPixbufFormat *) it->data);
57
58 for (i = 0; mime_types[i] != NULL; i++) {
59 supported_mime_types =
60 g_list_prepend (supported_mime_types,
61 g_strdup (mime_types[i]));
62 }
63
64 g_strfreev (mime_types);
65 }
66
67 supported_mime_types = g_list_prepend(supported_mime_types,
68 "image/vnd.microsoft.icon");
69
70 supported_mime_types = g_list_sort (supported_mime_types,
71 (GCompareFunc) compare_quarks);
72
73 g_slist_free (format_list);
74 }
75
76 return supported_mime_types;
77 }
78
79 static gboolean
vnr_file_is_supported_mime_type(const char * mime_type)80 vnr_file_is_supported_mime_type (const char *mime_type)
81 {
82 GList *result;
83 GQuark quark;
84
85 if (mime_type == NULL) {
86 return FALSE;
87 }
88
89 supported_mime_types = vnr_file_get_supported_mime_types ();
90
91 quark = g_quark_from_string (mime_type);
92
93 result = g_list_find_custom (supported_mime_types,
94 GINT_TO_POINTER (quark),
95 (GCompareFunc) compare_quarks);
96
97 return (result != NULL);
98 }
99
100 static void
vnr_file_class_init(VnrFileClass * klass)101 vnr_file_class_init (VnrFileClass * klass)
102 {
103 }
104
105 static void
vnr_file_init(VnrFile * file)106 vnr_file_init (VnrFile * file)
107 {
108 file->display_name = NULL;
109 }
110
111 VnrFile *
vnr_file_new()112 vnr_file_new ()
113 {
114 return VNR_FILE (g_object_new (VNR_TYPE_FILE, NULL));
115 }
116
117 static void
vnr_file_set_display_name(VnrFile * vnr_file,char * display_name)118 vnr_file_set_display_name(VnrFile *vnr_file, char *display_name)
119 {
120 vnr_file->display_name = g_strdup(display_name);
121 vnr_file->display_name_collate = g_utf8_collate_key_for_filename(display_name, -1);
122 }
123
124
125 static gint
vnr_file_list_compare(gconstpointer a,gconstpointer b,gpointer user_data)126 vnr_file_list_compare(gconstpointer a, gconstpointer b, gpointer user_data){
127 return g_strcmp0(VNR_FILE(a)->display_name_collate,
128 VNR_FILE(b)->display_name_collate);
129 }
130
131
132 static GList *
vnr_file_dir_content_to_list(gchar * path,gboolean sort,gboolean include_hidden)133 vnr_file_dir_content_to_list(gchar *path, gboolean sort, gboolean include_hidden)
134 {
135 GList *file_list = NULL;
136 GFile *file;
137 GFileEnumerator *f_enum ;
138 GFileInfo *file_info;
139 VnrFile *vnr_file;
140 const char *mimetype;
141
142 file = g_file_new_for_path(path);
143 f_enum = g_file_enumerate_children(file, G_FILE_ATTRIBUTE_STANDARD_NAME","
144 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME","
145 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE","
146 G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN,
147 G_FILE_QUERY_INFO_NONE,
148 NULL, NULL);
149 file_info = g_file_enumerator_next_file(f_enum,NULL,NULL);
150
151
152 while(file_info != NULL){
153 vnr_file = vnr_file_new();
154
155 mimetype =g_file_info_get_content_type(file_info);
156
157 if(vnr_file_is_supported_mime_type(mimetype) && (include_hidden || !g_file_info_get_is_hidden (file_info)) ){
158 vnr_file_set_display_name(vnr_file, (char*)g_file_info_get_display_name (file_info));
159
160 vnr_file->path =g_strjoin(G_DIR_SEPARATOR_S, path,
161 vnr_file->display_name, NULL);
162
163 file_list = g_list_prepend(file_list, vnr_file);
164 }
165
166 g_object_unref(file_info);
167 file_info = g_file_enumerator_next_file(f_enum,NULL,NULL);
168 }
169
170 g_object_unref (file);
171 g_file_enumerator_close (f_enum, NULL, NULL);
172 g_object_unref (f_enum);
173
174 if(sort)
175 file_list = g_list_sort_with_data(file_list,
176 vnr_file_list_compare, NULL);
177
178 return file_list;
179 }
180
181
182 void
vnr_file_load_single_uri(char * p_path,GList ** file_list,gboolean include_hidden,GError ** error)183 vnr_file_load_single_uri(char *p_path, GList **file_list, gboolean include_hidden, GError **error)
184 {
185 GFile *file;
186 GFileInfo *fileinfo;
187 GFileType filetype;
188
189 file = g_file_new_for_path(p_path);
190 fileinfo = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE","
191 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
192 0, NULL, error);
193
194 if (fileinfo == NULL)
195 return;
196
197 filetype = g_file_info_get_file_type(fileinfo);
198
199 if (filetype == G_FILE_TYPE_DIRECTORY)
200 {
201 *file_list = vnr_file_dir_content_to_list(p_path, TRUE, include_hidden);
202 }
203 else
204 {
205 GFile *parent;
206 GList *current_position;
207
208 parent = g_file_get_parent(file);
209 *file_list = vnr_file_dir_content_to_list(g_file_get_path(parent), TRUE, include_hidden);
210
211 g_object_unref(parent);
212
213 current_position = g_list_find_custom(*file_list, p_path,
214 (GCompareFunc)compare_files);
215
216 if(current_position != NULL)
217 *file_list = current_position;
218 else if(*file_list == NULL)
219 return;
220 else
221 {
222 *error = g_error_new(1, 0,
223 _("Couldn't recognise the image file\n"
224 "format for file '%s'"),
225 g_file_info_get_display_name (fileinfo));
226 }
227 }
228 g_object_unref (file);
229 g_object_unref(fileinfo);
230 }
231
232 void
vnr_file_load_uri_list(GSList * uri_list,GList ** file_list,gboolean include_hidden,GError ** error)233 vnr_file_load_uri_list (GSList *uri_list, GList **file_list, gboolean include_hidden, GError **error)
234 {
235 GFile *file;
236 GFileInfo *fileinfo;
237 GFileType filetype;
238 gchar *p_path;
239
240 while(uri_list != NULL)
241 {
242 p_path = uri_list->data;
243 file = g_file_new_for_path(p_path);
244 fileinfo = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE","
245 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME","
246 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE","
247 G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN,
248 0, NULL, error);
249
250 if (fileinfo == NULL)
251 {
252 g_clear_error (error);
253 g_object_unref (file);
254
255 uri_list = g_slist_next(uri_list);
256 continue;
257 }
258
259 filetype = g_file_info_get_file_type(fileinfo);
260
261 if (filetype == G_FILE_TYPE_DIRECTORY)
262 {
263 *file_list = g_list_concat (*file_list, vnr_file_dir_content_to_list(p_path, FALSE, include_hidden));
264 }
265 else
266 {
267 VnrFile *new_vnrfile;
268 const char *mimetype;
269
270 new_vnrfile = vnr_file_new();
271
272 mimetype = g_file_info_get_content_type(fileinfo);
273
274 if(vnr_file_is_supported_mime_type(mimetype) && (include_hidden || !g_file_info_get_is_hidden (fileinfo)) )
275 {
276 vnr_file_set_display_name(new_vnrfile, (char*)g_file_info_get_display_name (fileinfo));
277
278 new_vnrfile->path = p_path;
279
280 *file_list = g_list_prepend(*file_list, new_vnrfile);
281 }
282 }
283 g_object_unref (file);
284 g_object_unref (fileinfo);
285
286 uri_list = g_slist_next(uri_list);
287 }
288
289 *file_list = g_list_sort_with_data(*file_list, vnr_file_list_compare, NULL);
290 }
291