📄 fl_file_chooser2.cxx
字号:
strlcpy(pathname, filename, sizeof(pathname));
} else if (strcmp(directory_, "/") == 0) {
snprintf(pathname, sizeof(pathname), "/%s", filename);
} else {
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename);
}
if (Fl::event_clicks()) {
#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
if ((strlen(pathname) == 2 && pathname[1] == ':') ||
fl_filename_isdir(pathname))
#else
if (fl_filename_isdir(pathname))
#endif /* WIN32 || __EMX__ */
{
// Change directories...
directory(pathname);
}
else
{
// Hide the window - picked the file...
window->hide();
}
}
else
{
// Strip any trailing slash from the directory name...
filename = pathname + strlen(pathname) - 1;
if (*filename == '/') *filename = '\0';
// puts("Setting fileName from 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();
}
}
//
// 'Fl_File_Chooser::fileNameCB()' - Handle text entry in the FileBrowser.
//
void
Fl_File_Chooser::fileNameCB()
{
char *filename, // New filename
*slash, // Pointer to trailing slash
pathname[1024], // Full pathname to file
matchname[256]; // Matching filename
int i, // Looping var
min_match, // Minimum number of matching chars
max_match, // Maximum number of matching chars
num_files, // Number of files in directory
first_line; // First matching line
const char *file; // File from directory
// puts("fileNameCB()");
// Get the filename from the text field...
filename = (char *)fileName->value();
if (!filename || !filename[0]) {
okButton->deactivate();
return;
}
// Expand ~ and $ variables as needed...
if (strchr(filename, '~') || strchr(filename, '$')) {
fl_filename_expand(pathname, sizeof(pathname), filename);
filename = pathname;
value(pathname);
}
// Make sure we have an absolute path...
#if (defined(WIN32) && !defined(__CYGWIN__)) || defined(__EMX__)
if (directory_[0] != '\0' && filename[0] != '/' &&
filename[0] != '\\' &&
!(isalpha(filename[0]) && filename[1] == ':')) {
#else
if (directory_[0] != '\0' && filename[0] != '/') {
#endif /* WIN32 || __EMX__ */
fl_filename_absolute(pathname, sizeof(pathname), filename);
value(pathname);
} else if (filename != pathname) {
// Finally, make sure that we have a writable copy...
strlcpy(pathname, filename, sizeof(pathname));
}
filename = pathname;
// Now process things according to the key pressed...
if (Fl::event_key() == FL_Enter)
{
// Enter pressed - select or change directory...
#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
if ((strlen(pathname) == 2 && pathname[1] == ':') ||
fl_filename_isdir(pathname)) {
#else
if (fl_filename_isdir(pathname)) {
#endif /* WIN32 || __EMX__ */
directory(pathname);
} else if ((type_ & CREATE) || access(pathname, 0) == 0) {
// New file or file exists... If we are in multiple selection mode,
// switch to single selection mode...
if (type_ & MULTI)
type(SINGLE);
// Update the preview box...
update_preview();
// Do any callback that is registered...
if (callback_) (*callback_)(this, data_);
// Hide the window to signal things are done...
window->hide();
}
else
{
// File doesn't exist, so beep at and alert the user...
fl_alert(existing_file_label);
}
}
else if (Fl::event_key() != FL_Delete &&
Fl::event_key() != FL_BackSpace)
{
// Check to see if the user has entered a directory...
if ((slash = strrchr(pathname, '/')) == NULL)
slash = strrchr(pathname, '\\');
if (slash != NULL)
{
// Yes, change directories if necessary...
*slash++ = '\0';
filename = slash;
#if defined(WIN32) || defined(__EMX__)
if (strcasecmp(pathname, directory_) &&
(pathname[0] || strcasecmp("/", directory_))) {
#else
if (strcmp(pathname, directory_) &&
(pathname[0] || strcasecmp("/", directory_))) {
#endif // WIN32 || __EMX__
int p = fileName->position();
int m = fileName->mark();
directory(pathname);
if (filename[0]) {
char tempname[1024];
snprintf(tempname, sizeof(tempname), "%s/%s", directory_, filename);
fileName->value(tempname);
}
fileName->position(p, m);
}
}
// Other key pressed - do filename completion as possible...
num_files = fileList->size();
min_match = strlen(filename);
max_match = 100000;
first_line = 0;
for (i = 1; i <= num_files && max_match > min_match; i ++)
{
file = fileList->text(i);
#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
if (strnicmp(filename, file, min_match) == 0)
#else
if (strncmp(filename, file, min_match) == 0)
#endif // WIN32 || __EMX__
{
// OK, this one matches; check against the previous match
if (max_match == 100000)
{
// First match; copy stuff over...
strlcpy(matchname, file, sizeof(matchname));
max_match = strlen(matchname);
// Strip trailing /, if any...
if (matchname[max_match - 1] == '/')
{
max_match --;
matchname[max_match] = '\0';
}
// And then make sure that the item is visible
fileList->topline(i);
first_line = i;
}
else
{
// Succeeding match; compare to find maximum string match...
while (max_match > min_match)
#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
if (strnicmp(file, matchname, max_match) == 0)
#else
if (strncmp(file, matchname, max_match) == 0)
#endif // WIN32 || __EMX__
break;
else
max_match --;
// Truncate the string as needed...
matchname[max_match] = '\0';
}
}
}
// If we have any matches, add them to the input field...
if (first_line > 0 && min_match == max_match &&
max_match == (int)strlen(fileList->text(first_line))) {
// This is the only possible match...
fileList->deselect(0);
fileList->select(first_line);
fileList->redraw();
}
else if (max_match > min_match && max_match != 100000)
{
// Add the matching portion...
fileName->replace(filename - pathname, filename - pathname + min_match,
matchname);
// Highlight it with the cursor at the end of the selection so
// s/he can press the right arrow to accept the selection
// (Tab and End also do this for both cases.)
fileName->position(filename - pathname + max_match,
filename - pathname + min_match);
}
else if (max_match == 0) {
fileList->deselect(0);
fileList->redraw();
}
// See if we need to enable the OK button...
if ((type_ & CREATE || access(fileName->value(), 0) == 0) &&
(!fl_filename_isdir(fileName->value()) || type_ & DIRECTORY))
okButton->activate();
else
okButton->deactivate();
} else {
// FL_Delete or FL_BackSpace
fileList->deselect(0);
fileList->redraw();
okButton->deactivate();
}
}
//
// '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?
char temp[1024]; // Temporary pattern string
// 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();
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 {
quote_pathname(temp, start, sizeof(temp));
showChoice->add(temp);
if (strstr(start, "(*)") != NULL) allfiles = 1;
}
}
free(copyp);
if (!allfiles) showChoice->add(all_files_label);
showChoice->add(custom_filter_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();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -