From 8c9a5385cc6093d660399bc3f85abc3002fce170 Mon Sep 17 00:00:00 2001 From: Jeff Shipley Date: Fri, 26 Jul 2013 15:27:58 -0600 Subject: [PATCH] smarter file extension splitting - new method in thunar-util.h to split filenames with complex extensions - simple file rename changed to use new method - bulk file renamer changed to use new method --- thunar/thunar-dialogs.c | 22 ++++++++++------------ thunar/thunar-renamer-model.c | 31 +++++++++++++------------------ thunar/thunar-util.c | 32 ++++++++++++++++++++++++++++++++ thunar/thunar-util.h | 2 ++ 4 files changed, 57 insertions(+), 30 deletions(-) diff --git a/thunar/thunar-dialogs.c b/thunar/thunar-dialogs.c index 953d4f5..ae4abbe 100644 --- a/thunar/thunar-dialogs.c +++ b/thunar/thunar-dialogs.c @@ -62,6 +62,7 @@ thunar_dialogs_show_rename_file (gpointer parent, ThunarIconFactory *icon_factory; GtkIconTheme *icon_theme; const gchar *filename; + gchar **file_parts; const gchar *text; ThunarJob *job = NULL; GtkWidget *dialog; @@ -137,20 +138,17 @@ thunar_dialogs_show_rename_file (gpointer parent, /* check if we don't have a directory here */ if (!thunar_file_is_directory (file)) { - /* check if the filename contains a dot */ - text = g_utf8_strrchr (filename, -1, '.'); - if (G_LIKELY (text != NULL)) - { - /* grab focus to the entry first, else the selection will be altered later */ - gtk_widget_grab_focus (entry); + /* split filename into basename and possible extension */ + file_parts = thunar_util_split_filename(filename); + offset = g_utf8_strlen(file_parts[0], -1); + g_strfreev(file_parts); - /* determine the UTF-8 char offset */ - offset = g_utf8_pointer_to_offset (filename, text); + /* grab focus to the entry first, else the selection will be altered later */ + gtk_widget_grab_focus (entry); - /* select the text prior to the dot */ - if (G_LIKELY (offset > 0)) - gtk_editable_select_region (GTK_EDITABLE (entry), 0, offset); - } + /* select the text prior to the extension */ + if (G_LIKELY (offset > 0)) + gtk_editable_select_region (GTK_EDITABLE (entry), 0, offset); } /* get the size the entry requires to render the full text */ diff --git a/thunar/thunar-renamer-model.c b/thunar/thunar-renamer-model.c index 853b797..2313d49 100644 --- a/thunar/thunar-renamer-model.c +++ b/thunar/thunar-renamer-model.c @@ -33,6 +33,7 @@ #include #include #include +#include @@ -806,11 +807,10 @@ thunar_renamer_model_process_item (ThunarRenamerModel *renamer_model, { ThunarRenamerMode mode; const gchar *display_name; - const gchar *dot; gchar *name = NULL; + gchar **file_parts; gchar *prefix; gchar *suffix; - gchar *text; /* no new name if no renamer is set */ if (G_UNLIKELY (renamer_model->renamer == NULL)) @@ -819,16 +819,14 @@ thunar_renamer_model_process_item (ThunarRenamerModel *renamer_model, /* determine the current display name of the file */ display_name = thunar_file_get_display_name (item->file); - /* determine the last dot in the filename */ - dot = strrchr (display_name, '.'); - if (G_UNLIKELY (dot == display_name || (dot != NULL && dot[1] == '\0'))) - dot = NULL; + /* split filename into basename and possible extension */ + file_parts = thunar_util_split_filename(display_name); /* if we don't have a dot, then no "Suffix only" rename can take place */ - if (G_LIKELY (dot != NULL || renamer_model->mode != THUNAR_RENAMER_MODE_SUFFIX)) + if (G_LIKELY (file_parts[1] != NULL || renamer_model->mode != THUNAR_RENAMER_MODE_SUFFIX)) { /* now, for "Name only", we need a dot, otherwise treat everything as name */ - if (renamer_model->mode == THUNAR_RENAMER_MODE_NAME && dot == NULL) + if (renamer_model->mode == THUNAR_RENAMER_MODE_NAME && file_parts[1] == NULL) mode = THUNAR_RENAMER_MODE_BOTH; else mode = renamer_model->mode; @@ -837,27 +835,21 @@ thunar_renamer_model_process_item (ThunarRenamerModel *renamer_model, switch (mode) { case THUNAR_RENAMER_MODE_NAME: - /* determine the name part of the display name */ - text = g_strndup (display_name, (dot - display_name)); - /* determine the new name */ - prefix = thunarx_renamer_process (renamer_model->renamer, THUNARX_FILE_INFO (item->file), text, idx); + prefix = thunarx_renamer_process (renamer_model->renamer, THUNARX_FILE_INFO (item->file), file_parts[0], idx); /* determine the new full name */ - name = g_strconcat (prefix, dot, NULL); + name = g_strconcat (prefix, file_parts[1], NULL); /* release the temporary strings */ g_free (prefix); - g_free (text); break; case THUNAR_RENAMER_MODE_SUFFIX: /* determine the new suffix */ - suffix = thunarx_renamer_process (renamer_model->renamer, THUNARX_FILE_INFO (item->file), dot + 1, idx); + suffix = thunarx_renamer_process (renamer_model->renamer, THUNARX_FILE_INFO (item->file), file_parts[1] + 1, idx); - prefix = g_strndup (display_name, (dot - display_name) + 1); - name = g_strconcat (prefix, suffix, NULL); - g_free (prefix); + name = g_strconcat (file_parts[0], suffix, NULL); /* release the suffix */ g_free (suffix); @@ -874,6 +866,9 @@ thunar_renamer_model_process_item (ThunarRenamerModel *renamer_model, } } + /* release the file_parts */ + g_strfreev(file_parts); + /* check if the new name is equal to the old one */ if (exo_str_is_equal (name, display_name)) { diff --git a/thunar/thunar-util.c b/thunar/thunar-util.c index 7b8665f..26fb24c 100644 --- a/thunar/thunar-util.c +++ b/thunar/thunar-util.c @@ -234,6 +234,38 @@ thunar_util_expand_filename (const gchar *filename, } +/** + * thunar_util_split_filename: + * @filename : a filename + * + * Returns a NULL-terminated list of strings containing the + * base filename and, if it exists, the file extension. + * + * The caller is responsible to free the returned list using + * g_strfreev() when no longer needed.* +**/ +gchar** +thunar_util_split_filename(const gchar *filename) +{ + gchar **file_parts; + + /** + * Match/return any extension followed by any number of common compound + * extensions. This should get most common cases such as .tar.gz or even + * .desktop.in.in + * + * The biggest limitation is that for a file like annoying.filename.gz it + * will return .filename.gz as the extension (or annoying.filename will get + * .filename as the extension). + **/ + file_parts = g_regex_split_simple( + "(?i)(?!^)(\\.[^.]+(?:\\.(?:gz|bz2|z|lzma|xz|lrz|lzo|in|rpm|bak))*)?$", + filename, 0, 0); + + return file_parts; +} + + /** * thunar_util_humanize_file_time: diff --git a/thunar/thunar-util.h b/thunar/thunar-util.h index 8170bdc..cb3206b 100644 --- a/thunar/thunar-util.h +++ b/thunar/thunar-util.h @@ -41,6 +41,8 @@ gchar *thunar_util_expand_filename (const gchar *filename, GFile *working_directory, GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +gchar **thunar_util_split_filename (const gchar *filename); + gchar *thunar_util_humanize_file_time (guint64 file_time, ThunarDateStyle date_style) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -- 1.8.1.2