1 // File: QtxPathDialog.cxx
2 // Author: Sergey TELKOV
4 #include "QtxPathDialog.h"
6 #include "QtxGroupBox.h"
12 #include <qlineedit.h>
13 #include <qfileinfo.h>
14 #include <qobjectlist.h>
15 #include <qstringlist.h>
16 #include <qfiledialog.h>
17 #include <qmessagebox.h>
18 #include <qpushbutton.h>
20 static const char* open_icon[] = {
45 //================================================================
46 // Function : QtxPathDialog
47 // Purpose : Constructor.
48 //================================================================
50 QtxPathDialog::QtxPathDialog( const bool import, QWidget* parent, const bool modal, const bool resize, const int buttons, WFlags f )
51 : QtxDialog( parent, 0, modal, resize, buttons, f ),
58 setCaption( tr( import ? "Open file" : "Save file" ) );
60 setDefaultEntry( createFileEntry( tr( "File name" ), import ? OpenFile : SaveFile ) );
61 QLineEdit* le = fileEntry( defaultEntry() );
63 le->setMinimumWidth( 200 );
70 //================================================================
71 // Function : QtxPathDialog
72 // Purpose : Constructor.
73 //================================================================
75 QtxPathDialog::QtxPathDialog( QWidget* parent, const bool modal, const bool resize, const int buttons, WFlags f )
76 : QtxDialog( parent, 0, modal, resize, buttons, f ),
84 //================================================================
85 // Function : ~QtxPathDialog
86 // Purpose : Destructor.
87 //================================================================
89 QtxPathDialog::~QtxPathDialog()
93 //================================================================
94 // Function : fileName
96 //================================================================
98 QString QtxPathDialog::fileName() const
100 return fileName( defaultEntry() );
103 //================================================================
104 // Function : setFileName
106 //================================================================
108 void QtxPathDialog::setFileName( const QString& txt, const bool autoExtension )
110 setFileName( defaultEntry(), txt, autoExtension );
113 //================================================================
116 //================================================================
118 QString QtxPathDialog::filter() const
123 //================================================================
124 // Function : setFilter
126 //================================================================
128 void QtxPathDialog::setFilter( const QString& fltr )
133 //================================================================
136 //================================================================
138 void QtxPathDialog::show()
140 if ( hasVisibleChildren( myEntriesFrame ) )
141 myEntriesFrame->show();
143 myEntriesFrame->hide();
145 if ( hasVisibleChildren( myOptionsFrame ) )
146 myOptionsFrame->show();
148 myOptionsFrame->hide();
153 //================================================================
154 // Function : onBrowse
156 //================================================================
158 void QtxPathDialog::onBrowse()
160 const QObject* obj = sender();
164 for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && id == -1; ++it )
165 if ( it.data().btn == obj )
171 FileEntry& entry = myEntries[id];
173 bool isDir = entry.mode != OpenFile && entry.mode != SaveFile;
177 entry.dlg = new QFileDialog( QDir::current().path(), QString::null, this, 0, true );
178 entry.dlg->setCaption( caption() );
179 switch ( entry.mode )
185 entry.dlg->setMode( QFileDialog::DirectoryOnly );
188 entry.dlg->setMode( QFileDialog::AnyFile );
192 entry.dlg->setMode( QFileDialog::ExistingFile );
198 entry.dlg->setFilters( prepareFilters() );
199 entry.dlg->setSelection( fileName( id ) );
201 if ( entry.dlg->exec() != Accepted )
204 QString fName = entry.dlg->selectedFile();
206 if ( fName.isEmpty() )
209 if ( QFileInfo( fName ).extension().isEmpty() && !isDir )
210 fName = autoExtension( fName, entry.dlg->selectedFilter() );
212 fName = QDir::convertSeparators( fName );
213 QString prev = QDir::convertSeparators( fileName( id ) );
216 while ( prev.length() && prev.at( prev.length() - 1 ) == QDir::separator() )
217 prev.remove( prev.length() - 1, 1 );
218 while ( fName.length() && fName.at( fName.length() - 1 ) == QDir::separator() )
219 fName.remove( fName.length() - 1, 1 );
225 setFileName( id, fName );
226 fileNameChanged( id, fName );
228 if ( id == defaultEntry() )
229 emit fileNameChanged( fName );
232 //================================================================
233 // Function : onReturnPressed
235 //================================================================
237 void QtxPathDialog::onReturnPressed()
239 const QObject* obj = sender();
242 for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && id == -1; ++it )
243 if ( it.data().edit == obj )
249 fileNameChanged( id, fileName( id ) );
251 if ( id == defaultEntry() )
252 emit fileNameChanged( fileName() );
255 //================================================================
256 // Function : onTextChanged
258 //================================================================
260 void QtxPathDialog::onTextChanged( const QString& )
265 //================================================================
266 // Function : validate
268 //================================================================
270 void QtxPathDialog::validate()
272 setButtonEnabled( isValid(), OK | Yes );
275 //================================================================
276 // Function : isValid
278 //================================================================
280 bool QtxPathDialog::isValid()
283 for ( FileEntryMap::Iterator it = myEntries.begin(); it != myEntries.end() && ok; ++it )
284 if ( it.data().edit->isEnabled() )
285 ok = !it.data().edit->text().stripWhiteSpace().isEmpty();
290 //================================================================
291 // Function : acceptData
293 //================================================================
295 bool QtxPathDialog::acceptData() const
299 QWidget* parent = (QWidget*)this;
301 FileEntryMap::ConstIterator it;
302 for ( it = myEntries.begin(); it != myEntries.end() && ok; ++it )
304 const FileEntry& entry = it.data();
305 QFileInfo fileInfo( entry.edit->text() );
306 if ( entry.edit->text().isEmpty() )
308 QMessageBox::critical( parent, caption(), tr( "File name not specified" ),
309 QMessageBox::Ok, QMessageBox::NoButton );
312 else switch ( entry.mode )
315 if ( !fileInfo.exists() )
317 QMessageBox::critical( parent, caption(), tr( "File \"%1\" does not exist" ).arg( fileInfo.filePath() ),
318 QMessageBox::Ok, QMessageBox::NoButton );
323 if ( fileInfo.exists() )
324 ok = QMessageBox::warning( parent, caption(), tr( "File \"%1\" already exist. Do you want to overwrite it?" ).arg( fileInfo.filePath() ),
325 QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes;
328 if ( !fileInfo.exists() || !fileInfo.isDir() )
330 QMessageBox::critical( parent, caption(), tr( "Directory \"%1\" does not exist" ).arg( fileInfo.filePath() ),
331 QMessageBox::Ok, QMessageBox::NoButton );
336 if ( fileInfo.exists() && !fileInfo.isDir() )
338 QMessageBox::critical( parent, caption(), tr( "Directory \"%1\" can't be created because file with the same name exist" ).arg( fileInfo.filePath() ),
339 QMessageBox::Ok, QMessageBox::NoButton );
344 if ( fileInfo.exists() )
346 if ( !fileInfo.isDir() )
348 QMessageBox::critical( parent, caption(), tr( "Directory \"%1\" can't be created because file with the same name exist" ).arg( fileInfo.filePath() ),
349 QMessageBox::Ok, QMessageBox::NoButton );
352 else if ( QDir( fileInfo.filePath() ).count() > 2 )
353 ok = QMessageBox::warning( parent, caption(), tr( "Directory \"%1\" not empty. Do you want to remove all files in this directory?" ).arg( fileInfo.filePath() ),
354 QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes;
362 entry.edit->setFocus();
368 //================================================================
369 // Function : fileNameChanged
371 //================================================================
373 void QtxPathDialog::fileNameChanged( int, QString )
377 //================================================================
378 // Function : optionsFrame
380 //================================================================
382 QFrame* QtxPathDialog::optionsFrame()
384 return myOptionsFrame;
387 //================================================================
388 // Function : getFileName
390 //================================================================
392 QString QtxPathDialog::fileName( const int id ) const
395 if ( myEntries.contains( id ) )
396 res = myEntries[id].edit->text();
401 //================================================================
402 // Function : setFileName
404 //================================================================
406 void QtxPathDialog::setFileName( const int id, const QString& txt, const bool autoExt )
409 QLineEdit* le = fileEntry( id, mode );
413 if ( autoExt && ( mode == OpenFile || mode == SaveFile ) )
414 le->setText( autoExtension( txt ) );
420 //================================================================
421 // Function : fileEntry
423 //================================================================
425 QLineEdit* QtxPathDialog::fileEntry( const int id ) const
428 if ( myEntries.contains( id ) )
429 le = myEntries[id].edit;
434 //================================================================
435 // Function : fileEntry
437 //================================================================
439 QLineEdit* QtxPathDialog::fileEntry( const int theId, int& theMode ) const
442 if ( myEntries.contains( theId ) )
444 le = myEntries[theId].edit;
445 theMode = myEntries[theId].mode;
451 //================================================================
452 // Function : createFileEntry
454 //================================================================
456 int QtxPathDialog::createFileEntry( const QString& lab, const int mode, const int id )
462 while ( myEntries.contains( num ) )
470 new QLabel( lab, myEntriesFrame );
471 entry.edit = new QLineEdit( myEntriesFrame );
472 entry.btn = new QPushButton( myEntriesFrame );
473 entry.btn->setAutoDefault( false );
474 entry.btn->setPixmap( QPixmap( open_icon ) );
476 connect( entry.btn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
477 connect( entry.edit, SIGNAL( returnPressed() ), this, SLOT( onReturnPressed() ) );
478 connect( entry.edit, SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
480 myEntries.insert( num, entry );
485 //================================================================
486 // Function : defaultEntry
488 //================================================================
490 int QtxPathDialog::defaultEntry() const
495 //================================================================
496 // Function : setDefaultEntry
498 //================================================================
500 void QtxPathDialog::setDefaultEntry( const int id )
505 //================================================================
506 // Function : initialize
508 //================================================================
510 void QtxPathDialog::initialize()
512 setCaption( tr( "File dialog" ) );
514 QVBoxLayout* main = new QVBoxLayout( mainFrame() );
515 QtxGroupBox* mainGroup = new QtxGroupBox( 1, Qt::Horizontal, "", mainFrame() );
516 mainGroup->setFrameStyle( QFrame::NoFrame );
517 mainGroup->setInsideMargin( 0 );
518 main->addWidget( mainGroup );
520 myEntriesFrame = new QGroupBox( 3, Qt::Horizontal, "", mainGroup );
521 myOptionsFrame = new QFrame( mainGroup );
524 //================================================================
525 // Function : prepareFilters
527 //================================================================
529 QStringList QtxPathDialog::prepareFilters() const
532 if ( !myFilter.isEmpty() )
534 res = QStringList::split( ";;", myFilter );
535 bool allFilter = false;
536 for ( QStringList::ConstIterator it = res.begin(); it != res.end() && !allFilter; ++it )
538 QStringList wildCards = filterWildCards( *it );
539 allFilter = wildCards.findIndex( "*.*" ) != -1;
543 res.append( tr( "All files (*.*)" ) );
549 //================================================================
550 // Function : filterWildCards
552 //================================================================
554 QStringList QtxPathDialog::filterWildCards( const QString& theFilter ) const
558 int b = theFilter.findRev( "(" );
559 int e = theFilter.findRev( ")" );
560 if ( b != -1 && e != -1 )
562 QString content = theFilter.mid( b + 1, e - b - 1 ).stripWhiteSpace();
563 QStringList lst = QStringList::split( " ", content );
564 for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
565 if ( (*it).find( "." ) != -1 )
566 res.append( (*it).stripWhiteSpace() );
571 //================================================================
572 // Function : autoExtension
574 //================================================================
576 QString QtxPathDialog::autoExtension( const QString& theFileName, const QString& theFilter ) const
578 QString fName = theFileName;
580 if ( fName.isEmpty() )
583 QString filter = theFilter;
584 if ( filter.isEmpty() )
586 QStringList filters = prepareFilters();
587 if ( !filters.isEmpty() )
588 filter = filters.first();
591 QStringList wildCards = filterWildCards( filter );
592 if ( !wildCards.isEmpty() )
594 QString ext = wildCards.first();
595 if ( ext.find( "." ) != -1 )
596 ext = ext.mid( ext.find( "." ) + 1 );
598 if ( !ext.isEmpty() && !ext.contains( "*" ) )
599 fName = QDir::convertSeparators( fName ) + QString( "." ) + ext;
605 //================================================================
606 // Function : hasVisibleChildren
608 //================================================================
610 bool QtxPathDialog::hasVisibleChildren( QWidget* wid ) const
615 const QObjectList* aChildren = wid->children();
618 for ( QObjectListIt it( *aChildren ); it.current() && !res; ++it )
620 if ( it.current()->isWidgetType() )
621 res = ((QWidget*)it.current())->isVisibleTo( wid );