summaryrefslogtreecommitdiff
path: root/src/Fl_File_Chooser2.cxx
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>2002-06-07 15:06:32 +0000
committerMichael R Sweet <michael.r.sweet@gmail.com>2002-06-07 15:06:32 +0000
commit861ad9769b94f52e3528817c8654c572d98ce760 (patch)
tree81868ee9e2a622094a9d873949311b3fc83ffc78 /src/Fl_File_Chooser2.cxx
parent5c17a15fd444acdc1c8e6bd8de2ba5669042b958 (diff)
New file chooser.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@2286 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_File_Chooser2.cxx')
-rw-r--r--src/Fl_File_Chooser2.cxx950
1 files changed, 689 insertions, 261 deletions
diff --git a/src/Fl_File_Chooser2.cxx b/src/Fl_File_Chooser2.cxx
index 488898c6c..10e56c960 100644
--- a/src/Fl_File_Chooser2.cxx
+++ b/src/Fl_File_Chooser2.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_File_Chooser2.cxx,v 1.1.2.14 2002/06/06 21:26:12 easysw Exp $"
+// "$Id: Fl_File_Chooser2.cxx,v 1.1.2.15 2002/06/07 15:06:32 easysw Exp $"
//
// More Fl_File_Chooser routines.
//
@@ -24,15 +24,19 @@
//
// Contents:
//
-// Fl_File_Chooser::directory() - Set the directory in the file chooser.
-// Fl_File_Chooser::count() - Return the number of selected files.
-// Fl_File_Chooser::value() - Return a selected filename.
-// Fl_File_Chooser::up() - Go up one directory.
-// Fl_File_Chooser::newdir() - Make a new directory.
-// Fl_File_Chooser::rescan() - Rescan the current directory.
-// Fl_File_Chooser::fileListCB() - Handle clicks (and double-clicks) in the
-// FileBrowser.
-// Fl_File_Chooser::fileNameCB() - Handle text entry in the FileBrowser.
+// Fl_File_Chooser::count() - Return the number of selected files.
+// Fl_File_Chooser::directory() - Set the directory in the file chooser.
+// Fl_File_Chooser::filter() - Set the filter(s) for the chooser.
+// Fl_File_Chooser::newdir() - Make a new directory.
+// Fl_File_Chooser::value() - Return a selected filename.
+// Fl_File_Chooser::rescan() - Rescan the current directory.
+// Fl_File_Chooser::favoritesButtonCB() - Handle favorites selections.
+// Fl_File_Chooser::fileListCB() - Handle clicks (and double-clicks)
+// in the Fl_File_Browser.
+// Fl_File_Chooser::fileNameCB() - Handle text entry in the FileBrowser.
+// Fl_File_Chooser::showChoiceCB() - Handle show selections.
+// quote_pathname() - Quote a pathname for a menu.
+// unquote_pathname() - Unquote a pathname from a menu.
//
//
@@ -43,11 +47,11 @@
#include <FL/filename.H>
#include <FL/fl_ask.H>
#include <FL/x.H>
+#include <FL/Fl_Shared_Image.H>
#include <stdio.h>
#include <stdlib.h>
#include "flstring.h"
-#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -62,95 +66,34 @@
//
-// File chooser label strings...
+// File chooser label strings and sort function...
//
-const char *Fl_File_Chooser::directory_label = "Directory:";
+Fl_Preferences Fl_File_Chooser::prefs_(Fl_Preferences::USER, "fltk.org", "filechooser");
+
+const char *Fl_File_Chooser::add_favorites_label = "Add to Favorites";
+const char *Fl_File_Chooser::all_files_label = "All Files (*)";
+const char *Fl_File_Chooser::existing_file_label = "Please choose an existing file!";
+const char *Fl_File_Chooser::favorites_label = "Favorites";
const char *Fl_File_Chooser::filename_label = "Filename:";
-const char *Fl_File_Chooser::filter_label = "New Filter?";
+#ifdef WIN32
+const char *Fl_File_Chooser::filesystems_label = "My Computer";
+#else
+const char *Fl_File_Chooser::filesystems_label = "File Systems";
+#endif // WIN32
+const char *Fl_File_Chooser::manage_favorites_label = "Manage Favorites";
+const char *Fl_File_Chooser::new_directory_label = "New Directory?";
+const char *Fl_File_Chooser::preview_label = "Preview";
+const char *Fl_File_Chooser::show_label = "Show:";
Fl_File_Sort_F *Fl_File_Chooser::sort = fl_numericsort;
//
-// 'Fl_File_Chooser::directory()' - Set the directory in the file chooser.
+// Local functions...
//
-void
-Fl_File_Chooser::directory(const char *d)// I - Directory to change to
-{
- char pathname[1024], // Full path of directory
- *pathptr, // Pointer into full path
- *dirptr; // Pointer into directory
- int levels; // Number of levels in directory
-
-
-// printf("Fl_File_Chooser::directory(\"%s\")\n", d == NULL ? "(null)" : d);
-
- // NULL == current directory
- if (d == NULL)
- d = ".";
-
- if (d[0] != '\0')
- {
- // Make the directory absolute...
-#if (defined(WIN32) && ! defined(__CYGWIN__))|| defined(__EMX__)
- if (d[0] != '/' && d[0] != '\\' && d[1] != ':')
-#else
- if (d[0] != '/' && d[0] != '\\')
-#endif /* WIN32 || __EMX__ */
- fl_filename_absolute(directory_, d);
- else
- strlcpy(directory_, d, sizeof(directory_));
-
- // Strip any trailing slash and/or period...
- dirptr = directory_ + strlen(directory_) - 1;
- if (*dirptr == '.')
- *dirptr-- = '\0';
- if ((*dirptr == '/' || *dirptr == '\\') && dirptr > directory_)
- *dirptr = '\0';
- }
- else
- directory_[0] = '\0';
-
- // Clear the directory menu and fill it as needed...
- dirMenu->clear();
-#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
- dirMenu->add("My Computer");
-#else
- dirMenu->add("File Systems");
-#endif /* WIN32 || __EMX__ */
-
- levels = 0;
- for (dirptr = directory_, pathptr = pathname; *dirptr != '\0';)
- {
- if (*dirptr == '/' || *dirptr == '\\')
- {
- // Need to quote the slash first, and then add it to the menu...
- *pathptr++ = '\\';
- *pathptr++ = '/';
- *pathptr++ = '\0';
- dirptr ++;
-
- dirMenu->add(pathname);
- levels ++;
- pathptr = pathname;
- }
- else
- *pathptr++ = *dirptr++;
- }
-
- if (pathptr > pathname)
- {
- *pathptr = '\0';
- dirMenu->add(pathname);
- levels ++;
- }
-
- dirMenu->value(levels);
-
- // Rescan the directory...
- rescan();
-}
+static void quote_pathname(char *, const char *, int);
+static void unquote_pathname(char *, const char *, int);
//
@@ -196,230 +139,222 @@ Fl_File_Chooser::count()
//
-// 'Fl_File_Chooser::value()' - Return a selected filename.
+// 'Fl_File_Chooser::directory()' - Set the directory in the file chooser.
//
-const char * // O - Filename or NULL
-Fl_File_Chooser::value(int f) // I - File number
+void
+Fl_File_Chooser::directory(const char *d)// I - Directory to change to
{
- int i; // Looping var
- int count; // Number of selected files
- const char *name; // Current filename
- static char pathname[1024]; // Filename + directory
+ char *dirptr; // Pointer into directory
- if (!(type_ & MULTI))
- {
- name = fileName->value();
- if (name[0] == '\0') return NULL;
- else if (fl_filename_isdir(name)) {
- if (type_ & DIRECTORY) return name;
- else return NULL;
- } else return name;
- }
+// printf("Fl_File_Chooser::directory(\"%s\")\n", d == NULL ? "(null)" : d);
- for (i = 1, count = 0; i <= fileList->size(); i ++)
- if (fileList->selected(i))
- {
- // See if this file is a directory...
- name = fileList->text(i);
+ // NULL == current directory
+ if (d == NULL)
+ d = ".";
- if (directory_[0]) {
- snprintf(pathname, sizeof(pathname), "%s/%s", directory_, name);
- } else {
- strlcpy(pathname, name, sizeof(pathname));
- }
+ if (d[0] != '\0')
+ {
+ // Make the directory absolute...
+#if (defined(WIN32) && ! defined(__CYGWIN__))|| defined(__EMX__)
+ if (d[0] != '/' && d[0] != '\\' && d[1] != ':')
+#else
+ if (d[0] != '/' && d[0] != '\\')
+#endif /* WIN32 || __EMX__ */
+ fl_filename_absolute(directory_, d);
+ else
+ strlcpy(directory_, d, sizeof(directory_));
- if (!fl_filename_isdir(pathname))
- {
- // Nope, see if this this is "the one"...
- count ++;
- if (count == f)
- return ((const char *)pathname);
- }
- }
+ // Strip any trailing slash and/or period...
+ dirptr = directory_ + strlen(directory_) - 1;
+ if (*dirptr == '.')
+ *dirptr-- = '\0';
+ if ((*dirptr == '/' || *dirptr == '\\') && dirptr > directory_)
+ *dirptr = '\0';
+ }
+ else
+ directory_[0] = '\0';
- return (NULL);
+ // Rescan the directory...
+ rescan();
}
//
-// 'Fl_File_Chooser::value()' - Set the current filename.
+// 'Fl_File_Chooser::favoritesButtonCB()' - Handle favorites selections.
//
void
-Fl_File_Chooser::value(const char *filename) // I - Filename + directory
+Fl_File_Chooser::favoritesButtonCB()
{
- int i, // Looping var
- count; // Number of items in list
- char *slash; // Directory separator
- char pathname[1024]; // Local copy of filename
+ int value; // Current selection
+ char pathname[1024], // Pathname
+ menuname[2048]; // Menu name
-// printf("Fl_File_Chooser::value(\"%s\")\n", filename == NULL ? "(null)" : filename);
+ value = favoritesButton->value();
- // See if the filename is the "My System" directory...
- if (filename == NULL || !filename[0]) {
- // Yes, just change the current directory...
- directory(filename);
- fileName->value("");
- okButton->deactivate();
- return;
- }
+ if (!value) {
+ // Add current directory to favorites...
+ if (getenv("HOME")) value = favoritesButton->size() - 5;
+ else value = favoritesButton->size() - 4;
- // Switch to single-selection mode as needed
- if (type_ & MULTI)
- type(SINGLE);
+ sprintf(menuname, "favorite%02d", value);
- // See if there is a directory in there...
- fl_filename_absolute(pathname, sizeof(pathname), filename);
+ prefs_.set(menuname, directory_);
- if ((slash = strrchr(pathname, '/')) == NULL)
- slash = strrchr(pathname, '\\');
+ quote_pathname(menuname, directory_, sizeof(menuname));
+ favoritesButton->add(menuname);
- if (slash != NULL)
- {
- // Yes, change the display to the directory...
- *slash++ = '\0';
+ if (favoritesButton->size() > 104) {
+ ((Fl_Menu_Item *)favoritesButton->menu())[0].deactivate();
+ }
+ } else if (value == 1) {
+ // Manage favorites...
+ favoritesCB(0);
+ } else if (value == 2) {
+ // Filesystems/My Computer
+ directory("");
+ } else {
+ unquote_pathname(pathname, favoritesButton->text(value), sizeof(pathname));
directory(pathname);
}
- else
- {
- directory(".");
- slash = pathname;
- }
+}
- // Set the input field to the absolute path...
- if (slash > pathname) slash[-1] = '/';
- fileName->value(pathname);
- fileName->position(0, strlen(pathname));
- okButton->activate();
+//
+// 'Fl_File_Chooser::favoritesCB()' - Handle favorites dialog.
+//
- // Then find the file in the file list and select it...
- count = fileList->size();
+void
+Fl_File_Chooser::favoritesCB(Fl_Widget *w)
+ // I - Widget
+{
+ int i; // Looping var
+ char name[32], // Preference name
+ pathname[1024]; // Directory in list
- fileList->deselect(0);
- fileList->redraw();
- for (i = 1; i <= count; i ++)
-#if defined(WIN32) || defined(__EMX__)
- if (strcasecmp(fileList->text(i), slash) == 0) {
-#else
- if (strcmp(fileList->text(i), slash) == 0) {
-#endif // WIN32 || __EMX__
-// printf("Selecting line %d...\n", i);
- fileList->topline(i);
- fileList->select(i);
- break;
+ if (!w) {
+ // Load the favorites list...
+ favList->clear();
+ favList->deselect();
+
+ for (i = 0; i < 100; i ++) {
+ // Get favorite directory 0 to 99...
+ sprintf(name, "favorite%02d", i);
+
+ prefs_.get(name, pathname, "", sizeof(pathname));
+
+ // Stop on the first empty favorite...
+ if (!pathname[0]) break;
+
+ // Add the favorite to the list...
+ favList->add(pathname,
+ Fl_File_Icon::find(pathname, Fl_File_Icon::DIRECTORY));
}
-}
+ favUpButton->deactivate();
+ favDeleteButton->deactivate();
+ favDownButton->deactivate();
+ favOkButton->deactivate();
+
+ favWindow->hotspot(favList);
+ favWindow->show();
+ } else if (w == favList) {
+ i = favList->value();
+ if (i) {
+ if (i > 1) favUpButton->activate();
+ else favUpButton->deactivate();
+
+ favDeleteButton->activate();
+
+ if (i < favList->size()) favDownButton->activate();
+ else favDownButton->deactivate();
+ } else {
+ favUpButton->deactivate();
+ favDeleteButton->deactivate();
+ favDownButton->deactivate();
+ }
+ } else if (w == favUpButton) {
+ i = favList->value();
-//
-// 'Fl_File_Chooser::up()' - Go up one directory.
-//
+ favList->insert(i - 1, favList->text(i), favList->data(i));
+ favList->remove(i + 1);
+ favList->select(i - 1);
-void
-Fl_File_Chooser::up()
-{
- char *slash; // Trailing slash
+ if (i == 2) favUpButton->deactivate();
+ favDownButton->activate();
- if ((slash = strrchr(directory_, '/')) == NULL)
- slash = strrchr(directory_, '\\');
+ favOkButton->activate();
+ } else if (w == favDeleteButton) {
+ i = favList->value();
- if (directory_[0] != '\0')
- dirMenu->value(dirMenu->value() - 1);
+ favList->remove(i);
- if (slash != NULL)
- *slash = '\0';
- else
- {
- upButton->deactivate();
- directory_[0] = '\0';
- }
+ if (i > favList->size()) i --;
+ favList->select(i);
- rescan();
-}
+ if (i < favList->size()) favDownButton->activate();
+ else favDownButton->deactivate();
+ if (i > 1) favUpButton->activate();
+ else favUpButton->deactivate();
-//
-// 'Fl_File_Chooser::newdir()' - Make a new directory.
-//
+ if (!i) favDeleteButton->deactivate();
-void
-Fl_File_Chooser::newdir()
-{
- const char *dir; // New directory name
- char pathname[1024]; // Full path of directory
+ favOkButton->activate();
+ } else if (w == favDownButton) {
+ i = favList->value();
+ favList->insert(i + 2, favList->text(i), favList->data(i));
+ favList->remove(i);
+ favList->select(i + 1);
- // Get a directory name from the user
- if ((dir = fl_input("New Directory?", NULL)) == NULL)
- return;
+ if ((i + 1) == favList->size()) favDownButton->deactivate();
- // Make it relative to the current directory as needed...
-#if (defined(WIN32) && ! defined (__CYGWIN__)) || defined(__EMX__)
- if (dir[0] != '/' && dir[0] != '\\' && dir[1] != ':')
-#else
- if (dir[0] != '/' && dir[0] != '\\')
-#endif /* WIN32 || __EMX__ */
- snprintf(pathname, sizeof(pathname), "%s/%s", directory_, dir);
- else
- strlcpy(pathname, dir, sizeof(pathname));
+ favUpButton->activate();
- // Create the directory; ignore EEXIST errors...
-#if defined(WIN32) && ! defined (__CYGWIN__)
- if (mkdir(pathname))
-#else
- if (mkdir(pathname, 0777))
-#endif /* WIN32 */
- if (errno != EEXIST)
- {
- fl_alert("Unable to create directory!");
- return;
+ favOkButton->activate();
+ } else if (w == favOkButton) {
+ // Copy the new list over...
+ for (i = 0; i < favList->size(); i ++) {
+ // Set favorite directory 0 to 99...
+ sprintf(name, "favorite%02d", i);
+
+ prefs_.set(name, favList->text(i + 1));
}
- // Show the new directory...
- directory(pathname);
-}
+ // Clear old entries as necessary...
+ for (; i < 100; i ++) {
+ // Clear favorite directory 0 to 99...
+ sprintf(name, "favorite%02d", i);
+ prefs_.get(name, pathname, "", sizeof(pathname));
-//
-// 'Fl_File_Chooser::rescan()' - Rescan the current directory.
-//
-
-void
-Fl_File_Chooser::rescan()
-{
- char pathname[1024]; // New pathname for filename field
+ if (pathname[0]) prefs_.set(name, "");
+ else break;
+ }
-// printf("Fl_File_Chooser::rescan(); directory = \"%s\"\n", directory_);
+ update_favorites();
- // Clear the current filename
- strlcpy(pathname, directory_, sizeof(pathname));
- if (pathname[strlen(pathname) - 1] != '/') {
- strlcat(pathname, "/", sizeof(pathname));
+ favWindow->hide();
}
- fileName->value(pathname);
- okButton->deactivate();
-
- // Build the file list...
- fileList->load(directory_, sort);
}
//
// 'Fl_File_Chooser::fileListCB()' - Handle clicks (and double-clicks) in the
-// FileBrowser.
+// Fl_File_Browser.
//
void
Fl_File_Chooser::fileListCB()
{
- char *filename, // New filename
- pathname[1024]; // Full pathname to file
+ char *filename, // New filename
+ pathname[1024]; // Full pathname to file
filename = (char *)fileList->text(fileList->value());
@@ -440,16 +375,12 @@ Fl_File_Chooser::fileListCB()
if (fl_filename_isdir(pathname))
#endif /* WIN32 || __EMX__ */
{
+ // Change directories...
directory(pathname);
- upButton->activate();
}
else
{
- // Do any callback that is registered...
- if (callback_)
- (*callback_)(this, data_);
-
- // Hide the window...
+ // Hide the window - picked the file...
window->hide();
}
}
@@ -461,6 +392,14 @@ Fl_File_Chooser::fileListCB()
fileName->value(pathname);
+ // Update the preview box...
+ Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this);
+ Fl::add_timeout(1.0, (Fl_Timeout_Handler)previewCB, this);
+
+ // Do any callback that is registered...
+ if (callback_) (*callback_)(this, data_);
+
+ // Activate the OK button as needed...
if (!fl_filename_isdir(pathname) || (type_ & DIRECTORY))
okButton->activate();
}
@@ -537,9 +476,11 @@ Fl_File_Chooser::fileNameCB()
if (type_ & MULTI)
type(SINGLE);
+ // Update the preview box...
+ update_preview();
+
// Do any callback that is registered...
- if (callback_)
- (*callback_)(this, data_);
+ if (callback_) (*callback_)(this, data_);
// Hide the window to signal things are done...
window->hide();
@@ -547,7 +488,7 @@ Fl_File_Chooser::fileNameCB()
else
{
// File doesn't exist, so beep at and alert the user...
- fl_alert("Please choose an existing file!");
+ fl_alert(existing_file_label);
}
}
else if (Fl::event_key() != FL_Delete &&
@@ -675,5 +616,492 @@ Fl_File_Chooser::fileNameCB()
//
-// End of "$Id: Fl_File_Chooser2.cxx,v 1.1.2.14 2002/06/06 21:26:12 easysw Exp $".
+// 'Fl_File_Chooser::filter()' - Set the filter(s) for the chooser.
+//
+
+void
+Fl_File_Chooser::filter(const char *p) // I - Pattern(s)
+{
+ char *copyp, // Copy of pattern
+ *start, // Start of pattern
+ *end; // End of pattern
+ int allfiles; // Do we have a "*" pattern?
+
+
+ // Make sure we have a pattern...
+ if (!p || !*p) p = "*";
+
+ // Copy the pattern string...
+ copyp = strdup(p);
+
+ // Separate the pattern string as necessary...
+ showChoice->clear();
+ showChoice->add("bla");
+ showChoice->clear();
+
+ for (start = copyp, allfiles = 0; start && *start; start = end) {
+ end = strchr(start, '\t');
+ if (end) *end++ = '\0';
+
+ if (strcmp(start, "*") == 0) {
+ showChoice->add(all_files_label);
+ allfiles = 1;
+ } else {
+ showChoice->add(start);
+ if (strstr(start, "(*)") != NULL) allfiles = 1;
+ }
+ }
+
+ free(copyp);
+
+ if (!allfiles) showChoice->add(all_files_label);
+
+ showChoice->value(0);
+ showChoiceCB();
+}
+
+
+//
+// 'Fl_File_Chooser::newdir()' - Make a new directory.
+//
+
+void
+Fl_File_Chooser::newdir()
+{
+ const char *dir; // New directory name
+ char pathname[1024]; // Full path of directory
+
+
+ // Get a directory name from the user
+ if ((dir = fl_input(new_directory_label, NULL)) == NULL)
+ return;
+
+ // Make it relative to the current directory as needed...
+#if (defined(WIN32) && ! defined (__CYGWIN__)) || defined(__EMX__)
+ if (dir[0] != '/' && dir[0] != '\\' && dir[1] != ':')
+#else
+ if (dir[0] != '/' && dir[0] != '\\')
+#endif /* WIN32 || __EMX__ */
+ snprintf(pathname, sizeof(pathname), "%s/%s", directory_, dir);
+ else
+ strlcpy(pathname, dir, sizeof(pathname));
+
+ // Create the directory; ignore EEXIST errors...
+#if defined(WIN32) && ! defined (__CYGWIN__)
+ if (mkdir(pathname))
+#else
+ if (mkdir(pathname, 0777))
+#endif /* WIN32 */
+ if (errno != EEXIST)
+ {
+ fl_alert("%s", strerror(errno));
+ return;
+ }
+
+ // Show the new directory...
+ directory(pathname);
+}
+
+
+//
+// 'Fl_File_Chooser::preview()' - Enable or disable the preview tile.
+//
+
+void
+Fl_File_Chooser::preview(int e)// I - 1 = enable preview, 0 = disable preview
+{
+ previewButton->value(e);
+ prefs_.set("preview", e);
+
+ if (e) {
+ int w = previewBox->h() * 2 / 3;
+ fileList->resize(fileList->x(), fileList->y(),
+ window->w() - 20 - w, fileList->h());
+ previewBox->resize(window->w() - 10 - w, previewBox->y(),
+ w, previewBox->h());
+
+ update_preview();
+ } else {
+ fileList->resize(fileList->x(), fileList->y(),
+ window->w() - 20, fileList->h());
+ previewBox->resize(window->w() - 10, previewBox->y(),
+ 0, previewBox->h());
+ }
+
+ fileList->parent()->redraw();
+}
+
+
+//
+// 'Fl_File_Chooser::previewCB()' - Timeout handler for the preview box.
+//
+
+void
+Fl_File_Chooser::previewCB(Fl_File_Chooser *fc) { // I - File chooser
+ fc->update_preview();
+}
+
+
+//
+// 'Fl_File_Chooser::rescan()' - Rescan the current directory.
+//
+
+void
+Fl_File_Chooser::rescan()
+{
+ char pathname[1024]; // New pathname for filename field
+
+ // Clear the current filename
+ strlcpy(pathname, directory_, sizeof(pathname));
+ if (pathname[strlen(pathname) - 1] != '/') {
+ strlcat(pathname, "/", sizeof(pathname));
+ }
+ fileName->value(pathname);
+ okButton->deactivate();
+
+ // Build the file list...
+ fileList->load(directory_, sort);
+
+ // Update the preview box...
+ update_preview();
+}
+
+
+//
+// 'Fl_File_Chooser::showChoiceCB()' - Handle show selections.
+//
+
+void
+Fl_File_Chooser::showChoiceCB()
+{
+ const char *item, // Selected item
+ *patstart; // Start of pattern
+ char *patend; // End of pattern
+
+
+ item = showChoice->text(showChoice->value());
+
+ if ((patstart = strchr(item, '(')) == NULL) {
+ strlcpy(pattern_, item, sizeof(pattern_));
+ } else {
+ strlcpy(pattern_, patstart + 1, sizeof(pattern_));
+ if ((patend = strrchr(pattern_, ')')) != NULL) *patend = '\0';
+ }
+
+ fileList->filter(pattern_);
+ rescan();
+}
+
+
+//
+// 'Fl_File_Chooser::update_favorites()' - Update the favorites menu.
+//
+
+void
+Fl_File_Chooser::update_favorites()
+{
+ int i; // Looping var
+ char pathname[1024], // Pathname
+ menuname[2048]; // Menu name
+ const char *home; // Home directory
+
+
+ favoritesButton->clear();
+ favoritesButton->add("bla");
+ favoritesButton->clear();
+ favoritesButton->add(add_favorites_label, FL_ALT + 'a', 0);
+ favoritesButton->add(manage_favorites_label, FL_ALT + 'm', 0, 0, FL_MENU_DIVIDER);
+ favoritesButton->add(filesystems_label, FL_ALT + 'f', 0);
+
+ if ((home = getenv("HOME")) != NULL) {
+ quote_pathname(menuname, home, sizeof(menuname));
+ favoritesButton->add(menuname, FL_ALT + 'h', 0);
+ }
+
+ for (i = 0; i < 100; i ++) {
+ sprintf(menuname, "favorite%02d", i);
+ prefs_.get(menuname, pathname, "", sizeof(pathname));
+ if (!pathname[0]) break;
+
+ quote_pathname(menuname, pathname, sizeof(menuname));
+
+ if (i < 10) favoritesButton->add(menuname, FL_ALT + '0' + i, 0);
+ else favoritesButton->add(menuname);
+ }
+
+ if (i == 100) ((Fl_Menu_Item *)favoritesButton->menu())[0].deactivate();
+}
+
+
+//
+// 'Fl_File_Chooser::update_preview()' - Update the preview box...
+//
+
+void
+Fl_File_Chooser::update_preview()
+{
+ const char *filename; // Current filename
+ Fl_Shared_Image *image, // New image
+ *oldimage; // Old image
+ int pbw, pbh; // Width and height of preview box
+ int w, h; // Width and height of preview image
+
+
+ if (!previewButton->value()) return;
+
+ if ((filename = value()) == NULL) image = NULL;
+ else {
+ window->cursor(FL_CURSOR_WAIT);
+ Fl::check();
+
+ image = Fl_Shared_Image::get(filename);
+
+ if (image) {
+ window->cursor(FL_CURSOR_DEFAULT);
+ Fl::check();
+ }
+ }
+
+ oldimage = (Fl_Shared_Image *)previewBox->image();
+
+ if (oldimage) while (oldimage->refcount()) oldimage->release();
+
+ previewBox->image(0);
+
+ if (!image) {
+ FILE *fp;
+ int bytes;
+ char *ptr;
+
+ if (filename) fp = fopen(filename, "rb");
+ else fp = NULL;
+
+ if (fp != NULL) {
+ // Try reading the first 1k of data for a label...
+ bytes = fread(preview_text_, 1, sizeof(preview_text_) - 1, fp);
+ preview_text_[bytes] = '\0';
+ fclose(fp);
+ } else {
+ // Assume we can't read any data...
+ preview_text_[0] = '\0';
+ }
+
+ window->cursor(FL_CURSOR_DEFAULT);
+ Fl::check();
+
+ // Scan the buffer for printable chars...
+ for (ptr = preview_text_; *ptr && (isprint(*ptr) || isspace(*ptr)); ptr ++);
+
+ if (*ptr || ptr == preview_text_) {
+ // Non-printable file, just show a big ?...
+ previewBox->label(filename ? "?" : 0);
+ previewBox->align(FL_ALIGN_CLIP);
+ previewBox->labelsize(100);
+ previewBox->labelfont(FL_HELVETICA);
+ } else {
+ // Show the first 1k of text...
+ int size = previewBox->h() / 20;
+ if (size < 6) size = 6;
+ else if (size > 14) size = 14;
+
+ previewBox->label(preview_text_);
+ previewBox->align((Fl_Align)(FL_ALIGN_CLIP | FL_ALIGN_INSIDE |
+ FL_ALIGN_LEFT | FL_ALIGN_TOP));
+ previewBox->labelsize(size);
+ previewBox->labelfont(FL_COURIER);
+ }
+ } else {
+ pbw = previewBox->w() - 20;
+ pbh = previewBox->h() - 20;
+
+ if (image->w() > pbw || image->h() > pbh) {
+ w = pbw;
+ h = w * image->h() / image->w();
+
+ if (h > pbh) {
+ h = pbh;
+ w = h * image->w() / image->h();
+ }
+
+ oldimage = (Fl_Shared_Image *)image->copy(w, h);
+ previewBox->image((Fl_Image *)oldimage);
+
+ image->release();
+ } else {
+ previewBox->image((Fl_Image *)image);
+ }
+
+ previewBox->align(FL_ALIGN_CLIP);
+ previewBox->label(0);
+ }
+
+ previewBox->redraw();
+}
+
+
+//
+// 'Fl_File_Chooser::value()' - Return a selected filename.
+//
+
+const char * // O - Filename or NULL
+Fl_File_Chooser::value(int f) // I - File number
+{
+ int i; // Looping var
+ int count; // Number of selected files
+ const char *name; // Current filename
+ static char pathname[1024]; // Filename + directory
+
+
+ if (!(type_ & MULTI))
+ {
+ name = fileName->value();
+ if (name[0] == '\0') return NULL;
+ else if (fl_filename_isdir(name)) {
+ if (type_ & DIRECTORY) return name;
+ else return NULL;
+ } else return name;
+ }
+
+ for (i = 1, count = 0; i <= fileList->size(); i ++)
+ if (fileList->selected(i))
+ {
+ // See if this file is a directory...
+ name = fileList->text(i);
+
+ if (directory_[0]) {
+ snprintf(pathname, sizeof(pathname), "%s/%s", directory_, name);
+ } else {
+ strlcpy(pathname, name, sizeof(pathname));
+ }
+
+ if (!fl_filename_isdir(pathname))
+ {
+ // Nope, see if this this is "the one"...
+ count ++;
+ if (count == f)
+ return ((const char *)pathname);
+ }
+ }
+
+ return (NULL);
+}
+
+
+//
+// 'Fl_File_Chooser::value()' - Set the current filename.
+//
+
+void
+Fl_File_Chooser::value(const char *filename) // I - Filename + directory
+{
+ int i, // Looping var
+ count; // Number of items in list
+ char *slash; // Directory separator
+ char pathname[1024]; // Local copy of filename
+
+
+// printf("Fl_File_Chooser::value(\"%s\")\n", filename == NULL ? "(null)" : filename);
+
+ // See if the filename is the "My System" directory...
+ if (filename == NULL || !filename[0]) {
+ // Yes, just change the current directory...
+ directory(filename);
+ fileName->value("");
+ okButton->deactivate();
+ return;
+ }
+
+ // Switch to single-selection mode as needed
+ if (type_ & MULTI)
+ type(SINGLE);
+
+ // See if there is a directory in there...
+ fl_filename_absolute(pathname, sizeof(pathname), filename);
+
+ if ((slash = strrchr(pathname, '/')) == NULL)
+ slash = strrchr(pathname, '\\');
+
+ if (slash != NULL)
+ {
+ // Yes, change the display to the directory...
+ *slash++ = '\0';
+ directory(pathname);
+ }
+ else
+ {
+ directory(".");
+ slash = pathname;
+ }
+
+ // Set the input field to the absolute path...
+ if (slash > pathname) slash[-1] = '/';
+
+ fileName->value(pathname);
+ fileName->position(0, strlen(pathname));
+ okButton->activate();
+
+ // Then find the file in the file list and select it...
+ count = fileList->size();
+
+ fileList->deselect(0);
+ fileList->redraw();
+
+ for (i = 1; i <= count; i ++)
+#if defined(WIN32) || defined(__EMX__)
+ if (strcasecmp(fileList->text(i), slash) == 0) {
+#else
+ if (strcmp(fileList->text(i), slash) == 0) {
+#endif // WIN32 || __EMX__
+// printf("Selecting line %d...\n", i);
+ fileList->topline(i);
+ fileList->select(i);
+ break;
+ }
+}
+
+
+//
+// 'quote_pathname()' - Quote a pathname for a menu.
+//
+
+static void
+quote_pathname(char *dst, // O - Destination string
+ const char *src, // I - Source string
+ int dstsize) // I - Size of destination string
+{
+ dstsize --;
+
+ while (*src && dstsize > 1) {
+ if (*src == '/')
+ *dst++ = '\\';
+
+ *dst++ = *src++;
+ }
+
+ *dst = '\0';
+}
+
+
+//
+// 'unquote_pathname()' - Unquote a pathname from a menu.
+//
+
+static void
+unquote_pathname(char *dst, // O - Destination string
+ const char *src, // I - Source string
+ int dstsize) // I - Size of destination string
+{
+ dstsize --;
+
+ while (*src && dstsize > 1) {
+ if (*src == '\\') src ++;
+ *dst++ = *src++;
+ }
+
+ *dst = '\0';
+}
+
+
+//
+// End of "$Id: Fl_File_Chooser2.cxx,v 1.1.2.15 2002/06/07 15:06:32 easysw Exp $".
//