[Xfce4-commits] <thunar:master> Smarter file extension selecting (bug #10268).
Nick Schermer
noreply at xfce.org
Sun Jul 28 12:30:01 CEST 2013
Updating branch refs/heads/master
to 5e25c200fa3071e4c0a47d2f621e45819f42706f (commit)
from 82701c297ac6788db64a251e10d77f96f04486ce (commit)
commit 5e25c200fa3071e4c0a47d2f621e45819f42706f
Author: Jeff Shipley <jshipley at fastmail.fm>
Date: Sun Jul 28 12:25:34 2013 +0200
Smarter file extension selecting (bug #10268).
Instead of simply looking for the last '.' in the filename,
do a better job at selecting compound filenames like
.tar.gz and development files like .desktop.in.in.
thunar/thunar-create-dialog.c | 2 +-
thunar/thunar-dialogs.c | 4 +-
thunar/thunar-properties-dialog.c | 6 +--
thunar/thunar-renamer-model.c | 7 ++-
thunar/thunar-text-renderer.c | 3 +-
thunar/thunar-util.c | 107 +++++++++++++++++++++++++++++++++++++
thunar/thunar-util.h | 2 +
7 files changed, 119 insertions(+), 12 deletions(-)
diff --git a/thunar/thunar-create-dialog.c b/thunar/thunar-create-dialog.c
index 781b060..f31f337 100644
--- a/thunar/thunar-create-dialog.c
+++ b/thunar/thunar-create-dialog.c
@@ -329,7 +329,7 @@ thunar_create_dialog_set_filename (ThunarCreateDialog *dialog,
gtk_entry_set_text (GTK_ENTRY (dialog->entry), filename);
/* check if filename contains a dot */
- dot = g_utf8_strrchr (filename, -1, '.');
+ dot = thunar_util_str_get_extension (filename);
if (G_LIKELY (dot != NULL))
{
/* grab focus to the entry first, else
diff --git a/thunar/thunar-dialogs.c b/thunar/thunar-dialogs.c
index 953d4f5..99b9e54 100644
--- a/thunar/thunar-dialogs.c
+++ b/thunar/thunar-dialogs.c
@@ -137,8 +137,8 @@ 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, '.');
+ /* check if the filename contains an extension */
+ text = thunar_util_str_get_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-properties-dialog.c b/thunar/thunar-properties-dialog.c
index f5e5483..6e6fa8d 100644
--- a/thunar/thunar-properties-dialog.c
+++ b/thunar/thunar-properties-dialog.c
@@ -56,6 +56,7 @@
#include <thunar/thunar-properties-dialog.h>
#include <thunar/thunar-size-label.h>
#include <thunar/thunar-thumbnailer.h>
+#include <thunar/thunar-util.h>
@@ -913,7 +914,7 @@ thunar_properties_dialog_update_single (ThunarPropertiesDialog *dialog)
gtk_widget_grab_focus (dialog->name_entry);
/* select the pre-dot part of the name */
- str = strrchr (name, '.');
+ str = thunar_util_str_get_extension (name);
if (G_LIKELY (str != NULL))
{
/* calculate the offset */
@@ -1260,9 +1261,6 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog)
/* update the properties for a dialog showing 1 file */
thunar_properties_dialog_update_single (dialog);
-
- /* place the initial focus on the name entry widget */
- gtk_widget_grab_focus (dialog->name_entry);
}
else
{
diff --git a/thunar/thunar-renamer-model.c b/thunar/thunar-renamer-model.c
index 853b797..3d8c209 100644
--- a/thunar/thunar-renamer-model.c
+++ b/thunar/thunar-renamer-model.c
@@ -33,6 +33,7 @@
#include <thunar/thunar-gobject-extensions.h>
#include <thunar/thunar-private.h>
#include <thunar/thunar-renamer-model.h>
+#include <thunar/thunar-util.h>
@@ -819,10 +820,8 @@ 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;
+ /* determine the extension in the filename */
+ dot = thunar_util_str_get_extension (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))
diff --git a/thunar/thunar-text-renderer.c b/thunar/thunar-text-renderer.c
index 8b111cc..d85f65a 100644
--- a/thunar/thunar-text-renderer.c
+++ b/thunar/thunar-text-renderer.c
@@ -34,6 +34,7 @@
#include <thunar/thunar-marshal.h>
#include <thunar/thunar-pango-extensions.h>
#include <thunar/thunar-text-renderer.h>
+#include <thunar/thunar-util.h>
@@ -756,7 +757,7 @@ thunar_text_renderer_grab_focus (GtkWidget *entry,
text = gtk_entry_get_text (GTK_ENTRY (entry));
/* lookup the last dot in the text */
- dot = strrchr (text, '.');
+ dot = thunar_util_str_get_extension (text);
if (G_LIKELY (dot != NULL))
{
/* determine the UTF-8 char offset */
diff --git a/thunar/thunar-util.c b/thunar/thunar-util.c
index 7b8665f..77a36f9 100644
--- a/thunar/thunar-util.c
+++ b/thunar/thunar-util.c
@@ -62,6 +62,113 @@
+/**
+ * thunar_util_strrchr_offset:
+ * @str: haystack
+ * @offset: pointer offset in @str
+ * @c: search needle
+ *
+ * Return the last occurrence of the character @c in
+ * the string @str starting at @offset.
+ *
+ * There are also Glib functions for this like g_strrstr_len
+ * and g_utf8_strrchr, but these work internally the same
+ * as this function (tho, less efficient).
+ *
+ * Return value: pointer in @str or NULL.
+ **/
+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;
+}
+
+
+
+/**
+ * thunar_util_str_get_extension
+ * @filename : an UTF-8 filename
+ *
+ * Returns a pointer to the extension in @filename.
+ *
+ * This is an improved version of g_utf8_strrchr with
+ * improvements to recognize compound extensions like
+ * ".tar.gz" and ".desktop.in.in".
+ *
+ * Return value: pointer to the extension in @filename
+ * or NULL.
+**/
+gchar *
+thunar_util_str_get_extension (const gchar *filename)
+{
+ 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 (filename, '.');
+ if (dot == NULL || dot[1] == '\0')
+ 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 (filename, 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 (filename, dot - 1, '.');
+ /* the extension before .in could be long. check that it's at least 2 chars */
+ len = dot - dot2 - 1;
+ if (dot2 == NULL || len < 2)
+ 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..b80f070 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_str_get_extension (const gchar *name) G_GNUC_WARN_UNUSED_RESULT;
+
void thunar_util_load_bookmarks (GFile *bookmarks_file,
ThunarBookmarksFunc foreach_func,
gpointer user_data);
More information about the Xfce4-commits
mailing list