Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/dialogs/file/GNEFileSelector.cpp
169684 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file GNEFileSelector.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Aug 2025
17
///
18
// widget used for file selection
19
/****************************************************************************/
20
21
#include <fxkeys.h>
22
#include <netedit/dialogs/basic/GNEErrorBasicDialog.h>
23
#include <netedit/dialogs/basic/GNEQuestionBasicDialog.h>
24
#include <netedit/GNEApplicationWindow.h>
25
#include <utils/common/StringTokenizer.h>
26
#include <utils/foxtools/MFXTextFieldIcon.h>
27
#include <utils/foxtools/MFXToggleButtonTooltip.h>
28
#include <utils/gui/div/GUIDesigns.h>
29
#include <utils/gui/div/GUIIOGlobals.h>
30
31
#include "GNEFilePathDialog.h"
32
#include "GNEFileSelector.h"
33
34
#define FILELISTMASK (ICONLIST_EXTENDEDSELECT|ICONLIST_SINGLESELECT|ICONLIST_BROWSESELECT|ICONLIST_MULTIPLESELECT)
35
#define FILESTYLEMASK (ICONLIST_DETAILED|ICONLIST_MINI_ICONS|ICONLIST_BIG_ICONS|ICONLIST_ROWS|ICONLIST_COLUMNS|ICONLIST_AUTOSIZE)
36
37
// ===========================================================================
38
// FOX callback mapping
39
// ===========================================================================
40
41
// Map
42
FXDEFMAP(GNEFileSelector) GNEFileSelectorMap[] = {
43
// interaction
44
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_ACCEPT, GNEFileSelector::onCmdAccept),
45
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_FILEFILTER, GNEFileSelector::onCmdFilter),
46
FXMAPFUNC(SEL_DOUBLECLICKED, FXFileSelector::ID_FILELIST, GNEFileSelector::onCmdItemDoubleClicked),
47
FXMAPFUNC(SEL_SELECTED, FXFileSelector::ID_FILELIST, GNEFileSelector::onCmdItemSelected),
48
FXMAPFUNC(SEL_DESELECTED, FXFileSelector::ID_FILELIST, GNEFileSelector::onCmdItemDeselected),
49
FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, FXFileSelector::ID_FILELIST, GNEFileSelector::onPopupMenu),
50
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_DIRECTORY_UP, GNEFileSelector::onCmdDirectoryUp),
51
FXMAPFUNC(SEL_UPDATE, FXFileSelector::ID_DIRECTORY_UP, GNEFileSelector::onUpdDirectoryUp),
52
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_DIRTREE, GNEFileSelector::onCmdDirTree),
53
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_HOME, GNEFileSelector::onCmdHomeFolder),
54
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_WORK, GNEFileSelector::onCmdWorkFolder),
55
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_VISIT, GNEFileSelector::onCmdVisit),
56
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_BOOKMARK, GNEFileSelector::onCmdBookmark),
57
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_NEW, GNEFileSelector::onCmdNewFolder),
58
FXMAPFUNC(SEL_UPDATE, FXFileSelector::ID_NEW, GNEFileSelector::onUpdNewFolder),
59
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_DELETE, GNEFileSelector::onCmdDelete),
60
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_MOVE, GNEFileSelector::onCmdMove),
61
FXMAPFUNC(SEL_COMMAND, FXFileSelector::ID_COPY, GNEFileSelector::onCmdCopy),
62
FXMAPFUNC(SEL_UPDATE, FXFileSelector::ID_COPY, GNEFileSelector::onUpdSelected),
63
FXMAPFUNC(SEL_UPDATE, FXFileSelector::ID_MOVE, GNEFileSelector::onUpdSelected),
64
FXMAPFUNC(SEL_UPDATE, FXFileSelector::ID_DELETE, GNEFileSelector::onUpdSelected),
65
FXMAPFUNCS(SEL_COMMAND, FXFileSelector::ID_NORMAL_SIZE, FXFileSelector::ID_GIANT_SIZE, GNEFileSelector::onCmdImageSize),
66
FXMAPFUNCS(SEL_UPDATE, FXFileSelector::ID_NORMAL_SIZE, FXFileSelector::ID_GIANT_SIZE, GNEFileSelector::onUpdImageSize),
67
FXMAPFUNC(SEL_KEYPRESS, 0, GNEFileSelector::onKeyPress),
68
FXMAPFUNC(SEL_COMMAND, MID_GNE_BUTTON_CONFIG, GNEFileSelector::onCmdConfigFolder),
69
};
70
71
// Implementation
72
FXIMPLEMENT(GNEFileSelector, FXVerticalFrame, GNEFileSelectorMap, ARRAYNUMBER(GNEFileSelectorMap))
73
74
// ===========================================================================
75
// member method definitions
76
// ===========================================================================
77
78
GNEFileSelector::GNEFileSelector(GNEFileDialog* fileDialog, const std::vector<std::string>& extensions,
79
GNEFileDialog::OpenMode openMode, GNEFileDialog::ConfigType configType):
80
FXVerticalFrame(fileDialog->getContentFrame(), GUIDesignAuxiliarFrame),
81
myFileDialog(fileDialog),
82
myOpenMode(openMode),
83
myConfigType(configType),
84
myBookmarksRecentFiles(fileDialog->getApplicationWindow()->getApp(), TL("Visited Directories")) {
85
// get static tooltip
86
const auto tooltipMenu = fileDialog->getApplicationWindow()->getStaticTooltipMenu();
87
// create horizontal frame for top buttons
88
auto navigatorHorizontalFrame = new FXHorizontalFrame(this, GUIDesignDialogContentHorizontalFrame);
89
// create two horizontal frame for file selector
90
auto externFileboxframe = new FXHorizontalFrame(this, GUIDesignDialogContentFrame);
91
auto fileboxframe = new FXHorizontalFrame(externFileboxframe, GUIDesignFileBoxFrame);
92
// horizontal frame for filename
93
auto filenameHorizontalFrame = new FXHorizontalFrame(this, GUIDesignDialogContentHorizontalFrame);
94
// first create file selector
95
myFileSelector = new FXFileList(fileboxframe, this, FXFileSelector::ID_FILELIST, GUIDesignFileList);
96
// label for directory
97
new FXLabel(navigatorHorizontalFrame, TL("Directory:"), nullptr, GUIDesignLabelFixed(100));
98
// create directory box
99
myDirBox = new FXDirBox(navigatorHorizontalFrame, this, FXFileSelector::ID_DIRTREE, GUIDesignDirBox);
100
myDirBox->setNumVisible(5);
101
myDirBox->setAssociations(myFileSelector->getAssociations());
102
// build bookmark menu pane
103
buildBookmarkMenuPane(navigatorHorizontalFrame);
104
// build buttons
105
buildButtons(navigatorHorizontalFrame, tooltipMenu);
106
// create label for filename
107
new FXLabel(filenameHorizontalFrame,
108
TL("File Name:"),
109
nullptr, GUIDesignLabelFixed(100));
110
// create filename text field and set focus
111
myFilenameTextField = new MFXTextFieldIcon(filenameHorizontalFrame, tooltipMenu, GUIIcon::EMPTY,
112
this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextFieldFileDialog);
113
// create comboBox for file filter
114
myFileFilterComboBox = new MFXComboBoxIcon(filenameHorizontalFrame, tooltipMenu, false, GUIDesignComboBoxVisibleItems,
115
this, FXFileSelector::ID_FILEFILTER, GUIDesignComboBoxFileDialog);
116
// build shortcuts
117
buildShortcuts();
118
// continue depending of open mode
119
switch (myOpenMode) {
120
case GNEFileDialog::OpenMode::SAVE:
121
myFileSelector->showOnlyDirectories(FALSE);
122
myFileSelector->setListStyle((myFileSelector->getListStyle() & ~FILELISTMASK) | ICONLIST_BROWSESELECT);
123
break;
124
case GNEFileDialog::OpenMode::LOAD_SINGLE:
125
myFileSelector->showOnlyDirectories(FALSE);
126
myFileSelector->setListStyle((myFileSelector->getListStyle() & ~FILELISTMASK) | ICONLIST_BROWSESELECT);
127
break;
128
case GNEFileDialog::OpenMode::LOAD_MULTIPLE:
129
myFileSelector->showOnlyDirectories(FALSE);
130
myFileSelector->setListStyle((myFileSelector->getListStyle() & ~FILELISTMASK) | ICONLIST_EXTENDEDSELECT);
131
break;
132
case GNEFileDialog::OpenMode::LOAD_DIRECTORY:
133
myFileSelector->showOnlyDirectories(TRUE);
134
myFileSelector->setListStyle((myFileSelector->getListStyle() & ~FILELISTMASK) | ICONLIST_BROWSESELECT);
135
break;
136
default:
137
throw ProcessError("Invalid open mode");
138
}
139
// set directory
140
if (gCurrentFolder.length() != 0) {
141
setDirectory(gCurrentFolder);
142
} else {
143
setDirectory(FXSystem::getCurrentDirectory());
144
}
145
// set extensions
146
if (extensions.size() == 0) {
147
throw ProcessError("At least one extension is needed");
148
} else {
149
for (const auto& extension : extensions) {
150
myFileFilterComboBox->appendIconItem(extension.c_str());
151
}
152
}
153
myFileFilterComboBox->setNumVisible(FXMIN((int)extensions.size(), 12));
154
// parse extensions
155
parseExtensions(extensions);
156
// apply first filter
157
myFileSelector->setPattern(FXFileSelector::patternFromText(extensions.front().c_str()));
158
}
159
160
161
GNEFileSelector::~GNEFileSelector() {
162
FXAccelTable* table = getShell()->getAccelTable();
163
if (table) {
164
table->removeAccel(MKUINT(KEY_BackSpace, 0));
165
table->removeAccel(MKUINT(KEY_Delete, 0));
166
table->removeAccel(MKUINT(KEY_h, CONTROLMASK));
167
table->removeAccel(MKUINT(KEY_w, CONTROLMASK));
168
table->removeAccel(MKUINT(KEY_n, CONTROLMASK));
169
table->removeAccel(MKUINT(KEY_a, CONTROLMASK));
170
table->removeAccel(MKUINT(KEY_b, CONTROLMASK));
171
table->removeAccel(MKUINT(KEY_s, CONTROLMASK));
172
table->removeAccel(MKUINT(KEY_l, CONTROLMASK));
173
}
174
delete myBookmarkMenuPane;
175
}
176
177
178
void
179
GNEFileSelector::setPath(const std::string& path) {
180
myFilenameTextField->setText(path.c_str(), TRUE);
181
}
182
183
184
void
185
GNEFileSelector::setFilter(const int index) {
186
myFileFilterComboBox->setCurrentItem(index, TRUE);
187
}
188
189
190
long
191
GNEFileSelector::onUpdNewFolder(FXObject* sender, FXSelector, void*) {
192
// check if directory is writable
193
const bool writable = FXStat::isWritable(myFileSelector->getDirectory());
194
return sender->handle(this, writable ? FXSEL(SEL_COMMAND, ID_ENABLE) : FXSEL(SEL_COMMAND, ID_DISABLE), NULL);
195
}
196
197
198
std::vector<std::string>
199
GNEFileSelector::getSelectedFiles() const {
200
std::vector<std::string> files;
201
for (int i = 0; i < myFileSelector->getNumItems(); i++) {
202
if (myFileSelector->isItemSelected(i) && (myFileSelector->getItemFilename(i) != "..") && (myFileSelector->getItemFilename(i) != ".")) {
203
files.push_back(myFileSelector->getItemPathname(i).text());
204
}
205
}
206
return files;
207
}
208
209
210
std::vector<std::string>
211
GNEFileSelector::getSelectedFilesOnly() const {
212
std::vector<std::string> files;
213
for (int i = 0; i < myFileSelector->getNumItems(); i++) {
214
if (myFileSelector->isItemSelected(i) && !myFileSelector->isItemDirectory(i)) {
215
files.push_back(myFileSelector->getItemPathname(i).text());
216
}
217
}
218
return files;
219
}
220
221
222
long
223
GNEFileSelector::onCmdCopy(FXObject*, FXSelector, void*) {
224
const auto filenameList = getSelectedFiles();
225
// first check if we have files to copy
226
if (filenameList.size() > 0) {
227
// get only first filename
228
const std::string originFilePath = filenameList.front();
229
// create default destiny filename
230
std::string destinyFilename = FXPath::absolute(FXPath::directory(originFilePath.c_str()), "CopyOf" + FXPath::name(originFilePath.c_str())).text();
231
// create file path dialog
232
const auto filePathDialog = new GNEFilePathDialog(myFileDialog->getApplicationWindow(), TL("Copy File"), TL("Select destiny file"), destinyFilename);
233
// continue depending of filePathDialog results
234
if (filePathDialog->getResult() == GNEDialog::Result::ACCEPT) {
235
// get destiny filename from dialog
236
destinyFilename = filePathDialog->getFilePath();
237
// check if we selected the same file
238
if (FXFile::identical(originFilePath.c_str(), destinyFilename.c_str())) {
239
// open error dialog
240
GNEErrorBasicDialog(myFileDialog->getApplicationWindow(), TL("Error copying file"),
241
TLF("Unable to copy file:\n%\n", destinyFilename),
242
TL("The source and destiny files are the same"));
243
} else {
244
// check if file exist
245
if (FXStat::exists(destinyFilename.c_str())) {
246
// open question dialog
247
const auto overwriteDialog = GNEQuestionBasicDialog(myFileDialog->getApplicationWindow(), GNEDialog::Buttons::YES_NO,
248
TL("Overwrite file"), TLF("The destiny file:\n%\n", destinyFilename),
249
TL("already exist. Overwrite?"));
250
// check if abort
251
if (overwriteDialog.getResult() != GNEDialog::Result::ACCEPT) {
252
return 1;
253
}
254
}
255
// try to copy overwritten
256
if (!FXFile::copyFiles(originFilePath.c_str(), destinyFilename.c_str(), TRUE)) {
257
// open error dialog
258
GNEErrorBasicDialog(myFileDialog->getApplicationWindow(), TL("Error copying file"),
259
TLF("Unable to copy file:\n%\n", destinyFilename),
260
TL("Check destiny file permissions"));
261
}
262
}
263
}
264
}
265
return 1;
266
}
267
268
269
long
270
GNEFileSelector::onCmdMove(FXObject*, FXSelector, void*) {
271
const auto filenameList = getSelectedFiles();
272
// first check if we have files to move
273
if (filenameList.size() > 0) {
274
// get only first filename
275
const std::string originFilePath = filenameList.front();
276
// create file path dialog
277
const auto filePathDialog = new GNEFilePathDialog(myFileDialog->getApplicationWindow(), TL("Move File"), TL("Select destiny file"), originFilePath);
278
// continue depending of filePathDialog results
279
if (filePathDialog->getResult() == GNEDialog::Result::ACCEPT) {
280
// get destiny filename from dialog
281
const std::string destinyFilename = filePathDialog->getFilePath();
282
// check if we selected the same file
283
if (FXFile::identical(originFilePath.c_str(), destinyFilename.c_str())) {
284
// open error dialog
285
GNEErrorBasicDialog(myFileDialog->getApplicationWindow(), TL("Error moving file"),
286
TLF("Unable to move file:\n%\n", destinyFilename),
287
TL("The source and destiny files are the same"));
288
} else {
289
// check if file exist
290
if (FXStat::exists(destinyFilename.c_str())) {
291
// open question dialog
292
const auto overwriteDialog = GNEQuestionBasicDialog(myFileDialog->getApplicationWindow(), GNEDialog::Buttons::YES_NO,
293
TL("Overwrite file"), TLF("The destiny file:\n%\n", destinyFilename),
294
TL("already exist. Overwrite?"));
295
// check if abort
296
if (overwriteDialog.getResult() != GNEDialog::Result::ACCEPT) {
297
return 1;
298
}
299
}
300
// try to move overwritten
301
if (!FXFile::moveFiles(originFilePath.c_str(), destinyFilename.c_str(), TRUE)) {
302
// open error dialog
303
GNEErrorBasicDialog(myFileDialog->getApplicationWindow(), TL("Error moving file"),
304
TLF("Unable to move file:\n%\n", destinyFilename),
305
TL("Check destiny file permissions"));
306
}
307
}
308
}
309
}
310
return 1;
311
}
312
313
314
long
315
GNEFileSelector::onCmdDelete(FXObject*, FXSelector, void*) {
316
const auto filenameList = getSelectedFiles();
317
// first check if we have files to link
318
if (filenameList.size() > 0) {
319
// get only first filename
320
const std::string fileToDelete = filenameList.front();
321
// open question dialog
322
const auto askDialog = GNEQuestionBasicDialog(myFileDialog->getApplicationWindow(), GNEDialog::Buttons::YES_NO,
323
TL("Deleting file"), TL("Are you sure you want to delete the file:"),
324
fileToDelete);
325
// check if continue
326
if (askDialog.getResult() == GNEDialog::Result::ACCEPT) {
327
// try to remove it
328
if (!FXFile::removeFiles(fileToDelete.c_str(), TRUE)) {
329
// open error dialog
330
GNEErrorBasicDialog(myFileDialog->getApplicationWindow(), TL("Error deleting file"),
331
TLF("Unable to delete file:\n%\n", fileToDelete),
332
TL("Check file permissions"));
333
}
334
}
335
}
336
return 1;
337
}
338
339
340
long
341
GNEFileSelector::onUpdSelected(FXObject* sender, FXSelector, void*) {
342
for (FXint i = 0; i < myFileSelector->getNumItems(); i++) {
343
if (myFileSelector->isItemSelected(i)) {
344
sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
345
return 1;
346
}
347
}
348
sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), NULL);
349
return 1;
350
}
351
352
353
long
354
GNEFileSelector::onCmdImageSize(FXObject*, FXSelector sel, void*) {
355
switch (FXSELID(sel)) {
356
case FXFileSelector::ID_NORMAL_SIZE:
357
setImageSize(32);
358
break;
359
case FXFileSelector::ID_MEDIUM_SIZE:
360
setImageSize(48);
361
break;
362
case FXFileSelector::ID_GIANT_SIZE:
363
setImageSize(64);
364
break;
365
}
366
return 1;
367
}
368
369
370
long
371
GNEFileSelector::onUpdImageSize(FXObject* sender, FXSelector sel, void*) {
372
FXbool check = FALSE;
373
switch (FXSELID(sel)) {
374
case FXFileSelector::ID_NORMAL_SIZE:
375
check = (getImageSize() == 32);
376
break;
377
case FXFileSelector::ID_MEDIUM_SIZE:
378
check = (getImageSize() == 48);
379
break;
380
case FXFileSelector::ID_GIANT_SIZE:
381
check = (getImageSize() == 64);
382
break;
383
}
384
sender->handle(this, check ? FXSEL(SEL_COMMAND, ID_CHECK) : FXSEL(SEL_COMMAND, ID_UNCHECK), NULL);
385
return 1;
386
}
387
388
389
long
390
GNEFileSelector::onKeyPress(FXObject* obj, FXSelector sel, void* ptr) {
391
// if ESC key is pressed, close dialog aborting
392
FXEvent* event = (FXEvent*)ptr;
393
if (event->code == KEY_Return) {
394
return onCmdAccept(obj, sel, ptr);
395
} else {
396
return FXVerticalFrame::onKeyPress(obj, sel, ptr);
397
}
398
}
399
400
401
long
402
GNEFileSelector::onPopupMenu(FXObject*, FXSelector, void* ptr) {
403
FXEvent* event = (FXEvent*)ptr;
404
if (event->moved) {
405
return 1;
406
}
407
408
FXMenuPane filemenu(this);
409
new FXMenuCommand(&filemenu, TL("Up one level"), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_DIRUP_ICON), this, FXFileSelector::ID_DIRECTORY_UP);
410
new FXMenuCommand(&filemenu, TL("Home directory"), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_GOTO_HOME), this, FXFileSelector::ID_HOME);
411
new FXMenuCommand(&filemenu, TL("Work directory"), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_GOTO_WORK), this, FXFileSelector::ID_WORK);
412
auto configDirectory = new FXMenuCommand(&filemenu, TL("Config directory"), nullptr, this, MID_GNE_BUTTON_CONFIG);
413
// disable if configuration file is empty
414
if (OptionsCont::getOptions().getString("configuration-file").empty()) {
415
configDirectory->disable();
416
}
417
// set icon and tip depending of config type
418
if (myConfigType == GNEFileDialog::ConfigType::NETEDIT) {
419
configDirectory->setIcon(GUIIconSubSys::getIcon(GUIIcon::NETEDIT_MINI));
420
} else {
421
configDirectory->setIcon(GUIIconSubSys::getIcon(GUIIcon::SUMO_MINI));
422
}
423
new FXMenuCommand(&filemenu, TL("Select all"), NULL, myFileSelector, FXFileList::ID_SELECT_ALL);
424
new FXMenuSeparator(&filemenu);
425
426
FXMenuPane sortmenu(this);
427
new FXMenuCascade(&filemenu, TL("Sort by"), NULL, &sortmenu);
428
new FXMenuRadio(&sortmenu, TL("Name"), myFileSelector, FXFileList::ID_SORT_BY_NAME);
429
new FXMenuRadio(&sortmenu, TL("Type"), myFileSelector, FXFileList::ID_SORT_BY_TYPE);
430
new FXMenuRadio(&sortmenu, TL("Size"), myFileSelector, FXFileList::ID_SORT_BY_SIZE);
431
new FXMenuRadio(&sortmenu, TL("Time"), myFileSelector, FXFileList::ID_SORT_BY_TIME);
432
new FXMenuRadio(&sortmenu, TL("User"), myFileSelector, FXFileList::ID_SORT_BY_USER);
433
new FXMenuRadio(&sortmenu, TL("Group"), myFileSelector, FXFileList::ID_SORT_BY_GROUP);
434
new FXMenuSeparator(&sortmenu);
435
new FXMenuCheck(&sortmenu, TL("Reverse"), myFileSelector, FXFileList::ID_SORT_REVERSE);
436
new FXMenuCheck(&sortmenu, TL("Ignore case"), myFileSelector, FXFileList::ID_SORT_CASE);
437
438
FXMenuPane viewmenu(this);
439
new FXMenuCascade(&filemenu, TL("View"), NULL, &viewmenu);
440
new FXMenuRadio(&viewmenu, TL("Small icons"), myFileSelector, FXFileList::ID_SHOW_MINI_ICONS);
441
new FXMenuRadio(&viewmenu, TL("Big icons"), myFileSelector, FXFileList::ID_SHOW_BIG_ICONS);
442
new FXMenuRadio(&viewmenu, TL("Details"), myFileSelector, FXFileList::ID_SHOW_DETAILS);
443
new FXMenuSeparator(&viewmenu);
444
new FXMenuRadio(&viewmenu, TL("Rows"), myFileSelector, FXFileList::ID_ARRANGE_BY_ROWS);
445
new FXMenuRadio(&viewmenu, TL("Columns"), myFileSelector, FXFileList::ID_ARRANGE_BY_COLUMNS);
446
new FXMenuSeparator(&viewmenu);
447
new FXMenuCheck(&viewmenu, TL("Hidden files"), myFileSelector, FXFileList::ID_TOGGLE_HIDDEN);
448
new FXMenuCheck(&viewmenu, TL("Preview images"), myFileSelector, FXFileList::ID_TOGGLE_IMAGES);
449
new FXMenuSeparator(&viewmenu);
450
new FXMenuRadio(&viewmenu, TL("Normal images"), this, FXFileSelector::ID_NORMAL_SIZE);
451
new FXMenuRadio(&viewmenu, TL("Medium images"), this, FXFileSelector::ID_MEDIUM_SIZE);
452
new FXMenuRadio(&viewmenu, TL("Giant images"), this, FXFileSelector::ID_GIANT_SIZE);
453
454
FXMenuPane bookmenu(this);
455
FXMenuCascade* bookcasc = new FXMenuCascade(&filemenu, TL("Bookmarks"), NULL, &bookmenu);
456
bookcasc->setTarget(this);
457
bookcasc->setSelector(FXFileSelector::ID_BOOKMENU);
458
new FXMenuCommand(&bookmenu, TL("Set bookmark"), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_BOOK_SET), this, FXFileSelector::ID_BOOKMARK);
459
new FXMenuCommand(&bookmenu, TL("Clear bookmarks"), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_BOOK_CLR), &myBookmarksRecentFiles, FXRecentFiles::ID_CLEAR);
460
FXMenuSeparator* sep1 = new FXMenuSeparator(&bookmenu);
461
sep1->setTarget(&myBookmarksRecentFiles);
462
sep1->setSelector(FXRecentFiles::ID_ANYFILES);
463
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_1);
464
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_2);
465
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_3);
466
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_4);
467
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_5);
468
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_6);
469
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_7);
470
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_8);
471
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_9);
472
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_10);
473
474
new FXMenuSeparator(&filemenu);
475
new FXMenuCommand(&filemenu, TL("New directory..."), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FOLDER_NEW), this, FXFileSelector::ID_NEW);
476
new FXMenuCommand(&filemenu, TL("Copy..."), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FILE_COPY), this, FXFileSelector::ID_COPY);
477
new FXMenuCommand(&filemenu, TL("Move..."), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FILE_MOVE), this, FXFileSelector::ID_MOVE);
478
// disabled linker because it doesn't work
479
new FXMenuCommand(&filemenu, TL("Delete..."), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FILE_DELETE), this, FXFileSelector::ID_DELETE);
480
481
filemenu.create();
482
filemenu.popup(NULL, event->root_x, event->root_y);
483
getApp()->runModalWhileShown(&filemenu);
484
return 1;
485
}
486
487
488
long
489
GNEFileSelector::onCmdFilter(FXObject*, FXSelector, void* ptr) {
490
const FXString pat = FXFileSelector::patternFromText((FXchar*)ptr);
491
myFileSelector->setPattern(pat);
492
if (myOpenMode == GNEFileDialog::OpenMode::SAVE) {
493
FXString ext = FXFileSelector::extensionFromPattern(pat);
494
if (!ext.empty()) {
495
FXString name = FXPath::stripExtension(myFilenameTextField->getText());
496
if (!name.empty()) {
497
myFilenameTextField->setText(name + "." + ext);
498
}
499
}
500
}
501
return 1;
502
}
503
504
505
void
506
GNEFileSelector::setDirectory(const FXString& path) {
507
const FXString abspath = FXPath::absolute(path);
508
myFileSelector->setDirectory(abspath);
509
myDirBox->setDirectory(abspath);
510
if (myOpenMode != GNEFileDialog::OpenMode::SAVE) {
511
myFilenameTextField->setText(FXString::null);
512
}
513
}
514
515
516
void
517
GNEFileSelector::setFilename(const FXString& path) {
518
const FXString fullname(FXPath::absolute(path));
519
FXString name(FXPath::name(fullname));
520
myFileSelector->setCurrentFile(fullname);
521
myDirBox->setDirectory(myFileSelector->getDirectory());
522
myFilenameTextField->setText(name);
523
}
524
525
526
std::string
527
GNEFileSelector::getFilename() const {
528
if (myOpenMode == GNEFileDialog::OpenMode::LOAD_MULTIPLE) {
529
for (FXint i = 0; i < myFileSelector->getNumItems(); i++) {
530
if (myFileSelector->isItemSelected(i) && !myFileSelector->isItemDirectory(i)) {
531
return FXPath::absolute(myFileSelector->getDirectory(), myFileSelector->getItemFilename(i)).text();
532
}
533
}
534
} else if (!myFilenameTextField->getText().empty()) {
535
//return FXPath::absolute(myFileSelector->getDirectory(),myFilenameTextField->getText());
536
return FXPath::absolute(myFileSelector->getDirectory(), FXPath::expand(myFilenameTextField->getText())).text(); // FIXME don't always want to expand!
537
}
538
return "";
539
}
540
541
542
std::vector<std::string>
543
GNEFileSelector::getFilenames() const {
544
return getSelectedFilesOnly();
545
}
546
547
548
std::string
549
GNEFileSelector::getDirectory() const {
550
return myFileSelector->getDirectory().text();
551
}
552
553
554
const std::vector<std::string>&
555
GNEFileSelector::getFileExtension() const {
556
return myExtensions.at(myFileFilterComboBox->getCurrentItem());
557
}
558
559
560
void
561
GNEFileSelector::setItemSpace(FXint s) {
562
myFileSelector->setItemSpace(s);
563
}
564
565
566
FXint
567
GNEFileSelector::getItemSpace() const {
568
return myFileSelector->getItemSpace();
569
}
570
571
572
void
573
GNEFileSelector::setFileBoxStyle(FXuint style) {
574
myFileSelector->setListStyle((myFileSelector->getListStyle() & ~FILESTYLEMASK) | (style & FILESTYLEMASK));
575
}
576
577
578
FXuint
579
GNEFileSelector::getFileBoxStyle() const {
580
return myFileSelector->getListStyle()&FILESTYLEMASK;
581
}
582
583
584
void
585
GNEFileSelector::setMatchMode(FXuint mode) {
586
myFileSelector->setMatchMode(mode);
587
}
588
589
590
FXuint
591
GNEFileSelector::getMatchMode() const {
592
return myFileSelector->getMatchMode();
593
}
594
595
596
FXbool
597
GNEFileSelector::showHiddenFiles() const {
598
return myFileSelector->showHiddenFiles();
599
}
600
601
602
void
603
GNEFileSelector::showHiddenFiles(FXbool showing) {
604
myFileSelector->showHiddenFiles(showing);
605
}
606
607
608
FXbool
609
GNEFileSelector::showImages() const {
610
return myFileSelector->showImages();
611
}
612
613
614
void
615
GNEFileSelector::showImages(FXbool showing) {
616
myFileSelector->showImages(showing);
617
}
618
619
620
FXint
621
GNEFileSelector::getImageSize() const {
622
return myFileSelector->getImageSize();
623
}
624
625
626
void
627
GNEFileSelector::setImageSize(FXint size) {
628
myFileSelector->setImageSize(size);
629
}
630
631
632
MFXTextFieldIcon*
633
GNEFileSelector::getFilenameTextField() const {
634
return myFilenameTextField;
635
}
636
637
638
long
639
GNEFileSelector::onCmdItemSelected(FXObject*, FXSelector, void* ptr) {
640
const FXint index = (FXint)(FXival)ptr;
641
FXString text, file;
642
if (myOpenMode == GNEFileDialog::OpenMode::LOAD_MULTIPLE) {
643
for (FXint i = 0; i < myFileSelector->getNumItems(); i++) {
644
if (myFileSelector->isItemSelected(i) && !myFileSelector->isItemDirectory(i)) {
645
if (!text.empty()) {
646
text += ' ';
647
}
648
text += "\"" + myFileSelector->getItemFilename(i) + "\"";
649
}
650
}
651
myFilenameTextField->setText(text);
652
} else if (myOpenMode == GNEFileDialog::OpenMode::LOAD_DIRECTORY) {
653
if (myFileSelector->isItemDirectory(index)) {
654
text = myFileSelector->getItemFilename(index);
655
myFilenameTextField->setText(text);
656
}
657
} else {
658
if (!myFileSelector->isItemDirectory(index)) {
659
text = myFileSelector->getItemFilename(index);
660
myFilenameTextField->setText(text);
661
}
662
}
663
return 1;
664
}
665
666
667
long
668
GNEFileSelector::onCmdItemDeselected(FXObject*, FXSelector, void*) {
669
FXString text, file;
670
if (myOpenMode == GNEFileDialog::OpenMode::LOAD_MULTIPLE) {
671
for (FXint i = 0; i < myFileSelector->getNumItems(); i++) {
672
if (myFileSelector->isItemSelected(i) && !myFileSelector->isItemDirectory(i)) {
673
if (!text.empty()) {
674
text += ' ';
675
}
676
text += "\"" + myFileSelector->getItemFilename(i) + "\"";
677
}
678
}
679
myFilenameTextField->setText(text);
680
}
681
return 1;
682
}
683
684
685
long
686
GNEFileSelector::onCmdItemDoubleClicked(FXObject* obj, FXSelector sel, void* ptr) {
687
const FXint index = (FXint)(FXival)ptr;
688
if (0 <= index) {
689
// If directory, open the directory
690
if (myFileSelector->isItemShare(index) || myFileSelector->isItemDirectory(index)) {
691
setDirectory(myFileSelector->getItemPathname(index));
692
return 1;
693
}
694
// Only return if we wanted a file
695
if (myOpenMode != GNEFileDialog::OpenMode::LOAD_DIRECTORY) {
696
return myFileDialog->onCmdAccept(obj, sel, ptr);
697
}
698
}
699
return 1;
700
}
701
702
703
long
704
GNEFileSelector::onCmdAccept(FXObject* obj, FXSelector sel, void* ptr) {
705
// Get (first) myFilenameTextField or directory
706
std::string path = getFilename();
707
// Only do something if a selection was made
708
if (path.size() > 0) {
709
// Is directory?
710
if (FXStat::isDirectory(path.c_str())) {
711
// In directory mode:- we got our answer!
712
if (myOpenMode == GNEFileDialog::OpenMode::LOAD_DIRECTORY) {
713
return myFileDialog->onCmdAccept(obj, sel, ptr);
714
}
715
// Hop over to that directory
716
myDirBox->setDirectory(path.c_str());
717
myFileSelector->setDirectory(path.c_str());
718
myFilenameTextField->setText(FXString::null);
719
return 1;
720
}
721
// Get directory part of path
722
FXString dir = FXPath::directory(path.c_str());
723
// In file mode, directory part of path should exist
724
if (FXStat::isDirectory(dir)) {
725
// In any mode, existing directory part is good enough
726
if (myOpenMode == GNEFileDialog::OpenMode::SAVE) {
727
return myFileDialog->onCmdAccept(obj, sel, ptr);
728
}
729
// Otherwise, the whole myFilenameTextField must exist and be a file
730
if (FXStat::exists(path.c_str())) {
731
return myFileDialog->onCmdAccept(obj, sel, ptr);
732
733
}
734
}
735
// Go up to the lowest directory which still exists
736
while (!FXPath::isTopDirectory(dir) && !FXStat::isDirectory(dir)) {
737
dir = FXPath::upLevel(dir);
738
}
739
// Switch as far as we could go
740
myDirBox->setDirectory(dir);
741
myFileSelector->setDirectory(dir);
742
// Put the tail end back for further editing
743
FXASSERT(dir.length() <= (int)path.size());
744
if (ISPATHSEP(path[dir.length()])) {
745
path.erase(0, dir.length() + 1);
746
} else {
747
path.erase(0, dir.length());
748
}
749
// Replace text box with new stuff
750
myFilenameTextField->setText(path.c_str());
751
myFilenameTextField->selectAll();
752
}
753
// Beep
754
getApp()->beep();
755
return 1;
756
}
757
758
759
long
760
GNEFileSelector::onCmdDirectoryUp(FXObject*, FXSelector, void*) {
761
setDirectory(FXPath::upLevel(myFileSelector->getDirectory()));
762
return 1;
763
}
764
765
766
long
767
GNEFileSelector::onUpdDirectoryUp(FXObject* sender, FXSelector, void*) {
768
// check if this is a top directory
769
const bool topDirectory = FXPath::isTopDirectory(myFileSelector->getDirectory());
770
return sender->handle(this, topDirectory ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
771
}
772
773
774
long
775
GNEFileSelector::onCmdHomeFolder(FXObject*, FXSelector, void*) {
776
setDirectory(FXSystem::getHomeDirectory());
777
return 1;
778
}
779
780
781
long
782
GNEFileSelector::onCmdWorkFolder(FXObject*, FXSelector, void*) {
783
setDirectory(FXSystem::getCurrentDirectory());
784
return 1;
785
}
786
787
788
long
789
GNEFileSelector::onCmdConfigFolder(FXObject*, FXSelector, void*) {
790
// get config file folder
791
const auto configFileFolder = FXPath::directory(OptionsCont::getOptions().getString("configuration-file").c_str());
792
setDirectory(configFileFolder);
793
return 1;
794
}
795
796
797
long
798
GNEFileSelector::onCmdVisit(FXObject*, FXSelector, void* ptr) {
799
setDirectory((FXchar*)ptr);
800
return 1;
801
}
802
803
804
long
805
GNEFileSelector::onCmdBookmark(FXObject*, FXSelector, void*) {
806
myBookmarksRecentFiles.appendFile(myFileSelector->getDirectory());
807
return 1;
808
}
809
810
811
long
812
GNEFileSelector::onCmdDirTree(FXObject*, FXSelector, void* ptr) {
813
myFileSelector->setDirectory((FXchar*)ptr);
814
if (myOpenMode == GNEFileDialog::OpenMode::LOAD_DIRECTORY) {
815
myFilenameTextField->setText(FXString::null);
816
}
817
return 1;
818
}
819
820
821
long
822
GNEFileSelector::onCmdNewFolder(FXObject*, FXSelector, void*) {
823
// create file path dialog
824
const auto filePathDialog = new GNEFilePathDialog(myFileDialog->getApplicationWindow(), TL("Create New Directory"), TL("Create new directory with name:"), "DirectoryName");
825
// continue depending of filePathDialog results
826
if (filePathDialog->getResult() == GNEDialog::Result::ACCEPT) {
827
const FXString dirname = FXPath::absolute(myFileSelector->getDirectory(), filePathDialog->getFilePath().c_str());
828
// check if exist
829
if (FXStat::exists(dirname)) {
830
// open error dialog
831
GNEErrorBasicDialog(myFileDialog->getApplicationWindow(), TL("Directory already Exists"),
832
TLF("The new directory:\n%", dirname.text()),
833
TL("already exists"));
834
return 1;
835
}
836
// try to create it
837
if (!FXDir::create(dirname)) {
838
// open error dialog
839
GNEErrorBasicDialog(myFileDialog->getApplicationWindow(), TL("Cannot create directory"),
840
TLF("Cannot create directory:\n%", dirname.text()),
841
TL("Check folder permissions"));
842
return 1;
843
}
844
// set as current directory
845
setDirectory(dirname);
846
}
847
return 1;
848
}
849
850
851
void
852
GNEFileSelector::buildBookmarkMenuPane(FXHorizontalFrame* navigatorHorizontalFrame) {
853
// create bookmarks menu pane
854
myBookmarkMenuPane = new FXMenuPane(this, POPUP_SHRINKWRAP);
855
new FXMenuCommand(myBookmarkMenuPane, (TL("Set bookmark") + std::string("\t\t") + TL("Bookmark current directory.")).c_str(),
856
GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_BOOK_SET), this, FXFileSelector::ID_BOOKMARK);
857
new FXMenuCommand(myBookmarkMenuPane, (TL("Clear bookmarks") + std::string("\t\t") + TL("Clear bookmarks.")).c_str(),
858
GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_BOOK_CLR), &myBookmarksRecentFiles, FXRecentFiles::ID_CLEAR);
859
FXMenuSeparator* separator = new FXMenuSeparator(myBookmarkMenuPane);
860
separator->setTarget(&myBookmarksRecentFiles);
861
separator->setSelector(FXRecentFiles::ID_ANYFILES);
862
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_1);
863
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_2);
864
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_3);
865
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_4);
866
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_5);
867
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_6);
868
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_7);
869
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_8);
870
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_9);
871
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_10);
872
new FXFrame(navigatorHorizontalFrame, LAYOUT_FIX_WIDTH, 0, 0, 4, 1);
873
myBookmarksRecentFiles.setTarget(this);
874
myBookmarksRecentFiles.setSelector(FXFileSelector::ID_VISIT);
875
}
876
877
878
void
879
GNEFileSelector::buildButtons(FXHorizontalFrame* navigatorHorizontalFrame, MFXStaticToolTip* staticTooltipMenu) {
880
// create button for going up one directory
881
auto goUpButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_DIRUP_ICON),
882
this, FXFileSelector::ID_DIRECTORY_UP, GUIDesignButtonIconFileDialog);
883
goUpButton->setTipText(TL("Go up one directory"));
884
// create button for go to home directory
885
auto goHomeButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_GOTO_HOME),
886
this, FXFileSelector::ID_HOME, GUIDesignButtonIconFileDialog);
887
goHomeButton->setTipText(TL("Go to home directory"));
888
// create button for go to work directory
889
auto goWorkDirectory = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_GOTO_WORK),
890
this, FXFileSelector::ID_WORK, GUIDesignButtonIconFileDialog);
891
goWorkDirectory->setTipText(TL("Go to work directory"));
892
// create button for go to work directory
893
auto goConfigDirectory = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", nullptr,
894
this, MID_GNE_BUTTON_CONFIG, GUIDesignButtonIconFileDialog);
895
// disable if configuration file is empty
896
if (OptionsCont::getOptions().getString("configuration-file").empty()) {
897
goConfigDirectory->disable();
898
}
899
// set icon and tip depending of config type
900
if (myConfigType == GNEFileDialog::ConfigType::NETEDIT) {
901
goConfigDirectory->setIcon(GUIIconSubSys::getIcon(GUIIcon::NETEDIT_MINI));
902
goConfigDirectory->setTipText(TL("Go to netedit config directory"));
903
} else {
904
goConfigDirectory->setIcon(GUIIconSubSys::getIcon(GUIIcon::SUMO_MINI));
905
goConfigDirectory->setTipText(TL("Go to sumo config directory"));
906
}
907
// create button for bookmarks menu
908
auto bookmenuTooltip = new MFXMenuButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_BOOK_SET),
909
myBookmarkMenuPane, this, GUIDesignButtonIconFileDialog);
910
bookmenuTooltip->setTipText(TL("Bookmarks"));
911
bookmenuTooltip->setSelector(FXFileSelector::ID_BOOKMENU);
912
// create button for creating a new directory
913
auto newDirectoryButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FOLDER_NEW),
914
this, FXFileSelector::ID_NEW, GUIDesignButtonIconFileDialog);
915
newDirectoryButton->setTipText(TL("Create new directory"));
916
// create button for show lists
917
auto showListButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_SHOW_SMALLICONS),
918
myFileSelector, FXFileList::ID_SHOW_MINI_ICONS, GUIDesignButtonIconFileDialog);
919
showListButton->setTipText(TL("Display directory with small icons"));
920
// create button for show icons
921
auto showIconsButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_SHOW_BIGICONS),
922
myFileSelector, FXFileList::ID_SHOW_BIG_ICONS, GUIDesignButtonIconFileDialog);
923
showIconsButton->setTipText(TL("Display directory with big icons"));
924
// create button for show details
925
auto showDetailsButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_SHOW_DETAILS),
926
myFileSelector, FXFileList::ID_SHOW_DETAILS, GUIDesignButtonIconFileDialog);
927
showDetailsButton->setTipText(TL("Display detailed directory listing"));
928
// create button for toogle show/hide hidden files
929
auto showHiddeToogleButton = new MFXToggleButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", "",
930
GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FILE_HIDDEN),
931
GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FILE_SHOWN),
932
myFileSelector, FXFileList::ID_TOGGLE_HIDDEN, GUIDesignButtonIconFileDialog);
933
showHiddeToogleButton->setTipText(TL("Toggle show hidden files and directories"));
934
}
935
936
937
void
938
GNEFileSelector::buildShortcuts() {
939
// set shortcuts
940
FXAccelTable* table = getShell()->getAccelTable();
941
if (table) {
942
table->addAccel(MKUINT(KEY_BackSpace, 0), this, FXSEL(SEL_COMMAND, FXFileSelector::ID_DIRECTORY_UP));
943
table->addAccel(MKUINT(KEY_Delete, 0), this, FXSEL(SEL_COMMAND, FXFileSelector::ID_DELETE));
944
table->addAccel(MKUINT(KEY_h, CONTROLMASK), this, FXSEL(SEL_COMMAND, FXFileSelector::ID_HOME));
945
table->addAccel(MKUINT(KEY_w, CONTROLMASK), this, FXSEL(SEL_COMMAND, FXFileSelector::ID_WORK));
946
table->addAccel(MKUINT(KEY_n, CONTROLMASK), this, FXSEL(SEL_COMMAND, FXFileSelector::ID_NEW));
947
table->addAccel(MKUINT(KEY_a, CONTROLMASK), myFileSelector, FXSEL(SEL_COMMAND, FXFileList::ID_SELECT_ALL));
948
table->addAccel(MKUINT(KEY_b, CONTROLMASK), myFileSelector, FXSEL(SEL_COMMAND, FXFileList::ID_SHOW_BIG_ICONS));
949
table->addAccel(MKUINT(KEY_s, CONTROLMASK), myFileSelector, FXSEL(SEL_COMMAND, FXFileList::ID_SHOW_MINI_ICONS));
950
table->addAccel(MKUINT(KEY_l, CONTROLMASK), myFileSelector, FXSEL(SEL_COMMAND, FXFileList::ID_SHOW_DETAILS));
951
}
952
}
953
954
955
void
956
GNEFileSelector::parseExtensions(const std::vector<std::string>& extensions) {
957
// convert extensions in FXString
958
for (const auto& extension : extensions) {
959
// first get all characters within () excluding spaces
960
const std::string cleanExtension = FXFileSelector::patternFromText(extension.c_str()).text();
961
// declare subextensions
962
std::vector<std::string> subExtensions;
963
// now subdivide
964
if (cleanExtension != "*") {
965
// split extensions
966
const auto subExtensionsStr = StringTokenizer(cleanExtension, ",").getVector();
967
for (const auto& subExtensionStr : subExtensionsStr) {
968
// ignore first *
969
subExtensions.push_back(subExtensionStr.substr(1));
970
}
971
}
972
myExtensions.push_back(subExtensions);
973
}
974
}
975
976
/*******************************************************************************/
977
978