diff --git a/thunar/thunar-dialogs.c b/thunar/thunar-dialogs.c index 953d4f5..9c07f4b 100644 --- a/thunar/thunar-dialogs.c +++ b/thunar/thunar-dialogs.c @@ -138,7 +138,7 @@ thunar_dialogs_show_rename_file (gpointer parent, if (!thunar_file_is_directory (file)) { /* check if the filename contains a dot */ - text = g_utf8_strrchr (filename, -1, '.'); + text = thunar_util_strrchr_extension (filename); if (G_LIKELY (text != NULL)) { /* grab focus to the entry first, else the selection will be altered later */ diff --git a/thunar/thunar-util.c b/thunar/thunar-util.c index 7b8665f..13502ec 100644 --- a/thunar/thunar-util.c +++ b/thunar/thunar-util.c @@ -62,6 +62,83 @@ +static inline gchar * +thunar_util_strrchr_offset (const gchar *str, + const gchar *offset, + gchar c) +{ + const gchar *p; + + for (p = offset; p > str; p--) + if (*p == c) + return (gchar *) p; + + return NULL; +} + + + +gchar * +thunar_util_strrchr_extension (const gchar *name) +{ + static const gchar *compressed[] = { "gz", "bz2", "lzma", "lrz", "rpm", "lzo", "xz", "z" }; + gchar *dot; + gchar *ext; + guint i; + gchar *dot2; + gsize len; + gboolean is_in; + + /* check if there is an possible extension part in the name */ + dot = strrchr (name, '.'); + if (dot == NULL) + return NULL; + + /* skip the . */ + ext = dot + 1; + + /* check if this looks like a compression mime-type */ + for (i = 0; i < G_N_ELEMENTS (compressed); i++) + { + if (strcasecmp (ext, compressed[i]) == 0) + { + /* look for a possible container part (tar, psd, epsf) */ + dot2 = thunar_util_strrchr_offset (name, dot - 1, '.'); + if (dot2 != NULL) + { + /* check the 2nd part range, keep it between 2 and 5 chars */ + len = dot - dot2 - 1; + if (len >= 2 && len <= 5) + dot = dot2; + } + + /* that's it for compression types */ + return dot; + } + } + + /* for coders, .in are quite common, so check for those too + * with a max of 3 rounds (2x .in and the possibly final extension) */ + if (strcasecmp (ext, "in") == 0) + { + for (i = 0, is_in = TRUE; is_in && i < 3; i++) + { + dot2 = thunar_util_strrchr_offset (name, dot - 1, '.'); + if (dot2 == NULL) + break; + + /* continue if another .in was found */ + is_in = dot - dot2 == 3 && strncasecmp (dot2, ".in", 3) == 0; + + dot = dot2; + } + } + + return dot; +} + + + void thunar_util_load_bookmarks (GFile *bookmarks_file, ThunarBookmarksFunc foreach_func, diff --git a/thunar/thunar-util.h b/thunar/thunar-util.h index 8170bdc..d08675f 100644 --- a/thunar/thunar-util.h +++ b/thunar/thunar-util.h @@ -31,6 +31,8 @@ typedef void (*ThunarBookmarksFunc) (GFile *file, gint row_num, gpointer user_data); +gchar *thunar_util_strrchr_extension (const gchar *name) G_GNUC_WARN_UNUSED_RESULT; + void thunar_util_load_bookmarks (GFile *bookmarks_file, ThunarBookmarksFunc foreach_func, gpointer user_data);