// $Id: QtUtils/RwFileDialog.cpp 2013/09/21 19:30:38 philw $ // A wrapper class for QFileDialog's static and instance-based APIs. // // namespace RwFile // class RwFileDialog // class RwOpenFileDialog : public RwFileDialog // class RwSaveFileDialog : public RwFileDialog // // SEE: "Configuration Constants" section, below. // // Documentation Below: // (1) Background: QFileDialog // (2) RwFileDialog Wrapper Class // (3) RwFileDialog Automatic History Support // (4) Gnats 5364 Notes // // =========================== // (1) Background: QFileDialog // =========================== // // The Qt4 QFileDialog file chooser dialog class has effectively two API: // // (1) Static QFileDialog methods: Show and execute a file chooser // dialog with a single call. EXAMPLE: // // QString selectedFileName = // QFileDialog::getOpenFileName ( // parentWidget, windowTitle, initialSelection, // nameFilters, &selectedNameFilter, optionFlags); // // (2) Qt Instance (QFileDialog instance) API -- broader control of the // file chooser dialog's configuration -- including an application- // level chooser history. EXAMPLE: // // QFileDialog dlg (parentWidget); // dlg.setWindowTitle (windowTitle); // dlg.setAcceptMode (QFileDialog::AcceptSave); // dlg.setFileMode (QFileDialog::AnyFile); // dlg.setNameFilters (filterPatterns); // dlg.setHistory (historyList); // dlg.setLabelText (QFileDialog::Accept, tr ("Select")); // dlg.setOptions (QFileDialog::DontConfirmOverwrite); // const int dialogResult = dlg.exec(); // SHOW AND EXECUTE // const QStringList selFiles = dlg.selectedFiles(); // // For the most part, // - the STATIC interface shows a NATIVE WINDOWS file chooser. // - the QT INSTANCE interface shows a QT-IMPLEMENTED file chooser. // // Major Differences between these two QFileDialog interfaces: // // (1) The Qt Instance chooser supports application-level history. // For example, showing the most recent six RplSet files when // choosing a RplSet file to open. The Static (Native Windows) // file chooser supports just a single unified file access history, // not specific to RiverWare operation. // // (2) The Qt Instance chooser supports custom button text for the // accept button (other than "Save" or "Open"). (Other dialog // text can also be customized). In RiverWare, this has been used // when showing a dialog selector to pick a filepath for a line // editor in some other dialog ("Select"). // // (3) There is evidence of a possible lockup/crash with the Qt // Instance chooser -- but not with the Static/Native chooser. // SEE SECTION (4) BELOW. // // RiverWare 6.4 development (9-2013) had about: // [61] Static uses of QFileDialog // [23] Qt Instances of QFileDialog (plus a few subclass instances) // // ============================== // (2) RwFileDialog Wrapper Class // ============================== // // The RwFileDialog has an API which replicates the part of the // Qt4 QFileDialog API used by RiverWare -- BOTH the Static/Native // functions and the Qt Instance methods. Its API makes possible // a mostly transparent port in RiverWare from QFileDialog to // RwFileDialog. // // The primary motivation is to (at least in the short term) port // all of the 23+ "Instance" uses to the Static/Native implementation // to see if this avoids the Gnats 5364 lockup/crash with Samba -- // for users who are experiencing this problem -- (we have not been // able to reproduce this problem ourselves). // // This class also provides the ability to GLOBALLY SWITCH between the // two QFileDialog implementations (APIs) -- for all uses of this // RwFileDialog class (REGARDLESS of which RwFileDialog interface is // actually used in RiverWare application code). It also provides a // central place from which to customize the implementation of all uses // of file choosers in RiverWare, and to provide additional processing // of file selections. // // SEE the "Configuration Constants" below. Options include: // // (a) Which mode should be the default: "Native" or not (Qt Instance). // (b) Option to include a terse tag in the file chooser window // title to indicate the file chooser mode, initially either: // "[WIN]" or "[Qt]". // (c) Optional post-seletion processing features. // // Note [9-16-2013]: The RiverWare Workspace TEST MENU now supports // these two test functions which (a) operate the RwFileDialog // file chooser in the respective mode, and (b) SWITCHES all // subsequent RwFileDialog uses to that mode. [The implementations // are defined in this class, and also serve as a usage example]. // // (1) Test File Chooser: Native // (2) Test File Chooser: Qt // // ========================================== // (3) RwFileDialog Automatic History Support // ========================================== // // With this QFileDialog encapsulation, we have the opportunity to also // encapsulate the maintanence of RiverWare's application-level history // data. As noted, this history is not available to the Static/Native // file chooser mode. However, even when that mode is used, there is // benefit to maintaining this history data -- for construction of the // dynamic "Reopen" submenus (e.g. the "Reopen Model" submenu under the // Workspace File menu). // // Automatic initialization from the application-level history -- and // saving of the chosen file within the proper history type (Model, // RplSet, etc.) is supported with a "Use Type" parameter added to new // versions of the API. (There are also methods which lack this new // parameter -- those use and save data to RiverWare's general "recent // directory" history). // // See the UseType enumerated type, and parameters. The available values // correspond to the specific histories supported by the LoadSaveMgr. // // ==================== // (4) Gnats 5364 Notes // ==================== // // See Gnats 5364: (effectively a crash using a QFileDialog instance). // "Load model across Samba network, hangs just before presenting file // chooser. One fix: native file chooser + no history [QFileDialog:: // setHistory(), setDirectory() passed in model directory]." // [Patrick, 8-23-2013, see e-mails]. [Rw 6.4 development, Qt 4.8.5]. // //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ********************************* // *** Configuration Constants *** // ********************************* #include <QString> // Active/Default File Chooser Type: Windows Native? (or Qt Instance). static const bool DEFAULT_USE_NATIVE (true); // release: true (9-2013) // File Chooser Dialog Type Indication in Title Bar: "[WIN]" or "[QT]". static const bool SHOW_WINDOW_TITLE_STR_NATIVE (true); // release: false static const bool SHOW_WINDOW_TITLE_STR_QtINST (true); // release: true static const QString WINDOW_TITLE_STR_NATIVE ("[WIN]"); // Native (Static) static const QString WINDOW_TITLE_STR_QtINST ("[QT]"); // Qt Instance // Post-Selection Processing Features: // (1) Save picked filepath to application-level file history? // (2) Copy picked filepath to system clipboard? // // Note [9-2013, Rw 6.4]: Especially the SAVE HISTORY feature is // currently implemented where necessary in the application (client) // code. If and when we remove history saving from all the clients, // history saving -- based on UseTypes specified by the client -- // would be enabled here. // static const bool SAVE_PICKED_TO_HISTORY_ENA (false); // rel 6.4: false static const bool COPY_PICKED_TO_CLIPBOARD_ENA (false); // rel 6.4: false //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- #include "RwFileDialog.hpp" #include "LoadSaveMgr.hpp" #include "QGui.hpp" #include "RwQtUtils.hpp" #include "rwError.hpp" //--- for rwAssert #include <QApplication> #include <QFileDialog> #include <QMessageBox> #include <QPushButton> #include <iostream> using namespace RwFile; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // *********************************************** // *** class RwFileDialog / Static Interface *** // *********************************************** // static bool RwFileDialog::_useNativeChooser (DEFAULT_USE_NATIVE); // static void RwFileDialog::setUseNativeChooser (bool on) { _useNativeChooser = on; } // static void RwFileDialog::setAndTestChooserType (bool native) { static const char* mname ("RwFileDialog::showTest"); static int callCnt (0); ++callCnt; // ********************************************************** // *** SET FILE SELECTOR TYPE: Native? or Qt Instance? *** // ********************************************************** setUseNativeChooser (native); static const QString fmt (QObject::tr ( "Active File Chooser Dialog Type: %1 \n" "Save picked filename to history: %2 \n" "Copy picked filename to clipboard: %3")); const char* typeStr = native ? "NATIVE" : "QT"; const QString msg = fmt .arg (typeStr) .arg (SAVE_PICKED_TO_HISTORY_ENA ? "ENABLED" : "DISABLED") .arg (COPY_PICKED_TO_CLIPBOARD_ENA ? "ENABLED" : "DISABLED"); QMessageBox mbox; mbox.setWindowTitle ("RiverWare File Chooser Type Set"); mbox.setText (msg); mbox.setIcon (QMessageBox::Information); QPushButton* testBut = mbox.addButton ("Show Test Dialog", QMessageBox::YesRole); mbox.addButton (QMessageBox::Close); mbox.exec(); QAbstractButton* userBut = mbox.clickedButton(); if (userBut != testBut) return; //--------------------------->> // ********************************************************** // *** SHOW TEST FILE CHOOSER (picked file is not used) *** // ********************************************************** const QString caption = QString ("Test File Chooser (%1) for Load Model File") .arg (typeStr); static QString selectedFilter; RwOpenFileDialog dlg (RwFile::For_Model); dlg.setWindowTitle (caption); dlg.setSelectedNameFilterPtr (&selectedFilter); const int stat = dlg.exec(); // **************************** // *** REPORT PICKED FILE *** // **************************** const QString selFile = dlg.selectedFile(); const char* statStr = (stat == QDialog::Accepted) ? "ACCEPT" : "CANCEL"; // std::cout << mname << " [#" << callCnt << " " << typeStr << "] " // << statStr << " \"" << qPrintable (selFile) << "\"" // << std::endl; static const QString fmt2 ("Selected file (%1): \n \"%2\""); const QString msg2 = fmt2 .arg (statStr) .arg (selFile); QMessageBox::information (NULL, caption, msg2); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // static QString RwFileDialog::getOpenFileName (UseType useType, QWidget* parentWid, // = NULL const QString& caption, // = QString() const QString& initPath, // = QString() const QString& filter, // = QString() QString* selectedFilter, // = NULL int options) // = 0 (Options flags) { RwOpenFileDialog dlg (useType, parentWid); dlg.setWindowTitle (caption); if (!initPath.isEmpty()) dlg.selectFile (initPath); if (!filter.isEmpty()) dlg.setNameFilter (filter); dlg.setSelectedNameFilterPtr (selectedFilter); dlg.setOptions (options); // *** SHOW DIALOG *** const int stat = dlg.exec(); stat; // (avoid compilation warning) const QString retFilePath = dlg.selectedFile(); return (retFilePath); } // static QString RwFileDialog::getOpenFileName ( QWidget* parentWid, // = NULL const QString& caption, // = QString() const QString& initPath, // = QString() const QString& filter, // = QString() QString* selectedFilter, // = NULL int options) // = 0 (Options flags) { const QString selFilePath = getOpenFileName (For_Other, parentWid, caption, initPath, filter, selectedFilter, options); return (selFilePath); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // static QString RwFileDialog::getSaveFileName (UseType useType, QWidget* parentWid, // = NULL const QString& caption, // = QString() const QString& initPath, // = QString() const QString& filter, // = QString() QString* selectedFilter, // = NULL int options) // = 0 (Options flags) { RwSaveFileDialog dlg (useType, parentWid); dlg.setWindowTitle (caption); if (!initPath.isEmpty()) dlg.selectFile (initPath); if (!filter.isEmpty()) dlg.setNameFilter (filter); dlg.setSelectedNameFilterPtr (selectedFilter); dlg.setOptions (options); // *** SHOW DIALOG *** const int stat = dlg.exec(); stat; // (avoid compilation warning) const QString retFilePath = dlg.selectedFile(); return (retFilePath); } // static QString RwFileDialog::getSaveFileName ( QWidget* parentWid, // = NULL const QString& caption, // = QString() const QString& initPath, // = QString() const QString& filter, // = QString() QString* selectedFilter, // = NULL int options) // = 0 (Options flags) { const QString selFilePath = getSaveFileName (For_Other, parentWid, caption, initPath, filter, selectedFilter, options); return (selFilePath); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // static QString RwFileDialog::getExistingDirectory (UseType useType, QWidget* parentWid, // = NULL const QString& caption, // = QString() const QString& initPath, // = QString() int options) // = ShowDirsOnly { RwFileDialog dlg (useType, parentWid); dlg.setFileMode (DirectoryLoad); dlg.setWindowTitle (caption); if (!initPath.isEmpty()) dlg.selectFile (initPath); dlg.setOptions (options); // *** SHOW DIALOG *** const int stat = dlg.exec(); stat; // (avoid compilation warning) const QString retFilePath = dlg.selectedFile(); return (retFilePath); } // static QString RwFileDialog::getExistingDirectory ( QWidget* parentWid, // = NULL const QString& caption, // = QString() const QString& initPath, // = QString() int options) // = ShowDirsOnly { const QString selFilePath = getExistingDirectory (For_Other, parentWid, caption, initPath, options); return (selFilePath); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ************************************************* // *** class RwFileDialog / Instance Interface *** // ************************************************* // constructor RwFileDialog::RwFileDialog (UseType useType, /*= For_Und */ QWidget* parentWid) /*= NULL */ : _useType (useType), _parentWid (parentWid), _windowTitle (), // QString _fileMode (AnyFile), // FileMode _options (0), // int (Options flags) _initPath (), // QString _historyPaths (), // QStringList _nameFilters (), // QString _buttonLabel_Accept (), // QString _buttonLabel_Reject (), // QString _selNameFilterLocal (), // QString _selNameFilterPtr (NULL), // QString* _selectedFiles () // QStringList { setDefaultsForUseType(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- RwFileDialog::~RwFileDialog() { } void RwFileDialog::setWindowTitle (const QString& winTitle) { _windowTitle = winTitle; } void RwFileDialog::setFileMode (FileMode mode) { _fileMode = mode; } void RwFileDialog::setOptions (int options) // Options flags { _options = options; } void RwFileDialog::selectFile (const QString& filename) // initPath { _initPath = filename; if (!_initPath.isEmpty()) { _historyPaths.removeAll (_initPath); _historyPaths.prepend (_initPath); } } void RwFileDialog::setHistory (const QStringList& paths) { // History is automatically provided for many of the use types. // Note [9-2013, RW 4.8.5]: Application-level history is not supported // in native (static function) mode. It is supported only by the Qt // (QFileDialog-) Instance file chooser. const QStringList saveHistoryPaths = _historyPaths; const int saveCnt = saveHistoryPaths.count(); _historyPaths = paths; for (int inx = 0; inx < saveCnt; ++inx) { const QString savePath = saveHistoryPaths [inx]; if (!_historyPaths.contains (savePath)) _historyPaths.append (savePath); } // If the intitial path was also set, put that as the most recent // file in the history. if (!_initPath.isEmpty()) { _historyPaths.removeAll (_initPath); _historyPaths.prepend (_initPath); } } void RwFileDialog::setNameFilter (const QString& nameFilterSpec) { // The nameFilterSpec can contain multiple filters seperated by ";;". // Filter specs are automatically provided for many of the use types. _nameFilters = nameFilterSpec; } void RwFileDialog::setNameFilters (const QStringList& filterList) { const QString nameFilterSpec = filterList.join (";;"); setNameFilter (nameFilterSpec); } void RwFileDialog::selectNameFilter (const QString& selFilter) { _selNameFilterLocal = selFilter; if (_selNameFilterPtr) *_selNameFilterPtr = selFilter; } void RwFileDialog::setSelectedNameFilterPtr (QString* strPtr) { _selNameFilterPtr = strPtr; if (_selNameFilterPtr) _selNameFilterLocal = *_selNameFilterPtr; } void RwFileDialog::setLabelText (RwFile::LabelId id, const QString& text) { switch (id) { case RwFile::Accept: _buttonLabel_Accept = text; break; case RwFile::Reject: _buttonLabel_Reject = text; break; default: rwAssert (("Unsupported LabelId", 0)); } } QString RwFileDialog::selectedFile() const { // first file, if multiple were selected. const QString selFile = _selectedFiles .value (0); return selFile; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- int RwFileDialog::exec() { // Returns QDialog::Accepted or QDialog::Rejected // *************************** // *** Show File Chooser *** // *************************** _selectedFiles.clear(); const int stat = _useNativeChooser ? execNative() // Show and Execute Native Dialog : execInstance(); // Show and Execute Qt Instance // *********************************** // *** Post-Selection Processing *** // *********************************** if (stat == QDialog::Accepted) { if (SAVE_PICKED_TO_HISTORY_ENA) { recordPickedFileInHistory(); } if (COPY_PICKED_TO_CLIPBOARD_ENA) { const QString selFile = selectedFile(); if (!selFile.isEmpty()) { const QString nativeFile = QDir::toNativeSeparators (selFile); RwQtUtils::setClipboardText (nativeFile); } } } return (stat); // QDialog::Accepted or QDialog::Rejected } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void RwFileDialog::setDefaultsForUseType() { // ****************************************************************** // *** Default File Filter Initializations (for some use types) *** // ****************************************************************** // Note: This method sets some of the file chooser parameter settings, // so should be performed before customizations performed by the // client. It is called from the RwFileDialog constructor. // See definitions in LoadSaveMgr.cpp. switch (_useType) { case For_Model: _nameFilters = FILTER_STR_MODEL_FILES; break; case For_RuleSet: _nameFilters = FILTER_STR_RULESET_FILES; break; case For_OptSet: _nameFilters = FILTER_STR_OPTSET_FILES; break; case For_GblSet: _nameFilters = FILTER_STR_GBLSET_FILES; break; } // *************************** // *** Default Histories *** // *************************** // Note [9-2013, RW 4.8.5]: Except for the "initialization path" for a // single recent file, application-level history is not supported // in native (static function) mode. The full history queue is // supported only by the Qt (QFileDialog-) Instance file chooser. const LoadSaveMgr* mgr = LoadSaveMgrInst; QString recentPath; switch (_useType) { case For_Model: recentPath = mgr->recentModelPath(); break; case For_RuleSet: recentPath = mgr->recentRuleSetPath(); break; case For_OptSet: recentPath = mgr->recentOptSetPath(); break; case For_GblSet: recentPath = mgr->recentGblSetPath(); break; case For_Obj: recentPath = mgr->recentObjPath(); break; case For_Output: recentPath = mgr->recentOutputPath(); break; } if (!recentPath.isEmpty()) { _initPath = recentPath; _historyPaths.append (recentPath); } switch (_useType) { case For_Model: mgr->appendRecentModelDirs (_historyPaths); mgr->appendRecentObjDirs (_historyPaths); break; case For_RuleSet: mgr->appendRecentRuleSetDirs (_historyPaths); mgr->appendRecentModelDirs (_historyPaths); break; case For_OptSet: mgr->appendRecentOptSetDirs (_historyPaths); mgr->appendRecentRuleSetDirs (_historyPaths); mgr->appendRecentModelDirs (_historyPaths); break; case For_GblSet: mgr->appendRecentGblSetDirs (_historyPaths); mgr->appendRecentRuleSetDirs (_historyPaths); mgr->appendRecentModelDirs (_historyPaths); break; case For_Obj: mgr->appendRecentObjDirs (_historyPaths); mgr->appendRecentModelDirs (_historyPaths); mgr->appendRecentOutputDirs (_historyPaths); break; case For_Output: mgr->appendRecentOutputDirs (_historyPaths); mgr->appendRecentModelDirs (_historyPaths); break; case For_Und: case For_Other: default: mgr->appendRecentModelDirs (_historyPaths); mgr->appendRecentObjDirs (_historyPaths); mgr->appendRecentOutputDirs (_historyPaths); break; } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // private int RwFileDialog::execNative() { // ****************************************************** // *** Show QFileDialog w/static functions (Native) *** // ****************************************************** //------------------------------------------------ // Returns QDialog::Accepted or QDialog::Rejected // Sets: QString _selNameFilterLocal // Sets: QString* *_selNameFilterPtr // Sets: QStringList _selectedFiles //------------------------------------------------ // NOTE [Phil, 9-2013, Qt 4.8.5]: The QFileDialog's static function // API lacks support for an application-level file history. So the // QStringList _historyPaths data is not used here. // // Ditto for overrides to the Accept and Reject button text. QString selFile; _selectedFiles.clear(); const QString winTitle = SHOW_WINDOW_TITLE_STR_NATIVE ? (WINDOW_TITLE_STR_NATIVE + " " + _windowTitle) : _windowTitle; QFileDialog::Options opts (0); if ((_options & ShowDirsOnly) != 0) opts |= QFileDialog::ShowDirsOnly; if ((_options & DontConfirmOverwrite)!= 0) opts |= QFileDialog::DontConfirmOverwrite; switch (_fileMode) { // ******************************************************* // *** The name of a file, whether it exists or not. *** // ******************************************************* case AnyFile: { selFile = QFileDialog::getSaveFileName ( _parentWid, // QWidget* parent winTitle, // const QString& caption _initPath, // const QString& dir _nameFilters, // const QString& filter &_selNameFilterLocal, // QString* selectedFilter opts); // QFileDialog::Options break; } // ********************************************* // *** The name of a single existing file. *** // ********************************************* case ExistingFile: { selFile = QFileDialog::getOpenFileName ( _parentWid, // QWidget* parent winTitle, // const QString& caption _initPath, // const QString& dir _nameFilters, // const QString& filter &_selNameFilterLocal, // QString* selectedFilter opts); // QFileDialog::Options options=0 break; } // ********************************* // *** The name of a directory *** // ********************************* case DirectorySave: case DirectoryLoad: { selFile = QFileDialog::getExistingDirectory ( _parentWid, // QWidget* parent winTitle, // const QString& caption _initPath, // const QString& dir opts); // QFileDialog::Options options=0 break; } // *************************************************** // *** The names of zero or more existing files. *** // *************************************************** case ExistingFiles: // (multiple files). { _selectedFiles = QFileDialog::getOpenFileNames ( _parentWid, // QWidget* parent winTitle, // const QString& caption _initPath, // const QString& dir _nameFilters, // const QString& filter &_selNameFilterLocal, // QString* selectedFilter opts); // QFileDialog::Options options=0 break; } default: QApplication::beep(); } // *********************************** // *** Post-Selection Processing *** // *********************************** if (_selectedFiles.isEmpty() && !selFile.isEmpty()) { _selectedFiles.append (selFile); } if (_selNameFilterPtr) { *_selNameFilterPtr = _selNameFilterLocal; } return (_selectedFiles.isEmpty() ? QDialog::Rejected : QDialog::Accepted); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // private int RwFileDialog::execInstance() { // ********************************************************** // *** Show QFileDialog as an instance (non-native, Qt) *** // ********************************************************** //------------------------------------------------ // Returns QDialog::Accepted or QDialog::Rejected // Sets: QString _selNameFilterLocal // Sets: QString* *_selNameFilterPtr // Sets: QStringList _selectedFiles //------------------------------------------------ const QString winTitle = SHOW_WINDOW_TITLE_STR_QtINST ? (WINDOW_TITLE_STR_QtINST + " " + _windowTitle) : _windowTitle; QFileDialog::Options opts (0); if ((_options & ShowDirsOnly) != 0) opts |= QFileDialog::ShowDirsOnly; if ((_options & DontConfirmOverwrite)!= 0) opts |= QFileDialog::DontConfirmOverwrite; QFileDialog dlg (_parentWid, winTitle, _nameFilters); dlg.setOptions (opts); QGui::setWindowLogoIcon (&dlg); dlg.setAttribute (Qt::WA_AlwaysShowToolTips, true); switch (_fileMode) { case AnyFile: dlg.setFileMode (QFileDialog::AnyFile); break; case ExistingFile: dlg.setFileMode (QFileDialog::ExistingFile); break; case DirectorySave: dlg.setFileMode (QFileDialog::Directory); break; case DirectoryLoad: dlg.setFileMode (QFileDialog::Directory); break; case ExistingFiles: dlg.setFileMode (QFileDialog::ExistingFiles); break; } switch (_fileMode) { case AnyFile: dlg.setAcceptMode (QFileDialog::AcceptSave); break; case ExistingFile: dlg.setAcceptMode (QFileDialog::AcceptOpen); break; case DirectorySave: dlg.setAcceptMode (QFileDialog::AcceptSave); break; case DirectoryLoad: dlg.setAcceptMode (QFileDialog::AcceptOpen); break; case ExistingFiles: dlg.setAcceptMode (QFileDialog::AcceptOpen); break; } if (!_historyPaths.empty()) dlg.setHistory (_historyPaths); if (!_initPath.isEmpty()) dlg.selectFile (_initPath); if (!_nameFilters.isEmpty()) { dlg.setNameFilter (_nameFilters); if (!_selNameFilterLocal.isEmpty()) dlg.selectNameFilter (_selNameFilterLocal); } if (!_buttonLabel_Accept.isEmpty()) { dlg.setLabelText (QFileDialog::Accept, _buttonLabel_Accept); } if (!_buttonLabel_Reject.isEmpty()) { dlg.setLabelText (QFileDialog::Reject, _buttonLabel_Reject); } // *************************************** // *** Show and Execute File Chooser *** // *************************************** const int stat = dlg.exec(); // QDialog::Accepted or QDialog::Rejected // *********************************** // *** Post-Selection Processing *** // *********************************** if (stat == QDialog::Accepted) { _selectedFiles = dlg.selectedFiles(); } _selNameFilterLocal = dlg.selectedNameFilter(); if (_selNameFilterPtr) { *_selNameFilterPtr = _selNameFilterLocal; } return (stat); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void RwFileDialog::recordPickedFileInHistory() { // **************************************************** // *** Record Selected File for RiverWare History *** // **************************************************** // Note: Even though History is not supported in all file chooser modes. // (See relevant notes in this file), the History saved here IS also // used by various dynamic "reload" submenus -- both recent files and // directories. const QString firstFile = _selectedFiles .value (0); if (!firstFile.isEmpty()) { LoadSaveMgr* mgr = LoadSaveMgrInst; bool saveOp (false); // or loadOp? switch (_fileMode) { case AnyFile: saveOp = true; break; case ExistingFile: saveOp = false; break; case DirectorySave: saveOp = true; break; case DirectoryLoad: saveOp = false; break; case ExistingFiles: saveOp = false; break; } switch (_useType) { case For_Und: mgr->recordDirPath (firstFile, saveOp); break; case For_Other: mgr->recordDirPath (firstFile, saveOp); break; case For_Model: mgr->recordModelPath (firstFile, saveOp); break; case For_RuleSet: mgr->recordRuleSetPath (firstFile, saveOp); break; case For_OptSet: mgr->recordOptSetPath (firstFile, saveOp); break; case For_GblSet: mgr->recordGblSetPath (firstFile, saveOp); break; case For_Obj: mgr->recordObjPath (firstFile, saveOp); break; case For_Output: mgr->recordOutputPath (firstFile, saveOp); break; } } } //--- (end RwFileDialog.cpp) ---