summaryrefslogtreecommitdiff
path: root/src/Fl_Tree.cxx
diff options
context:
space:
mode:
authorGreg Ercolano <erco@seriss.com>2011-05-04 02:59:50 +0000
committerGreg Ercolano <erco@seriss.com>2011-05-04 02:59:50 +0000
commit6871a6512ae600b98ddf7a45dc24aff1d7ff4275 (patch)
treef1c54aee6703de7c50178dd1c6e63bd6545e84a2 /src/Fl_Tree.cxx
parent14839338ec48079cd40c078c5dc1bc20337c5eac (diff)
Fl_Tree mods for handling escaped item menu names.
Docs clarified. Also, tree-simple example's callback handler brought up to date. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@8632 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Tree.cxx')
-rw-r--r--src/Fl_Tree.cxx59
1 files changed, 47 insertions, 12 deletions
diff --git a/src/Fl_Tree.cxx b/src/Fl_Tree.cxx
index a3c7cd3ff..de07c599c 100644
--- a/src/Fl_Tree.cxx
+++ b/src/Fl_Tree.cxx
@@ -38,6 +38,7 @@ static void scroll_cb(Fl_Widget*,void *data) {
}
// INTERNAL: Parse elements from path into an array of null terminated strings
+// Handles escape characters.
// Path="/aa/bb"
// Return: arr[0]="aa", arr[1]="bb", arr[2]=0
// Caller must call free_path(arr).
@@ -48,19 +49,29 @@ static char **parse_path(const char *path) {
int seps = 1; // separator count (1: first item)
int arrsize = 1; // array size (1: first item)
char *save = strdup(path); // make copy we can modify
- char *s = save;
- while ( ( s = strchr(s, '/') ) ) {
- while ( *s == '/' ) { *s++ = 0; seps++; }
- if ( *s ) { arrsize++; }
+ char *sin = save, *sout = save;
+ while ( *sin ) {
+ if ( *sin == '\\' ) { // handle escape character
+ *sout++ = *++sin;
+ if ( *sin ) ++sin;
+ } else if ( *sin == '/' ) { // handle submenu
+ *sout++ = 0;
+ sin++;
+ seps++;
+ arrsize++;
+ } else { // all other chars
+ *sout++ = *sin++;
+ }
}
+ *sout = 0;
arrsize++; // (room for terminating NULL)
// Second pass: create array, save nonblank elements
char **arr = (char**)malloc(sizeof(char*) * arrsize);
int t = 0;
- s = save;
+ sin = save;
while ( seps-- > 0 ) {
- if ( *s ) { arr[t++] = s; } // skips empty fields, eg. '//'
- s += (strlen(s) + 1);
+ if ( *sin ) { arr[t++] = sin; } // skips empty fields, e.g. '//'
+ sin += (strlen(sin) + 1);
}
arr[t] = 0;
return(arr);
@@ -111,6 +122,15 @@ Fl_Tree::~Fl_Tree() {
/// Adds a new item, given a 'menu style' path, eg: "/Parent/Child/item".
/// Any parent nodes that don't already exist are created automatically.
/// Adds the item based on the value of sortorder().
+///
+/// To specify items or submenus that contain slashes ('/' or '\')
+/// use an escape character to protect them, e.g.
+///
+/// \code
+/// tree->add("/Holidays/Photos/12\\/25\\2010"); // Adds item "12/25/2010"
+/// tree->add("/Pathnames/c:\\\\Program Files\\\\MyApp"); // Adds item "c:\Program Files\MyApp"
+/// \endcode
+///
/// \returns the child item created, or 0 on error.
///
Fl_Tree_Item* Fl_Tree::add(const char *path) {
@@ -156,12 +176,19 @@ Fl_Tree_Item* Fl_Tree::add(Fl_Tree_Item *item, const char *name) {
}
/// Find the item, given a menu style path, eg: "/Parent/Child/item".
-///
/// There is both a const and non-const version of this method.
/// Const version allows pure const methods to use this method
/// to do lookups without causing compiler errors.
///
-/// \param[in] path -- the tree item's pathname to be found (eg. "Flintstones/Fred")
+/// To specify items or submenus that contain slashes ('/' or '\')
+/// use an escape character to protect them, e.g.
+///
+/// \code
+/// tree->add("/Holidays/Photos/12\\/25\\2010"); // Adds item "12/25/2010"
+/// tree->add("/Pathnames/c:\\\\Program Files\\\\MyApp"); // Adds item "c:\Program Files\MyApp"
+/// \endcode
+///
+/// \param[in] path -- the tree item's pathname to be found (e.g. "Flintstones/Fred")
/// \returns the item, or NULL if not found.
///
/// \see item_pathname()
@@ -195,6 +222,9 @@ const Fl_Tree_Item *Fl_Tree::find_item(const char *path) const {
/// Find the pathname for the specified \p item.
/// If \p item is NULL, root() is used.
/// The tree's root will be included in the pathname of showroot() is on.
+/// Menu items or submenus that contain slashes ('/' or '\') in their names
+/// will be escaped with a backslash. This is symmetrical with the add()
+/// function which uses the same escape pattern to set names.
/// \param[in] pathname The string to use to return the pathname
/// \param[in] pathnamelen The maximum length of the string (including NULL). Must not be zero.
/// \param[in] item The item whose pathname is to be returned.
@@ -218,7 +248,12 @@ int Fl_Tree::item_pathname(char *pathname, int pathnamelen, const Fl_Tree_Item *
const char *name = item->label() ? item->label() : "???"; // name for this item
int len = strlen(name);
// Add name to end of pathname[]
- for ( --len; len>=0; len-- ) { SAFE_RCAT(name[len]); } // rcat name of item
+ for ( --len; len>=0; len-- ) {
+ SAFE_RCAT(name[len]); // rcat name of item
+ if ( name[len] == '/' || name[len] == '\\' ) {
+ SAFE_RCAT('\\'); // escape front or back slashes within name
+ }
+ }
SAFE_RCAT('/'); // rcat leading slash
item = item->parent(); // move up tree (NULL==root)
}
@@ -258,7 +293,7 @@ void Fl_Tree::draw() {
// Show vertical scrollbar?
int ydiff = (Y+_prefs.margintop())-Ysave; // ydiff=size of tree
- int ytoofar = (cy+ch) - Y; // ytoofar -- scrolled beyond bottom (eg. stow)
+ int ytoofar = (cy+ch) - Y; // ytoofar -- scrolled beyond bottom (e.g. stow)
//printf("ydiff=%d ch=%d Ysave=%d ytoofar=%d value=%d\n",
//int(ydiff),int(ch),int(Ysave),int(ytoofar), int(_vscroll->value()));
@@ -813,7 +848,7 @@ int Fl_Tree::displayed(Fl_Tree_Item *item) {
}
/// Adjust the vertical scroll bar to show \p item at the top
-/// of the display IF it is currently off-screen (eg. show_item_top()).
+/// of the display IF it is currently off-screen (e.g. show_item_top()).
/// If it is already on-screen, no change is made.
///
/// \param[in] item The item to be shown. If NULL, first() is used.