Salome HOME
Copyright update: 2016
[modules/gui.git] / src / SUIT / SUIT_FileDlg.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File   : SUIT_FileDlg.cxx
24 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 //
26 /*!
27   \class SUIT_FileDlg
28   \brief An extension of the Qt Open/Save file dialog box.
29
30   The class SUIT_FileDlg provides a set of static methods which canbe used
31   for file or directories selection:
32   - getFileName() for single file opening or saving
33   - getOpenFileNames() for mulktiple files opening
34   - getExistingDirectory() for existing directory selection
35
36   Examples:
37   \code
38   // select file to dump contents of the view
39   QStringList filters;
40   filters << "Image files (*.bmp *.gif *.jpg )" << "All files (*)";
41   QString fileName = SUIT_FileDlg::getFileName( desktop(), 
42                                                 QString(), 
43                                                 filters, 
44                                                 "Dump view",
45                                                 false );
46   if ( !fileName.isEmpty() ) {
47     ... writing image to the file 
48   }
49
50   // select list of files to open in the editor windows
51   QStringList filters;
52   filters << "*.cpp | *.cxx | *.c++" << "*.h | *.hpp | *.hxx";
53   QStringList fileNames = SUIT_FileDlg::getOpenFileName( desktop(),
54                                                          QString(), 
55                                                          filters, 
56                                                          QString() );
57   if ( !fileNames.isEmpty() ) {
58     ... open files
59   }
60   \endcode
61
62   The class SUIT_FileDlg can be subclassed to implement custom file 
63   dialog boxes. The class provides a set of methods which can be used
64   in subclasses:
65   - setCheckPermissions() - to enable/disable check of files/directories
66     permissions
67   - setValidator() - to use custom file validator
68   - addWidgets() - to add custom widgets to the lower part of the 
69     dialog box
70   - getLastVisitedDirectory() - to get last visited directory
71   - acceptData() - can be used ti customize user selection validation
72
73   \sa SUIT_FileValidator class.
74 */
75
76 #include "SUIT_FileDlg.h"
77
78 #include "SUIT_Tools.h"   
79 #include "SUIT_Session.h"
80 #include "SUIT_MessageBox.h"
81 #include "SUIT_ResourceMgr.h"
82 #include "SUIT_FileValidator.h"
83 #include "Qtx.h"
84
85 #include <QDir>
86 #include <QEvent>
87 #include <QRegExp>
88 #include <QLabel>
89 #include <QComboBox>
90 #include <QPushButton>
91 #include <QGridLayout>
92 #include <QApplication>
93 #include <QListView>
94 #include <QLineEdit>
95 // GDD
96 #include <QUrl>
97 #include <QDesktopServices>
98
99 /*!
100   \brief Defines extension behavior.
101
102   If the selected file name has extension which does not match the selected filter
103   and this variable is set to \c true, the file extension is ignored and new one
104   (from current file filter will be added.
105   \sa addExtension()
106 */
107 const bool IGNORE_NON_MATCHING_EXTENSION = true;
108
109 QString SUIT_FileDlg::myLastVisitedPath;
110
111 /*!
112   \brief Constructor.
113   \param parent parent widget
114   \param open if \c true dialog box is used for file opening, otherwise - for saving
115   \param showQuickDir if \c true the quick directory list widgets will be shown
116   \param modal if \c true the dialog box will be modal
117 */
118 SUIT_FileDlg::SUIT_FileDlg( QWidget* parent, bool open, bool showQuickDir, bool modal )
119 : QFileDialog( parent ),
120   myValidator( 0 ),
121   myQuickLab( 0 ),
122   myQuickCombo( 0 ),
123   myQuickButton( 0 ),
124   myCheckPermissions( true )
125 {
126   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
127   setOption(QFileDialog::DontUseNativeDialog, true);
128   setModal( modal );
129   setSizeGripEnabled( true );
130   if ( parent )
131     setWindowIcon( parent->windowIcon() );
132
133   // GDD
134   myUrls.insert(0,QUrl::fromLocalFile(QDesktopServices::storageLocation(QDesktopServices::ApplicationsLocation)));
135   myUrls.insert(0,QUrl::fromLocalFile(QDesktopServices::storageLocation(QDesktopServices::HomeLocation)));
136   setSidebarUrls(myUrls);
137
138   // add quick directories widgets
139   if ( showQuickDir ) {
140     myQuickLab    = new QLabel( tr( "LAB_QUICK_PATH" ), this );
141     myQuickCombo  = new QComboBox( this );
142     myQuickButton = new QPushButton( tr( "BUT_ADD_PATH" ), this );
143     
144     if ( addWidgets( myQuickLab, myQuickCombo, myQuickButton ) ) {
145       connect( myQuickCombo,  SIGNAL( activated( const QString& ) ), this, SLOT( quickDir( const QString& ) ) );
146       connect( myQuickButton, SIGNAL( clicked() ),                   this, SLOT( addQuickDir() ) );
147
148       // retrieve directories list from the resources
149       QStringList dirList;
150   
151       if ( resMgr )
152         dirList = resMgr->stringValue( "FileDlg", "QuickDirList" ).split( ';', QString::SkipEmptyParts );
153
154       if ( dirList.isEmpty() ) 
155         dirList << QDir::homePath();
156
157       // GDD
158       for ( int i = 0; i < dirList.count(); i++ ) {
159         myQuickCombo->addItem( dirList[i] );
160         myUrls.append(QUrl::fromLocalFile(dirList[i]));
161       }
162
163       // GDD
164       setSidebarUrls(myUrls);
165       
166     }
167     else {
168       delete myQuickLab;    myQuickLab = 0;
169       delete myQuickCombo;  myQuickCombo = 0;
170       delete myQuickButton; myQuickButton = 0;
171     }
172   }
173
174   setAcceptMode( open ? AcceptOpen: AcceptSave );
175   setWindowTitle( open ? tr( "INF_DESK_DOC_OPEN" ) : tr( "INF_DESK_DOC_SAVE" ) );
176
177   bool showCurrentDirInitial = resMgr ? resMgr->booleanValue( "FileDlg", "ShowCurDirInitial", false ) : false;
178
179   // If last visited path doesn't exist -> switch to the first preferred path
180   if ( !myLastVisitedPath.isEmpty() ) {
181     if ( !processPath( myLastVisitedPath ) && showQuickDir )
182       processPath( myQuickCombo->itemText( 0 ) );
183   }
184   else if ( showCurrentDirInitial ) {
185     processPath( QDir::currentPath() );
186   }
187   else if ( showQuickDir ) {
188     processPath( myQuickCombo->itemText( 0 ) );
189   }
190
191   // set default file validator
192   myValidator = new SUIT_FileValidator( this );
193 }
194
195 /*!
196   \brief Destructor.
197 */
198 SUIT_FileDlg::~SUIT_FileDlg() 
199 {
200   setValidator( 0 );
201 }
202
203
204 /*! 
205   \brief Check if the dialog box is used for opening or saving the file.
206   \return \c true if dialog is used for file opening and \c false otherwise
207 */
208 bool SUIT_FileDlg::isOpenDlg() const
209 {
210   return acceptMode() == AcceptOpen;
211 }
212
213 /*!
214   \brief Get 'check file permissions' flag.
215   \return flag value
216   \sa setCheckPermissions()
217 */
218 bool SUIT_FileDlg::checkPermissions() const
219 {
220   return myCheckPermissions;
221 }
222
223 /*!
224   \brief Set 'check file permissions' flag.
225  
226   If this flag is set and file validator is not null,
227   the validator will check the file permissions also.
228
229   \param checkPerm new flag value
230   \sa checkPermissions()
231 */
232 void SUIT_FileDlg::setCheckPermissions( const bool checkPerm )
233 {
234   myCheckPermissions = checkPerm;
235 }
236
237 /*!
238   \brief Get file validator.
239   \return current file validator
240   \sa setValidator()
241 */
242 SUIT_FileValidator* SUIT_FileDlg::validator() const
243 {
244   return myValidator;
245 }
246
247 /*!
248   \brief Set file validator.
249  
250   Destroys previous validator if the dialog owns it.
251
252   \param v new file validator
253   \sa validator()
254 */
255 void SUIT_FileDlg::setValidator( SUIT_FileValidator* v )
256 {
257   if ( myValidator && myValidator->parent() == this )
258     delete myValidator;
259   myValidator = v;
260 }
261
262 /*!
263   \brief Adds the specified widgets to the bottom of the file dialog. 
264   
265   The first widget (usually label) \a l is placed underneath the "file name" 
266   and the "file types" labels. 
267   The widget \a w is placed underneath the file types combobox.
268   The last widget (usually button) \a b is placed underneath the Cancel push button. 
269
270   In general, the widgets can be arbitrary. This method is added to support 
271   the functionality provided by the Qt series 3.x.
272
273   If you don't want to have one of the widgets added, pass 0 in that widget's position. 
274   Every time this function is called, a new row of widgets is added to the bottom of the 
275   file dialog. 
276
277   \param l first widget (e.g. text label)
278   \param w second widget (e.g. combo box)
279   \param b third widget (e.g. push button)
280   \return \c true if widgets have been added successfully
281 */
282 bool SUIT_FileDlg::addWidgets( QWidget* l, QWidget* w, QWidget* b )
283 {
284   QGridLayout* grid = ::qobject_cast<QGridLayout*>( layout() );
285   if ( grid ) {
286     int row = grid->rowCount();
287     int columns = grid->columnCount();
288     if ( l ) 
289       grid->addWidget( l, row, 0 );
290     if ( w )
291       grid->addWidget( w, row, 1, 1, columns-2 );
292     if ( b )
293       grid->addWidget( b, row, columns-1 );
294     return true;
295   }
296   return false;
297 }
298
299 /*!
300   \brief Get list of selected files.
301   \return selected file names
302 */
303 QStringList SUIT_FileDlg::selectedFiles() const
304 {
305   QStringList files = QFileDialog::selectedFiles();
306   if ( fileMode() != DirectoryOnly && fileMode() != Directory ) {
307     QMutableListIterator<QString> it( files );
308     while ( it.hasNext() ) {
309       QString f = it.next();
310       QFileInfo finfo( f );
311       if ( !finfo.isDir() )
312         it.setValue( addExtension( f ) );
313     }
314   }
315   return files;
316 }
317
318 /*!
319   \brief Get selected file.
320   \return selected file name or null string if file is not selected
321 */
322 QString SUIT_FileDlg::selectedFile() const
323 {
324   QStringList files = selectedFiles();
325   return files.count() > 0 ? files[0] : QString();
326 }
327
328 /*!
329   \brief Get last visited directory.
330
331   Note, that last visited path is memorized only if the 
332   dialog box is accepted.
333
334   \return last visited directory
335 */
336 QString SUIT_FileDlg::getLastVisitedDirectory()
337 {
338   return myLastVisitedPath;
339 }
340
341 /*!
342   \brief Customize events processing.
343   \param e event
344   \return \c true if the event e was recognized and processed
345 */
346 bool SUIT_FileDlg::event( QEvent* e )
347 {
348   bool res = QFileDialog::event( e );
349
350   if ( e->type() == QEvent::Polish )
351     polish();
352
353   return res;
354 }
355
356 /*!
357   \brief Get line edit which is used to enter file name.
358   \return line edit widget or0 if it could not be found
359 */
360 QLineEdit* SUIT_FileDlg::lineEdit() const
361 {
362   QLineEdit* ebox = 0;
363   QList<QLineEdit*> editBoxes = findChildren<QLineEdit*>();
364   QGridLayout* grid = ::qobject_cast<QGridLayout*>( layout() );
365   if ( grid ) {
366     int idx = 10000;
367     for ( int i = 0; i < editBoxes.count(); i++ ) {
368       int widx = grid->indexOf( editBoxes[ i ] );
369       if ( widx >= 0 )
370         idx = qMin( idx, widx );
371     }
372     if ( grid->itemAt( idx )  )
373       ebox = qobject_cast<QLineEdit*>( grid->itemAt( idx )->widget() );
374   }
375   return ebox;
376 }
377
378 /*! 
379   \brief Validate user selection.
380
381   The validation is done by calling the corresponding methods
382   of the validator. If the validator is not set, this method
383   always returns \c true.
384
385   This method can be re-implemented in the subclasses to customize
386   the file dialog behavior.
387   Another solution could be implementing own file validator class.
388
389   \return \c true if user selection (file(s) or directory) is valid
390   \sa SUIT_FileValidator class, validator(), setValidator()
391 */
392 bool SUIT_FileDlg::acceptData()
393 {    
394   QStringList files = selectedFiles();
395   if ( files.isEmpty() )
396     return false;
397
398   // special case for ".."
399   if ( lineEdit() ) {
400     QString txt = lineEdit()->text();
401     if ( txt == ".." ) {
402       QDir dir = directory();
403       if ( dir.cdUp() ) {
404         setDirectory( dir );
405         bool block = lineEdit()->blockSignals( true );
406         lineEdit()->setText( ".." );
407         lineEdit()->selectAll();
408         lineEdit()->setFocus( Qt::OtherFocusReason );
409         lineEdit()->blockSignals( block );
410         return false;
411       }
412     }
413     else if ( fileMode() != DirectoryOnly ) {
414       QStringList fs = txt.split( " ", QString::SkipEmptyParts );
415       for ( int i = 0; i < fs.count(); i++ ) {
416         QString wc = fs.at( i );
417         if ( wc.startsWith( "\"" ) && wc.endsWith( "\"" ) )
418           wc = wc.mid( 1, wc.length()-2 );
419         if ( hasWildCards( wc ) ) {
420           addFilter( wc );
421           lineEdit()->clear();
422           return false;
423         }
424       }
425     }
426   }
427
428   // special case for wildcards
429   for ( int i = 0; i < files.count(); ++i ) {
430   }
431
432   bool bOk = true;
433
434   switch ( fileMode() ) {
435   case DirectoryOnly:
436   case Directory: 
437     {
438       QString fn = files.first();
439       if ( validator() ) {
440         bOk = isOpenDlg() ? validator()->canReadDir( fn, checkPermissions() ) : 
441                             validator()->canWriteDir( fn, checkPermissions() );
442       }
443       break;
444     }
445   case AnyFile: 
446     {
447       QString fn = files.first();
448       QFileInfo info( fn );
449       if ( info.isDir() ) {
450         setDirectory( info.absoluteFilePath() );
451         if ( lineEdit() ) {
452           lineEdit()->selectAll();
453           lineEdit()->setFocus( Qt::OtherFocusReason );
454         }
455         return false;
456       }
457       // validation is not required
458       if ( validator() ) {
459         bOk = isOpenDlg() ? validator()->canOpen( fn, checkPermissions() ) : 
460                             validator()->canSave( fn, checkPermissions() );
461       }
462       break;
463     }
464   case ExistingFile:
465   case ExistingFiles: 
466     {
467       for ( int i = 0; i < files.count(); ++i ) {
468         QFileInfo info( files.at( i ) );
469         if ( info.isDir() ) {
470           setDirectory( info.absoluteFilePath() );
471           if ( lineEdit() ) {
472             lineEdit()->selectAll();
473             lineEdit()->setFocus( Qt::OtherFocusReason );
474           }
475           return false;
476         }
477         if ( validator() ) {
478           bOk = isOpenDlg() ? validator()->canOpen( files.at( i ), checkPermissions() ) : 
479                               validator()->canSave( files.at( i ), checkPermissions() );
480         if ( !bOk )
481           return false;
482         }
483       }
484       break;
485     }
486   }
487
488   if ( bOk )
489     emit filesSelected( files );
490
491   return bOk;
492 }
493
494 /*!
495   \brief Add an extension to the specified file name.
496  
497   The extension is extracted from the active filter.
498
499   \param fileName file name to be processed
500   \return fileName with the extension added
501 */
502 QString SUIT_FileDlg::addExtension( const QString& fileName ) const
503 {
504   QString fname = fileName.trimmed();
505
506   // check if file name entered is empty
507   if ( fname.isEmpty() )
508     return fileName;
509
510   // current file extension
511   QString anExt = "." + SUIT_Tools::extension( fname ).trimmed();
512
513   // If the file already has extension and it does not match the filter there are two choices:
514   // - to leave it 'as is'
515   // - to ignore it
516   // The behavior is defined by IGNORE_NON_MATCHING_EXTENSION constant
517   if ( anExt != "." && !IGNORE_NON_MATCHING_EXTENSION )
518     return fileName;
519
520   QRegExp r( QString::fromLatin1("\\(?[a-zA-Z0-9.*? +;#|]*\\)?$") );
521   int index = r.indexIn( selectedNameFilter().trimmed() );
522
523   if ( QFileInfo( fileName ).exists() )
524     return fileName; // if file exists return as is
525
526   if ( index >= 0 ) {            
527     // Create wildcard regular expression basing on selected filter 
528     // in order to validate a file extension.
529     // Due to transformations from the filter list (*.txt *.*xx *.c++ SUIT*.* ) we 
530     // will have the pattern (\.txt|\..*xx|\.c\+\+|\..*) (as we validate extension only, 
531     // we remove everything except extension mask from the pattern
532     QString wildcard = selectedNameFilter().mid( index, r.matchedLength() ).trimmed();
533     // replace '|' and ';' separators by space symbol and also brackets if there are some
534     wildcard.replace( QRegExp( "[\\|;|(|)]" )," " ); 
535
536     QString aPattern = wildcard.replace( QRegExp( "(^| )(\\s*)[0-9a-zA-Z*_?]*\\."), " \\." ).trimmed().
537                                          replace( QRegExp( "\\s+" ), "|" ).replace( QRegExp( "[?]" ),".?" ).
538                                          replace( QRegExp( "[*]" ),".*" ).replace( QRegExp( "[+]" ),"\\+" );
539
540     // now we get the list of all extension masks and remove all which does not contain wildcard symbols
541     QStringList extList = aPattern.split( "|", QString::SkipEmptyParts );
542     for ( int i = extList.count() - 1; i >= 0; i-- ) {
543       if ( !extList[i].contains( "." ) )
544         extList.removeAt( i );
545     }
546     aPattern = extList.join( "|" );
547
548     // finalize pattern
549     QRegExp anExtRExp( "^("+ aPattern + ")$" );
550
551     // Check if the current file extension matches the pattern
552     if ( !anExtRExp.exactMatch( anExt ) ) {
553       // find first appropriate extension in the selected filter 
554       // (it should be without wildcard symbols)
555       for ( int i = 0; i < extList.count(); i++ ) {
556         QString newExt = extList[i].replace( QRegExp( "[\\\\][+]" ),"+" );
557         int res = newExt.lastIndexOf( '.' );
558         if ( res >= 0 )
559           newExt = newExt.mid( res + 1 );
560         if ( newExt.indexOf( QRegExp("[*|?]" ) ) < 0 ) {
561           fname += fname.endsWith( "." ) ? newExt : QString( "." ) + newExt;
562           return fname;
563         }
564       }
565     }
566   }
567   return fileName;
568 }
569
570 /*!
571   \brief Processes selection : tries to set specified sirectory or filename
572   as current file dialog selection.
573   \param path file or directory path
574   \return \c true if \a path is processed correctly and \c false otherwise
575 */
576 bool SUIT_FileDlg::processPath( const QString& path )
577 {
578   if ( !path.isNull() ) {
579     QFileInfo fi( path );
580     if ( fi.exists() ) {
581       if ( fi.isFile() )
582         selectFile( path );
583       else if ( fi.isDir() )
584         setDirectory( path );
585       return true;
586     }
587     QString dirPath = SUIT_Tools::dir( path, false );
588     if ( !dirPath.isEmpty() && QFileInfo( dirPath ).exists() )
589       setDirectory( dirPath );
590     selectFile( SUIT_Tools::file( path ) );
591     return true;
592   }
593   return false;
594 }
595
596 /*!
597   \brief Add file filter and activates it.
598   \param filter new file filter
599 */
600 void SUIT_FileDlg::addFilter( const QString& filter )
601 {
602   QStringList flist = nameFilters();
603   if ( !flist.contains( filter ) ) {
604     flist << filter;
605     setNameFilters( flist );
606   }
607   selectNameFilter( filter );
608 }
609
610 /*!
611   \brief Check if the string contains wildcard symbols.
612   \param s string to be checked (for example, file name)
613   \return \c true if string contains "*" or "?" symbols
614 */
615 bool SUIT_FileDlg::hasWildCards( const QString& s )
616 {
617   return s.contains( QRegExp("[*|?]") );
618 }
619
620 /*!
621   \brief Called when the user presses "Open"or "Save" button.
622
623   Verifies the user choice and closes dialog box, setting the return code to QDialog::Accepted
624
625   \sa acceptData()
626 */
627 void SUIT_FileDlg::accept()
628 {
629   if ( acceptData() ) {
630     myLastVisitedPath = directory().path();
631     QDialog::accept();        
632   }
633 }
634
635 /*!
636   \brief Called when user selects directory from the "Quick Dir" combo box.
637
638   Browses the file dialog to the specified directory (if it is valid).
639
640   \param dirPath selected directory
641 */
642 void SUIT_FileDlg::quickDir( const QString& dirPath )
643 {
644   if ( !QDir( dirPath ).exists() )
645     SUIT_MessageBox::critical( this, tr( "ERR_ERROR" ), tr( "ERR_DIR_NOT_EXIST" ).arg( dirPath ) );
646   else
647     processPath( dirPath );
648 }
649
650 /*!
651   \brief Called when user presses "Quick Dir Add" button.
652   
653   Adds current directory to the quick directories list and to the preferences.
654 */
655 void SUIT_FileDlg::addQuickDir()
656 {
657   QString dp = directory().path();
658   if ( !dp.isEmpty() ) {
659     QDir dir( dp );
660
661     QStringList dirList;
662
663     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
664     if ( resMgr )
665       dirList = resMgr->stringValue( "FileDlg", "QuickDirList" ).split( ';', QString::SkipEmptyParts );
666
667     bool found = false;
668     bool emptyAndHome = false;
669     if ( dirList.count() > 0 ) {
670       for ( int i = 0; i < dirList.count() && !found; i++ )  {
671         QDir aDir( dirList[i] );
672         if ( ( aDir.canonicalPath().isNull() && dirList[i] == dir.absolutePath() ) ||
673              ( !aDir.canonicalPath().isNull() && aDir.exists() &&  
674              aDir.canonicalPath() == dir.canonicalPath() ) ) {
675           found = true;
676         }
677       }
678     }
679     else {
680       emptyAndHome = dir.canonicalPath() == QDir( QDir::homePath() ).canonicalPath();
681     }
682
683     if ( !found ) {
684       dirList.append( dp );
685       resMgr->setValue( "FileDlg", "QuickDirList", dirList.join( ";" ) );
686       // GDD
687       if ( !emptyAndHome ) {
688         myQuickCombo->addItem( dp );
689         myUrls.append(QUrl::fromLocalFile( dp ));
690         setSidebarUrls(myUrls);
691       }
692     }
693   }
694 }
695
696 /*!
697   \brief Polish the dialog box.
698 */
699 void SUIT_FileDlg::polish()
700 {
701   QList<QPushButton*> buttons = findChildren<QPushButton*>();
702
703   int maxBtnWidth = 0;
704
705   for ( QList<QPushButton*>::const_iterator it = buttons.begin(); 
706         it != buttons.end(); ++it )
707     maxBtnWidth = qMax( maxBtnWidth, (*it)->sizeHint().width() );
708
709   for ( QList<QPushButton*>::const_iterator it = buttons.begin(); 
710         it != buttons.end(); ++it ) {
711     (*it)->setDefault( false );
712     (*it)->setAutoDefault( false );
713     (*it)->setFixedWidth( maxBtnWidth );
714   }
715
716   QList<QListView*> views = findChildren<QListView*>();
717   for ( QList<QListView*>::const_iterator it = views.begin(); 
718         it != views.end(); ++it ) {
719     (*it)->setViewMode( QListView::ListMode );
720   }
721 }
722
723 /*!
724   \brief Show dialog box for the file opening/saving.
725
726   This method can be used to select the file for opening
727   or saving. The behavior is defined by the \a open parameter.
728   Note, that selection validation depends on the dialog mode used.
729
730   If \a initial parameter is not null string it is used as starting directory
731   or file at which dialog box is opened.
732   
733   The parameter \a filters defines file filters (wildcards) to be used.
734   If filters list is empty, "All files (*)" is used by default.
735   
736   The parameter \a caption is used as dialog box title. If it is
737   is empty, the default title is used.
738   
739   The parameter \a showQuickDir specifies if it is necessary to 
740   show additional quick directories list controls in the bottom part
741   of the dialog box.
742
743   The validation of the user selection is done with help of the file 
744   validator (SUIT_FileValidator class). The last parameter \a validator
745   can be used to pass the custom file validator to the dialog box.
746   
747   \param parent parent widget
748   \param initial initial file (or directory) dialog box to be opened on
749   \param filters file filters list
750   \param caption dialog box title
751   \param open if \c true dialog box is used for file opening, otherwise - for saving
752   \param showQuickDir if \c true the quick directory list widgets will be shown
753   \param validator custom file validator
754   \return selected file name or null string if dialog box is cancelled
755   \sa getOpenFileNames(), getExistingDirectory()
756 */
757 QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, 
758                                    const QStringList& filters, const QString& caption, 
759                                    const bool open, const bool showQuickDir,
760                                    SUIT_FileValidator* validator )
761 {            
762   SUIT_FileDlg fd( parent, open, showQuickDir, true );    
763
764   fd.setFileMode( open ? ExistingFile : AnyFile );
765
766   QString tmpfilename = initial;
767   tmpfilename = tmpfilename.simplified();
768   tmpfilename = tmpfilename.replace(QRegExp("\\*"), "" ).replace(QRegExp("\\?"), "" );
769
770   if ( filters.isEmpty() )
771     fd.setNameFilter( tr( "ALL_FILES_FILTER" ) ); // All files (*)
772   else
773     fd.setNameFilters( filters );
774
775   if ( !caption.isEmpty() )
776     fd.setWindowTitle( caption );
777
778   if ( !tmpfilename.isEmpty() )
779     fd.processPath( tmpfilename );
780
781   if ( validator )
782     fd.setValidator( validator );
783
784   QString filename;
785
786   if ( fd.exec() == QDialog::Accepted )
787     filename = fd.selectedFile();
788
789   QApplication::processEvents();
790
791   return filename;
792 }
793
794 /*!
795   \brief Show dialog box for the file opening/saving.
796   \overload
797
798   This method can be used to select the file for opening
799   or saving. The behavior is defined by the \a open parameter.
800   Note, that selection validation depends on the dialog mode used.
801
802   If \a initial parameter is not null string it is used as starting directory
803   or file at which dialog box is opened.
804   
805   The parameter \a filters defines file filters (wildcards) to be used.
806   This is the list of wildcards, separated by the ";;" symbols.
807   If filters list is empty, "All files (*)" is used by default.
808   
809   The parameter \a caption is used as dialog box title. If it is
810   is empty, the default title is used.
811   
812   The parameter \a showQuickDir specifies if it is necessary to 
813   show additional quick directories list controls in the bottom part
814   of the dialog box.
815
816   The validation of the user selection is done with help of the file 
817   validator (SUIT_FileValidator class). The last parameter \a validator
818   can be used to pass the custom file validator to the dialog box.
819   
820   \param parent parent widget
821   \param initial initial file (or directory) dialog box to be opened on
822   \param filters file filters separated by ";;"
823   \param caption dialog box title
824   \param open if \c true dialog box is used for file opening, otherwise - for saving
825   \param showQuickDir if \c true the quick directory list widgets will be shown
826   \param validator custom file validator
827   \return selected file name or null string if dialog box is cancelled
828   \sa getOpenFileNames(), getExistingDirectory()
829 */
830 QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, 
831                                    const QString& filters, const QString& caption, 
832                                    const bool open, const bool showQuickDir,
833                                    SUIT_FileValidator* validator )
834 {
835   return getFileName( parent, initial, filters.split( ";;", QString::SkipEmptyParts ), 
836                       caption, open, showQuickDir, validator );
837 }
838
839 /*!
840   \brief Show dialog box for the multiple files selection.
841
842   If \a initial parameter is not null string it is used as starting directory
843   or file at which dialog box is opened.
844   
845   The parameter \a filters defines file filters (wildcards) to be used.
846   If filters list is empty, "All files (*)" is used by default.
847   
848   The parameter \a caption is used as dialog box title. If it is
849   is empty, the default title is used.
850   
851   The parameter \a showQuickDir specifies if it is necessary to 
852   show additional quick directories list controls in the bottom part
853   of the dialog box.
854
855   The validation of the user selection is done with help of the file 
856   validator (SUIT_FileValidator class). The last parameter \a validator
857   can be used to pass the custom file validator to the dialog box.
858   
859   \param parent parent widget
860   \param initial initial file (or directory) dialog box to be opened on
861   \param filters file filters list
862   \param caption dialog box title
863   \param showQuickDir if \c true the quick directory list widgets will be shown
864   \param validator custom file validator
865   \return selected file names or empty list if dialog box is cancelled
866   \sa getFileName(), getExistingDirectory()
867 */
868 QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial,
869                                             const QStringList& filters, const QString& caption,
870                                             const bool showQuickDir, 
871                                             SUIT_FileValidator* validator )
872 {            
873   SUIT_FileDlg fd( parent, true, showQuickDir, true );
874
875   fd.setFileMode( ExistingFiles );
876
877   if ( filters.isEmpty() )
878     fd.setNameFilter( tr( "ALL_FILES_FILTER" ) ); // All files (*)
879   else
880     fd.setNameFilters( filters );
881
882   if ( !caption.isEmpty() )
883     fd.setWindowTitle( caption );
884
885   if ( !initial.isEmpty() )
886     fd.processPath( initial );
887
888   if ( validator )
889     fd.setValidator( validator );
890
891   QStringList filenames;
892
893   if ( fd.exec() == QDialog::Accepted )
894     filenames = fd.selectedFiles();
895
896   QApplication::processEvents();
897
898   return filenames;
899 }
900
901 /*!
902   \brief Show dialog box for the multiple file opening.
903   \overload
904
905   If \a initial parameter is not null string it is used as starting directory
906   or file at which dialog box is opened.
907   
908   The parameter \a filters defines file filters (wildcards) to be used.
909   This is the list of wildcards, separated by the ";;" symbols.
910   If filters list is empty, "All files (*)" is used by default.
911   
912   The parameter \a caption is used as dialog box title. If it is
913   is empty, the default title is used.
914   
915   The parameter \a showQuickDir specifies if it is necessary to 
916   show additional quick directories list controls in the bottom part
917   of the dialog box.
918
919   The validation of the user selection is done with help of the file 
920   validator (SUIT_FileValidator class). The last parameter \a validator
921   can be used to pass the custom file validator to the dialog box.
922   
923   \param parent parent widget
924   \param initial initial file (or directory) dialog box to be opened on
925   \param filters file filters separated by ";;"
926   \param caption dialog box title
927   \param showQuickDir if \c true the quick directory list widgets will be shown
928   \param validator custom file validator
929   \return selected file names or empty list if dialog box is cancelled
930   \sa getFileName(), getExistingDirectory()
931 */
932 QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial,
933                                             const QString& filters, const QString& caption,
934                                             const bool showQuickDir,
935                                             SUIT_FileValidator* validator )
936 {
937   return getOpenFileNames( parent, initial, filters.split( ";;", QString::SkipEmptyParts ), 
938                            caption, showQuickDir, validator );
939 }
940
941 /*!
942   \brief Show dialog box for the existing directory selection.
943
944   If \a initial parameter is not null string it is used as starting directory
945   at which dialog box is opened.
946   
947   The parameter \a caption is used as dialog box title. If it is
948   is empty, the default title is used.
949   
950   The parameter \a showQuickDir specifies if it is necessary to 
951   show additional quick directories list controls in the bottom part
952   of the dialog box.
953
954   The validation of the user selection is done with help of the file 
955   validator (SUIT_FileValidator class). The last parameter \a validator
956   can be used to pass the custom file validator to the dialog box.
957   
958   \param parent parent widget
959   \param initial initial directory dialog box to be opened on
960   \param caption dialog box title
961   \param showQuickDir if \c true the quick directory list widgets will be shown
962   \param validator custom file validator
963   \return selected directory name or null string if dialog box is cancelled
964   \sa getFileName(), getOpenFileNames()
965 */
966 QString SUIT_FileDlg::getExistingDirectory( QWidget* parent, const QString& initial,
967                                             const QString& caption, const bool showQuickDir,
968                                             SUIT_FileValidator* validator )
969 {
970   SUIT_FileDlg fd( parent, true, showQuickDir, true );
971
972   fd.setFileMode( DirectoryOnly );
973
974   if ( !caption.isEmpty() )
975     fd.setWindowTitle( caption );
976
977   if ( !initial.isEmpty() )
978     fd.processPath( initial );
979   
980   if ( validator )
981     fd.setValidator( validator );
982
983   QString dirname;
984
985   if ( fd.exec() == QDialog::Accepted )
986     dirname = fd.selectedFile();
987
988   QApplication::processEvents();
989
990   return dirname;
991 }
992
993 /*!
994   \brief Get last visited path
995   \return last visited path
996 */
997 QString SUIT_FileDlg::getLastVisitedPath()
998 {
999   return myLastVisitedPath;
1000 }
1001
1002 /*!
1003   \brief Selects current file
1004
1005   This version of selectFile() methods works similar to Qt version 3.x:
1006   it selects the given file as current and it changes the current file dialog's directory
1007   to the directory of the file
1008   
1009   \param f - new current file name 
1010 */
1011 void SUIT_FileDlg::selectFile( const QString& f )
1012 {
1013   QFileDialog::selectFile( QFileInfo( f ).baseName() );
1014   if ( !Qtx::dir( f, false ).isEmpty() )
1015     setDirectory( QFileInfo( f ).absolutePath() );
1016 }