TDME2  1.9.200
FileDialogScreenController.cpp
Go to the documentation of this file.
2 
3 #include <algorithm>
4 #include <memory>
5 #include <string>
6 #include <unordered_map>
7 #include <vector>
8 
9 #include <tdme/tdme.h>
10 #include <tdme/engine/Engine.h>
15 #include <tdme/gui/nodes/GUINode.h>
20 #include <tdme/gui/GUI.h>
21 #include <tdme/gui/GUIParser.h>
27 #include <tdme/utilities/Action.h>
28 #include <tdme/utilities/Console.h>
33 
34 using std::remove;
35 using std::reverse;
36 using std::string;
37 using std::unique_ptr;
38 using std::unordered_map;
39 using std::vector;
40 
42 
53 using tdme::gui::GUI;
66 
67 FileDialogScreenController::FileDialogScreenController(PopUps* popUps)
68 {
69  this->popUps = popUps;
70  this->cwd = FileSystem::getStandardFileSystem()->getCurrentWorkingPathName();
71 }
72 
74 }
75 
77 {
79 }
80 
82 {
83  try {
84  screenNode = GUIParser::parse("resources/engine/gui", "popup_filedialog.xml");
85  screenNode->setEnabled(false);
90  tabsHeaderNode = required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("filedialog_tabs-header"));
91  pathNode = required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("filedialog_path"));
92  filesNode = required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("filedialog_files"));
93  favoritesNode = required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("filedialog_favorites"));
94  recentsNode = required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("filedialog_recent"));
95  drivesNode = required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("filedialog_drives"));
96  fileNameNode = required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("filedialog_filename"));
97  typeDropDownNode = required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("filedialog_typedropdown"));
98  } catch (Exception& exception) {
99  Console::println("FileDialogScreenController::initialize(): An error occurred: " + string(exception.what()));
100  }
101 }
102 
104 {
105  screenNode = nullptr;
106 }
107 
109 {
110  class ExtensionFilter: public virtual FileNameFilter
111  {
112  public:
113  bool accept(const string& pathName, const string& fileName) override {
114  if (FileSystem::getStandardFileSystem()->isPath(pathName + "/" + fileName) == true) return true;
115  if (extension.empty() == false) {
116  if (StringTools::endsWith(StringTools::toLowerCase(fileName), "." + extension) == true) return true;
117  } else {
118  for (const auto& extension : fileDialogScreenController->extensions) {
119  if (StringTools::endsWith(StringTools::toLowerCase(fileName), "." + extension) == true) return true;
120  }
121  }
122  return false;
123  }
124 
125  /**
126  * Public constructor
127  * @param fileDialogScreenController file dialog screen controller
128  */
129  ExtensionFilter(FileDialogScreenController* fileDialogScreenController, const string& extension): fileDialogScreenController(fileDialogScreenController), extension(extension) {
130  }
131 
132  private:
133  FileDialogScreenController* fileDialogScreenController;
134  string extension;
135  };
136 
137  //
138  required_dynamic_cast<GUIParentNode*>(screenNode->getInnerNodeById(tabsHeaderNode->getId()))->replaceSubNodes("<tab id=\"filedialog_caption\" image=\"resources/engine/images/attention.png\" text=\"" + GUIParser::escape(captionText)+ "\" closeable=\"true\"/>", true);
140 
141  //
142  fileList.clear();
143  auto success = true;
144  try {
145  auto directory = cwd;
146  ExtensionFilter extensionsFilter(this, typeDropDownNode->getController()->getValue().getString());
147  FileSystem::getStandardFileSystem()->list(directory, fileList, &extensionsFilter);
148  } catch (Exception& exception) {
149  Console::println("FileDialogScreenController::setupFileDialogListBox(): An error occurred: " + string(exception.what()));
150  success = false;
151  }
153  if (enableFilter == true) fileNameNode->getController()->setValue(MutableString("Type a string to filter the list..."));
154 
155  //
156  filtered = false;
157 
158  //
159  return success;
160 }
161 
162 void FileDialogScreenController::setupFiles(const vector<string>& fileNameList, const string& selectedFileName) {
163  auto filesInnerNode = required_dynamic_cast<GUIParentNode*>(filesNode->getScreenNode()->getInnerNodeById(filesNode->getId()));
164  auto idx = 1;
165  string filesInnerNodeSubNodesXML;
166  filesInnerNodeSubNodesXML+=
167  "<scrollarea width=\"100%\" height=\"100%\" background-color=\"{$color.element_midground}\">\n";
168  for (const auto& fileName : fileNameList) {
169  auto fileImageName = getFileImageName(fileName);
170  try {
171  if (FileSystem::getStandardFileSystem()->isPath(cwd + "/" + fileName) == true) fileImageName = "folder";
172  } catch (Exception& exception) {
173  Console::println("FileDialogScreenController::setupFileDialogListBox(): An error occurred: " + string(exception.what()));
174  }
175  filesInnerNodeSubNodesXML+=
176  "<selectbox-option text=\"" +
177  GUIParser::escape(fileName) +
178  "\" value=\"" +
179  GUIParser::escape(fileName) +
180  "\"" +
181  (selectedFileName == fileName?" selected=\"true\"":"") + " " +
182  "image=\"{$icon.type_" + fileImageName + "}\" " +
183  "/>\n";
184  }
185  filesInnerNodeSubNodesXML+= "</scrollarea>\n";
186  try {
187  filesInnerNode->replaceSubNodes(filesInnerNodeSubNodesXML, false);
188  } catch (Exception& exception) {
189  Console::println("FileDialogScreenController::setupFileDialogListBox(): An error occurred: " + string(exception.what()));
190  }
191 }
192 
194  auto favoritesInnerNode = required_dynamic_cast<GUIParentNode*>(favoritesNode->getScreenNode()->getInnerNodeById(favoritesNode->getId()));
195  auto idx = 1;
196  string favoritesInnerNodeSubNodesXML;
197  favoritesInnerNodeSubNodesXML+=
198  "<scrollarea width=\"100%\" height=\"100%\" background-color=\"{$color.element_midground}\">\n";
199  for (const auto& favorite: favorites) {
200  auto fileImageName = "folder";
201  favoritesInnerNodeSubNodesXML+=
202  "<selectbox-option text=\"" +
203  GUIParser::escape(FileSystem::getStandardFileSystem()->getFileName(StringTools::endsWith(favorite, "/") == true?StringTools::substring(favorite, 0, favorite.size() - 1):favorite)) +
204  "\" value=\"" +
205  GUIParser::escape(favorite) +
206  "\" " +
207  "image=\"{$icon.type_folder}\" " +
208  "/>\n";
209  }
210  favoritesInnerNodeSubNodesXML+= "</scrollarea>\n";
211  try {
212  favoritesInnerNode->replaceSubNodes(favoritesInnerNodeSubNodesXML, false);
213  } catch (Exception& exception) {
214  Console::println("FileDialogScreenController::setupFavorites(): An error occurred: " + string(exception.what()));
215  }
216 }
217 
219  auto recentsInnerNode = required_dynamic_cast<GUIParentNode*>(recentsNode->getScreenNode()->getInnerNodeById(recentsNode->getId()));
220  auto idx = 1;
221  string recentsInnerNodeSubNodesXML;
222  recentsInnerNodeSubNodesXML+=
223  "<scrollarea width=\"100%\" height=\"100%\" background-color=\"{$color.element_midground}\">\n";
224  auto recentsReversed = recents;
225  reverse(recentsReversed.begin(), recentsReversed.end());
226  for (const auto& recent: recentsReversed) {
227  auto fileImageName = "folder";
228  recentsInnerNodeSubNodesXML+=
229  "<selectbox-option text=\"" +
230  GUIParser::escape(FileSystem::getStandardFileSystem()->getFileName(StringTools::endsWith(recent, "/") == true?StringTools::substring(recent, 0, recent.size() - 1):recent)) +
231  "\" value=\"" +
232  GUIParser::escape(recent) +
233  "\" " +
234  "image=\"{$icon.type_folder}\" " +
235  "/>\n";
236  }
237  recentsInnerNodeSubNodesXML+= "</scrollarea>\n";
238  try {
239  recentsInnerNode->replaceSubNodes(recentsInnerNodeSubNodesXML, false);
240  } catch (Exception& exception) {
241  Console::println("FileDialogScreenController::setupRecents(): An error occurred: " + string(exception.what()));
242  }
243 }
244 
246  vector<string> drives;
247  #if defined(_WIN32)
248  for (char drive = 'A'; drive <= 'Z'; drive++) {
249  string fileName;
250  fileName+= drive;
251  fileName+= ":";
252  try {
253  if (FileSystem::getStandardFileSystem()->exists(fileName + "/") == true) drives.push_back(fileName);
254  } catch (Exception& exception) {
255  Console::println("FileDialogScreenController::setupDrives(): " + string(exception.what()));
256  }
257  }
258  #else
259  drives.push_back("/");
260  #endif
261  auto drivesInnerNode = required_dynamic_cast<GUIParentNode*>(drivesNode->getScreenNode()->getInnerNodeById(drivesNode->getId()));
262  auto idx = 1;
263  string drivesInnerNodeSubNodesXML;
264  drivesInnerNodeSubNodesXML+=
265  "<scrollarea width=\"100%\" height=\"100%\" background-color=\"{$color.element_midground}\">\n";
266  for (const auto& drive: drives) {
267  drivesInnerNodeSubNodesXML+=
268  "<selectbox-option text=\"" +
269  GUIParser::escape(drive) +
270  "\" value=\"" +
271  GUIParser::escape(drive) +
272  "\" " +
273  "image=\"{$icon.type_drive}\" " +
274  "/>\n";
275  }
276  drivesInnerNodeSubNodesXML+= "</scrollarea>\n";
277  try {
278  drivesInnerNode->replaceSubNodes(drivesInnerNodeSubNodesXML, false);
279  } catch (Exception& exception) {
280  Console::println("FileDialogScreenController::setupDrives(): An error occurred: " + string(exception.what()));
281  }
282 }
283 
284 void FileDialogScreenController::show(const string& cwd, const string& captionText, const vector<string>& extensions, const string& fileName, bool enableFilter, Action* applyAction, Action* cancelAction, const string& settingsFileName, const string& settingsPathName)
285 {
286  this->settingsPathName = settingsPathName;
287  this->settingsFileName = settingsFileName;
288  loadSettings();
289  this->captionText = captionText;
290  this->extensions = extensions;
291  this->fileNameNode->getController()->setValue(fileName);
292  this->enableFilter = enableFilter;
293  auto _cwd = cwd;
294  if (cwd.empty() == true) {
295  auto defaultCwdByExtensionsIt = defaultCwdByExtensions.find(getExtensionHash());
296  if (defaultCwdByExtensionsIt != defaultCwdByExtensions.end()) {
297  _cwd = defaultCwdByExtensionsIt->second;
298  } else {
299  _cwd = defaultCwd;
300  }
301  }
302  try {
303  this->cwd = FileSystem::getStandardFileSystem()->getCanonicalURI(_cwd, "");
304  if (this->cwd.empty() == true || FileSystem::getStandardFileSystem()->isPath(this->cwd) == false) {
305  this->cwd = FileSystem::getStandardFileSystem()->getCurrentWorkingPathName();
306  }
307  } catch (Exception& exception) {
308  Console::println("FileDialogScreenController::show(): An error occurred: " + string(exception.what()));
309  this->cwd = FileSystem::getStandardFileSystem()->getCurrentWorkingPathName();
310  }
311  setupFiles();
312  this->applyAction = unique_ptr<Action>(applyAction);
313  this->cancelAction = unique_ptr<Action>(cancelAction);
314  {
315  string extensionsDropDownOptionsXML = "<dropdown-option text=\"All supported extensions\" value=\"\" selected=\"true\"/>\n";
316  for (const auto& extension: extensions) {
317  extensionsDropDownOptionsXML+= "<dropdown-option text=\"" + StringTools::toUpperCase(extension) + " Files\" value=\"" + StringTools::toLowerCase(extension) + "\" selected=\"false\" />\n";
318  }
319  required_dynamic_cast<GUIParentNode*>(screenNode->getInnerNodeById(typeDropDownNode->getId()))->replaceSubNodes(extensionsDropDownOptionsXML, true);
320  }
321  setupDrives();
322  setupFavorites();
323  setupRecents();
324  //
325  screenNode->setEnabled(true);
326  Engine::getInstance()->getGUI()->setFoccussedNode(fileNameNode);
327 }
328 
330 {
331  screenNode->setEnabled(false);
332  applyAction = nullptr;
333  cancelAction = nullptr;
334 }
335 
337 {
338  if (node->getId() == typeDropDownNode->getId()) {
339  setupFiles();
340  } else
341  if (node->getId() == fileNameNode->getId()) {
342  try {
343  if (enableFilter == true) {
344  auto filterString = StringTools::toLowerCase(node->getController()->getValue().getString());
345  if (FileSystem::getStandardFileSystem()->exists(cwd + "/" + filterString) == true) {
346  auto selectedFile = node->getController()->getValue().getString();
347  setupFiles(fileList, selectedFile);
348  } else
349  if (filterString.empty() == true) {
351  } else {
352  vector<string> fileListFiltered;
353  for (const auto& file: fileList) {
354  if (filterString.empty() == true || StringTools::toLowerCase(file).find(filterString) != -1) fileListFiltered.push_back(file);
355  }
356  setupFiles(fileListFiltered);
357  filtered = true;
358  }
359  }
360  } catch (Exception& exception) {
361  Console::println("FileDialogScreenController::onChange(): An error occurred: " + string(exception.what()));
363  }
364  }
365 }
366 
368 {
369  if (type == GUIActionListenerType::PERFORMED) {
370  if (node->getId() == filesNode->getId()) {
371  try {
372  auto selectedFile = node->getController()->getValue().getString();
373  if (FileSystem::getStandardFileSystem()->isDrive(selectedFile) == true) {
374  auto lastCwd = cwd;
375  cwd = selectedFile;
376  if (setupFiles() == false) {
377  cwd = lastCwd;
378  setupFiles();
379  }
380  } else
381  if (FileSystem::getStandardFileSystem()->isPath(cwd + "/" + selectedFile) == true) {
382  auto lastCwd = cwd;
383  try {
384  cwd = FileSystem::getStandardFileSystem()->getCanonicalURI(cwd, selectedFile);
385  } catch (Exception& exception) {
386  Console::println("FileDialogScreenController::onAction(): An error occurred: " + string(exception.what()));
387  }
388  if (setupFiles() == false) {
389  cwd = lastCwd;
390  setupFiles();
391  }
392  } else {
393  if (filtered == true) {
394  setupFiles(fileList, selectedFile);
395  filtered = false;
396  }
397  fileNameNode->getController()->setValue(selectedFile);
398  }
399  } catch (Exception& exception) {
400  Console::println("FileDialogScreenController::onAction(): An error occurred: " + string(exception.what()));
402  }
403  } else
404  if (node->getId() == pathNode->getId()) {
405  if (StringTools::endsWith(cwd, "/") == true) cwd = StringTools::substring(cwd, 0, cwd.size() - 1);
406  auto lastCwd = cwd;
408  if (setupFiles() == true) {
409  recents.erase(remove(recents.begin(), recents.end(), cwd), recents.end());
410  recents.push_back(cwd);
411  setupRecents();
412  saveSettings();
413  } else {
414  cwd = lastCwd;
415  setupFiles();
416  }
417  } else
418  if (node->getId() == "filedialog_apply") {
419  if (StringTools::endsWith(cwd, "/") == true) cwd = StringTools::substring(cwd, 0, cwd.size() - 1);
421  recents.erase(remove(recents.begin(), recents.end(), cwd), recents.end());
422  recents.push_back(cwd);
423  setupRecents();
424  saveSettings();
425  if (applyAction != nullptr) {
426  applyAction->performAction();
427  applyAction = nullptr;
428  }
429  } else
430  if (node->getId() == "filedialog_abort" ||
431  StringTools::startsWith(node->getId(), "filedialog_caption_close_") == true) { // TODO: a.drewke, check with DH
432  if (defaultCwd.empty() == false) {
434  saveSettings();
435  }
436  if (cancelAction != nullptr) {
437  cancelAction->performAction();
438  cancelAction = nullptr;
439  }
440  close();
441  } else
442  if (node->getId() == "filedialog_favorites_add") {
443  if (StringTools::endsWith(cwd, "/") == true) cwd = StringTools::substring(cwd, 0, cwd.size() - 1);
444  favorites.erase(remove(favorites.begin(), favorites.end(), cwd), favorites.end());
445  favorites.push_back(cwd);
446  setupFavorites();
447  } else
448  if (node->getId() == "filedialog_favorites_remove") {
449  auto favorite = favoritesNode->getController()->getValue().getString();
450  favorites.erase(remove(favorites.begin(), favorites.end(), favorite), favorites.end());
451  setupFavorites();
452  } else
453  if (node->getId() == "filedialog_recent_delete") {
454  recents.clear();
455  setupRecents();
456  saveSettings();
457  } else
458  if (node == favoritesNode) {
459  auto _cwd = favoritesNode->getController()->getValue().getString();
460  if (_cwd.empty() == false) {
461  cwd = _cwd;
462  setupFiles();
463  }
464  } else
465  if (node == drivesNode) {
466  auto _cwd = drivesNode->getController()->getValue().getString();
467  if (_cwd.empty() == false) {
468  cwd = _cwd;
469  setupFiles();
470  }
471  } else
472  if (node == recentsNode) {
473  auto _cwd = recentsNode->getController()->getValue().getString();
474  if (_cwd.empty() == false) {
475  cwd = _cwd;
476  setupFiles();
477  }
478  }
479  }
480 }
481 
483  GUI::setDisableTabFocusControl(node->getScreenNode() != screenNode);
484  if (node->getId() == "filedialog_filename") {
485  if (enableFilter == true) node->getController()->setValue(MutableString(""));
486  }
487 }
488 
490 }
491 
493  // TODO: load relative paths
494  defaultCwdByExtensions.clear();
495  favorites.clear();
496  recents.clear();
497  defaultCwdByExtensions.clear();
498  try {
499  Properties settings;
500  settings.load(settingsPathName.empty() == false?settingsPathName:defaultCwd, settingsFileName, FileSystem::getStandardFileSystem());
501  {
502  auto i = 0;
503  string favorite;
504  while ((favorite = settings.get("favorite_" + to_string(i++), "")).empty() == false) {
505  favorites.push_back(favorite);
506  }
507  }
508  {
509  auto i = 0;
510  string recent;
511  while ((recent = settings.get("recent_" + to_string(i++), "")).empty() == false) {
512  recents.push_back(recent);
513  }
514  }
515  {
516  auto i = 0;
517  string defaultCwdString;
518  while ((defaultCwdString = settings.get("default_cwd_" + to_string(i++), "")).empty() == false) {
519  auto defaultCwdComponents = StringTools::tokenize(defaultCwdString, ":");
520  if (defaultCwdComponents.size() == 2) {
521  defaultCwdByExtensions[defaultCwdComponents[0]] = defaultCwdComponents[1];
522  }
523  }
524  }
525  } catch (Exception& exception) {
526  Console::println("FileDialogScreenController::setDefaultCWD(): An error occurred: " + string(exception.what()));
527  }
528 
529 }
530 
532  // TODO: store relative paths
533  try {
534  Properties settings;
535  {
536  auto i = 0;
537  for (const auto& favorite: favorites) {
538  settings.put("favorite_" + to_string(i++), favorite);
539  }
540  }
541  {
542  auto i = 0;
543  for (const auto& recent: recents) {
544  settings.put("recent_" + to_string(i++), recent);
545  }
546  }
547  {
548  auto i = 0;
549  for (const auto& [extension, defaultCwd]: defaultCwdByExtensions) {
550  settings.put("default_cwd_" + to_string(i++), extension + ":" + defaultCwd);
551  }
552  }
553  settings.store(settingsPathName.empty() == false?settingsPathName:defaultCwd, settingsFileName, FileSystem::getStandardFileSystem());
554  } catch (Exception& exception) {
555  Console::println("FileDialogScreenController::setDefaultCWD(): An error occurred: " + string(exception.what()));
556  }
557 }
558 
559 const string FileDialogScreenController::getFileImageName(const string& fileName) {
560  auto fileNameLowerCase = StringTools::toLowerCase(fileName);
561  if (StringTools::endsWith(fileNameLowerCase, ".ogg") == true) {
562  return "sound";
563  } else
564  // markdown
565  if (StringTools::endsWith(fileNameLowerCase, ".md") == true) {
566  return "script";
567  } else
568  // license
569  if (fileNameLowerCase == "license") {
570  return "script";
571  } else
572  // C++/C code
573  if (StringTools::endsWith(fileNameLowerCase, ".h") == true) {
574  return "script";
575  } else
576  if (StringTools::endsWith(fileNameLowerCase, ".cpp") == true) {
577  return "script";
578  } else
579  if (StringTools::endsWith(fileNameLowerCase, ".c") == true) {
580  return "script";
581  } else
582  if (StringTools::endsWith(fileNameLowerCase, ".tscript") == true) {
583  return "script";
584  } else
585  if (StringTools::endsWith(fileNameLowerCase, ".ttf") == true) {
586  return "font";
587  } else
588  // images
589  if (StringTools::endsWith(fileNameLowerCase, ".icns") == true) {
590  return "texture";
591  } else
592  if (StringTools::endsWith(fileNameLowerCase, ".ico") == true) {
593  return "texture";
594  } else
595  if (StringTools::endsWith(fileNameLowerCase, ".png") == true) {
596  return "texture";
597  } else
598  // videos
599  if (StringTools::endsWith(fileNameLowerCase, ".mpg") == true) {
600  return "texture";
601  } else
602  // models
603  if (StringTools::endsWith(fileNameLowerCase, ".dae") == true) {
604  return "mesh";
605  } else
606  if (StringTools::endsWith(fileNameLowerCase, ".fbx") == true) {
607  return "mesh";
608  } else
609  if (StringTools::endsWith(fileNameLowerCase, ".glb") == true) {
610  return "mesh";
611  } else
612  if (StringTools::endsWith(fileNameLowerCase, ".gltf") == true) {
613  return "mesh";
614  } else
615  if (StringTools::endsWith(fileNameLowerCase, ".tm") == true) {
616  return "mesh";
617  } else
618  // property files
619  if (StringTools::endsWith(fileNameLowerCase, ".properties") == true) {
620  return "script";
621  } else
622  // shader
623  if (StringTools::endsWith(fileNameLowerCase, ".cl") == true) {
624  return "script";
625  } else
626  if (StringTools::endsWith(fileNameLowerCase, ".frag") == true) {
627  return "script";
628  } else
629  if (StringTools::endsWith(fileNameLowerCase, ".glsl") == true) {
630  return "script";
631  } else
632  if (StringTools::endsWith(fileNameLowerCase, ".vert") == true) {
633  return "script";
634  } else
635  // tdme empty
636  if (StringTools::endsWith(fileNameLowerCase, ".tempty") == true) {
637  return "prototype";
638  } else
639  // tdme trigger
640  if (StringTools::endsWith(fileNameLowerCase, ".ttrigger") == true) {
641  return "prototype";
642  } else
643  // tdme envmap
644  if (StringTools::endsWith(fileNameLowerCase, ".tenvmap") == true) {
645  return "prototype";
646  } else
647  // tdme model
648  if (StringTools::endsWith(fileNameLowerCase, ".tmodel") == true) {
649  return "prototype";
650  } else
651  // tdme scene
652  if (StringTools::endsWith(fileNameLowerCase, ".tscene") == true) {
653  return "scene";
654  } else
655  // tdme particle system
656  if (StringTools::endsWith(fileNameLowerCase, ".tparticle") == true) {
657  return "particle";
658  } else
659  // tdme decal
660  if (StringTools::endsWith(fileNameLowerCase, ".tdecal") == true) {
661  return "prototype";
662  } else
663  // tdme terrain
664  if (StringTools::endsWith(fileNameLowerCase, ".tterrain") == true) {
665  return "terrain";
666  } else
667  // tdme script
668  if (StringTools::endsWith(fileNameLowerCase, ".tscript") == true) {
669  return "script";
670  } else
671  // xml
672  if (StringTools::endsWith(fileNameLowerCase, ".xml") == true) {
673  return "gui";
674  } else
675  // nmake
676  if (StringTools::endsWith(fileNameLowerCase, ".nmake") == true) {
677  return "script";
678  } else
679  if (StringTools::endsWith(fileNameLowerCase, ".nmake.main") == true) {
680  return "script";
681  } else
682  // bat
683  if (StringTools::endsWith(fileNameLowerCase, ".bat") == true) {
684  return "script";
685  } else
686  // bash
687  if (StringTools::endsWith(fileNameLowerCase, ".sh") == true) {
688  return "script";
689  } else
690  if (StringTools::endsWith(fileNameLowerCase, ".bash") == true) {
691  return "script";
692  } else
693  // files without ending
694  if (fileName.rfind(".") == string::npos ||
695  (fileName.rfind("/") != string::npos &&
696  fileName.rfind(".") < fileName.rfind("/"))) {
697  return "script";
698  }
699  return string();
700 }
701 
702 void FileDialogScreenController::onTooltipShowRequest(GUINode* node, int mouseX, int mouseY) {
703  popUps->getTooltipScreenController()->show(mouseX, mouseY, node->getToolTip());
704 }
705 
708 }
Engine main class.
Definition: Engine.h:131
GUI parser.
Definition: GUIParser.h:40
GUI module class.
Definition: GUI.h:64
GUI node controller base class.
virtual void setValue(const MutableString &value)=0
Set value.
virtual const MutableString & getValue()=0
GUI node base class.
Definition: GUINode.h:64
const string & getToolTip()
Definition: GUINode.h:346
GUINodeController * getController()
Definition: GUINode.h:661
GUIScreenNode * getScreenNode()
Definition: GUINode.h:325
const string & getId()
Definition: GUINode.h:339
GUI parent node base class thats supporting child nodes.
Definition: GUIParentNode.h:42
GUI screen node that represents a screen that can be rendered via GUI system.
Definition: GUIScreenNode.h:72
void setEnabled(bool enabled)
Set enabled.
void addChangeListener(GUIChangeListener *listener)
Add change listener.
void addTooltipRequestListener(GUITooltipRequestListener *listener)
Add tooltip request listener.
void addActionListener(GUIActionListener *listener)
Add action listener.
void addFocusListener(GUIFocusListener *listener)
Add focus listener.
GUINode * getInnerNodeById(const string &nodeId)
Get inner GUI node by id.
GUINode * getNodeById(const string &nodeId)
Get GUI node by id.
File system singleton class.
Definition: FileSystem.h:17
void show(const string &cwd, const string &captionText, const vector< string > &extensions, const string &fileName, bool enableFilter, Action *applyAction, Action *cancelAction=nullptr, const string &settingsFileName=".filedialog.properties", const string &settingsPathName=string())
Shows the file dialog pop up.
static const string getFileImageName(const string &fileName)
Get file image name.
void onAction(GUIActionListenerType type, GUIElementNode *node) override
void onTooltipShowRequest(GUINode *node, int mouseX, int mouseY) override
On tooltip show request.
void show(int mouseX, int mouseY, const string &tooltip)
Show tooltip.
Pop ups controller accessor class.
Definition: PopUps.h:29
TooltipScreenController * getTooltipScreenController()
Definition: PopUps.h:131
Console class.
Definition: Console.h:29
Mutable utf8 aware string class.
Definition: MutableString.h:23
const string & getString() const
Properties class, which helps out with storeing or loading key value pairs from/to property files.
Definition: Properties.h:23
void put(const string &key, const string &value)
Add property.
Definition: Properties.h:58
const string & get(const string &key, const string &defaultValue) const
Get property value by key.
Definition: Properties.h:46
void load(const string &pathName, const string &fileName, FileSystemInterface *fileSystem=nullptr)
Load property file.
Definition: Properties.cpp:24
void store(const string &pathName, const string &fileName, FileSystemInterface *fileSystem=nullptr) const
Store property file.
Definition: Properties.cpp:41
String tools class.
Definition: StringTools.h:22
std::exception Exception
Exception base class.
Definition: Exception.h:18
GUI action listener interface.
File system file name filter interface.
Action Interface.
Definition: Action.h:11