SF.net SVN: geany:[3718] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Tue Apr 21 20:52:51 UTC 2009


Revision: 3718
          http://geany.svn.sourceforge.net/geany/?rev=3718&view=rev
Author:   eht16
Date:     2009-04-21 20:52:51 +0000 (Tue, 21 Apr 2009)

Log Message:
-----------
Ellipsize tab labels and some status messages for very long filenames (closes #2777348).

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/dialogs.c
    trunk/src/document.c
    trunk/src/document.h
    trunk/src/treeviews.c
    trunk/src/utils.c
    trunk/src/utils.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2009-04-21 20:52:32 UTC (rev 3717)
+++ trunk/ChangeLog	2009-04-21 20:52:51 UTC (rev 3718)
@@ -1,3 +1,11 @@
+2009-04-21  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
+
+ * src/dialogs.c, src/document.c, src/document.h, src/treeviews.c,
+   src/utils.c, src/utils.h:
+   Ellipsize tab labels and some status messages for very long
+   filenames (closes #2777348).
+
+
 2009-04-20  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
 
  * src/callbacks.c, src/editor.c, src/keybindings.c, src/keybindings.h,

Modified: trunk/src/dialogs.c
===================================================================
--- trunk/src/dialogs.c	2009-04-21 20:52:32 UTC (rev 3717)
+++ trunk/src/dialogs.c	2009-04-21 20:52:51 UTC (rev 3718)
@@ -648,10 +648,7 @@
 		document_get_notebook_page(doc));
 	main_status.quitting = old_quitting_state;
 
-	if (doc->file_name != NULL)
-	{
-		short_fn = g_path_get_basename(doc->file_name);
-	}
+	short_fn = document_get_basename_for_display(doc, -1);
 
 	msg = g_strdup_printf(_("The file '%s' is not saved."),
 		(short_fn != NULL) ? short_fn : GEANY_STRING_UNTITLED);
@@ -942,6 +939,7 @@
 {
 	GtkWidget *dialog, *label, *table, *hbox, *image, *perm_table, *check, *vbox;
 	gchar *file_size, *title, *base_name, *time_changed, *time_modified, *time_accessed, *enctext;
+	gchar *short_name;
 #ifdef HAVE_SYS_TYPES_H
 	struct stat st;
 	off_t filesize;
@@ -1003,10 +1001,12 @@
 #endif
 
 	base_name = g_path_get_basename(doc->file_name);
-	title = g_strconcat(base_name, " ", _("Properties"), NULL);
+	short_name = utils_str_middle_truncate(base_name, 30);
+	title = g_strconcat(short_name, " ", _("Properties"), NULL);
 	dialog = gtk_dialog_new_with_buttons(title, GTK_WINDOW(main_widgets.window),
 										 GTK_DIALOG_DESTROY_WITH_PARENT,
 										 GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL);
+	g_free(short_name);
 	g_free(title);
 	gtk_widget_set_name(dialog, "GeanyDialog");
 	vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog));

Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c	2009-04-21 20:52:32 UTC (rev 3717)
+++ trunk/src/document.c	2009-04-21 20:52:51 UTC (rev 3718)
@@ -282,23 +282,55 @@
 }
 
 
+/**
+ *  Returns the last part of the filename of the given GeanyDocument. The result is also
+ *  truncated to a maximum of @c length characters in case the filename is very long.
+ *
+ *  @param doc The document to use.
+ *  @param length The length of the resulting string or -1 to use a default value.
+ *
+ *  @return The ellipsized last part of the filename of @c doc, should be freed when no
+ *          longer needed.
+ *
+ *  @since 0.17
+ */
+/* TODO make more use of this */
+gchar *document_get_basename_for_display(GeanyDocument *doc, gint length)
+{
+	gchar *base_name, *short_name;
+
+	g_return_val_if_fail(doc != NULL, NULL);
+
+	if (length < 0)
+		length = 30;
+
+	base_name = g_path_get_basename(DOC_FILENAME(doc));
+	short_name = utils_str_middle_truncate(base_name, length);
+
+	g_free(base_name);
+
+	return short_name;
+}
+
+
 void document_update_tab_label(GeanyDocument *doc)
 {
-	gchar *base_name;
+	gchar *short_name;
 	GtkWidget *parent;
 
 	g_return_if_fail(doc != NULL);
 
-	base_name = g_path_get_basename(DOC_FILENAME(doc));
+	short_name = document_get_basename_for_display(doc, -1);
+
 	/* we need to use the event box for the tooltip, labels don't get the necessary events */
 	parent = gtk_widget_get_parent(doc->priv->tab_label);
 	parent = gtk_widget_get_parent(parent);
 
-	gtk_label_set_text(GTK_LABEL(doc->priv->tab_label), base_name);
+	gtk_label_set_text(GTK_LABEL(doc->priv->tab_label), short_name);
 
 	ui_widget_set_tooltip_text(parent, DOC_FILENAME(doc));
 
-	g_free(base_name);
+	g_free(short_name);
 }
 
 
@@ -914,8 +946,8 @@
 
 
 /* loads textfile data, verifies and converts to forced_enc or UTF-8. Also handles BOM. */
-static gboolean load_text_file(const gchar *locale_filename, const gchar *utf8_filename,
-		FileData *filedata, const gchar *forced_enc)
+static gboolean load_text_file(const gchar *locale_filename, const gchar *display_filename,
+	FileData *filedata, const gchar *forced_enc)
 {
 	GError *err = NULL;
 	struct stat st;
@@ -929,7 +961,8 @@
 
 	if (g_stat(locale_filename, &st) != 0)
 	{
-		ui_set_statusbar(TRUE, _("Could not open file %s (%s)"), utf8_filename, g_strerror(errno));
+		ui_set_statusbar(TRUE, _("Could not open file %s (%s)"),
+			display_filename, g_strerror(errno));
 		return FALSE;
 	}
 
@@ -963,9 +996,9 @@
 			"Be aware that saving it can cause data loss.\nThe file was set to read-only.");
 
 		if (main_status.main_window_realized)
-			dialogs_show_msgbox(GTK_MESSAGE_WARNING, warn_msg, utf8_filename);
+			dialogs_show_msgbox(GTK_MESSAGE_WARNING, warn_msg, display_filename);
 
-		ui_set_statusbar(TRUE, warn_msg, utf8_filename);
+		ui_set_statusbar(TRUE, warn_msg, display_filename);
 
 		/* set the file to read-only mode because saving it is probably dangerous */
 		filedata->readonly = TRUE;
@@ -985,7 +1018,7 @@
 			/* For translators: the second wildcard is an encoding name, e.g.
 			 * The file \"test.txt\" is not valid UTF-8. */
 			ui_set_statusbar(TRUE, _("The file \"%s\" is not valid %s."),
-				utf8_filename, forced_enc);
+				display_filename, forced_enc);
 			utils_beep();
 			g_free(filedata->data);
 			return FALSE;
@@ -995,7 +1028,7 @@
 	{
 		ui_set_statusbar(TRUE,
 	_("The file \"%s\" does not look like a text file or the file encoding is not supported."),
-			utf8_filename);
+			display_filename);
 		utils_beep();
 		g_free(filedata->data);
 		return FALSE;
@@ -1181,6 +1214,7 @@
 	gint editor_mode;
 	gboolean reload = (doc == NULL) ? FALSE : TRUE;
 	gchar *utf8_filename = NULL;
+	gchar *display_filename = NULL;
 	gchar *locale_filename = NULL;
 	GeanyFiletype *use_ft;
 	FileData filedata;
@@ -1223,13 +1257,15 @@
 			return doc;
 		}
 	}
+	display_filename = utils_str_middle_truncate(utf8_filename, 100);
 
 	/* if default encoding for opening files is set, use it if no forced encoding is set */
 	if (file_prefs.default_open_encoding >= 0 && forced_enc == NULL)
 		forced_enc = encodings[file_prefs.default_open_encoding].charset;
 
-	if (! load_text_file(locale_filename, utf8_filename, &filedata, forced_enc))
+	if (! load_text_file(locale_filename, display_filename, &filedata, forced_enc))
 	{
+		g_free(display_filename);
 		g_free(utf8_filename);
 		g_free(locale_filename);
 		return NULL;
@@ -1313,12 +1349,13 @@
 		g_signal_emit_by_name(geany_object, "document-open", doc);
 
 	if (reload)
-		ui_set_statusbar(TRUE, _("File %s reloaded."), utf8_filename);
+		ui_set_statusbar(TRUE, _("File %s reloaded."), display_filename);
 	else
 		msgwin_status_add(_("File %s opened(%d%s)."),
-				utf8_filename, gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)),
-				(readonly) ? _(", read-only") : "");
+			display_filename, gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)),
+			(readonly) ? _(", read-only") : "");
 
+	g_free(display_filename);
 	g_free(utf8_filename);
 	g_free(locale_filename);
 

Modified: trunk/src/document.h
===================================================================
--- trunk/src/document.h	2009-04-21 20:52:32 UTC (rev 3717)
+++ trunk/src/document.h	2009-04-21 20:52:51 UTC (rev 3718)
@@ -225,4 +225,6 @@
 
 const GdkColor *document_get_status_color(GeanyDocument *doc);
 
+gchar *document_get_basename_for_display(GeanyDocument *doc, gint length);
+
 #endif

Modified: trunk/src/treeviews.c
===================================================================
--- trunk/src/treeviews.c	2009-04-21 20:52:32 UTC (rev 3717)
+++ trunk/src/treeviews.c	2009-04-21 20:52:51 UTC (rev 3718)
@@ -368,7 +368,7 @@
 		gtk_tree_view_expand_row(GTK_TREE_VIEW(tv.tree_openfiles), path, TRUE);
 		gtk_tree_path_free(path);
 	}
-	basename = g_path_get_basename(DOC_FILENAME(doc));
+	basename = document_get_basename_for_display(doc, 30);
 	gtk_tree_store_set(store_openfiles, iter, DOCUMENTS_ICON, GTK_STOCK_FILE,
 		DOCUMENTS_SHORTNAME, basename, DOCUMENTS_DOCUMENT, doc, DOCUMENTS_COLOR, color,
 		DOCUMENTS_FILENAME, DOC_FILENAME(doc), -1);

Modified: trunk/src/utils.c
===================================================================
--- trunk/src/utils.c	2009-04-21 20:52:32 UTC (rev 3717)
+++ trunk/src/utils.c	2009-04-21 20:52:51 UTC (rev 3718)
@@ -402,6 +402,60 @@
 
 
 /**
+ *  Truncates the input string to a given length.
+ *  Characters are removed from the middle of the string, so the start and the end of string
+ *  won't change.
+ *
+ *  @param string Input string.
+ *  @param truncate_length The length in characters of the resulting string.
+ *
+ *  @return A copy of @c string which is truncated to @c truncate_length characters,
+ *          should be freed when no longer needed.
+ *
+ *  @since 0.17
+ */
+/* This following function is taken from Gedit. */
+gchar *utils_str_middle_truncate(const gchar *string, guint truncate_length)
+{
+	GString *truncated;
+	guint length;
+	guint n_chars;
+	guint num_left_chars;
+	guint right_offset;
+	guint delimiter_length;
+	const gchar *delimiter = "\342\200\246";
+
+	g_return_val_if_fail(string != NULL, NULL);
+
+	length = strlen(string);
+
+	g_return_val_if_fail(g_utf8_validate(string, length, NULL), NULL);
+
+	/* It doesnt make sense to truncate strings to less than the size of the delimiter plus 2
+	 * characters (one on each side) */
+	delimiter_length = g_utf8_strlen(delimiter, -1);
+	if (truncate_length < (delimiter_length + 2))
+		return g_strdup(string);
+
+	n_chars = g_utf8_strlen(string, length);
+
+	/* Make sure the string is not already small enough. */
+	if (n_chars <= truncate_length)
+		return g_strdup (string);
+
+	/* Find the 'middle' where the truncation will occur. */
+	num_left_chars = (truncate_length - delimiter_length) / 2;
+	right_offset = n_chars - truncate_length + num_left_chars + delimiter_length;
+
+	truncated = g_string_new_len(string, g_utf8_offset_to_pointer(string, num_left_chars) - string);
+	g_string_append(truncated, delimiter);
+	g_string_append(truncated, g_utf8_offset_to_pointer(string, right_offset));
+
+	return g_string_free(truncated, FALSE);
+}
+
+
+/**
  *  @a NULL-safe string comparison. Returns @a TRUE if both @c a and @c b are @a NULL
  *  or if @c a and @c b refer to valid strings which are equal.
  *

Modified: trunk/src/utils.h
===================================================================
--- trunk/src/utils.h	2009-04-21 20:52:32 UTC (rev 3717)
+++ trunk/src/utils.h	2009-04-21 20:52:51 UTC (rev 3718)
@@ -175,4 +175,6 @@
 
 gboolean utils_is_remote_path(const gchar *path);
 
+gchar *utils_str_middle_truncate(const gchar *string, guint truncate_length);
+
 #endif


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list