Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/dialogs/file/GNEFileSelector.cpp
193674 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2026 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
auto GNEApp = myFileDialog->getApplicationWindow();
225
const auto filenameList = getSelectedFiles();
226
// first check if we have files to copy
227
if (filenameList.size() > 0) {
228
// get only first filename
229
const std::string originFilePath = filenameList.front();
230
// create default destiny filename
231
std::string destinyFilename = FXPath::absolute(FXPath::directory(originFilePath.c_str()), "CopyOf" + FXPath::name(originFilePath.c_str())).text();
232
// create file path dialog
233
const auto filePathDialog = new GNEFilePathDialog(GNEApp, myFileDialog, TL("Copy File"), TL("Select destination file"), destinyFilename);
234
// continue depending of filePathDialog results
235
if (filePathDialog->getResult() == GNEDialog::Result::ACCEPT) {
236
// get destiny filename from dialog
237
destinyFilename = filePathDialog->getFilePath();
238
// check if we selected the same file
239
if (FXFile::identical(originFilePath.c_str(), destinyFilename.c_str())) {
240
// open error dialog
241
GNEErrorBasicDialog(GNEApp, myFileDialog, TL("Error copying file"),
242
TLF("Unable to copy file: %", destinyFilename),
243
TL("The source and destination files are the same"));
244
} else {
245
// check if file exist
246
if (FXStat::exists(destinyFilename.c_str())) {
247
// open question dialog
248
const GNEQuestionBasicDialog overwriteDialog(GNEApp, myFileDialog, GNEDialog::Buttons::YES_NO,
249
TL("Overwrite file"), TLF("The destination file: %", destinyFilename),
250
TL("already exist. Overwrite?"));
251
// check if abort
252
if (overwriteDialog.getResult() != GNEDialog::Result::ACCEPT) {
253
return 1;
254
}
255
}
256
// try to copy overwritten
257
if (!FXFile::copyFiles(originFilePath.c_str(), destinyFilename.c_str(), TRUE)) {
258
// open error dialog
259
GNEErrorBasicDialog(GNEApp, myFileDialog, TL("Error copying file"),
260
TLF("Unable to copy file: %", destinyFilename),
261
TL("Check destination file permissions"));
262
}
263
}
264
}
265
}
266
return 1;
267
}
268
269
270
long
271
GNEFileSelector::onCmdMove(FXObject*, FXSelector, void*) {
272
auto GNEApp = myFileDialog->getApplicationWindow();
273
const auto filenameList = getSelectedFiles();
274
// first check if we have files to move
275
if (filenameList.size() > 0) {
276
// get only first filename
277
const std::string originFilePath = filenameList.front();
278
// create file path dialog
279
const auto filePathDialog = new GNEFilePathDialog(GNEApp, myFileDialog, TL("Move File"), TL("Select destination file"), originFilePath);
280
// continue depending of filePathDialog results
281
if (filePathDialog->getResult() == GNEDialog::Result::ACCEPT) {
282
// get destiny filename from dialog
283
const std::string destinyFilename = filePathDialog->getFilePath();
284
// check if we selected the same file
285
if (FXFile::identical(originFilePath.c_str(), destinyFilename.c_str())) {
286
// open error dialog
287
GNEErrorBasicDialog(GNEApp, myFileDialog, TL("Error moving file"),
288
TLF("Unable to move file:\n%\n", destinyFilename),
289
TL("The source and destination files are the same"));
290
} else {
291
// check if file exist
292
if (FXStat::exists(destinyFilename.c_str())) {
293
// open question dialog
294
const GNEQuestionBasicDialog overwriteDialog(GNEApp, myFileDialog, GNEDialog::Buttons::YES_NO,
295
TL("Overwrite file"), TLF("The destination file: %", destinyFilename),
296
TL("already exist. Overwrite?"));
297
// check if abort
298
if (overwriteDialog.getResult() != GNEDialog::Result::ACCEPT) {
299
return 1;
300
}
301
}
302
// try to move overwritten
303
if (!FXFile::moveFiles(originFilePath.c_str(), destinyFilename.c_str(), TRUE)) {
304
// open error dialog
305
GNEErrorBasicDialog(GNEApp, myFileDialog, TL("Error moving file"),
306
TLF("Unable to move file:\n%\n", destinyFilename),
307
TL("Check destination file permissions"));
308
}
309
}
310
}
311
}
312
return 1;
313
}
314
315
316
long
317
GNEFileSelector::onCmdDelete(FXObject*, FXSelector, void*) {
318
auto GNEApp = myFileDialog->getApplicationWindow();
319
const auto filenameList = getSelectedFiles();
320
// first check if we have files to link
321
if (filenameList.size() > 0) {
322
// get only first filename
323
const std::string fileToDelete = filenameList.front();
324
// open question dialog
325
const GNEQuestionBasicDialog askDialog(GNEApp, myFileDialog, GNEDialog::Buttons::YES_NO,
326
TL("Deleting file"), TL("Are you sure you want to delete the file:"),
327
fileToDelete);
328
// check if continue
329
if (askDialog.getResult() == GNEDialog::Result::ACCEPT) {
330
// try to remove it
331
if (!FXFile::removeFiles(fileToDelete.c_str(), TRUE)) {
332
// open error dialog
333
GNEErrorBasicDialog(GNEApp, myFileDialog, TL("Error deleting file"),
334
TLF("Unable to delete file: %", fileToDelete),
335
TL("Check file permissions"));
336
}
337
}
338
}
339
return 1;
340
}
341
342
343
long
344
GNEFileSelector::onUpdSelected(FXObject* sender, FXSelector, void*) {
345
for (FXint i = 0; i < myFileSelector->getNumItems(); i++) {
346
if (myFileSelector->isItemSelected(i)) {
347
sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
348
return 1;
349
}
350
}
351
sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), NULL);
352
return 1;
353
}
354
355
356
long
357
GNEFileSelector::onCmdImageSize(FXObject*, FXSelector sel, void*) {
358
switch (FXSELID(sel)) {
359
case FXFileSelector::ID_NORMAL_SIZE:
360
setImageSize(32);
361
break;
362
case FXFileSelector::ID_MEDIUM_SIZE:
363
setImageSize(48);
364
break;
365
case FXFileSelector::ID_GIANT_SIZE:
366
setImageSize(64);
367
break;
368
default:
369
setImageSize(32);
370
break;
371
}
372
return 1;
373
}
374
375
376
long
377
GNEFileSelector::onUpdImageSize(FXObject* sender, FXSelector sel, void*) {
378
FXbool check = FALSE;
379
switch (FXSELID(sel)) {
380
case FXFileSelector::ID_NORMAL_SIZE:
381
check = (getImageSize() == 32);
382
break;
383
case FXFileSelector::ID_MEDIUM_SIZE:
384
check = (getImageSize() == 48);
385
break;
386
case FXFileSelector::ID_GIANT_SIZE:
387
check = (getImageSize() == 64);
388
break;
389
default:
390
check = (getImageSize() == 32);
391
break;
392
}
393
sender->handle(this, check ? FXSEL(SEL_COMMAND, ID_CHECK) : FXSEL(SEL_COMMAND, ID_UNCHECK), NULL);
394
return 1;
395
}
396
397
398
long
399
GNEFileSelector::onKeyPress(FXObject* obj, FXSelector sel, void* ptr) {
400
// if ESC key is pressed, close dialog aborting
401
FXEvent* event = (FXEvent*)ptr;
402
if (event->code == KEY_Return) {
403
return onCmdAccept(obj, sel, ptr);
404
} else {
405
return FXVerticalFrame::onKeyPress(obj, sel, ptr);
406
}
407
}
408
409
410
long
411
GNEFileSelector::onPopupMenu(FXObject*, FXSelector, void* ptr) {
412
FXEvent* event = (FXEvent*)ptr;
413
if (event->moved) {
414
return 1;
415
}
416
417
FXMenuPane filemenu(this);
418
new FXMenuCommand(&filemenu, TL("Up one level"), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_DIRUP_ICON), this, FXFileSelector::ID_DIRECTORY_UP);
419
new FXMenuCommand(&filemenu, TL("Home directory"), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_GOTO_HOME), this, FXFileSelector::ID_HOME);
420
new FXMenuCommand(&filemenu, TL("Work directory"), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_GOTO_WORK), this, FXFileSelector::ID_WORK);
421
auto configDirectory = new FXMenuCommand(&filemenu, TL("Config directory"), nullptr, this, MID_GNE_BUTTON_CONFIG);
422
// disable if configuration file is empty
423
if (OptionsCont::getOptions().getString("configuration-file").empty()) {
424
configDirectory->disable();
425
}
426
// set icon and tip depending of config type
427
if (myConfigType == GNEFileDialog::ConfigType::NETEDIT) {
428
configDirectory->setIcon(GUIIconSubSys::getIcon(GUIIcon::NETEDIT_MINI));
429
} else {
430
configDirectory->setIcon(GUIIconSubSys::getIcon(GUIIcon::SUMO_MINI));
431
}
432
new FXMenuCommand(&filemenu, TL("Select all"), NULL, myFileSelector, FXFileList::ID_SELECT_ALL);
433
new FXMenuSeparator(&filemenu);
434
435
FXMenuPane sortmenu(this);
436
new FXMenuCascade(&filemenu, TL("Sort by"), NULL, &sortmenu);
437
new FXMenuRadio(&sortmenu, TL("Name"), myFileSelector, FXFileList::ID_SORT_BY_NAME);
438
new FXMenuRadio(&sortmenu, TL("Type"), myFileSelector, FXFileList::ID_SORT_BY_TYPE);
439
new FXMenuRadio(&sortmenu, TL("Size"), myFileSelector, FXFileList::ID_SORT_BY_SIZE);
440
new FXMenuRadio(&sortmenu, TL("Time"), myFileSelector, FXFileList::ID_SORT_BY_TIME);
441
new FXMenuRadio(&sortmenu, TL("User"), myFileSelector, FXFileList::ID_SORT_BY_USER);
442
new FXMenuRadio(&sortmenu, TL("Group"), myFileSelector, FXFileList::ID_SORT_BY_GROUP);
443
new FXMenuSeparator(&sortmenu);
444
new FXMenuCheck(&sortmenu, TL("Reverse"), myFileSelector, FXFileList::ID_SORT_REVERSE);
445
new FXMenuCheck(&sortmenu, TL("Ignore case"), myFileSelector, FXFileList::ID_SORT_CASE);
446
447
FXMenuPane viewmenu(this);
448
new FXMenuCascade(&filemenu, TL("View"), NULL, &viewmenu);
449
new FXMenuRadio(&viewmenu, TL("Small icons"), myFileSelector, FXFileList::ID_SHOW_MINI_ICONS);
450
new FXMenuRadio(&viewmenu, TL("Big icons"), myFileSelector, FXFileList::ID_SHOW_BIG_ICONS);
451
new FXMenuRadio(&viewmenu, TL("Details"), myFileSelector, FXFileList::ID_SHOW_DETAILS);
452
new FXMenuSeparator(&viewmenu);
453
new FXMenuRadio(&viewmenu, TL("Rows"), myFileSelector, FXFileList::ID_ARRANGE_BY_ROWS);
454
new FXMenuRadio(&viewmenu, TL("Columns"), myFileSelector, FXFileList::ID_ARRANGE_BY_COLUMNS);
455
new FXMenuSeparator(&viewmenu);
456
new FXMenuCheck(&viewmenu, TL("Hidden files"), myFileSelector, FXFileList::ID_TOGGLE_HIDDEN);
457
new FXMenuCheck(&viewmenu, TL("Preview images"), myFileSelector, FXFileList::ID_TOGGLE_IMAGES);
458
new FXMenuSeparator(&viewmenu);
459
new FXMenuRadio(&viewmenu, TL("Normal images"), this, FXFileSelector::ID_NORMAL_SIZE);
460
new FXMenuRadio(&viewmenu, TL("Medium images"), this, FXFileSelector::ID_MEDIUM_SIZE);
461
new FXMenuRadio(&viewmenu, TL("Giant images"), this, FXFileSelector::ID_GIANT_SIZE);
462
463
FXMenuPane bookmenu(this);
464
FXMenuCascade* bookcasc = new FXMenuCascade(&filemenu, TL("Bookmarks"), NULL, &bookmenu);
465
bookcasc->setTarget(this);
466
bookcasc->setSelector(FXFileSelector::ID_BOOKMENU);
467
new FXMenuCommand(&bookmenu, TL("Set bookmark"), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_BOOK_SET), this, FXFileSelector::ID_BOOKMARK);
468
new FXMenuCommand(&bookmenu, TL("Clear bookmarks"), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_BOOK_CLR), &myBookmarksRecentFiles, FXRecentFiles::ID_CLEAR);
469
FXMenuSeparator* sep1 = new FXMenuSeparator(&bookmenu);
470
sep1->setTarget(&myBookmarksRecentFiles);
471
sep1->setSelector(FXRecentFiles::ID_ANYFILES);
472
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_1);
473
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_2);
474
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_3);
475
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_4);
476
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_5);
477
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_6);
478
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_7);
479
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_8);
480
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_9);
481
new FXMenuCommand(&bookmenu, FXString::null, NULL, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_10);
482
483
new FXMenuSeparator(&filemenu);
484
new FXMenuCommand(&filemenu, TL("New directory..."), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FOLDER_NEW), this, FXFileSelector::ID_NEW);
485
new FXMenuCommand(&filemenu, TL("Copy..."), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FILE_COPY), this, FXFileSelector::ID_COPY);
486
new FXMenuCommand(&filemenu, TL("Move..."), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FILE_MOVE), this, FXFileSelector::ID_MOVE);
487
// disabled linker because it doesn't work
488
new FXMenuCommand(&filemenu, TL("Delete..."), GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FILE_DELETE), this, FXFileSelector::ID_DELETE);
489
490
filemenu.create();
491
filemenu.popup(NULL, event->root_x, event->root_y);
492
getApp()->runModalWhileShown(&filemenu);
493
return 1;
494
}
495
496
497
long
498
GNEFileSelector::onCmdFilter(FXObject*, FXSelector, void* ptr) {
499
const FXString pat = FXFileSelector::patternFromText((FXchar*)ptr);
500
myFileSelector->setPattern(pat);
501
if (myOpenMode == GNEFileDialog::OpenMode::SAVE) {
502
FXString ext = FXFileSelector::extensionFromPattern(pat);
503
if (!ext.empty()) {
504
FXString name = FXPath::stripExtension(myFilenameTextField->getText());
505
if (!name.empty()) {
506
myFilenameTextField->setText(name + "." + ext);
507
}
508
}
509
}
510
return 1;
511
}
512
513
514
void
515
GNEFileSelector::setDirectory(const FXString& path) {
516
const FXString abspath = FXPath::absolute(path);
517
myFileSelector->setDirectory(abspath);
518
myDirBox->setDirectory(abspath);
519
if (myOpenMode != GNEFileDialog::OpenMode::SAVE) {
520
myFilenameTextField->setText(FXString::null);
521
}
522
}
523
524
525
void
526
GNEFileSelector::setFilename(const FXString& path) {
527
const FXString fullname(FXPath::absolute(path));
528
FXString name(FXPath::name(fullname));
529
myFileSelector->setCurrentFile(fullname);
530
myDirBox->setDirectory(myFileSelector->getDirectory());
531
myFilenameTextField->setText(name);
532
}
533
534
535
std::string
536
GNEFileSelector::getFilename() const {
537
// continue depending if we write something in the text field
538
if (myFilenameTextField->getText().empty()) {
539
for (FXint i = 0; i < myFileSelector->getNumItems(); i++) {
540
if (myFileSelector->isItemSelected(i) &&
541
!myFileSelector->isItemDirectory(i)) {
542
return FXPath::absolute(myFileSelector->getDirectory(), myFileSelector->getItemFilename(i)).text();
543
}
544
}
545
return "";
546
} else {
547
return FXPath::absolute(myFileSelector->getDirectory(), myFilenameTextField->getText()).text();
548
}
549
}
550
551
552
std::string
553
GNEFileSelector::getDirectory() const {
554
// continue depending if we write something in the text field
555
if (myFilenameTextField->getText().empty()) {
556
for (FXint i = 0; i < myFileSelector->getNumItems(); i++) {
557
if (myFileSelector->isItemSelected(i) &&
558
myFileSelector->isItemDirectory(i)) {
559
return FXPath::absolute(myFileSelector->getDirectory(), myFileSelector->getItemFilename(i)).text();
560
}
561
}
562
} else if (FXStat::isDirectory(myFilenameTextField->getText())) {
563
return myFilenameTextField->getText().text();
564
} else {
565
for (FXint i = 0; i < myFileSelector->getNumItems(); i++) {
566
if (myFileSelector->isItemDirectory(i) &&
567
(myFileSelector->getItemFilename(i) == myFilenameTextField->getText())) {
568
return FXPath::absolute(myFileSelector->getDirectory(), myFileSelector->getItemFilename(i)).text();
569
}
570
}
571
}
572
return "";
573
}
574
575
576
std::vector<std::string>
577
GNEFileSelector::getFilenames() const {
578
return getSelectedFilesOnly();
579
}
580
581
582
std::string
583
GNEFileSelector::getCurrentDirectory() const {
584
return myFileSelector->getDirectory().text();
585
}
586
587
588
const std::vector<std::string>&
589
GNEFileSelector::getFileExtension() const {
590
return myExtensions.at(myFileFilterComboBox->getCurrentItem());
591
}
592
593
594
void
595
GNEFileSelector::setItemSpace(FXint s) {
596
myFileSelector->setItemSpace(s);
597
}
598
599
600
FXint
601
GNEFileSelector::getItemSpace() const {
602
return myFileSelector->getItemSpace();
603
}
604
605
606
void
607
GNEFileSelector::setFileBoxStyle(FXuint style) {
608
myFileSelector->setListStyle((myFileSelector->getListStyle() & ~FILESTYLEMASK) | (style & FILESTYLEMASK));
609
}
610
611
612
FXuint
613
GNEFileSelector::getFileBoxStyle() const {
614
return myFileSelector->getListStyle()&FILESTYLEMASK;
615
}
616
617
618
void
619
GNEFileSelector::setMatchMode(FXuint mode) {
620
myFileSelector->setMatchMode(mode);
621
}
622
623
624
FXuint
625
GNEFileSelector::getMatchMode() const {
626
return myFileSelector->getMatchMode();
627
}
628
629
630
FXbool
631
GNEFileSelector::showHiddenFiles() const {
632
return myFileSelector->showHiddenFiles();
633
}
634
635
636
void
637
GNEFileSelector::showHiddenFiles(FXbool showing) {
638
myFileSelector->showHiddenFiles(showing);
639
}
640
641
642
FXbool
643
GNEFileSelector::showImages() const {
644
return myFileSelector->showImages();
645
}
646
647
648
void
649
GNEFileSelector::showImages(FXbool showing) {
650
myFileSelector->showImages(showing);
651
}
652
653
654
FXint
655
GNEFileSelector::getImageSize() const {
656
return myFileSelector->getImageSize();
657
}
658
659
660
void
661
GNEFileSelector::setImageSize(FXint size) {
662
myFileSelector->setImageSize(size);
663
}
664
665
666
MFXTextFieldIcon*
667
GNEFileSelector::getFilenameTextField() const {
668
return myFilenameTextField;
669
}
670
671
672
long
673
GNEFileSelector::onCmdItemSelected(FXObject*, FXSelector, void* ptr) {
674
const FXint index = (FXint)(FXival)ptr;
675
FXString text, file;
676
if (myOpenMode == GNEFileDialog::OpenMode::LOAD_MULTIPLE) {
677
for (FXint i = 0; i < myFileSelector->getNumItems(); i++) {
678
if (myFileSelector->isItemSelected(i) && !myFileSelector->isItemDirectory(i)) {
679
if (!text.empty()) {
680
text += ' ';
681
}
682
text += "\"" + myFileSelector->getItemFilename(i) + "\"";
683
}
684
}
685
myFilenameTextField->setText(text);
686
} else if (myOpenMode == GNEFileDialog::OpenMode::LOAD_DIRECTORY) {
687
if (myFileSelector->isItemDirectory(index)) {
688
text = myFileSelector->getItemFilename(index);
689
myFilenameTextField->setText(text);
690
}
691
} else {
692
if (!myFileSelector->isItemDirectory(index)) {
693
text = myFileSelector->getItemFilename(index);
694
myFilenameTextField->setText(text);
695
}
696
}
697
return 1;
698
}
699
700
701
long
702
GNEFileSelector::onCmdItemDeselected(FXObject*, FXSelector, void*) {
703
FXString text, file;
704
if (myOpenMode == GNEFileDialog::OpenMode::LOAD_MULTIPLE) {
705
for (FXint i = 0; i < myFileSelector->getNumItems(); i++) {
706
if (myFileSelector->isItemSelected(i) && !myFileSelector->isItemDirectory(i)) {
707
if (!text.empty()) {
708
text += ' ';
709
}
710
text += "\"" + myFileSelector->getItemFilename(i) + "\"";
711
}
712
}
713
myFilenameTextField->setText(text);
714
}
715
return 1;
716
}
717
718
719
long
720
GNEFileSelector::onCmdItemDoubleClicked(FXObject* obj, FXSelector sel, void* ptr) {
721
const FXint index = (FXint)(FXival)ptr;
722
if (0 <= index) {
723
// If directory, open the directory
724
if (myFileSelector->isItemShare(index) || myFileSelector->isItemDirectory(index)) {
725
setDirectory(myFileSelector->getItemPathname(index));
726
return 1;
727
}
728
// Only return if we wanted a file
729
if (myOpenMode != GNEFileDialog::OpenMode::LOAD_DIRECTORY) {
730
return onCmdAccept(obj, sel, ptr);
731
}
732
}
733
return 1;
734
}
735
736
737
long
738
GNEFileSelector::onCmdAccept(FXObject* obj, FXSelector sel, void* ptr) {
739
auto GNEApp = myFileDialog->getApplicationWindow();
740
// get directory
741
const std::string directory = getDirectory();
742
// continue if we selected a directory
743
if (directory.size() > 0) {
744
// In directory mode:- we got our answer!
745
if (myOpenMode == GNEFileDialog::OpenMode::LOAD_DIRECTORY) {
746
return myFileDialog->onCmdAccept(obj, sel, ptr);
747
} else {
748
// Hop over to that directory
749
setDirectory(directory.c_str());
750
myFilenameTextField->setText(FXString::null);
751
return 1;
752
}
753
}
754
// get filename
755
std::string filename = getFilename();
756
// continue if we selected a filename
757
if (filename.size() > 0) {
758
// Get directory part of path
759
FXString dir = FXPath::directory(filename.c_str());
760
// In file mode, directory part of path should exist
761
if (FXStat::isDirectory(dir)) {
762
// set directory
763
setDirectory(dir);
764
// ensure that filename has extension
765
const std::string filenameExtension = myFileDialog->assureExtension(filename);
766
const std::string file = FXPath::name(filenameExtension.c_str()).text();
767
// now continue if we're loading or saving
768
if (myOpenMode == GNEFileDialog::OpenMode::SAVE) {
769
// ask if file exist
770
if (FXStat::exists(filenameExtension.c_str())) {
771
// open question dialog
772
const GNEQuestionBasicDialog overwriteDialog(GNEApp, myFileDialog, GNEDialog::Buttons::YES_NO,
773
TL("Overwrite file"), TLF("The selected file: %", file),
774
TL("already exist. Overwrite?"));
775
// check if abort
776
if (overwriteDialog.getResult() != GNEDialog::Result::ACCEPT) {
777
return 1;
778
}
779
}
780
return myFileDialog->onCmdAccept(obj, sel, ptr);
781
} else {
782
// check that file exist
783
if (FXStat::exists(filenameExtension.c_str())) {
784
return myFileDialog->onCmdAccept(obj, sel, ptr);
785
} else {
786
// open error dialog
787
GNEErrorBasicDialog(GNEApp, myFileDialog,
788
TL("File doesn't exist"),
789
TLF("The selected file '%'", file),
790
TL("doesn't exist"));
791
return 0;
792
}
793
}
794
}
795
}
796
// Beep
797
getApp()->beep();
798
return 1;
799
}
800
801
802
long
803
GNEFileSelector::onCmdDirectoryUp(FXObject*, FXSelector, void*) {
804
setDirectory(FXPath::upLevel(myFileSelector->getDirectory()));
805
return 1;
806
}
807
808
809
long
810
GNEFileSelector::onUpdDirectoryUp(FXObject* sender, FXSelector, void*) {
811
// check if this is a top directory
812
const bool topDirectory = FXPath::isTopDirectory(myFileSelector->getDirectory());
813
return sender->handle(this, topDirectory ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
814
}
815
816
817
long
818
GNEFileSelector::onCmdHomeFolder(FXObject*, FXSelector, void*) {
819
setDirectory(FXSystem::getHomeDirectory());
820
return 1;
821
}
822
823
824
long
825
GNEFileSelector::onCmdWorkFolder(FXObject*, FXSelector, void*) {
826
setDirectory(FXSystem::getCurrentDirectory());
827
return 1;
828
}
829
830
831
long
832
GNEFileSelector::onCmdConfigFolder(FXObject*, FXSelector, void*) {
833
// get config file folder
834
const auto configFileFolder = FXPath::directory(OptionsCont::getOptions().getString("configuration-file").c_str());
835
setDirectory(configFileFolder);
836
return 1;
837
}
838
839
840
long
841
GNEFileSelector::onCmdVisit(FXObject*, FXSelector, void* ptr) {
842
setDirectory((FXchar*)ptr);
843
return 1;
844
}
845
846
847
long
848
GNEFileSelector::onCmdBookmark(FXObject*, FXSelector, void*) {
849
myBookmarksRecentFiles.appendFile(myFileSelector->getDirectory());
850
return 1;
851
}
852
853
854
long
855
GNEFileSelector::onCmdDirTree(FXObject*, FXSelector, void* ptr) {
856
myFileSelector->setDirectory((FXchar*)ptr);
857
if (myOpenMode == GNEFileDialog::OpenMode::LOAD_DIRECTORY) {
858
myFilenameTextField->setText(FXString::null);
859
}
860
return 1;
861
}
862
863
864
long
865
GNEFileSelector::onCmdNewFolder(FXObject*, FXSelector, void*) {
866
auto GNEApp = myFileDialog->getApplicationWindow();
867
// create file path dialog
868
const auto filePathDialog = new GNEFilePathDialog(GNEApp, myFileDialog, TL("Create New Directory"),
869
TL("Create new directory with name:"), "DirectoryName");
870
// continue depending of filePathDialog results
871
if (filePathDialog->getResult() == GNEDialog::Result::ACCEPT) {
872
const FXString dirname = FXPath::absolute(myFileSelector->getDirectory(), filePathDialog->getFilePath().c_str());
873
// check if exist
874
if (FXStat::exists(dirname)) {
875
// open error dialog
876
GNEErrorBasicDialog(GNEApp, myFileDialog, TL("Directory already Exists"),
877
TLF("The new directory:\n%", dirname.text()),
878
TL("already exists"));
879
return 1;
880
}
881
// try to create it
882
if (!FXDir::create(dirname)) {
883
// open error dialog
884
GNEErrorBasicDialog(GNEApp, myFileDialog, TL("Cannot create directory"),
885
TLF("Cannot create directory:\n%", dirname.text()),
886
TL("Check folder permissions"));
887
return 1;
888
}
889
// set as current directory
890
setDirectory(dirname);
891
}
892
return 1;
893
}
894
895
896
void
897
GNEFileSelector::buildBookmarkMenuPane(FXHorizontalFrame* navigatorHorizontalFrame) {
898
// create bookmarks menu pane
899
myBookmarkMenuPane = new FXMenuPane(this, POPUP_SHRINKWRAP);
900
new FXMenuCommand(myBookmarkMenuPane, (TL("Set bookmark") + std::string("\t\t") + TL("Bookmark current directory.")).c_str(),
901
GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_BOOK_SET), this, FXFileSelector::ID_BOOKMARK);
902
new FXMenuCommand(myBookmarkMenuPane, (TL("Clear bookmarks") + std::string("\t\t") + TL("Clear bookmarks.")).c_str(),
903
GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_BOOK_CLR), &myBookmarksRecentFiles, FXRecentFiles::ID_CLEAR);
904
FXMenuSeparator* separator = new FXMenuSeparator(myBookmarkMenuPane);
905
separator->setTarget(&myBookmarksRecentFiles);
906
separator->setSelector(FXRecentFiles::ID_ANYFILES);
907
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_1);
908
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_2);
909
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_3);
910
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_4);
911
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_5);
912
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_6);
913
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_7);
914
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_8);
915
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_9);
916
new FXMenuCommand(myBookmarkMenuPane, FXString::null, nullptr, &myBookmarksRecentFiles, FXRecentFiles::ID_FILE_10);
917
new FXFrame(navigatorHorizontalFrame, LAYOUT_FIX_WIDTH, 0, 0, 4, 1);
918
myBookmarksRecentFiles.setTarget(this);
919
myBookmarksRecentFiles.setSelector(FXFileSelector::ID_VISIT);
920
}
921
922
923
void
924
GNEFileSelector::buildButtons(FXHorizontalFrame* navigatorHorizontalFrame, MFXStaticToolTip* staticTooltipMenu) {
925
// create button for going up one directory
926
auto goUpButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_DIRUP_ICON),
927
this, FXFileSelector::ID_DIRECTORY_UP, GUIDesignButtonIconFileDialog);
928
goUpButton->setTipText(TL("Go up one directory"));
929
// create button for go to home directory
930
auto goHomeButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_GOTO_HOME),
931
this, FXFileSelector::ID_HOME, GUIDesignButtonIconFileDialog);
932
goHomeButton->setTipText(TL("Go to home directory"));
933
// create button for go to work directory
934
auto goWorkDirectory = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_GOTO_WORK),
935
this, FXFileSelector::ID_WORK, GUIDesignButtonIconFileDialog);
936
goWorkDirectory->setTipText(TL("Go to work directory"));
937
// create button for go to work directory
938
auto goConfigDirectory = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", nullptr,
939
this, MID_GNE_BUTTON_CONFIG, GUIDesignButtonIconFileDialog);
940
// disable if configuration file is empty
941
if (OptionsCont::getOptions().getString("configuration-file").empty()) {
942
goConfigDirectory->disable();
943
}
944
// set icon and tip depending of config type
945
if (myConfigType == GNEFileDialog::ConfigType::NETEDIT) {
946
goConfigDirectory->setIcon(GUIIconSubSys::getIcon(GUIIcon::NETEDIT_MINI));
947
goConfigDirectory->setTipText(TL("Go to netedit config directory"));
948
} else {
949
goConfigDirectory->setIcon(GUIIconSubSys::getIcon(GUIIcon::SUMO_MINI));
950
goConfigDirectory->setTipText(TL("Go to sumo config directory"));
951
}
952
// create button for bookmarks menu
953
auto bookmenuTooltip = new MFXMenuButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_BOOK_SET),
954
myBookmarkMenuPane, this, GUIDesignButtonIconFileDialog);
955
bookmenuTooltip->setTipText(TL("Bookmarks"));
956
bookmenuTooltip->setSelector(FXFileSelector::ID_BOOKMENU);
957
// create button for creating a new directory
958
auto newDirectoryButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FOLDER_NEW),
959
this, FXFileSelector::ID_NEW, GUIDesignButtonIconFileDialog);
960
newDirectoryButton->setTipText(TL("Create new directory"));
961
// create button for show lists
962
auto showListButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_SHOW_SMALLICONS),
963
myFileSelector, FXFileList::ID_SHOW_MINI_ICONS, GUIDesignButtonIconFileDialog);
964
showListButton->setTipText(TL("Display directory with small icons"));
965
// create button for show icons
966
auto showIconsButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_SHOW_BIGICONS),
967
myFileSelector, FXFileList::ID_SHOW_BIG_ICONS, GUIDesignButtonIconFileDialog);
968
showIconsButton->setTipText(TL("Display directory with big icons"));
969
// create button for show details
970
auto showDetailsButton = new MFXButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_SHOW_DETAILS),
971
myFileSelector, FXFileList::ID_SHOW_DETAILS, GUIDesignButtonIconFileDialog);
972
showDetailsButton->setTipText(TL("Display detailed directory listing"));
973
// create button for toogle show/hide hidden files
974
auto showHiddeToogleButton = new MFXToggleButtonTooltip(navigatorHorizontalFrame, staticTooltipMenu, "", "",
975
GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FILE_HIDDEN),
976
GUIIconSubSys::getIcon(GUIIcon::FILEDIALOG_FILE_SHOWN),
977
myFileSelector, FXFileList::ID_TOGGLE_HIDDEN, GUIDesignButtonIconFileDialog);
978
showHiddeToogleButton->setTipText(TL("Toggle show hidden files and directories"));
979
}
980
981
982
void
983
GNEFileSelector::buildShortcuts() {
984
// set shortcuts
985
FXAccelTable* table = getShell()->getAccelTable();
986
if (table) {
987
table->addAccel(MKUINT(KEY_BackSpace, 0), this, FXSEL(SEL_COMMAND, FXFileSelector::ID_DIRECTORY_UP));
988
table->addAccel(MKUINT(KEY_Delete, 0), this, FXSEL(SEL_COMMAND, FXFileSelector::ID_DELETE));
989
table->addAccel(MKUINT(KEY_h, CONTROLMASK), this, FXSEL(SEL_COMMAND, FXFileSelector::ID_HOME));
990
table->addAccel(MKUINT(KEY_w, CONTROLMASK), this, FXSEL(SEL_COMMAND, FXFileSelector::ID_WORK));
991
table->addAccel(MKUINT(KEY_n, CONTROLMASK), this, FXSEL(SEL_COMMAND, FXFileSelector::ID_NEW));
992
table->addAccel(MKUINT(KEY_a, CONTROLMASK), myFileSelector, FXSEL(SEL_COMMAND, FXFileList::ID_SELECT_ALL));
993
table->addAccel(MKUINT(KEY_b, CONTROLMASK), myFileSelector, FXSEL(SEL_COMMAND, FXFileList::ID_SHOW_BIG_ICONS));
994
table->addAccel(MKUINT(KEY_s, CONTROLMASK), myFileSelector, FXSEL(SEL_COMMAND, FXFileList::ID_SHOW_MINI_ICONS));
995
table->addAccel(MKUINT(KEY_l, CONTROLMASK), myFileSelector, FXSEL(SEL_COMMAND, FXFileList::ID_SHOW_DETAILS));
996
}
997
}
998
999
1000
void
1001
GNEFileSelector::parseExtensions(const std::vector<std::string>& extensions) {
1002
// convert extensions in FXString
1003
for (const auto& extension : extensions) {
1004
// first get all characters within () excluding spaces
1005
const std::string cleanExtension = FXFileSelector::patternFromText(extension.c_str()).text();
1006
// declare subextensions
1007
std::vector<std::string> subExtensions;
1008
// now subdivide
1009
if (cleanExtension != "*") {
1010
// split extensions
1011
const auto subExtensionsStr = StringTokenizer(cleanExtension, ",").getVector();
1012
for (const auto& subExtensionStr : subExtensionsStr) {
1013
// ignore first *
1014
subExtensions.push_back(subExtensionStr.substr(1));
1015
}
1016
}
1017
myExtensions.push_back(subExtensions);
1018
}
1019
}
1020
1021
/*******************************************************************************/
1022
1023