diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | ce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch) | |
tree | 5ac38a06f3dde268dc7927dc155896926aaf7012 /kio/kfile/kdiroperator.cpp | |
download | tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kio/kfile/kdiroperator.cpp')
-rw-r--r-- | kio/kfile/kdiroperator.cpp | 1740 |
1 files changed, 1740 insertions, 0 deletions
diff --git a/kio/kfile/kdiroperator.cpp b/kio/kfile/kdiroperator.cpp new file mode 100644 index 000000000..b12e45153 --- /dev/null +++ b/kio/kfile/kdiroperator.cpp @@ -0,0 +1,1740 @@ +/* This file is part of the KDE libraries + Copyright (C) 1999,2000 Stephan Kulow <coolo@kde.org> + 1999,2000,2001,2002,2003 Carsten Pfeiffer <pfeiffer@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <unistd.h> + +#include <qdir.h> +#include <qapplication.h> +#include <qdialog.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qpopupmenu.h> +#include <qregexp.h> +#include <qtimer.h> +#include <qvbox.h> + +#include <kaction.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kdialog.h> +#include <kdialogbase.h> +#include <kdirlister.h> +#include <kinputdialog.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kpopupmenu.h> +#include <kprogress.h> +#include <kstdaction.h> +#include <kio/job.h> +#include <kio/jobclasses.h> +#include <kio/netaccess.h> +#include <kio/previewjob.h> +#include <kio/renamedlg.h> +#include <kpropertiesdialog.h> +#include <kservicetypefactory.h> +#include <kstdaccel.h> +#include <kde_file.h> + +#include "config-kfile.h" +#include "kcombiview.h" +#include "kdiroperator.h" +#include "kfiledetailview.h" +#include "kfileiconview.h" +#include "kfilepreview.h" +#include "kfileview.h" +#include "kfileitem.h" +#include "kfilemetapreview.h" + + +template class QPtrStack<KURL>; +template class QDict<KFileItem>; + + +class KDirOperator::KDirOperatorPrivate +{ +public: + KDirOperatorPrivate() { + onlyDoubleClickSelectsFiles = false; + progressDelayTimer = 0L; + dirHighlighting = false; + config = 0L; + dropOptions = 0; + } + + ~KDirOperatorPrivate() { + delete progressDelayTimer; + } + + bool dirHighlighting; + QString lastURL; // used for highlighting a directory on cdUp + bool onlyDoubleClickSelectsFiles; + QTimer *progressDelayTimer; + KActionSeparator *viewActionSeparator; + int dropOptions; + + KConfig *config; + QString configGroup; +}; + +KDirOperator::KDirOperator(const KURL& _url, + QWidget *parent, const char* _name) + : QWidget(parent, _name), + dir(0), + m_fileView(0), + progress(0) +{ + myPreview = 0L; + myMode = KFile::File; + m_viewKind = KFile::Simple; + mySorting = static_cast<QDir::SortSpec>(QDir::Name | QDir::DirsFirst); + d = new KDirOperatorPrivate; + + if (_url.isEmpty()) { // no dir specified -> current dir + QString strPath = QDir::currentDirPath(); + strPath.append('/'); + currUrl = KURL(); + currUrl.setProtocol(QString::fromLatin1("file")); + currUrl.setPath(strPath); + } + else { + currUrl = _url; + if ( currUrl.protocol().isEmpty() ) + currUrl.setProtocol(QString::fromLatin1("file")); + + currUrl.addPath("/"); // make sure we have a trailing slash! + } + + setDirLister( new KDirLister( true ) ); + + connect(&myCompletion, SIGNAL(match(const QString&)), + SLOT(slotCompletionMatch(const QString&))); + + progress = new KProgress(this, "progress"); + progress->adjustSize(); + progress->move(2, height() - progress->height() -2); + + d->progressDelayTimer = new QTimer( this, "progress delay timer" ); + connect( d->progressDelayTimer, SIGNAL( timeout() ), + SLOT( slotShowProgress() )); + + myCompleteListDirty = false; + + backStack.setAutoDelete( true ); + forwardStack.setAutoDelete( true ); + + // action stuff + setupActions(); + setupMenu(); + + setFocusPolicy(QWidget::WheelFocus); +} + +KDirOperator::~KDirOperator() +{ + resetCursor(); + if ( m_fileView ) + { + if ( d->config ) + m_fileView->writeConfig( d->config, d->configGroup ); + + delete m_fileView; + m_fileView = 0L; + } + + delete myPreview; + delete dir; + delete d; +} + + +void KDirOperator::setSorting( QDir::SortSpec spec ) +{ + if ( m_fileView ) + m_fileView->setSorting( spec ); + mySorting = spec; + updateSortActions(); +} + +void KDirOperator::resetCursor() +{ + QApplication::restoreOverrideCursor(); + progress->hide(); +} + +void KDirOperator::insertViewDependentActions() +{ + // If we have a new view actionCollection(), insert its actions + // into viewActionMenu. + + if( !m_fileView ) + return; + + if ( (viewActionMenu->popupMenu()->count() == 0) || // Not yet initialized or... + (viewActionCollection != m_fileView->actionCollection()) ) // ...changed since. + { + if (viewActionCollection) + { + disconnect( viewActionCollection, SIGNAL( inserted( KAction * )), + this, SLOT( slotViewActionAdded( KAction * ))); + disconnect( viewActionCollection, SIGNAL( removed( KAction * )), + this, SLOT( slotViewActionRemoved( KAction * ))); + } + + viewActionMenu->popupMenu()->clear(); +// viewActionMenu->insert( shortAction ); +// viewActionMenu->insert( detailedAction ); +// viewActionMenu->insert( actionSeparator ); + viewActionMenu->insert( myActionCollection->action( "short view" ) ); + viewActionMenu->insert( myActionCollection->action( "detailed view" ) ); + viewActionMenu->insert( actionSeparator ); + viewActionMenu->insert( showHiddenAction ); +// viewActionMenu->insert( myActionCollection->action( "single" )); + viewActionMenu->insert( separateDirsAction ); + // Warning: adjust slotViewActionAdded() and slotViewActionRemoved() + // when you add/remove actions here! + + viewActionCollection = m_fileView->actionCollection(); + if (!viewActionCollection) + return; + + if ( !viewActionCollection->isEmpty() ) + { + viewActionMenu->insert( d->viewActionSeparator ); + + // first insert the normal actions, then the grouped ones + QStringList groups = viewActionCollection->groups(); + groups.prepend( QString::null ); // actions without group + QStringList::ConstIterator git = groups.begin(); + KActionPtrList list; + KAction *sep = actionCollection()->action("separator"); + for ( ; git != groups.end(); ++git ) + { + if ( git != groups.begin() ) + viewActionMenu->insert( sep ); + + list = viewActionCollection->actions( *git ); + KActionPtrList::ConstIterator it = list.begin(); + for ( ; it != list.end(); ++it ) + viewActionMenu->insert( *it ); + } + } + + connect( viewActionCollection, SIGNAL( inserted( KAction * )), + SLOT( slotViewActionAdded( KAction * ))); + connect( viewActionCollection, SIGNAL( removed( KAction * )), + SLOT( slotViewActionRemoved( KAction * ))); + } +} + +void KDirOperator::activatedMenu( const KFileItem *, const QPoint& pos ) +{ + setupMenu(); + updateSelectionDependentActions(); + + actionMenu->popup( pos ); +} + +void KDirOperator::updateSelectionDependentActions() +{ + bool hasSelection = m_fileView && m_fileView->selectedItems() && + !m_fileView->selectedItems()->isEmpty(); + myActionCollection->action( "trash" )->setEnabled( hasSelection ); + myActionCollection->action( "delete" )->setEnabled( hasSelection ); + myActionCollection->action( "properties" )->setEnabled( hasSelection ); +} + +void KDirOperator::setPreviewWidget(const QWidget *w) +{ + if(w != 0L) + m_viewKind = (m_viewKind | KFile::PreviewContents); + else + m_viewKind = (m_viewKind & ~KFile::PreviewContents); + + delete myPreview; + myPreview = w; + + KToggleAction *preview = static_cast<KToggleAction*>(myActionCollection->action("preview")); + preview->setEnabled( w != 0L ); + preview->setChecked( w != 0L ); + setView( static_cast<KFile::FileView>(m_viewKind) ); +} + +int KDirOperator::numDirs() const +{ + return m_fileView ? m_fileView->numDirs() : 0; +} + +int KDirOperator::numFiles() const +{ + return m_fileView ? m_fileView->numFiles() : 0; +} + +void KDirOperator::slotDetailedView() +{ + KFile::FileView view = static_cast<KFile::FileView>( (m_viewKind & ~KFile::Simple) | KFile::Detail ); + setView( view ); +} + +void KDirOperator::slotSimpleView() +{ + KFile::FileView view = static_cast<KFile::FileView>( (m_viewKind & ~KFile::Detail) | KFile::Simple ); + setView( view ); +} + +void KDirOperator::slotToggleHidden( bool show ) +{ + dir->setShowingDotFiles( show ); + updateDir(); + if ( m_fileView ) + m_fileView->listingCompleted(); +} + +void KDirOperator::slotSeparateDirs() +{ + if (separateDirsAction->isChecked()) + { + KFile::FileView view = static_cast<KFile::FileView>( m_viewKind | KFile::SeparateDirs ); + setView( view ); + } + else + { + KFile::FileView view = static_cast<KFile::FileView>( m_viewKind & ~KFile::SeparateDirs ); + setView( view ); + } +} + +void KDirOperator::slotDefaultPreview() +{ + m_viewKind = m_viewKind | KFile::PreviewContents; + if ( !myPreview ) { + myPreview = new KFileMetaPreview( this ); + (static_cast<KToggleAction*>( myActionCollection->action("preview") ))->setChecked(true); + } + + setView( static_cast<KFile::FileView>(m_viewKind) ); +} + +void KDirOperator::slotSortByName() +{ + int sorting = (m_fileView->sorting()) & ~QDir::SortByMask; + m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Name )); + mySorting = m_fileView->sorting(); + caseInsensitiveAction->setEnabled( true ); +} + +void KDirOperator::slotSortBySize() +{ + int sorting = (m_fileView->sorting()) & ~QDir::SortByMask; + m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Size )); + mySorting = m_fileView->sorting(); + caseInsensitiveAction->setEnabled( false ); +} + +void KDirOperator::slotSortByDate() +{ + int sorting = (m_fileView->sorting()) & ~QDir::SortByMask; + m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Time )); + mySorting = m_fileView->sorting(); + caseInsensitiveAction->setEnabled( false ); +} + +void KDirOperator::slotSortReversed() +{ + if ( m_fileView ) + m_fileView->sortReversed(); +} + +void KDirOperator::slotToggleDirsFirst() +{ + QDir::SortSpec sorting = m_fileView->sorting(); + if ( !KFile::isSortDirsFirst( sorting ) ) + m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::DirsFirst )); + else + m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting & ~QDir::DirsFirst)); + mySorting = m_fileView->sorting(); +} + +void KDirOperator::slotToggleIgnoreCase() +{ + QDir::SortSpec sorting = m_fileView->sorting(); + if ( !KFile::isSortCaseInsensitive( sorting ) ) + m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting | QDir::IgnoreCase )); + else + m_fileView->setSorting( static_cast<QDir::SortSpec>( sorting & ~QDir::IgnoreCase)); + mySorting = m_fileView->sorting(); +} + +void KDirOperator::mkdir() +{ + bool ok; + QString where = url().pathOrURL(); + QString name = i18n( "New Folder" ); + if ( url().isLocalFile() && QFileInfo( url().path(+1) + name ).exists() ) + name = KIO::RenameDlg::suggestName( url(), name ); + + QString dir = KInputDialog::getText( i18n( "New Folder" ), + i18n( "Create new folder in:\n%1" ).arg( where ), + name, &ok, this); + if (ok) + mkdir( KIO::encodeFileName( dir ), true ); +} + +bool KDirOperator::mkdir( const QString& directory, bool enterDirectory ) +{ + // Creates "directory", relative to the current directory (currUrl). + // The given path may contain any number directories, existant or not. + // They will all be created, if possible. + + bool writeOk = false; + bool exists = false; + KURL url( currUrl ); + + QStringList dirs = QStringList::split( QDir::separator(), directory ); + QStringList::ConstIterator it = dirs.begin(); + + for ( ; it != dirs.end(); ++it ) + { + url.addPath( *it ); + exists = KIO::NetAccess::exists( url, false, 0 ); + writeOk = !exists && KIO::NetAccess::mkdir( url, topLevelWidget() ); + } + + if ( exists ) // url was already existant + { + KMessageBox::sorry(viewWidget(), i18n("A file or folder named %1 already exists.").arg(url.pathOrURL())); + enterDirectory = false; + } + else if ( !writeOk ) { + KMessageBox::sorry(viewWidget(), i18n("You do not have permission to " + "create that folder." )); + } + else if ( enterDirectory ) { + setURL( url, true ); + } + + return writeOk; +} + +KIO::DeleteJob * KDirOperator::del( const KFileItemList& items, + bool ask, bool showProgress ) +{ + return del( items, this, ask, showProgress ); +} + +KIO::DeleteJob * KDirOperator::del( const KFileItemList& items, + QWidget *parent, + bool ask, bool showProgress ) +{ + if ( items.isEmpty() ) { + KMessageBox::information( parent, + i18n("You did not select a file to delete."), + i18n("Nothing to Delete") ); + return 0L; + } + + KURL::List urls; + QStringList files; + KFileItemListIterator it( items ); + + for ( ; it.current(); ++it ) { + KURL url = (*it)->url(); + urls.append( url ); + if ( url.isLocalFile() ) + files.append( url.path() ); + else + files.append( url.prettyURL() ); + } + + bool doIt = !ask; + if ( ask ) { + int ret; + if ( items.count() == 1 ) { + ret = KMessageBox::warningContinueCancel( parent, + i18n( "<qt>Do you really want to delete\n <b>'%1'</b>?</qt>" ) + .arg( files.first() ), + i18n("Delete File"), + KStdGuiItem::del(), "AskForDelete" ); + } + else + ret = KMessageBox::warningContinueCancelList( parent, + i18n("Do you really want to delete this item?", "Do you really want to delete these %n items?", items.count() ), + files, + i18n("Delete Files"), + KStdGuiItem::del(), "AskForDelete" ); + doIt = (ret == KMessageBox::Continue); + } + + if ( doIt ) { + KIO::DeleteJob *job = KIO::del( urls, false, showProgress ); + job->setWindow (topLevelWidget()); + job->setAutoErrorHandlingEnabled( true, parent ); + return job; + } + + return 0L; +} + +void KDirOperator::deleteSelected() +{ + if ( !m_fileView ) + return; + + const KFileItemList *list = m_fileView->selectedItems(); + if ( list ) + del( *list ); +} + +KIO::CopyJob * KDirOperator::trash( const KFileItemList& items, + QWidget *parent, + bool ask, bool showProgress ) +{ + if ( items.isEmpty() ) { + KMessageBox::information( parent, + i18n("You did not select a file to trash."), + i18n("Nothing to Trash") ); + return 0L; + } + + KURL::List urls; + QStringList files; + KFileItemListIterator it( items ); + + for ( ; it.current(); ++it ) { + KURL url = (*it)->url(); + urls.append( url ); + if ( url.isLocalFile() ) + files.append( url.path() ); + else + files.append( url.prettyURL() ); + } + + bool doIt = !ask; + if ( ask ) { + int ret; + if ( items.count() == 1 ) { + ret = KMessageBox::warningContinueCancel( parent, + i18n( "<qt>Do you really want to trash\n <b>'%1'</b>?</qt>" ) + .arg( files.first() ), + i18n("Trash File"), + KGuiItem(i18n("to trash", "&Trash"),"edittrash"), "AskForTrash" ); + } + else + ret = KMessageBox::warningContinueCancelList( parent, + i18n("translators: not called for n == 1", "Do you really want to trash these %n items?", items.count() ), + files, + i18n("Trash Files"), + KGuiItem(i18n("to trash", "&Trash"),"edittrash"), "AskForTrash" ); + doIt = (ret == KMessageBox::Continue); + } + + if ( doIt ) { + KIO::CopyJob *job = KIO::trash( urls, showProgress ); + job->setWindow (topLevelWidget()); + job->setAutoErrorHandlingEnabled( true, parent ); + return job; + } + + return 0L; +} + +void KDirOperator::trashSelected(KAction::ActivationReason reason, Qt::ButtonState state) +{ + if ( !m_fileView ) + return; + + if ( reason == KAction::PopupMenuActivation && ( state & Qt::ShiftButton ) ) { + deleteSelected(); + return; + } + + const KFileItemList *list = m_fileView->selectedItems(); + if ( list ) + trash( *list, this ); +} + +void KDirOperator::close() +{ + resetCursor(); + pendingMimeTypes.clear(); + myCompletion.clear(); + myDirCompletion.clear(); + myCompleteListDirty = true; + dir->stop(); +} + +void KDirOperator::checkPath(const QString &, bool /*takeFiles*/) // SLOT +{ +#if 0 + // copy the argument in a temporary string + QString text = _txt; + // it's unlikely to happen, that at the beginning are spaces, but + // for the end, it happens quite often, I guess. + text = text.stripWhiteSpace(); + // if the argument is no URL (the check is quite fragil) and it's + // no absolute path, we add the current directory to get a correct url + if (text.find(':') < 0 && text[0] != '/') + text.insert(0, currUrl); + + // in case we have a selection defined and someone patched the file- + // name, we check, if the end of the new name is changed. + if (!selection.isNull()) { + int position = text.findRev('/'); + ASSERT(position >= 0); // we already inserted the current dir in case + QString filename = text.mid(position + 1, text.length()); + if (filename != selection) + selection = QString::null; + } + + KURL u(text); // I have to take care of entered URLs + bool filenameEntered = false; + + if (u.isLocalFile()) { + // the empty path is kind of a hack + KFileItem i("", u.path()); + if (i.isDir()) + setURL(text, true); + else { + if (takeFiles) + if (acceptOnlyExisting && !i.isFile()) + warning("you entered an invalid URL"); + else + filenameEntered = true; + } + } else + setURL(text, true); + + if (filenameEntered) { + filename_ = u.url(); + emit fileSelected(filename_); + + QApplication::restoreOverrideCursor(); + + accept(); + } +#endif + kdDebug(kfile_area) << "TODO KDirOperator::checkPath()" << endl; +} + +void KDirOperator::setURL(const KURL& _newurl, bool clearforward) +{ + KURL newurl; + + if ( !_newurl.isValid() ) + newurl.setPath( QDir::homeDirPath() ); + else + newurl = _newurl; + + QString pathstr = newurl.path(+1); + newurl.setPath(pathstr); + + // already set + if ( newurl.equals( currUrl, true ) ) + return; + + if ( !isReadable( newurl ) ) { + // maybe newurl is a file? check its parent directory + newurl.cd(QString::fromLatin1("..")); + if ( !isReadable( newurl ) ) { + resetCursor(); + KMessageBox::error(viewWidget(), + i18n("The specified folder does not exist " + "or was not readable.")); + return; + } + } + + if (clearforward) { + // autodelete should remove this one + backStack.push(new KURL(currUrl)); + forwardStack.clear(); + } + + d->lastURL = currUrl.url(-1); + currUrl = newurl; + + pathChanged(); + emit urlEntered(newurl); + + // enable/disable actions + forwardAction->setEnabled( !forwardStack.isEmpty() ); + backAction->setEnabled( !backStack.isEmpty() ); + upAction->setEnabled( !isRoot() ); + + openURL( newurl ); +} + +void KDirOperator::updateDir() +{ + dir->emitChanges(); + if ( m_fileView ) + m_fileView->listingCompleted(); +} + +void KDirOperator::rereadDir() +{ + pathChanged(); + openURL( currUrl, false, true ); +} + + +bool KDirOperator::openURL( const KURL& url, bool keep, bool reload ) +{ + bool result = dir->openURL( url, keep, reload ); + if ( !result ) // in that case, neither completed() nor canceled() will be emitted by KDL + slotCanceled(); + + return result; +} + +// Protected +void KDirOperator::pathChanged() +{ + if (!m_fileView) + return; + + pendingMimeTypes.clear(); + m_fileView->clear(); + myCompletion.clear(); + myDirCompletion.clear(); + + // it may be, that we weren't ready at this time + QApplication::restoreOverrideCursor(); + + // when KIO::Job emits finished, the slot will restore the cursor + QApplication::setOverrideCursor( waitCursor ); + + if ( !isReadable( currUrl )) { + KMessageBox::error(viewWidget(), + i18n("The specified folder does not exist " + "or was not readable.")); + if (backStack.isEmpty()) + home(); + else + back(); + } +} + +void KDirOperator::slotRedirected( const KURL& newURL ) +{ + currUrl = newURL; + pendingMimeTypes.clear(); + myCompletion.clear(); + myDirCompletion.clear(); + myCompleteListDirty = true; + emit urlEntered( newURL ); +} + +// Code pinched from kfm then hacked +void KDirOperator::back() +{ + if ( backStack.isEmpty() ) + return; + + forwardStack.push( new KURL(currUrl) ); + + KURL *s = backStack.pop(); + + setURL(*s, false); + delete s; +} + +// Code pinched from kfm then hacked +void KDirOperator::forward() +{ + if ( forwardStack.isEmpty() ) + return; + + backStack.push(new KURL(currUrl)); + + KURL *s = forwardStack.pop(); + setURL(*s, false); + delete s; +} + +KURL KDirOperator::url() const +{ + return currUrl; +} + +void KDirOperator::cdUp() +{ + KURL tmp(currUrl); + tmp.cd(QString::fromLatin1("..")); + setURL(tmp, true); +} + +void KDirOperator::home() +{ + KURL u; + u.setPath( QDir::homeDirPath() ); + setURL(u, true); +} + +void KDirOperator::clearFilter() +{ + dir->setNameFilter( QString::null ); + dir->clearMimeFilter(); + checkPreviewSupport(); +} + +void KDirOperator::setNameFilter(const QString& filter) +{ + dir->setNameFilter(filter); + checkPreviewSupport(); +} + +void KDirOperator::setMimeFilter( const QStringList& mimetypes ) +{ + dir->setMimeFilter( mimetypes ); + checkPreviewSupport(); +} + +bool KDirOperator::checkPreviewSupport() +{ + KToggleAction *previewAction = static_cast<KToggleAction*>( myActionCollection->action( "preview" )); + + bool hasPreviewSupport = false; + KConfig *kc = KGlobal::config(); + KConfigGroupSaver cs( kc, ConfigGroup ); + if ( kc->readBoolEntry( "Show Default Preview", true ) ) + hasPreviewSupport = checkPreviewInternal(); + + previewAction->setEnabled( hasPreviewSupport ); + return hasPreviewSupport; +} + +bool KDirOperator::checkPreviewInternal() const +{ + QStringList supported = KIO::PreviewJob::supportedMimeTypes(); + // no preview support for directories? + if ( dirOnlyMode() && supported.findIndex( "inode/directory" ) == -1 ) + return false; + + QStringList mimeTypes = dir->mimeFilters(); + QStringList nameFilter = QStringList::split( " ", dir->nameFilter() ); + + if ( mimeTypes.isEmpty() && nameFilter.isEmpty() && !supported.isEmpty() ) + return true; + else { + QRegExp r; + r.setWildcard( true ); // the "mimetype" can be "image/*" + + if ( !mimeTypes.isEmpty() ) { + QStringList::Iterator it = supported.begin(); + + for ( ; it != supported.end(); ++it ) { + r.setPattern( *it ); + + QStringList result = mimeTypes.grep( r ); + if ( !result.isEmpty() ) { // matches! -> we want previews + return true; + } + } + } + + if ( !nameFilter.isEmpty() ) { + // find the mimetypes of all the filter-patterns and + KServiceTypeFactory *fac = KServiceTypeFactory::self(); + QStringList::Iterator it1 = nameFilter.begin(); + for ( ; it1 != nameFilter.end(); ++it1 ) { + if ( (*it1) == "*" ) { + return true; + } + + KMimeType *mt = fac->findFromPattern( *it1 ); + if ( !mt ) + continue; + QString mime = mt->name(); + delete mt; + + // the "mimetypes" we get from the PreviewJob can be "image/*" + // so we need to check in wildcard mode + QStringList::Iterator it2 = supported.begin(); + for ( ; it2 != supported.end(); ++it2 ) { + r.setPattern( *it2 ); + if ( r.search( mime ) != -1 ) { + return true; + } + } + } + } + } + + return false; +} + +KFileView* KDirOperator::createView( QWidget* parent, KFile::FileView view ) +{ + KFileView* new_view = 0L; + bool separateDirs = KFile::isSeparateDirs( view ); + bool preview = ( KFile::isPreviewInfo(view) || KFile::isPreviewContents( view ) ); + + if ( separateDirs || preview ) { + KCombiView *combi = 0L; + if (separateDirs) + { + combi = new KCombiView( parent, "combi view" ); + combi->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles); + } + + KFileView* v = 0L; + if ( KFile::isSimpleView( view ) ) + v = createView( combi, KFile::Simple ); + else + v = createView( combi, KFile::Detail ); + + v->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles); + + if (combi) + combi->setRight( v ); + + if (preview) + { + KFilePreview* pView = new KFilePreview( combi ? combi : v, parent, "preview" ); + pView->setOnlyDoubleClickSelectsFiles(d->onlyDoubleClickSelectsFiles); + new_view = pView; + } + else + new_view = combi; + } + else if ( KFile::isDetailView( view ) && !preview ) { + new_view = new KFileDetailView( parent, "detail view"); + new_view->setViewName( i18n("Detailed View") ); + } + else /* if ( KFile::isSimpleView( view ) && !preview ) */ { + KFileIconView *iconView = new KFileIconView( parent, "simple view"); + new_view = iconView; + new_view->setViewName( i18n("Short View") ); + } + + new_view->widget()->setAcceptDrops(acceptDrops()); + return new_view; +} + +void KDirOperator::setAcceptDrops(bool b) +{ + if (m_fileView) + m_fileView->widget()->setAcceptDrops(b); + QWidget::setAcceptDrops(b); +} + +void KDirOperator::setDropOptions(int options) +{ + d->dropOptions = options; + if (m_fileView) + m_fileView->setDropOptions(options); +} + +void KDirOperator::setView( KFile::FileView view ) +{ + bool separateDirs = KFile::isSeparateDirs( view ); + bool preview=( KFile::isPreviewInfo(view) || KFile::isPreviewContents( view ) ); + + if (view == KFile::Default) { + if ( KFile::isDetailView( (KFile::FileView) defaultView ) ) + view = KFile::Detail; + else + view = KFile::Simple; + + separateDirs = KFile::isSeparateDirs( static_cast<KFile::FileView>(defaultView) ); + preview = ( KFile::isPreviewInfo( static_cast<KFile::FileView>(defaultView) ) || + KFile::isPreviewContents( static_cast<KFile::FileView>(defaultView) ) ) + && myActionCollection->action("preview")->isEnabled(); + + if ( preview ) { // instantiates KFileMetaPreview and calls setView() + m_viewKind = defaultView; + slotDefaultPreview(); + return; + } + else if ( !separateDirs ) + separateDirsAction->setChecked(true); + } + + // if we don't have any files, we can't separate dirs from files :) + if ( (mode() & KFile::File) == 0 && + (mode() & KFile::Files) == 0 ) { + separateDirs = false; + separateDirsAction->setEnabled( false ); + } + + m_viewKind = static_cast<int>(view) | (separateDirs ? KFile::SeparateDirs : 0); + view = static_cast<KFile::FileView>(m_viewKind); + + KFileView *new_view = createView( this, view ); + if ( preview ) { + // we keep the preview-_widget_ around, but not the KFilePreview. + // KFilePreview::setPreviewWidget handles the reparenting for us + static_cast<KFilePreview*>(new_view)->setPreviewWidget(myPreview, url()); + } + + setView( new_view ); +} + + +void KDirOperator::connectView(KFileView *view) +{ + // TODO: do a real timer and restart it after that + pendingMimeTypes.clear(); + bool listDir = true; + + if ( dirOnlyMode() ) + view->setViewMode(KFileView::Directories); + else + view->setViewMode(KFileView::All); + + if ( myMode & KFile::Files ) + view->setSelectionMode( KFile::Extended ); + else + view->setSelectionMode( KFile::Single ); + + if (m_fileView) + { + if ( d->config ) // save and restore the views' configuration + { + m_fileView->writeConfig( d->config, d->configGroup ); + view->readConfig( d->config, d->configGroup ); + } + + // transfer the state from old view to new view + view->clear(); + view->addItemList( *m_fileView->items() ); + listDir = false; + + if ( m_fileView->widget()->hasFocus() ) + view->widget()->setFocus(); + + KFileItem *oldCurrentItem = m_fileView->currentFileItem(); + if ( oldCurrentItem ) { + view->setCurrentItem( oldCurrentItem ); + view->setSelected( oldCurrentItem, false ); + view->ensureItemVisible( oldCurrentItem ); + } + + const KFileItemList *oldSelected = m_fileView->selectedItems(); + if ( !oldSelected->isEmpty() ) { + KFileItemListIterator it( *oldSelected ); + for ( ; it.current(); ++it ) + view->setSelected( it.current(), true ); + } + + m_fileView->widget()->hide(); + delete m_fileView; + } + + else + { + if ( d->config ) + view->readConfig( d->config, d->configGroup ); + } + + m_fileView = view; + m_fileView->setDropOptions(d->dropOptions); + viewActionCollection = 0L; + KFileViewSignaler *sig = view->signaler(); + + connect(sig, SIGNAL( activatedMenu(const KFileItem *, const QPoint& ) ), + this, SLOT( activatedMenu(const KFileItem *, const QPoint& ))); + connect(sig, SIGNAL( dirActivated(const KFileItem *) ), + this, SLOT( selectDir(const KFileItem*) ) ); + connect(sig, SIGNAL( fileSelected(const KFileItem *) ), + this, SLOT( selectFile(const KFileItem*) ) ); + connect(sig, SIGNAL( fileHighlighted(const KFileItem *) ), + this, SLOT( highlightFile(const KFileItem*) )); + connect(sig, SIGNAL( sortingChanged( QDir::SortSpec ) ), + this, SLOT( slotViewSortingChanged( QDir::SortSpec ))); + connect(sig, SIGNAL( dropped(const KFileItem *, QDropEvent*, const KURL::List&) ), + this, SIGNAL( dropped(const KFileItem *, QDropEvent*, const KURL::List&)) ); + + if ( reverseAction->isChecked() != m_fileView->isReversed() ) + slotSortReversed(); + + updateViewActions(); + m_fileView->widget()->resize(size()); + m_fileView->widget()->show(); + + if ( listDir ) { + QApplication::setOverrideCursor( waitCursor ); + openURL( currUrl ); + } + else + view->listingCompleted(); +} + +KFile::Mode KDirOperator::mode() const +{ + return myMode; +} + +void KDirOperator::setMode(KFile::Mode m) +{ + if (myMode == m) + return; + + myMode = m; + + dir->setDirOnlyMode( dirOnlyMode() ); + + // reset the view with the different mode + setView( static_cast<KFile::FileView>(m_viewKind) ); +} + +void KDirOperator::setView(KFileView *view) +{ + if ( view == m_fileView ) { + return; + } + + setFocusProxy(view->widget()); + view->setSorting( mySorting ); + view->setOnlyDoubleClickSelectsFiles( d->onlyDoubleClickSelectsFiles ); + connectView(view); // also deletes the old view + + emit viewChanged( view ); +} + +void KDirOperator::setDirLister( KDirLister *lister ) +{ + if ( lister == dir ) // sanity check + return; + + delete dir; + dir = lister; + + dir->setAutoUpdate( true ); + + QWidget* mainWidget = topLevelWidget(); + dir->setMainWindow (mainWidget); + kdDebug (kfile_area) << "mainWidget=" << mainWidget << endl; + + connect( dir, SIGNAL( percent( int )), + SLOT( slotProgress( int ) )); + connect( dir, SIGNAL(started( const KURL& )), SLOT(slotStarted())); + connect( dir, SIGNAL(newItems(const KFileItemList &)), + SLOT(insertNewFiles(const KFileItemList &))); + connect( dir, SIGNAL(completed()), SLOT(slotIOFinished())); + connect( dir, SIGNAL(canceled()), SLOT(slotCanceled())); + connect( dir, SIGNAL(deleteItem(KFileItem *)), + SLOT(itemDeleted(KFileItem *))); + connect( dir, SIGNAL(redirection( const KURL& )), + SLOT( slotRedirected( const KURL& ))); + connect( dir, SIGNAL( clear() ), SLOT( slotClearView() )); + connect( dir, SIGNAL( refreshItems( const KFileItemList& ) ), + SLOT( slotRefreshItems( const KFileItemList& ) ) ); +} + +void KDirOperator::insertNewFiles(const KFileItemList &newone) +{ + if ( newone.isEmpty() || !m_fileView ) + return; + + myCompleteListDirty = true; + m_fileView->addItemList( newone ); + emit updateInformation(m_fileView->numDirs(), m_fileView->numFiles()); + + KFileItem *item; + KFileItemListIterator it( newone ); + + while ( (item = it.current()) ) { + // highlight the dir we come from, if possible + if ( d->dirHighlighting && item->isDir() && + item->url().url(-1) == d->lastURL ) { + m_fileView->setCurrentItem( item ); + m_fileView->ensureItemVisible( item ); + } + + ++it; + } + + QTimer::singleShot(200, this, SLOT(resetCursor())); +} + +void KDirOperator::selectDir(const KFileItem *item) +{ + setURL(item->url(), true); +} + +void KDirOperator::itemDeleted(KFileItem *item) +{ + pendingMimeTypes.removeRef( item ); + if ( m_fileView ) + { + m_fileView->removeItem( static_cast<KFileItem *>( item )); + emit updateInformation(m_fileView->numDirs(), m_fileView->numFiles()); + } +} + +void KDirOperator::selectFile(const KFileItem *item) +{ + QApplication::restoreOverrideCursor(); + + emit fileSelected( item ); +} + +void KDirOperator::setCurrentItem( const QString& filename ) +{ + if ( m_fileView ) { + const KFileItem *item = 0L; + + if ( !filename.isNull() ) + item = static_cast<KFileItem *>(dir->findByName( filename )); + + m_fileView->clearSelection(); + if ( item ) { + m_fileView->setCurrentItem( item ); + m_fileView->setSelected( item, true ); + m_fileView->ensureItemVisible( item ); + } + } +} + +QString KDirOperator::makeCompletion(const QString& string) +{ + if ( string.isEmpty() ) { + m_fileView->clearSelection(); + return QString::null; + } + + prepareCompletionObjects(); + return myCompletion.makeCompletion( string ); +} + +QString KDirOperator::makeDirCompletion(const QString& string) +{ + if ( string.isEmpty() ) { + m_fileView->clearSelection(); + return QString::null; + } + + prepareCompletionObjects(); + return myDirCompletion.makeCompletion( string ); +} + +void KDirOperator::prepareCompletionObjects() +{ + if ( !m_fileView ) + return; + + if ( myCompleteListDirty ) { // create the list of all possible completions + KFileItemListIterator it( *(m_fileView->items()) ); + for( ; it.current(); ++it ) { + KFileItem *item = it.current(); + + myCompletion.addItem( item->name() ); + if ( item->isDir() ) + myDirCompletion.addItem( item->name() ); + } + myCompleteListDirty = false; + } +} + +void KDirOperator::slotCompletionMatch(const QString& match) +{ + setCurrentItem( match ); + emit completion( match ); +} + +void KDirOperator::setupActions() +{ + myActionCollection = new KActionCollection( topLevelWidget(), this, "KDirOperator::myActionCollection" ); + + actionMenu = new KActionMenu( i18n("Menu"), myActionCollection, "popupMenu" ); + upAction = KStdAction::up( this, SLOT( cdUp() ), myActionCollection, "up" ); + upAction->setText( i18n("Parent Folder") ); + backAction = KStdAction::back( this, SLOT( back() ), myActionCollection, "back" ); + forwardAction = KStdAction::forward( this, SLOT(forward()), myActionCollection, "forward" ); + homeAction = KStdAction::home( this, SLOT( home() ), myActionCollection, "home" ); + homeAction->setText(i18n("Home Folder")); + reloadAction = KStdAction::redisplay( this, SLOT(rereadDir()), myActionCollection, "reload" ); + actionSeparator = new KActionSeparator( myActionCollection, "separator" ); + d->viewActionSeparator = new KActionSeparator( myActionCollection, + "viewActionSeparator" ); + mkdirAction = new KAction( i18n("New Folder..."), 0, + this, SLOT( mkdir() ), myActionCollection, "mkdir" ); + KAction* trash = new KAction( i18n( "Move to Trash" ), "edittrash", Key_Delete, myActionCollection, "trash" ); + connect( trash, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ), + this, SLOT( trashSelected( KAction::ActivationReason, Qt::ButtonState ) ) ); + new KAction( i18n( "Delete" ), "editdelete", SHIFT+Key_Delete, this, + SLOT( deleteSelected() ), myActionCollection, "delete" ); + mkdirAction->setIcon( QString::fromLatin1("folder_new") ); + reloadAction->setText( i18n("Reload") ); + reloadAction->setShortcut( KStdAccel::shortcut( KStdAccel::Reload )); + + + // the sort menu actions + sortActionMenu = new KActionMenu( i18n("Sorting"), myActionCollection, "sorting menu"); + byNameAction = new KRadioAction( i18n("By Name"), 0, + this, SLOT( slotSortByName() ), + myActionCollection, "by name" ); + byDateAction = new KRadioAction( i18n("By Date"), 0, + this, SLOT( slotSortByDate() ), + myActionCollection, "by date" ); + bySizeAction = new KRadioAction( i18n("By Size"), 0, + this, SLOT( slotSortBySize() ), + myActionCollection, "by size" ); + reverseAction = new KToggleAction( i18n("Reverse"), 0, + this, SLOT( slotSortReversed() ), + myActionCollection, "reversed" ); + + QString sortGroup = QString::fromLatin1("sort"); + byNameAction->setExclusiveGroup( sortGroup ); + byDateAction->setExclusiveGroup( sortGroup ); + bySizeAction->setExclusiveGroup( sortGroup ); + + + dirsFirstAction = new KToggleAction( i18n("Folders First"), 0, + myActionCollection, "dirs first"); + caseInsensitiveAction = new KToggleAction(i18n("Case Insensitive"), 0, + myActionCollection, "case insensitive" ); + + connect( dirsFirstAction, SIGNAL( toggled( bool ) ), + SLOT( slotToggleDirsFirst() )); + connect( caseInsensitiveAction, SIGNAL( toggled( bool ) ), + SLOT( slotToggleIgnoreCase() )); + + + + // the view menu actions + viewActionMenu = new KActionMenu( i18n("&View"), myActionCollection, "view menu" ); + connect( viewActionMenu->popupMenu(), SIGNAL( aboutToShow() ), + SLOT( insertViewDependentActions() )); + + shortAction = new KRadioAction( i18n("Short View"), "view_multicolumn", + KShortcut(), myActionCollection, "short view" ); + detailedAction = new KRadioAction( i18n("Detailed View"), "view_detailed", + KShortcut(), myActionCollection, "detailed view" ); + + showHiddenAction = new KToggleAction( i18n("Show Hidden Files"), KShortcut(), + myActionCollection, "show hidden" ); +// showHiddenAction->setCheckedState( i18n("Hide Hidden Files") ); + separateDirsAction = new KToggleAction( i18n("Separate Folders"), KShortcut(), + this, + SLOT(slotSeparateDirs()), + myActionCollection, "separate dirs" ); + KToggleAction *previewAction = new KToggleAction(i18n("Show Preview"), + "thumbnail", KShortcut(), + myActionCollection, + "preview" ); + previewAction->setCheckedState(i18n("Hide Preview")); + connect( previewAction, SIGNAL( toggled( bool )), + SLOT( togglePreview( bool ))); + + + QString viewGroup = QString::fromLatin1("view"); + shortAction->setExclusiveGroup( viewGroup ); + detailedAction->setExclusiveGroup( viewGroup ); + + connect( shortAction, SIGNAL( activated() ), + SLOT( slotSimpleView() )); + connect( detailedAction, SIGNAL( activated() ), + SLOT( slotDetailedView() )); + connect( showHiddenAction, SIGNAL( toggled( bool ) ), + SLOT( slotToggleHidden( bool ) )); + + new KAction( i18n("Properties"), KShortcut(ALT+Key_Return), this, + SLOT(slotProperties()), myActionCollection, "properties" ); +} + +void KDirOperator::setupMenu() +{ + setupMenu(AllActions); +} + +void KDirOperator::setupMenu(int whichActions) +{ + // first fill the submenus (sort and view) + sortActionMenu->popupMenu()->clear(); + sortActionMenu->insert( byNameAction ); + sortActionMenu->insert( byDateAction ); + sortActionMenu->insert( bySizeAction ); + sortActionMenu->insert( actionSeparator ); + sortActionMenu->insert( reverseAction ); + sortActionMenu->insert( dirsFirstAction ); + sortActionMenu->insert( caseInsensitiveAction ); + + // now plug everything into the popupmenu + actionMenu->popupMenu()->clear(); + if (whichActions & NavActions) + { + actionMenu->insert( upAction ); + actionMenu->insert( backAction ); + actionMenu->insert( forwardAction ); + actionMenu->insert( homeAction ); + actionMenu->insert( actionSeparator ); + } + + if (whichActions & FileActions) + { + actionMenu->insert( mkdirAction ); + if (currUrl.isLocalFile() && !(KApplication::keyboardMouseState() & Qt::ShiftButton)) + actionMenu->insert( myActionCollection->action( "trash" ) ); + KConfig *globalconfig = KGlobal::config(); + KConfigGroupSaver cs( globalconfig, QString::fromLatin1("KDE") ); + if (!currUrl.isLocalFile() || (KApplication::keyboardMouseState() & Qt::ShiftButton) || + globalconfig->readBoolEntry("ShowDeleteCommand", false)) + actionMenu->insert( myActionCollection->action( "delete" ) ); + actionMenu->insert( actionSeparator ); + } + + if (whichActions & SortActions) + { + actionMenu->insert( sortActionMenu ); + actionMenu->insert( actionSeparator ); + } + + if (whichActions & ViewActions) + { + actionMenu->insert( viewActionMenu ); + actionMenu->insert( actionSeparator ); + } + + if (whichActions & FileActions) + { + actionMenu->insert( myActionCollection->action( "properties" ) ); + } +} + +void KDirOperator::updateSortActions() +{ + if ( KFile::isSortByName( mySorting ) ) + byNameAction->setChecked( true ); + else if ( KFile::isSortByDate( mySorting ) ) + byDateAction->setChecked( true ); + else if ( KFile::isSortBySize( mySorting ) ) + bySizeAction->setChecked( true ); + + dirsFirstAction->setChecked( KFile::isSortDirsFirst( mySorting ) ); + caseInsensitiveAction->setChecked( KFile::isSortCaseInsensitive(mySorting) ); + caseInsensitiveAction->setEnabled( KFile::isSortByName( mySorting ) ); + + if ( m_fileView ) + reverseAction->setChecked( m_fileView->isReversed() ); +} + +void KDirOperator::updateViewActions() +{ + KFile::FileView fv = static_cast<KFile::FileView>( m_viewKind ); + + separateDirsAction->setChecked( KFile::isSeparateDirs( fv ) && + separateDirsAction->isEnabled() ); + + shortAction->setChecked( KFile::isSimpleView( fv )); + detailedAction->setChecked( KFile::isDetailView( fv )); +} + +void KDirOperator::readConfig( KConfig *kc, const QString& group ) +{ + if ( !kc ) + return; + QString oldGroup = kc->group(); + if ( !group.isEmpty() ) + kc->setGroup( group ); + + defaultView = 0; + int sorting = 0; + + QString viewStyle = kc->readEntry( QString::fromLatin1("View Style"), + QString::fromLatin1("Simple") ); + if ( viewStyle == QString::fromLatin1("Detail") ) + defaultView |= KFile::Detail; + else + defaultView |= KFile::Simple; + if ( kc->readBoolEntry( QString::fromLatin1("Separate Directories"), + DefaultMixDirsAndFiles ) ) + defaultView |= KFile::SeparateDirs; + if ( kc->readBoolEntry(QString::fromLatin1("Show Preview"), false)) + defaultView |= KFile::PreviewContents; + + if ( kc->readBoolEntry( QString::fromLatin1("Sort case insensitively"), + DefaultCaseInsensitive ) ) + sorting |= QDir::IgnoreCase; + if ( kc->readBoolEntry( QString::fromLatin1("Sort directories first"), + DefaultDirsFirst ) ) + sorting |= QDir::DirsFirst; + + + QString name = QString::fromLatin1("Name"); + QString sortBy = kc->readEntry( QString::fromLatin1("Sort by"), name ); + if ( sortBy == name ) + sorting |= QDir::Name; + else if ( sortBy == QString::fromLatin1("Size") ) + sorting |= QDir::Size; + else if ( sortBy == QString::fromLatin1("Date") ) + sorting |= QDir::Time; + + mySorting = static_cast<QDir::SortSpec>( sorting ); + setSorting( mySorting ); + + + if ( kc->readBoolEntry( QString::fromLatin1("Show hidden files"), + DefaultShowHidden ) ) { + showHiddenAction->setChecked( true ); + dir->setShowingDotFiles( true ); + } + if ( kc->readBoolEntry( QString::fromLatin1("Sort reversed"), + DefaultSortReversed ) ) + reverseAction->setChecked( true ); + + kc->setGroup( oldGroup ); +} + +void KDirOperator::writeConfig( KConfig *kc, const QString& group ) +{ + if ( !kc ) + return; + + const QString oldGroup = kc->group(); + + if ( !group.isEmpty() ) + kc->setGroup( group ); + + QString sortBy = QString::fromLatin1("Name"); + if ( KFile::isSortBySize( mySorting ) ) + sortBy = QString::fromLatin1("Size"); + else if ( KFile::isSortByDate( mySorting ) ) + sortBy = QString::fromLatin1("Date"); + kc->writeEntry( QString::fromLatin1("Sort by"), sortBy ); + + kc->writeEntry( QString::fromLatin1("Sort reversed"), + reverseAction->isChecked() ); + kc->writeEntry( QString::fromLatin1("Sort case insensitively"), + caseInsensitiveAction->isChecked() ); + kc->writeEntry( QString::fromLatin1("Sort directories first"), + dirsFirstAction->isChecked() ); + + // don't save the separate dirs or preview when an application specific + // preview is in use. + bool appSpecificPreview = false; + if ( myPreview ) { + QWidget *preview = const_cast<QWidget*>( myPreview ); // grmbl + KFileMetaPreview *tmp = dynamic_cast<KFileMetaPreview*>( preview ); + appSpecificPreview = (tmp == 0L); + } + + if ( !appSpecificPreview ) { + if ( separateDirsAction->isEnabled() ) + kc->writeEntry( QString::fromLatin1("Separate Directories"), + separateDirsAction->isChecked() ); + + KToggleAction *previewAction = static_cast<KToggleAction*>(myActionCollection->action("preview")); + if ( previewAction->isEnabled() ) { + bool hasPreview = previewAction->isChecked(); + kc->writeEntry( QString::fromLatin1("Show Preview"), hasPreview ); + } + } + + kc->writeEntry( QString::fromLatin1("Show hidden files"), + showHiddenAction->isChecked() ); + + KFile::FileView fv = static_cast<KFile::FileView>( m_viewKind ); + QString style; + if ( KFile::isDetailView( fv ) ) + style = QString::fromLatin1("Detail"); + else if ( KFile::isSimpleView( fv ) ) + style = QString::fromLatin1("Simple"); + kc->writeEntry( QString::fromLatin1("View Style"), style ); + + kc->setGroup( oldGroup ); +} + + +void KDirOperator::resizeEvent( QResizeEvent * ) +{ + if (m_fileView) + m_fileView->widget()->resize( size() ); + + if ( progress->parent() == this ) // might be reparented into a statusbar + progress->move(2, height() - progress->height() -2); +} + +void KDirOperator::setOnlyDoubleClickSelectsFiles( bool enable ) +{ + d->onlyDoubleClickSelectsFiles = enable; + if ( m_fileView ) + m_fileView->setOnlyDoubleClickSelectsFiles( enable ); +} + +bool KDirOperator::onlyDoubleClickSelectsFiles() const +{ + return d->onlyDoubleClickSelectsFiles; +} + +void KDirOperator::slotStarted() +{ + progress->setProgress( 0 ); + // delay showing the progressbar for one second + d->progressDelayTimer->start( 1000, true ); +} + +void KDirOperator::slotShowProgress() +{ + progress->raise(); + progress->show(); + QApplication::flushX(); +} + +void KDirOperator::slotProgress( int percent ) +{ + progress->setProgress( percent ); + // we have to redraw this as fast as possible + if ( progress->isVisible() ) + QApplication::flushX(); +} + + +void KDirOperator::slotIOFinished() +{ + d->progressDelayTimer->stop(); + slotProgress( 100 ); + progress->hide(); + emit finishedLoading(); + resetCursor(); + + if ( m_fileView ) + m_fileView->listingCompleted(); +} + +void KDirOperator::slotCanceled() +{ + emit finishedLoading(); + resetCursor(); + + if ( m_fileView ) + m_fileView->listingCompleted(); +} + +KProgress * KDirOperator::progressBar() const +{ + return progress; +} + +void KDirOperator::clearHistory() +{ + backStack.clear(); + backAction->setEnabled( false ); + forwardStack.clear(); + forwardAction->setEnabled( false ); +} + +void KDirOperator::slotViewActionAdded( KAction *action ) +{ + if ( viewActionMenu->popupMenu()->count() == 5 ) // need to add a separator + viewActionMenu->insert( d->viewActionSeparator ); + + viewActionMenu->insert( action ); +} + +void KDirOperator::slotViewActionRemoved( KAction *action ) +{ + viewActionMenu->remove( action ); + + if ( viewActionMenu->popupMenu()->count() == 6 ) // remove the separator + viewActionMenu->remove( d->viewActionSeparator ); +} + +void KDirOperator::slotViewSortingChanged( QDir::SortSpec sort ) +{ + mySorting = sort; + updateSortActions(); +} + +void KDirOperator::setEnableDirHighlighting( bool enable ) +{ + d->dirHighlighting = enable; +} + +bool KDirOperator::dirHighlighting() const +{ + return d->dirHighlighting; +} + +void KDirOperator::slotProperties() +{ + if ( m_fileView ) { + const KFileItemList *list = m_fileView->selectedItems(); + if ( !list->isEmpty() ) + (void) new KPropertiesDialog( *list, this, "props dlg", true); + } +} + +void KDirOperator::slotClearView() +{ + if ( m_fileView ) + m_fileView->clearView(); +} + +// ### temporary code +#include <dirent.h> +bool KDirOperator::isReadable( const KURL& url ) +{ + if ( !url.isLocalFile() ) + return true; // what else can we say? + + KDE_struct_stat buf; + QString ts = url.path(+1); + bool readable = ( KDE_stat( QFile::encodeName( ts ), &buf) == 0 ); + if (readable) { // further checks + DIR *test; + test = opendir( QFile::encodeName( ts )); // we do it just to test here + readable = (test != 0); + if (test) + closedir(test); + } + return readable; +} + +void KDirOperator::togglePreview( bool on ) +{ + if ( on ) + slotDefaultPreview(); + else + setView( (KFile::FileView) (m_viewKind & ~(KFile::PreviewContents|KFile::PreviewInfo)) ); +} + +void KDirOperator::slotRefreshItems( const KFileItemList& items ) +{ + if ( !m_fileView ) + return; + + KFileItemListIterator it( items ); + for ( ; it.current(); ++it ) + m_fileView->updateView( it.current() ); +} + +void KDirOperator::setViewConfig( KConfig *config, const QString& group ) +{ + d->config = config; + d->configGroup = group; +} + +KConfig * KDirOperator::viewConfig() +{ + return d->config; +} + +QString KDirOperator::viewConfigGroup() const +{ + return d->configGroup; +} + +void KDirOperator::virtual_hook( int, void* ) +{ /*BASE::virtual_hook( id, data );*/ } + +#include "kdiroperator.moc" |