kio Library: kdiroperator.cpp Source File (kio Library)

| # kio Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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 <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("translators: not called for n == 1", "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     dir->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     dir->openURL( currUrl, false, true );
    00695 }
    00696
    00697 // Protected
    00698 void KDirOperator::pathChanged()
    00699 {
    00700     if (!m_fileView)
    00701         return;
    00702
    00703     pendingMimeTypes.clear();
    00704     m_fileView->clear();
    00705     myCompletion.clear();
    00706     myDirCompletion.clear();
    00707
    00708     // it may be, that we weren't ready at this time
    00709     QApplication::restoreOverrideCursor();
    00710
    00711     // when KIO::Job emits finished, the slot will restore the cursor
    00712     QApplication::setOverrideCursor( waitCursor );
    00713
    00714     if ( !isReadable( currUrl )) {
    00715         KMessageBox::error(viewWidget(),
    00716                            i18n("The specified folder does not exist "
    00717                                 "or was not readable."));
    00718         if (backStack.isEmpty())
    00719             home();
    00720         else
    00721             back();
    00722     }
    00723 }
    00724
    00725 void KDirOperator::slotRedirected( const KURL& newURL )
    00726 {
    00727     currUrl = newURL;
    00728     pendingMimeTypes.clear();
    00729     myCompletion.clear();
    00730     myDirCompletion.clear();
    00731     myCompleteListDirty = true;
    00732     emit urlEntered( newURL );
    00733 }
    00734
    00735 // Code pinched from kfm then hacked
    00736 void KDirOperator::back()
    00737 {
    00738     if ( backStack.isEmpty() )
    00739         return;
    00740
    00741     forwardStack.push( new KURL(currUrl) );
    00742
    00743     KURL *s = backStack.pop();
    00744
    00745     setURL(*s, false);
    00746     delete s;
    00747 }
    00748
    00749 // Code pinched from kfm then hacked
    00750 void KDirOperator::forward()
    00751 {
    00752     if ( forwardStack.isEmpty() )
    00753         return;
    00754
    00755     backStack.push(new KURL(currUrl));
    00756
    00757     KURL *s = forwardStack.pop();
    00758     setURL(*s, false);
    00759     delete s;
    00760 }
    00761
    00762 KURL KDirOperator::url() const
    00763 {
    00764     return currUrl;
    00765 }
    00766
    00767 void KDirOperator::cdUp()
    00768 {
    00769     KURL tmp( currUrl );
    00770     tmp.cd(QString::fromLatin1(".."));
    00771     setURL(tmp, true);
    00772 }
    00773
    00774 void KDirOperator::home()
    00775 {
    00776     KURL u;
    00777     u.setPath( QDir::homeDirPath() );
    00778     setURL(u, true);
    00779 }
    00780
    00781 void KDirOperator::clearFilter()
    00782 {
    00783     dir->setNameFilter( QString::null );
    00784     dir->clearMimeFilter();
    00785     checkPreviewSupport();
    00786 }
    00787
    00788 void KDirOperator::setNameFilter(const QString& filter)
    00789 {
    00790     dir->setNameFilter(filter);
    00791     checkPreviewSupport();
    00792 }
    00793
    00794 void KDirOperator::setMimeFilter( const QStringList& mimetypes )
    00795 {
    00796     dir->setMimeFilter( mimetypes );
    00797     checkPreviewSupport();
    00798 }
    00799
    00800 bool KDirOperator::checkPreviewSupport()
    00801 {
    00802     KToggleAction *previewAction = static_cast<KToggleAction*>( myActionCollection->action( "preview" ));
    00803
    00804     bool hasPreviewSupport = false;
    00805     KConfig *kc = KGlobal::config();
    00806     KConfigGroupSaver cs( kc, ConfigGroup );
    00807     if ( kc->readBoolEntry( "Show Default Preview", true ) )
    00808         hasPreviewSupport = checkPreviewInternal();
    00809
    00810     previewAction->setEnabled( hasPreviewSupport );
    00811     return hasPreviewSupport;
    00812 }
    00813
    00814 bool KDirOperator::checkPreviewInternal() const
    00815 {
    00816     QStringList supported = KIO::PreviewJob::supportedMimeTypes();
    00817     // no preview support for directories?
    00818     if ( dirOnlyMode() && supported.findIndex( "inode/directory" ) == -1 )
    00819         return false;
    00820
    00821     QStringList mimeTypes = dir->mimeFilters();
    00822     QStringList nameFilter = QStringList::split( " ", dir->nameFilter() );
    00823
    00824     if ( mimeTypes.isEmpty() && nameFilter.isEmpty() && !supported.isEmpty() )
    00825         return true;
    00826     else {
    00827         QRegExp r;
    00828         r.setWildcard( true ); // the "mimetype" can be "image/*"
    00829
    00830         if ( !mimeTypes.isEmpty() ) {
    00831             QStringList::Iterator it = supported.begin();
    00832
    00833             for ( ; it != supported.end(); ++it ) {
    00834                 r.setPattern( *it );
    00835
    00836                 QStringList result = mimeTypes.grep( r );
    00837                 if ( !result.isEmpty() ) { // matches! -> we want previews
    00838                     return true;
    00839                 }
    00840             }
    00841         }
    00842
    00843         if ( !nameFilter.isEmpty() ) {
    00844             // find the mimetypes of all the filter-patterns and
    00845             KServiceTypeFactory *fac = KServiceTypeFactory::self();
    00846             QStringList::Iterator it1 = nameFilter.begin();
    00847             for ( ; it1 != nameFilter.end(); ++it1 ) {
    00848                 if ( (*it1) == "*" ) {
    00849                     return true;
    00850                 }
    00851
    00852                 KMimeType *mt = fac->findFromPattern( *it1 );
    00853                 if ( !mt )
    00854                     continue;
    00855                 QString mime = mt->name();
    00856                 delete mt;
    00857
    00858                 // the "mimetypes" we get from the PreviewJob can be "image/*"
    00859                 // so we need to check in wildcard mode
    00860                 QStringList::Iterator it2 = supported.begin();
    00861                 for ( ; it2 != supported.end(); ++it2 ) {
    00862                     r.setPattern( *it2 );
    00863                     if ( r.search( mime ) != -1 ) {
    00864                         return true;
    00865                     }
    00866                 }
    00867             }
    00868         }
    00869     }
    00870
    00871     return false;
    00872 }
    00873
    00874 KFileView* KDirOperator::createView( QWidget* parent, KFile::FileView view )
    00875 {
    00876     KFileView* new_view = 0L;
    00877     bool separateDirs = KFile::isSeparateDirs( view );
    00878     bool preview = ( KFile::isPreviewInfo(view) || KFile::isPreviewContents( view ) );
    00879
    00880     if ( separateDirs || preview ) {
    00881         KCombiView *combi = 0L;
    00882         if (separateDirs)
    00883         {
    00884             combi = new KCombiView( parent, "combi view" );
    00885             combi->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles);
    00886         }
    00887
    00888         KFileView* v = 0L;
    00889         if ( KFile::isSimpleView( view ) )
    00890             v = createView( combi, KFile::Simple );
    00891         else
    00892             v = createView( combi, KFile::Detail );
    00893
    00894         v->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles);
    00895
    00896         if (combi)
    00897             combi->setRight( v );
    00898
    00899         if (preview)
    00900         {
    00901             KFilePreview* pView = new KFilePreview( combi ? combi : v, parent, "preview" );
    00902             pView->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles);
    00903             new_view = pView;
    00904         }
    00905         else
    00906             new_view = combi;
    00907     }
    00908     else if ( KFile::isDetailView( view ) && !preview ) {
    00909         new_view = new KFileDetailView( parent, "detail view");
    00910         new_view->setViewName( i18n("Detailed View") );
    00911     }
    00912     else /* if ( KFile::isSimpleView( view ) && !preview ) */ {
    00913         KFileIconView *iconView =  new KFileIconView( parent, "simple view");
    00914         new_view = iconView;
    00915         new_view->setViewName( i18n("Short View") );
    00916     }
    00917
    00918     new_view->widget()->setAcceptDrops(acceptDrops());
    00919     return new_view;
    00920 }
    00921
    00922 void KDirOperator::setAcceptDrops(bool b)
    00923 {
    00924     if (m_fileView)
    00925        m_fileView->widget()->setAcceptDrops(b);
    00926     QWidget::setAcceptDrops(b);
    00927 }
    00928
    00929 void KDirOperator::setDropOptions(int options)
    00930 {
    00931     d->dropOptions = options;
    00932     if (m_fileView)
    00933        m_fileView->setDropOptions(options);
    00934 }
    00935
    00936 void KDirOperator::setView( KFile::FileView view )
    00937 {
    00938     bool separateDirs = KFile::isSeparateDirs( view );
    00939     bool preview=( KFile::isPreviewInfo(view) || KFile::isPreviewContents( view ) );
    00940
    00941     if (view == KFile::Default) {
    00942         if ( KFile::isDetailView( (KFile::FileView) defaultView ) )
    00943             view = KFile::Detail;
    00944         else
    00945             view = KFile::Simple;
    00946
    00947         separateDirs = KFile::isSeparateDirs( static_cast<KFile::FileView>(defaultView) );
    00948         preview = ( KFile::isPreviewInfo( static_cast<KFile::FileView>(defaultView) ) ||
    00949                     KFile::isPreviewContents( static_cast<KFile::FileView>(defaultView) ) )
    00950                   && myActionCollection->action("preview")->isEnabled();
    00951
    00952         if ( preview ) { // instantiates KFileMetaPreview and calls setView()
    00953             m_viewKind = defaultView;
    00954             slotDefaultPreview();
    00955             return;
    00956         }
    00957         else if ( !separateDirs )
    00958             separateDirsAction->setChecked(true);
    00959     }
    00960
    00961     // if we don't have any files, we can't separate dirs from files :)
    00962     if ( (mode() & KFile::File) == 0 &&
    00963          (mode() & KFile::Files) == 0 ) {
    00964         separateDirs = false;
    00965         separateDirsAction->setEnabled( false );
    00966     }
    00967
    00968     m_viewKind = static_cast<int>(view) | (separateDirs ? KFile::SeparateDirs : 0);
    00969     view = static_cast<KFile::FileView>(m_viewKind);
    00970
    00971     KFileView *new_view = createView( this, view );
    00972     if ( preview ) {
    00973         // we keep the preview-_widget_ around, but not the KFilePreview.
    00974         // KFilePreview::setPreviewWidget handles the reparenting for us
    00975         static_cast<KFilePreview*>(new_view)->setPreviewWidget(myPreview, url());
    00976     }
    00977
    00978     setView( new_view );
    00979 }
    00980
    00981
    00982 void KDirOperator::connectView(KFileView *view)
    00983 {
    00984     // TODO: do a real timer and restart it after that
    00985     pendingMimeTypes.clear();
    00986     bool listDir = true;
    00987
    00988     if ( dirOnlyMode() )
    00989          view->setViewMode(KFileView::Directories);
    00990     else
    00991         view->setViewMode(KFileView::All);
    00992
    00993     if ( myMode & KFile::Files )
    00994         view->setSelectionMode( KFile::Extended );
    00995     else
    00996         view->setSelectionMode( KFile::Single );
    00997
    00998     if (m_fileView)
    00999     {
    01000         if ( d->config ) // save and restore the views' configuration
    01001         {
    01002             m_fileView->writeConfig( d->config, d->configGroup );
    01003             view->readConfig( d->config, d->configGroup );
    01004         }
    01005
    01006         // transfer the state from old view to new view
    01007         view->clear();
    01008         view->addItemList( *m_fileView->items() );
    01009         listDir = false;
    01010
    01011         if ( m_fileView->widget()->hasFocus() )
    01012             view->widget()->setFocus();
    01013
    01014         KFileItem *oldCurrentItem = m_fileView->currentFileItem();
    01015         if ( oldCurrentItem ) {
    01016             view->setCurrentItem( oldCurrentItem );
    01017             view->setSelected( oldCurrentItem, false );
    01018             view->ensureItemVisible( oldCurrentItem );
    01019         }
    01020
    01021         const KFileItemList *oldSelected = m_fileView->selectedItems();
    01022         if ( !oldSelected->isEmpty() ) {
    01023             KFileItemListIterator it( *oldSelected );
    01024             for ( ; it.current(); ++it )
    01025                 view->setSelected( it.current(), true );
    01026         }
    01027
    01028         m_fileView->widget()->hide();
    01029         delete m_fileView;
    01030     }
    01031
    01032     else
    01033     {
    01034         if ( d->config )
    01035             view->readConfig( d->config, d->configGroup );
    01036     }
    01037
    01038     m_fileView = view;
    01039     m_fileView->setDropOptions(d->dropOptions);
    01040     viewActionCollection = 0L;
    01041     KFileViewSignaler *sig = view->signaler();
    01042
    01043     connect(sig, SIGNAL( activatedMenu(const KFileItem *, const QPoint& ) ),
    01044             this, SLOT( activatedMenu(const KFileItem *, const QPoint& )));
    01045     connect(sig, SIGNAL( dirActivated(const KFileItem *) ),
    01046             this, SLOT( selectDir(const KFileItem*) ) );
    01047     connect(sig, SIGNAL( fileSelected(const KFileItem *) ),
    01048             this, SLOT( selectFile(const KFileItem*) ) );
    01049     connect(sig, SIGNAL( fileHighlighted(const KFileItem *) ),
    01050             this, SLOT( highlightFile(const KFileItem*) ));
    01051     connect(sig, SIGNAL( sortingChanged( QDir::SortSpec ) ),
    01052             this, SLOT( slotViewSortingChanged( QDir::SortSpec )));
    01053     connect(sig, SIGNAL( dropped(const KFileItem *, QDropEvent*, const KURL::List&) ),
    01054             this, SIGNAL( dropped(const KFileItem *, QDropEvent*, const KURL::List&)) );
    01055
    01056     if ( reverseAction->isChecked() != m_fileView->isReversed() )
    01057         slotSortReversed();
    01058
    01059     updateViewActions();
    01060     m_fileView->widget()->resize(size());
    01061     m_fileView->widget()->show();
    01062
    01063     if ( listDir ) {
    01064         QApplication::setOverrideCursor( waitCursor );
    01065         dir->openURL( currUrl );
    01066     }
    01067     else
    01068         view->listingCompleted();
    01069 }
    01070
    01071 KFile::Mode KDirOperator::mode() const
    01072 {
    01073     return myMode;
    01074 }
    01075
    01076 void KDirOperator::setMode(KFile::Mode m)
    01077 {
    01078     if (myMode == m)
    01079         return;
    01080
    01081     myMode = m;
    01082
    01083     dir->setDirOnlyMode( dirOnlyMode() );
    01084
    01085     // reset the view with the different mode
    01086     setView( static_cast<KFile::FileView>(m_viewKind) );
    01087 }
    01088
    01089 void KDirOperator::setView(KFileView *view)
    01090 {
    01091     if ( view == m_fileView ) {
    01092         return;
    01093     }
    01094
    01095     setFocusProxy(view->widget());
    01096     view->setSorting( mySorting );
    01097     view->setOnlyDoubleClickSelectsFiles( d->onlyDoubleClickSelectsFiles );
    01098     connectView(view); // also deletes the old view
    01099
    01100     emit viewChanged( view );
    01101 }
    01102
    01103 void KDirOperator::setDirLister( KDirLister *lister )
    01104 {
    01105     if ( lister == dir ) // sanity check
    01106         return;
    01107
    01108     delete dir;
    01109     dir = lister;
    01110
    01111     dir->setAutoUpdate( true );
    01112
    01113     QWidget* mainWidget = topLevelWidget();
    01114     dir->setMainWindow (mainWidget);
    01115     kdDebug (kfile_area) << "mainWidget=" << mainWidget << endl;
    01116
    01117     connect( dir, SIGNAL( percent( int )),
    01118              SLOT( slotProgress( int ) ));
    01119     connect( dir, SIGNAL(started( const KURL& )), SLOT(slotStarted()));
    01120     connect( dir, SIGNAL(newItems(const KFileItemList &)),
    01121              SLOT(insertNewFiles(const KFileItemList &)));
    01122     connect( dir, SIGNAL(completed()), SLOT(slotIOFinished()));
    01123     connect( dir, SIGNAL(canceled()), SLOT(slotCanceled()));
    01124     connect( dir, SIGNAL(deleteItem(KFileItem *)),
    01125              SLOT(itemDeleted(KFileItem *)));
    01126     connect( dir, SIGNAL(redirection( const KURL& )),
    01127          SLOT( slotRedirected( const KURL& )));
    01128     connect( dir, SIGNAL( clear() ), SLOT( slotClearView() ));
    01129     connect( dir, SIGNAL( refreshItems( const KFileItemList& ) ),
    01130              SLOT( slotRefreshItems( const KFileItemList& ) ) );
    01131 }
    01132
    01133 void KDirOperator::insertNewFiles(const KFileItemList &newone)
    01134 {
    01135     if ( newone.isEmpty() || !m_fileView )
    01136         return;
    01137
    01138     myCompleteListDirty = true;
    01139     m_fileView->addItemList( newone );
    01140     emit updateInformation(m_fileView->numDirs(), m_fileView->numFiles());
    01141
    01142     KFileItem *item;
    01143     KFileItemListIterator it( newone );
    01144
    01145     while ( (item = it.current()) ) {
    01146     // highlight the dir we come from, if possible
    01147     if ( d->dirHighlighting && item->isDir() &&
    01148          item->url().url(-1) == d->lastURL ) {
    01149         m_fileView->setCurrentItem( item );
    01150         m_fileView->ensureItemVisible( item );
    01151     }
    01152
    01153     ++it;
    01154     }
    01155
    01156     QTimer::singleShot(200, this, SLOT(resetCursor()));
    01157 }
    01158
    01159 void KDirOperator::selectDir(const KFileItem *item)
    01160 {
    01161     setURL(item->url(), true);
    01162 }
    01163
    01164 void KDirOperator::itemDeleted(KFileItem *item)
    01165 {
    01166     pendingMimeTypes.removeRef( item );
    01167     if ( m_fileView )
    01168     {
    01169         m_fileView->removeItem( static_cast<KFileItem *>( item ));
    01170         emit updateInformation(m_fileView->numDirs(), m_fileView->numFiles());
    01171     }
    01172 }
    01173
    01174 void KDirOperator::selectFile(const KFileItem *item)
    01175 {
    01176     QApplication::restoreOverrideCursor();
    01177
    01178     emit fileSelected( item );
    01179 }
    01180
    01181 void KDirOperator::setCurrentItem( const QString& filename )
    01182 {
    01183     if ( m_fileView ) {
    01184         const KFileItem *item = 0L;
    01185
    01186         if ( !filename.isNull() )
    01187             item = static_cast<KFileItem *>(dir->findByName( filename ));
    01188
    01189         m_fileView->clearSelection();
    01190         if ( item ) {
    01191             m_fileView->setCurrentItem( item );
    01192             m_fileView->setSelected( item, true );
    01193             m_fileView->ensureItemVisible( item );
    01194         }
    01195     }
    01196 }
    01197
    01198 QString KDirOperator::makeCompletion(const QString& string)
    01199 {
    01200     if ( string.isEmpty() ) {
    01201         m_fileView->clearSelection();
    01202         return QString::null;
    01203     }
    01204
    01205     prepareCompletionObjects();
    01206     return myCompletion.makeCompletion( string );
    01207 }
    01208
    01209 QString KDirOperator::makeDirCompletion(const QString& string)
    01210 {
    01211     if ( string.isEmpty() ) {
    01212         m_fileView->clearSelection();
    01213         return QString::null;
    01214     }
    01215
    01216     prepareCompletionObjects();
    01217     return myDirCompletion.makeCompletion( string );
    01218 }
    01219
    01220 void KDirOperator::prepareCompletionObjects()
    01221 {
    01222     if ( !m_fileView )
    01223     return;
    01224
    01225     if ( myCompleteListDirty ) { // create the list of all possible completions
    01226         KFileItemListIterator it( *(m_fileView->items()) );
    01227         for( ; it.current(); ++it ) {
    01228             KFileItem *item = it.current();
    01229
    01230             myCompletion.addItem( item->name() );
    01231             if ( item->isDir() )
    01232                 myDirCompletion.addItem( item->name() );
    01233         }
    01234         myCompleteListDirty = false;
    01235     }
    01236 }
    01237
    01238 void KDirOperator::slotCompletionMatch(const QString& match)
    01239 {
    01240     setCurrentItem( match );
    01241     emit completion( match );
    01242 }
    01243
    01244 void KDirOperator::setupActions()
    01245 {
    01246     myActionCollection = new KActionCollection( this, "KDirOperator::myActionCollection" );
    01247     actionMenu = new KActionMenu( i18n("Menu"), myActionCollection, "popupMenu" );
    01248     upAction = KStdAction::up( this, SLOT( cdUp() ), myActionCollection, "up" );
    01249     upAction->setText( i18n("Parent Folder") );
    01250     backAction = KStdAction::back( this, SLOT( back() ), myActionCollection, "back" );
    01251     forwardAction = KStdAction::forward( this, SLOT(forward()), myActionCollection, "forward" );
    01252     homeAction = KStdAction::home( this, SLOT( home() ), myActionCollection, "home" );
    01253     homeAction->setText(i18n("Home Folder"));
    01254     reloadAction = KStdAction::redisplay( this, SLOT(rereadDir()), myActionCollection, "reload" );
    01255     actionSeparator = new KActionSeparator( myActionCollection, "separator" );
    01256     d->viewActionSeparator = new KActionSeparator( myActionCollection,
    01257                                                    "viewActionSeparator" );
    01258     mkdirAction = new KAction( i18n("New Folder..."), 0,
    01259                                  this, SLOT( mkdir() ), myActionCollection, "mkdir" );
    01260     KAction* trash = new KAction( i18n( "Move to Trash" ), "edittrash", Key_Delete, myActionCollection, "trash" );
    01261     connect( trash, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ),
    01262          this, SLOT( trashSelected( KAction::ActivationReason, Qt::ButtonState ) ) );
    01263     new KAction( i18n( "Delete" ), "editdelete", SHIFT+Key_Delete, this,
    01264                   SLOT( deleteSelected() ), myActionCollection, "delete" );
    01265     mkdirAction->setIcon( QString::fromLatin1("folder_new") );
    01266     reloadAction->setText( i18n("Reload") );
    01267     reloadAction->setShortcut( KStdAccel::shortcut( KStdAccel::Reload ));
    01268
    01269
    01270     // the sort menu actions
    01271     sortActionMenu = new KActionMenu( i18n("Sorting"), myActionCollection, "sorting menu");
    01272     byNameAction = new KRadioAction( i18n("By Name"), 0,
    01273                                      this, SLOT( slotSortByName() ),
    01274                                      myActionCollection, "by name" );
    01275     byDateAction = new KRadioAction( i18n("By Date"), 0,
    01276                                      this, SLOT( slotSortByDate() ),
    01277                                      myActionCollection, "by date" );
    01278     bySizeAction = new KRadioAction( i18n("By Size"), 0,
    01279                                      this, SLOT( slotSortBySize() ),
    01280                                      myActionCollection, "by size" );
    01281     reverseAction = new KToggleAction( i18n("Reverse"), 0,
    01282                                        this, SLOT( slotSortReversed() ),
    01283                                        myActionCollection, "reversed" );
    01284
    01285     QString sortGroup = QString::fromLatin1("sort");
    01286     byNameAction->setExclusiveGroup( sortGroup );
    01287     byDateAction->setExclusiveGroup( sortGroup );
    01288     bySizeAction->setExclusiveGroup( sortGroup );
    01289
    01290
    01291     dirsFirstAction = new KToggleAction( i18n("Folders First"), 0,
    01292                                          myActionCollection, "dirs first");
    01293     caseInsensitiveAction = new KToggleAction(i18n("Case Insensitive"), 0,
    01294                                               myActionCollection, "case insensitive" );
    01295
    01296     connect( dirsFirstAction, SIGNAL( toggled( bool ) ),
    01297              SLOT( slotToggleDirsFirst() ));
    01298     connect( caseInsensitiveAction, SIGNAL( toggled( bool ) ),
    01299              SLOT( slotToggleIgnoreCase() ));
    01300
    01301
    01302
    01303     // the view menu actions
    01304     viewActionMenu = new KActionMenu( i18n("&View"), myActionCollection, "view menu" );
    01305     connect( viewActionMenu->popupMenu(), SIGNAL( aboutToShow() ),
    01306              SLOT( insertViewDependentActions() ));
    01307
    01308     shortAction = new KRadioAction( i18n("Short View"), "view_multicolumn",
    01309                                     KShortcut(), myActionCollection, "short view" );
    01310     detailedAction = new KRadioAction( i18n("Detailed View"), "view_detailed",
    01311                                        KShortcut(), myActionCollection, "detailed view" );
    01312
    01313     showHiddenAction = new KToggleAction( i18n("Show Hidden Files"), KShortcut(),
    01314                                           myActionCollection, "show hidden" );
    01315 //    showHiddenAction->setCheckedState( i18n("Hide Hidden Files") );
    01316     separateDirsAction = new KToggleAction( i18n("Separate Folders"), KShortcut(),
    01317                                             this,
    01318                                             SLOT(slotSeparateDirs()),
    01319                                             myActionCollection, "separate dirs" );
    01320     KToggleAction *previewAction = new KToggleAction(i18n("Show Preview"),
    01321                                                      "thumbnail", KShortcut(),
    01322                                                      myActionCollection,
    01323                                                      "preview" );
    01324     previewAction->setCheckedState(i18n("Hide Preview"));
    01325     connect( previewAction, SIGNAL( toggled( bool )),
    01326              SLOT( togglePreview( bool )));
    01327
    01328
    01329     QString viewGroup = QString::fromLatin1("view");
    01330     shortAction->setExclusiveGroup( viewGroup );
    01331     detailedAction->setExclusiveGroup( viewGroup );
    01332
    01333     connect( shortAction, SIGNAL( activated() ),
    01334              SLOT( slotSimpleView() ));
    01335     connect( detailedAction, SIGNAL( activated() ),
    01336              SLOT( slotDetailedView() ));
    01337     connect( showHiddenAction, SIGNAL( toggled( bool ) ),
    01338              SLOT( slotToggleHidden( bool ) ));
    01339
    01340     new KAction( i18n("Properties"), KShortcut(ALT+Key_Return), this,
    01341                  SLOT(slotProperties()), myActionCollection, "properties" );
    01342 }
    01343
    01344 void KDirOperator::setupMenu()
    01345 {
    01346     setupMenu(AllActions);
    01347 }
    01348
    01349 void KDirOperator::setupMenu(int whichActions)
    01350 {
    01351     // first fill the submenus (sort and view)
    01352     sortActionMenu->popupMenu()->clear();
    01353     sortActionMenu->insert( byNameAction );
    01354     sortActionMenu->insert( byDateAction );
    01355     sortActionMenu->insert( bySizeAction );
    01356     sortActionMenu->insert( actionSeparator );
    01357     sortActionMenu->insert( reverseAction );
    01358     sortActionMenu->insert( dirsFirstAction );
    01359     sortActionMenu->insert( caseInsensitiveAction );
    01360
    01361     // now plug everything into the popupmenu
    01362     actionMenu->popupMenu()->clear();
    01363     if (whichActions & NavActions)
    01364     {
    01365         actionMenu->insert( upAction );
    01366         actionMenu->insert( backAction );
    01367         actionMenu->insert( forwardAction );
    01368         actionMenu->insert( homeAction );
    01369         actionMenu->insert( actionSeparator );
    01370     }
    01371
    01372     if (whichActions & FileActions)
    01373     {
    01374         actionMenu->insert( mkdirAction );
    01375         if (currUrl.isLocalFile() && !(KApplication::keyboardMouseState() & Qt::ShiftButton))
    01376             actionMenu->insert( myActionCollection->action( "trash" ) );
    01377         KConfig *globalconfig = KGlobal::config();
    01378         KConfigGroupSaver cs( globalconfig, QString::fromLatin1("KDE") );
    01379         if (!currUrl.isLocalFile() || (KApplication::keyboardMouseState() & Qt::ShiftButton) ||
    01380             globalconfig->readBoolEntry("ShowDeleteCommand", false))
    01381             actionMenu->insert( myActionCollection->action( "delete" ) );
    01382         actionMenu->insert( actionSeparator );
    01383     }
    01384
    01385     if (whichActions & SortActions)
    01386     {
    01387         actionMenu->insert( sortActionMenu );
    01388         actionMenu->insert( actionSeparator );
    01389     }
    01390
    01391     if (whichActions & ViewActions)
    01392     {
    01393         actionMenu->insert( viewActionMenu );
    01394         actionMenu->insert( actionSeparator );
    01395     }
    01396
    01397     if (whichActions & FileActions)
    01398     {
    01399         actionMenu->insert( myActionCollection->action( "properties" ) );
    01400     }
    01401 }
    01402
    01403 void KDirOperator::updateSortActions()
    01404 {
    01405     if ( KFile::isSortByName( mySorting ) )
    01406         byNameAction->setChecked( true );
    01407     else if ( KFile::isSortByDate( mySorting ) )
    01408         byDateAction->setChecked( true );
    01409     else if ( KFile::isSortBySize( mySorting ) )
    01410         bySizeAction->setChecked( true );
    01411
    01412     dirsFirstAction->setChecked( KFile::isSortDirsFirst( mySorting ) );
    01413     caseInsensitiveAction->setChecked( KFile::isSortCaseInsensitive(mySorting) );
    01414     caseInsensitiveAction->setEnabled( KFile::isSortByName( mySorting ) );
    01415
    01416     if ( m_fileView )
    01417         reverseAction->setChecked( m_fileView->isReversed() );
    01418 }
    01419
    01420 void KDirOperator::updateViewActions()
    01421 {
    01422     KFile::FileView fv = static_cast<KFile::FileView>( m_viewKind );
    01423
    01424     separateDirsAction->setChecked( KFile::isSeparateDirs( fv ) &&
    01425                                     separateDirsAction->isEnabled() );
    01426
    01427     shortAction->setChecked( KFile::isSimpleView( fv ));
    01428     detailedAction->setChecked( KFile::isDetailView( fv ));
    01429 }
    01430
    01431 void KDirOperator::readConfig( KConfig *kc, const QString& group )
    01432 {
    01433     if ( !kc )
    01434         return;
    01435     QString oldGroup = kc->group();
    01436     if ( !group.isEmpty() )
    01437         kc->setGroup( group );
    01438
    01439     defaultView = 0;
    01440     int sorting = 0;
    01441
    01442     QString viewStyle = kc->readEntry( QString::fromLatin1("View Style"),
    01443                                        QString::fromLatin1("Simple") );
    01444     if ( viewStyle == QString::fromLatin1("Detail") )
    01445         defaultView |= KFile::Detail;
    01446     else
    01447         defaultView |= KFile::Simple;
    01448     if ( kc->readBoolEntry( QString::fromLatin1("Separate Directories"),
    01449                             DefaultMixDirsAndFiles ) )
    01450         defaultView |= KFile::SeparateDirs;
    01451     if ( kc->readBoolEntry(QString::fromLatin1("Show Preview"), false))
    01452         defaultView |= KFile::PreviewContents;
    01453
    01454     if ( kc->readBoolEntry( QString::fromLatin1("Sort case insensitively"),
    01455                             DefaultCaseInsensitive ) )
    01456         sorting |= QDir::IgnoreCase;
    01457     if ( kc->readBoolEntry( QString::fromLatin1("Sort directories first"),
    01458                             DefaultDirsFirst ) )
    01459         sorting |= QDir::DirsFirst;
    01460
    01461
    01462     QString name = QString::fromLatin1("Name");
    01463     QString sortBy = kc->readEntry( QString::fromLatin1("Sort by"), name );
    01464     if ( sortBy == name )
    01465         sorting |= QDir::Name;
    01466     else if ( sortBy == QString::fromLatin1("Size") )
    01467         sorting |= QDir::Size;
    01468     else if ( sortBy == QString::fromLatin1("Date") )
    01469         sorting |= QDir::Time;
    01470
    01471     mySorting = static_cast<QDir::SortSpec>( sorting );
    01472     setSorting( mySorting );
    01473
    01474
    01475     if ( kc->readBoolEntry( QString::fromLatin1("Show hidden files"),
    01476                             DefaultShowHidden ) ) {
    01477          showHiddenAction->setChecked( true );
    01478          dir->setShowingDotFiles( true );
    01479     }
    01480     if ( kc->readBoolEntry( QString::fromLatin1("Sort reversed"),
    01481                             DefaultSortReversed ) )
    01482         reverseAction->setChecked( true );
    01483
    01484     kc->setGroup( oldGroup );
    01485 }
    01486
    01487 void KDirOperator::writeConfig( KConfig *kc, const QString& group )
    01488 {
    01489     if ( !kc )
    01490         return;
    01491
    01492     const QString oldGroup = kc->group();
    01493
    01494     if ( !group.isEmpty() )
    01495         kc->setGroup( group );
    01496
    01497     QString sortBy = QString::fromLatin1("Name");
    01498     if ( KFile::isSortBySize( mySorting ) )
    01499         sortBy = QString::fromLatin1("Size");
    01500     else if ( KFile::isSortByDate( mySorting ) )
    01501         sortBy = QString::fromLatin1("Date");
    01502     kc->writeEntry( QString::fromLatin1("Sort by"), sortBy );
    01503
    01504     kc->writeEntry( QString::fromLatin1("Sort reversed"),
    01505                     reverseAction->isChecked() );
    01506     kc->writeEntry( QString::fromLatin1("Sort case insensitively"),
    01507                     caseInsensitiveAction->isChecked() );
    01508     kc->writeEntry( QString::fromLatin1("Sort directories first"),
    01509                     dirsFirstAction->isChecked() );
    01510
    01511     // don't save the separate dirs or preview when an application specific
    01512     // preview is in use.
    01513     bool appSpecificPreview = false;
    01514     if ( myPreview ) {
    01515         QWidget *preview = const_cast<QWidget*>( myPreview ); // grmbl
    01516         KFileMetaPreview *tmp = dynamic_cast<KFileMetaPreview*>( preview );
    01517         appSpecificPreview = (tmp == 0L);
    01518     }
    01519
    01520     if ( !appSpecificPreview ) {
    01521         if ( separateDirsAction->isEnabled() )
    01522             kc->writeEntry( QString::fromLatin1("Separate Directories"),
    01523                             separateDirsAction->isChecked() );
    01524
    01525         KToggleAction *previewAction = static_cast<KToggleAction*>(myActionCollection->action("preview"));
    01526         if ( previewAction->isEnabled() ) {
    01527             bool hasPreview = previewAction->isChecked();
    01528             kc->writeEntry( QString::fromLatin1("Show Preview"), hasPreview );
    01529         }
    01530     }
    01531
    01532     kc->writeEntry( QString::fromLatin1("Show hidden files"),
    01533                     showHiddenAction->isChecked() );
    01534
    01535     KFile::FileView fv = static_cast<KFile::FileView>( m_viewKind );
    01536     QString style;
    01537     if ( KFile::isDetailView( fv ) )
    01538         style = QString::fromLatin1("Detail");
    01539     else if ( KFile::isSimpleView( fv ) )
    01540         style = QString::fromLatin1("Simple");
    01541     kc->writeEntry( QString::fromLatin1("View Style"), style );
    01542
    01543     kc->setGroup( oldGroup );
    01544 }
    01545
    01546
    01547 void KDirOperator::resizeEvent( QResizeEvent * )
    01548 {
    01549     if (m_fileView)
    01550         m_fileView->widget()->resize( size() );
    01551
    01552     if ( progress->parent() == this ) // might be reparented into a statusbar
    01553     progress->move(2, height() - progress->height() -2);
    01554 }
    01555
    01556 void KDirOperator::setOnlyDoubleClickSelectsFiles( bool enable )
    01557 {
    01558     d->onlyDoubleClickSelectsFiles = enable;
    01559     if ( m_fileView )
    01560         m_fileView->setOnlyDoubleClickSelectsFiles( enable );
    01561 }
    01562
    01563 bool KDirOperator::onlyDoubleClickSelectsFiles() const
    01564 {
    01565     return d->onlyDoubleClickSelectsFiles;
    01566 }
    01567
    01568 void KDirOperator::slotStarted()
    01569 {
    01570     progress->setProgress( 0 );
    01571     // delay showing the progressbar for one second
    01572     d->progressDelayTimer->start( 1000, true );
    01573 }
    01574
    01575 void KDirOperator::slotShowProgress()
    01576 {
    01577     progress->raise();
    01578     progress->show();
    01579     QApplication::flushX();
    01580 }
    01581
    01582 void KDirOperator::slotProgress( int percent )
    01583 {
    01584     progress->setProgress( percent );
    01585     // we have to redraw this as fast as possible
    01586     if ( progress->isVisible() )
    01587     QApplication::flushX();
    01588 }
    01589
    01590
    01591 void KDirOperator::slotIOFinished()
    01592 {
    01593     d->progressDelayTimer->stop();
    01594     slotProgress( 100 );
    01595     progress->hide();
    01596     emit finishedLoading();
    01597     resetCursor();
    01598
    01599     if ( m_fileView )
    01600         m_fileView->listingCompleted();
    01601 }
    01602
    01603 void KDirOperator::slotCanceled()
    01604 {
    01605     emit finishedLoading();
    01606     resetCursor();
    01607
    01608     if ( m_fileView )
    01609         m_fileView->listingCompleted();
    01610 }
    01611
    01612 KProgress * KDirOperator::progressBar() const
    01613 {
    01614     return progress;
    01615 }
    01616
    01617 void KDirOperator::clearHistory()
    01618 {
    01619     backStack.clear();
    01620     backAction->setEnabled( false );
    01621     forwardStack.clear();
    01622     forwardAction->setEnabled( false );
    01623 }
    01624
    01625 void KDirOperator::slotViewActionAdded( KAction *action )
    01626 {
    01627     if ( viewActionMenu->popupMenu()->count() == 5 ) // need to add a separator
    01628     viewActionMenu->insert( d->viewActionSeparator );
    01629
    01630     viewActionMenu->insert( action );
    01631 }
    01632
    01633 void KDirOperator::slotViewActionRemoved( KAction *action )
    01634 {
    01635     viewActionMenu->remove( action );
    01636
    01637     if ( viewActionMenu->popupMenu()->count() == 6 ) // remove the separator
    01638     viewActionMenu->remove( d->viewActionSeparator );
    01639 }
    01640
    01641 void KDirOperator::slotViewSortingChanged( QDir::SortSpec sort )
    01642 {
    01643     mySorting = sort;
    01644     updateSortActions();
    01645 }
    01646
    01647 void KDirOperator::setEnableDirHighlighting( bool enable )
    01648 {
    01649     d->dirHighlighting = enable;
    01650 }
    01651
    01652 bool KDirOperator::dirHighlighting() const
    01653 {
    01654     return d->dirHighlighting;
    01655 }
    01656
    01657 void KDirOperator::slotProperties()
    01658 {
    01659     if ( m_fileView ) {
    01660         const KFileItemList *list = m_fileView->selectedItems();
    01661         if ( !list->isEmpty() )
    01662             (void) new KPropertiesDialog( *list, this, "props dlg", true);
    01663     }
    01664 }
    01665
    01666 void KDirOperator::slotClearView()
    01667 {
    01668     if ( m_fileView )
    01669         m_fileView->clearView();
    01670 }
    01671
    01672 // ### temporary code
    01673 #include <dirent.h>
    01674 bool KDirOperator::isReadable( const KURL& url )
    01675 {
    01676     if ( !url.isLocalFile() )
    01677     return true; // what else can we say?
    01678
    01679     KDE_struct_stat buf;
    01680     QString ts = url.path(+1);
    01681     bool readable = ( KDE_stat( QFile::encodeName( ts ), &buf) == 0 );
    01682     if (readable) { // further checks
    01683     DIR *test;
    01684     test = opendir( QFile::encodeName( ts )); // we do it just to test here
    01685     readable = (test != 0);
    01686     if (test)
    01687         closedir(test);
    01688     }
    01689     return readable;
    01690 }
    01691
    01692 void KDirOperator::togglePreview( bool on )
    01693 {
    01694     if ( on )
    01695         slotDefaultPreview();
    01696     else
    01697         setView( (KFile::FileView) (m_viewKind & ~(KFile::PreviewContents|KFile::PreviewInfo)) );
    01698 }
    01699
    01700 void KDirOperator::slotRefreshItems( const KFileItemList& items )
    01701 {
    01702     if ( !m_fileView )
    01703         return;
    01704
    01705     KFileItemListIterator it( items );
    01706     for ( ; it.current(); ++it )
    01707         m_fileView->updateView( it.current() );
    01708 }
    01709
    01710 void KDirOperator::setViewConfig( KConfig *config, const QString& group )
    01711 {
    01712     d->config = config;
    01713     d->configGroup = group;
    01714 }
    01715
    01716 KConfig * KDirOperator::viewConfig()
    01717 {
    01718     return d->config;
    01719 }
    01720
    01721 QString KDirOperator::viewConfigGroup() const
    01722 {
    01723     return d->configGroup;
    01724 }
    01725
    01726 void KDirOperator::virtual_hook( int, void* )
    01727 { /*BASE::virtual_hook( id, data );*/ }
    01728
    01729 #include "kdiroperator.moc"

This file is part of the documentation for kio Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:23:56 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003