]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
*** empty log message ***
authorvsr <vsr@opencascade.com>
Fri, 27 Jul 2007 11:26:51 +0000 (11:26 +0000)
committervsr <vsr@opencascade.com>
Fri, 27 Jul 2007 11:26:51 +0000 (11:26 +0000)
src/SUIT/SUIT_FileDlg.cxx
src/SUIT/SUIT_FileDlg.h
src/SUIT/SUIT_FileValidator.cxx
src/SUIT/SUIT_FileValidator.h

index 8dc7fd64c76ac333c78d55e31053020c2284984a..bfb32cb885feed255d4d39b20d48053d2b4c758c 100755 (executable)
 //
 // 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"
 #include <QPushButton>
 #include <QGridLayout>
 #include <QApplication>
+#include <QListView>
+#include <QLineEdit>
 
-#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<QPushButton*>( *anIt );
-    if ( pb )
-    {
-      pb->setDefault( false );
-      pb->setAutoDefault( false );
-    }
-  }
-
+  setSizeGripEnabled( true );
   if ( parent )
     setWindowIcon( parent->windowIcon() );
-  setSizeGripEnabled( true );
-  
-  QGridLayout* grid = ::qobject_cast<QGridLayout*>( 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 );
-    
+
+  // 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() ) );
 
-    connect( myQuickCombo,  SIGNAL( activated( const QString& ) ), this, SLOT( quickDir( const QString& ) ) );
-    connect( myQuickButton, SIGNAL( clicked() ),                   this, SLOT( addQuickDir() ) );
+      // 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 );
 
-    int row = grid->rowCount();
-    grid->addWidget( myQuickLab, row, 0 );
-    grid->addWidget( myQuickCombo, row, 1, 1, 3 );
-    grid->addWidget( myQuickButton, row, 5 );
+      if ( dirList.isEmpty() ) 
+       dirList << QDir::homePath();
 
-    // getting dir list from settings
-    QString dirs;
-    SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-    if ( resMgr )
-      dirs = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) );
-
-    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<QPushButton*> buttonList;
-    QValueList<QLabel*> 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<QPushButton*>::Iterator bListIt;
-      for ( bListIt = buttonList.begin(); bListIt != buttonList.end(); ++bListIt )
-       (*bListIt)->setFixedWidth( maxButWidth );
-    }
-    if (maxLabWidth > 0) {
-      QValueList<QLabel*>::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,110 +234,256 @@ 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<QGridLayout*>( layout() );
+  if ( grid ) {
+    int row = grid->rowCount();
+    if ( l ) 
+      grid->addWidget( l, row, 0 );
+    if ( w )
+      grid->addWidget( w, row, 1, 1, 3 );
+    if ( b )
+      grid->addWidget( b, row, 5 );
+    return true;
+  }
+  return false;
+}
+
+/*!
+  \brief Get list of selected files.
+  \return selected file names
+*/
+QStringList SUIT_FileDlg::selectedFiles() const
+{
+  QStringList files = QFileDialog::selectedFiles();
+  QMutableListIterator<QString> it( files );
+  while ( it.hasNext() )
+    it.setValue( addExtension( it.next() ) );
+  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() )
-    {
-      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<QLineEdit*> editBoxes = findChildren<QLineEdit*>();
+  QGridLayout* grid = ::qobject_cast<QGridLayout*>( 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<QLineEdit*>( 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() );
@@ -358,8 +504,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 );
     }
@@ -369,129 +514,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 );
     }
   }
 }
+
+/*!
+  \brief Polish the dialog box.
+*/
+void SUIT_FileDlg::polish()
+{
+  QList<QPushButton*> buttons = findChildren<QPushButton*>();
+
+  int maxBtnWidth = 0;
+
+  for ( QList<QPushButton*>::const_iterator it = buttons.begin(); 
+       it != buttons.end(); ++it )
+    maxBtnWidth = qMax( maxBtnWidth, (*it)->sizeHint().width() );
+
+  for ( QList<QPushButton*>::const_iterator it = buttons.begin(); 
+       it != buttons.end(); ++it ) {
+    (*it)->setDefault( false );
+    (*it)->setAutoDefault( false );
+    (*it)->setFixedWidth( maxBtnWidth );
+  }
+
+  QList<QListView*> views = findChildren<QListView*>();
+  for ( QList<QListView*>::const_iterator it = views.begin(); 
+       it != views.end(); ++it ) {
+    (*it)->setViewMode( QListView::ListMode );
+  }
+}
+
 /*!
-  Returns the file name for Open/Save [ static ]
+  \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( ExistingFile );
+
+  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();
 
@@ -499,50 +749,200 @@ 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;
 }
index c2d7e4c44adf7072ea9dbef835c5f8ed64178cbc..c863dbf12911e4c7e7a6e2be69ba55c61b4b0d9e 100755 (executable)
 //
 // 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 <QFileDialog>
 
 class QLabel;
+class QLineEdit;
 class QComboBox;
 class QPushButton;
 class SUIT_FileValidator;
 
-/*! \class QFileDialog
- *  For more information see <a href="http://doc.trolltech.com">QT documentation</a>.
-*/
 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;    
-  QString             selectedFile() const;
+  
+  bool                checkPermissions() const;
+  void                setCheckPermissions( const bool );
 
+  SUIT_FileValidator* validator() const;
   void                setValidator( SUIT_FileValidator* );
 
-  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 );
+  bool                addWidgets( QWidget*, QWidget*, QWidget* );
 
-private:
-  void                polish();
-  bool                acceptData();
-  void                addExtension();
-  bool                processPath( const QString& path );
+  QStringList         selectedFiles() const;
+  QString             selectedFile() const;
+
+  static QString      getLastVisitedDirectory();
+
+  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 );
+
+  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 );
+
+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
index 0adb0b33163251a51f10132ba11a40571cb8d961..5885a7892ca0905b44642b4e6eba5f050e77dbf0 100755 (executable)
 //
 // 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 <QFile>
+#include "SUIT_Tools.h"   
 #include <QFileInfo>
 
-/*! 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; 
+}
index 9142c381db1fb00f11ccce1b7380c412d4eac632..edcd3398ba9ee62bb3e4ca583423d260f33e4de5 100755 (executable)
 //
 // 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
 
 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