PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/gnome-commander-1.2.8.15/src/gnome-cmd-advrename-dialog.cc

#
C++ | 733 lines | 518 code | 188 blank | 27 comment | 31 complexity | 832bf31589dd0af1b01b08198eb3cae6 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. GNOME Commander - A GNOME based file manager
  3. Copyright (C) 2001-2006 Marcus Bjurman
  4. Copyright (C) 2007-2011 Piotr Eljasiak
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
  16. */
  17. #include <config.h>
  18. #include <sys/types.h>
  19. #include <regex.h>
  20. #include <unistd.h>
  21. #include <errno.h>
  22. #include <gtk/gtkdialog.h>
  23. #include "gnome-cmd-includes.h"
  24. #include "gnome-cmd-convert.h"
  25. #include "gnome-cmd-advrename-dialog.h"
  26. #include "gnome-cmd-profile-component.h"
  27. #include "dialogs/gnome-cmd-advrename-regex-dialog.h"
  28. #include "dialogs/gnome-cmd-manage-profiles-dialog.h"
  29. #include "gnome-cmd-advrename-lexer.h"
  30. #include "gnome-cmd-file.h"
  31. #include "gnome-cmd-treeview.h"
  32. #include "gnome-cmd-menu-button.h"
  33. #include "gnome-cmd-data.h"
  34. #include "tags/gnome-cmd-tags.h"
  35. #include "utils.h"
  36. using namespace std;
  37. struct GnomeCmdAdvrenameDialogClass
  38. {
  39. GtkDialogClass parent_class;
  40. };
  41. struct GnomeCmdAdvrenameDialog::Private
  42. {
  43. gboolean template_has_counters;
  44. GtkWidget *vbox;
  45. GnomeCmdProfileComponent *profile_component;
  46. GtkWidget *files_view;
  47. GtkWidget *profile_menu_button;
  48. Private();
  49. ~Private();
  50. static gchar *translate_menu (const gchar *path, gpointer data);
  51. GtkWidget *create_placeholder_menu(GnomeCmdData::AdvrenameConfig *cfg);
  52. GtkWidget *create_button_with_menu(gchar *label_text, GnomeCmdData::AdvrenameConfig *cfg=NULL);
  53. static void manage_profiles(GnomeCmdAdvrenameDialog::Private *priv, guint unused, GtkWidget *menu);
  54. static void load_profile(GnomeCmdAdvrenameDialog::Private *priv, guint profile_idx, GtkWidget *menu);
  55. void files_view_popup_menu (GtkWidget *treeview, GnomeCmdAdvrenameDialog *dialog, GdkEventButton *event=NULL);
  56. static void on_profile_template_changed (GnomeCmdProfileComponent *component, GnomeCmdAdvrenameDialog *dialog);
  57. static void on_profile_counter_changed (GnomeCmdProfileComponent *component, GnomeCmdAdvrenameDialog *dialog);
  58. static void on_profile_regex_changed (GnomeCmdProfileComponent *component, GnomeCmdAdvrenameDialog *dialog);
  59. static void on_files_model_row_deleted (GtkTreeModel *files, GtkTreePath *path, GnomeCmdAdvrenameDialog *dialog);
  60. static void on_files_view_popup_menu__remove (GtkWidget *menuitem, GtkTreeView *treeview);
  61. static void on_files_view_popup_menu__view_file (GtkWidget *menuitem, GtkTreeView *treeview);
  62. static void on_files_view_popup_menu__show_properties (GtkWidget *menuitem, GtkTreeView *treeview);
  63. static void on_files_view_popup_menu__update_files (GtkWidget *menuitem, GnomeCmdAdvrenameDialog *dialog);
  64. static gboolean on_files_view_button_pressed (GtkWidget *treeview, GdkEventButton *event, GnomeCmdAdvrenameDialog *dialog);
  65. static gboolean on_files_view_popup_menu (GtkWidget *treeview, GnomeCmdAdvrenameDialog *dialog);
  66. static void on_files_view_row_activated (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, GnomeCmdAdvrenameDialog *dialog);
  67. static gboolean on_dialog_delete (GtkWidget *widget, GdkEvent *event, GnomeCmdAdvrenameDialog *dialog);
  68. static void on_dialog_size_allocate (GtkWidget *widget, GtkAllocation *allocation, GnomeCmdAdvrenameDialog *dialog);
  69. static void on_dialog_response (GnomeCmdAdvrenameDialog *dialog, int response_id, gpointer data);
  70. };
  71. inline GnomeCmdAdvrenameDialog::Private::Private()
  72. {
  73. profile_menu_button = NULL;
  74. template_has_counters = FALSE;
  75. }
  76. inline GnomeCmdAdvrenameDialog::Private::~Private()
  77. {
  78. }
  79. inline gboolean model_is_empty(GtkTreeModel *tree_model)
  80. {
  81. GtkTreeIter iter;
  82. return !gtk_tree_model_get_iter_first (tree_model, &iter);
  83. }
  84. gchar *GnomeCmdAdvrenameDialog::Private::translate_menu (const gchar *path, gpointer data)
  85. {
  86. return _(path);
  87. }
  88. inline GtkWidget *GnomeCmdAdvrenameDialog::Private::create_placeholder_menu(GnomeCmdData::AdvrenameConfig *cfg)
  89. {
  90. guint items_size = cfg->profiles.empty() ? 1 : cfg->profiles.size()+3;
  91. GtkItemFactoryEntry *items = g_try_new0 (GtkItemFactoryEntry, items_size);
  92. GtkItemFactoryEntry *i = items;
  93. g_return_val_if_fail (items!=NULL, NULL);
  94. i->path = g_strdup (_("/_Save Profile As..."));
  95. i->callback = (GtkItemFactoryCallback) manage_profiles;
  96. i->callback_action = TRUE;
  97. i->item_type = "<StockItem>";
  98. i->extra_data = GTK_STOCK_SAVE_AS;
  99. ++i;
  100. if (!cfg->profiles.empty())
  101. {
  102. i->path = g_strdup (_("/_Manage Profiles..."));
  103. i->callback = (GtkItemFactoryCallback) manage_profiles;
  104. i->item_type = "<StockItem>";
  105. i->extra_data = GTK_STOCK_EDIT;
  106. ++i;
  107. i->path = g_strdup ("/");
  108. i->item_type = "<Separator>";
  109. ++i;
  110. for (vector<GnomeCmdData::AdvrenameConfig::Profile>::const_iterator p=cfg->profiles.begin(); p!=cfg->profiles.end(); ++p, ++i)
  111. {
  112. i->path = g_strconcat ("/", p->name.c_str(), NULL);
  113. i->callback = (GtkItemFactoryCallback) load_profile;
  114. i->callback_action = (i-items)-3;
  115. i->item_type = "<StockItem>";
  116. i->extra_data = GTK_STOCK_REVERT_TO_SAVED;
  117. }
  118. }
  119. GtkItemFactory *ifac = gtk_item_factory_new (GTK_TYPE_MENU, "<main>", NULL);
  120. gtk_item_factory_create_items (ifac, items_size, items, this);
  121. for (guint i=0; i<items_size; ++i)
  122. g_free (items[i].path);
  123. g_free (items);
  124. return gtk_item_factory_get_widget (ifac, "<main>");
  125. }
  126. inline GtkWidget *GnomeCmdAdvrenameDialog::Private::create_button_with_menu(gchar *label_text, GnomeCmdData::AdvrenameConfig *cfg)
  127. {
  128. profile_menu_button = gnome_cmd_button_menu_new (label_text, create_placeholder_menu(cfg));
  129. return profile_menu_button;
  130. }
  131. void GnomeCmdAdvrenameDialog::Private::manage_profiles(GnomeCmdAdvrenameDialog::Private *priv, guint new_profile, GtkWidget *widget)
  132. {
  133. GtkWidget *dialog = gtk_widget_get_ancestor (priv->profile_menu_button, GNOME_CMD_TYPE_ADVRENAME_DIALOG);
  134. g_return_if_fail (dialog!=NULL);
  135. GnomeCmdData::AdvrenameConfig &cfg = GNOME_CMD_ADVRENAME_DIALOG(dialog)->defaults;
  136. if (new_profile)
  137. priv->profile_component->copy();
  138. if (gnome_cmd_manage_profiles_dialog_new (_("Profiles"), GTK_WINDOW (dialog), cfg, new_profile))
  139. {
  140. GtkWidget *menu = widget->parent;
  141. gnome_cmd_button_menu_disconnect_handler (priv->profile_menu_button, menu);
  142. g_object_unref (gtk_item_factory_from_widget (menu));
  143. gnome_cmd_button_menu_connect_handler (priv->profile_menu_button, priv->create_placeholder_menu(&cfg));
  144. }
  145. }
  146. void GnomeCmdAdvrenameDialog::Private::load_profile(GnomeCmdAdvrenameDialog::Private *priv, guint profile_idx, GtkWidget *widget)
  147. {
  148. GtkWidget *dialog = gtk_widget_get_ancestor (priv->profile_menu_button, GNOME_CMD_TYPE_ADVRENAME_DIALOG);
  149. g_return_if_fail (dialog!=NULL);
  150. GnomeCmdData::AdvrenameConfig &cfg = GNOME_CMD_ADVRENAME_DIALOG(dialog)->defaults;
  151. g_return_if_fail (profile_idx<cfg.profiles.size());
  152. cfg.default_profile = cfg.profiles[profile_idx];
  153. priv->profile_component->update();
  154. GNOME_CMD_ADVRENAME_DIALOG(dialog)->update_new_filenames(); // FIXME: ??
  155. }
  156. inline GtkTreeModel *create_files_model ();
  157. inline GtkWidget *create_files_view ();
  158. G_DEFINE_TYPE (GnomeCmdAdvrenameDialog, gnome_cmd_advrename_dialog, GTK_TYPE_DIALOG)
  159. void GnomeCmdAdvrenameDialog::Private::on_profile_template_changed (GnomeCmdProfileComponent *component, GnomeCmdAdvrenameDialog *dialog)
  160. {
  161. gnome_cmd_advrename_parse_template (component->get_template_entry(), dialog->priv->template_has_counters);
  162. dialog->update_new_filenames();
  163. }
  164. void GnomeCmdAdvrenameDialog::Private::on_profile_counter_changed (GnomeCmdProfileComponent *component, GnomeCmdAdvrenameDialog *dialog)
  165. {
  166. if (dialog->priv->template_has_counters)
  167. dialog->update_new_filenames();
  168. }
  169. void GnomeCmdAdvrenameDialog::Private::on_profile_regex_changed (GnomeCmdProfileComponent *component, GnomeCmdAdvrenameDialog *dialog)
  170. {
  171. dialog->update_new_filenames();
  172. }
  173. void GnomeCmdAdvrenameDialog::Private::on_files_model_row_deleted (GtkTreeModel *files, GtkTreePath *path, GnomeCmdAdvrenameDialog *dialog)
  174. {
  175. if (dialog->priv->template_has_counters)
  176. dialog->update_new_filenames();
  177. }
  178. void GnomeCmdAdvrenameDialog::Private::on_files_view_popup_menu__remove (GtkWidget *menuitem, GtkTreeView *treeview)
  179. {
  180. GtkTreeIter iter;
  181. if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (treeview), NULL, &iter))
  182. {
  183. GtkTreeModel *model = gtk_tree_view_get_model (treeview);
  184. GnomeCmdFile *f;
  185. gtk_tree_model_get (model, &iter, COL_FILE, &f, -1);
  186. gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
  187. gnome_cmd_file_unref (f);
  188. }
  189. }
  190. void GnomeCmdAdvrenameDialog::Private::on_files_view_popup_menu__view_file (GtkWidget *menuitem, GtkTreeView *treeview)
  191. {
  192. GtkTreeIter iter;
  193. if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (treeview), NULL, &iter))
  194. {
  195. GtkTreeModel *model = gtk_tree_view_get_model (treeview);
  196. GnomeCmdFile *f;
  197. gtk_tree_model_get (model, &iter, COL_FILE, &f, -1);
  198. if (f)
  199. gnome_cmd_file_view (f, -1);
  200. }
  201. }
  202. void GnomeCmdAdvrenameDialog::Private::on_files_view_popup_menu__show_properties (GtkWidget *menuitem, GtkTreeView *treeview)
  203. {
  204. GtkTreeIter iter;
  205. if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (treeview), NULL, &iter))
  206. {
  207. GtkTreeModel *model = gtk_tree_view_get_model (treeview);
  208. GnomeCmdFile *f;
  209. gtk_tree_model_get (model, &iter, COL_FILE, &f, -1);
  210. if (f)
  211. gnome_cmd_file_show_properties (f);
  212. }
  213. }
  214. void GnomeCmdAdvrenameDialog::Private::on_files_view_popup_menu__update_files (GtkWidget *menuitem, GnomeCmdAdvrenameDialog *dialog)
  215. {
  216. GtkTreeIter i;
  217. GnomeCmdFile *f;
  218. // re-read file attributes, as they could be changed...
  219. for (gboolean valid_iter=gtk_tree_model_get_iter_first (dialog->files, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (dialog->files, &i))
  220. {
  221. gtk_tree_model_get (dialog->files, &i,
  222. COL_FILE, &f,
  223. -1);
  224. gtk_list_store_set (GTK_LIST_STORE (dialog->files), &i,
  225. COL_NAME, gnome_cmd_file_get_name (f),
  226. COL_SIZE, gnome_cmd_file_get_size (f),
  227. COL_DATE, gnome_cmd_file_get_mdate (f, FALSE),
  228. COL_RENAME_FAILED, FALSE,
  229. -1);
  230. }
  231. gnome_cmd_advrename_parse_template (dialog->priv->profile_component->get_template_entry(), dialog->priv->template_has_counters);
  232. dialog->update_new_filenames();
  233. }
  234. inline void GnomeCmdAdvrenameDialog::Private::files_view_popup_menu (GtkWidget *treeview, GnomeCmdAdvrenameDialog *dialog, GdkEventButton *event)
  235. {
  236. GtkWidget *menu = gtk_menu_new ();
  237. GtkWidget *menuitem;
  238. menuitem = gtk_menu_item_new_with_label (_("Remove from file list"));
  239. g_signal_connect (menuitem, "activate", G_CALLBACK (on_files_view_popup_menu__remove), treeview);
  240. gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
  241. menuitem = gtk_menu_item_new_with_label (_("View file"));
  242. g_signal_connect (menuitem, "activate", G_CALLBACK (on_files_view_popup_menu__view_file), treeview);
  243. gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
  244. menuitem = gtk_menu_item_new_with_label (_("File properties"));
  245. g_signal_connect (menuitem, "activate", G_CALLBACK (on_files_view_popup_menu__show_properties), treeview);
  246. gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
  247. gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ());
  248. menuitem = gtk_menu_item_new_with_label (_("Update file list"));
  249. g_signal_connect (menuitem, "activate", G_CALLBACK (on_files_view_popup_menu__update_files), dialog);
  250. gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
  251. gtk_widget_show_all (menu);
  252. gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
  253. (event != NULL) ? event->button : 0, gdk_event_get_time ((GdkEvent*) event));
  254. }
  255. gboolean GnomeCmdAdvrenameDialog::Private::on_files_view_button_pressed (GtkWidget *treeview, GdkEventButton *event, GnomeCmdAdvrenameDialog *dialog)
  256. {
  257. if (event->type==GDK_BUTTON_PRESS && event->button==3)
  258. {
  259. // optional: select row if no row is selected or only one other row is selected
  260. // (will only do something if you set a tree selection mode
  261. // as described later in the tutorial)
  262. if (1)
  263. {
  264. GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
  265. if (gtk_tree_selection_count_selected_rows (selection) <= 1)
  266. {
  267. GtkTreePath *path;
  268. if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview),
  269. (gint) event->x, (gint) event->y,
  270. &path,
  271. NULL, NULL, NULL))
  272. {
  273. gtk_tree_selection_unselect_all (selection);
  274. gtk_tree_selection_select_path (selection, path);
  275. gtk_tree_path_free (path);
  276. }
  277. }
  278. }
  279. dialog->priv->files_view_popup_menu (treeview, dialog, event);
  280. return TRUE;
  281. }
  282. return FALSE;
  283. }
  284. gboolean GnomeCmdAdvrenameDialog::Private::on_files_view_popup_menu (GtkWidget *treeview, GnomeCmdAdvrenameDialog *dialog)
  285. {
  286. dialog->priv->files_view_popup_menu (treeview, dialog);
  287. return TRUE;
  288. }
  289. void GnomeCmdAdvrenameDialog::Private::on_files_view_row_activated (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, GnomeCmdAdvrenameDialog *dialog)
  290. {
  291. on_files_view_popup_menu__show_properties (NULL, view);
  292. }
  293. gboolean GnomeCmdAdvrenameDialog::Private::on_dialog_delete (GtkWidget *widget, GdkEvent *event, GnomeCmdAdvrenameDialog *dialog)
  294. {
  295. return event->type==GDK_DELETE;
  296. }
  297. void GnomeCmdAdvrenameDialog::Private::on_dialog_size_allocate (GtkWidget *widget, GtkAllocation *allocation, GnomeCmdAdvrenameDialog *dialog)
  298. {
  299. dialog->defaults.width = allocation->width;
  300. dialog->defaults.height = allocation->height;
  301. }
  302. void GnomeCmdAdvrenameDialog::Private::on_dialog_response (GnomeCmdAdvrenameDialog *dialog, int response_id, gpointer unused)
  303. {
  304. GtkTreeIter i;
  305. switch (response_id)
  306. {
  307. case GTK_RESPONSE_OK:
  308. case GTK_RESPONSE_APPLY:
  309. for (gboolean valid_iter=gtk_tree_model_get_iter_first (dialog->files, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (dialog->files, &i))
  310. {
  311. GnomeCmdFile *f;
  312. gchar *new_name;
  313. gtk_tree_model_get (dialog->files, &i,
  314. COL_FILE, &f,
  315. COL_NEW_NAME, &new_name,
  316. -1);
  317. GnomeVFSResult result = GNOME_VFS_OK;
  318. if (strcmp (f->info->name, new_name) != 0)
  319. result = gnome_cmd_file_rename (f, new_name);
  320. gtk_list_store_set (GTK_LIST_STORE (dialog->files), &i,
  321. COL_NAME, gnome_cmd_file_get_name (f),
  322. COL_RENAME_FAILED, result!=GNOME_VFS_OK,
  323. -1);
  324. g_free (new_name);
  325. }
  326. dialog->update_new_filenames();
  327. dialog->defaults.templates.add(dialog->priv->profile_component->get_template_entry());
  328. break;
  329. case GTK_RESPONSE_NONE:
  330. case GTK_RESPONSE_DELETE_EVENT:
  331. case GTK_RESPONSE_CANCEL:
  332. case GTK_RESPONSE_CLOSE:
  333. dialog->defaults.templates.add(dialog->priv->profile_component->get_template_entry());
  334. gtk_widget_hide (*dialog);
  335. dialog->unset();
  336. g_signal_stop_emission_by_name (dialog, "response"); // FIXME: ???
  337. break;
  338. case GTK_RESPONSE_HELP:
  339. gnome_cmd_help_display ("gnome-commander.xml", "gnome-commander-advanced-rename");
  340. g_signal_stop_emission_by_name (dialog, "response");
  341. break;
  342. case GCMD_RESPONSE_PROFILES:
  343. break;
  344. case GCMD_RESPONSE_RESET:
  345. dialog->defaults.default_profile.reset();
  346. dialog->priv->profile_component->update();
  347. break;
  348. default :
  349. g_assert_not_reached ();
  350. }
  351. }
  352. static void gnome_cmd_advrename_dialog_init (GnomeCmdAdvrenameDialog *dialog)
  353. {
  354. dialog->priv = new GnomeCmdAdvrenameDialog::Private;
  355. gtk_window_set_title (*dialog, _("Advanced Rename Tool"));
  356. gtk_window_set_resizable (*dialog, TRUE);
  357. gtk_dialog_set_has_separator (*dialog, FALSE);
  358. gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
  359. gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
  360. GtkWidget *vbox = dialog->priv->vbox = gtk_vbox_new (FALSE, 6);
  361. gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
  362. gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), vbox, TRUE, TRUE, 0);
  363. // Results
  364. gchar *str = g_strdup_printf ("<b>%s</b>", _("Results"));
  365. GtkWidget *label = gtk_label_new_with_mnemonic (str);
  366. g_free (str);
  367. gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
  368. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  369. gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
  370. GtkWidget *align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
  371. gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 6, 12, 0);
  372. gtk_container_add (GTK_CONTAINER (vbox), align);
  373. GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  374. gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
  375. gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
  376. gtk_container_add (GTK_CONTAINER (align), scrolled_window);
  377. dialog->priv->files_view = create_files_view ();
  378. gtk_container_add (GTK_CONTAINER (scrolled_window), dialog->priv->files_view);
  379. GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->files_view));
  380. gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
  381. }
  382. static void gnome_cmd_advrename_dialog_finalize (GObject *object)
  383. {
  384. GnomeCmdAdvrenameDialog *dialog = GNOME_CMD_ADVRENAME_DIALOG (object);
  385. delete dialog->priv;
  386. G_OBJECT_CLASS (gnome_cmd_advrename_dialog_parent_class)->finalize (object);
  387. }
  388. static void gnome_cmd_advrename_dialog_class_init (GnomeCmdAdvrenameDialogClass *klass)
  389. {
  390. GObjectClass *object_class = G_OBJECT_CLASS (klass);
  391. object_class->finalize = gnome_cmd_advrename_dialog_finalize;
  392. }
  393. inline GtkTreeModel *create_files_model ()
  394. {
  395. GtkListStore *store = gtk_list_store_new (GnomeCmdAdvrenameDialog::NUM_FILE_COLS,
  396. G_TYPE_POINTER,
  397. G_TYPE_STRING,
  398. G_TYPE_STRING,
  399. G_TYPE_STRING,
  400. G_TYPE_STRING,
  401. G_TYPE_BOOLEAN);
  402. return GTK_TREE_MODEL (store);
  403. }
  404. inline GtkWidget *create_files_view ()
  405. {
  406. GtkWidget *view = gtk_tree_view_new ();
  407. g_object_set (view,
  408. "rules-hint", TRUE,
  409. "reorderable", TRUE,
  410. "enable-search", TRUE,
  411. "search-column", GnomeCmdAdvrenameDialog::COL_NAME,
  412. NULL);
  413. GtkCellRenderer *renderer = NULL;
  414. GtkTreeViewColumn *col = NULL;
  415. GtkTooltips *tips = gtk_tooltips_new ();
  416. col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, GnomeCmdAdvrenameDialog::COL_NAME, _("Old name"));
  417. g_object_set (renderer, "foreground", "red", "style", PANGO_STYLE_ITALIC, NULL);
  418. gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
  419. gtk_tree_view_column_add_attribute (col, renderer, "style-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
  420. gtk_tooltips_set_tip (tips, col->button, _("Current file name"), NULL);
  421. col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, GnomeCmdAdvrenameDialog::COL_NEW_NAME, _("New name"));
  422. g_object_set (renderer, "foreground", "red", "style", PANGO_STYLE_ITALIC, NULL);
  423. gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
  424. gtk_tree_view_column_add_attribute (col, renderer, "style-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
  425. gtk_tooltips_set_tip (tips, col->button, _("New file name"), NULL);
  426. col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, GnomeCmdAdvrenameDialog::COL_SIZE, _("Size"));
  427. g_object_set (renderer, "xalign", 1.0, "foreground", "red", "style", PANGO_STYLE_ITALIC, NULL);
  428. gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
  429. gtk_tree_view_column_add_attribute (col, renderer, "style-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
  430. gtk_tooltips_set_tip (tips, col->button, _("File size"), NULL);
  431. col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, GnomeCmdAdvrenameDialog::COL_DATE, _("Date"));
  432. g_object_set (renderer, "foreground", "red", "style", PANGO_STYLE_ITALIC, NULL);
  433. gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
  434. gtk_tree_view_column_add_attribute (col, renderer, "style-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
  435. gtk_tooltips_set_tip (tips, col->button, _("File modification date"), NULL);
  436. return view;
  437. }
  438. void GnomeCmdAdvrenameDialog::update_new_filenames()
  439. {
  440. gnome_cmd_advrename_reset_counter (defaults.default_profile.counter_start,
  441. defaults.default_profile.counter_width,
  442. defaults.default_profile.counter_step);
  443. GtkTreeIter i;
  444. vector<GnomeCmd::RegexReplace *> rx;
  445. GtkTreeModel *regexes = priv->profile_component->get_regex_model();
  446. for (gboolean valid_iter=gtk_tree_model_get_iter_first (regexes, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (regexes, &i))
  447. {
  448. GnomeCmd::RegexReplace *r;
  449. gtk_tree_model_get (regexes, &i,
  450. GnomeCmdProfileComponent::COL_REGEX, &r,
  451. -1);
  452. if (r && *r) // ignore regex pattern if it can't be retrieved or if it is malformed
  453. rx.push_back(r);
  454. }
  455. for (gboolean valid_iter=gtk_tree_model_get_iter_first (files, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (files, &i))
  456. {
  457. GnomeCmdFile *f;
  458. gtk_tree_model_get (files, &i,
  459. COL_FILE, &f,
  460. -1);
  461. if (!f)
  462. continue;
  463. gchar *fname = gnome_cmd_advrename_gen_fname (f);
  464. for (vector<GnomeCmd::RegexReplace *>::iterator j=rx.begin(); j!=rx.end(); ++j)
  465. {
  466. GnomeCmd::RegexReplace *&r = *j;
  467. gchar *prev_fname = fname;
  468. fname = r->replace(prev_fname);
  469. g_free (prev_fname);
  470. }
  471. fname = priv->profile_component->trim_blanks (priv->profile_component->convert_case (fname));
  472. gtk_list_store_set (GTK_LIST_STORE (files), &i,
  473. COL_NEW_NAME, fname,
  474. -1);
  475. g_free (fname);
  476. }
  477. }
  478. GnomeCmdAdvrenameDialog::GnomeCmdAdvrenameDialog(GnomeCmdData::AdvrenameConfig &cfg): defaults(cfg)
  479. {
  480. gtk_window_set_default_size (*this, cfg.width, cfg.height);
  481. gtk_dialog_add_action_widget (*this,
  482. priv->create_button_with_menu (_("Profiles..."), &cfg),
  483. GCMD_RESPONSE_PROFILES);
  484. gtk_dialog_add_buttons (*this,
  485. GTK_STOCK_HELP, GTK_RESPONSE_HELP,
  486. _("Reset"), GCMD_RESPONSE_RESET,
  487. GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
  488. GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
  489. NULL);
  490. gtk_dialog_set_default_response (*this, GTK_RESPONSE_APPLY);
  491. priv->profile_component = new GnomeCmdProfileComponent(cfg.default_profile);
  492. gtk_box_pack_start (GTK_BOX (priv->vbox), *priv->profile_component, FALSE, FALSE, 0);
  493. gtk_box_reorder_child (GTK_BOX (priv->vbox), *priv->profile_component, 0);
  494. // Template
  495. priv->profile_component->set_template_history(defaults.templates.ents);
  496. // Results
  497. files = create_files_model ();
  498. g_signal_connect (priv->profile_component, "template-changed", G_CALLBACK (Private::on_profile_template_changed), this);
  499. g_signal_connect (priv->profile_component, "counter-changed", G_CALLBACK (Private::on_profile_counter_changed), this);
  500. g_signal_connect (priv->profile_component, "regex-changed", G_CALLBACK (Private::on_profile_regex_changed), this);
  501. g_signal_connect (files, "row-deleted", G_CALLBACK (Private::on_files_model_row_deleted), this);
  502. g_signal_connect (priv->files_view, "button-press-event", G_CALLBACK (Private::on_files_view_button_pressed), this);
  503. g_signal_connect (priv->files_view, "popup-menu", G_CALLBACK (Private::on_files_view_popup_menu), this);
  504. g_signal_connect (priv->files_view, "row-activated", G_CALLBACK (Private::on_files_view_row_activated), this);
  505. g_signal_connect (this, "delete-event", G_CALLBACK (Private::on_dialog_delete), this);
  506. g_signal_connect (this, "size-allocate", G_CALLBACK (Private::on_dialog_size_allocate), this);
  507. g_signal_connect (this, "response", G_CALLBACK (Private::on_dialog_response), this);
  508. gnome_cmd_advrename_parse_template (priv->profile_component->get_template_entry(), priv->template_has_counters);
  509. }
  510. void GnomeCmdAdvrenameDialog::set(GList *file_list)
  511. {
  512. for (GtkTreeIter iter; file_list; file_list=file_list->next)
  513. {
  514. GnomeCmdFile *f = (GnomeCmdFile *) file_list->data;
  515. gtk_list_store_append (GTK_LIST_STORE (files), &iter);
  516. gtk_list_store_set (GTK_LIST_STORE (files), &iter,
  517. COL_FILE, gnome_cmd_file_ref (f),
  518. COL_NAME, gnome_cmd_file_get_name (f),
  519. COL_SIZE, gnome_cmd_file_get_size (f),
  520. COL_DATE, gnome_cmd_file_get_mdate (f, FALSE),
  521. -1);
  522. }
  523. gtk_tree_view_set_model (GTK_TREE_VIEW (priv->files_view), files);
  524. // g_object_unref (files); // destroy model automatically with view
  525. update_new_filenames();
  526. }
  527. void GnomeCmdAdvrenameDialog::unset()
  528. {
  529. gtk_tree_view_set_model (GTK_TREE_VIEW (priv->files_view), NULL); // unset the model
  530. GnomeCmdFile *f;
  531. GtkTreeIter i;
  532. for (gboolean valid_iter=gtk_tree_model_get_iter_first (files, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (files, &i))
  533. {
  534. gtk_tree_model_get (files, &i,
  535. COL_FILE, &f,
  536. -1);
  537. gnome_cmd_file_unref (f);
  538. }
  539. g_signal_handlers_block_by_func (files, gpointer (Private::on_files_model_row_deleted), this);
  540. gtk_list_store_clear (GTK_LIST_STORE (files));
  541. g_signal_handlers_unblock_by_func (files, gpointer (Private::on_files_model_row_deleted), this);
  542. }