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