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