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