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