1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/
19 // File: QtxPathDialog.cxx
20 // Author: Sergey TELKOV
22 #include "QtxPathDialog.h"
24 #include "QtxGroupBox.h"
30 #include <qlineedit.h>
31 #include <qfileinfo.h>
32 #include <qobjectlist.h>
33 #include <qstringlist.h>
34 #include <qfiledialog.h>
35 #include <qmessagebox.h>
36 #include <qpushbutton.h>
38 static const char* open_icon[] = {
63 //================================================================
64 // Function : QtxPathDialog
65 // Purpose : Constructor.
66 //================================================================
68 QtxPathDialog::QtxPathDialog( const bool import, QWidget* parent, const bool modal, const bool resize, const int buttons, WFlags f )
69 : QtxDialog( parent, 0, modal, resize, buttons, f ),
76 setCaption( tr( import ? "Open file" : "Save file" ) );
78 setDefaultEntry( createFileEntry( tr( "File name" ), import ? OpenFile : SaveFile ) );
79 QLineEdit* le = fileEntry( defaultEntry() );
81 le->setMinimumWidth( 200 );
88 //================================================================
89 // Function : QtxPathDialog
90 // Purpose : Constructor.
91 //================================================================
93 QtxPathDialog::QtxPathDialog( QWidget* parent, const bool modal, const bool resize, const int buttons, WFlags f )
94 : QtxDialog( parent, 0, modal, resize, buttons, f ),
102 //================================================================
103 // Function : ~QtxPathDialog
104 // Purpose : Destructor.
105 //================================================================
107 QtxPathDialog::~QtxPathDialog()
111 //================================================================
112 // Function : fileName
114 //================================================================
116 QString QtxPathDialog::fileName() const
118 return fileName( defaultEntry() );
121 //================================================================
122 // Function : setFileName
124 //================================================================
126 void QtxPathDialog::setFileName( const QString& txt, const bool autoExtension )
128 setFileName( defaultEntry(), txt, autoExtension );
131 //================================================================
134 //================================================================
136 QString QtxPathDialog::filter() const
141 //================================================================
142 // Function : setFilter
144 //================================================================
146 void QtxPathDialog::setFilter( const QString& fltr )
151 //================================================================
154 //================================================================
156 void QtxPathDialog::show()
158 if ( hasVisibleChildren( myEntriesFrame ) )
159 myEntriesFrame->show();
161 myEntriesFrame->hide();
163 if ( hasVisibleChildren( myOptionsFrame ) )
164 myOptionsFrame->show();
166 myOptionsFrame->hide();
171 //================================================================
172 // Function : onBrowse
174 //================================================================
176 void QtxPathDialog::onBrowse()
178 const QObject* obj = sender();
182 for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && id == -1; ++it )
183 if ( it.data().btn == obj )
189 FileEntry& entry = myEntries[id];
191 bool isDir = entry.mode != OpenFile && entry.mode != SaveFile;
195 entry.dlg = new QFileDialog( QDir::current().path(), QString::null, this, 0, true );
196 entry.dlg->setCaption( caption() );
197 switch ( entry.mode )
203 entry.dlg->setMode( QFileDialog::DirectoryOnly );
206 entry.dlg->setMode( QFileDialog::AnyFile );
210 entry.dlg->setMode( QFileDialog::ExistingFile );
216 entry.dlg->setFilters( prepareFilters() );
217 entry.dlg->setSelection( fileName( id ) );
219 if ( entry.dlg->exec() != Accepted )
222 QString fName = entry.dlg->selectedFile();
224 if ( fName.isEmpty() )
227 if ( QFileInfo( fName ).extension().isEmpty() && !isDir )
228 fName = autoExtension( fName, entry.dlg->selectedFilter() );
230 fName = QDir::convertSeparators( fName );
231 QString prev = QDir::convertSeparators( fileName( id ) );
234 while ( prev.length() && prev.at( prev.length() - 1 ) == QDir::separator() )
235 prev.remove( prev.length() - 1, 1 );
236 while ( fName.length() && fName.at( fName.length() - 1 ) == QDir::separator() )
237 fName.remove( fName.length() - 1, 1 );
243 setFileName( id, fName );
244 fileNameChanged( id, fName );
246 if ( id == defaultEntry() )
247 emit fileNameChanged( fName );
250 //================================================================
251 // Function : onReturnPressed
253 //================================================================
255 void QtxPathDialog::onReturnPressed()
257 const QObject* obj = sender();
260 for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && id == -1; ++it )
261 if ( it.data().edit == obj )
267 fileNameChanged( id, fileName( id ) );
269 if ( id == defaultEntry() )
270 emit fileNameChanged( fileName() );
273 //================================================================
274 // Function : onTextChanged
276 //================================================================
278 void QtxPathDialog::onTextChanged( const QString& )
283 //================================================================
284 // Function : validate
286 //================================================================
288 void QtxPathDialog::validate()
290 setButtonEnabled( isValid(), OK | Yes );
293 //================================================================
294 // Function : isValid
296 //================================================================
298 bool QtxPathDialog::isValid()
301 for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && ok; ++it )
302 if ( it.data().edit->isEnabled() )
303 ok = !it.data().edit->text().stripWhiteSpace().isEmpty();
308 //================================================================
309 // Function : acceptData
311 //================================================================
313 bool QtxPathDialog::acceptData() const
317 QWidget* parent = (QWidget*)this;
319 FileEntryMap::ConstIterator it;
320 for ( it = myEntries.begin(); it != myEntries.end() && ok; ++it )
322 const FileEntry& entry = it.data();
323 QFileInfo fileInfo( entry.edit->text() );
324 if ( entry.edit->text().isEmpty() )
326 QMessageBox::critical( parent, caption(), tr( "File name not specified" ),
327 QMessageBox::Ok, QMessageBox::NoButton );
330 else switch ( entry.mode )
333 if ( !fileInfo.exists() )
335 QMessageBox::critical( parent, caption(), tr( "File \"%1\" does not exist" ).arg( fileInfo.filePath() ),
336 QMessageBox::Ok, QMessageBox::NoButton );
341 if ( fileInfo.exists() )
342 ok = QMessageBox::warning( parent, caption(), tr( "File \"%1\" already exist. Do you want to overwrite it?" ).arg( fileInfo.filePath() ),
343 QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes;
346 if ( !fileInfo.exists() || !fileInfo.isDir() )
348 QMessageBox::critical( parent, caption(), tr( "Directory \"%1\" does not exist" ).arg( fileInfo.filePath() ),
349 QMessageBox::Ok, QMessageBox::NoButton );
354 if ( fileInfo.exists() && !fileInfo.isDir() )
356 QMessageBox::critical( parent, caption(), tr( "Directory \"%1\" can't be created because file with the same name exist" ).arg( fileInfo.filePath() ),
357 QMessageBox::Ok, QMessageBox::NoButton );
362 if ( fileInfo.exists() )
364 if ( !fileInfo.isDir() )
366 QMessageBox::critical( parent, caption(), tr( "Directory \"%1\" can't be created because file with the same name exist" ).arg( fileInfo.filePath() ),
367 QMessageBox::Ok, QMessageBox::NoButton );
370 else if ( QDir( fileInfo.filePath() ).count() > 2 )
371 ok = QMessageBox::warning( parent, caption(), tr( "Directory \"%1\" not empty. Do you want to remove all files in this directory?" ).arg( fileInfo.filePath() ),
372 QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes;
380 entry.edit->setFocus();
386 //================================================================
387 // Function : fileNameChanged
389 //================================================================
391 void QtxPathDialog::fileNameChanged( int, QString )
395 //================================================================
396 // Function : optionsFrame
398 //================================================================
400 QFrame* QtxPathDialog::optionsFrame()
402 return myOptionsFrame;
405 //================================================================
406 // Function : getFileName
408 //================================================================
410 QString QtxPathDialog::fileName( const int id ) const
413 if ( myEntries.contains( id ) )
414 res = myEntries[id].edit->text();
419 //================================================================
420 // Function : setFileName
422 //================================================================
424 void QtxPathDialog::setFileName( const int id, const QString& txt, const bool autoExt )
427 QLineEdit* le = fileEntry( id, mode );
431 if ( autoExt && ( mode == OpenFile || mode == SaveFile ) )
432 le->setText( autoExtension( txt ) );
438 //================================================================
439 // Function : fileEntry
441 //================================================================
443 QLineEdit* QtxPathDialog::fileEntry( const int id ) const
446 if ( myEntries.contains( id ) )
447 le = myEntries[id].edit;
452 //================================================================
453 // Function : fileEntry
455 //================================================================
457 QLineEdit* QtxPathDialog::fileEntry( const int theId, int& theMode ) const
460 if ( myEntries.contains( theId ) )
462 le = myEntries[theId].edit;
463 theMode = myEntries[theId].mode;
469 //================================================================
470 // Function : createFileEntry
472 //================================================================
474 int QtxPathDialog::createFileEntry( const QString& lab, const int mode, const int id )
480 while ( myEntries.contains( num ) )
488 new QLabel( lab, myEntriesFrame );
489 entry.edit = new QLineEdit( myEntriesFrame );
490 entry.btn = new QPushButton( myEntriesFrame );
491 entry.btn->setAutoDefault( false );
492 entry.btn->setPixmap( QPixmap( open_icon ) );
494 connect( entry.btn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
495 connect( entry.edit, SIGNAL( returnPressed() ), this, SLOT( onReturnPressed() ) );
496 connect( entry.edit, SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
498 myEntries.insert( num, entry );
503 //================================================================
504 // Function : defaultEntry
506 //================================================================
508 int QtxPathDialog::defaultEntry() const
513 //================================================================
514 // Function : setDefaultEntry
516 //================================================================
518 void QtxPathDialog::setDefaultEntry( const int id )
523 //================================================================
524 // Function : initialize
526 //================================================================
528 void QtxPathDialog::initialize()
530 setCaption( tr( "File dialog" ) );
532 QVBoxLayout* main = new QVBoxLayout( mainFrame() );
533 QtxGroupBox* mainGroup = new QtxGroupBox( 1, Qt::Horizontal, "", mainFrame() );
534 mainGroup->setFrameStyle( QFrame::NoFrame );
535 mainGroup->setInsideMargin( 0 );
536 main->addWidget( mainGroup );
538 myEntriesFrame = new QGroupBox( 3, Qt::Horizontal, "", mainGroup );
539 myOptionsFrame = new QFrame( mainGroup );
542 //================================================================
543 // Function : prepareFilters
545 //================================================================
547 QStringList QtxPathDialog::prepareFilters() const
550 if ( !myFilter.isEmpty() )
552 res = QStringList::split( ";;", myFilter );
553 bool allFilter = false;
554 for ( QStringList::ConstIterator it = res.begin(); it != res.end() && !allFilter; ++it )
556 QStringList wildCards = filterWildCards( *it );
557 allFilter = wildCards.findIndex( "*.*" ) != -1;
561 res.append( tr( "All files (*.*)" ) );
567 //================================================================
568 // Function : filterWildCards
570 //================================================================
572 QStringList QtxPathDialog::filterWildCards( const QString& theFilter ) const
576 int b = theFilter.findRev( "(" );
577 int e = theFilter.findRev( ")" );
578 if ( b != -1 && e != -1 )
580 QString content = theFilter.mid( b + 1, e - b - 1 ).stripWhiteSpace();
581 QStringList lst = QStringList::split( " ", content );
582 for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
583 if ( (*it).find( "." ) != -1 )
584 res.append( (*it).stripWhiteSpace() );
589 //================================================================
590 // Function : autoExtension
592 //================================================================
594 QString QtxPathDialog::autoExtension( const QString& theFileName, const QString& theFilter ) const
596 QString fName = theFileName;
598 if ( fName.isEmpty() )
601 QString filter = theFilter;
602 if ( filter.isEmpty() )
604 QStringList filters = prepareFilters();
605 if ( !filters.isEmpty() )
606 filter = filters.first();
609 QStringList wildCards = filterWildCards( filter );
610 if ( !wildCards.isEmpty() )
612 QString ext = wildCards.first();
613 if ( ext.find( "." ) != -1 )
614 ext = ext.mid( ext.find( "." ) + 1 );
616 if ( !ext.isEmpty() && !ext.contains( "*" ) )
617 fName = QDir::convertSeparators( fName ) + QString( "." ) + ext;
623 //================================================================
624 // Function : hasVisibleChildren
626 //================================================================
628 bool QtxPathDialog::hasVisibleChildren( QWidget* wid ) const
633 const QObjectList* aChildren = wid->children();
636 for ( QObjectListIt it( *aChildren ); it.current() && !res; ++it )
638 if ( it.current()->isWidgetType() )
639 res = ((QWidget*)it.current())->isVisibleTo( wid );