1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3 * Brasero
4 * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app@wanadoo.fr>
5 *
6 * Brasero 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 2 of the License, or
9 * (at your option) any later version.
10 *
11 * brasero 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.
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with brasero. If not, write to:
18 * The Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <string.h>
28
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <glib/gi18n.h>
32
33 #include <gtk/gtk.h>
34
35 #include "brasero-rename.h"
36
37 typedef struct _BraseroRenamePrivate BraseroRenamePrivate;
38 struct _BraseroRenamePrivate
39 {
40 GtkWidget *notebook;
41 GtkWidget *combo;
42
43 GtkWidget *insert_entry;
44 GtkWidget *insert_combo;
45
46 GtkWidget *delete_entry;
47
48 GtkWidget *substitute_entry;
49 GtkWidget *joker_entry;
50
51 GtkWidget *number_left_entry;
52 GtkWidget *number_right_entry;
53 guint number;
54
55 guint show_default:1;
56 };
57
58 #define BRASERO_RENAME_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_RENAME, BraseroRenamePrivate))
59
60
61
62 G_DEFINE_TYPE (BraseroRename, brasero_rename, GTK_TYPE_BOX);
63
64 void
brasero_rename_set_show_keep_default(BraseroRename * self,gboolean show)65 brasero_rename_set_show_keep_default (BraseroRename *self,
66 gboolean show)
67 {
68 BraseroRenamePrivate *priv;
69
70 priv = BRASERO_RENAME_PRIVATE (self);
71
72 if (!show) {
73 if (!priv->show_default)
74 return;
75
76 gtk_combo_box_text_remove (GTK_COMBO_BOX_TEXT (priv->combo), 0);
77
78 /* make sure there is one item active */
79 if (gtk_combo_box_get_active (GTK_COMBO_BOX (priv->combo)) == -1) {
80 gtk_combo_box_set_active (GTK_COMBO_BOX (priv->combo), 0);
81 gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), 0);
82 gtk_widget_show (priv->notebook);
83 }
84 }
85 else {
86 if (priv->show_default)
87 return;
88
89 gtk_combo_box_text_prepend_text (GTK_COMBO_BOX_TEXT (priv->combo),
90 _("<Keep current values>"));
91 }
92
93 priv->show_default = show;
94 }
95
96 static gchar *
brasero_rename_insert_string(BraseroRename * self,const gchar * name)97 brasero_rename_insert_string (BraseroRename *self,
98 const gchar *name)
99 {
100 BraseroRenamePrivate *priv;
101 gboolean is_at_end;
102 const gchar *text;
103
104 priv = BRASERO_RENAME_PRIVATE (self);
105
106 text = gtk_entry_get_text (GTK_ENTRY (priv->insert_entry));
107 is_at_end = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->insert_combo));
108
109 if (is_at_end)
110 return g_strconcat (name, text, NULL);
111
112 return g_strconcat (text, name, NULL);
113 }
114
115 static gchar *
brasero_rename_delete_string(BraseroRename * self,const gchar * name)116 brasero_rename_delete_string (BraseroRename *self,
117 const gchar *name)
118 {
119 BraseroRenamePrivate *priv;
120 const gchar *text;
121 gchar *occurrence;
122
123 priv = BRASERO_RENAME_PRIVATE (self);
124
125 text = gtk_entry_get_text (GTK_ENTRY (priv->delete_entry));
126 occurrence = g_strstr_len (name, -1, text);
127
128 if (!occurrence)
129 return NULL;
130
131 return g_strdup_printf ("%.*s%s", (int) (occurrence - name), name, occurrence + strlen (text));
132 }
133
134 static gchar *
brasero_rename_substitute_string(BraseroRename * self,const gchar * name)135 brasero_rename_substitute_string (BraseroRename *self,
136 const gchar *name)
137 {
138 BraseroRenamePrivate *priv;
139 const gchar *joker;
140 const gchar *text;
141 gchar *occurrence;
142
143 priv = BRASERO_RENAME_PRIVATE (self);
144
145 text = gtk_entry_get_text (GTK_ENTRY (priv->substitute_entry));
146 occurrence = g_strstr_len (name, -1, text);
147
148 if (!occurrence)
149 return NULL;
150
151 joker = gtk_entry_get_text (GTK_ENTRY (priv->joker_entry));
152 return g_strdup_printf ("%.*s%s%s", (int) (occurrence - name), name, joker, occurrence + strlen (text));
153 }
154
155 static gchar *
brasero_rename_number_string(BraseroRename * self,const gchar * name)156 brasero_rename_number_string (BraseroRename *self,
157 const gchar *name)
158 {
159 BraseroRenamePrivate *priv;
160 const gchar *right;
161 const gchar *left;
162
163 priv = BRASERO_RENAME_PRIVATE (self);
164
165 left = gtk_entry_get_text (GTK_ENTRY (priv->number_left_entry));
166 right = gtk_entry_get_text (GTK_ENTRY (priv->number_right_entry));
167 return g_strdup_printf ("%s%i%s", left, priv->number ++, right);
168 }
169
170 static gchar *
brasero_rename_sequence_string(BraseroRename * self,const gchar * name,guint item_num,guint nb_items)171 brasero_rename_sequence_string (BraseroRename *self,
172 const gchar *name,
173 guint item_num,
174 guint nb_items)
175 {
176 BraseroRenamePrivate *priv;
177
178 priv = BRASERO_RENAME_PRIVATE (self);
179
180 if (!gtk_combo_box_get_active (GTK_COMBO_BOX (priv->insert_combo)))
181 return NULL;
182
183 if (nb_items < 10){
184 return g_strdup_printf ("%i%s", item_num, name);
185 } else if (nb_items < 100){
186 return g_strdup_printf ("%02i%s", item_num, name);
187 } else if (nb_items < 1000){
188 return g_strdup_printf ("%03i%s", item_num, name);
189 } else {
190 return g_strdup_printf ("%04i%s", item_num, name);
191 }
192 }
193
194 gboolean
brasero_rename_do(BraseroRename * self,GtkTreeSelection * selection,guint column_num,BraseroRenameCallback callback)195 brasero_rename_do (BraseroRename *self,
196 GtkTreeSelection *selection,
197 guint column_num,
198 BraseroRenameCallback callback)
199 {
200 BraseroRenamePrivate *priv;
201 GtkTreeModel *model;
202 GList *selected;
203 guint item_num;
204 guint nb_items;
205 GList *item;
206 gint mode;
207
208 priv = BRASERO_RENAME_PRIVATE (self);
209 mode = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->combo));
210
211 mode -= priv->show_default;
212 if (mode < 0)
213 return TRUE;
214
215 selected = gtk_tree_selection_get_selected_rows (selection, &model);
216
217 nb_items = g_list_length (selected);
218 item_num = 0;
219
220 for (item = selected; item; item = item->next, item_num ++) {
221 GtkTreePath *treepath;
222 GtkTreeIter iter;
223 gboolean result;
224 gchar *new_name;
225 gchar *name;
226
227 treepath = item->data;
228 gtk_tree_model_get_iter (model, &iter, treepath);
229
230 gtk_tree_model_get (model, &iter,
231 column_num, &name,
232 -1);
233
234 redo:
235 switch (mode) {
236 case 0:
237 new_name = brasero_rename_insert_string (self, name);
238 break;
239 case 1:
240 new_name = brasero_rename_delete_string (self, name);
241 break;
242 case 2:
243 new_name = brasero_rename_substitute_string (self, name);
244 break;
245 case 3:
246 new_name = brasero_rename_number_string (self, name);
247 break;
248 case 4:
249 new_name = brasero_rename_sequence_string (self, name, item_num, nb_items);
250 break;
251 default:
252 new_name = NULL;
253 break;
254 }
255
256 if (!new_name) {
257 g_free (name);
258 continue;
259 }
260
261 result = callback (model, &iter, treepath, name, new_name);
262
263 if (!result) {
264 if (mode == 3)
265 goto redo;
266
267 g_free (name);
268 break;
269 }
270 g_free (name);
271 }
272
273 g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
274 g_list_free (selected);
275 return TRUE;
276 }
277
278 static void
brasero_rename_type_changed(GtkComboBox * combo,BraseroRename * self)279 brasero_rename_type_changed (GtkComboBox *combo,
280 BraseroRename *self)
281 {
282 BraseroRenamePrivate *priv;
283
284 priv = BRASERO_RENAME_PRIVATE (self);
285
286 if (gtk_combo_box_get_active (combo) - priv->show_default < 0
287 || gtk_combo_box_get_active (combo) - priv->show_default == 4) {
288 gtk_widget_hide (priv->notebook);
289 return;
290 }
291
292 gtk_widget_show (priv->notebook);
293 gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook),
294 gtk_combo_box_get_active (combo) - priv->show_default);
295 }
296
297 static void
brasero_rename_init(BraseroRename * object)298 brasero_rename_init (BraseroRename *object)
299 {
300 BraseroRenamePrivate *priv;
301 GtkWidget *combo;
302 GtkWidget *entry;
303 GtkWidget *label;
304 GtkWidget *hbox;
305
306 priv = BRASERO_RENAME_PRIVATE (object);
307
308 gtk_orientable_set_orientation (GTK_ORIENTABLE (object), GTK_ORIENTATION_VERTICAL);
309
310 priv->notebook = gtk_notebook_new ();
311 gtk_widget_show (priv->notebook);
312 gtk_box_pack_end (GTK_BOX (object), priv->notebook, FALSE, FALSE, 4);
313 gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
314 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
315
316 priv->combo = gtk_combo_box_text_new ();
317 gtk_widget_show (priv->combo);
318 gtk_box_pack_start (GTK_BOX (object), priv->combo, FALSE, FALSE, 0);
319
320 priv->show_default = 1;
321 gtk_combo_box_text_prepend_text (GTK_COMBO_BOX_TEXT (priv->combo), _("<Keep current values>"));
322 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (priv->combo), _("Insert text"));
323 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (priv->combo), _("Delete text"));
324 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (priv->combo), _("Substitute text"));
325 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (priv->combo), _("Number files according to a pattern"));
326 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (priv->combo), _("Insert number sequence at beginning"));
327
328 g_signal_connect (priv->combo,
329 "changed",
330 G_CALLBACK (brasero_rename_type_changed),
331 object);
332
333 gtk_combo_box_set_active (GTK_COMBO_BOX (priv->combo), 0);
334
335 /* Insert */
336 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
337 gtk_widget_show (hbox);
338 gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), hbox, NULL);
339
340 /* Translators: This is a verb. This is completed later */
341 label = gtk_label_new (_("Insert"));
342 gtk_widget_show (label);
343 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
344
345 entry = gtk_entry_new ();
346 gtk_widget_show (entry);
347 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
348 priv->insert_entry = entry;
349
350 combo = gtk_combo_box_text_new ();
351 gtk_widget_show (combo);
352
353 /* Translators: This finishes previous action "Insert". It goes like
354 * this: "Insert" [Entry] "at the beginning". */
355 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("at the beginning"));
356
357 /* Translators: This finishes previous action "Insert". It goes like
358 * this: "Insert" [Entry] "at the end". */
359 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("at the end"));
360
361 gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
362 gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
363 priv->insert_combo = combo;
364
365 /* Delete */
366 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
367 gtk_widget_show (hbox);
368 gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), hbox, NULL);
369
370 label = gtk_label_new (_("Delete every occurrence of"));
371 gtk_widget_show (label);
372 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
373
374 entry = gtk_entry_new ();
375 gtk_widget_show (entry);
376 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
377 priv->delete_entry = entry;
378
379 /* Substitution */
380 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
381 gtk_widget_show (hbox);
382 gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), hbox, NULL);
383
384 /* Translators: this is a verb */
385 label = gtk_label_new_with_mnemonic (_("_Replace"));
386 gtk_widget_show (label);
387 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
388
389 entry = gtk_entry_new ();
390 gtk_widget_show (entry);
391 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
392 priv->substitute_entry = entry;
393
394 gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
395
396 /* Reminder: if this string happens to be used somewhere else in brasero
397 * we'll need a context with C_() macro */
398 /* Translators: this goes with above verb to say "_Replace" [Entry]
399 * "with" [Entry]. */
400 label = gtk_label_new (_("with"));
401 gtk_widget_show (label);
402 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
403
404 entry = gtk_entry_new ();
405 gtk_widget_show (entry);
406 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
407 priv->joker_entry = entry;
408
409 /* Pattern */
410 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
411 gtk_widget_show (hbox);
412 gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), hbox, NULL);
413
414 label = gtk_label_new (_("Rename to"));
415 gtk_widget_show (label);
416 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
417
418 entry = gtk_entry_new ();
419 gtk_widget_show (entry);
420 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
421 priv->number_left_entry = entry;
422
423 label = gtk_label_new (_("{number}"));
424 gtk_widget_show (label);
425 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
426
427 entry = gtk_entry_new ();
428 gtk_widget_show (entry);
429 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
430 priv->number_right_entry = entry;
431 }
432
433 static void
brasero_rename_finalize(GObject * object)434 brasero_rename_finalize (GObject *object)
435 {
436 G_OBJECT_CLASS (brasero_rename_parent_class)->finalize (object);
437 }
438
439 static void
brasero_rename_class_init(BraseroRenameClass * klass)440 brasero_rename_class_init (BraseroRenameClass *klass)
441 {
442 GObjectClass* object_class = G_OBJECT_CLASS (klass);
443
444 g_type_class_add_private (klass, sizeof (BraseroRenamePrivate));
445
446 object_class->finalize = brasero_rename_finalize;
447 }
448
449 GtkWidget *
brasero_rename_new(void)450 brasero_rename_new (void)
451 {
452 return g_object_new (BRASERO_TYPE_RENAME, NULL);
453 }
454