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