//
// 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 )
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() );
// 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 );
}
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();
}
/*!
- 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;
}