kexi

KexiStartupFileDialog.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003-2005 Jaroslaw Staniek <js@iidea.pl>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "KexiStartupFileDialog.h"
00021 
00022 #include <kexidb/driver.h>
00023 #include <core/kexi.h>
00024 #include <kexiutils/utils.h>
00025 
00026 #include <qlayout.h>
00027 #include <qobjectlist.h>
00028 #include <qpushbutton.h>
00029 #include <qapplication.h>
00030 
00031 #include <kmessagebox.h>
00032 #include <klocale.h>
00033 #include <kdebug.h>
00034 #include <kmimetype.h>
00035 #include <kfile.h>
00036 #include <kurlcombobox.h>
00037 
00038 KexiStartupFileDialog::KexiStartupFileDialog(
00039         const QString& startDirOrVariable, int mode,
00040         QWidget *parent, const char *name)
00041     :  KexiStartupFileDialogBase(startDirOrVariable, "", parent, name, 0)
00042     , m_confirmOverwrites(true)
00043     , m_filtersUpdated(false)
00044 {
00045     setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
00046     setMode( mode );
00047     
00048     QPoint point( 0, 0 );
00049     reparent( parentWidget(), point );
00050 
00051     if (layout())
00052         layout()->setMargin(0);
00053     setMinimumHeight(100);
00054     setSizeGripEnabled ( false );
00055 
00056     //dirty hack to customize filedialog view:
00057     {
00058         QObjectList *l = queryList( "QPushButton" );
00059         QObjectListIt it( *l );
00060         QObject *obj;
00061         while ( (obj = it.current()) != 0 ) {
00062             ++it;
00063             static_cast<QPushButton*>(obj)->hide();
00064         }
00065         delete l;
00066     }
00067     {
00068         QObjectList *l = queryList("QWidget");
00069         QObjectListIt it( *l );
00070         QObject *obj;
00071         while ( (obj = it.current()) != 0 ) {
00072             ++it;
00073             static_cast<QWidget*>(obj)->installEventFilter(this);
00074         }
00075         delete l;
00076     }   
00077     
00078 #ifdef Q_WS_WIN
00079     if (startDirOrVariable.startsWith(":"))
00080         m_lastVisitedPathsVariable = startDirOrVariable; //store for later use
00081 #else
00082     toggleSpeedbar(false);
00083     setFocusProxy( locationEdit );//locationWidget() );
00084 #endif
00085 }
00086 
00087 KexiStartupFileDialog::~KexiStartupFileDialog()
00088 {
00089 #ifdef Q_WS_WIN
00090     saveLastVisitedPath(currentFileName());
00091 #endif
00092 }
00093 
00094 void KexiStartupFileDialog::setMode(int mode)
00095 {
00096     //delayed
00097     m_mode = mode;
00098     m_filtersUpdated = false;
00099 }
00100 
00101 QStringList KexiStartupFileDialog::additionalFilters() const
00102 {
00103     return m_additionalMimeTypes;
00104 }
00105 
00106 void KexiStartupFileDialog::setAdditionalFilters(const QStringList &mimeTypes)
00107 {
00108     //delayed
00109     m_additionalMimeTypes = mimeTypes;
00110     m_filtersUpdated = false;
00111 }
00112 
00113 QStringList KexiStartupFileDialog::excludedFilters() const
00114 {
00115     return m_excludedMimeTypes;
00116 }
00117 
00118 void KexiStartupFileDialog::setExcludedFilters(const QStringList &mimeTypes)
00119 {
00120     //delayed
00121     m_excludedMimeTypes = mimeTypes;
00122     m_filtersUpdated = false;
00123 }
00124 
00125 void KexiStartupFileDialog::updateFilters()
00126 {
00127     if (m_filtersUpdated)
00128         return;
00129     m_filtersUpdated = true;
00130 
00131     m_lastFileName = QString::null;
00132 //  m_lastUrl = KURL();
00133 
00134     clearFilter();
00135     
00136     QString filter;
00137     KMimeType::Ptr mime;
00138     QStringList allfilters;
00139 
00140     const bool normalOpeningMode = m_mode & Opening && !(m_mode & Custom);
00141     const bool normalSavingMode = m_mode & SavingFileBasedDB && !(m_mode & Custom);
00142 
00143     if (normalOpeningMode || normalSavingMode) {
00144         mime = KMimeType::mimeType( KexiDB::Driver::defaultFileBasedDriverMimeType() );
00145         if (mime && m_excludedMimeTypes.find(mime->name())==m_excludedMimeTypes.end()) {
00146             filter += KexiUtils::fileDialogFilterString(mime);
00147             allfilters += mime->patterns();
00148         }
00149     }
00150 #ifdef KEXI_SERVER_SUPPORT
00151     if (normalOpeningMode || m_mode & SavingServerBasedDB) {
00152         mime = KMimeType::mimeType("application/x-kexiproject-shortcut");
00153         if (mime && m_excludedMimeTypes.find(mime->name())==m_excludedMimeTypes.end()) {
00154             filter += KexiUtils::fileDialogFilterString(mime);
00155             allfilters += mime->patterns();
00156         }
00157     }
00158     if (normalOpeningMode || m_mode & SavingServerBasedDB) {
00159         mime = KMimeType::mimeType("application/x-kexi-connectiondata");
00160         if (mime && m_excludedMimeTypes.find(mime->name())==m_excludedMimeTypes.end()) {
00161             filter += KexiUtils::fileDialogFilterString(mime);
00162             allfilters += mime->patterns();
00163         }
00164     }
00165 #endif
00166 
00168     if (normalOpeningMode) {
00169         mime = KMimeType::mimeType("application/x-msaccess");
00170         if (mime && m_excludedMimeTypes.find(mime->name())==m_excludedMimeTypes.end()) {
00171             filter += KexiUtils::fileDialogFilterString(mime);
00172             allfilters += mime->patterns();
00173         }
00174     }
00175 
00176     foreach (QStringList::ConstIterator, it, m_additionalMimeTypes) {
00177         if (*it == "all/allfiles")
00178             continue;
00179         if (m_excludedMimeTypes.find(*it)!=m_excludedMimeTypes.end())
00180             continue;
00181         filter += KexiUtils::fileDialogFilterString(*it);
00182         mime = KMimeType::mimeType(*it);
00183         allfilters += mime->patterns();
00184     }
00185 
00186     if (m_excludedMimeTypes.find("all/allfiles")==m_excludedMimeTypes.end())
00187         filter += KexiUtils::fileDialogFilterString("all/allfiles");
00188 //  mime = KMimeType::mimeType("all/allfiles");
00189 //  if (mime) {
00190 //      filter += QString(mime->patterns().isEmpty() ? "*" : mime->patterns().join(" ")) 
00191 //          + "|" + mime->comment()+ " (*)\n";
00192 //  }
00193     //remove duplicates made because upper- and lower-case extenstions are used:
00194     QStringList allfiltersUnique;
00195     QDict<char> uniqueDict(499, false);
00196     foreach (QStringList::ConstIterator, it, allfilters) {
00197 //      kdDebug() << *it << endl;
00198         uniqueDict.insert(*it, (char*)1);
00199     }
00200     foreach_dict (QDictIterator<char>, it, uniqueDict) {
00201         allfiltersUnique += it.currentKey();
00202     }
00203     allfiltersUnique.sort();
00204     
00205     if (allfiltersUnique.count()>1) {//prepend "all supoported files" entry
00206         filter.prepend(allfilters.join(" ")+"|" + i18n("All Supported Files")
00207             +" ("+allfiltersUnique.join(" ")+")\n");
00208     }
00209     
00210     if (filter.right(1)=="\n")
00211         filter.truncate(filter.length()-1);
00212     setFilter(filter);
00213     
00214     if (m_mode & Opening) {
00215         KexiStartupFileDialogBase::setMode( KFile::ExistingOnly | KFile::LocalOnly | KFile::File );
00216         setOperationMode( KFileDialog::Opening );
00217     } else {
00218         KexiStartupFileDialogBase::setMode( KFile::LocalOnly | KFile::File );
00219         setOperationMode( KFileDialog::Saving );
00220     }
00221 }
00222 
00223 void KexiStartupFileDialog::show()
00224 {
00225     m_filtersUpdated = false;
00226     updateFilters();
00227     KexiStartupFileDialogBase::show();
00228 }
00229 
00230 //KURL KexiStartupFileDialog::currentURL()
00231 QString KexiStartupFileDialog::currentFileName()
00232 {
00233     setResult( QDialog::Accepted ); // selectedURL tests for it
00234     
00235 #ifdef Q_WS_WIN
00236 //  QString path = selectedFile();
00237     //js @todo
00238 //  kdDebug() << "selectedFile() == " << path << " '" << url().fileName() << "' " << m_lineEdit->text() << endl;
00239     QString path = dir()->absPath();
00240     if (!path.endsWith("/") && !path.endsWith("\\"))
00241         path.append("/");
00242   path += m_lineEdit->text();
00243 //  QString path = QFileInfo(selectedFile()).dirPath(true) + "/" + m_lineEdit->text();
00244 #else
00245 //  QString path = locationEdit->currentText().stripWhiteSpace(); //url.path().stripWhiteSpace(); that does not work, if the full path is not in the location edit !!!!!
00246     QString path=KexiStartupFileDialogBase::selectedURL().path();
00247     kdDebug() << "prev selectedURL() == " << path <<endl;
00248     kdDebug() << "locationEdit == " << locationEdit->currentText().stripWhiteSpace() <<endl;
00249     //make sure user-entered path is acceped:
00250     setSelection( locationEdit->currentText().stripWhiteSpace() );
00251     
00252     path=KexiStartupFileDialogBase::selectedURL().path();
00253     kdDebug() << "selectedURL() == " << path <<endl;
00254     
00255 #endif
00256     
00257     if (!currentFilter().isEmpty()) {
00258         if (m_mode & SavingFileBasedDB) {
00259             QStringList filters = QStringList::split(" ", currentFilter()); //.first().stripWhiteSpace();
00260             kdDebug()<< " filter == " << filters << endl;
00261             QString ext = QFileInfo(path).extension(false);
00262             bool hasExtension = false;
00263             for (QStringList::ConstIterator filterIt = filters.constBegin(); 
00264                 filterIt != filters.constEnd() && !hasExtension; ++filterIt)
00265             {
00266                 QString f( (*filterIt).stripWhiteSpace() );
00267                 hasExtension = !f.mid(2).isEmpty() && ext==f.mid(2);
00268             }
00269             if (!hasExtension) {
00270                 //no extension: add one
00271                 QString defaultExtension( m_defaultExtension );
00272                 if (defaultExtension.isEmpty())
00273                     defaultExtension = filters.first().stripWhiteSpace().mid(2); //first one
00274                 path+=(QString(".")+defaultExtension);
00275                 kdDebug() << "KexiStartupFileDialog::checkURL(): append extension, " << path << endl;
00276                 setSelection( path );
00277             }
00278         }
00279     }
00280     kdDebug() << "KexiStartupFileDialog::currentFileName() == " << path <<endl;
00281     return path;
00282 //  return KFileDialog::selectedURL();
00283 }
00284 
00285 //bool KexiStartupFileDialog::checkURL()
00286 bool KexiStartupFileDialog::checkFileName()
00287 {
00288 //  KURL url = currentURL();
00289 //  QString path = url.path().stripWhiteSpace();
00290     QString path = currentFileName().stripWhiteSpace();
00291     
00292 //  if (url.fileName().stripWhiteSpace().isEmpty()) {
00293     if (path.isEmpty()) {
00294         KMessageBox::error( this, i18n( "Enter a filename." ));
00295         return false;
00296     }
00297     
00298     kdDebug() << "KexiStartupFileDialog::checkURL() path: " << path  << endl;
00299 //  kdDebug() << "KexiStartupFileDialog::checkURL() fname: " << url.fileName() << endl;
00300 //todo  if ( url.isLocalFile() ) {
00301         QFileInfo fi(path);
00302         if (mode() & KFile::ExistingOnly) {
00303             if ( !fi.exists() ) {
00304                 KMessageBox::error( this, "<qt>"+i18n( "The file \"%1\" does not exist." )
00305                     .arg( QDir::convertSeparators(path) ) );
00306                 return false;
00307             }
00308             else if (mode() & KFile::File) {
00309                 if (!fi.isFile()) {
00310                     KMessageBox::error( this, "<qt>"+i18n( "Enter a filename." ) );
00311                     return false;
00312                 }
00313                 else if (!fi.isReadable()) {
00314                     KMessageBox::error( this, "<qt>"+i18n( "The file \"%1\" is not readable." )
00315                         .arg( QDir::convertSeparators(path) ) );
00316                     return false;
00317                 }
00318             }
00319         }
00320         else if (m_confirmOverwrites && fi.exists()) {
00321             if (KMessageBox::Yes!=KMessageBox::warningYesNo( this, i18n( "The file \"%1\" already exists.\n"
00322             "Do you want to overwrite it?").arg( QDir::convertSeparators(path) ), QString::null, i18n("Overwrite"), KStdGuiItem::cancel() )) {
00323                 return false;
00324             }
00325         }
00326 //  }
00327     return true;
00328 }
00329 
00330 void KexiStartupFileDialog::accept()
00331 {
00332 //  locationEdit->setFocus();
00333 //  QKeyEvent ev(QEvent::KeyPress, Qt::Key_Enter, '\n', 0);
00334 //  QApplication::sendEvent(locationEdit, &ev);
00335 //  QApplication::postEvent(locationEdit, &ev);
00336     
00337 //  kdDebug() << "KexiStartupFileDialog::accept() m_lastUrl == " << m_lastUrl.path() << endl;
00338 //  if (m_lastUrl.path()==currentURL().path()) {//(js) to prevent more multiple kjob signals (i dont know why this is)
00339     if (m_lastFileName==currentFileName()) {//(js) to prevent more multiple kjob signals (i dont know why this is)
00340 //      m_lastUrl=KURL();
00341         m_lastFileName=QString::null;
00342         kdDebug() << "m_lastFileName==currentFileName()" << endl;
00343 #ifdef Q_WS_WIN
00344         return;
00345 #endif
00346     }
00347 //  kdDebug() << "KexiStartupFileDialog::accept(): url = " << currentURL().path() << " " << endl;
00348     kdDebug() << "KexiStartupFileDialog::accept(): path = " << currentFileName() << endl;
00349 //  if ( checkURL() ) {
00350     if ( checkFileName() ) {
00351         emit accepted();
00352     }
00353 //  else {
00354 //      m_lastUrl = KURL();
00355 //  }
00356 //  m_lastUrl = currentURL();
00357     m_lastFileName = currentFileName();
00358 
00359 #ifdef Q_WS_WIN
00360     saveLastVisitedPath(m_lastFileName);
00361 #endif
00362 }
00363 
00364 void KexiStartupFileDialog::reject()
00365 {
00366     kdDebug() << "KexiStartupFileDialog: reject!" << endl;
00367     emit rejected();
00368 }
00369 
00370 /*#ifndef Q_WS_WIN
00371 KURLComboBox *KexiStartupFileDialog::locationWidget() const
00372 {
00373     return locationEdit;
00374 }
00375 #endif
00376 */
00377 
00378 void KexiStartupFileDialog::setLocationText(const QString& fn)
00379 {
00380 #ifdef Q_WS_WIN
00381     //js @todo
00382     setSelection(fn);
00383 #else
00384     setSelection(fn);
00385 //  locationEdit->setCurrentText(fn);
00386 //  locationEdit->lineEdit()->setEdited( true );
00387 //  setSelection(fn);
00388 #endif
00389 }
00390 
00391 void KexiStartupFileDialog::setFocus()
00392 {
00393 #ifdef Q_WS_WIN
00394     m_lineEdit->setFocus();
00395 #else
00396     locationEdit->setFocus();
00397 #endif
00398 }
00399 
00400 bool KexiStartupFileDialog::eventFilter ( QObject * watched, QEvent * e )
00401 {
00402     //filter-out ESC key
00403     if (e->type()==QEvent::KeyPress && static_cast<QKeyEvent*>(e)->key()==Qt::Key_Escape
00404      && static_cast<QKeyEvent*>(e)->state()==Qt::NoButton) {
00405         static_cast<QKeyEvent*>(e)->accept();
00406         emit rejected();
00407         return true;
00408     }
00409     return KexiStartupFileDialogBase::eventFilter(watched,e);
00410 } 
00411 
00412 #include "KexiStartupFileDialog.moc"
00413 
KDE Home | KDE Accessibility Home | Description of Access Keys