Salome HOME
PR: merge from branch BR_UnitTests tag mergeto_trunk_17oct05
[modules/kernel.git] / src / SALOMEGUI / QAD_FileDlg.cxx
index 2d626eb9650659b1ceb477666fb38ab3cf5885dc..3f35d228eb7950ce6e05b0bcbfed94df24aeb65d 100644 (file)
@@ -9,19 +9,18 @@
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
 #include <qapplication.h>
 #include <qdir.h>
 #include <qlabel.h>
 #include <qobjectlist.h>
 #include <qpalette.h>
-#include <qpushbutton.h>
 #include <qregexp.h>
 #include "QAD_Config.h"
 #include "QAD_Desktop.h"   
 #include "QAD_FileDlg.h"
 #include "QAD_MessageBox.h"
 #include "QAD_Tools.h"   
+using namespace std;
 
 #define MIN_COMBO_SIZE     100
 
@@ -31,50 +30,27 @@ QString QAD_FileDlg::myLastVisitedPath;
 Constructor
 */
 QAD_FileDlg::QAD_FileDlg( QWidget* parent, bool open, bool showQuickDir, bool modal ) :
-QFileDialog( parent, 0, modal ),
+QFileDialogP( parent, 0, modal ),
 myValidator( 0 ),
 myQuickCombo( 0 ),
 myOpen( open )
 {    
   if ( parent->icon() )
-    setIcon( *parent->icon() );       
+    setIcon( *parent->icon() );
   setSizeGripEnabled( true );
-  
+
   if (showQuickDir) {
     // inserting quick dir combo box
-    QLabel* lab  = new QLabel(tr("Quick path:"), this);
+    QLabel* lab  = new QLabel(tr("QUICK_PATH_LAB"), this);
     myQuickCombo = new QComboBox(false, this);
     myQuickCombo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
     myQuickCombo->setMinimumSize(MIN_COMBO_SIZE, 0);
     
-    // the following is a workaround for proper layouting of custom widgets ===========
-    QPushButton* btn = new QPushButton(this);
-    btn->setEnabled(false);
-    QPalette pal = btn->palette();
-    QColorGroup ca = pal.active();
-    ca.setColor(QColorGroup::Light,    palette().active().background());
-    ca.setColor(QColorGroup::Midlight, palette().active().background());
-    ca.setColor(QColorGroup::Dark,     palette().active().background());
-    ca.setColor(QColorGroup::Mid,      palette().active().background());
-    ca.setColor(QColorGroup::Shadow,   palette().active().background());
-    QColorGroup ci = pal.inactive();
-    ci.setColor(QColorGroup::Light,    palette().inactive().background());
-    ci.setColor(QColorGroup::Midlight, palette().inactive().background());
-    ci.setColor(QColorGroup::Dark,     palette().inactive().background());
-    ci.setColor(QColorGroup::Mid,      palette().inactive().background());
-    ci.setColor(QColorGroup::Shadow,   palette().inactive().background());
-    QColorGroup cd = pal.disabled();
-    cd.setColor(QColorGroup::Light,    palette().disabled().background());
-    cd.setColor(QColorGroup::Midlight, palette().disabled().background());
-    cd.setColor(QColorGroup::Dark,     palette().disabled().background());
-    cd.setColor(QColorGroup::Mid,      palette().disabled().background());
-    cd.setColor(QColorGroup::Shadow,   palette().disabled().background());
-    pal.setActive(ca); pal.setInactive(ci); pal.setDisabled(cd);
-    btn->setPalette(pal);
-    // ================================================================================
+    myQuickButton = new QPushButton(tr("ADD_PATH_BTN"), this);
 
-    connect(myQuickCombo, SIGNAL(activated(const QString&)), this, SLOT(quickDir(const QString&)));
-    addWidgets(lab, myQuickCombo, btn);
+    connect(myQuickCombo,  SIGNAL(activated(const QString&)), this, SLOT(quickDir(const QString&)));
+    connect(myQuickButton, SIGNAL(clicked()),                 this, SLOT(addQuickDir()));
+    addWidgets(lab, myQuickCombo, myQuickButton);
 
     // getting dir list from settings
     QString dirs = QAD_CONFIG->getSetting("FileDlg:QuickDirList");
@@ -93,7 +69,7 @@ myOpen( open )
     const QObjectList *list = children();
     QObjectListIt it(*list);
     int maxButWidth = lab->sizeHint().width();
-    int maxLabWidth = btn->sizeHint().width();
+    int maxLabWidth = myQuickButton->sizeHint().width();
     
     for (; it.current() ; ++it) {
       if ( it.current()->isA( "QLabel" ) ) {
@@ -175,8 +151,10 @@ if the selected name is valid ( see 'acceptData()' )
 void QAD_FileDlg::accept()
 {
 //  mySelectedFile = QFileDialog::selectedFile().simplifyWhiteSpace(); //VSR- 06/12/02
-  mySelectedFile = QFileDialog::selectedFile(); //VSR+ 06/12/02
-  addExtension();
+  if ( mode() != ExistingFiles ) {
+    mySelectedFile = QFileDialogP::selectedFile(); //VSR+ 06/12/02
+    addExtension();
+  }
 //  mySelectedFile = mySelectedFile.simplifyWhiteSpace(); //VSR- 06/12/02
 
   /* Qt 2.2.2 BUG: accept() is called twice if you validate 
@@ -185,7 +163,7 @@ void QAD_FileDlg::accept()
   */
   if ( acceptData() ) {
     myLastVisitedPath = dirPath();
-    QFileDialog::accept();        
+    QFileDialogP::accept();        
   }
 }
 
@@ -195,7 +173,7 @@ Closes this dialog and sets the return code to 'Rejected'
 void QAD_FileDlg::reject()
 {
   mySelectedFile = QString::null;
-  QFileDialog::reject();        
+  QFileDialogP::reject();        
 }
 
 /*!
@@ -209,7 +187,17 @@ bool QAD_FileDlg::acceptData()
   if ( myValidator )
   {
     if ( isOpenDlg() )
-      return myValidator->canOpen( selectedFile() );
+      if ( mode() == ExistingFiles ) {
+       QStringList fileNames = selectedFiles();
+       for ( int i = 0; i < fileNames.count(); i++ ) {
+         if ( !myValidator->canOpen( fileNames[i] ) )
+           return false;
+       }
+       return true;
+      }
+      else {
+       return myValidator->canOpen( selectedFile() );
+      }
     else 
       return myValidator->canSave( selectedFile() );
   }
@@ -227,10 +215,11 @@ void QAD_FileDlg::addExtension()
 //  if ( mySelectedFile.isEmpty() )//VSR- 06/12/02
   if ( mySelectedFile.stripWhiteSpace().isEmpty() )//VSR+ 06/12/02
     return;
-  
+
 //  if ( QAD_Tools::getFileExtensionFromPath( mySelectedFile ).isEmpty() ) //VSR- 06/12/02
-  if ( QAD_Tools::getFileExtensionFromPath( mySelectedFile ).isEmpty() && !mySelectedFile.contains(".") ) //VSR+ 06/12/02
-  {
+//ota :   16/12/03  if ( QAD_Tools::getFileExtensionFromPath( mySelectedFile ).isEmpty() ) //VSR+ 06/12/02
+//  {
+
 #if QT_VERSION < 0x030000
     QRegExp r( QString::fromLatin1("([a-zA-Z0-9.*? +;#]*)$") );
     int len, index = r.match( selectedFilter(), 0, &len );
@@ -247,11 +236,28 @@ void QAD_FileDlg::addExtension()
 //      QString wildcard = selectedFilter().mid( index + 1, r.matchedLength()-2 ); //VSR- 06/12/02
       QString wildcard = selectedFilter().mid( index + 1, r.matchedLength()-2 ).stripWhiteSpace(); //VSR+ 06/12/02
 #endif
-      index = wildcard.findRev( '.' );    
-      if ( index >= 0 ) 
-        mySelectedFile += wildcard.mid( index );
+      if ( mySelectedFile[mySelectedFile.length() - 1] == '.')
+       //if the file name ends with the point remove it
+       mySelectedFile.truncate(mySelectedFile.length() - 1);
+      QString anExt = "." + QAD_Tools::getFileExtensionFromPath( mySelectedFile ).stripWhiteSpace();
+      // From the filters list make a pattern to validate a file extension
+      // Due to transformations from the filter list (*.txt *.*xx *.c++ QAD*.* ) we 
+      // will have the pattern (\.txt|\..*xx|\.c\+\+|\..*) (as we validate extension only we remove
+      // stay extension mask only in the pattern
+      QString aPattern(wildcard);
+      QRegExp anExtRExp("("+aPattern.replace(QRegExp("(^| )[0-9a-zA-Z*_?]*\\."), " \\.").
+                       stripWhiteSpace().replace(QRegExp("\\s+"), "|").
+                       replace(QRegExp("[*]"),".*").replace(QRegExp("[+]"),"\\+") + ")");
+      
+      if ( anExtRExp.match(anExt) == -1 ) //if a selected file extension does not match to filter's list
+       { //remove a point if it is at the word end
+         if (anExt[ anExt.length() - 1 ] == '.')  anExt.truncate( anExt.length() - 1 );
+         index = wildcard.findRev( '.' );    
+         if ( index >= 0 ) 
+           mySelectedFile += wildcard.mid( index ); //add the extension
+       }
     }
-  }
+  //  }
 }
 
 /*!
@@ -271,6 +277,7 @@ bool QAD_FileDlg::processPath( const QString& path )
     else {
       if ( QFileInfo( fi.dirPath() ).exists() ) {
        setDir( fi.dirPath() );
+       setSelection( path );
        return true;
       }
     }
@@ -293,15 +300,49 @@ void QAD_FileDlg::quickDir(const QString& dirPath)
     processPath(dirPath);
   }
 }
-
+/*!
+  Called when user presses "Add" button - adds current directory to quick directory
+  list and to the preferences
+*/
+void QAD_FileDlg::addQuickDir()
+{
+  QString dp = dirPath();
+  if ( !dp.isEmpty() ) {
+    QDir dir( dp );
+    // getting dir list from settings
+    QString dirs = QAD_CONFIG->getSetting("FileDlg:QuickDirList");
+    QStringList dirList = QStringList::split(';', dirs, false);
+    bool found = false;
+    bool emptyAndHome = false;
+    if ( dirList.count() > 0 ) {
+      for ( unsigned i = 0; i < dirList.count(); i++ ) {
+       QDir aDir( dirList[i] );
+       if ( aDir.canonicalPath().isNull() && dirList[i] == dir.absPath() ||
+           !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath() ) {
+         found = true;
+         break;
+       }
+      }
+    }
+    else {
+      emptyAndHome = dir.canonicalPath() == QDir(QDir::homeDirPath()).canonicalPath();
+    }
+    if ( !found ) {
+      dirList.append( dp );
+      QAD_CONFIG->addSetting("FileDlg:QuickDirList", dirList.join(";"));
+      if ( !emptyAndHome )
+       myQuickCombo->insertItem( dp );
+    }
+  }
+}
 /*!
   Returns the file name for Open/Save [ static ]
 */
 QString QAD_FileDlg::getFileName( QWidget*           parent, 
                                  const QString&     initial, 
-                                  const QStringList& filters, 
-                                  const QString&     caption,
-                                  bool               open,
+                                 const QStringList& filters, 
+                                 const QString&     caption,
+                                 bool               open,
                                  bool               showQuickDir, 
                                  QAD_FileValidator* validator )
 {            
@@ -311,7 +352,9 @@ QString QAD_FileDlg::getFileName( QWidget*           parent,
   if ( !initial.isEmpty() ) { 
     fd->processPath( initial ); // VSR 24/03/03 check for existing of directory has been added to avoid QFileDialog's bug
   }
-  fd->setFilters( filters );        
+
+  fd->setFilters( filters );
+
   if ( validator )
     fd->setValidator( validator );
   fd->exec();
@@ -321,6 +364,34 @@ QString QAD_FileDlg::getFileName( QWidget*           parent,
   return filename;
 }
 
+
+/*!
+  Returns the list of files to be opened [ static ]
+*/
+QStringList QAD_FileDlg::getOpenFileNames( QWidget*           parent, 
+                                          const QString&     initial, 
+                                          const QStringList& filters, 
+                                          const QString&     caption,
+                                          bool               showQuickDir, 
+                                          QAD_FileValidator* validator )
+{            
+  QAD_FileDlg* fd = new QAD_FileDlg( parent, true, showQuickDir, true );    
+  fd->setMode( ExistingFiles );     
+  if ( !caption.isEmpty() )
+    fd->setCaption( 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->setFilters( filters );        
+  if ( validator )
+    fd->setValidator( validator );
+  fd->exec();
+  QStringList filenames = fd->selectedFiles();
+  delete fd;
+  qApp->processEvents();
+  return filenames;
+}
+
 /*!
   Existing directory selection dialog [ static ]
 */
@@ -337,10 +408,11 @@ QString QAD_FileDlg::getExistingDirectory ( QWidget*       parent,
   }
   fd->setMode( DirectoryOnly );
   fd->setFilters(tr("DIRECTORIES_FILTER"));
+
   fd->exec();
   QString dirname = fd->selectedFile();
   delete fd;
   qApp->processEvents();
   return dirname;
-  
 }
+