• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KFile

kdiroperator.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002     Copyright (C) 1999,2000 Stephan Kulow <coolo@kde.org>
00003                   1999,2000,2001,2002,2003 Carsten Pfeiffer <pfeiffer@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kdiroperator.h"
00022 #include <kprotocolmanager.h>
00023 #include "kdirmodel.h"
00024 #include "kdiroperatordetailview_p.h"
00025 #include "kdirsortfilterproxymodel.h"
00026 #include "kfileitem.h"
00027 #include "kfilemetapreview.h"
00028 #include "kpreviewwidgetbase.h"
00029 #include "knewfilemenu.h"
00030 
00031 #include <config-kfile.h>
00032 
00033 #include <unistd.h>
00034 
00035 #include <QtCore/QDir>
00036 #include <QtCore/QRegExp>
00037 #include <QtCore/QTimer>
00038 #include <QtCore/QAbstractItemModel>
00039 #include <QtGui/QApplication>
00040 #include <QtGui/QDialog>
00041 #include <QtGui/QHeaderView>
00042 #include <QtGui/QLabel>
00043 #include <QtGui/QLayout>
00044 #include <QtGui/QListView>
00045 #include <QtGui/QMouseEvent>
00046 #include <QtGui/QTreeView>
00047 #include <QtGui/QPushButton>
00048 #include <QtGui/QProgressBar>
00049 #include <QtGui/QScrollBar>
00050 #include <QtGui/QSplitter>
00051 #include <QtGui/QWheelEvent>
00052 
00053 #include <kaction.h>
00054 #include <kapplication.h>
00055 #include <kdebug.h>
00056 #include <kdialog.h>
00057 #include <kdirlister.h>
00058 #include <kfileitemdelegate.h>
00059 #include <kicon.h>
00060 #include <kinputdialog.h>
00061 #include <klocale.h>
00062 #include <kmessagebox.h>
00063 #include <kmenu.h>
00064 #include <kstandardaction.h>
00065 #include <kio/job.h>
00066 #include <kio/deletejob.h>
00067 #include <kio/copyjob.h>
00068 #include <kio/jobuidelegate.h>
00069 #include <kio/jobclasses.h>
00070 #include <kio/netaccess.h>
00071 #include <kio/previewjob.h>
00072 #include <kio/renamedialog.h>
00073 #include <kfilepreviewgenerator.h>
00074 #include <krun.h>
00075 #include <kpropertiesdialog.h>
00076 #include <kstandardshortcut.h>
00077 #include <kde_file.h>
00078 #include <kactioncollection.h>
00079 #include <ktoggleaction.h>
00080 #include <kactionmenu.h>
00081 #include <kconfiggroup.h>
00082 #include <kdeversion.h>
00083 
00084 
00085 template class QHash<QString, KFileItem>;
00086 
00087 // QDir::SortByMask is not only undocumented, it also omits QDir::Type which  is another
00088 // sorting mode.
00089 static const int QDirSortMask = QDir::SortByMask | QDir::Type;
00090 
00095 class KDirOperatorIconView : public QListView
00096 {
00097 public:
00098     KDirOperatorIconView(KDirOperator *dirOperator, QWidget *parent = 0);
00099     virtual ~KDirOperatorIconView();
00100 
00101 protected:
00102     virtual QStyleOptionViewItem viewOptions() const;
00103     virtual void dragEnterEvent(QDragEnterEvent* event);
00104     virtual void mousePressEvent(QMouseEvent *event);
00105     virtual void wheelEvent(QWheelEvent *event);
00106 
00107 private:
00108     KDirOperator *ops;
00109 };
00110 
00111 KDirOperatorIconView::KDirOperatorIconView(KDirOperator *dirOperator, QWidget *parent) :
00112     QListView(parent),
00113     ops(dirOperator)
00114 {
00115     setViewMode(QListView::IconMode);
00116     setFlow(QListView::TopToBottom);
00117     setResizeMode(QListView::Adjust);
00118     setSpacing(0);
00119     setMovement(QListView::Static);
00120     setDragDropMode(QListView::DragOnly);
00121     setVerticalScrollMode(QListView::ScrollPerPixel);
00122     setHorizontalScrollMode(QListView::ScrollPerPixel);
00123     setEditTriggers(QAbstractItemView::NoEditTriggers);
00124     setWordWrap(true);
00125     setIconSize(QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall));
00126 }
00127 
00128 KDirOperatorIconView::~KDirOperatorIconView()
00129 {
00130 }
00131 
00132 QStyleOptionViewItem KDirOperatorIconView::viewOptions() const
00133 {
00134     QStyleOptionViewItem viewOptions = QListView::viewOptions();
00135     viewOptions.showDecorationSelected = true;
00136     viewOptions.decorationPosition = ops->decorationPosition();
00137     if (viewOptions.decorationPosition == QStyleOptionViewItem::Left) {
00138         viewOptions.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter;
00139     } else {
00140         viewOptions.displayAlignment = Qt::AlignCenter;
00141     }
00142 
00143     return viewOptions;
00144 }
00145 
00146 void KDirOperatorIconView::dragEnterEvent(QDragEnterEvent* event)
00147 {
00148     if (event->mimeData()->hasUrls()) {
00149         event->acceptProposedAction();
00150     }
00151 }
00152 
00153 void KDirOperatorIconView::mousePressEvent(QMouseEvent *event)
00154 {
00155     if (!indexAt(event->pos()).isValid()) {
00156         const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
00157         if (!(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier)) {
00158             clearSelection();
00159         }
00160     }
00161 
00162     QListView::mousePressEvent(event);
00163 }
00164 
00165 void KDirOperatorIconView::wheelEvent(QWheelEvent *event)
00166 {
00167     QListView::wheelEvent(event);
00168 
00169     // apply the vertical wheel event to the horizontal scrollbar, as
00170     // the items are aligned from left to right
00171     if (event->orientation() == Qt::Vertical) {
00172         QWheelEvent horizEvent(event->pos(),
00173                                event->delta(),
00174                                event->buttons(),
00175                                event->modifiers(),
00176                                Qt::Horizontal);
00177         QApplication::sendEvent(horizontalScrollBar(), &horizEvent);
00178     }
00179 }
00180 
00181 void KDirOperator::keyPressEvent(QKeyEvent *e)
00182 {
00183     if (!(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter )) {
00184         QWidget::keyPressEvent(e);
00185     }
00186 }
00187 
00188 class KDirOperator::Private
00189 {
00190 public:
00191     Private( KDirOperator *parent );
00192     ~Private();
00193 
00194     enum InlinePreviewState {
00195         ForcedToFalse = 0,
00196         ForcedToTrue,
00197         NotForced
00198     };
00199 
00200     // private methods
00201     bool checkPreviewInternal() const;
00202     void checkPath(const QString &txt, bool takeFiles = false);
00203     bool openUrl(const KUrl &url, KDirLister::OpenUrlFlags flags = KDirLister::NoFlags);
00204     int sortColumn() const;
00205     Qt::SortOrder sortOrder() const;
00206     void updateSorting(QDir::SortFlags sort);
00207 
00208     static bool isReadable(const KUrl &url);
00209 
00210     KFile::FileView allViews();
00211 
00212     // private slots
00213     void _k_slotDetailedView();
00214     void _k_slotSimpleView();
00215     void _k_slotTreeView();
00216     void _k_slotDetailedTreeView();
00217     void _k_slotToggleHidden(bool);
00218     void _k_togglePreview(bool);
00219     void _k_toggleInlinePreviews(bool);
00220     void _k_slotOpenFileManager();
00221     void _k_slotSortByName();
00222     void _k_slotSortBySize();
00223     void _k_slotSortByDate();
00224     void _k_slotSortByType();
00225     void _k_slotSortReversed(bool doReverse);
00226     void _k_slotToggleDirsFirst();
00227     void _k_slotToggleIgnoreCase();
00228     void _k_slotStarted();
00229     void _k_slotProgress(int);
00230     void _k_slotShowProgress();
00231     void _k_slotIOFinished();
00232     void _k_slotCanceled();
00233     void _k_slotRedirected(const KUrl&);
00234     void _k_slotProperties();
00235     void _k_slotActivated(const QModelIndex&);
00236     void _k_slotSelectionChanged();
00237     void _k_openContextMenu(const QPoint&);
00238     void _k_triggerPreview(const QModelIndex&);
00239     void _k_showPreview();
00240     void _k_slotSplitterMoved(int, int);
00241     void _k_assureVisibleSelection();
00242     void _k_synchronizeSortingState(int, Qt::SortOrder);
00243     void _k_slotChangeDecorationPosition();
00244     void _k_slotExpandToUrl(const QModelIndex&);
00245     void _k_slotItemsChanged();
00246     void _k_slotDirectoryCreated(const KUrl&);
00247 
00248     void updateListViewGrid();
00249     int iconSizeForViewType(QAbstractItemView *itemView) const;
00250 
00251     // private members
00252     KDirOperator *parent;
00253     QStack<KUrl*> backStack;    
00254     QStack<KUrl*> forwardStack; 
00255 
00256     QModelIndex lastHoveredIndex;
00257 
00258     KDirLister *dirLister;
00259     KUrl currUrl;
00260 
00261     KCompletion completion;
00262     KCompletion dirCompletion;
00263     bool completeListDirty;
00264     QDir::SortFlags sorting;
00265     QStyleOptionViewItem::Position decorationPosition;
00266 
00267     QSplitter *splitter;
00268 
00269     QAbstractItemView *itemView;
00270     KDirModel *dirModel;
00271     KDirSortFilterProxyModel *proxyModel;
00272 
00273     KFileItemList pendingMimeTypes;
00274 
00275     // the enum KFile::FileView as an int
00276     int viewKind;
00277     int defaultView;
00278 
00279     KFile::Modes mode;
00280     QProgressBar *progressBar;
00281 
00282     KPreviewWidgetBase *preview;
00283     KUrl previewUrl;
00284     int previewWidth;
00285 
00286     bool dirHighlighting;
00287     bool onlyDoubleClickSelectsFiles;
00288     QString lastURL; // used for highlighting a directory on cdUp
00289     QTimer *progressDelayTimer;
00290     int dropOptions;
00291 
00292     KActionMenu *actionMenu;
00293     KActionCollection *actionCollection;
00294 
00295     KNewFileMenu *newFileMenu;
00296 
00297     KConfigGroup *configGroup;
00298 
00299     KFilePreviewGenerator *previewGenerator;
00300 
00301     bool showPreviews;
00302     int iconsZoom;
00303 
00304     bool isSaving;
00305 
00306     KActionMenu *decorationMenu;
00307     KToggleAction *leftAction;
00308     KUrl::List itemsToBeSetAsCurrent;
00309     bool shouldFetchForItems;
00310     InlinePreviewState inlinePreviewState;
00311 };
00312 
00313 KDirOperator::Private::Private(KDirOperator *_parent) :
00314     parent(_parent),
00315     dirLister(0),
00316     decorationPosition(QStyleOptionViewItem::Left),
00317     splitter(0),
00318     itemView(0),
00319     dirModel(0),
00320     proxyModel(0),
00321     progressBar(0),
00322     preview(0),
00323     previewUrl(),
00324     previewWidth(0),
00325     dirHighlighting(false),
00326     onlyDoubleClickSelectsFiles(!KGlobalSettings::singleClick()),
00327     progressDelayTimer(0),
00328     dropOptions(0),
00329     actionMenu(0),
00330     actionCollection(0),
00331     newFileMenu(0),
00332     configGroup(0),
00333     previewGenerator(0),
00334     showPreviews(false),
00335     iconsZoom(0),
00336     isSaving(false),
00337     decorationMenu(0),
00338     leftAction(0),
00339     shouldFetchForItems(false),
00340     inlinePreviewState(NotForced)
00341 {
00342 }
00343 
00344 KDirOperator::Private::~Private()
00345 {
00346     delete itemView;
00347     itemView = 0;
00348 
00349     // TODO:
00350     // if (configGroup) {
00351     //     itemView->writeConfig(configGroup);
00352     // }
00353 
00354     qDeleteAll(backStack);
00355     qDeleteAll(forwardStack);
00356     delete preview;
00357     preview = 0;
00358 
00359     delete proxyModel;
00360     proxyModel = 0;
00361     delete dirModel;
00362     dirModel = 0;
00363     dirLister = 0; // deleted by KDirModel
00364     delete configGroup;
00365     configGroup = 0;
00366 
00367     delete progressDelayTimer;
00368     progressDelayTimer = 0;
00369 }
00370 
00371 KDirOperator::KDirOperator(const KUrl& _url, QWidget *parent) :
00372     QWidget(parent),
00373     d(new Private(this))
00374 {
00375     d->splitter = new QSplitter(this);
00376     d->splitter->setChildrenCollapsible(false);
00377     connect(d->splitter, SIGNAL(splitterMoved(int, int)),
00378             this, SLOT(_k_slotSplitterMoved(int, int)));
00379 
00380     d->preview = 0;
00381 
00382     d->mode = KFile::File;
00383     d->viewKind = KFile::Simple;
00384 
00385     if (_url.isEmpty()) { // no dir specified -> current dir
00386         QString strPath = QDir::currentPath();
00387         strPath.append(QChar('/'));
00388         d->currUrl = KUrl();
00389         d->currUrl.setProtocol(QLatin1String("file"));
00390         d->currUrl.setPath(strPath);
00391     } else {
00392         d->currUrl = _url;
00393         if (d->currUrl.protocol().isEmpty())
00394             d->currUrl.setProtocol(QLatin1String("file"));
00395 
00396         d->currUrl.addPath("/"); // make sure we have a trailing slash!
00397     }
00398 
00399     // We set the direction of this widget to LTR, since even on RTL desktops
00400     // viewing directory listings in RTL mode makes people's head explode.
00401     // Is this the correct place? Maybe it should be in some lower level widgets...?
00402     setLayoutDirection(Qt::LeftToRight);
00403     setDirLister(new KDirLister());
00404 
00405     connect(&d->completion, SIGNAL(match(const QString&)),
00406             SLOT(slotCompletionMatch(const QString&)));
00407 
00408     d->progressBar = new QProgressBar(this);
00409     d->progressBar->setObjectName("d->progressBar");
00410     d->progressBar->adjustSize();
00411     d->progressBar->move(2, height() - d->progressBar->height() - 2);
00412 
00413     d->progressDelayTimer = new QTimer(this);
00414     d->progressDelayTimer->setObjectName(QLatin1String("d->progressBar delay timer"));
00415     connect(d->progressDelayTimer, SIGNAL(timeout()),
00416             SLOT(_k_slotShowProgress()));
00417 
00418     d->completeListDirty = false;
00419 
00420     // action stuff
00421     setupActions();
00422     setupMenu();
00423 
00424     d->sorting = QDir::NoSort;  //so updateSorting() doesn't think nothing has changed
00425     d->updateSorting(QDir::Name | QDir::DirsFirst);
00426 
00427     setFocusPolicy(Qt::WheelFocus);
00428 }
00429 
00430 KDirOperator::~KDirOperator()
00431 {
00432     resetCursor();
00433     disconnect(d->dirLister, 0, this, 0);
00434     delete d;
00435 }
00436 
00437 
00438 void KDirOperator::setSorting(QDir::SortFlags spec)
00439 {
00440     d->updateSorting(spec);
00441 }
00442 
00443 QDir::SortFlags KDirOperator::sorting() const
00444 {
00445     return d->sorting;
00446 }
00447 
00448 bool KDirOperator::isRoot() const
00449 {
00450 #ifdef Q_WS_WIN
00451     if (url().isLocalFile()) {
00452         const QString path = url().toLocalFile();
00453         if (path.length() == 3)
00454             return (path[0].isLetter() && path[1] == ':' && path[2] == '/');
00455         return false;
00456     } else
00457 #endif
00458     return url().path() == QString(QLatin1Char('/'));
00459 }
00460 
00461 KDirLister *KDirOperator::dirLister() const
00462 {
00463     return d->dirLister;
00464 }
00465 
00466 void KDirOperator::resetCursor()
00467 {
00468     if (qApp)
00469         QApplication::restoreOverrideCursor();
00470     d->progressBar->hide();
00471 }
00472 
00473 void KDirOperator::sortByName()
00474 {
00475     d->updateSorting((d->sorting & ~QDirSortMask) | QDir::Name);
00476 }
00477 
00478 void KDirOperator::sortBySize()
00479 {
00480     d->updateSorting((d->sorting & ~QDirSortMask) | QDir::Size);
00481 }
00482 
00483 void KDirOperator::sortByDate()
00484 {
00485     d->updateSorting((d->sorting & ~QDirSortMask) | QDir::Time);
00486 }
00487 
00488 void KDirOperator::sortByType()
00489 {
00490     d->updateSorting((d->sorting & ~QDirSortMask) | QDir::Type);
00491 }
00492 
00493 void KDirOperator::sortReversed()
00494 {
00495     // toggle it, hence the inversion of current state
00496     d->_k_slotSortReversed(!(d->sorting & QDir::Reversed));
00497 }
00498 
00499 void KDirOperator::toggleDirsFirst()
00500 {
00501     d->_k_slotToggleDirsFirst();
00502 }
00503 
00504 void KDirOperator::toggleIgnoreCase()
00505 {
00506     if (d->proxyModel != 0) {
00507         Qt::CaseSensitivity cs = d->proxyModel->sortCaseSensitivity();
00508         cs = (cs == Qt::CaseSensitive) ? Qt::CaseInsensitive : Qt::CaseSensitive;
00509         d->proxyModel->setSortCaseSensitivity(cs);
00510     }
00511 }
00512 
00513 void KDirOperator::updateSelectionDependentActions()
00514 {
00515     const bool hasSelection = (d->itemView != 0) &&
00516                               d->itemView->selectionModel()->hasSelection();
00517     d->actionCollection->action("trash")->setEnabled(hasSelection);
00518     d->actionCollection->action("delete")->setEnabled(hasSelection);
00519     d->actionCollection->action("properties")->setEnabled(hasSelection);
00520 }
00521 
00522 void KDirOperator::setPreviewWidget(KPreviewWidgetBase *w)
00523 {
00524     const bool showPreview = (w != 0);
00525     if (showPreview) {
00526         d->viewKind = (d->viewKind | KFile::PreviewContents);
00527     } else {
00528         d->viewKind = (d->viewKind & ~KFile::PreviewContents);
00529     }
00530 
00531     delete d->preview;
00532     d->preview = w;
00533 
00534     if (w) {
00535         d->splitter->addWidget(w);
00536     }
00537 
00538     KToggleAction *previewAction = static_cast<KToggleAction*>(d->actionCollection->action("preview"));
00539     previewAction->setEnabled(showPreview);
00540     previewAction->setChecked(showPreview);
00541     setView(static_cast<KFile::FileView>(d->viewKind));
00542 }
00543 
00544 KFileItemList KDirOperator::selectedItems() const
00545 {
00546     KFileItemList itemList;
00547     if (d->itemView == 0) {
00548         return itemList;
00549     }
00550 
00551     const QItemSelection selection = d->proxyModel->mapSelectionToSource(d->itemView->selectionModel()->selection());
00552 
00553     const QModelIndexList indexList = selection.indexes();
00554     foreach(const QModelIndex &index, indexList) {
00555         KFileItem item = d->dirModel->itemForIndex(index);
00556         if (!item.isNull()) {
00557             itemList.append(item);
00558         }
00559     }
00560 
00561     return itemList;
00562 }
00563 
00564 bool KDirOperator::isSelected(const KFileItem &item) const
00565 {
00566     if ((item.isNull()) || (d->itemView == 0)) {
00567         return false;
00568     }
00569 
00570     const QModelIndex dirIndex = d->dirModel->indexForItem(item);
00571     const QModelIndex proxyIndex = d->proxyModel->mapFromSource(dirIndex);
00572     return d->itemView->selectionModel()->isSelected(proxyIndex);
00573 }
00574 
00575 int KDirOperator::numDirs() const
00576 {
00577     return (d->dirLister == 0) ? 0 : d->dirLister->directories().count();
00578 }
00579 
00580 int KDirOperator::numFiles() const
00581 {
00582     return (d->dirLister == 0) ? 0 : d->dirLister->items().count() - numDirs();
00583 }
00584 
00585 KCompletion * KDirOperator::completionObject() const
00586 {
00587     return const_cast<KCompletion *>(&d->completion);
00588 }
00589 
00590 KCompletion *KDirOperator::dirCompletionObject() const
00591 {
00592     return const_cast<KCompletion *>(&d->dirCompletion);
00593 }
00594 
00595 KActionCollection * KDirOperator::actionCollection() const
00596 {
00597     return d->actionCollection;
00598 }
00599 
00600 KFile::FileView KDirOperator::Private::allViews() {
00601     return static_cast<KFile::FileView>(KFile::Simple | KFile::Detail | KFile::Tree | KFile::DetailTree);
00602 }
00603 
00604 void KDirOperator::Private::_k_slotDetailedView()
00605 {
00606     KFile::FileView view = static_cast<KFile::FileView>((viewKind & ~allViews()) | KFile::Detail);
00607     parent->setView(view);
00608 }
00609 
00610 void KDirOperator::Private::_k_slotSimpleView()
00611 {
00612     KFile::FileView view = static_cast<KFile::FileView>((viewKind & ~allViews()) | KFile::Simple);
00613     parent->setView(view);
00614 }
00615 
00616 void KDirOperator::Private::_k_slotTreeView()
00617 {
00618     KFile::FileView view = static_cast<KFile::FileView>((viewKind & ~allViews()) | KFile::Tree);
00619     parent->setView(view);
00620 }
00621 
00622 void KDirOperator::Private::_k_slotDetailedTreeView()
00623 {
00624     KFile::FileView view = static_cast<KFile::FileView>((viewKind & ~allViews()) | KFile::DetailTree);
00625     parent->setView(view);
00626 }
00627 
00628 void KDirOperator::Private::_k_slotToggleHidden(bool show)
00629 {
00630     dirLister->setShowingDotFiles(show);
00631     parent->updateDir();
00632     _k_assureVisibleSelection();
00633 }
00634 
00635 void KDirOperator::Private::_k_togglePreview(bool on)
00636 {
00637     if (on) {
00638         viewKind = viewKind | KFile::PreviewContents;
00639         if (preview == 0) {
00640             preview = new KFileMetaPreview(parent);
00641             actionCollection->action("preview")->setChecked(true);
00642             splitter->addWidget(preview);
00643         }
00644 
00645         preview->show();
00646 
00647         QMetaObject::invokeMethod(parent, "_k_assureVisibleSelection", Qt::QueuedConnection);
00648         if (itemView != 0) {
00649             const QModelIndex index = itemView->selectionModel()->currentIndex();
00650             if (index.isValid()) {
00651                 _k_triggerPreview(index);
00652             }
00653         }
00654     } else if (preview != 0) {
00655         viewKind = viewKind & ~KFile::PreviewContents;
00656         preview->hide();
00657     }
00658 }
00659 
00660 void KDirOperator::Private::_k_toggleInlinePreviews(bool show)
00661 {
00662     if (showPreviews == show) {
00663         return;
00664     }
00665 
00666     showPreviews = show;
00667 
00668     if (!previewGenerator) {
00669         return;
00670     }
00671 
00672     previewGenerator->setPreviewShown(show);
00673 
00674     if (!show) {
00675         // remove all generated previews
00676         QAbstractItemModel *model = dirModel;
00677         for (int i = 0; i < model->rowCount(); ++i) {
00678             QModelIndex index = model->index(i, 0);
00679             const KFileItem item = dirModel->itemForIndex(index);
00680             const_cast<QAbstractItemModel*>(index.model())->setData(index, KIcon(item.iconName()), Qt::DecorationRole);
00681         }
00682     }
00683 }
00684 
00685 void KDirOperator::Private::_k_slotOpenFileManager()
00686 {
00687     new KRun(currUrl, parent);
00688 }
00689 
00690 void KDirOperator::Private::_k_slotSortByName()
00691 {
00692     parent->sortByName();
00693 }
00694 
00695 void KDirOperator::Private::_k_slotSortBySize()
00696 {
00697     parent->sortBySize();
00698 }
00699 
00700 void KDirOperator::Private::_k_slotSortByDate()
00701 {
00702     parent->sortByDate();
00703 }
00704 
00705 void KDirOperator::Private::_k_slotSortByType()
00706 {
00707     parent->sortByType();
00708 }
00709 
00710 void KDirOperator::Private::_k_slotSortReversed(bool doReverse)
00711 {
00712     QDir::SortFlags s = sorting & ~QDir::Reversed;
00713     if (doReverse) {
00714         s |= QDir::Reversed;
00715     }
00716     updateSorting(s);
00717 }
00718 
00719 void KDirOperator::Private::_k_slotToggleDirsFirst()
00720 {
00721     QDir::SortFlags s = (sorting ^ QDir::DirsFirst);
00722     updateSorting(s);
00723 }
00724 
00725 void KDirOperator::Private::_k_slotToggleIgnoreCase()
00726 {
00727     // TODO: port to Qt4's QAbstractItemView
00728     /*if ( !d->fileView )
00729       return;
00730 
00731     QDir::SortFlags sorting = d->fileView->sorting();
00732     if ( !KFile::isSortCaseInsensitive( sorting ) )
00733         d->fileView->setSorting( sorting | QDir::IgnoreCase );
00734     else
00735         d->fileView->setSorting( sorting & ~QDir::IgnoreCase );
00736     d->sorting = d->fileView->sorting();*/
00737 }
00738 
00739 void KDirOperator::mkdir()
00740 {
00741     d->newFileMenu->setPopupFiles(url());
00742     d->newFileMenu->setViewShowsHiddenFiles(showHiddenFiles());
00743     d->newFileMenu->createDirectory();
00744 }
00745 
00746 bool KDirOperator::mkdir(const QString& directory, bool enterDirectory)
00747 {
00748     // Creates "directory", relative to the current directory (d->currUrl).
00749     // The given path may contain any number directories, existent or not.
00750     // They will all be created, if possible.
00751 
00752     bool writeOk = false;
00753     bool exists = false;
00754     KUrl url(d->currUrl);
00755 
00756     const QStringList dirs = directory.split('/', QString::SkipEmptyParts);
00757     QStringList::ConstIterator it = dirs.begin();
00758 
00759     for (; it != dirs.end(); ++it) {
00760         url.addPath(*it);
00761         exists = KIO::NetAccess::exists(url, KIO::NetAccess::DestinationSide, 0);
00762         writeOk = !exists && KIO::NetAccess::mkdir(url, topLevelWidget());
00763     }
00764 
00765     if (exists) { // url was already existent
00766         KMessageBox::sorry(d->itemView, i18n("A file or folder named %1 already exists.", url.pathOrUrl()));
00767     } else if (!writeOk) {
00768         KMessageBox::sorry(d->itemView, i18n("You do not have permission to "
00769                                               "create that folder."));
00770     } else if (enterDirectory) {
00771         setUrl(url, true);
00772     }
00773 
00774     return writeOk;
00775 }
00776 
00777 KIO::DeleteJob * KDirOperator::del(const KFileItemList& items,
00778                                    QWidget *parent,
00779                                    bool ask, bool showProgress)
00780 {
00781     if (items.isEmpty()) {
00782         KMessageBox::information(parent,
00783                                  i18n("You did not select a file to delete."),
00784                                  i18n("Nothing to Delete"));
00785         return 0L;
00786     }
00787 
00788     if (parent == 0) {
00789         parent = this;
00790     }
00791 
00792     KUrl::List urls;
00793     QStringList files;
00794     foreach (const KFileItem &item, items) {
00795         const KUrl url = item.url();
00796         urls.append(url);
00797         files.append(url.pathOrUrl());
00798     }
00799 
00800     bool doIt = !ask;
00801     if (ask) {
00802         int ret;
00803         if (items.count() == 1) {
00804             ret = KMessageBox::warningContinueCancel(parent,
00805                     i18n("<qt>Do you really want to delete\n <b>'%1'</b>?</qt>" ,
00806                          files.first()),
00807                     i18n("Delete File"),
00808                     KStandardGuiItem::del(),
00809                     KStandardGuiItem::cancel(), "AskForDelete");
00810         } else
00811             ret = KMessageBox::warningContinueCancelList(parent,
00812                     i18np("Do you really want to delete this item?", "Do you really want to delete these %1 items?", items.count()),
00813                     files,
00814                     i18n("Delete Files"),
00815                     KStandardGuiItem::del(),
00816                     KStandardGuiItem::cancel(), "AskForDelete");
00817         doIt = (ret == KMessageBox::Continue);
00818     }
00819 
00820     if (doIt) {
00821         KIO::JobFlags flags = showProgress ? KIO::DefaultFlags : KIO::HideProgressInfo;
00822         KIO::DeleteJob *job = KIO::del(urls, flags);
00823         job->ui()->setWindow(topLevelWidget());
00824         job->ui()->setAutoErrorHandlingEnabled(true);
00825         return job;
00826     }
00827 
00828     return 0L;
00829 }
00830 
00831 void KDirOperator::deleteSelected()
00832 {
00833     const KFileItemList list = selectedItems();
00834     if (!list.isEmpty()) {
00835         del(list, this);
00836     }
00837 }
00838 
00839 KIO::CopyJob * KDirOperator::trash(const KFileItemList& items,
00840                                    QWidget *parent,
00841                                    bool ask, bool showProgress)
00842 {
00843     if (items.isEmpty()) {
00844         KMessageBox::information(parent,
00845                                  i18n("You did not select a file to trash."),
00846                                  i18n("Nothing to Trash"));
00847         return 0L;
00848     }
00849 
00850     KUrl::List urls;
00851     QStringList files;
00852     foreach (const KFileItem &item, items) {
00853         const KUrl url = item.url();
00854         urls.append(url);
00855         files.append(url.pathOrUrl());
00856     }
00857 
00858     bool doIt = !ask;
00859     if (ask) {
00860         int ret;
00861         if (items.count() == 1) {
00862             ret = KMessageBox::warningContinueCancel(parent,
00863                     i18n("<qt>Do you really want to trash\n <b>'%1'</b>?</qt>" ,
00864                          files.first()),
00865                     i18n("Trash File"),
00866                     KGuiItem(i18nc("to trash", "&Trash"), "user-trash"),
00867                     KStandardGuiItem::cancel(), "AskForTrash");
00868         } else
00869             ret = KMessageBox::warningContinueCancelList(parent,
00870                     i18np("translators: not called for n == 1", "Do you really want to trash these %1 items?", items.count()),
00871                     files,
00872                     i18n("Trash Files"),
00873                     KGuiItem(i18nc("to trash", "&Trash"), "user-trash"),
00874                     KStandardGuiItem::cancel(), "AskForTrash");
00875         doIt = (ret == KMessageBox::Continue);
00876     }
00877 
00878     if (doIt) {
00879         KIO::JobFlags flags = showProgress ? KIO::DefaultFlags : KIO::HideProgressInfo;
00880         KIO::CopyJob *job = KIO::trash(urls, flags);
00881         job->ui()->setWindow(topLevelWidget());
00882         job->ui()->setAutoErrorHandlingEnabled(true);
00883         return job;
00884     }
00885 
00886     return 0L;
00887 }
00888 
00889 KFilePreviewGenerator *KDirOperator::previewGenerator() const
00890 {
00891     return d->previewGenerator;
00892 }
00893 
00894 void KDirOperator::setInlinePreviewShown(bool show)
00895 {
00896     d->inlinePreviewState = show ? Private::ForcedToTrue : Private::ForcedToFalse;
00897 }
00898 
00899 bool KDirOperator::isInlinePreviewShown() const
00900 {
00901     return d->showPreviews;
00902 }
00903 
00904 int KDirOperator::iconsZoom() const
00905 {
00906     return d->iconsZoom;
00907 }
00908 
00909 void KDirOperator::setIsSaving(bool isSaving)
00910 {
00911     d->isSaving = isSaving;
00912 }
00913 
00914 bool KDirOperator::isSaving() const
00915 {
00916     return d->isSaving;
00917 }
00918 
00919 void KDirOperator::trashSelected()
00920 {
00921     if (d->itemView == 0) {
00922         return;
00923     }
00924 
00925     if (QApplication::keyboardModifiers() & Qt::ShiftModifier) {
00926         deleteSelected();
00927         return;
00928     }
00929 
00930     const KFileItemList list = selectedItems();
00931     if (!list.isEmpty()) {
00932         trash(list, this);
00933     }
00934 }
00935 
00936 void KDirOperator::setIconsZoom(int _value)
00937 {
00938     if (d->iconsZoom == _value) {
00939         return;
00940     }
00941 
00942     int value = _value;
00943     value = qMin(100, value);
00944     value = qMax(0, value);
00945 
00946     d->iconsZoom = value;
00947 
00948     if (d->configGroup && d->inlinePreviewState == Private::NotForced) {
00949         if (qobject_cast<QListView*>(d->itemView)) {
00950             d->configGroup->writeEntry("listViewIconSize", d->iconsZoom);
00951         } else {
00952             d->configGroup->writeEntry("detailedViewIconSize", d->iconsZoom);
00953         }
00954     }
00955 
00956     if (!d->previewGenerator) {
00957         return;
00958     }
00959 
00960     const int maxSize = KIconLoader::SizeEnormous - KIconLoader::SizeSmall;
00961     const int val = (maxSize * value / 100) + KIconLoader::SizeSmall;
00962     d->itemView->setIconSize(QSize(val, val));
00963     d->updateListViewGrid();
00964     d->previewGenerator->updatePreviews();
00965 
00966     emit currentIconSizeChanged(value);
00967 }
00968 
00969 void KDirOperator::close()
00970 {
00971     resetCursor();
00972     d->pendingMimeTypes.clear();
00973     d->completion.clear();
00974     d->dirCompletion.clear();
00975     d->completeListDirty = true;
00976     d->dirLister->stop();
00977 }
00978 
00979 void KDirOperator::Private::checkPath(const QString &, bool /*takeFiles*/) // SLOT
00980 {
00981 #if 0
00982     // copy the argument in a temporary string
00983     QString text = _txt;
00984     // it's unlikely to happen, that at the beginning are spaces, but
00985     // for the end, it happens quite often, I guess.
00986     text = text.trimmed();
00987     // if the argument is no URL (the check is quite fragil) and it's
00988     // no absolute path, we add the current directory to get a correct url
00989     if (text.find(':') < 0 && text[0] != '/')
00990         text.insert(0, d->currUrl);
00991 
00992     // in case we have a selection defined and someone patched the file-
00993     // name, we check, if the end of the new name is changed.
00994     if (!selection.isNull()) {
00995         int position = text.lastIndexOf('/');
00996         ASSERT(position >= 0); // we already inserted the current d->dirLister in case
00997         QString filename = text.mid(position + 1, text.length());
00998         if (filename != selection)
00999             selection.clear();
01000     }
01001 
01002     KUrl u(text); // I have to take care of entered URLs
01003     bool filenameEntered = false;
01004 
01005     if (u.isLocalFile()) {
01006         // the empty path is kind of a hack
01007         KFileItem i("", u.toLocalFile());
01008         if (i.isDir())
01009             setUrl(text, true);
01010         else {
01011             if (takeFiles)
01012                 if (acceptOnlyExisting && !i.isFile())
01013                     warning("you entered an invalid URL");
01014                 else
01015                     filenameEntered = true;
01016         }
01017     } else
01018         setUrl(text, true);
01019 
01020     if (filenameEntered) {
01021         filename_ = u.url();
01022         emit fileSelected(filename_);
01023 
01024         QApplication::restoreOverrideCursor();
01025 
01026         accept();
01027     }
01028 #endif
01029     kDebug(kfile_area) << "TODO KDirOperator::checkPath()";
01030 }
01031 
01032 void KDirOperator::setUrl(const KUrl& _newurl, bool clearforward)
01033 {
01034     KUrl newurl;
01035 
01036     if (!_newurl.isValid())
01037         newurl.setPath(QDir::homePath());
01038     else
01039         newurl = _newurl;
01040 
01041     newurl.adjustPath( KUrl::AddTrailingSlash );
01042 #ifdef Q_WS_WIN
01043     QString pathstr = QDir::fromNativeSeparators(newurl.toLocalFile());
01044 #else
01045     QString pathstr = newurl.path();
01046 #endif
01047     newurl.setPath(pathstr);
01048 
01049     // already set
01050     if (newurl.equals(d->currUrl, KUrl::CompareWithoutTrailingSlash))
01051         return;
01052 
01053     if (!Private::isReadable(newurl)) {
01054         // maybe newurl is a file? check its parent directory
01055         newurl.setPath(newurl.directory(KUrl::ObeyTrailingSlash));
01056         if (newurl.equals(d->currUrl, KUrl::CompareWithoutTrailingSlash))
01057             return; // parent is current dir, nothing to do (fixes #173454, too)
01058         KIO::UDSEntry entry;
01059         bool res = KIO::NetAccess::stat(newurl, entry, this);
01060         KFileItem i(entry, newurl);
01061         if ((!res || !Private::isReadable(newurl)) && i.isDir()) {
01062             resetCursor();
01063             KMessageBox::error(d->itemView,
01064                                i18n("The specified folder does not exist "
01065                                     "or was not readable."));
01066             return;
01067         } else if (!i.isDir()) {
01068             return;
01069         }
01070     }
01071 
01072     if (clearforward) {
01073         // autodelete should remove this one
01074         d->backStack.push(new KUrl(d->currUrl));
01075         qDeleteAll(d->forwardStack);
01076         d->forwardStack.clear();
01077     }
01078 
01079     d->lastURL = d->currUrl.url(KUrl::RemoveTrailingSlash);
01080     d->currUrl = newurl;
01081 
01082     pathChanged();
01083     emit urlEntered(newurl);
01084 
01085     // enable/disable actions
01086     QAction* forwardAction = d->actionCollection->action("forward");
01087     forwardAction->setEnabled(!d->forwardStack.isEmpty());
01088 
01089     QAction* backAction = d->actionCollection->action("back");
01090     backAction->setEnabled(!d->backStack.isEmpty());
01091 
01092     QAction* upAction = d->actionCollection->action("up");
01093     upAction->setEnabled(!isRoot());
01094 
01095     d->openUrl(newurl);
01096 }
01097 
01098 void KDirOperator::updateDir()
01099 {
01100     QApplication::setOverrideCursor(Qt::WaitCursor);
01101     d->dirLister->emitChanges();
01102     QApplication::restoreOverrideCursor();
01103 }
01104 
01105 void KDirOperator::rereadDir()
01106 {
01107     pathChanged();
01108     d->openUrl(d->currUrl, KDirLister::Reload);
01109 }
01110 
01111 
01112 bool KDirOperator::Private::openUrl(const KUrl& url, KDirLister::OpenUrlFlags flags)
01113 {
01114     const bool result = KProtocolManager::supportsListing(url) && dirLister->openUrl(url, flags);
01115     if (!result)   // in that case, neither completed() nor canceled() will be emitted by KDL
01116         _k_slotCanceled();
01117 
01118     return result;
01119 }
01120 
01121 int KDirOperator::Private::sortColumn() const
01122 {
01123     int column = KDirModel::Name;
01124     if (KFile::isSortByDate(sorting)) {
01125         column = KDirModel::ModifiedTime;
01126     } else if (KFile::isSortBySize(sorting)) {
01127         column = KDirModel::Size;
01128     } else if (KFile::isSortByType(sorting)) {
01129         column = KDirModel::Type;
01130     } else {
01131         Q_ASSERT(KFile::isSortByName(sorting));
01132     }
01133 
01134     return column;
01135 }
01136 
01137 Qt::SortOrder KDirOperator::Private::sortOrder() const
01138 {
01139     return (sorting & QDir::Reversed) ? Qt::DescendingOrder :
01140                                         Qt::AscendingOrder;
01141 }
01142 
01143 void KDirOperator::Private::updateSorting(QDir::SortFlags sort)
01144 {
01145     kDebug(kfile_area) << "changing sort flags from"  << sorting << "to" << sort;
01146     if (sort == sorting) {
01147         return;
01148     }
01149 
01150     if ((sorting ^ sort) & QDir::DirsFirst) {
01151         // The "Folders First" setting has been changed.
01152         // We need to make sure that the files and folders are really re-sorted.
01153         // Without the following intermediate "fake resorting",
01154         // QSortFilterProxyModel::sort(int column, Qt::SortOrder order)
01155         // would do nothing because neither the column nor the sort order have been changed.
01156         Qt::SortOrder tmpSortOrder = (sortOrder() == Qt::AscendingOrder ? Qt::DescendingOrder : Qt::AscendingOrder);
01157         proxyModel->sort(sortOrder(), tmpSortOrder);
01158         proxyModel->setSortFoldersFirst(sort & QDir::DirsFirst);
01159     }
01160 
01161     sorting = sort;
01162     parent->updateSortActions();
01163     proxyModel->sort(sortColumn(), sortOrder());
01164 
01165     // TODO: The headers from QTreeView don't take care about a sorting
01166     // change of the proxy model hence they must be updated the manually.
01167     // This is done here by a qobject_cast, but it would be nicer to:
01168     // - provide a signal 'sortingChanged()'
01169     // - connect KDirOperatorDetailView() with this signal and update the
01170     //   header internally
01171     QTreeView* treeView = qobject_cast<QTreeView*>(itemView);
01172     if (treeView != 0) {
01173         QHeaderView* headerView = treeView->header();
01174         headerView->blockSignals(true);
01175         headerView->setSortIndicator(sortColumn(), sortOrder());
01176         headerView->blockSignals(false);
01177     }
01178 
01179     _k_assureVisibleSelection();
01180 }
01181 
01182 // Protected
01183 void KDirOperator::pathChanged()
01184 {
01185     if (d->itemView == 0)
01186         return;
01187 
01188     d->pendingMimeTypes.clear();
01189     //d->fileView->clear(); TODO
01190     d->completion.clear();
01191     d->dirCompletion.clear();
01192 
01193     // it may be, that we weren't ready at this time
01194     QApplication::restoreOverrideCursor();
01195 
01196     // when KIO::Job emits finished, the slot will restore the cursor
01197     QApplication::setOverrideCursor(Qt::WaitCursor);
01198 
01199     if (!Private::isReadable(d->currUrl)) {
01200         KMessageBox::error(d->itemView,
01201                            i18n("The specified folder does not exist "
01202                                 "or was not readable."));
01203         if (d->backStack.isEmpty())
01204             home();
01205         else
01206             back();
01207     }
01208 }
01209 
01210 void KDirOperator::Private::_k_slotRedirected(const KUrl& newURL)
01211 {
01212     currUrl = newURL;
01213     pendingMimeTypes.clear();
01214     completion.clear();
01215     dirCompletion.clear();
01216     completeListDirty = true;
01217     emit parent->urlEntered(newURL);
01218 }
01219 
01220 // Code pinched from kfm then hacked
01221 void KDirOperator::back()
01222 {
01223     if (d->backStack.isEmpty())
01224         return;
01225 
01226     d->forwardStack.push(new KUrl(d->currUrl));
01227 
01228     KUrl *s = d->backStack.pop();
01229 
01230     setUrl(*s, false);
01231     delete s;
01232 }
01233 
01234 // Code pinched from kfm then hacked
01235 void KDirOperator::forward()
01236 {
01237     if (d->forwardStack.isEmpty())
01238         return;
01239 
01240     d->backStack.push(new KUrl(d->currUrl));
01241 
01242     KUrl *s = d->forwardStack.pop();
01243     setUrl(*s, false);
01244     delete s;
01245 }
01246 
01247 KUrl KDirOperator::url() const
01248 {
01249     return d->currUrl;
01250 }
01251 
01252 void KDirOperator::cdUp()
01253 {
01254     KUrl tmp(d->currUrl);
01255     tmp.cd(QLatin1String(".."));
01256     setUrl(tmp, true);
01257 }
01258 
01259 void KDirOperator::home()
01260 {
01261     KUrl u;
01262     u.setPath(QDir::homePath());
01263     setUrl(u, true);
01264 }
01265 
01266 void KDirOperator::clearFilter()
01267 {
01268     d->dirLister->setNameFilter(QString());
01269     d->dirLister->clearMimeFilter();
01270     checkPreviewSupport();
01271 }
01272 
01273 void KDirOperator::setNameFilter(const QString& filter)
01274 {
01275     d->dirLister->setNameFilter(filter);
01276     checkPreviewSupport();
01277 }
01278 
01279 QString KDirOperator::nameFilter() const
01280 {
01281     return d->dirLister->nameFilter();
01282 }
01283 
01284 void KDirOperator::setMimeFilter(const QStringList& mimetypes)
01285 {
01286     d->dirLister->setMimeFilter(mimetypes);
01287     checkPreviewSupport();
01288 }
01289 
01290 QStringList KDirOperator::mimeFilter() const
01291 {
01292     return d->dirLister->mimeFilters();
01293 }
01294 
01295 void KDirOperator::setNewFileMenuSupportedMimeTypes(const QStringList& mimeTypes)
01296 {
01297     d->newFileMenu->setSupportedMimeTypes(mimeTypes);
01298 }
01299 
01300 QStringList KDirOperator::newFileMenuSupportedMimeTypes() const
01301 {
01302     return d->newFileMenu->supportedMimeTypes();
01303 }
01304 
01305 bool KDirOperator::checkPreviewSupport()
01306 {
01307     KToggleAction *previewAction = static_cast<KToggleAction*>(d->actionCollection->action("preview"));
01308 
01309     bool hasPreviewSupport = false;
01310     KConfigGroup cg(KGlobal::config(), ConfigGroup);
01311     if (cg.readEntry("Show Default Preview", true))
01312         hasPreviewSupport = d->checkPreviewInternal();
01313 
01314     previewAction->setEnabled(hasPreviewSupport);
01315     return hasPreviewSupport;
01316 }
01317 
01318 void KDirOperator::activatedMenu(const KFileItem &item, const QPoint &pos)
01319 {
01320     Q_UNUSED(item);
01321     updateSelectionDependentActions();
01322 
01323     d->newFileMenu->setPopupFiles(url());
01324     d->newFileMenu->setViewShowsHiddenFiles(showHiddenFiles());
01325     d->newFileMenu->checkUpToDate();
01326 
01327     emit contextMenuAboutToShow( item, d->actionMenu->menu() );
01328 
01329     d->actionMenu->menu()->exec(pos);
01330 }
01331 
01332 void KDirOperator::changeEvent(QEvent *event)
01333 {
01334     QWidget::changeEvent(event);
01335 }
01336 
01337 bool KDirOperator::eventFilter(QObject *watched, QEvent *event)
01338 {
01339     Q_UNUSED(watched);
01340 
01341     // If we are not hovering any items, check if there is a current index
01342     // set. In that case, we show the preview of that item.
01343     switch(event->type()) {
01344         case QEvent::MouseMove: {
01345                 if (d->preview && !d->preview->isHidden()) {
01346                     const QModelIndex hoveredIndex = d->itemView->indexAt(d->itemView->viewport()->mapFromGlobal(QCursor::pos()));
01347 
01348                     if (d->lastHoveredIndex == hoveredIndex)
01349                         return QWidget::eventFilter(watched, event);
01350 
01351                     d->lastHoveredIndex = hoveredIndex;
01352 
01353                     const QModelIndex focusedIndex = d->itemView->selectionModel() ? d->itemView->selectionModel()->currentIndex()
01354                                                                                 : QModelIndex();
01355 
01356                     if (!hoveredIndex.isValid() && focusedIndex.isValid() &&
01357                         d->itemView->selectionModel()->isSelected(focusedIndex) &&
01358                         (d->lastHoveredIndex != focusedIndex)) {
01359                         const QModelIndex sourceFocusedIndex = d->proxyModel->mapToSource(focusedIndex);
01360                         const KFileItem item = d->dirModel->itemForIndex(sourceFocusedIndex);
01361                         if (!item.isNull()) {
01362                             d->preview->showPreview(item.url());
01363                         }
01364                     }
01365                 }
01366             }
01367             break;
01368         case QEvent::MouseButtonRelease: {
01369                 if (d->preview != 0 && !d->preview->isHidden()) {
01370                     const QModelIndex hoveredIndex = d->itemView->indexAt(d->itemView->viewport()->mapFromGlobal(QCursor::pos()));
01371                     const QModelIndex focusedIndex = d->itemView->selectionModel() ? d->itemView->selectionModel()->currentIndex()
01372                                                                                 : QModelIndex();
01373 
01374                     if (((!focusedIndex.isValid()) ||
01375                         !d->itemView->selectionModel()->isSelected(focusedIndex)) &&
01376                         (!hoveredIndex.isValid())) {
01377                         d->preview->clearPreview();
01378                     }
01379                 }
01380             }
01381             break;
01382         case QEvent::Wheel: {
01383                 QWheelEvent *evt = static_cast<QWheelEvent*>(event);
01384                 if (evt->modifiers() & Qt::ControlModifier) {
01385                     if (evt->delta() > 0) {
01386                         setIconsZoom(d->iconsZoom + 10);
01387                     } else {
01388                         setIconsZoom(d->iconsZoom - 10);
01389                     }
01390                     return true;
01391                 }
01392             }
01393             break;
01394         default:
01395             break;
01396     }
01397 
01398     return QWidget::eventFilter(watched, event);
01399 }
01400 
01401 bool KDirOperator::Private::checkPreviewInternal() const
01402 {
01403     const QStringList supported = KIO::PreviewJob::supportedMimeTypes();
01404     // no preview support for directories?
01405     if (parent->dirOnlyMode() && supported.indexOf("inode/directory") == -1)
01406         return false;
01407 
01408     QStringList mimeTypes = dirLister->mimeFilters();
01409     const QStringList nameFilter = dirLister->nameFilter().split(' ', QString::SkipEmptyParts);
01410 
01411     if (mimeTypes.isEmpty() && nameFilter.isEmpty() && !supported.isEmpty())
01412         return true;
01413     else {
01414         QRegExp r;
01415         r.setPatternSyntax(QRegExp::Wildcard);   // the "mimetype" can be "image/*"
01416 
01417         if (!mimeTypes.isEmpty()) {
01418             QStringList::ConstIterator it = supported.begin();
01419 
01420             for (; it != supported.end(); ++it) {
01421                 r.setPattern(*it);
01422 
01423                 QStringList result = mimeTypes.filter(r);
01424                 if (!result.isEmpty()) {   // matches! -> we want previews
01425                     return true;
01426                 }
01427             }
01428         }
01429 
01430         if (!nameFilter.isEmpty()) {
01431             // find the mimetypes of all the filter-patterns
01432             QStringList::const_iterator it1 = nameFilter.begin();
01433             for (; it1 != nameFilter.end(); ++it1) {
01434                 if ((*it1) == "*") {
01435                     return true;
01436                 }
01437 
01438                 KMimeType::Ptr mt = KMimeType::findByPath(*it1, 0, true /*fast mode, no file contents exist*/);
01439                 if (!mt)
01440                     continue;
01441                 QString mime = mt->name();
01442 
01443                 // the "mimetypes" we get from the PreviewJob can be "image/*"
01444                 // so we need to check in wildcard mode
01445                 QStringList::ConstIterator it2 = supported.begin();
01446                 for (; it2 != supported.end(); ++it2) {
01447                     r.setPattern(*it2);
01448                     if (r.indexIn(mime) != -1) {
01449                         return true;
01450                     }
01451                 }
01452             }
01453         }
01454     }
01455 
01456     return false;
01457 }
01458 
01459 QAbstractItemView* KDirOperator::createView(QWidget* parent, KFile::FileView viewKind)
01460 {
01461     QAbstractItemView *itemView = 0;
01462     if (KFile::isDetailView(viewKind) || KFile::isTreeView(viewKind) || KFile::isDetailTreeView(viewKind)) {
01463         KDirOperatorDetailView *detailView = new KDirOperatorDetailView(parent);
01464         detailView->setViewMode(viewKind);
01465         itemView = detailView;
01466     } else {
01467         itemView = new KDirOperatorIconView(this, parent);
01468     }
01469 
01470     return itemView;
01471 }
01472 
01473 void KDirOperator::setAcceptDrops(bool b)
01474 {
01475     // TODO:
01476     //if (d->fileView)
01477     //   d->fileView->widget()->setAcceptDrops(b);
01478     QWidget::setAcceptDrops(b);
01479 }
01480 
01481 void KDirOperator::setDropOptions(int options)
01482 {
01483     d->dropOptions = options;
01484     // TODO:
01485     //if (d->fileView)
01486     //   d->fileView->setDropOptions(options);
01487 }
01488 
01489 void KDirOperator::setView(KFile::FileView viewKind)
01490 {
01491     bool preview = (KFile::isPreviewInfo(viewKind) || KFile::isPreviewContents(viewKind));
01492 
01493     if (viewKind == KFile::Default) {
01494         if (KFile::isDetailView((KFile::FileView)d->defaultView)) {
01495             viewKind = KFile::Detail;
01496         } else if (KFile::isTreeView((KFile::FileView)d->defaultView)) {
01497             viewKind = KFile::Tree;
01498         } else if (KFile::isDetailTreeView((KFile::FileView)d->defaultView)) {
01499             viewKind = KFile::DetailTree;
01500         } else {
01501             viewKind = KFile::Simple;
01502         }
01503 
01504         const KFile::FileView defaultViewKind = static_cast<KFile::FileView>(d->defaultView);
01505         preview = (KFile::isPreviewInfo(defaultViewKind) || KFile::isPreviewContents(defaultViewKind))
01506                   && d->actionCollection->action("preview")->isEnabled();
01507     }
01508 
01509     d->viewKind = static_cast<int>(viewKind);
01510     viewKind = static_cast<KFile::FileView>(d->viewKind);
01511 
01512     QAbstractItemView *newView = createView(this, viewKind);
01513     setView(newView);
01514 
01515     d->_k_togglePreview(preview);
01516 }
01517 
01518 QAbstractItemView * KDirOperator::view() const
01519 {
01520     return d->itemView;
01521 }
01522 
01523 KFile::Modes KDirOperator::mode() const
01524 {
01525     return d->mode;
01526 }
01527 
01528 void KDirOperator::setMode(KFile::Modes mode)
01529 {
01530     if (d->mode == mode)
01531         return;
01532 
01533     d->mode = mode;
01534 
01535     d->dirLister->setDirOnlyMode(dirOnlyMode());
01536 
01537     // reset the view with the different mode
01538     if (d->itemView != 0)
01539     setView(static_cast<KFile::FileView>(d->viewKind));
01540 }
01541 
01542 void KDirOperator::setView(QAbstractItemView *view)
01543 {
01544     if (view == d->itemView) {
01545         return;
01546     }
01547 
01548     // TODO: do a real timer and restart it after that
01549     d->pendingMimeTypes.clear();
01550     const bool listDir = (d->itemView == 0);
01551 
01552     if (d->mode & KFile::Files) {
01553         view->setSelectionMode(QAbstractItemView::ExtendedSelection);
01554     } else {
01555         view->setSelectionMode(QAbstractItemView::SingleSelection);
01556     }
01557 
01558     QItemSelectionModel *selectionModel = 0;
01559     if ((d->itemView != 0) && d->itemView->selectionModel()->hasSelection()) {
01560         // remember the selection of the current item view and apply this selection
01561         // to the new view later
01562         const QItemSelection selection = d->itemView->selectionModel()->selection();
01563         selectionModel = new QItemSelectionModel(d->proxyModel, this);
01564         selectionModel->select(selection, QItemSelectionModel::Select);
01565     }
01566 
01567     setFocusProxy(0);
01568     delete d->itemView;
01569     d->itemView = view;
01570     d->itemView->setModel(d->proxyModel);
01571     setFocusProxy(d->itemView);
01572 
01573     view->viewport()->installEventFilter(this);
01574 
01575     KFileItemDelegate *delegate = new KFileItemDelegate(d->itemView);
01576     d->itemView->setItemDelegate(delegate);
01577     d->itemView->viewport()->setAttribute(Qt::WA_Hover);
01578     d->itemView->setContextMenuPolicy(Qt::CustomContextMenu);
01579     d->itemView->setMouseTracking(true);
01580     //d->itemView->setDropOptions(d->dropOptions);
01581 
01582     // first push our settings to the view, then listen for changes from the view
01583     QTreeView* treeView = qobject_cast<QTreeView*>(d->itemView);
01584     if (treeView) {
01585         QHeaderView* headerView = treeView->header();
01586         headerView->setSortIndicator(d->sortColumn(), d->sortOrder());
01587         connect(headerView, SIGNAL(sortIndicatorChanged (int, Qt::SortOrder)),
01588                 this, SLOT(_k_synchronizeSortingState(int, Qt::SortOrder)));
01589     }
01590 
01591     connect(d->itemView, SIGNAL(activated(const QModelIndex&)),
01592             this, SLOT(_k_slotActivated(const QModelIndex&)));
01593     connect(d->itemView, SIGNAL(customContextMenuRequested(const QPoint&)),
01594             this, SLOT(_k_openContextMenu(const QPoint&)));
01595     connect(d->itemView, SIGNAL(entered(const QModelIndex&)),
01596             this, SLOT(_k_triggerPreview(const QModelIndex&)));
01597 
01598     updateViewActions();
01599     d->splitter->insertWidget(0, d->itemView);
01600 
01601     d->splitter->resize(size());
01602     d->itemView->show();
01603 
01604     if (listDir) {
01605         QApplication::setOverrideCursor(Qt::WaitCursor);
01606         d->openUrl(d->currUrl);
01607     }
01608 
01609     if (selectionModel != 0) {
01610         d->itemView->setSelectionModel(selectionModel);
01611         QMetaObject::invokeMethod(this, "_k_assureVisibleSelection", Qt::QueuedConnection);
01612     }
01613 
01614     connect(d->itemView->selectionModel(),
01615             SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)),
01616             this, SLOT(_k_triggerPreview(const QModelIndex&)));
01617     connect(d->itemView->selectionModel(),
01618             SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
01619             this, SLOT(_k_slotSelectionChanged()));
01620 
01621     // if we cannot cast it to a QListView, disable the "Icon Position" menu. Note that this check
01622     // needs to be done here, and not in createView, since we can be set an external view
01623     d->decorationMenu->setEnabled(qobject_cast<QListView*>(d->itemView));
01624 
01625     d->shouldFetchForItems = qobject_cast<QTreeView*>(view);
01626     if (d->shouldFetchForItems) {
01627         connect(d->dirModel, SIGNAL(expand(QModelIndex)), this, SLOT(_k_slotExpandToUrl(QModelIndex)));
01628     } else {
01629         d->itemsToBeSetAsCurrent.clear();
01630     }
01631 
01632     const bool previewForcedToTrue = d->inlinePreviewState == Private::ForcedToTrue;
01633     const bool previewShown = d->inlinePreviewState == Private::NotForced ? d->showPreviews : previewForcedToTrue;
01634     d->previewGenerator = new KFilePreviewGenerator(d->itemView);
01635     const int maxSize = KIconLoader::SizeEnormous - KIconLoader::SizeSmall;
01636     const int val = (maxSize * d->iconsZoom / 100) + KIconLoader::SizeSmall;
01637     d->itemView->setIconSize(previewForcedToTrue ? QSize(KIconLoader::SizeHuge, KIconLoader::SizeHuge) : QSize(val, val));
01638     d->previewGenerator->setPreviewShown(previewShown);
01639     d->actionCollection->action("inline preview")->setChecked(previewShown);
01640 
01641     // ensure we change everything needed
01642     d->_k_slotChangeDecorationPosition();
01643 
01644     emit viewChanged(view);
01645 
01646     const int zoom = previewForcedToTrue ? (KIconLoader::SizeHuge - KIconLoader::SizeSmall + 1) * 100 / maxSize : d->iconSizeForViewType(view);
01647 
01648     // this will make d->iconsZoom be updated, since setIconsZoom slot will be called
01649     emit currentIconSizeChanged(zoom);
01650 }
01651 
01652 void KDirOperator::setDirLister(KDirLister *lister)
01653 {
01654     if (lister == d->dirLister)   // sanity check
01655         return;
01656 
01657     delete d->dirModel;
01658     d->dirModel = 0;
01659 
01660     delete d->proxyModel;
01661     d->proxyModel = 0;
01662 
01663     //delete d->dirLister; // deleted by KDirModel already, which took ownership
01664     d->dirLister = lister;
01665 
01666     d->dirModel = new KDirModel();
01667     d->dirModel->setDirLister(d->dirLister);
01668     d->dirModel->setDropsAllowed(KDirModel::DropOnDirectory);
01669 
01670     d->shouldFetchForItems = qobject_cast<QTreeView*>(d->itemView);
01671     if (d->shouldFetchForItems) {
01672         connect(d->dirModel, SIGNAL(expand(QModelIndex)), this, SLOT(_k_slotExpandToUrl(QModelIndex)));
01673     } else {
01674         d->itemsToBeSetAsCurrent.clear();
01675     }
01676 
01677     d->proxyModel = new KDirSortFilterProxyModel(this);
01678     d->proxyModel->setSourceModel(d->dirModel);
01679 
01680     d->dirLister->setAutoUpdate(true);
01681     d->dirLister->setDelayedMimeTypes(true);
01682 
01683     QWidget* mainWidget = topLevelWidget();
01684     d->dirLister->setMainWindow(mainWidget);
01685     kDebug(kfile_area) << "mainWidget=" << mainWidget;
01686 
01687     connect(d->dirLister, SIGNAL(percent(int)),
01688             SLOT(_k_slotProgress(int)));
01689     connect(d->dirLister, SIGNAL(started(const KUrl&)), SLOT(_k_slotStarted()));
01690     connect(d->dirLister, SIGNAL(completed()), SLOT(_k_slotIOFinished()));
01691     connect(d->dirLister, SIGNAL(canceled()), SLOT(_k_slotCanceled()));
01692     connect(d->dirLister, SIGNAL(redirection(const KUrl&)),
01693             SLOT(_k_slotRedirected(const KUrl&)));
01694     connect(d->dirLister, SIGNAL(newItems(const KFileItemList&)), SLOT(_k_slotItemsChanged()));
01695     connect(d->dirLister, SIGNAL(itemsDeleted(const KFileItemList&)), SLOT(_k_slotItemsChanged()));
01696     connect(d->dirLister, SIGNAL(itemsFilteredByMime(const KFileItemList&)), SLOT(_k_slotItemsChanged()));
01697     connect(d->dirLister, SIGNAL(clear()), SLOT(_k_slotItemsChanged()));
01698 }
01699 
01700 void KDirOperator::selectDir(const KFileItem &item)
01701 {
01702     setUrl(item.targetUrl(), true);
01703 }
01704 
01705 void KDirOperator::selectFile(const KFileItem &item)
01706 {
01707     QApplication::restoreOverrideCursor();
01708 
01709     emit fileSelected(item);
01710 }
01711 
01712 void KDirOperator::highlightFile(const KFileItem &item)
01713 {
01714     if ((d->preview != 0 && !d->preview->isHidden()) && !item.isNull()) {
01715         d->preview->showPreview(item.url());
01716     }
01717 
01718     emit fileHighlighted(item);
01719 }
01720 
01721 void KDirOperator::setCurrentItem(const QString& url)
01722 {
01723     kDebug(kfile_area);
01724 
01725     KFileItem item = d->dirLister->findByUrl(url);
01726     if (d->shouldFetchForItems && item.isNull()) {
01727         d->itemsToBeSetAsCurrent << url;
01728         d->dirModel->expandToUrl(url);
01729         return;
01730     }
01731 
01732     setCurrentItem(item);
01733 }
01734 
01735 void KDirOperator::setCurrentItem(const KFileItem& item)
01736 {
01737     kDebug(kfile_area);
01738 
01739     if (!d->itemView) {
01740         return;
01741     }
01742 
01743     QItemSelectionModel *selModel = d->itemView->selectionModel();
01744     if (selModel) {
01745         selModel->clear();
01746         if (!item.isNull()) {
01747             const QModelIndex dirIndex = d->dirModel->indexForItem(item);
01748             const QModelIndex proxyIndex = d->proxyModel->mapFromSource(dirIndex);
01749             selModel->setCurrentIndex(proxyIndex, QItemSelectionModel::Select);
01750         }
01751     }
01752 }
01753 
01754 void KDirOperator::setCurrentItems(const QStringList& urls)
01755 {
01756     kDebug(kfile_area);
01757 
01758     if (!d->itemView) {
01759         return;
01760     }
01761 
01762     KFileItemList itemList;
01763     foreach (const QString &url, urls) {
01764         KFileItem item = d->dirLister->findByUrl(url);
01765         if (d->shouldFetchForItems && item.isNull()) {
01766             d->itemsToBeSetAsCurrent << url;
01767             d->dirModel->expandToUrl(url);
01768             continue;
01769         }
01770         itemList << item;
01771     }
01772 
01773     setCurrentItems(itemList);
01774 }
01775 
01776 void KDirOperator::setCurrentItems(const KFileItemList& items)
01777 {
01778     kDebug(kfile_area);
01779 
01780     if (d->itemView == 0) {
01781         return;
01782     }
01783 
01784     QItemSelectionModel *selModel = d->itemView->selectionModel();
01785     if (selModel) {
01786         selModel->clear();
01787         QModelIndex proxyIndex;
01788         foreach (const KFileItem &item, items) {
01789             if (!item.isNull()) {
01790                 const QModelIndex dirIndex = d->dirModel->indexForItem(item);
01791                 proxyIndex = d->proxyModel->mapFromSource(dirIndex);
01792                 selModel->select(proxyIndex, QItemSelectionModel::Select);
01793             }
01794         }
01795         if (proxyIndex.isValid()) {
01796             selModel->setCurrentIndex(proxyIndex, QItemSelectionModel::NoUpdate);
01797         }
01798     }
01799 }
01800 
01801 QString KDirOperator::makeCompletion(const QString& string)
01802 {
01803     if (string.isEmpty()) {
01804         d->itemView->selectionModel()->clear();
01805         return QString();
01806     }
01807 
01808     prepareCompletionObjects();
01809     return d->completion.makeCompletion(string);
01810 }
01811 
01812 QString KDirOperator::makeDirCompletion(const QString& string)
01813 {
01814     if (string.isEmpty()) {
01815         d->itemView->selectionModel()->clear();
01816         return QString();
01817     }
01818 
01819     prepareCompletionObjects();
01820     return d->dirCompletion.makeCompletion(string);
01821 }
01822 
01823 void KDirOperator::prepareCompletionObjects()
01824 {
01825     if (d->itemView == 0) {
01826         return;
01827     }
01828 
01829     if (d->completeListDirty) {   // create the list of all possible completions
01830         const KFileItemList itemList = d->dirLister->items();
01831         foreach (const KFileItem &item, itemList) {
01832             d->completion.addItem(item.name());
01833             if (item.isDir()) {
01834                 d->dirCompletion.addItem(item.name());
01835             }
01836         }
01837         d->completeListDirty = false;
01838     }
01839 }
01840 
01841 void KDirOperator::slotCompletionMatch(const QString& match)
01842 {
01843     setCurrentItem(match);
01844     emit completion(match);
01845 }
01846 
01847 void KDirOperator::setupActions()
01848 {
01849     d->actionCollection = new KActionCollection(this);
01850     d->actionCollection->setObjectName("KDirOperator::actionCollection");
01851 
01852     d->actionMenu = new KActionMenu(i18n("Menu"), this);
01853     d->actionCollection->addAction("popupMenu", d->actionMenu);
01854 
01855     QAction* upAction = d->actionCollection->addAction(KStandardAction::Up, "up", this, SLOT(cdUp()));
01856     upAction->setText(i18n("Parent Folder"));
01857 
01858     d->actionCollection->addAction(KStandardAction::Back, "back", this, SLOT(back()));
01859 
01860     d->actionCollection->addAction(KStandardAction::Forward, "forward", this, SLOT(forward()));
01861 
01862     QAction* homeAction = d->actionCollection->addAction(KStandardAction::Home, "home", this, SLOT(home()));
01863     homeAction->setText(i18n("Home Folder"));
01864 
01865     KAction* reloadAction = d->actionCollection->addAction(KStandardAction::Redisplay, "reload", this, SLOT(rereadDir()));
01866     reloadAction->setText(i18n("Reload"));
01867     reloadAction->setShortcuts(KStandardShortcut::shortcut(KStandardShortcut::Reload));
01868 
01869     KAction* mkdirAction = new KAction(i18n("New Folder..."), this);
01870     d->actionCollection->addAction("mkdir", mkdirAction);
01871     mkdirAction->setIcon(KIcon(QLatin1String("folder-new")));
01872     connect(mkdirAction, SIGNAL(triggered(bool)), this, SLOT(mkdir()));
01873 
01874     KAction* trash = new KAction(i18n("Move to Trash"), this);
01875     d->actionCollection->addAction("trash", trash);
01876     trash->setIcon(KIcon("user-trash"));
01877     trash->setShortcuts(KShortcut(Qt::Key_Delete));
01878     connect(trash, SIGNAL(triggered(bool)), SLOT(trashSelected()));
01879 
01880     KAction* action = new KAction(i18n("Delete"), this);
01881     d->actionCollection->addAction("delete", action);
01882     action->setIcon(KIcon("edit-delete"));
01883     action->setShortcuts(KShortcut(Qt::SHIFT + Qt::Key_Delete));
01884     connect(action, SIGNAL(triggered(bool)), this, SLOT(deleteSelected()));
01885 
01886     // the sort menu actions
01887     KActionMenu *sortMenu = new KActionMenu(i18n("Sorting"), this);
01888     d->actionCollection->addAction("sorting menu",  sortMenu);
01889 
01890     KToggleAction *byNameAction = new KToggleAction(i18n("By Name"), this);
01891     d->actionCollection->addAction("by name", byNameAction);
01892     connect(byNameAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortByName()));
01893 
01894     KToggleAction *bySizeAction = new KToggleAction(i18n("By Size"), this);
01895     d->actionCollection->addAction("by size", bySizeAction);
01896     connect(bySizeAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortBySize()));
01897 
01898     KToggleAction *byDateAction = new KToggleAction(i18n("By Date"), this);
01899     d->actionCollection->addAction("by date", byDateAction);
01900     connect(byDateAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortByDate()));
01901 
01902     KToggleAction *byTypeAction = new KToggleAction(i18n("By Type"), this);
01903     d->actionCollection->addAction("by type", byTypeAction);
01904     connect(byTypeAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortByType()));
01905 
01906     KToggleAction *descendingAction = new KToggleAction(i18n("Descending"), this);
01907     d->actionCollection->addAction("descending", descendingAction);
01908     connect(descendingAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortReversed(bool)));
01909 
01910     KToggleAction *dirsFirstAction = new KToggleAction(i18n("Folders First"), this);
01911     d->actionCollection->addAction("dirs first", dirsFirstAction);
01912     connect(dirsFirstAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotToggleDirsFirst()));
01913 
01914     QActionGroup* sortGroup = new QActionGroup(this);
01915     byNameAction->setActionGroup(sortGroup);
01916     bySizeAction->setActionGroup(sortGroup);
01917     byDateAction->setActionGroup(sortGroup);
01918     byTypeAction->setActionGroup(sortGroup);
01919 
01920     d->decorationMenu = new KActionMenu(i18n("Icon Position"), this);
01921     d->actionCollection->addAction("decoration menu", d->decorationMenu);
01922 
01923     d->leftAction = new KToggleAction(i18n("Next to File Name"), this);
01924     d->actionCollection->addAction("decorationAtLeft", d->leftAction);
01925     connect(d->leftAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotChangeDecorationPosition()));
01926 
01927     KToggleAction *topAction = new KToggleAction(i18n("Above File Name"), this);
01928     d->actionCollection->addAction("decorationAtTop", topAction);
01929     connect(topAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotChangeDecorationPosition()));
01930 
01931     d->decorationMenu->addAction(d->leftAction);
01932     d->decorationMenu->addAction(topAction);
01933 
01934     QActionGroup* decorationGroup = new QActionGroup(this);
01935     d->leftAction->setActionGroup(decorationGroup);
01936     topAction->setActionGroup(decorationGroup);
01937 
01938     KToggleAction *shortAction = new KToggleAction(i18n("Short View"), this);
01939     d->actionCollection->addAction("short view",  shortAction);
01940     shortAction->setIcon(KIcon(QLatin1String("view-list-icons")));
01941     connect(shortAction, SIGNAL(triggered()), SLOT(_k_slotSimpleView()));
01942 
01943     KToggleAction *detailedAction = new KToggleAction(i18n("Detailed View"), this);
01944     d->actionCollection->addAction("detailed view", detailedAction);
01945     detailedAction->setIcon(KIcon(QLatin1String("view-list-details")));
01946     connect(detailedAction, SIGNAL(triggered ()), SLOT(_k_slotDetailedView()));
01947 
01948     KToggleAction *treeAction = new KToggleAction(i18n("Tree View"), this);
01949     d->actionCollection->addAction("tree view", treeAction);
01950     treeAction->setIcon(KIcon(QLatin1String("view-list-tree")));
01951     connect(treeAction, SIGNAL(triggered ()), SLOT(_k_slotTreeView()));
01952 
01953     KToggleAction *detailedTreeAction = new KToggleAction(i18n("Detailed Tree View"), this);
01954     d->actionCollection->addAction("detailed tree view", detailedTreeAction);
01955     detailedTreeAction->setIcon(KIcon(QLatin1String("view-list-tree")));
01956     connect(detailedTreeAction, SIGNAL(triggered ()), SLOT(_k_slotDetailedTreeView()));
01957 
01958     QActionGroup* viewGroup = new QActionGroup(this);
01959     shortAction->setActionGroup(viewGroup);
01960     detailedAction->setActionGroup(viewGroup);
01961     treeAction->setActionGroup(viewGroup);
01962     detailedTreeAction->setActionGroup(viewGroup);
01963 
01964     KToggleAction *showHiddenAction = new KToggleAction(i18n("Show Hidden Files"), this);
01965     d->actionCollection->addAction("show hidden", showHiddenAction);
01966     connect(showHiddenAction, SIGNAL(toggled(bool)), SLOT(_k_slotToggleHidden(bool)));
01967 
01968     KToggleAction *previewAction = new KToggleAction(i18n("Show Aside Preview"), this);
01969     d->actionCollection->addAction("preview", previewAction);
01970     connect(previewAction, SIGNAL(toggled(bool)),
01971             SLOT(_k_togglePreview(bool)));
01972 
01973     KToggleAction *inlinePreview = new KToggleAction(KIcon("view-preview"),
01974                                                      i18n("Show Preview"), this);
01975     d->actionCollection->addAction("inline preview", inlinePreview);
01976     connect(inlinePreview, SIGNAL(toggled(bool)), SLOT(_k_toggleInlinePreviews(bool)));
01977 
01978     KAction *fileManager = new KAction(i18n("Open File Manager"), this);
01979     d->actionCollection->addAction("file manager", fileManager);
01980     fileManager->setIcon(KIcon(QLatin1String("system-file-manager")));
01981     connect(fileManager, SIGNAL(triggered()), SLOT(_k_slotOpenFileManager()));
01982 
01983     action = new KAction(i18n("Properties"), this);
01984     d->actionCollection->addAction("properties", action);
01985     action->setIcon(KIcon("document-properties"));
01986     action->setShortcut(KShortcut(Qt::ALT + Qt::Key_Return));
01987     connect(action, SIGNAL(triggered(bool)), this, SLOT(_k_slotProperties()));
01988 
01989     // the view menu actions
01990     KActionMenu* viewMenu = new KActionMenu(i18n("&View"), this);
01991     d->actionCollection->addAction("view menu", viewMenu);
01992     viewMenu->addAction(shortAction);
01993     viewMenu->addAction(detailedAction);
01994     // Comment following lines to hide the extra two modes
01995     viewMenu->addAction(treeAction);
01996     viewMenu->addAction(detailedTreeAction);
01997     // TODO: QAbstractItemView does not offer an action collection. Provide
01998     // an interface to add a custom action collection.
01999 
02000     d->newFileMenu = new KNewFileMenu(d->actionCollection, "new", this);
02001     connect(d->newFileMenu, SIGNAL(directoryCreated(KUrl)), this, SLOT(_k_slotDirectoryCreated(KUrl)));
02002 
02003     d->actionCollection->addAssociatedWidget(this);
02004     foreach (QAction* action, d->actionCollection->actions())
02005       action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
02006 }
02007 
02008 void KDirOperator::setupMenu()
02009 {
02010     setupMenu(SortActions | ViewActions | FileActions);
02011 }
02012 
02013 void KDirOperator::setupMenu(int whichActions)
02014 {
02015     // first fill the submenus (sort and view)
02016     KActionMenu *sortMenu = static_cast<KActionMenu*>(d->actionCollection->action("sorting menu"));
02017     sortMenu->menu()->clear();
02018     sortMenu->addAction(d->actionCollection->action("by name"));
02019     sortMenu->addAction(d->actionCollection->action("by size"));
02020     sortMenu->addAction(d->actionCollection->action("by date"));
02021     sortMenu->addAction(d->actionCollection->action("by type"));
02022     sortMenu->addSeparator();
02023     sortMenu->addAction(d->actionCollection->action("descending"));
02024     sortMenu->addAction(d->actionCollection->action("dirs first"));
02025 
02026     // now plug everything into the popupmenu
02027     d->actionMenu->menu()->clear();
02028     if (whichActions & NavActions) {
02029         d->actionMenu->addAction(d->actionCollection->action("up"));
02030         d->actionMenu->addAction(d->actionCollection->action("back"));
02031         d->actionMenu->addAction(d->actionCollection->action("forward"));
02032         d->actionMenu->addAction(d->actionCollection->action("home"));
02033         d->actionMenu->addSeparator();
02034     }
02035 
02036     if (whichActions & FileActions) {
02037         d->actionMenu->addAction(d->actionCollection->action("new"));
02038         if (d->currUrl.isLocalFile() && !(QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
02039             d->actionMenu->addAction(d->actionCollection->action("trash"));
02040         }
02041         KConfigGroup cg(KGlobal::config(), QLatin1String("KDE"));
02042         const bool del = !d->currUrl.isLocalFile() ||
02043                          (QApplication::keyboardModifiers() & Qt::ShiftModifier) ||
02044                          cg.readEntry("ShowDeleteCommand", false);
02045         if (del) {
02046             d->actionMenu->addAction(d->actionCollection->action("delete"));
02047         }
02048         d->actionMenu->addSeparator();
02049     }
02050 
02051     if (whichActions & SortActions) {
02052         d->actionMenu->addAction(sortMenu);
02053         if (!(whichActions & ViewActions)) {
02054             d->actionMenu->addSeparator();
02055         }
02056     }
02057 
02058     if (whichActions & ViewActions) {
02059         d->actionMenu->addAction(d->actionCollection->action("view menu"));
02060         d->actionMenu->addSeparator();
02061     }
02062 
02063     if (whichActions & FileActions) {
02064         d->actionMenu->addAction(d->actionCollection->action("file manager"));
02065         d->actionMenu->addAction(d->actionCollection->action("properties"));
02066     }
02067 }
02068 
02069 void KDirOperator::updateSortActions()
02070 {
02071     if (KFile::isSortByName(d->sorting)) {
02072         d->actionCollection->action("by name")->setChecked(true);
02073     } else if (KFile::isSortByDate(d->sorting)) {
02074         d->actionCollection->action("by date")->setChecked(true);
02075     } else if (KFile::isSortBySize(d->sorting)) {
02076         d->actionCollection->action("by size")->setChecked(true);
02077     } else if (KFile::isSortByType(d->sorting)) {
02078         d->actionCollection->action("by type")->setChecked(true);
02079     }
02080     d->actionCollection->action("descending")->setChecked(d->sorting & QDir::Reversed);
02081     d->actionCollection->action("dirs first")->setChecked(d->sorting & QDir::DirsFirst);
02082 }
02083 
02084 void KDirOperator::updateViewActions()
02085 {
02086     KFile::FileView fv = static_cast<KFile::FileView>(d->viewKind);
02087 
02088     //QAction *separateDirs = d->actionCollection->action("separate dirs");
02089     //separateDirs->setChecked(KFile::isSeparateDirs(fv) &&
02090     //                         separateDirs->isEnabled());
02091 
02092     d->actionCollection->action("short view")->setChecked(KFile::isSimpleView(fv));
02093     d->actionCollection->action("detailed view")->setChecked(KFile::isDetailView(fv));
02094     d->actionCollection->action("tree view")->setChecked(KFile::isTreeView(fv));
02095     d->actionCollection->action("detailed tree view")->setChecked(KFile::isDetailTreeView(fv));
02096 }
02097 
02098 void KDirOperator::readConfig(const KConfigGroup& configGroup)
02099 {
02100     d->defaultView = 0;
02101     QString viewStyle = configGroup.readEntry("View Style", "Simple");
02102     if (viewStyle == QLatin1String("Detail")) {
02103         d->defaultView |= KFile::Detail;
02104     } else if (viewStyle == QLatin1String("Tree")) {
02105         d->defaultView |= KFile::Tree;
02106     } else if (viewStyle == QLatin1String("DetailTree")) {
02107         d->defaultView |= KFile::DetailTree;
02108     } else {
02109         d->defaultView |= KFile::Simple;
02110     }
02111     //if (configGroup.readEntry(QLatin1String("Separate Directories"),
02112     //                          DefaultMixDirsAndFiles)) {
02113     //    d->defaultView |= KFile::SeparateDirs;
02114     //}
02115     if (configGroup.readEntry(QLatin1String("Show Preview"), false)) {
02116         d->defaultView |= KFile::PreviewContents;
02117     }
02118 
02119     d->previewWidth = configGroup.readEntry(QLatin1String("Preview Width"), 100);
02120 
02121     if (configGroup.readEntry(QLatin1String("Show hidden files"),
02122                               DefaultShowHidden)) {
02123         d->actionCollection->action("show hidden")->setChecked(true);
02124         d->dirLister->setShowingDotFiles(true);
02125     }
02126 
02127     QDir::SortFlags sorting = QDir::Name;
02128     if (configGroup.readEntry(QLatin1String("Sort directories first"),
02129                               DefaultDirsFirst)) {
02130         sorting |= QDir::DirsFirst;
02131     }
02132     QString name = QLatin1String("Name");
02133     QString sortBy = configGroup.readEntry(QLatin1String("Sort by"), name);
02134     if (sortBy == name) {
02135         sorting |= QDir::Name;
02136     } else if (sortBy == QLatin1String("Size")) {
02137         sorting |= QDir::Size;
02138     } else if (sortBy == QLatin1String("Date")) {
02139         sorting |= QDir::Time;
02140     } else if (sortBy == QLatin1String("Type")) {
02141         sorting |= QDir::Type;
02142     }
02143     if (configGroup.readEntry(QLatin1String("Sort reversed"), DefaultSortReversed)) {
02144         sorting |= QDir::Reversed;
02145     }
02146     d->updateSorting(sorting);
02147 
02148     if (d->inlinePreviewState == Private::NotForced) {
02149         d->showPreviews = configGroup.readEntry(QLatin1String("Previews"), false);
02150     }
02151     QStyleOptionViewItem::Position pos = (QStyleOptionViewItem::Position) configGroup.readEntry(QLatin1String("Decoration position"), (int) QStyleOptionViewItem::Left);
02152     setDecorationPosition(pos);
02153 }
02154 
02155 void KDirOperator::writeConfig(KConfigGroup& configGroup)
02156 {
02157     QString sortBy = QLatin1String("Name");
02158     if (KFile::isSortBySize(d->sorting)) {
02159         sortBy = QLatin1String("Size");
02160     } else if (KFile::isSortByDate(d->sorting)) {
02161         sortBy = QLatin1String("Date");
02162     } else if (KFile::isSortByType(d->sorting)) {
02163         sortBy = QLatin1String("Type");
02164     }
02165 
02166     configGroup.writeEntry(QLatin1String("Sort by"), sortBy);
02167 
02168     configGroup.writeEntry(QLatin1String("Sort reversed"),
02169                            d->actionCollection->action("descending")->isChecked());
02170 
02171     configGroup.writeEntry(QLatin1String("Sort directories first"),
02172                            d->actionCollection->action("dirs first")->isChecked());
02173 
02174     // don't save the preview when an application specific preview is in use.
02175     bool appSpecificPreview = false;
02176     if (d->preview) {
02177         KFileMetaPreview *tmp = dynamic_cast<KFileMetaPreview*>(d->preview);
02178         appSpecificPreview = (tmp == 0);
02179     }
02180 
02181     if (!appSpecificPreview) {
02182         KToggleAction *previewAction = static_cast<KToggleAction*>(d->actionCollection->action("preview"));
02183         if (previewAction->isEnabled()) {
02184             bool hasPreview = previewAction->isChecked();
02185             configGroup.writeEntry(QLatin1String("Show Preview"), hasPreview);
02186 
02187             if (hasPreview) {
02188                 // remember the width of the preview widget
02189                 QList<int> sizes = d->splitter->sizes();
02190                 Q_ASSERT(sizes.count() == 2);
02191                 configGroup.writeEntry(QLatin1String("Preview Width"), sizes[1]);
02192             }
02193         }
02194     }
02195 
02196     configGroup.writeEntry(QLatin1String("Show hidden files"),
02197                            d->actionCollection->action("show hidden")->isChecked());
02198 
02199     KFile::FileView fv = static_cast<KFile::FileView>(d->viewKind);
02200     QString style;
02201     if (KFile::isDetailView(fv))
02202         style = QLatin1String("Detail");
02203     else if (KFile::isSimpleView(fv))
02204         style = QLatin1String("Simple");
02205     else if (KFile::isTreeView(fv))
02206         style = QLatin1String("Tree");
02207     else if (KFile::isDetailTreeView(fv))
02208         style = QLatin1String("DetailTree");
02209     configGroup.writeEntry(QLatin1String("View Style"), style);
02210 
02211     if (d->inlinePreviewState == Private::NotForced) {
02212         configGroup.writeEntry(QLatin1String("Previews"), d->showPreviews);
02213     }
02214 
02215     configGroup.writeEntry(QLatin1String("Decoration position"), (int) d->decorationPosition);
02216 }
02217 
02218 void KDirOperator::resizeEvent(QResizeEvent *)
02219 {
02220     // resize the splitter and assure that the width of
02221     // the preview widget is restored
02222     QList<int> sizes = d->splitter->sizes();
02223     const bool hasPreview = (sizes.count() == 2);
02224 
02225     d->splitter->resize(size());
02226     sizes = d->splitter->sizes();
02227 
02228     const bool restorePreviewWidth = hasPreview && (d->previewWidth != sizes[1]);
02229     if (restorePreviewWidth) {
02230         const int availableWidth = sizes[0] + sizes[1];
02231         sizes[0] = availableWidth - d->previewWidth;
02232         sizes[1] = d->previewWidth;
02233         d->splitter->setSizes(sizes);
02234     }
02235     if (hasPreview) {
02236         d->previewWidth = sizes[1];
02237     }
02238 
02239     if (d->progressBar->parent() == this) {
02240         // might be reparented into a statusbar
02241         d->progressBar->move(2, height() - d->progressBar->height() - 2);
02242     }
02243 }
02244 
02245 void KDirOperator::setOnlyDoubleClickSelectsFiles(bool enable)
02246 {
02247     d->onlyDoubleClickSelectsFiles = enable;
02248     // TODO: port to Qt4's QAbstractItemModel
02249     //if (d->itemView != 0) {
02250     //    d->itemView->setOnlyDoubleClickSelectsFiles(enable);
02251     //}
02252 }
02253 
02254 bool KDirOperator::onlyDoubleClickSelectsFiles() const
02255 {
02256     return d->onlyDoubleClickSelectsFiles;
02257 }
02258 
02259 void KDirOperator::Private::_k_slotStarted()
02260 {
02261     progressBar->setValue(0);
02262     // delay showing the progressbar for one second
02263     progressDelayTimer->setSingleShot(true);
02264     progressDelayTimer->start(1000);
02265 }
02266 
02267 void KDirOperator::Private::_k_slotShowProgress()
02268 {
02269     progressBar->raise();
02270     progressBar->show();
02271     QApplication::flush();
02272 }
02273 
02274 void KDirOperator::Private::_k_slotProgress(int percent)
02275 {
02276     progressBar->setValue(percent);
02277     // we have to redraw this as fast as possible
02278     if (progressBar->isVisible())
02279         QApplication::flush();
02280 }
02281 
02282 
02283 void KDirOperator::Private::_k_slotIOFinished()
02284 {
02285     progressDelayTimer->stop();
02286     _k_slotProgress(100);
02287     progressBar->hide();
02288     emit parent->finishedLoading();
02289     parent->resetCursor();
02290 
02291     if (preview) {
02292         preview->clearPreview();
02293     }
02294 }
02295 
02296 void KDirOperator::Private::_k_slotCanceled()
02297 {
02298     emit parent->finishedLoading();
02299     parent->resetCursor();
02300 }
02301 
02302 QProgressBar * KDirOperator::progressBar() const
02303 {
02304     return d->progressBar;
02305 }
02306 
02307 void KDirOperator::clearHistory()
02308 {
02309     qDeleteAll(d->backStack);
02310     d->backStack.clear();
02311     d->actionCollection->action("back")->setEnabled(false);
02312 
02313     qDeleteAll(d->forwardStack);
02314     d->forwardStack.clear();
02315     d->actionCollection->action("forward")->setEnabled(false);
02316 }
02317 
02318 void KDirOperator::setEnableDirHighlighting(bool enable)
02319 {
02320     d->dirHighlighting = enable;
02321 }
02322 
02323 bool KDirOperator::dirHighlighting() const
02324 {
02325     return d->dirHighlighting;
02326 }
02327 
02328 bool KDirOperator::dirOnlyMode() const
02329 {
02330     return dirOnlyMode(d->mode);
02331 }
02332 
02333 bool KDirOperator::dirOnlyMode(uint mode)
02334 {
02335     return ((mode & KFile::Directory) &&
02336             (mode & (KFile::File | KFile::Files)) == 0);
02337 }
02338 
02339 void KDirOperator::Private::_k_slotProperties()
02340 {
02341     if (itemView == 0) {
02342         return;
02343     }
02344 
02345     const KFileItemList list = parent->selectedItems();
02346     if (!list.isEmpty()) {
02347         KPropertiesDialog dialog(list, parent);
02348         dialog.exec();
02349     }
02350 }
02351 
02352 void KDirOperator::Private::_k_slotActivated(const QModelIndex& index)
02353 {
02354     const QModelIndex dirIndex = proxyModel->mapToSource(index);
02355     KFileItem item = dirModel->itemForIndex(dirIndex);
02356 
02357     const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
02358     if (item.isNull() || (modifiers & Qt::ShiftModifier) || (modifiers & Qt::ControlModifier))
02359         return;
02360 
02361     if (item.isDir()) {
02362         parent->selectDir(item);
02363     } else {
02364         parent->selectFile(item);
02365     }
02366 }
02367 
02368 void KDirOperator::Private::_k_slotSelectionChanged()
02369 {
02370     if (itemView == 0) {
02371         return;
02372     }
02373 
02374     // In the multiselection mode each selection change is indicated by
02375     // emitting a null item. Also when the selection has been cleared, a
02376     // null item must be emitted.
02377     const bool multiSelectionMode = (itemView->selectionMode() == QAbstractItemView::ExtendedSelection);
02378     const bool hasSelection = itemView->selectionModel()->hasSelection();
02379     if (multiSelectionMode || !hasSelection) {
02380         KFileItem nullItem;
02381         parent->highlightFile(nullItem);
02382     }
02383     else {
02384         KFileItem selectedItem = parent->selectedItems().first();
02385         parent->highlightFile(selectedItem);
02386     }
02387 }
02388 
02389 void KDirOperator::Private::_k_openContextMenu(const QPoint& pos)
02390 {
02391     const QModelIndex proxyIndex = itemView->indexAt(pos);
02392     const QModelIndex dirIndex = proxyModel->mapToSource(proxyIndex);
02393     KFileItem item = dirModel->itemForIndex(dirIndex);
02394 
02395     if (item.isNull())
02396         return;
02397 
02398     parent->activatedMenu(item, QCursor::pos());
02399 }
02400 
02401 void KDirOperator::Private::_k_triggerPreview(const QModelIndex& index)
02402 {
02403     if ((preview != 0 && !preview->isHidden()) && index.isValid() && (index.column() == KDirModel::Name)) {
02404         const QModelIndex dirIndex = proxyModel->mapToSource(index);
02405         const KFileItem item = dirModel->itemForIndex(dirIndex);
02406 
02407         if (item.isNull())
02408             return;
02409 
02410         if (!item.isDir()) {
02411             previewUrl = item.url();
02412             _k_showPreview();
02413         } else {
02414             preview->clearPreview();
02415         }
02416     }
02417 }
02418 
02419 void KDirOperator::Private::_k_showPreview()
02420 {
02421     if (preview != 0) {
02422         preview->showPreview(previewUrl);
02423     }
02424 }
02425 
02426 void KDirOperator::Private::_k_slotSplitterMoved(int, int)
02427 {
02428     const QList<int> sizes = splitter->sizes();
02429     if (sizes.count() == 2) {
02430         // remember the width of the preview widget (see KDirOperator::resizeEvent())
02431         previewWidth = sizes[1];
02432     }
02433 }
02434 
02435 void KDirOperator::Private::_k_assureVisibleSelection()
02436 {
02437     if (itemView == 0) {
02438         return;
02439     }
02440 
02441     QItemSelectionModel* selModel = itemView->selectionModel();
02442     if (selModel->hasSelection()) {
02443         const QModelIndex index = selModel->currentIndex();
02444         itemView->scrollTo(index, QAbstractItemView::EnsureVisible);
02445         _k_triggerPreview(index);
02446     }
02447 }
02448 
02449 
02450 void KDirOperator::Private::_k_synchronizeSortingState(int logicalIndex, Qt::SortOrder order)
02451 {
02452     QDir::SortFlags newSort = sorting & ~(QDirSortMask | QDir::Reversed);
02453 
02454     switch (logicalIndex) {
02455     case KDirModel::Name:
02456         newSort |= QDir::Name;
02457         break;
02458     case KDirModel::Size:
02459         newSort |= QDir::Size;
02460         break;
02461     case KDirModel::ModifiedTime:
02462         newSort |= QDir::Time;
02463         break;
02464     case KDirModel::Type:
02465         newSort |= QDir::Type;
02466         break;
02467     default:
02468         Q_ASSERT(false);
02469     }
02470 
02471     if (order == Qt::DescendingOrder) {
02472         newSort |= QDir::Reversed;
02473     }
02474 
02475     updateSorting(newSort);
02476 
02477     QMetaObject::invokeMethod(parent, "_k_assureVisibleSelection", Qt::QueuedConnection);
02478 }
02479 
02480 void KDirOperator::Private::_k_slotChangeDecorationPosition()
02481 {
02482     if (!itemView) {
02483         return;
02484     }
02485 
02486     QListView *view = qobject_cast<QListView*>(itemView);
02487 
02488     if (!view) {
02489         return;
02490     }
02491 
02492     const bool leftChecked = actionCollection->action("decorationAtLeft")->isChecked();
02493 
02494     if (leftChecked) {
02495         decorationPosition = QStyleOptionViewItem::Left;
02496         view->setFlow(QListView::TopToBottom);
02497     } else {
02498         decorationPosition = QStyleOptionViewItem::Top;
02499         view->setFlow(QListView::LeftToRight);
02500     }
02501 
02502     updateListViewGrid();
02503 
02504     itemView->update();
02505 }
02506 
02507 void KDirOperator::Private::_k_slotExpandToUrl(const QModelIndex &index)
02508 {
02509     QTreeView *treeView = qobject_cast<QTreeView*>(itemView);
02510 
02511     if (!treeView) {
02512         return;
02513     }
02514 
02515     const KFileItem item = dirModel->itemForIndex(index);
02516 
02517     if (item.isNull()) {
02518         return;
02519     }
02520 
02521     if (!item.isDir()) {
02522         const QModelIndex proxyIndex = proxyModel->mapFromSource(index);
02523 
02524         KUrl::List::Iterator it = itemsToBeSetAsCurrent.begin();
02525         while (it != itemsToBeSetAsCurrent.end()) {
02526             const KUrl url = *it;
02527             if (url.isParentOf(item.url())) {
02528                 const KFileItem _item = dirLister->findByUrl(url);
02529                 if (_item.isDir()) {
02530                     const QModelIndex _index = dirModel->indexForItem(_item);
02531                     const QModelIndex _proxyIndex = proxyModel->mapFromSource(_index);
02532                     treeView->expand(_proxyIndex);
02533 
02534                     // if we have expanded the last parent of this item, select it
02535                     if (item.url().directory() == url.path(KUrl::RemoveTrailingSlash)) {
02536                         treeView->selectionModel()->select(proxyIndex, QItemSelectionModel::Select);
02537                     }
02538                 }
02539                 it = itemsToBeSetAsCurrent.erase(it);
02540             } else {
02541                 ++it;
02542             }
02543         }
02544     } else if (!itemsToBeSetAsCurrent.contains(item.url())) {
02545         itemsToBeSetAsCurrent << item.url();
02546     }
02547 }
02548 
02549 void KDirOperator::Private::_k_slotItemsChanged()
02550 {
02551     completeListDirty = true;
02552 }
02553 
02554 void KDirOperator::Private::updateListViewGrid()
02555 {
02556     if (!itemView) {
02557         return;
02558     }
02559 
02560     QListView *view = qobject_cast<QListView*>(itemView);
02561 
02562     if (!view) {
02563         return;
02564     }
02565 
02566     const bool leftChecked = actionCollection->action("decorationAtLeft")->isChecked();
02567 
02568     if (leftChecked) {
02569         view->setGridSize(QSize());
02570         KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate*>(view->itemDelegate());
02571         if (delegate) {
02572             delegate->setMaximumSize(QSize());
02573         }
02574     } else {
02575         const QFontMetrics metrics(itemView->viewport()->font());
02576         int size = itemView->iconSize().height() + metrics.height() * 2;
02577         // some heuristics for good looking. let's guess width = height * (3 / 2) is nice
02578         view->setGridSize(QSize(size * (3.0 / 2.0), size + metrics.height()));
02579         KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate*>(view->itemDelegate());
02580         if (delegate) {
02581             delegate->setMaximumSize(QSize(size * (3.0 / 2.0), size + metrics.height()));
02582         }
02583     }
02584 }
02585 
02586 int KDirOperator::Private::iconSizeForViewType(QAbstractItemView *itemView) const
02587 {
02588     if (!itemView || !configGroup) {
02589         return 0;
02590     }
02591 
02592     if (qobject_cast<QListView*>(itemView)) {
02593         return configGroup->readEntry("listViewIconSize", 0);
02594     } else {
02595         return configGroup->readEntry("detailedViewIconSize", 0);
02596     }
02597 }
02598 
02599 void KDirOperator::setViewConfig(KConfigGroup& configGroup)
02600 {
02601     delete d->configGroup;
02602     d->configGroup = new KConfigGroup(configGroup);
02603 }
02604 
02605 KConfigGroup* KDirOperator::viewConfigGroup() const
02606 {
02607     return d->configGroup;
02608 }
02609 
02610 void KDirOperator::setShowHiddenFiles(bool s)
02611 {
02612     d->actionCollection->action("show hidden")->setChecked(s);
02613 }
02614 
02615 bool KDirOperator::showHiddenFiles() const
02616 {
02617     return d->actionCollection->action("show hidden")->isChecked();
02618 }
02619 
02620 QStyleOptionViewItem::Position KDirOperator::decorationPosition() const
02621 {
02622     return d->decorationPosition;
02623 }
02624 
02625 void KDirOperator::setDecorationPosition(QStyleOptionViewItem::Position position)
02626 {
02627     d->decorationPosition = position;
02628     const bool decorationAtLeft = d->decorationPosition == QStyleOptionViewItem::Left;
02629     d->actionCollection->action("decorationAtLeft")->setChecked(decorationAtLeft);
02630     d->actionCollection->action("decorationAtTop")->setChecked(!decorationAtLeft);
02631 }
02632 
02633 // ### temporary code
02634 #include <dirent.h>
02635 bool KDirOperator::Private::isReadable(const KUrl& url)
02636 {
02637     if (!url.isLocalFile())
02638         return true; // what else can we say?
02639 
02640     KDE_struct_stat buf;
02641 #ifdef Q_WS_WIN
02642     QString ts = url.toLocalFile();
02643 #else
02644     QString ts = url.path(KUrl::AddTrailingSlash);
02645 #endif
02646     bool readable = (KDE::stat(ts, &buf) == 0);
02647     if (readable) { // further checks
02648         DIR *test;
02649         test = opendir(QFile::encodeName(ts));    // we do it just to test here
02650         readable = (test != 0);
02651         if (test)
02652             closedir(test);
02653     }
02654     return readable;
02655 }
02656 
02657 void KDirOperator::Private::_k_slotDirectoryCreated(const KUrl& url)
02658 {
02659     parent->setUrl(url, true);
02660 }
02661 
02662 #include "kdiroperator.moc"

KFile

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal