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.