Skip to content

Commit 351a97a

Browse files
committed
Renamer 1.1.2 (Jul / 20 / 2008)
* Windows version available * Fixed a crash bug during shutdown * Literal search and replace now replaces all instances of the specified text
1 parent 356db7d commit 351a97a

File tree

1 file changed

+340
-0
lines changed

1 file changed

+340
-0
lines changed

main.c

Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
#include <gtk/gtk.h>
2+
#include <string.h>
3+
4+
enum {
5+
COL_NAME = 0,
6+
COL_PATH,
7+
NUM_COLS
8+
} ;
9+
10+
GtkWidget *list = NULL;
11+
GtkListStore *store = NULL;
12+
GtkWidget *entry_search = NULL;
13+
GtkWidget *entry_replace = NULL;
14+
GtkWidget *checkbox = NULL;
15+
GRegex *rx_name = NULL;
16+
GRegex *rx_path = NULL;
17+
GRegex *rx_replace = NULL;
18+
GRegex *rx_split = NULL;
19+
20+
int g_rename(const gchar *oldfilename, const gchar *newfilename);
21+
void destroy(void);
22+
23+
/* ************************************************************************ *
24+
* UTILITY FUNCTIONS
25+
* ************************************************************************ */
26+
gchar *replace_str(gchar *str, gchar *orig, gchar *rep)
27+
{
28+
static gchar buffer[4096];
29+
gchar *p;
30+
31+
strncpy(buffer, str, strlen(str));
32+
buffer[strlen(str)] = '\0';
33+
34+
while((p = strstr(str, orig))) // Is 'orig' even in 'str'?
35+
{
36+
strncpy(buffer, str, p-str); // Copy characters from 'str' start to 'orig' st$
37+
buffer[p-str] = '\0';
38+
39+
sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig));
40+
str = buffer;
41+
}
42+
return str;
43+
}
44+
45+
/* ************************************************************************ *
46+
* POPULATING THE LIST (DRAG-N-DROP)
47+
* ************************************************************************ */
48+
void view_onDragDataReceived(GtkWidget *wgt, GdkDragContext *context, int x, int y,
49+
GtkSelectionData *seldata, guint info, guint time)
50+
{
51+
GtkTreeIter iter;
52+
gchar **strings = g_regex_split(rx_split, (gchar*)seldata->data, 0);
53+
gchar *input = NULL;
54+
int index = 0;
55+
56+
while (strings[index] != NULL && strcmp(strings[index], "") != 0)
57+
{
58+
input = strings[index];
59+
gtk_list_store_append(GTK_LIST_STORE(store), &iter);
60+
gtk_list_store_set(GTK_LIST_STORE(store), &iter, COL_NAME,
61+
g_regex_replace(rx_name, input, strlen(input), 0, "\\1", 0, NULL), -1);
62+
#ifdef WIN_32
63+
gtk_list_store_set(GTK_LIST_STORE(store), &iter, COL_PATH,
64+
replace_str(g_regex_replace(rx_path,
65+
input,
66+
strlen(input),
67+
0, "\\1", 0,
68+
NULL), "%20", " "), -1);
69+
#else
70+
gtk_list_store_set(GTK_LIST_STORE(store), &iter, COL_PATH,
71+
g_regex_replace(rx_path, input, strlen(input), 0, "\\1", 0, NULL), -1);
72+
#endif
73+
++index;
74+
}
75+
}
76+
77+
/* ************************************************************************ *
78+
* REMOVING ITEMS FROM THE LIST
79+
* ************************************************************************ */
80+
gboolean get_reference_foreach (GtkTreeModel *model,
81+
GtkTreePath *path,
82+
GtkTreeIter *iter,
83+
GList **rowref_list)
84+
{
85+
*rowref_list = g_list_append(*rowref_list, gtk_tree_row_reference_new(model, path));
86+
return TRUE;
87+
}
88+
89+
void clear_selected()
90+
{
91+
GList *selected = NULL; /* references of selected items */
92+
GList *node;
93+
94+
gtk_tree_selection_selected_foreach(gtk_tree_view_get_selection(GTK_TREE_VIEW(list)),
95+
(GtkTreeSelectionForeachFunc) get_reference_foreach,
96+
&selected);
97+
98+
for ( node = selected; node != NULL; node = node->next )
99+
{
100+
GtkTreePath *path = gtk_tree_row_reference_get_path((GtkTreeRowReference*)node->data);
101+
102+
if (path)
103+
{
104+
GtkTreeIter iter;
105+
106+
if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path))
107+
{ gtk_list_store_remove(store, &iter); }
108+
109+
gtk_tree_path_free(path);
110+
}
111+
}
112+
113+
g_list_foreach(selected, (GFunc) gtk_tree_row_reference_free, NULL);
114+
g_list_free(selected);
115+
g_list_free(node);
116+
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(list));
117+
}
118+
119+
void clear_list()
120+
{
121+
gtk_tree_selection_select_all(gtk_tree_view_get_selection(GTK_TREE_VIEW(list)));
122+
clear_selected();
123+
}
124+
125+
/* ************************************************************************ *
126+
* PERFORMING THE SEARCH AND REPLACE
127+
* ************************************************************************ */
128+
gboolean rename_foreach (GtkTreeModel *model,
129+
GtkTreePath *path,
130+
GtkTreeIter *iter)
131+
{
132+
gchar *_name, *_path, *_name2;
133+
134+
gtk_tree_model_get (model, iter, COL_NAME, &_name, -1);
135+
gtk_tree_model_get (model, iter, COL_PATH, &_path, -1);
136+
137+
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox))) {
138+
_name2 = g_regex_replace(rx_replace, _name, strlen(_name), 0,
139+
gtk_entry_get_text(GTK_ENTRY(entry_replace)), 0, NULL);
140+
} else {
141+
_name2 = replace_str(_name, (gchar*) gtk_entry_get_text(GTK_ENTRY(entry_search)),
142+
(gchar*) gtk_entry_get_text(GTK_ENTRY(entry_replace)));
143+
}
144+
145+
if (g_rename(g_strconcat(_path, _name, NULL), g_strconcat(_path, _name2, NULL)) == 0)
146+
{ gtk_list_store_set (store, iter, COL_NAME, _name2, -1); }
147+
148+
return FALSE;
149+
}
150+
151+
void search_and_replace(void)
152+
{
153+
rx_replace = g_regex_new(gtk_entry_get_text(GTK_ENTRY(entry_search)), G_REGEX_OPTIMIZE, 0, NULL);
154+
155+
gtk_tree_model_foreach(GTK_TREE_MODEL(store),
156+
(GtkTreeModelForeachFunc) rename_foreach,
157+
NULL);
158+
159+
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(list));
160+
}
161+
162+
/* ************************************************************************ *
163+
* KEY PRESS HANDLERS
164+
* ************************************************************************ */
165+
gboolean key_press_event (GtkWidget *widget,
166+
GdkEventKey *event,
167+
gpointer user_data)
168+
{
169+
if(event->keyval == 65307) /* Escape Key */
170+
{ destroy(); }
171+
else if((GTK_WIDGET_HAS_FOCUS(entry_search) || GTK_WIDGET_HAS_FOCUS(entry_replace))
172+
&& (event->keyval == 65293 || event->keyval == 65421)) /* Enter Keys */
173+
{ search_and_replace(); }
174+
else if(GTK_WIDGET_HAS_FOCUS(list) && event->keyval == 65535) /* Delete Key */
175+
{ clear_selected(); }
176+
177+
return FALSE;
178+
}
179+
180+
/* ************************************************************************ *
181+
* DESTRUCTOR
182+
* ************************************************************************ */
183+
void destroy(void)
184+
{
185+
g_regex_unref(rx_name);
186+
g_regex_unref(rx_path);
187+
g_regex_unref(rx_split);
188+
if (rx_replace != NULL)
189+
g_regex_unref(rx_replace);
190+
gtk_main_quit();
191+
}
192+
193+
/* ************************************************************************ *
194+
* WIDGETS & BASE SETUP
195+
* ************************************************************************ */
196+
static GtkWidget *create_view_and_model (void)
197+
{
198+
GtkCellRenderer *renderer;
199+
GtkWidget *view;
200+
201+
view = gtk_tree_view_new ();
202+
203+
/* --- Column #1 --- */
204+
renderer = gtk_cell_renderer_text_new ();
205+
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
206+
-1,
207+
"File Name",
208+
renderer,
209+
"text", COL_NAME,
210+
NULL);
211+
212+
/* --- Column #2 --- */
213+
renderer = gtk_cell_renderer_text_new ();
214+
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
215+
-1,
216+
"Path",
217+
renderer,
218+
"text", COL_PATH,
219+
NULL);
220+
221+
store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING);
222+
gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (store));
223+
224+
/* Make tree view a destination for Drag'n'Drop */
225+
if (1)
226+
{
227+
enum {
228+
TARGET_STRING,
229+
TARGET_URL
230+
};
231+
232+
static GtkTargetEntry targetentries[] =
233+
{
234+
{ "STRING", 0, TARGET_STRING },
235+
{ "text/plain", 0, TARGET_STRING },
236+
{ "text/uri-list", 0, TARGET_URL },
237+
};
238+
239+
gtk_drag_dest_set(view, GTK_DEST_DEFAULT_ALL, targetentries, 3,
240+
GDK_ACTION_COPY|GDK_ACTION_MOVE|GDK_ACTION_LINK);
241+
242+
g_signal_connect(view, "drag_data_received",
243+
G_CALLBACK(view_onDragDataReceived), NULL);
244+
}
245+
246+
return view;
247+
}
248+
249+
int main (int argc, char *argv[])
250+
{
251+
GtkWidget *win = NULL;
252+
GtkWidget *vbox = NULL;
253+
GtkWidget *hbox = NULL;
254+
GtkWidget *table = NULL;
255+
GtkWidget *scroll = NULL;
256+
GtkWidget *align = NULL;
257+
GtkWidget *label = NULL;
258+
GtkWidget *button = NULL;
259+
260+
/* Initialize GTK+ */
261+
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
262+
gtk_init (&argc, &argv);
263+
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);
264+
265+
/* Create the main window */
266+
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
267+
gtk_window_set_default_size(GTK_WINDOW(win), 500, 380);
268+
gtk_container_set_border_width (GTK_CONTAINER (win), 8);
269+
gtk_window_set_title (GTK_WINDOW (win), "Multi-File Renamer - v1.1.2"); /* Jul / 20 / 2008 */
270+
gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_NONE);
271+
gtk_widget_realize (win);
272+
g_signal_connect (win, "destroy", destroy, NULL);
273+
gtk_signal_connect (GTK_OBJECT (win), "key_press_event",
274+
GTK_SIGNAL_FUNC (key_press_event),
275+
NULL);
276+
277+
/* Form-wide Widgets */
278+
vbox = gtk_vbox_new (FALSE, 6);
279+
gtk_container_add (GTK_CONTAINER (win), vbox);
280+
281+
/* First row of the Form */
282+
scroll = gtk_scrolled_window_new(NULL, NULL);
283+
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
284+
gtk_box_pack_start(GTK_BOX(vbox), scroll, TRUE, TRUE, 0);
285+
286+
list = create_view_and_model();
287+
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(list)), GTK_SELECTION_MULTIPLE);
288+
gtk_container_add(GTK_CONTAINER(scroll), list);
289+
290+
/* Second / Third rows of the Form */
291+
table = gtk_table_new(2, 2, FALSE);
292+
gtk_table_set_row_spacings(GTK_TABLE(table), 6);
293+
gtk_table_set_col_spacings(GTK_TABLE(table), 6);
294+
gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
295+
296+
label = gtk_label_new("Search:");
297+
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
298+
entry_search = gtk_entry_new();
299+
gtk_table_attach_defaults(GTK_TABLE(table), entry_search, 1, 2, 0, 1);
300+
301+
label = gtk_label_new("Replace:");
302+
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
303+
entry_replace = gtk_entry_new();
304+
gtk_table_attach_defaults(GTK_TABLE(table), entry_replace, 1, 2, 1, 2);
305+
306+
/* Fourth row of the Form */
307+
hbox = gtk_hbox_new(FALSE, 6);
308+
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
309+
310+
checkbox = gtk_check_button_new_with_label("Use Regex");
311+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), TRUE);
312+
gtk_box_pack_start(GTK_BOX(hbox), checkbox, FALSE, FALSE, 0);
313+
314+
align = gtk_alignment_new(1, 0, 0, 0);
315+
gtk_box_pack_start(GTK_BOX(hbox), align, TRUE, TRUE, 0);
316+
317+
button = gtk_button_new_with_label ("Clear List");
318+
g_signal_connect (button, "clicked", G_CALLBACK (clear_list), NULL);
319+
gtk_container_add(GTK_CONTAINER(align), button);
320+
321+
button = gtk_button_new_with_label ("Search and Replace");
322+
g_signal_connect (button, "clicked", G_CALLBACK (search_and_replace), NULL);
323+
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
324+
325+
/* Complie Regex Patterns */
326+
#ifdef WIN_32
327+
rx_name = g_regex_new(".*/([^/\r]+)\r?$", G_REGEX_OPTIMIZE, 0, NULL);
328+
rx_path = g_regex_new("file:///(.*?/)[^/]+$", G_REGEX_OPTIMIZE, 0, NULL);
329+
#else
330+
rx_name = g_regex_new(".*/([^/]+)$", G_REGEX_OPTIMIZE, 0, NULL);
331+
rx_path = g_regex_new("file://(.*?/)[^/]+$", G_REGEX_OPTIMIZE, 0, NULL);
332+
#endif
333+
rx_split = g_regex_new("\n", G_REGEX_OPTIMIZE, 0, NULL);
334+
335+
/* Enter the main loop */
336+
gtk_widget_show_all (win);
337+
gtk_main ();
338+
339+
return 0;
340+
}

0 commit comments

Comments
 (0)