summaryrefslogtreecommitdiff
path: root/fluid
diff options
context:
space:
mode:
Diffstat (limited to 'fluid')
-rw-r--r--fluid/fluid.cxx12
-rw-r--r--fluid/fluid_filename.cxx57
-rw-r--r--fluid/fluid_filename.h1
3 files changed, 63 insertions, 7 deletions
diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx
index faf696e44..9f20843f7 100644
--- a/fluid/fluid.cxx
+++ b/fluid/fluid.cxx
@@ -1948,10 +1948,9 @@ void load_history() {
for (i = 0; i < max_files; i ++) {
fluid_prefs.get( Fl_Preferences::Name("file%d", i), absolute_history[i], "", sizeof(absolute_history[i]));
if (absolute_history[i][0]) {
- // Make a relative version of the filename for the menu...
- fl_filename_relative(relative_history[i], sizeof(relative_history[i]),
- absolute_history[i]);
-
+ // Make a shortened version of the filename for the menu...
+ Fl_String fn = fl_filename_shortened(absolute_history[i], 48);
+ strncpy(relative_history[i], fn.c_str(), sizeof(relative_history[i]));
if (i == 9) history_item[i].flags = FL_MENU_DIVIDER;
else history_item[i].flags = 0;
} else break;
@@ -2002,9 +2001,8 @@ void update_history(const char *flname) {
// Put the new file at the top...
strlcpy(absolute_history[0], absolute, sizeof(absolute_history[0]));
-
- fl_filename_relative(relative_history[0], sizeof(relative_history[0]),
- absolute_history[0]);
+ Fl_String fn = fl_filename_shortened(absolute_history[0], 48);
+ strncpy(relative_history[0], fn.c_str(), sizeof(relative_history[0]));
// Update the menu items as needed...
for (i = 0; i < max_files; i ++) {
diff --git a/fluid/fluid_filename.cxx b/fluid/fluid_filename.cxx
index dc323c2aa..99e1e068b 100644
--- a/fluid/fluid_filename.cxx
+++ b/fluid/fluid_filename.cxx
@@ -162,3 +162,60 @@ Fl_String fl_getcwd() {
fl_getcwd(buffer, FL_PATH_MAX);
return Fl_String(buffer);
}
+
+/**
+ Return a shortened filename for limited display width.
+
+ Replace the start uf a path with "~" if it matches the home directory.
+ If the remaining filename has more than the give number of characters, it will
+ be shortened by replacing parts of the path with an ellipsis ("...").
+
+ The shortened name can no longer be used to open a file. This is purely to
+ make as much information visible while fitting into a give space.
+
+ \param[in] filename absolute path and name, UTF-8 aware
+ \param[in[ max_chars maximum number of characters in result, including ellipsis
+ \return shortened file path and name
+ */
+Fl_String fl_filename_shortened(const Fl_String &filename, int max_chars) {
+ // Insert this as the ellipsis
+ static const char *ell = "...";
+ static const int ell_bytes = 3;
+ // Replace the start of a path with "~" if it matches the home directory
+ static Fl_String tilde = "~/";
+ static Fl_String home;
+ static int home_chars = -1;
+ if (home_chars==-1) {
+ home = fl_filename_expand(tilde);
+ home_chars = fl_utf_nb_char((const uchar*)home.c_str(), home.size());
+ }
+ Fl_String homed_filename;
+#if defined(_WIN32) || defined(__APPLE__)
+ bool starts_with_home = fl_utf_strncasecmp(home.c_str(), filename.c_str(), home_chars)==0;
+#else
+ bool starts_with_home = ::strncmp(home.c_str(), filename.c_str(), home.size())==0;
+#endif
+ if (starts_with_home) {
+ homed_filename = tilde + filename.substr(home.size());
+ } else {
+ homed_filename = filename;
+ }
+ // C style pointer will stay valid until filename is modified.
+ const unsigned char *u8str = reinterpret_cast<const unsigned char *>(homed_filename.c_str());
+ // Count the number of UTF-8 characters in the name.
+ int num_chars = fl_utf_nb_char(u8str, homed_filename.size());
+ if (num_chars+ell_bytes-1 > max_chars) {
+ // Create a new string by replacing characters in the middle.
+ int remove_chars = num_chars - max_chars + ell_bytes;
+ int left_chars = (max_chars - ell_bytes)/2;
+ int right_chars = max_chars - left_chars - 3;
+ int right_start_char = num_chars - right_chars;
+ // Convert character counts into byte counts.
+ int left_bytes = fl_utf8strlen(homed_filename.c_str(), left_chars);
+ int right_start_byte = fl_utf8strlen(homed_filename.c_str()+left_bytes, remove_chars) + left_bytes;
+ return homed_filename.substr(0, left_bytes) + "..." + homed_filename.substr(right_start_byte);
+ } else {
+ // Nothing to change.
+ return homed_filename;
+ }
+}
diff --git a/fluid/fluid_filename.h b/fluid/fluid_filename.h
index afd2aed7e..8a97f132c 100644
--- a/fluid/fluid_filename.h
+++ b/fluid/fluid_filename.h
@@ -41,6 +41,7 @@
class Fl_String;
+Fl_String fl_filename_shortened(const Fl_String &filename, int maxchars);
Fl_String fl_filename_name(const Fl_String &filename);
Fl_String fl_filename_path(const Fl_String &filename);
Fl_String fl_filename_ext(const Fl_String &filename);