• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kio

kdiroperator.cpp

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

kio

Skip menu "kio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal