From 3629c7d79a45e16a70fe97302a51e50171015b55 Mon Sep 17 00:00:00 2001 From: nds Date: Thu, 18 Sep 2008 11:37:29 +0000 Subject: [PATCH] Merge from BR_QT4_Dev --- src/SUIT/SUIT_FileDlg.cxx | 1049 +++++++++++++++++++++---------- src/SUIT/SUIT_FileDlg.h | 109 ++-- src/SUIT/SUIT_FileValidator.cxx | 200 ++++-- src/SUIT/SUIT_FileValidator.h | 25 +- 4 files changed, 963 insertions(+), 420 deletions(-) diff --git a/src/SUIT/SUIT_FileDlg.cxx b/src/SUIT/SUIT_FileDlg.cxx index 7d169045c..6d5a1f002 100755 --- a/src/SUIT/SUIT_FileDlg.cxx +++ b/src/SUIT/SUIT_FileDlg.cxx @@ -16,50 +16,58 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SUIT_FileDlg.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// /*! - SUIT_FileDlg class is the extension of the Qt's Open/Save file dialog box. - To get the file/directory name(s) call static methods: - - to invoke "Open file" or "Save file" dialog box - static QString getFileName(QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, const bool open, const bool showQuickDir = true, - SUIT_FileValidator* validator = 0); - - to invoke "Open files" dialog box (to get the multiple file selection) - static QStringList getOpenFileNames(QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, bool showQuickDir = true, - SUIT_FileValidator* validator = 0); - - to invoke "Select directory" dialog box - static QString getExistingDirectory(QWidget* parent, const QString& initial, - const QString& caption, const bool showQuickDir = true); - - The parameters: - - parent parent widget (if 0, the current desktop is used) - - initial starting directory or file name (if null, last visited directory is used) - - filters file filters list; patterns inside the filter can be separated by ';','|' or ' ' - symbols - - caption dialog box's caption: if null, the default one is used - - open open flag - true for "Open File" and false for "Save File" dialog box - - showQuickDir this flag enables/disables "Quick directory list" controls - - validator you can provide custom file validator with this parameter - - Examples: - ... - QStringList flist; - flist.append( "Image files (*.bmp *.gif *.jpg )" ); - flist.append( "All files (*.*)" ); - QMyFileValidator* v = new QMyFileValidator( 0 ); - QString fileName = SUIT_FileDlg::getFileName( 0, QString::null, flist, "Dump view", false, true, v ); - if ( !fileName.isEmpty() ) { - ... writing image to the file - } - ... - QStringList flist; - flist.append( "*.cpp | *.cxx | *.c++" ); - flist.append( "*.h | *.hpp | *.hxx" ); - QString fileName = SUIT_FileDlg::getFileName( desktop(), QString::null, flist, QString::null, true, true ); + \class SUIT_FileDlg + \brief An extension of the Qt Open/Save file dialog box. + + The class SUIT_FileDlg provides a set of static methods which canbe used + for file or directories selection: + - getFileName() for single file opening or saving + - getOpenFileNames() for mulktiple files opening + - getExistingDirectory() for existing directory selection + + Examples: + \code + // select file to dump contents of the view + QStringList filters; + filters << "Image files (*.bmp *.gif *.jpg )" << "All files (*)"; + QString fileName = SUIT_FileDlg::getFileName( desktop(), + QString(), + filters, + "Dump view", + false ); + if ( !fileName.isEmpty() ) { + ... writing image to the file + } + + // select list of files to open in the editor windows + QStringList filters; + filters << "*.cpp | *.cxx | *.c++" << "*.h | *.hpp | *.hxx"; + QStringList fileNames = SUIT_FileDlg::getOpenFileName( desktop(), + QString(), + filters, + QString() ); + if ( !fileNames.isEmpty() ) { + ... open files + } + \endcode + + The class SUIT_FileDlg can be subclassed to implement custom file + dialog boxes. The class provides a set of methods which can be used + in subclasses: + - setCheckPermissions() - to enable/disable check of files/directories + permissions + - setValidator() - to use custom file validator + - addWidgets() - to add custom widgets to the lower part of the + dialog box + - getLastVisitedDirectory() - to get last visited directory + - acceptData() - can be used ti customize user selection validation + + \sa SUIT_FileValidator class. */ #include "SUIT_FileDlg.h" @@ -78,155 +86,147 @@ #include #include #include +#include +#include -#define MIN_COMBO_SIZE 100 +/*! + \brief Defines extension behavior. -/*! If the selected file name has extension which does not match the selected filter - * this extension is ignored (and new one will be added). See below for details. - */ + If the selected file name has extension which does not match the selected filter + and this variable is set to \c true, the file extension is ignored and new one + (from current file filter will be added. + \sa addExtension() +*/ const bool IGNORE_NON_MATCHING_EXTENSION = true; QString SUIT_FileDlg::myLastVisitedPath; -/*! Constructor */ +/*! + \brief Constructor. + \param parent parent widget + \param open if \c true dialog box is used for file opening, otherwise - for saving + \param showQuickDir if \c true the quick directory list widgets will be shown + \param modal if \c true the dialog box will be modal +*/ SUIT_FileDlg::SUIT_FileDlg( QWidget* parent, bool open, bool showQuickDir, bool modal ) : QFileDialog( parent ), -myOpen( open ), -myValidator( 0 ), -myQuickLab( 0 ), -myQuickCombo( 0 ), -myQuickButton( 0 )//, -//myAccepted( false ) + myValidator( 0 ), + myQuickLab( 0 ), + myQuickCombo( 0 ), + myQuickButton( 0 ), + myCheckPermissions( true ) { setModal( modal ); - - const QObjectList& child = children(); - for ( QObjectList::const_iterator anIt = child.begin(); anIt != child.end(); ++anIt ) - { - QPushButton* pb = ::qobject_cast( *anIt ); - if ( pb ) - { - pb->setDefault( false ); - pb->setAutoDefault( false ); - } - } - + setSizeGripEnabled( true ); if ( parent ) setWindowIcon( parent->windowIcon() ); - setSizeGripEnabled( true ); - - QGridLayout* grid = ::qobject_cast( layout() ); - if ( showQuickDir && grid ) - { - // inserting quick dir combo box - myQuickLab = new QLabel( tr( "LAB_QUICK_PATH" ), this ); - myQuickCombo = new QComboBox( this ); - myQuickCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - myQuickCombo->setMinimumSize( MIN_COMBO_SIZE, 0 ); - - myQuickButton = new QPushButton( tr( "BUT_ADD_PATH" ), this ); - connect( myQuickCombo, SIGNAL( activated( const QString& ) ), this, SLOT( quickDir( const QString& ) ) ); - connect( myQuickButton, SIGNAL( clicked() ), this, SLOT( addQuickDir() ) ); + // add quick directories widgets + if ( showQuickDir ) { + myQuickLab = new QLabel( tr( "LAB_QUICK_PATH" ), this ); + myQuickCombo = new QComboBox( this ); + myQuickButton = new QPushButton( tr( "BUT_ADD_PATH" ), this ); + + if ( addWidgets( myQuickLab, myQuickCombo, myQuickButton ) ) { + connect( myQuickCombo, SIGNAL( activated( const QString& ) ), this, SLOT( quickDir( const QString& ) ) ); + connect( myQuickButton, SIGNAL( clicked() ), this, SLOT( addQuickDir() ) ); - int row = grid->rowCount(); - grid->addWidget( myQuickLab, row, 0 ); - grid->addWidget( myQuickCombo, row, 1, 1, 3 ); - grid->addWidget( myQuickButton, row, 5 ); + // retrieve directories list from the resources + QStringList dirList; + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + if ( resMgr ) + dirList = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ).split( ';', QString::SkipEmptyParts ); - // getting dir list from settings - QString dirs; - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); - if ( resMgr ) - dirs = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ); + if ( dirList.isEmpty() ) + dirList << QDir::homePath(); - QStringList dirList = dirs.split( ';' ); - if ( dirList.count() > 0 ) - { for ( int i = 0; i < dirList.count(); i++ ) - myQuickCombo->addItem( dirList[i] ); + myQuickCombo->addItem( dirList[i] ); + } + else { + delete myQuickLab; myQuickLab = 0; + delete myQuickCombo; myQuickCombo = 0; + delete myQuickButton; myQuickButton = 0; } - else - myQuickCombo->addItem( QDir::homePath() ); } - setAcceptMode( myOpen ? AcceptOpen: AcceptSave ); - setWindowTitle( myOpen ? tr( "INF_DESK_DOC_OPEN" ) : tr( "INF_DESK_DOC_SAVE" ) ); + + setAcceptMode( open ? AcceptOpen: AcceptSave ); + setWindowTitle( open ? tr( "INF_DESK_DOC_OPEN" ) : tr( "INF_DESK_DOC_SAVE" ) ); // If last visited path doesn't exist -> switch to the first preferred path - if ( !myLastVisitedPath.isEmpty() ) - { + if ( !myLastVisitedPath.isEmpty() ) { if ( !processPath( myLastVisitedPath ) && showQuickDir ) processPath( myQuickCombo->itemText( 0 ) ); } - else - { - if ( showQuickDir ) - processPath( myQuickCombo->itemText( 0 ) ); + else if ( showQuickDir ) { + processPath( myQuickCombo->itemText( 0 ) ); } // set default file validator - myValidator = new SUIT_FileValidator(this); + myValidator = new SUIT_FileValidator( this ); } -/*! Destructor*/ +/*! + \brief Destructor. +*/ SUIT_FileDlg::~SUIT_FileDlg() { setValidator( 0 ); } -bool SUIT_FileDlg::event( QEvent* e ) -{ - bool res = QFileDialog::event( e ); - if ( e->type() == QEvent::Polish ) - polish(); +/*! + \brief Check if the dialog box is used for opening or saving the file. + \return \c true if dialog is used for file opening and \c false otherwise +*/ +bool SUIT_FileDlg::isOpenDlg() const +{ + return acceptMode() == AcceptOpen; +} - return res; +/*! + \brief Get 'check file permissions' flag. + \return flag value + \sa setCheckPermissions() +*/ +bool SUIT_FileDlg::checkPermissions() const +{ + return myCheckPermissions; } -/*! Redefined from QFileDialog.*/ -void SUIT_FileDlg::polish() +/*! + \brief Set 'check file permissions' flag. + + If this flag is set and file validator is not null, + the validator will check the file permissions also. + + \param checkPerm new flag value + \sa checkPermissions() +*/ +void SUIT_FileDlg::setCheckPermissions( const bool checkPerm ) { -/* - if ( myQuickButton && myQuickLab ) - { - // the following is a workaround for proper layouting of custom widgets - QValueList buttonList; - QValueList labelList; - const QObjectList *list = children(); - QObjectListIt it(*list); - int maxButWidth = myQuickLab->sizeHint().width(); - int maxLabWidth = myQuickButton->sizeHint().width(); - - for (; it.current() ; ++it) { - if ( it.current()->isA( "QLabel" ) ) { - int tempW = ((QLabel*)it.current())->minimumWidth(); - if ( maxLabWidth < tempW ) maxLabWidth = tempW; - labelList.append( (QLabel*)it.current() ); - } - else if( it.current()->isA("QPushButton") ) { - int tempW = ((QPushButton*)it.current())->minimumWidth(); - if ( maxButWidth < tempW ) maxButWidth = tempW; - buttonList.append( (QPushButton*)it.current() ); - } - } - if (maxButWidth > 0) { - QValueList::Iterator bListIt; - for ( bListIt = buttonList.begin(); bListIt != buttonList.end(); ++bListIt ) - (*bListIt)->setFixedWidth( maxButWidth ); - } - if (maxLabWidth > 0) { - QValueList::Iterator lListIt; - for ( lListIt = labelList.begin(); lListIt != labelList.end(); ++lListIt ) - (*lListIt)->setFixedWidth( maxLabWidth ); - } - } + myCheckPermissions = checkPerm; +} + +/*! + \brief Get file validator. + \return current file validator + \sa setValidator() */ +SUIT_FileValidator* SUIT_FileDlg::validator() const +{ + return myValidator; } -/*! Sets validator for file names to open/save - * Deletes previous validator if the dialog owns it. - */ +/*! + \brief Set file validator. + + Destroys previous validator if the dialog owns it. + + \param v new file validator + \sa validator() +*/ void SUIT_FileDlg::setValidator( SUIT_FileValidator* v ) { if ( myValidator && myValidator->parent() == this ) @@ -234,117 +234,267 @@ void SUIT_FileDlg::setValidator( SUIT_FileValidator* v ) myValidator = v; } -/*! Returns the selected file */ +/*! + \brief Adds the specified widgets to the bottom of the file dialog. + + The first widget (usually label) \a l is placed underneath the "file name" + and the "file types" labels. + The widget \a w is placed underneath the file types combobox. + The last widget (usually button) \a b is placed underneath the Cancel push button. + + In general, the widgets can be arbitrary. This method is added to support + the functionality provided by the Qt series 3.x. + + If you don't want to have one of the widgets added, pass 0 in that widget's position. + Every time this function is called, a new row of widgets is added to the bottom of the + file dialog. + + \param l first widget (e.g. text label) + \param w second widget (e.g. combo box) + \param b third widget (e.g. push button) + \return \c true if widgets have been added successfully +*/ +bool SUIT_FileDlg::addWidgets( QWidget* l, QWidget* w, QWidget* b ) +{ + QGridLayout* grid = ::qobject_cast( layout() ); + if ( grid ) { + int row = grid->rowCount(); + int columns = grid->columnCount(); + if ( l ) + grid->addWidget( l, row, 0 ); + if ( w ) +#if QT_VERSION < 0x040303 + grid->addWidget( w, row, 1, 1, columns-3 ); +#else + grid->addWidget( w, row, 1, 1, columns-2 ); +#endif + if ( b ) + grid->addWidget( b, row, columns-1 ); + return true; + } + return false; +} + +/*! + \brief Get list of selected files. + \return selected file names +*/ +QStringList SUIT_FileDlg::selectedFiles() const +{ + QStringList files = QFileDialog::selectedFiles(); + if ( fileMode() != DirectoryOnly && fileMode() != Directory ) { + QMutableListIterator it( files ); + while ( it.hasNext() ) { + QString f = it.next(); + QFileInfo finfo( f ); + if ( !finfo.isDir() ) + it.setValue( addExtension( f ) ); + } + } + return files; +} + +/*! + \brief Get selected file. + \return selected file name or null string if file is not selected +*/ QString SUIT_FileDlg::selectedFile() const { - return mySelectedFile; + QStringList files = selectedFiles(); + return files.count() > 0 ? files[0] : QString(); } -/*! Returns 'true' if this is 'Open File' dialog - * and 'false' if 'Save File' dialog - */ -bool SUIT_FileDlg::isOpenDlg() const +/*! + \brief Get last visited directory. + + Note, that last visited path is memorized only if the + dialog box is accepted. + + \return last visited directory +*/ +QString SUIT_FileDlg::getLastVisitedDirectory() { - return myOpen; + return myLastVisitedPath; } -/*! Closes this dialog and sets the return code to 'Accepted' - * if the selected name is valid ( see 'acceptData()' ) - */ -void SUIT_FileDlg::accept() +/*! + \brief Customize events processing. + \param e event + \return \c true if the event e was recognized and processed +*/ +bool SUIT_FileDlg::event( QEvent* e ) { - /* myAccepted - * flag is used to warkaround the Qt 2.2.2 BUG: - * accept() method is called twice if user presses 'Enter' key - * in file name editor while file name is not acceptable by acceptData() - * (e.g. permission denied) - */ -// if ( !myAccepted ) { - if ( acceptMode() != AcceptOpen ) - { - QString fn; - QStringList lst = QFileDialog::selectedFiles(); - if ( !lst.isEmpty() ) - fn = lst.first(); - mySelectedFile = fn; - addExtension(); - } + bool res = QFileDialog::event( e ); - if ( acceptData() ) - { - // NDS: needs to fill string mySelected file - QString fn; - QStringList lst = QFileDialog::selectedFiles(); - if ( !lst.isEmpty() ) - fn = lst.first(); - mySelectedFile = fn; - // end NDS - myLastVisitedPath = directory().path(); - QFileDialog::accept(); -// myAccepted = true; - } -// } -// myAccepted = !myAccepted; + if ( e->type() == QEvent::Polish ) + polish(); + + return res; } -/*! Closes this dialog and sets the return code to 'Rejected' */ -void SUIT_FileDlg::reject() +/*! + \brief Get line edit which is used to enter file name. + \return line edit widget or0 if it could not be found +*/ +QLineEdit* SUIT_FileDlg::lineEdit() const { - mySelectedFile = QString::null; - QFileDialog::reject(); + QLineEdit* ebox = 0; + QList editBoxes = findChildren(); + QGridLayout* grid = ::qobject_cast( layout() ); + if ( grid ) { + int idx = 10000; + for ( int i = 0; i < editBoxes.count(); i++ ) { + int widx = grid->indexOf( editBoxes[ i ] ); + if ( widx >= 0 ) + idx = qMin( idx, widx ); + } + if ( grid->itemAt( idx ) ) + ebox = qobject_cast( grid->itemAt( idx )->widget() ); + } + return ebox; } -/*! Returns 'true' if selected file is valid. - * The validity is checked by a file validator, - * if there is no validator the file is always - * considered as valid - */ +/*! + \brief Validate user selection. + + The validation is done by calling the corresponding methods + of the validator. If the validator is not set, this method + always returns \c true. + + This method can be re-implemented in the subclasses to customize + the file dialog behavior. + Another solution could be implementing own file validator class. + + \return \c true if user selection (file(s) or directory) is valid + \sa SUIT_FileValidator class, validator(), setValidator() +*/ bool SUIT_FileDlg::acceptData() { - if ( myValidator ) - { - if ( isOpenDlg() ) + QStringList files = selectedFiles(); + if ( files.isEmpty() ) + return false; + + // special case for ".." + if ( lineEdit() ) { + QString txt = lineEdit()->text(); + if ( txt == ".." ) { + QDir dir = directory(); + if ( dir.cdUp() ) { + setDirectory( dir ); + bool block = lineEdit()->blockSignals( true ); + lineEdit()->setText( ".." ); + lineEdit()->selectAll(); + lineEdit()->setFocus( Qt::OtherFocusReason ); + lineEdit()->blockSignals( block ); + return false; + } + } + else if ( fileMode() != DirectoryOnly ) { + QStringList fs = txt.split( " ", QString::SkipEmptyParts ); + for ( int i = 0; i < fs.count(); i++ ) { + QString wc = fs.at( i ); + if ( wc.startsWith( "\"" ) && wc.endsWith( "\"" ) ) + wc = wc.mid( 1, wc.length()-2 ); + if ( hasWildCards( wc ) ) { + addFilter( wc ); + lineEdit()->clear(); + return false; + } + } + } + } + + // special case for wildcards + for ( int i = 0; i < files.count(); ++i ) { + } + + bool bOk = true; + + switch ( fileMode() ) { + case DirectoryOnly: + case Directory: { - if ( acceptMode() == AcceptOpen ) - { - QStringList fileNames = selectedFiles(); - for ( int i = 0; i < (int)fileNames.count(); i++ ) - { - if ( !myValidator->canOpen( fileNames[i] ) ) - return false; - } - return true; + QString fn = files.first(); + if ( validator() ) { + bOk = isOpenDlg() ? validator()->canReadDir( fn, checkPermissions() ) : + validator()->canWriteDir( fn, checkPermissions() ); } - else - { - return myValidator->canOpen( selectedFile() ); + break; + } + case AnyFile: + { + QString fn = files.first(); + QFileInfo info( fn ); + if ( info.isDir() ) { + setDirectory( info.absoluteFilePath() ); + if ( lineEdit() ) { + lineEdit()->selectAll(); + lineEdit()->setFocus( Qt::OtherFocusReason ); + } + return false; + } + // validation is not required + if ( validator() ) { + bOk = isOpenDlg() ? validator()->canOpen( fn, checkPermissions() ) : + validator()->canSave( fn, checkPermissions() ); } + break; + } + case ExistingFile: + case ExistingFiles: + { + for ( int i = 0; i < files.count(); ++i ) { + QFileInfo info( files.at( i ) ); + if ( info.isDir() ) { + setDirectory( info.absoluteFilePath() ); + if ( lineEdit() ) { + lineEdit()->selectAll(); + lineEdit()->setFocus( Qt::OtherFocusReason ); + } + return false; + } + if ( validator() ) { + bOk = isOpenDlg() ? validator()->canOpen( files.at( i ), checkPermissions() ) : + validator()->canSave( files.at( i ), checkPermissions() ); + if ( !bOk ) + return false; + } + } + break; } - else - return myValidator->canSave( selectedFile() ); } - return true; + + if ( bOk ) + emit filesSelected( files ); + + return bOk; } -/*! Adds an extension to the selected file name - * if the file has not it. - * The extension is extracted from the active filter. - */ -void SUIT_FileDlg::addExtension() +/*! + \brief Add an extension to the specified file name. + + The extension is extracted from the active filter. + + \param fileName file name to be processed + \return fileName with the extension added +*/ +QString SUIT_FileDlg::addExtension( const QString& fileName ) const { + QString fname = fileName.trimmed(); + // check if file name entered is empty - if ( mySelectedFile.trimmed().isEmpty() ) - return; + if ( fname.isEmpty() ) + return fileName; // current file extension - QString anExt = "." + SUIT_Tools::extension( mySelectedFile.trimmed() ).trimmed(); + QString anExt = "." + SUIT_Tools::extension( fname ).trimmed(); // If the file already has extension and it does not match the filter there are two choices: // - to leave it 'as is' // - to ignore it // The behavior is defined by IGNORE_NON_MATCHING_EXTENSION constant if ( anExt != "." && !IGNORE_NON_MATCHING_EXTENSION ) - return; + return fileName; QRegExp r( QString::fromLatin1("\\(?[a-zA-Z0-9.*? +;#|]*\\)?$") ); int index = r.indexIn( selectedFilter().trimmed() ); @@ -365,8 +515,7 @@ void SUIT_FileDlg::addExtension() // now we get the list of all extension masks and remove all which does not contain wildcard symbols QStringList extList = aPattern.split( "|", QString::SkipEmptyParts ); - for ( int i = extList.count() - 1; i >= 0; i-- ) - { + for ( int i = extList.count() - 1; i >= 0; i-- ) { if ( !extList[i].contains( "." ) ) extList.removeAt( i ); } @@ -376,129 +525,234 @@ void SUIT_FileDlg::addExtension() QRegExp anExtRExp( "^("+ aPattern + ")$" ); // Check if the current file extension matches the pattern - if ( !anExtRExp.exactMatch( anExt ) ) - { + if ( !anExtRExp.exactMatch( anExt ) ) { // find first appropriate extension in the selected filter // (it should be without wildcard symbols) - for ( int i = 0; i < (int)extList.count(); i++ ) - { + for ( int i = 0; i < extList.count(); i++ ) { QString newExt = extList[i].replace( QRegExp( "[\\\\][+]" ),"+" ); int res = newExt.lastIndexOf( '.' ); if ( res >= 0 ) newExt = newExt.mid( res + 1 ); - if ( newExt.indexOf( QRegExp("[*|?]" ) ) < 0 ) - { - mySelectedFile.trimmed(); - mySelectedFile += mySelectedFile.endsWith(".") ? newExt : QString(".") + newExt; - break; + if ( newExt.indexOf( QRegExp("[*|?]" ) ) < 0 ) { + fname += fname.endsWith( "." ) ? newExt : QString( "." ) + newExt; + return fname; } } } } + return fileName; } -/*! Processes selection : tries to set given path or filename as selection */ +/*! + \brief Processes selection : tries to set specified sirectory or filename + as current file dialog selection. + \param path file or directory path + \return \c true if \a path is processed correctly and \c false otherwise +*/ bool SUIT_FileDlg::processPath( const QString& path ) { - if ( !path.isNull() ) - { + if ( !path.isNull() ) { QFileInfo fi( path ); - if ( fi.exists() ) - { + if ( fi.exists() ) { if ( fi.isFile() ) - selectFile( path ); + selectFile( path ); else if ( fi.isDir() ) - setDirectory( path ); + setDirectory( path ); return true; } - else - { - if ( QFileInfo( SUIT_Tools::dir( path ) ).exists() ) - { - setDirectory( SUIT_Tools::dir( path ) ); - selectFile( path ); - return true; - } + else if ( QFileInfo( SUIT_Tools::dir( path ) ).exists() ) { + setDirectory( SUIT_Tools::dir( path ) ); + selectFile( path ); + return true; } } return false; } -/*! Called when user selects item from "Quick Dir" combo box */ -void SUIT_FileDlg::quickDir(const QString& dirPath) + +/*! + \brief Add file filter and activates it. + \param filter new file filter +*/ +void SUIT_FileDlg::addFilter( const QString& filter ) { - QString aPath = dirPath; - if ( !QDir(aPath).exists() ) - { - aPath = QDir::homePath(); - SUIT_MessageBox::critical( this, tr( "ERR_ERROR" ), tr( "ERR_DIR_NOT_EXIST" ).arg( dirPath ) ); + QStringList flist = filters(); + if ( !flist.contains( filter ) ) { + flist << filter; + setFilters( flist ); } + selectFilter( filter ); +} + +/*! + \brief Check if the string contains wildcard symbols. + \param s string to be checked (for example, file name) + \return \c true if string contains "*" or "?" symbols +*/ +bool SUIT_FileDlg::hasWildCards( const QString& s ) +{ + return s.contains( QRegExp("[*|?]") ); +} + +/*! + \brief Called when the user presses "Open"or "Save" button. + + Verifies the user choice and closes dialog box, setting the return code to QDialog::Accepted + + \sa acceptData() +*/ +void SUIT_FileDlg::accept() +{ + if ( acceptData() ) { + myLastVisitedPath = directory().path(); + QDialog::accept(); + } +} + +/*! + \brief Called when user selects directory from the "Quick Dir" combo box. + + Browses the file dialog to the specified directory (if it is valid). + + \param dirPath selected directory +*/ +void SUIT_FileDlg::quickDir( const QString& dirPath ) +{ + if ( !QDir( dirPath ).exists() ) + SUIT_MessageBox::critical( this, tr( "ERR_ERROR" ), tr( "ERR_DIR_NOT_EXIST" ).arg( dirPath ) ); else - processPath( aPath ); + processPath( dirPath ); } + /*! - Called when user presses "Add" button - adds current directory to quick directory - list and to the preferences + \brief Called when user presses "Quick Dir Add" button. + + Adds current directory to the quick directories list and to the preferences. */ void SUIT_FileDlg::addQuickDir() { QString dp = directory().path(); - if ( !dp.isEmpty() ) - { + if ( !dp.isEmpty() ) { QDir dir( dp ); - // getting dir list from settings - QString dirs; + + QStringList dirList; + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); if ( resMgr ) - dirs = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ); - QStringList dirList = dirs.split( ';', QString::SkipEmptyParts ); + dirList = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ).split( ';', QString::SkipEmptyParts ); + bool found = false; bool emptyAndHome = false; - if ( dirList.count() > 0 ) - { - for ( int i = 0; i < dirList.count(); i++ ) - { - QDir aDir( dirList[i] ); - if ( aDir.canonicalPath().isNull() && dirList[i] == dir.absolutePath() || - !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath() ) - { - found = true; - break; - } + if ( dirList.count() > 0 ) { + for ( int i = 0; i < dirList.count() && !found; i++ ) { + QDir aDir( dirList[i] ); + if ( aDir.canonicalPath().isNull() && dirList[i] == dir.absolutePath() || + !aDir.canonicalPath().isNull() && aDir.exists() && + aDir.canonicalPath() == dir.canonicalPath() ) { + found = true; + } } } - else + else { emptyAndHome = dir.canonicalPath() == QDir( QDir::homePath() ).canonicalPath(); + } - if ( !found ) - { + if ( !found ) { dirList.append( dp ); resMgr->setValue( "FileDlg", QString( "QuickDirList" ), dirList.join( ";" ) ); if ( !emptyAndHome ) - myQuickCombo->addItem( dp ); + myQuickCombo->addItem( dp ); } } } + /*! - Returns the file name for Open/Save [ static ] + \brief Polish the dialog box. +*/ +void SUIT_FileDlg::polish() +{ + QList buttons = findChildren(); + + int maxBtnWidth = 0; + + for ( QList::const_iterator it = buttons.begin(); + it != buttons.end(); ++it ) + maxBtnWidth = qMax( maxBtnWidth, (*it)->sizeHint().width() ); + + for ( QList::const_iterator it = buttons.begin(); + it != buttons.end(); ++it ) { + (*it)->setDefault( false ); + (*it)->setAutoDefault( false ); + (*it)->setFixedWidth( maxBtnWidth ); + } + + QList views = findChildren(); + for ( QList::const_iterator it = views.begin(); + it != views.end(); ++it ) { + (*it)->setViewMode( QListView::ListMode ); + } +} + +/*! + \brief Show dialog box for the file opening/saving. + + This method can be used to select the file for opening + or saving. The behavior is defined by the \a open parameter. + Note, that selection validation depends on the dialog mode used. + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters list + \param caption dialog box title + \param open if \c true dialog box is used for file opening, otherwise - for saving + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file name or null string if dialog box is cancelled + \sa getOpenFileNames(), getExistingDirectory() */ -QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, bool open, bool showQuickDir, +QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, + const QStringList& filters, const QString& caption, + const bool open, const bool showQuickDir, SUIT_FileValidator* validator ) { - SUIT_FileDlg* fd = new SUIT_FileDlg( parent, open, showQuickDir, true ); + SUIT_FileDlg fd( parent, open, showQuickDir, true ); + + fd.setFileMode( open ? ExistingFile : AnyFile ); + + if ( filters.isEmpty() ) + fd.setFilter( tr( "ALL_FILES_FILTER" ) ); // All files (*) + else + fd.setFilters( filters ); + if ( !caption.isEmpty() ) - fd->setWindowTitle( caption ); + fd.setWindowTitle( caption ); + if ( !initial.isEmpty() ) - fd->processPath( initial ); // VSR 24/03/03 check for existing of directory has been added to avoid QFileDialog's bug + fd.processPath( initial ); - fd->setFilters( filters ); if ( validator ) - fd->setValidator( validator ); + fd.setValidator( validator ); - fd->exec(); + QString filename; - QString filename = fd->selectedFile(); - delete fd; + if ( fd.exec() == QDialog::Accepted ) + filename = fd.selectedFile(); QApplication::processEvents(); @@ -506,54 +760,213 @@ QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, cons } /*! - Returns the list of files to be opened [ static ] + \brief Show dialog box for the file opening/saving. + \overload + + This method can be used to select the file for opening + or saving. The behavior is defined by the \a open parameter. + Note, that selection validation depends on the dialog mode used. + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + This is the list of wildcards, separated by the ";;" symbols. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters separated by ";;" + \param caption dialog box title + \param open if \c true dialog box is used for file opening, otherwise - for saving + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file name or null string if dialog box is cancelled + \sa getOpenFileNames(), getExistingDirectory() +*/ +QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, + const QString& filters, const QString& caption, + const bool open, const bool showQuickDir, + SUIT_FileValidator* validator ) +{ + return getFileName( parent, initial, filters.split( ";;", QString::SkipEmptyParts ), + caption, open, showQuickDir, validator ); +} + +/*! + \brief Show dialog box for the multiple files selection. + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters list + \param caption dialog box title + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file names or empty list if dialog box is cancelled + \sa getFileName(), getExistingDirectory() */ -QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, bool showQuickDir, SUIT_FileValidator* validator ) +QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial, + const QStringList& filters, const QString& caption, + const bool showQuickDir, + SUIT_FileValidator* validator ) { - SUIT_FileDlg* fd = new SUIT_FileDlg( parent, true, showQuickDir, true ); - fd->setFileMode( ExistingFiles ); + SUIT_FileDlg fd( parent, true, showQuickDir, true ); + + fd.setFileMode( ExistingFiles ); + + if ( filters.isEmpty() ) + fd.setFilter( tr( "ALL_FILES_FILTER" ) ); // All files (*) + else + fd.setFilters( filters ); + if ( !caption.isEmpty() ) - fd->setWindowTitle( caption ); + fd.setWindowTitle( caption ); + if ( !initial.isEmpty() ) - fd->processPath( initial ); // VSR 24/03/03 check for existing of directory has been added to avoid QFileDialog's bug + fd.processPath( initial ); - fd->setFilters( filters ); if ( validator ) - fd->setValidator( validator ); + fd.setValidator( validator ); + + QStringList filenames; - fd->exec(); - QStringList filenames = fd->selectedFiles(); - delete fd; + if ( fd.exec() == QDialog::Accepted ) + filenames = fd.selectedFiles(); QApplication::processEvents(); + return filenames; } /*! - Existing directory selection dialog [ static ] + \brief Show dialog box for the multiple file opening. + \overload + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + This is the list of wildcards, separated by the ";;" symbols. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters separated by ";;" + \param caption dialog box title + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file names or empty list if dialog box is cancelled + \sa getFileName(), getExistingDirectory() +*/ +QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial, + const QString& filters, const QString& caption, + const bool showQuickDir, + SUIT_FileValidator* validator ) +{ + return getOpenFileNames( parent, initial, filters.split( ";;", QString::SkipEmptyParts ), + caption, showQuickDir, validator ); +} + +/*! + \brief Show dialog box for the existing directory selection. + + If \a initial parameter is not null string it is used as starting directory + at which dialog box is opened. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial directory dialog box to be opened on + \param caption dialog box title + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected directory name or null string if dialog box is cancelled + \sa getFileName(), getOpenFileNames() */ QString SUIT_FileDlg::getExistingDirectory( QWidget* parent, const QString& initial, - const QString& caption, bool showQuickDir ) + const QString& caption, const bool showQuickDir, + SUIT_FileValidator* validator ) { - SUIT_FileDlg* fd = new SUIT_FileDlg( parent, true, showQuickDir, true ); + SUIT_FileDlg fd( parent, true, showQuickDir, true ); + + fd.setFileMode( DirectoryOnly ); + if ( !caption.isEmpty() ) - fd->setWindowTitle( caption ); - if ( !initial.isEmpty() ) - fd->processPath( initial ); // VSR 24/03/03 check for existing of directory has been added to avoid QFileDialog's bug + fd.setWindowTitle( caption ); - fd->setFileMode( DirectoryOnly ); - fd->setFilters( QStringList( tr( "INF_DIRECTORIES_FILTER" ) ) ); + if ( !initial.isEmpty() ) + fd.processPath( initial ); + + if ( validator ) + fd.setValidator( validator ); - fd->exec(); + QString dirname; - QString dirname = fd->selectedFile(); - delete fd; + if ( fd.exec() == QDialog::Accepted ) + dirname = fd.selectedFile(); QApplication::processEvents(); + return dirname; } +/*! + \brief Get last visited path + \return last visited path +*/ +QString SUIT_FileDlg::getLastVisitedPath() +{ + return myLastVisitedPath; +} + /*! \brief Selects current file diff --git a/src/SUIT/SUIT_FileDlg.h b/src/SUIT/SUIT_FileDlg.h index 1adee9e3d..76309c67a 100755 --- a/src/SUIT/SUIT_FileDlg.h +++ b/src/SUIT/SUIT_FileDlg.h @@ -16,81 +16,108 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef SUIT_FILEDIALOG_H -#define SUIT_FILEDIALOG_H +// File : SUIT_FileDlg.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#ifndef SUIT_FILEDLG_H +#define SUIT_FILEDLG_H #include "SUIT.h" #include class QLabel; +class QLineEdit; class QComboBox; class QPushButton; class SUIT_FileValidator; -/*! \class QFileDialog - * For more information see QT documentation. -*/ class SUIT_EXPORT SUIT_FileDlg : public QFileDialog { Q_OBJECT public: - SUIT_FileDlg( QWidget*, bool open, bool showQuickDir = true, bool modal = true ); + SUIT_FileDlg( QWidget*, bool, bool = true, bool = true ); virtual ~SUIT_FileDlg(); -public: bool isOpenDlg() const; + + bool checkPermissions() const; + void setCheckPermissions( const bool ); + + SUIT_FileValidator* validator() const; + void setValidator( SUIT_FileValidator* ); + + bool addWidgets( QWidget*, QWidget*, QWidget* ); + + QStringList selectedFiles() const; QString selectedFile() const; - void selectFile( const QString& ); + void selectFile( const QString& ); - void setValidator( SUIT_FileValidator* ); + static QString getLastVisitedDirectory(); - static QString getFileName( QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, const bool open, const bool showQuickDir = true, - SUIT_FileValidator* validator = 0 ); - static QStringList getOpenFileNames( QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, bool showQuickDir = true, - SUIT_FileValidator* validator = 0 ); - static QString getExistingDirectory( QWidget* parent, const QString& initial, - const QString& caption, const bool showQuickDir = true ); + static QString getFileName( QWidget*, + const QString&, + const QStringList&, + const QString& = QString(), + const bool = true, + const bool = true, + SUIT_FileValidator* = 0 ); + static QString getFileName( QWidget*, + const QString&, + const QString&, + const QString& = QString(), + const bool = true, + const bool = true, + SUIT_FileValidator* = 0 ); -private: - void polish(); - bool acceptData(); - void addExtension(); - bool processPath( const QString& path ); + static QStringList getOpenFileNames( QWidget*, + const QString&, + const QStringList&, + const QString& = QString(), + const bool = true, + SUIT_FileValidator* = 0 ); + static QStringList getOpenFileNames( QWidget*, + const QString&, + const QString&, + const QString& = QString(), + const bool = true, + SUIT_FileValidator* = 0 ); + + static QString getExistingDirectory( QWidget*, + const QString&, + const QString& = QString(), + const bool = true, + SUIT_FileValidator* = 0 ); + + static QString getLastVisitedPath(); + +protected: + virtual bool event( QEvent* ); + QLineEdit* lineEdit() const; + virtual bool acceptData(); + QString addExtension( const QString& ) const; + bool processPath( const QString& ); + void addFilter( const QString& ); + static bool hasWildCards( const QString& ); protected slots: void accept(); - void reject(); void quickDir( const QString& ); void addQuickDir(); -protected: - virtual bool event( QEvent* ); +private: + void polish(); -protected: - bool myOpen; //!< open/save selector - QString mySelectedFile; //!< selected filename +private: SUIT_FileValidator* myValidator; //!< file validator QLabel* myQuickLab; //!< quick dir combo box QComboBox* myQuickCombo; //!< quick dir combo box QPushButton* myQuickButton; //!< quick dir add button - - /*! \var myAccepted - * \brief flag is used to warkaround the Qt 2.2.2 - * \bug accept() method is called twice if user presses 'Enter' key - * in file name editor while file name is not acceptable by acceptData() - * (e.g. permission denied) - */ -// bool myAccepted; - /*! ASL: this bug can be fixed with help of call setDefault( false ) - * and setAutoDefault( false ) methods for all QPushButtons of this dialog - */ - + bool myCheckPermissions; //!< check permissions option static QString myLastVisitedPath; //!< last visited path }; -#endif +#endif // SUIT_FILEDLG_H diff --git a/src/SUIT/SUIT_FileValidator.cxx b/src/SUIT/SUIT_FileValidator.cxx index 0adb0b331..5885a7892 100755 --- a/src/SUIT/SUIT_FileValidator.cxx +++ b/src/SUIT/SUIT_FileValidator.cxx @@ -16,74 +16,178 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include "SUIT_FileValidator.h" +// File : SUIT_FileValidator.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// +#include "SUIT_FileValidator.h" #include "SUIT_MessageBox.h" - -#include +#include "SUIT_Tools.h" #include -/*! constructor */ -SUIT_FileValidator::SUIT_FileValidator(QWidget* parent) : -myParent(parent) +/*! + \class SUIT_FileValidator + \brief Provides functionality to check the file or directory + existance and permissions. + \sa SUIT_FileDlg class +*/ + +/*! + \brief Constructor. + \param parent parent widget (used as parent when displaying + information message boxes) +*/ +SUIT_FileValidator::SUIT_FileValidator( QWidget* parent ) +: myParent( parent ) { } -/*! returns false if can't open file */ -bool SUIT_FileValidator::canOpen( const QString& file ) +/*! + \brief Check if the specified file exists and (optionally) can be read. + + If file does not exists or can not be read (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param fileName file path + \param checkPermission if \c true (default) check also file permissions + \return \c false if file does not exist or if it does not have + read permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canOpen( const QString& fileName, bool checkPermission ) { - if ( !QFile::exists( file ) ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_FILE_NOT_EXIST" ).arg( file ) ); - return false; + if ( !QFile::exists( fileName ) ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_FILE_NOT_EXIST" ).arg( fileName ) ); + return false; } - if ( !QFileInfo( file ).isReadable() ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_PERMISSION_DENIED" ).arg( file ) ); + if ( checkPermission && !QFileInfo( fileName ).isReadable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( fileName ) ); return false; } return true; } -/*! returns false if can't save file */ -bool SUIT_FileValidator::canSave( const QString& file ) +/*! + \brief Check if the specified file can be written. + + If file already exists and parent() is not null, prompts + question message box to the user to confirm file overwriting. + + If file can not be written (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param fileName file path + \param checkPermission if \c true (default) check also file permissions + \return \c false if file exists and user rejects file overwriting + or if file does not have write permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canSave( const QString& fileName, bool checkPermission ) { - if ( QFile::exists( file ) ) - { - // if file exists - raise warning... - if ( SUIT_MessageBox::question( myParent, QObject::tr( "WRN_WARNING" ), - QObject::tr( "QUE_DOC_FILEEXISTS" ).arg( file ), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, - SUIT_MessageBox::No ) != SUIT_MessageBox::Yes ) - { - return false; - } - // ... and if user wants to overwrite file, check it for writeability - if ( !QFileInfo( file ).isWritable() ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_PERMISSION_DENIED" ).arg( file ) ); + if ( QFile::exists( fileName ) ) { + if ( parent() ) + if ( SUIT_MessageBox::question( parent(), QObject::tr( "WRN_WARNING" ), + QObject::tr( "QUE_DOC_FILEEXISTS" ).arg( fileName ), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::No ) != SUIT_MessageBox::Yes ) + return false; + + if ( checkPermission && !QFileInfo( fileName ).isWritable() ) { + if ( parent() ) + SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( fileName ) ); return false; } } - else - { - // if file doesn't exist - try to create it - QFile qf( file ); - if ( !qf.open( QFile::WriteOnly ) ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_PERMISSION_DENIED" ).arg( file ) ); + else { + QString dirName = SUIT_Tools::dir( fileName ); + if ( checkPermission && !QFileInfo( dirName ).isWritable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( fileName ) ); return false; } - else - { - // remove just created file - qf.close(); - qf.remove(); - } } return true; } + +/*! + \brief Check if the specified directory exists and (optionally) can be read. + + If directory does not exists or can not be read (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param dirName directory path + \param checkPermission if \c true (default) check also directory permissions + \return \c false if directory does not exist or if it does not have + read permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canReadDir( const QString& dirName, bool checkPermission ) +{ + QFileInfo info( dirName ); + if ( !info.exists() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_DIR_NOT_EXIST" ).arg( dirName ) ); + return false; + } + if ( !info.isDir() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_FILE_NOT_DIR" ).arg( dirName ) ); + return false; + } + if ( checkPermission && !info.isReadable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( dirName ) ); + return false; + } + return true; +} + +/*! + \brief Check if the specified directory can be written. + + If directory does not exists or can not be modified (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param dirName directory path + \param checkPermission if \c true (default) check also directory permissions + \return \c false if directory does not exist or if it does not have + write permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canWriteDir( const QString& dirName, bool checkPermission ) +{ + QFileInfo info( dirName ); + if ( !info.exists() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_DIR_NOT_EXIST" ).arg( dirName ) ); + return false; + } + if ( !info.isDir() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_FILE_NOT_DIR" ).arg( dirName ) ); + return false; + } + if ( checkPermission && !info.isWritable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( dirName ) ); + return false; + } + return true; +} + +/*! + \brief Get parent widget. + \return parent widget +*/ +QWidget* SUIT_FileValidator::parent() const +{ + return myParent; +} diff --git a/src/SUIT/SUIT_FileValidator.h b/src/SUIT/SUIT_FileValidator.h index 9142c381d..edcd3398b 100755 --- a/src/SUIT/SUIT_FileValidator.h +++ b/src/SUIT/SUIT_FileValidator.h @@ -16,8 +16,10 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SALOME SALOMEGUI : implementation of desktop and GUI kernel +// File : SUIT_FileValidator.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) // + #ifndef SUIT_FILEVALIDATOR_H #define SUIT_FILEVALIDATOR_H @@ -26,24 +28,21 @@ class QWidget; class QString; -/*! - \class SUIT_FileValidator - Provides functionality to check file -*/ class SUIT_EXPORT SUIT_FileValidator { public: - SUIT_FileValidator(QWidget* parent = 0); + SUIT_FileValidator( QWidget* = 0 ); - virtual bool canOpen( const QString& file ); - virtual bool canSave( const QString& file ); + virtual bool canOpen( const QString&, bool = true ); + virtual bool canSave( const QString&, bool = true ); - //! Return parent widget - QWidget* parent() const { return myParent; } - - private: + virtual bool canReadDir( const QString&, bool = true ); + virtual bool canWriteDir( const QString&, bool = true ); + + QWidget* parent() const; +private: QWidget* myParent; }; -#endif +#endif // SUIT_FILEVALIDATOR_H -- 2.39.2