kio Library API Documentation

kdiroperator.cpp

00001 /* This file is part of the KDE libraries
00002     Copyright (C) 1999,2000 Stephan Kulow <coolo@kde.org>
00003                   1999,2000,2001 Carsten Pfeiffer <pfeiffer@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018     Boston, MA 02111-1307, USA.
00019 */
00020 
00021 #include <unistd.h>
00022 
00023 #include <qdir.h>
00024 #include <qapplication.h>
00025 #include <qdialog.h>
00026 #include <qlabel.h>
00027 #include <qlayout.h>
00028 #include <qpushbutton.h>
00029 #include <qpopupmenu.h>
00030 #include <qregexp.h>
00031 #include <qtimer.h>
00032 #include <qvbox.h>
00033 
00034 #include <kaction.h>
00035 #include <kapplication.h>
00036 #include <kdebug.h>
00037 #include <kdialog.h>
00038 #include <kdialogbase.h>
00039 #include <kdirlister.h>
00040 #include <klineeditdlg.h>
00041 #include <klocale.h>
00042 #include <kmessagebox.h>
00043 #include <kpopupmenu.h>
00044 #include <kprogress.h>
00045 #include <kstdaction.h>
00046 #include <kio/job.h>
00047 #include <kio/jobclasses.h>
00048 #include <kio/netaccess.h>
00049 #include <kio/previewjob.h>
00050 #include <kpropertiesdialog.h>
00051 #include <kservicetypefactory.h>
00052 #include <kstdaccel.h>
00053 
00054 #include "config-kfile.h"
00055 #include "kcombiview.h"
00056 #include "kdiroperator.h"
00057 #include "kfiledetailview.h"
00058 #include "kfileiconview.h"
00059 #include "kfilepreview.h"
00060 #include "kfileview.h"
00061 #include "kfileitem.h"
00062 #include "kimagefilepreview.h"
00063 
00064 
00065 template class QPtrStack<KURL>;
00066 template class QDict<KFileItem>;
00067 
00068 
00069 class KDirOperator::KDirOperatorPrivate
00070 {
00071 public:
00072     KDirOperatorPrivate() {
00073         onlyDoubleClickSelectsFiles = false;
00074         progressDelayTimer = 0L;
00075         dirHighlighting = false;
00076         config = 0L;
00077     }
00078 
00079     ~KDirOperatorPrivate() {
00080         delete progressDelayTimer;
00081     }
00082 
00083     bool dirHighlighting;
00084     QString lastURL; // used for highlighting a directory on cdUp
00085     bool onlyDoubleClickSelectsFiles;
00086     QTimer *progressDelayTimer;
00087     KActionSeparator *viewActionSeparator;
00088 
00089     KConfig *config;
00090     QString configGroup;
00091 };
00092 
00093 KDirOperator::KDirOperator(const KURL& _url,
00094                            QWidget *parent, const char* _name)
00095     : QWidget(parent, _name),
00096       dir(0),
00097       m_fileView(0),
00098       progress(0)
00099 {
00100     myPreview = 0L;
00101     myMode = KFile::File;
00102     m_viewKind = KFile::Simple;
00103     mySorting = static_cast<QDir::SortSpec>(QDir::Name | QDir::DirsFirst);
00104     d = new KDirOperatorPrivate;
00105 
00106     if (_url.isEmpty()) { // no dir specified -> current dir
00107         QString strPath = QDir::currentDirPath();
00108         strPath.append('/');
00109         currUrl = KURL();
00110         currUrl.setProtocol(QString::fromLatin1("file"));
00111         currUrl.setPath(strPath);
00112     }
00113     else {
00114         currUrl = _url;
00115         if ( currUrl.protocol().isEmpty() )
00116             currUrl.setProtocol(QString::fromLatin1("file"));
00117 
00118         currUrl.addPath("/"); // make sure we have a trailing slash!
00119     }
00120 
00121     setDirLister( new KDirLister( true ) );
00122 
00123     connect(&myCompletion, SIGNAL(match(const QString&)),
00124             SLOT(slotCompletionMatch(const QString&)));
00125 
00126     progress = new KProgress(this, "progress");
00127     progress->adjustSize();
00128     progress->move(2, height() - progress->height() -2);
00129 
00130     d->progressDelayTimer = new QTimer( this, "progress delay timer" );
00131     connect( d->progressDelayTimer, SIGNAL( timeout() ),
00132          SLOT( slotShowProgress() ));
00133 
00134     myCompleteListDirty = false;
00135 
00136     backStack.setAutoDelete( true );
00137     forwardStack.setAutoDelete( true );
00138 
00139     // action stuff
00140     setupActions();
00141     setupMenu();
00142 
00143     setFocusPolicy(QWidget::WheelFocus);
00144 }
00145 
00146 KDirOperator::~KDirOperator()
00147 {
00148     resetCursor();
00149     if ( m_fileView )
00150     {
00151         if ( d->config )
00152             m_fileView->writeConfig( d->config, d->configGroup );
00153         
00154     delete m_fileView;
00155     m_fileView = 0L;
00156     }
00157     
00158     delete myPreview;
00159     delete dir;
00160     delete d;
00161 }
00162 
00163 
00164 void KDirOperator::setSorting( QDir::SortSpec spec )
00165 {
00166     if ( m_fileView )
00167         m_fileView->setSorting( spec );
00168     mySorting = spec;
00169     updateSortActions();
00170 }
00171 
00172 void KDirOperator::resetCursor()
00173 {
00174     QApplication::restoreOverrideCursor();
00175     progress->hide();
00176 }
00177 
00178 void KDirOperator::insertViewDependentActions()
00179 {
00180     // If we have a new view actionCollection(), insert its actions
00181     //  into viewActionMenu.
00182 
00183     if( m_fileView && viewActionCollection != m_fileView->actionCollection() )
00184     {
00185         viewActionCollection = m_fileView->actionCollection();
00186 
00187         if ( !viewActionCollection->isEmpty() ) {
00188             viewActionMenu->insert( d->viewActionSeparator );
00189 
00190             for ( uint i = 0; i < viewActionCollection->count(); i++ )
00191                 viewActionMenu->insert( viewActionCollection->action( i ));
00192         }
00193 
00194         connect( viewActionCollection, SIGNAL( inserted( KAction * )),
00195                  SLOT( slotViewActionAdded( KAction * )));
00196         connect( viewActionCollection, SIGNAL( removed( KAction * )),
00197                  SLOT( slotViewActionRemoved( KAction * )));
00198     }
00199 }
00200 
00201 void KDirOperator::activatedMenu( const KFileItem *, const QPoint& pos )
00202 {
00203     updateSelectionDependentActions();
00204 
00205     actionMenu->popup( pos );
00206 }
00207 
00208 void KDirOperator::updateSelectionDependentActions()
00209 {
00210     bool hasSelection = m_fileView && m_fileView->selectedItems() &&
00211                         !m_fileView->selectedItems()->isEmpty();
00212     myActionCollection->action( "delete" )->setEnabled( hasSelection );
00213     myActionCollection->action( "properties" )->setEnabled( hasSelection );
00214 }
00215 
00216 void KDirOperator::setPreviewWidget(const QWidget *w)
00217 {
00218     if(w != 0L)
00219         m_viewKind = (m_viewKind | KFile::PreviewContents);
00220     else
00221         m_viewKind = (m_viewKind & ~KFile::PreviewContents);
00222 
00223     delete myPreview;
00224     myPreview = w;
00225 
00226     KToggleAction *preview = static_cast<KToggleAction*>(myActionCollection->action("preview"));
00227     preview->setEnabled( w != 0L );
00228     preview->setChecked( w != 0L );
00229     setView( static_cast<KFile::FileView>(m_viewKind) );
00230 }
00231 
00232 int KDirOperator::numDirs() const
00233 {
00234     return m_fileView ? m_fileView->numDirs() : 0;
00235 }
00236 
00237 int KDirOperator::numFiles() const
00238 {
00239     return m_fileView ? m_fileView->numFiles() : 0;
00240 }
00241 
00242 void KDirOperator::slotDetailedView()
00243 {
00244     KFile::FileView view = static_cast<KFile::FileView>( (m_viewKind & ~KFile::Simple) | KFile::Detail );
00245     setView( view );
00246 }
00247 
00248 void KDirOperator::slotSimpleView()
00249 {
00250     KFile::FileView view = static_cast<KFile::FileView>( (m_viewKind & ~KFile::Detail) | KFile::Simple );
00251     setView( view );
00252 }
00253 
00254 void KDirOperator::slotToggleHidden( bool show )
00255 {
00256     dir->setShowingDotFiles( show );
00257     updateDir();
00258     if ( m_fileView )
00259         m_fileView->listingCompleted();
00260 }
00261 
00262 void KDirOperator::slotSeparateDirs()
00263 {
00264     if (separateDirsAction->isChecked())
00265     {
00266         KFile::FileView view = static_cast<KFile::FileView>( m_viewKind | KFile::SeparateDirs );
00267         setView( view );
00268     }
00269     else
00270     {
00271         KFile::FileView view = static_cast<KFile::FileView>( m_viewKind & ~KFile::SeparateDirs );
00272         setView( view );
00273     }
00274 }
00275 
00276 void KDirOperator::slotDefaultPreview()
00277 {
00278     m_viewKind = m_viewKind | KFile::PreviewContents;
00279     if ( !myPreview ) {
00280         myPreview = new KImageFilePreview( this );
00281         (static_cast<KToggleAction*>( myActionCollection->action("preview") ))->setChecked(true);
00282     }
00283 
00284     setView( static_cast<KFile::FileView>(m_viewKind) );
00285 }
00286 
00287 void KDirOperator::slotSortByName()
00288 {
00289     int sorting = (m_fileView->sorting()) & ~QDir::SortByMask;
00290     m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Name ));
00291     mySorting = m_fileView->sorting();
00292     caseInsensitiveAction->setEnabled( true );
00293 }
00294 
00295 void KDirOperator::slotSortBySize()
00296 {
00297     int sorting = (m_fileView->sorting()) & ~QDir::SortByMask;
00298     m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Size ));
00299     mySorting = m_fileView->sorting();
00300     caseInsensitiveAction->setEnabled( false );
00301 }
00302 
00303 void KDirOperator::slotSortByDate()
00304 {
00305     int sorting = (m_fileView->sorting()) & ~QDir::SortByMask;
00306     m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Time ));
00307     mySorting = m_fileView->sorting();
00308     caseInsensitiveAction->setEnabled( false );
00309 }
00310 
00311 void KDirOperator::slotSortReversed()
00312 {
00313     if ( m_fileView )
00314         m_fileView->sortReversed();
00315 }
00316 
00317 void KDirOperator::slotToggleDirsFirst()
00318 {
00319     QDir::SortSpec sorting = m_fileView->sorting();
00320     if ( !KFile::isSortDirsFirst( sorting ) )
00321         m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::DirsFirst ));
00322     else
00323         m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting & ~QDir::DirsFirst));
00324     mySorting = m_fileView->sorting();
00325 }
00326 
00327 void KDirOperator::slotToggleIgnoreCase()
00328 {
00329     QDir::SortSpec sorting = m_fileView->sorting();
00330     if ( !KFile::isSortCaseInsensitive( sorting ) )
00331         m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::IgnoreCase ));
00332     else
00333         m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting & ~QDir::IgnoreCase));
00334     mySorting = m_fileView->sorting();
00335 }
00336 
00337 void KDirOperator::mkdir()
00338 {
00339     KLineEditDlg dlg(i18n("Create new directory in:") +
00340                      QString::fromLatin1( "\n" ) + /* don't break i18n now*/
00341                      url().prettyURL(), i18n("New Directory"), this);
00342     dlg.setCaption(i18n("New Directory"));
00343     if (dlg.exec()) {
00344       mkdir( dlg.text(), true );
00345     }
00346 }
00347 
00348 bool KDirOperator::mkdir( const QString& directory, bool enterDirectory )
00349 {
00350     bool writeOk = false;
00351     KURL url( currUrl );
00352     url.addPath(directory);
00353 
00354     if ( url.isLocalFile() ) {
00355         // check if we are allowed to create local directories
00356         writeOk = checkAccess( url.path(), W_OK );
00357         if ( writeOk )
00358             writeOk = QDir().mkdir( url.path() );
00359     }
00360     else
00361         writeOk = KIO::NetAccess::mkdir( url );
00362 
00363     if ( !writeOk )
00364         KMessageBox::sorry(viewWidget(), i18n("You don't have permission to "
00365                                               "create that directory." ));
00366     else {
00367         if ( enterDirectory )
00368             setURL( url, true );
00369     }
00370 
00371     return writeOk;
00372 }
00373 
00374 KIO::DeleteJob * KDirOperator::del( const KFileItemList& items,
00375                                     bool ask, bool showProgress )
00376 {
00377     return del( items, this, ask, showProgress );
00378 }
00379 
00380 KIO::DeleteJob * KDirOperator::del( const KFileItemList& items,
00381                                     QWidget *parent,
00382                                     bool ask, bool showProgress )
00383 {
00384     if ( items.isEmpty() ) {
00385         KMessageBox::information( parent,
00386                                 i18n("You didn't select a file to delete."),
00387                                 i18n("Nothing to delete") );
00388         return 0L;
00389     }
00390 
00391     KURL::List urls;
00392     QStringList files;
00393     KFileItemListIterator it( items );
00394 
00395     for ( ; it.current(); ++it ) {
00396         KURL url = (*it)->url();
00397         urls.append( url );
00398         if ( url.isLocalFile() )
00399             files.append( url.path() );
00400         else
00401             files.append( url.prettyURL() );
00402     }
00403 
00404     bool doIt = !ask;
00405     if ( ask ) {
00406         int ret;
00407         if ( items.count() == 1 ) {
00408             ret = KMessageBox::warningContinueCancel( parent,
00409                 i18n( "<qt>Do you really want to delete\n <b>'%1'</b>?</qt>" )
00410                 .arg( files.first() ),
00411                                                       i18n("Delete File"),
00412                                                       i18n("Delete") );
00413         }
00414         else
00415             ret = KMessageBox::warningContinueCancelList( parent,
00416                 i18n("translators: not called for n == 1", "Do you really want to delete these %n items?", items.count() ),
00417                                                     files,
00418                                                     i18n("Delete Files"),
00419                                                     i18n("Delete") );
00420         doIt = (ret == KMessageBox::Continue);
00421     }
00422 
00423     if ( doIt ) {
00424         KIO::DeleteJob *job = KIO::del( urls, false, showProgress );
00425         job->setAutoErrorHandlingEnabled( true, parent );
00426         return job;
00427     }
00428 
00429     return 0L;
00430 }
00431 
00432 void KDirOperator::deleteSelected()
00433 {
00434     if ( !m_fileView )
00435         return;
00436 
00437     const KFileItemList *list = m_fileView->selectedItems();
00438     if ( list )
00439         del( *list );
00440 }
00441 
00442 void KDirOperator::close()
00443 {
00444     resetCursor();
00445     pendingMimeTypes.clear();
00446     myCompletion.clear();
00447     myDirCompletion.clear();
00448     myCompleteListDirty = true;
00449     dir->stop();
00450 }
00451 
00452 void KDirOperator::checkPath(const QString &, bool /*takeFiles*/) // SLOT
00453 {
00454 #if 0
00455     // copy the argument in a temporary string
00456     QString text = _txt;
00457     // it's unlikely to happen, that at the beginning are spaces, but
00458     // for the end, it happens quite often, I guess.
00459     text = text.stripWhiteSpace();
00460     // if the argument is no URL (the check is quite fragil) and it's
00461     // no absolute path, we add the current directory to get a correct url
00462     if (text.find(':') < 0 && text[0] != '/')
00463         text.insert(0, currUrl);
00464 
00465     // in case we have a selection defined and someone patched the file-
00466     // name, we check, if the end of the new name is changed.
00467     if (!selection.isNull()) {
00468         int position = text.findRev('/');
00469         ASSERT(position >= 0); // we already inserted the current dir in case
00470         QString filename = text.mid(position + 1, text.length());
00471         if (filename != selection)
00472             selection = QString::null;
00473     }
00474 
00475     KURL u(text); // I have to take care of entered URLs
00476     bool filenameEntered = false;
00477 
00478     if (u.isLocalFile()) {
00479         // the empty path is kind of a hack
00480         KFileItem i("", u.path());
00481         if (i.isDir())
00482             setURL(text, true);
00483         else {
00484             if (takeFiles)
00485                 if (acceptOnlyExisting && !i.isFile())
00486                     warning("you entered an invalid URL");
00487                 else
00488                     filenameEntered = true;
00489         }
00490     } else
00491         setURL(text, true);
00492 
00493     if (filenameEntered) {
00494         filename_ = u.url();
00495         emit fileSelected(filename_);
00496 
00497         QApplication::restoreOverrideCursor();
00498 
00499         accept();
00500     }
00501 #endif
00502     kdDebug(kfile_area) << "TODO KDirOperator::checkPath()" << endl;
00503 }
00504 
00505 void KDirOperator::setURL(const KURL& _newurl, bool clearforward)
00506 {
00507     KURL newurl;
00508 
00509     if ( _newurl.isMalformed() )
00510     newurl.setPath( QDir::homeDirPath() );
00511     else
00512     newurl = _newurl;
00513 
00514     QString pathstr = newurl.path(+1);
00515     newurl.setPath(pathstr);
00516 
00517     // already set
00518     if ( newurl.cmp( currUrl, true ) )
00519         return;
00520 
00521     if ( !isReadable( newurl ) ) {
00522         // maybe newurl is a file? check its parent directory
00523         newurl.cd(QString::fromLatin1(".."));
00524         if ( !isReadable( newurl ) ) {
00525             resetCursor();
00526             KMessageBox::error(viewWidget(),
00527                                i18n("The specified directory does not exist "
00528                                     "or was not readable."));
00529             return;
00530         }
00531     }
00532 
00533     if (clearforward) {
00534         // autodelete should remove this one
00535         backStack.push(new KURL(currUrl));
00536         forwardStack.clear();
00537     }
00538 
00539     d->lastURL = currUrl.url(-1);
00540     currUrl = newurl;
00541 
00542     pathChanged();
00543     emit urlEntered(newurl);
00544 
00545     // enable/disable actions
00546     forwardAction->setEnabled( !forwardStack.isEmpty() );
00547     backAction->setEnabled( !backStack.isEmpty() );
00548     upAction->setEnabled( !isRoot() );
00549 
00550     dir->openURL( newurl );
00551 }
00552 
00553 void KDirOperator::updateDir()
00554 {
00555     dir->emitChanges();
00556     if ( m_fileView )
00557         m_fileView->listingCompleted();
00558 }
00559 
00560 void KDirOperator::rereadDir()
00561 {
00562     pathChanged();
00563     dir->openURL( currUrl, false, true );
00564 }
00565 
00566 // Protected
00567 void KDirOperator::pathChanged()
00568 {
00569     if (!m_fileView)
00570         return;
00571 
00572     pendingMimeTypes.clear();
00573     m_fileView->clear();
00574     myCompletion.clear();
00575     myDirCompletion.clear();
00576 
00577     // it may be, that we weren't ready at this time
00578     QApplication::restoreOverrideCursor();
00579 
00580     // when KIO::Job emits finished, the slot will restore the cursor
00581     QApplication::setOverrideCursor( waitCursor );
00582 
00583     if ( !isReadable( currUrl )) {
00584         KMessageBox::error(viewWidget(),
00585                            i18n("The specified directory does not exist "
00586                                 "or was not readable."));
00587         if (backStack.isEmpty())
00588             home();
00589         else
00590             back();
00591     }
00592 }
00593 
00594 void KDirOperator::slotRedirected( const KURL& newURL )
00595 {
00596     currUrl = newURL;
00597     pendingMimeTypes.clear();
00598     myCompletion.clear();
00599     myDirCompletion.clear();
00600     myCompleteListDirty = true;
00601     emit urlEntered( newURL );
00602 }
00603 
00604 // Code pinched from kfm then hacked
00605 void KDirOperator::back()
00606 {
00607     if ( backStack.isEmpty() )
00608         return;
00609 
00610     forwardStack.push( new KURL(currUrl) );
00611 
00612     KURL *s = backStack.pop();
00613 
00614     setURL(*s, false);
00615     delete s;
00616 }
00617 
00618 // Code pinched from kfm then hacked
00619 void KDirOperator::forward()
00620 {
00621     if ( forwardStack.isEmpty() )
00622         return;
00623 
00624     backStack.push(new KURL(currUrl));
00625 
00626     KURL *s = forwardStack.pop();
00627     setURL(*s, false);
00628     delete s;
00629 }
00630 
00631 KURL KDirOperator::url() const
00632 {
00633     return currUrl;
00634 }
00635 
00636 void KDirOperator::cdUp()
00637 {
00638     KURL tmp( currUrl );
00639     tmp.cd(QString::fromLatin1(".."));
00640     setURL(tmp, true);
00641 }
00642 
00643 void KDirOperator::home()
00644 {
00645     setURL(QDir::homeDirPath(), true);
00646 }
00647 
00648 void KDirOperator::clearFilter()
00649 {
00650     dir->setNameFilter( QString::null );
00651     dir->clearMimeFilter();
00652     checkPreviewSupport();
00653 }
00654 
00655 void KDirOperator::setNameFilter(const QString& filter)
00656 {
00657     dir->setNameFilter(filter);
00658     checkPreviewSupport();
00659 }
00660 
00661 void KDirOperator::setMimeFilter( const QStringList& mimetypes )
00662 {
00663     dir->setMimeFilter( mimetypes );
00664     checkPreviewSupport();
00665 }
00666 
00667 bool KDirOperator::checkPreviewSupport()
00668 {
00669     KToggleAction *previewAction = static_cast<KToggleAction*>( myActionCollection->action( "preview" ));
00670 
00671     bool hasPreviewSupport = false;
00672     KConfig *kc = KGlobal::config();
00673     KConfigGroupSaver cs( kc, ConfigGroup );
00674     if ( kc->readBoolEntry( "Show Default Preview", true ) )
00675         hasPreviewSupport = checkPreviewInternal();
00676 
00677     previewAction->setEnabled( hasPreviewSupport );
00678     return hasPreviewSupport;
00679 }
00680 
00681 bool KDirOperator::checkPreviewInternal() const
00682 {
00683     QStringList supported = KIO::PreviewJob::supportedMimeTypes();
00684     // no preview support for directories?
00685     if ( dirOnlyMode() && supported.findIndex( "inode/directory" ) == -1 )
00686         return false;
00687 
00688     QStringList mimeTypes = dir->mimeFilters();
00689     QStringList nameFilter = QStringList::split( " ", dir->nameFilter() );
00690 
00691     if ( mimeTypes.isEmpty() && nameFilter.isEmpty() && !supported.isEmpty() )
00692         return true;
00693     else {
00694         QRegExp r;
00695         r.setWildcard( true ); // the "mimetype" can be "image/*"
00696 
00697         if ( !mimeTypes.isEmpty() ) {
00698             QStringList::Iterator it = supported.begin();
00699 
00700             for ( ; it != supported.end(); ++it ) {
00701                 r.setPattern( *it );
00702 
00703                 QStringList result = mimeTypes.grep( r );
00704                 if ( !result.isEmpty() ) { // matches! -> we want previews
00705                     return true;
00706                 }
00707             }
00708         }
00709 
00710         if ( !nameFilter.isEmpty() ) {
00711             // find the mimetypes of all the filter-patterns and
00712             KServiceTypeFactory *fac = KServiceTypeFactory::self();
00713             QStringList::Iterator it1 = nameFilter.begin();
00714             for ( ; it1 != nameFilter.end(); ++it1 ) {
00715                 if ( (*it1) == "*" ) {
00716                     return true;
00717                 }
00718 
00719                 KMimeType *mt = fac->findFromPattern( *it1 );
00720                 if ( !mt )
00721                     continue;
00722                 QString mime = mt->name();
00723                 delete mt;
00724 
00725                 // the "mimetypes" we get from the PreviewJob can be "image/*"
00726                 // so we need to check in wildcard mode
00727                 QStringList::Iterator it2 = supported.begin();
00728                 for ( ; it2 != supported.end(); ++it2 ) {
00729                     r.setPattern( *it2 );
00730                     if ( r.search( mime ) != -1 ) {
00731                         return true;
00732                     }
00733                 }
00734             }
00735         }
00736     }
00737 
00738     return false;
00739 }
00740 
00741 KFileView* KDirOperator::createView( QWidget* parent, KFile::FileView view )
00742 {
00743     KFileView* new_view = 0L;
00744     bool separateDirs = KFile::isSeparateDirs( view );
00745     bool preview = ( KFile::isPreviewInfo(view) || KFile::isPreviewContents( view ) );
00746 
00747     if ( separateDirs || preview ) {
00748         KCombiView *combi = 0L;
00749         if (separateDirs)
00750         {
00751             combi = new KCombiView( parent, "combi view" );
00752             combi->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles);
00753         }
00754 
00755         KFileView* v = 0L;
00756         if ( KFile::isSimpleView( view ) )
00757             v = createView( combi, KFile::Simple );
00758         else
00759             v = createView( combi, KFile::Detail );
00760 
00761         v->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles);
00762 
00763         if (combi)
00764             combi->setRight( v );
00765 
00766         if (preview)
00767         {
00768             KFilePreview* pView = new KFilePreview( combi ? combi : v, parent, "preview" );
00769             pView->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles);
00770             new_view = pView;
00771         }
00772         else
00773             new_view = combi;
00774     }
00775     else if ( KFile::isDetailView( view ) && !preview ) {
00776         new_view = new KFileDetailView( parent, "detail view");
00777         new_view->setViewName( i18n("Detailed View") );
00778     }
00779     else /* if ( KFile::isSimpleView( view ) && !preview ) */ {
00780         new_view = new KFileIconView( parent, "simple view");
00781         new_view->setViewName( i18n("Short View") );
00782     }
00783 
00784     return new_view;
00785 }
00786 
00787 void KDirOperator::setView( KFile::FileView view )
00788 {
00789     bool separateDirs = KFile::isSeparateDirs( view );
00790     bool preview=( KFile::isPreviewInfo(view) || KFile::isPreviewContents( view ) );
00791 
00792     if (view == KFile::Default) {
00793         if ( KFile::isDetailView( (KFile::FileView) defaultView ) )
00794             view = KFile::Detail;
00795         else
00796             view = KFile::Simple;
00797 
00798         separateDirs = KFile::isSeparateDirs( static_cast<KFile::FileView>(defaultView) );
00799         preview = ( KFile::isPreviewInfo( static_cast<KFile::FileView>(defaultView) ) ||
00800                     KFile::isPreviewContents( static_cast<KFile::FileView>(defaultView) ) )
00801                   && myActionCollection->action("preview")->isEnabled();
00802 
00803         if ( preview ) { // instantiates KImageFilePreview and calls setView()
00804             m_viewKind = view;
00805             slotDefaultPreview();
00806             return;
00807         }
00808         else if ( !separateDirs )
00809             separateDirsAction->setChecked(true);
00810     }
00811 
00812     // if we don't have any files, we can't separate dirs from files :)
00813     if ( (mode() & KFile::File) == 0 &&
00814          (mode() & KFile::Files) == 0 ) {
00815         separateDirs = false;
00816         separateDirsAction->setEnabled( false );
00817     }
00818 
00819     m_viewKind = static_cast<int>(view) | (separateDirs ? KFile::SeparateDirs : 0);
00820     view = static_cast<KFile::FileView>(m_viewKind);
00821 
00822     KFileView *new_view = createView( this, view );
00823     if ( preview ) {
00824         // we keep the preview-_widget_ around, but not the KFilePreview.
00825         // KFilePreview::setPreviewWidget handles the reparenting for us
00826         static_cast<KFilePreview*>(new_view)->setPreviewWidget(myPreview, url());
00827     }
00828 
00829     setView( new_view );
00830 }
00831 
00832 
00833 void KDirOperator::connectView(KFileView *view)
00834 {
00835     // TODO: do a real timer and restart it after that
00836     pendingMimeTypes.clear();
00837     bool listDir = true;
00838 
00839     if ( dirOnlyMode() )
00840          view->setViewMode(KFileView::Directories);
00841     else
00842         view->setViewMode(KFileView::All);
00843 
00844     if ( myMode & KFile::Files )
00845         view->setSelectionMode( KFile::Extended );
00846     else
00847         view->setSelectionMode( KFile::Single );
00848 
00849     if (m_fileView) {
00850         if ( d->config ) // save and restore coniguration the views' config
00851         {
00852             m_fileView->writeConfig( d->config, d->configGroup );
00853             view->readConfig( d->config, d->configGroup );
00854         }
00855 
00856         // transfer the state from old view to new view
00857         view->clear();
00858         view->addItemList( *m_fileView->items() );
00859         listDir = false;
00860 
00861         if ( m_fileView->widget()->hasFocus() )
00862             view->widget()->setFocus();
00863 
00864         KFileItem *oldCurrentItem = m_fileView->currentFileItem();
00865         if ( oldCurrentItem ) {
00866             view->setCurrentItem( oldCurrentItem );
00867             view->setSelected( oldCurrentItem, false );
00868             view->ensureItemVisible( oldCurrentItem );
00869         }
00870 
00871         const KFileItemList *oldSelected = m_fileView->selectedItems();
00872         if ( !oldSelected->isEmpty() ) {
00873             KFileItemListIterator it( *oldSelected );
00874             for ( ; it.current(); ++it )
00875                 view->setSelected( it.current(), true );
00876         }
00877 
00878         m_fileView->widget()->hide();
00879         delete m_fileView;
00880     }
00881 
00882     else
00883     {
00884         if ( d->config )
00885             view->readConfig( d->config, d->configGroup );
00886     }
00887 
00888     m_fileView = view;
00889     viewActionCollection = 0L;
00890     KFileViewSignaler *sig = view->signaler();
00891 
00892     connect(sig, SIGNAL( activatedMenu(const KFileItem *, const QPoint& ) ),
00893             this, SLOT( activatedMenu(const KFileItem *, const QPoint& )));
00894     connect(sig, SIGNAL( dirActivated(const KFileItem *) ),
00895             this, SLOT( selectDir(const KFileItem*) ) );
00896     connect(sig, SIGNAL( fileSelected(const KFileItem *) ),
00897             this, SLOT( selectFile(const KFileItem*) ) );
00898     connect(sig, SIGNAL( fileHighlighted(const KFileItem *) ),
00899             this, SLOT( highlightFile(const KFileItem*) ));
00900     connect(sig, SIGNAL( sortingChanged( QDir::SortSpec ) ),
00901             this, SLOT( slotViewSortingChanged( QDir::SortSpec )));
00902 
00903     if ( reverseAction->isChecked() != m_fileView->isReversed() )
00904         slotSortReversed();
00905 
00906     updateViewActions();
00907     m_fileView->widget()->resize(size());
00908     m_fileView->widget()->show();
00909 
00910     if ( listDir ) {
00911         QApplication::setOverrideCursor( waitCursor );
00912         dir->openURL( currUrl );
00913     }
00914     else
00915         view->listingCompleted();
00916 }
00917 
00918 KFile::Mode KDirOperator::mode() const
00919 {
00920     return myMode;
00921 }
00922 
00923 void KDirOperator::setMode(KFile::Mode m)
00924 {
00925     if (myMode == m)
00926         return;
00927 
00928     myMode = m;
00929 
00930     dir->setDirOnlyMode( dirOnlyMode() );
00931 
00932     // reset the view with the different mode
00933     setView( static_cast<KFile::FileView>(m_viewKind) );
00934 }
00935 
00936 void KDirOperator::setView(KFileView *view)
00937 {
00938     if ( view == m_fileView ) {
00939         return;
00940     }
00941 
00942     setFocusProxy(view->widget());
00943     view->setSorting( mySorting );
00944     view->setOnlyDoubleClickSelectsFiles( d->onlyDoubleClickSelectsFiles );
00945     connectView(view); // also deletes the old view
00946 
00947     emit viewChanged( view );
00948 }
00949 
00950 void KDirOperator::setDirLister( KDirLister *lister )
00951 {
00952     if ( lister == dir ) // sanity check
00953         return;
00954 
00955     delete dir;
00956     dir = lister;
00957 
00958     dir->setAutoUpdate( true );
00959 
00960     connect( dir, SIGNAL( percent( int )),
00961              SLOT( slotProgress( int ) ));
00962     connect( dir, SIGNAL(started( const KURL& )), SLOT(slotStarted()));
00963     connect( dir, SIGNAL(newItems(const KFileItemList &)),
00964              SLOT(insertNewFiles(const KFileItemList &)));
00965     connect( dir, SIGNAL(completed()), SLOT(slotIOFinished()));
00966     connect( dir, SIGNAL(canceled()), SLOT(slotCanceled()));
00967     connect( dir, SIGNAL(deleteItem(KFileItem *)),
00968              SLOT(itemDeleted(KFileItem *)));
00969     connect( dir, SIGNAL(redirection( const KURL& )),
00970          SLOT( slotRedirected( const KURL& )));
00971     connect( dir, SIGNAL( clear() ), SLOT( slotClearView() ));
00972     connect( dir, SIGNAL( refreshItems( const KFileItemList& ) ),
00973              SLOT( slotRefreshItems( const KFileItemList& ) ) );
00974 }
00975 
00976 void KDirOperator::insertNewFiles(const KFileItemList &newone)
00977 {
00978     if ( newone.isEmpty() || !m_fileView )
00979         return;
00980 
00981     myCompleteListDirty = true;
00982     m_fileView->addItemList( newone );
00983     emit updateInformation(m_fileView->numDirs(), m_fileView->numFiles());
00984 
00985     KFileItem *item;
00986     KFileItemListIterator it( newone );
00987 
00988     while ( (item = it.current()) ) {
00989     // highlight the dir we come from, if possible
00990     if ( d->dirHighlighting && item->isDir() &&
00991          item->url().url(-1) == d->lastURL ) {
00992         m_fileView->setCurrentItem( item );
00993         m_fileView->ensureItemVisible( item );
00994     }
00995 
00996     ++it;
00997     }
00998 
00999     QTimer::singleShot(200, this, SLOT(resetCursor()));
01000 }
01001 
01002 void KDirOperator::selectDir(const KFileItem *item)
01003 {
01004     setURL(item->url(), true);
01005 }
01006 
01007 void KDirOperator::itemDeleted(KFileItem *item)
01008 {
01009     pendingMimeTypes.removeRef( item );
01010     m_fileView->removeItem( static_cast<KFileItem *>( item ));
01011     emit updateInformation(m_fileView->numDirs(), m_fileView->numFiles());
01012 }
01013 
01014 void KDirOperator::selectFile(const KFileItem *item)
01015 {
01016     QApplication::restoreOverrideCursor();
01017 
01018     emit fileSelected( item );
01019 }
01020 
01021 void KDirOperator::setCurrentItem( const QString& filename )
01022 {
01023     if ( m_fileView ) {
01024         const KFileItem *item = 0L;
01025 
01026         if ( !filename.isNull() )
01027             item = static_cast<KFileItem *>(dir->findByName( filename ));
01028 
01029         m_fileView->clearSelection();
01030         if ( item ) {
01031             m_fileView->setCurrentItem( item );
01032             m_fileView->setSelected( item, true );
01033             m_fileView->ensureItemVisible( item );
01034         }
01035     }
01036 }
01037 
01038 QString KDirOperator::makeCompletion(const QString& string)
01039 {
01040     if ( string.isEmpty() ) {
01041         m_fileView->clearSelection();
01042         return QString::null;
01043     }
01044 
01045     prepareCompletionObjects();
01046     return myCompletion.makeCompletion( string );
01047 }
01048 
01049 QString KDirOperator::makeDirCompletion(const QString& string)
01050 {
01051     if ( string.isEmpty() ) {
01052         m_fileView->clearSelection();
01053         return QString::null;
01054     }
01055 
01056     prepareCompletionObjects();
01057     return myDirCompletion.makeCompletion( string );
01058 }
01059 
01060 void KDirOperator::prepareCompletionObjects()
01061 {
01062     if ( !m_fileView )
01063     return;
01064 
01065     if ( myCompleteListDirty ) { // create the list of all possible completions
01066         KFileItemListIterator it( *(m_fileView->items()) );
01067         for( ; it.current(); ++it ) {
01068             KFileItem *item = it.current();
01069 
01070             myCompletion.addItem( item->name() );
01071             if ( item->isDir() )
01072                 myDirCompletion.addItem( item->name() );
01073         }
01074         myCompleteListDirty = false;
01075     }
01076 }
01077 
01078 void KDirOperator::slotCompletionMatch(const QString& match)
01079 {
01080     setCurrentItem( match );
01081     emit completion( match );
01082 }
01083 
01084 void KDirOperator::setupActions()
01085 {
01086     myActionCollection = new KActionCollection( this, "KDirOperator::myActionCollection" );
01087     actionMenu = new KActionMenu( i18n("Menu"), myActionCollection, "popupMenu" );
01088     upAction = KStdAction::up( this, SLOT( cdUp() ), myActionCollection, "up" );
01089     upAction->setText( i18n("Parent Directory") );
01090     backAction = KStdAction::back( this, SLOT( back() ), myActionCollection, "back" );
01091     forwardAction = KStdAction::forward( this, SLOT(forward()), myActionCollection, "forward" );
01092     homeAction = KStdAction::home( this, SLOT( home() ), myActionCollection, "home" );
01093     homeAction->setText(i18n("Home Directory"));
01094     reloadAction = KStdAction::redisplay( this, SLOT(rereadDir()), myActionCollection, "reload" );
01095     actionSeparator = new KActionSeparator( myActionCollection, "separator" );
01096     d->viewActionSeparator = new KActionSeparator( myActionCollection,
01097                                                    "viewActionSeparator" );
01098     mkdirAction = new KAction( i18n("New Directory..."), 0,
01099                                  this, SLOT( mkdir() ), myActionCollection, "mkdir" );
01100     new KAction( i18n( "Delete" ), "editdelete", Key_Delete, this,
01101                   SLOT( deleteSelected() ), myActionCollection, "delete" );
01102     mkdirAction->setIcon( QString::fromLatin1("folder_new") );
01103     reloadAction->setText( i18n("Reload") );
01104     reloadAction->setShortcut( KStdAccel::shortcut( KStdAccel::Reload ));
01105 
01106 
01107     // the sort menu actions
01108     sortActionMenu = new KActionMenu( i18n("Sorting"), myActionCollection, "sorting menu");
01109     byNameAction = new KRadioAction( i18n("By Name"), 0,
01110                                      this, SLOT( slotSortByName() ),
01111                                      myActionCollection, "by name" );
01112     byDateAction = new KRadioAction( i18n("By Date"), 0,
01113                                      this, SLOT( slotSortByDate() ),
01114                                      myActionCollection, "by date" );
01115     bySizeAction = new KRadioAction( i18n("By Size"), 0,
01116                                      this, SLOT( slotSortBySize() ),
01117                                      myActionCollection, "by size" );
01118     reverseAction = new KToggleAction( i18n("Reverse"), 0,
01119                                        this, SLOT( slotSortReversed() ),
01120                                        myActionCollection, "reversed" );
01121 
01122     QString sortGroup = QString::fromLatin1("sort");
01123     byNameAction->setExclusiveGroup( sortGroup );
01124     byDateAction->setExclusiveGroup( sortGroup );
01125     bySizeAction->setExclusiveGroup( sortGroup );
01126 
01127 
01128     dirsFirstAction = new KToggleAction( i18n("Directories First"), 0,
01129                                          myActionCollection, "dirs first");
01130     caseInsensitiveAction = new KToggleAction(i18n("Case Insensitive"), 0,
01131                                               myActionCollection, "case insensitive" );
01132 
01133     connect( dirsFirstAction, SIGNAL( toggled( bool ) ),
01134              SLOT( slotToggleDirsFirst() ));
01135     connect( caseInsensitiveAction, SIGNAL( toggled( bool ) ),
01136              SLOT( slotToggleIgnoreCase() ));
01137 
01138 
01139 
01140     // the view menu actions
01141     viewActionMenu = new KActionMenu( i18n("View"), myActionCollection, "view menu" );
01142     connect( viewActionMenu->popupMenu(), SIGNAL( aboutToShow() ),
01143              SLOT( insertViewDependentActions() ));
01144 
01145     shortAction = new KRadioAction( i18n("Short View"), "view_multicolumn",
01146                                     KShortcut(), myActionCollection, "short view" );
01147     detailedAction = new KRadioAction( i18n("Detailed View"), "view_detailed",
01148                                        KShortcut(), myActionCollection, "detailed view" );
01149 
01150     showHiddenAction = new KToggleAction( i18n("Show Hidden Files"), KShortcut(),
01151                                           myActionCollection, "show hidden" );
01152     separateDirsAction = new KToggleAction( i18n("Separate Directories"), KShortcut(),
01153                                             this,
01154                                             SLOT(slotSeparateDirs()),
01155                                             myActionCollection, "separate dirs" );
01156     KToggleAction *previewAction = new KToggleAction(i18n("Show Preview"),
01157                                                      "thumbnail", KShortcut(),
01158                                                      myActionCollection,
01159                                                      "preview" );
01160     connect( previewAction, SIGNAL( toggled( bool )),
01161              SLOT( togglePreview( bool )));
01162 
01163 
01164     QString viewGroup = QString::fromLatin1("view");
01165     shortAction->setExclusiveGroup( viewGroup );
01166     detailedAction->setExclusiveGroup( viewGroup );
01167 
01168     connect( shortAction, SIGNAL( activated() ),
01169              SLOT( slotSimpleView() ));
01170     connect( detailedAction, SIGNAL( activated() ),
01171              SLOT( slotDetailedView() ));
01172     connect( showHiddenAction, SIGNAL( toggled( bool ) ),
01173              SLOT( slotToggleHidden( bool ) ));
01174 
01175     new KAction( i18n("Properties..."), KShortcut(ALT+Key_Return), this,
01176                  SLOT(slotProperties()), myActionCollection, "properties" );
01177 }
01178 
01179 void KDirOperator::setupMenu()
01180 {
01181     setupMenu(AllActions);
01182 }
01183 
01184 void KDirOperator::setupMenu(int whichActions)
01185 {
01186     // first fill the submenus (sort and view)
01187     sortActionMenu->popupMenu()->clear();
01188     sortActionMenu->insert( byNameAction );
01189     sortActionMenu->insert( byDateAction );
01190     sortActionMenu->insert( bySizeAction );
01191     sortActionMenu->insert( actionSeparator );
01192     sortActionMenu->insert( reverseAction );
01193     sortActionMenu->insert( dirsFirstAction );
01194     sortActionMenu->insert( caseInsensitiveAction );
01195 
01196     viewActionMenu->popupMenu()->clear();
01197 //     viewActionMenu->insert( shortAction );
01198 //     viewActionMenu->insert( detailedAction );
01199 //     viewActionMenu->insert( actionSeparator );
01200     viewActionMenu->insert( myActionCollection->action( "short view" ) );
01201     viewActionMenu->insert( myActionCollection->action( "detailed view" ) );
01202     viewActionMenu->insert( actionSeparator );
01203     viewActionMenu->insert( showHiddenAction );
01204 //    viewActionMenu->insert( myActionCollection->action( "single" ));
01205     viewActionMenu->insert( separateDirsAction );
01206     // Warning: adjust slotViewActionAdded() and slotViewActionRemoved()
01207     // when you add/remove actions here!
01208 
01209     // now plug everything into the popupmenu
01210     actionMenu->popupMenu()->clear();
01211     if (whichActions & NavActions)
01212     {
01213         actionMenu->insert( upAction );
01214         actionMenu->insert( backAction );
01215         actionMenu->insert( forwardAction );
01216         actionMenu->insert( homeAction );
01217         actionMenu->insert( actionSeparator );
01218     }
01219 
01220     if (whichActions & FileActions)
01221     {
01222         actionMenu->insert( mkdirAction );
01223         actionMenu->insert( myActionCollection->action( "delete" ) );
01224         actionMenu->insert( actionSeparator );
01225     }
01226 
01227     if (whichActions & SortActions)
01228     {
01229         actionMenu->insert( sortActionMenu );
01230         actionMenu->insert( actionSeparator );
01231     }
01232 
01233     if (whichActions & ViewActions)
01234     {
01235         actionMenu->insert( viewActionMenu );
01236         actionMenu->insert( actionSeparator );
01237     }
01238 
01239     if (whichActions & FileActions)
01240     {
01241         actionMenu->insert( myActionCollection->action( "properties" ) );
01242     }
01243 }
01244 
01245 void KDirOperator::updateSortActions()
01246 {
01247     if ( KFile::isSortByName( mySorting ) )
01248         byNameAction->setChecked( true );
01249     else if ( KFile::isSortByDate( mySorting ) )
01250         byDateAction->setChecked( true );
01251     else if ( KFile::isSortBySize( mySorting ) )
01252         bySizeAction->setChecked( true );
01253 
01254     dirsFirstAction->setChecked( KFile::isSortDirsFirst( mySorting ) );
01255     caseInsensitiveAction->setChecked( KFile::isSortCaseInsensitive(mySorting) );
01256     caseInsensitiveAction->setEnabled( KFile::isSortByName( mySorting ) );
01257 
01258     if ( m_fileView )
01259         reverseAction->setChecked( m_fileView->isReversed() );
01260 }
01261 
01262 void KDirOperator::updateViewActions()
01263 {
01264     KFile::FileView fv = static_cast<KFile::FileView>( m_viewKind );
01265 
01266     separateDirsAction->setChecked( KFile::isSeparateDirs( fv ) &&
01267                                     separateDirsAction->isEnabled() );
01268 
01269     shortAction->setChecked( KFile::isSimpleView( fv ));
01270     detailedAction->setChecked( KFile::isDetailView( fv ));
01271 }
01272 
01273 void KDirOperator::readConfig( KConfig *kc, const QString& group )
01274 {
01275     if ( !kc )
01276         return;
01277     QString oldGroup = kc->group();
01278     if ( !group.isEmpty() )
01279         kc->setGroup( group );
01280 
01281     defaultView = 0;
01282     int sorting = 0;
01283 
01284     QString viewStyle = kc->readEntry( QString::fromLatin1("View Style"),
01285                                        QString::fromLatin1("Simple") );
01286     if ( viewStyle == QString::fromLatin1("Detail") )
01287         defaultView |= KFile::Detail;
01288     else
01289         defaultView |= KFile::Simple;
01290     if ( kc->readBoolEntry( QString::fromLatin1("Separate Directories"),
01291                             DefaultMixDirsAndFiles ) )
01292         defaultView |= KFile::SeparateDirs;
01293     else {
01294         if ( kc->readBoolEntry(QString::fromLatin1("Show Preview"), false))
01295             defaultView |= KFile::PreviewContents;
01296     }
01297 
01298     if ( kc->readBoolEntry( QString::fromLatin1("Sort case insensitively"),
01299                             DefaultCaseInsensitive ) )
01300         sorting |= QDir::IgnoreCase;
01301     if ( kc->readBoolEntry( QString::fromLatin1("Sort directories first"),
01302                             DefaultDirsFirst ) )
01303         sorting |= QDir::DirsFirst;
01304 
01305 
01306     QString name = QString::fromLatin1("Name");
01307     QString sortBy = kc->readEntry( QString::fromLatin1("Sort by"), name );
01308     if ( sortBy == name )
01309         sorting |= QDir::Name;
01310     else if ( sortBy == QString::fromLatin1("Size") )
01311         sorting |= QDir::Size;
01312     else if ( sortBy == QString::fromLatin1("Date") )
01313         sorting |= QDir::Time;
01314 
01315     mySorting = static_cast<QDir::SortSpec>( sorting );
01316     setSorting( mySorting );
01317 
01318 
01319     if ( kc->readBoolEntry( QString::fromLatin1("Show hidden files"),
01320                             DefaultShowHidden ) ) {
01321          showHiddenAction->setChecked( true );
01322          dir->setShowingDotFiles( true );
01323     }
01324     if ( kc->readBoolEntry( QString::fromLatin1("Sort reversed"),
01325                             DefaultSortReversed ) )
01326         reverseAction->setChecked( true );
01327 
01328     kc->setGroup( oldGroup );
01329 }
01330 
01331 void KDirOperator::writeConfig( KConfig *kc, const QString& group )
01332 {
01333     if ( !kc )
01334         return;
01335 
01336     const QString oldGroup = kc->group();
01337 
01338     if ( !group.isEmpty() )
01339         kc->setGroup( group );
01340 
01341     QString sortBy = QString::fromLatin1("Name");
01342     if ( KFile::isSortBySize( mySorting ) )
01343         sortBy = QString::fromLatin1("Size");
01344     else if ( KFile::isSortByDate( mySorting ) )
01345         sortBy = QString::fromLatin1("Date");
01346     kc->writeEntry( QString::fromLatin1("Sort by"), sortBy );
01347 
01348     kc->writeEntry( QString::fromLatin1("Sort reversed"),
01349                     reverseAction->isChecked() );
01350     kc->writeEntry( QString::fromLatin1("Sort case insensitively"),
01351                     caseInsensitiveAction->isChecked() );
01352     kc->writeEntry( QString::fromLatin1("Sort directories first"),
01353                     dirsFirstAction->isChecked() );
01354 
01355     // don't save the separate dirs or preview when an application specific
01356     // preview is in use.
01357     bool appSpecificPreview = false;
01358     if ( myPreview ) {
01359         QWidget *preview = const_cast<QWidget*>( myPreview ); // grmbl
01360         KImageFilePreview *tmp = dynamic_cast<KImageFilePreview*>( preview );
01361         appSpecificPreview = (tmp == 0L);
01362     }
01363 
01364     if ( !appSpecificPreview ) {
01365         if ( separateDirsAction->isEnabled() )
01366             kc->writeEntry( QString::fromLatin1("Separate Directories"),
01367                             separateDirsAction->isChecked() );
01368 
01369         KToggleAction *previewAction = static_cast<KToggleAction*>(myActionCollection->action("preview"));
01370         if ( previewAction->isEnabled() ) {
01371             bool hasPreview = previewAction->isChecked();
01372             kc->writeEntry( QString::fromLatin1("Show Preview"), hasPreview );
01373         }
01374     }
01375 
01376     kc->writeEntry( QString::fromLatin1("Show hidden files"),
01377                     showHiddenAction->isChecked() );
01378 
01379     KFile::FileView fv = static_cast<KFile::FileView>( m_viewKind );
01380     QString style;
01381     if ( KFile::isDetailView( fv ) )
01382         style = QString::fromLatin1("Detail");
01383     else if ( KFile::isSimpleView( fv ) )
01384         style = QString::fromLatin1("Simple");
01385     kc->writeEntry( QString::fromLatin1("View Style"), style );
01386 
01387     kc->setGroup( oldGroup );
01388 }
01389 
01390 
01391 void KDirOperator::resizeEvent( QResizeEvent * )
01392 {
01393     if (m_fileView)
01394         m_fileView->widget()->resize( size() );
01395 
01396     if ( progress->parent() == this ) // might be reparented into a statusbar
01397     progress->move(2, height() - progress->height() -2);
01398 }
01399 
01400 void KDirOperator::setOnlyDoubleClickSelectsFiles( bool enable )
01401 {
01402     d->onlyDoubleClickSelectsFiles = enable;
01403     if ( m_fileView )
01404         m_fileView->setOnlyDoubleClickSelectsFiles( enable );
01405 }
01406 
01407 bool KDirOperator::onlyDoubleClickSelectsFiles() const
01408 {
01409     return d->onlyDoubleClickSelectsFiles;
01410 }
01411 
01412 void KDirOperator::slotStarted()
01413 {
01414     progress->setProgress( 0 );
01415     // delay showing the progressbar for one second
01416     d->progressDelayTimer->start( 1000, true );
01417 }
01418 
01419 void KDirOperator::slotShowProgress()
01420 {
01421     progress->raise();
01422     progress->show();
01423     QApplication::flushX();
01424 }
01425 
01426 void KDirOperator::slotProgress( int percent )
01427 {
01428     progress->setProgress( percent );
01429     // we have to redraw this in as fast as possible
01430     if ( progress->isVisible() )
01431     QApplication::flushX();
01432 }
01433 
01434 
01435 void KDirOperator::slotIOFinished()
01436 {
01437     d->progressDelayTimer->stop();
01438     slotProgress( 100 );
01439     progress->hide();
01440     emit finishedLoading();
01441     resetCursor();
01442 
01443     if ( m_fileView )
01444         m_fileView->listingCompleted();
01445 }
01446 
01447 void KDirOperator::slotCanceled()
01448 {
01449     emit finishedLoading();
01450     resetCursor();
01451 
01452     if ( m_fileView )
01453         m_fileView->listingCompleted();
01454 }
01455 
01456 KProgress * KDirOperator::progressBar() const
01457 {
01458     return progress;
01459 }
01460 
01461 void KDirOperator::clearHistory()
01462 {
01463     backStack.clear();
01464     backAction->setEnabled( false );
01465     forwardStack.clear();
01466     forwardAction->setEnabled( false );
01467 }
01468 
01469 void KDirOperator::slotViewActionAdded( KAction *action )
01470 {
01471     if ( viewActionMenu->popupMenu()->count() == 5 ) // need to add a separator
01472     viewActionMenu->insert( d->viewActionSeparator );
01473 
01474     viewActionMenu->insert( action );
01475 }
01476 
01477 void KDirOperator::slotViewActionRemoved( KAction *action )
01478 {
01479     viewActionMenu->remove( action );
01480 
01481     if ( viewActionMenu->popupMenu()->count() == 6 ) // remove the separator
01482     viewActionMenu->remove( d->viewActionSeparator );
01483 }
01484 
01485 void KDirOperator::slotViewSortingChanged( QDir::SortSpec sort )
01486 {
01487     mySorting = sort;
01488     updateSortActions();
01489 }
01490 
01491 void KDirOperator::setEnableDirHighlighting( bool enable )
01492 {
01493     d->dirHighlighting = enable;
01494 }
01495 
01496 bool KDirOperator::dirHighlighting() const
01497 {
01498     return d->dirHighlighting;
01499 }
01500 
01501 void KDirOperator::slotProperties()
01502 {
01503     if ( m_fileView ) {
01504         const KFileItemList *list = m_fileView->selectedItems();
01505         if ( !list->isEmpty() )
01506             (void) new KPropertiesDialog( *list, this, "props dlg", true);
01507     }
01508 }
01509 
01510 void KDirOperator::slotClearView()
01511 {
01512     if ( m_fileView )
01513         m_fileView->clearView();
01514 }
01515 
01516 // ### temporary code
01517 #include <dirent.h>
01518 bool KDirOperator::isReadable( const KURL& url )
01519 {
01520     if ( !url.isLocalFile() )
01521     return true; // what else can we say?
01522 
01523     struct stat buf;
01524     QString ts = url.path(+1);
01525     bool readable = ( ::stat( QFile::encodeName( ts ), &buf) == 0 );
01526     if (readable) { // further checks
01527     DIR *test;
01528     test = opendir( QFile::encodeName( ts )); // we do it just to test here
01529     readable = (test != 0);
01530     if (test)
01531         closedir(test);
01532     }
01533     return readable;
01534 }
01535 
01536 void KDirOperator::togglePreview( bool on )
01537 {
01538     if ( on )
01539         slotDefaultPreview();
01540     else
01541         setView( (KFile::FileView) (m_viewKind & ~(KFile::PreviewContents|KFile::PreviewInfo)) );
01542 }
01543 
01544 void KDirOperator::slotRefreshItems( const KFileItemList& items )
01545 {
01546     if ( !m_fileView )
01547         return;
01548 
01549     KFileItemListIterator it( items );
01550     for ( ; it.current(); ++it )
01551         m_fileView->updateView( it.current() );
01552 }
01553 
01554 void KDirOperator::setViewConfig( KConfig *config, const QString& group )
01555 {
01556     d->config = config;
01557     d->configGroup = group;
01558 }
01559 
01560 KConfig * KDirOperator::viewConfig()
01561 {
01562     return d->config;
01563 }
01564 
01565 QString KDirOperator::viewConfigGroup() const
01566 {
01567     return d->configGroup;
01568 }
01569 
01570 void KDirOperator::virtual_hook( int, void* )
01571 { /*BASE::virtual_hook( id, data );*/ }
01572 
01573 #include "kdiroperator.moc"
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:21:28 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001