1 /*
2  * Copyright (c) 2017-2021 gnome-mpv
3  *
4  * This file is part of Celluloid.
5  *
6  * Celluloid 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  * Celluloid 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 Celluloid.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <glib/gi18n.h>
21 #include <string.h>
22 
23 #include "celluloid-file-chooser.h"
24 #include "celluloid-def.h"
25 
26 static void
27 load_last_folder(GtkFileChooser *chooser);
28 
29 static void
30 save_last_folder(GtkFileChooser *chooser);
31 
32 static void
33 response_handler(GtkDialog *dialog, gint response_id, gpointer data);
34 
35 static void
load_last_folder(GtkFileChooser * chooser)36 load_last_folder(GtkFileChooser *chooser)
37 {
38 	GSettings *win_config = g_settings_new(CONFIG_WIN_STATE);
39 	gchar *uri = g_settings_get_string(win_config, "last-folder-uri");
40 
41 	if(uri && *uri)
42 	{
43 		GFile *folder = g_file_new_for_uri(uri);
44 
45 		gtk_file_chooser_set_current_folder(chooser, folder, NULL);
46 		g_object_unref(folder);
47 	}
48 
49 	g_free(uri);
50 	g_object_unref(win_config);
51 }
52 
53 static void
save_last_folder(GtkFileChooser * chooser)54 save_last_folder(GtkFileChooser *chooser)
55 {
56 	GFile *folder = gtk_file_chooser_get_current_folder(chooser);
57 	gchar *uri = g_file_get_uri(folder);
58 	GSettings *win_config = g_settings_new(CONFIG_WIN_STATE);
59 
60 	g_settings_set_string(win_config, "last-folder-uri", uri?:"");
61 
62 	g_object_unref(win_config);
63 	g_free(uri);
64 	g_object_unref(folder);
65 }
66 
67 static void
response_handler(GtkDialog * dialog,gint response_id,gpointer data)68 response_handler(GtkDialog *dialog, gint response_id, gpointer data)
69 {
70 	if(response_id == GTK_RESPONSE_ACCEPT)
71 	{
72 		GSettings *main_config;
73 		gboolean last_folder_enable;
74 
75 		main_config = g_settings_new(CONFIG_ROOT);
76 		last_folder_enable =	g_settings_get_boolean
77 					(main_config, "last-folder-enable");
78 
79 		if(last_folder_enable)
80 		{
81 			save_last_folder(GTK_FILE_CHOOSER(dialog));
82 		}
83 
84 		g_object_unref(main_config);
85 	}
86 }
87 
88 CelluloidFileChooser *
celluloid_file_chooser_new(const gchar * title,GtkWindow * parent,GtkFileChooserAction action)89 celluloid_file_chooser_new(	const gchar *title,
90 				GtkWindow *parent,
91 				GtkFileChooserAction action )
92 {
93 	CelluloidFileChooser *chooser;
94 	GSettings *main_config;
95 	gboolean last_folder_enable;
96 
97 	chooser = gtk_file_chooser_native_new(title, parent, action, NULL, NULL);
98 	main_config = g_settings_new(CONFIG_ROOT);
99 	last_folder_enable =	g_settings_get_boolean
100 				(main_config, "last-folder-enable");
101 
102 	if(last_folder_enable)
103 	{
104 		load_last_folder(GTK_FILE_CHOOSER(chooser));
105 	}
106 
107 	celluloid_file_chooser_set_modal(chooser, TRUE);
108 
109 	g_signal_connect(chooser, "response", G_CALLBACK(response_handler), NULL);
110 
111 	g_object_unref(main_config);
112 
113 	return chooser;
114 }
115 
116 void
celluloid_file_chooser_destroy(CelluloidFileChooser * chooser)117 celluloid_file_chooser_destroy(CelluloidFileChooser *chooser)
118 {
119 	gtk_native_dialog_destroy(GTK_NATIVE_DIALOG(chooser));
120 	g_object_unref(chooser);
121 }
122 
123 void
celluloid_file_chooser_set_default_filters(CelluloidFileChooser * chooser,gboolean audio,gboolean video,gboolean image,gboolean subtitle)124 celluloid_file_chooser_set_default_filters(	CelluloidFileChooser *chooser,
125 						gboolean audio,
126 						gboolean video,
127 						gboolean image,
128 						gboolean subtitle )
129 {
130 	GtkFileChooser *gtk_chooser = GTK_FILE_CHOOSER(chooser);
131 	GListModel *filters = gtk_file_chooser_get_filters(gtk_chooser);
132 	const guint filters_count = g_list_model_get_n_items(filters);
133 
134 	for(guint i = 0; i < filters_count; i++)
135 	{
136 		GtkFileFilter *filter = g_list_model_get_item(filters, i);
137 
138 		gtk_file_chooser_remove_filter(gtk_chooser, filter);
139 	}
140 
141 	if(audio || video || image || subtitle)
142 	{
143 		GtkFileFilter *filter = gtk_file_filter_new();
144 		gtk_file_filter_set_name(filter, _("All Files"));
145 		gtk_file_filter_add_pattern(filter, "*");
146 		gtk_file_chooser_add_filter(gtk_chooser, filter);
147 	}
148 
149 	if(audio && video && image)
150 	{
151 		GtkFileFilter *filter = gtk_file_filter_new();
152 		gtk_file_filter_set_name(filter, _("Media Files"));
153 		gtk_file_filter_add_mime_type(filter, "audio/*");
154 		gtk_file_filter_add_mime_type(filter, "video/*");
155 		gtk_file_filter_add_mime_type(filter, "image/*");
156 		gtk_file_chooser_add_filter(gtk_chooser, filter);
157 		gtk_file_chooser_set_filter(gtk_chooser, filter);
158 	}
159 
160 	if(audio)
161 	{
162 		GtkFileFilter *filter = gtk_file_filter_new();
163 		gtk_file_filter_set_name(filter, _("Audio Files"));
164 		gtk_file_filter_add_mime_type(filter, "audio/*");
165 		gtk_file_chooser_add_filter(gtk_chooser, filter);
166 	}
167 
168 	if(video)
169 	{
170 		GtkFileFilter *filter = gtk_file_filter_new();
171 		gtk_file_filter_set_name(filter, _("Video Files"));
172 		gtk_file_filter_add_mime_type(filter, "video/*");
173 		gtk_file_chooser_add_filter(gtk_chooser, filter);
174 	}
175 
176 	if(image)
177 	{
178 		GtkFileFilter *filter = gtk_file_filter_new();
179 		gtk_file_filter_set_name(filter, _("Image Files"));
180 		gtk_file_filter_add_mime_type(filter, "image/*");
181 		gtk_file_chooser_add_filter(gtk_chooser, filter);
182 	}
183 
184 	if(subtitle)
185 	{
186 		GtkFileFilter *filter = gtk_file_filter_new();
187 		const gchar *exts[] = SUBTITLE_EXTS;
188 
189 		gtk_file_filter_set_name(filter, _("Subtitle Files"));
190 
191 		for(gint i = 0; exts[i]; i++)
192 		{
193 			gchar *pattern = g_strdup_printf("*.%s", exts[i]);
194 
195 			gtk_file_filter_add_pattern(filter, pattern);
196 			g_free(pattern);
197 		}
198 
199 		gtk_file_chooser_add_filter(gtk_chooser, filter);
200 
201 		if(!(audio || video || image))
202 		{
203 			gtk_file_chooser_set_filter(gtk_chooser, filter);
204 		}
205 	}
206 
207 	g_object_unref(filters);
208 }
209