1 /*
2 * Copyright (c) 2016-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 <gdk/gdk.h>
21 #include <gio/gio.h>
22 #include <glib.h>
23 #include <glib-object.h>
24 #include <glib/gi18n.h>
25
26 #include "celluloid-plugins-manager-item.h"
27
28 enum
29 {
30 PROP_0,
31 PROP_PARENT,
32 PROP_TITLE,
33 PROP_PATH,
34 N_PROPERTIES
35 };
36
37 struct _CelluloidPluginsManagerItem
38 {
39 GtkListBoxRow parent;
40 GtkWindow *parent_window;
41 gchar *title;
42 gchar *path;
43 };
44
45 struct _CelluloidPluginsManagerItemClass
46 {
47 GtkListBoxRowClass parent_class;
48 };
49
50 G_DEFINE_TYPE(CelluloidPluginsManagerItem, celluloid_plugins_manager_item, GTK_TYPE_LIST_BOX_ROW)
51
52 static void
53 celluloid_plugins_manager_item_constructed(GObject *object);
54
55 static void
56 celluloid_plugins_manager_item_finalize(GObject *object);
57
58 static void
59 celluloid_plugins_manager_item_set_property( GObject *object,
60 guint property_id,
61 const GValue *value,
62 GParamSpec *pspec );
63
64 static void
65 celluloid_plugins_manager_item_get_property( GObject *object,
66 guint property_id,
67 GValue *value,
68 GParamSpec *pspec );
69
70 static void
71 remove_response_handler(GtkDialog *dialog, gint response_id, gpointer data);
72
73 static void
74 remove_handler(GtkButton *button, gpointer data);
75
76 static void
celluloid_plugins_manager_item_constructed(GObject * object)77 celluloid_plugins_manager_item_constructed(GObject *object)
78 {
79 CelluloidPluginsManagerItem *self = CELLULOID_PLUGINS_MANAGER_ITEM(object);
80 GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
81 GtkWidget *title_label = gtk_label_new(self->title);
82 GtkWidget *remove_button = gtk_button_new_with_label(_("Remove"));
83
84 g_signal_connect( remove_button,
85 "clicked",
86 G_CALLBACK(remove_handler),
87 self );
88
89 gtk_widget_set_halign(title_label, GTK_ALIGN_START);
90 gtk_widget_set_hexpand(title_label, TRUE);
91 gtk_widget_set_margin_start(title_label, 6);
92 gtk_label_set_ellipsize(GTK_LABEL(title_label), PANGO_ELLIPSIZE_END);
93 gtk_list_box_row_set_selectable(GTK_LIST_BOX_ROW(self), FALSE);
94
95 gtk_box_append(GTK_BOX(box), title_label);
96 gtk_box_append(GTK_BOX(box), remove_button);
97 gtk_list_box_row_set_child(GTK_LIST_BOX_ROW(self), box);
98
99 G_OBJECT_CLASS(celluloid_plugins_manager_item_parent_class)
100 ->constructed(object);
101 }
102
103 static void
celluloid_plugins_manager_item_finalize(GObject * object)104 celluloid_plugins_manager_item_finalize(GObject *object)
105 {
106 CelluloidPluginsManagerItem *self = CELLULOID_PLUGINS_MANAGER_ITEM(object);
107
108 g_free(self->title);
109 g_free(self->path);
110
111 G_OBJECT_CLASS(celluloid_plugins_manager_item_parent_class)
112 ->finalize(object);
113 }
114
115 static void
celluloid_plugins_manager_item_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)116 celluloid_plugins_manager_item_set_property( GObject *object,
117 guint property_id,
118 const GValue *value,
119 GParamSpec *pspec )
120 {
121 CelluloidPluginsManagerItem *self = CELLULOID_PLUGINS_MANAGER_ITEM(object);
122
123 if(property_id == PROP_PARENT)
124 {
125 self->parent_window = g_value_get_pointer(value);
126 }
127 else if(property_id == PROP_TITLE)
128 {
129 g_free(self->title);
130
131 self->title = g_value_dup_string(value);
132 }
133 else if(property_id == PROP_PATH)
134 {
135 g_free(self->path);
136
137 self->path = g_value_dup_string(value);
138 }
139 else
140 {
141 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
142 }
143 }
144
145 static void
celluloid_plugins_manager_item_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)146 celluloid_plugins_manager_item_get_property( GObject *object,
147 guint property_id,
148 GValue *value,
149 GParamSpec *pspec )
150 {
151 CelluloidPluginsManagerItem *self = CELLULOID_PLUGINS_MANAGER_ITEM(object);
152
153 if(property_id == PROP_PARENT)
154 {
155 g_value_set_pointer(value, self->parent_window);
156 }
157 else if(property_id == PROP_TITLE)
158 {
159 g_value_set_string(value, self->title);
160 }
161 else if(property_id == PROP_PATH)
162 {
163 g_value_set_string(value, self->path);
164 }
165 else
166 {
167 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
168 }
169 }
170
171 static void
remove_response_handler(GtkDialog * dialog,gint response_id,gpointer data)172 remove_response_handler(GtkDialog *dialog, gint response_id, gpointer data)
173 {
174 CelluloidPluginsManagerItem *item = data;
175 GFile *file = g_file_new_for_path(item->path);
176 GError *error = NULL;
177
178 if(response_id == GTK_RESPONSE_YES)
179 {
180 g_file_delete(file, NULL, &error);
181 }
182
183 gtk_window_destroy(GTK_WINDOW(dialog));
184
185 if(error)
186 {
187 GtkWidget *error_dialog;
188
189 error_dialog = gtk_message_dialog_new
190 ( item->parent_window,
191 GTK_DIALOG_MODAL|
192 GTK_DIALOG_DESTROY_WITH_PARENT,
193 GTK_MESSAGE_ERROR,
194 GTK_BUTTONS_OK,
195 _("Failed to delete file '%s'. "
196 "Reason: %s"),
197 g_file_get_uri(file),
198 error->message );
199
200 g_warning( "Failed to delete file '%s'. Reason: %s",
201 g_file_get_uri(file),
202 error->message );
203
204 gtk_window_set_modal(GTK_WINDOW(error_dialog), TRUE);
205 gtk_widget_show(error_dialog);
206
207 gtk_window_destroy(GTK_WINDOW(error_dialog));
208 g_error_free(error);
209 }
210
211 g_object_unref(file);
212 }
213
214 static void
remove_handler(GtkButton * button,gpointer data)215 remove_handler(GtkButton *button, gpointer data)
216 {
217 CelluloidPluginsManagerItem *item = data;
218 GtkWidget *confirm_dialog = gtk_message_dialog_new
219 ( item->parent_window,
220 GTK_DIALOG_MODAL|
221 GTK_DIALOG_DESTROY_WITH_PARENT,
222 GTK_MESSAGE_QUESTION,
223 GTK_BUTTONS_YES_NO,
224 _("Are you sure you want to "
225 "remove this script? This "
226 "action cannot be undone."));
227
228 g_signal_connect( confirm_dialog,
229 "response",
230 G_CALLBACK(remove_response_handler),
231 item );
232
233 gtk_window_set_modal(GTK_WINDOW(confirm_dialog), TRUE);
234 gtk_widget_show(confirm_dialog);
235 }
236
237 static void
celluloid_plugins_manager_item_class_init(CelluloidPluginsManagerItemClass * klass)238 celluloid_plugins_manager_item_class_init(CelluloidPluginsManagerItemClass *klass)
239 {
240 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
241 GParamSpec *pspec = NULL;
242
243 obj_class->constructed = celluloid_plugins_manager_item_constructed;
244 obj_class->finalize = celluloid_plugins_manager_item_finalize;
245 obj_class->set_property = celluloid_plugins_manager_item_set_property;
246 obj_class->get_property = celluloid_plugins_manager_item_get_property;
247
248 pspec = g_param_spec_pointer
249 ( "parent",
250 "Parent",
251 "Parent window for the dialogs",
252 G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
253 g_object_class_install_property(obj_class, PROP_PARENT, pspec);
254
255 pspec = g_param_spec_string
256 ( "title",
257 "Title",
258 "The string to display as the title of the item",
259 "",
260 G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
261 g_object_class_install_property(obj_class, PROP_TITLE, pspec);
262
263 pspec = g_param_spec_string
264 ( "path",
265 "Path",
266 "The path to the file that this item references",
267 "",
268 G_PARAM_CONSTRUCT_ONLY|G_PARAM_READWRITE );
269 g_object_class_install_property(obj_class, PROP_PATH, pspec);
270 }
271
272 static void
celluloid_plugins_manager_item_init(CelluloidPluginsManagerItem * item)273 celluloid_plugins_manager_item_init(CelluloidPluginsManagerItem *item)
274 {
275 item->parent_window = NULL;
276 item->title = NULL;
277 item->path = NULL;
278 }
279
280 GtkWidget *
celluloid_plugins_manager_item_new(GtkWindow * parent,const gchar * title,const gchar * path)281 celluloid_plugins_manager_item_new( GtkWindow *parent,
282 const gchar *title,
283 const gchar *path )
284 {
285 return GTK_WIDGET(g_object_new( celluloid_plugins_manager_item_get_type(),
286 "parent", parent,
287 "title", title,
288 "path", path,
289 NULL));
290 }
291