00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 <kpropertiesdialog.h>
00072 #include <kstandardshortcut.h>
00073 #include <kde_file.h>
00074 #include <kactioncollection.h>
00075 #include <ktoggleaction.h>
00076 #include <kactionmenu.h>
00077 #include <kconfiggroup.h>
00078 #include <kdeversion.h>
00079
00080
00081 template class QHash<QString, KFileItem>;
00082
00087 class KDirOperatorIconView : public QListView
00088 {
00089 public:
00090 KDirOperatorIconView(QWidget *parent = 0);
00091 virtual ~KDirOperatorIconView();
00092
00093 protected:
00094 virtual QStyleOptionViewItem viewOptions() const;
00095 virtual void dragEnterEvent(QDragEnterEvent* event);
00096 virtual void mousePressEvent(QMouseEvent *event);
00097 virtual void wheelEvent(QWheelEvent *event);
00098 };
00099
00100 KDirOperatorIconView::KDirOperatorIconView(QWidget *parent) :
00101 QListView(parent)
00102 {
00103 setViewMode(QListView::IconMode);
00104 setFlow(QListView::TopToBottom);
00105 setResizeMode(QListView::Adjust);
00106 setSpacing(KDialog::spacingHint());
00107 setMovement(QListView::Static);
00108 setDragDropMode(QListView::DragOnly);
00109 setVerticalScrollMode(QListView::ScrollPerPixel);
00110 setHorizontalScrollMode(QListView::ScrollPerPixel);
00111 setEditTriggers(QAbstractItemView::NoEditTriggers);
00112
00113 QFontMetrics metrics(viewOptions().font);
00114 const int fontHeight = metrics.height();
00115 setGridSize(QSize(fontHeight * 10, fontHeight + 4));
00116 }
00117
00118 KDirOperatorIconView::~KDirOperatorIconView()
00119 {
00120 }
00121
00122 QStyleOptionViewItem KDirOperatorIconView::viewOptions() const
00123 {
00124 QStyleOptionViewItem viewOptions = QListView::viewOptions();
00125 viewOptions.showDecorationSelected = true;
00126 viewOptions.decorationPosition = QStyleOptionViewItem::Left;
00127 viewOptions.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter;
00128 viewOptions.decorationSize = QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
00129
00130 return viewOptions;
00131 }
00132
00133 void KDirOperatorIconView::dragEnterEvent(QDragEnterEvent* event)
00134 {
00135 if (event->mimeData()->hasUrls()) {
00136 event->acceptProposedAction();
00137 }
00138 }
00139
00140 void KDirOperatorIconView::mousePressEvent(QMouseEvent *event)
00141 {
00142 if (!indexAt(event->pos()).isValid()) {
00143 const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
00144 if (!(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier)) {
00145 clearSelection();
00146 }
00147 }
00148
00149 QListView::mousePressEvent(event);
00150 }
00151
00152 void KDirOperatorIconView::wheelEvent(QWheelEvent *event)
00153 {
00154 QListView::wheelEvent(event);
00155
00156
00157
00158 if (event->orientation() == Qt::Vertical) {
00159 QWheelEvent horizEvent(event->pos(),
00160 event->delta(),
00161 event->buttons(),
00162 event->modifiers(),
00163 Qt::Horizontal);
00164 QApplication::sendEvent(horizontalScrollBar(), &horizEvent);
00165 }
00166 }
00167
00168 class KDirOperator::Private
00169 {
00170 public:
00171 Private( KDirOperator *parent );
00172 ~Private();
00173
00174
00175 bool checkPreviewInternal() const;
00176 void checkPath(const QString &txt, bool takeFiles = false);
00177 bool openUrl(const KUrl &url, KDirLister::OpenUrlFlags flags = KDirLister::NoFlags);
00178 int sortColumn() const;
00179 Qt::SortOrder sortOrder() const;
00180 void triggerSorting();
00181
00182 static bool isReadable(const KUrl &url);
00183
00184
00185 void _k_slotDetailedView();
00186 void _k_slotSimpleView();
00187 void _k_slotToggleHidden(bool);
00188 void _k_togglePreview(bool);
00189 void _k_slotSortByName();
00190 void _k_slotSortBySize();
00191 void _k_slotSortByDate();
00192 void _k_slotSortByType();
00193 void _k_slotSortReversed();
00194 void _k_slotToggleDirsFirst();
00195 void _k_slotToggleIgnoreCase();
00196 void _k_slotStarted();
00197 void _k_slotProgress(int);
00198 void _k_slotShowProgress();
00199 void _k_slotIOFinished();
00200 void _k_slotCanceled();
00201 void _k_slotRedirected(const KUrl&);
00202 void _k_slotProperties();
00203 void _k_slotPressed(const QModelIndex&);
00204 void _k_slotClicked(const QModelIndex&);
00205 void _k_slotActivated(const QModelIndex&);
00206 void _k_slotDoubleClicked(const QModelIndex&);
00207 void _k_slotSelectionChanged();
00208 void _k_openContextMenu(const QPoint&);
00209 void _k_triggerPreview(const QModelIndex&);
00210 void _k_showPreview();
00211 void _k_slotSplitterMoved(int, int);
00212 void _k_assureVisibleSelection();
00213 void _k_synchronizeSortingState(int, Qt::SortOrder);
00214
00215
00216 KDirOperator *parent;
00217 QStack<KUrl*> backStack;
00218 QStack<KUrl*> forwardStack;
00219
00220 QModelIndex lastHoveredIndex;
00221
00222 KDirLister *dirLister;
00223 KUrl currUrl;
00224
00225 KCompletion completion;
00226 KCompletion dirCompletion;
00227 bool completeListDirty;
00228 QDir::SortFlags sorting;
00229
00230 QSplitter *splitter;
00231
00232 QAbstractItemView *itemView;
00233 KDirModel *dirModel;
00234 KDirSortFilterProxyModel *proxyModel;
00235
00236 KFileItemList pendingMimeTypes;
00237
00238
00239 int viewKind;
00240 int defaultView;
00241
00242 KFile::Modes mode;
00243 QProgressBar *progressBar;
00244
00245 KPreviewWidgetBase *preview;
00246 KUrl previewUrl;
00247 int previewWidth;
00248
00249 bool leftButtonPressed;
00250 bool dirHighlighting;
00251 bool onlyDoubleClickSelectsFiles;
00252 QString lastURL;
00253 QTimer *progressDelayTimer;
00254 int dropOptions;
00255
00256 KActionMenu *actionMenu;
00257 KActionCollection *actionCollection;
00258
00259 KConfigGroup *configGroup;
00260 };
00261
00262 KDirOperator::Private::Private(KDirOperator *_parent) :
00263 parent(_parent),
00264 dirLister(0),
00265 splitter(0),
00266 itemView(0),
00267 dirModel(0),
00268 proxyModel(0),
00269 progressBar(0),
00270 preview(0),
00271 previewUrl(),
00272 previewWidth(0),
00273 leftButtonPressed(false),
00274 dirHighlighting(false),
00275 onlyDoubleClickSelectsFiles(false),
00276 progressDelayTimer(0),
00277 dropOptions(0),
00278 actionMenu(0),
00279 actionCollection(0),
00280 configGroup(0)
00281 {
00282 }
00283
00284 KDirOperator::Private::~Private()
00285 {
00286 delete itemView;
00287 itemView = 0;
00288
00289
00290
00291
00292
00293
00294 qDeleteAll(backStack);
00295 qDeleteAll(forwardStack);
00296 delete preview;
00297 preview = 0;
00298
00299 delete proxyModel;
00300 proxyModel = 0;
00301 delete dirModel;
00302 dirModel = 0;
00303 dirLister = 0;
00304 delete configGroup;
00305 configGroup = 0;
00306
00307 delete progressDelayTimer;
00308 progressDelayTimer = 0;
00309 }
00310
00311 KDirOperator::KDirOperator(const KUrl& _url, QWidget *parent) :
00312 QWidget(parent),
00313 d(new Private(this))
00314 {
00315 d->splitter = new QSplitter(this);
00316 d->splitter->setChildrenCollapsible(false);
00317 connect(d->splitter, SIGNAL(splitterMoved(int, int)),
00318 this, SLOT(_k_slotSplitterMoved(int, int)));
00319
00320 d->preview = 0;
00321
00322 d->mode = KFile::File;
00323 d->viewKind = KFile::Simple;
00324 d->sorting = QDir::Name | QDir::DirsFirst;
00325
00326 if (_url.isEmpty()) {
00327 QString strPath = QDir::currentPath();
00328 strPath.append(QChar('/'));
00329 d->currUrl = KUrl();
00330 d->currUrl.setProtocol(QLatin1String("file"));
00331 d->currUrl.setPath(strPath);
00332 } else {
00333 d->currUrl = _url;
00334 if (d->currUrl.protocol().isEmpty())
00335 d->currUrl.setProtocol(QLatin1String("file"));
00336
00337 d->currUrl.addPath("/");
00338 }
00339
00340 setDirLister(new KDirLister());
00341
00342 connect(&d->completion, SIGNAL(match(const QString&)),
00343 SLOT(slotCompletionMatch(const QString&)));
00344
00345 d->progressBar = new QProgressBar(this);
00346 d->progressBar->setObjectName("d->progressBar");
00347 d->progressBar->adjustSize();
00348 d->progressBar->move(2, height() - d->progressBar->height() - 2);
00349
00350 d->progressDelayTimer = new QTimer(this);
00351 d->progressDelayTimer->setObjectName(QLatin1String("d->progressBar delay timer"));
00352 connect(d->progressDelayTimer, SIGNAL(timeout()),
00353 SLOT(_k_slotShowProgress()));
00354
00355 d->completeListDirty = false;
00356
00357
00358 setupActions();
00359 setupMenu();
00360
00361 setFocusPolicy(Qt::WheelFocus);
00362 }
00363
00364 KDirOperator::~KDirOperator()
00365 {
00366 resetCursor();
00367 delete d;
00368 }
00369
00370
00371 void KDirOperator::setSorting(QDir::SortFlags spec)
00372 {
00373 d->sorting = spec;
00374 d->triggerSorting();
00375 updateSortActions();
00376 }
00377
00378 QDir::SortFlags KDirOperator::sorting() const
00379 {
00380 return d->sorting;
00381 }
00382
00383 bool KDirOperator::isRoot() const
00384 {
00385 return url().path() == QString(QLatin1Char('/'));
00386 }
00387
00388 KDirLister *KDirOperator::dirLister() const
00389 {
00390 return d->dirLister;
00391 }
00392
00393 void KDirOperator::resetCursor()
00394 {
00395 if (qApp)
00396 QApplication::restoreOverrideCursor();
00397 d->progressBar->hide();
00398 }
00399
00400 void KDirOperator::sortByName()
00401 {
00402 d->sorting = QDir::Name;
00403 d->actionCollection->action("by name")->setChecked(true);
00404 }
00405
00406 void KDirOperator::sortBySize()
00407 {
00408 d->sorting = (d->sorting & ~QDir::SortByMask) | QDir::Size;
00409 d->actionCollection->action("by size")->setChecked(true);
00410 }
00411
00412 void KDirOperator::sortByDate()
00413 {
00414 d->sorting = (d->sorting & ~QDir::SortByMask) | QDir::Time;
00415 d->actionCollection->action("by date")->setChecked(true);
00416 }
00417
00418 void KDirOperator::sortByType()
00419 {
00420 d->sorting = (d->sorting & ~QDir::SortByMask) | QDir::Type;
00421 d->actionCollection->action("by type")->setChecked(true);
00422 }
00423
00424 void KDirOperator::sortReversed()
00425 {
00426 if (d->sorting & QDir::Reversed) {
00427 d->sorting = d->sorting & ~QDir::Reversed;
00428 d->actionCollection->action("descending")->setChecked(false);
00429 } else {
00430 d->sorting = d->sorting | QDir::Reversed;
00431 d->actionCollection->action("descending")->setChecked(true);
00432 }
00433 }
00434
00435 void KDirOperator::toggleDirsFirst()
00436 {
00437
00438 }
00439
00440 void KDirOperator::toggleIgnoreCase()
00441 {
00442 if (d->proxyModel != 0) {
00443 Qt::CaseSensitivity cs = d->proxyModel->sortCaseSensitivity();
00444 cs = (cs == Qt::CaseSensitive) ? Qt::CaseInsensitive : Qt::CaseSensitive;
00445 d->proxyModel->setSortCaseSensitivity(cs);
00446 }
00447 }
00448
00449 void KDirOperator::updateSelectionDependentActions()
00450 {
00451 const bool hasSelection = (d->itemView != 0) &&
00452 d->itemView->selectionModel()->hasSelection();
00453 d->actionCollection->action("trash")->setEnabled(hasSelection);
00454 d->actionCollection->action("delete")->setEnabled(hasSelection);
00455 d->actionCollection->action("properties")->setEnabled(hasSelection);
00456 }
00457
00458 void KDirOperator::setPreviewWidget(KPreviewWidgetBase *w)
00459 {
00460 const bool showPreview = (w != 0);
00461 if (showPreview) {
00462 d->viewKind = (d->viewKind | KFile::PreviewContents);
00463 } else {
00464 d->viewKind = (d->viewKind & ~KFile::PreviewContents);
00465 }
00466
00467 delete d->preview;
00468 d->preview = w;
00469
00470 if (w) {
00471 d->splitter->addWidget(w);
00472 }
00473
00474 KToggleAction *previewAction = static_cast<KToggleAction*>(d->actionCollection->action("preview"));
00475 previewAction->setEnabled(showPreview);
00476 previewAction->setChecked(showPreview);
00477 setView(static_cast<KFile::FileView>(d->viewKind));
00478 }
00479
00480 KFileItemList KDirOperator::selectedItems() const
00481 {
00482 KFileItemList itemList;
00483 if (d->itemView == 0) {
00484 return itemList;
00485 }
00486
00487 const QItemSelection selection = d->proxyModel->mapSelectionToSource(d->itemView->selectionModel()->selection());
00488
00489 const QModelIndexList indexList = selection.indexes();
00490 foreach(const QModelIndex &index, indexList) {
00491 KFileItem item = d->dirModel->itemForIndex(index);
00492 if (!item.isNull()) {
00493 itemList.append(item);
00494 }
00495 }
00496
00497 return itemList;
00498 }
00499
00500 bool KDirOperator::isSelected(const KFileItem &item) const
00501 {
00502 if ((item.isNull()) || (d->itemView == 0)) {
00503 return false;
00504 }
00505
00506 const QModelIndex dirIndex = d->dirModel->indexForItem(item);
00507 const QModelIndex proxyIndex = d->proxyModel->mapFromSource(dirIndex);
00508 return d->itemView->selectionModel()->isSelected(proxyIndex);
00509 }
00510
00511 int KDirOperator::numDirs() const
00512 {
00513 return (d->dirLister == 0) ? 0 : d->dirLister->directories().count();
00514 }
00515
00516 int KDirOperator::numFiles() const
00517 {
00518 return (d->dirLister == 0) ? 0 : d->dirLister->items().count() - numDirs();
00519 }
00520
00521 KCompletion * KDirOperator::completionObject() const
00522 {
00523 return const_cast<KCompletion *>(&d->completion);
00524 }
00525
00526 KCompletion *KDirOperator::dirCompletionObject() const
00527 {
00528 return const_cast<KCompletion *>(&d->dirCompletion);
00529 }
00530
00531 KActionCollection * KDirOperator::actionCollection() const
00532 {
00533 return d->actionCollection;
00534 }
00535
00536 void KDirOperator::Private::_k_slotDetailedView()
00537 {
00538 KFile::FileView view = static_cast<KFile::FileView>((viewKind & ~KFile::Simple) | KFile::Detail);
00539 parent->setView(view);
00540 }
00541
00542 void KDirOperator::Private::_k_slotSimpleView()
00543 {
00544 KFile::FileView view = static_cast<KFile::FileView>((viewKind & ~KFile::Detail) | KFile::Simple);
00545 parent->setView(view);
00546 }
00547
00548 void KDirOperator::Private::_k_slotToggleHidden(bool show)
00549 {
00550 dirLister->setShowingDotFiles(show);
00551 parent->updateDir();
00552 _k_assureVisibleSelection();
00553 }
00554
00555 void KDirOperator::Private::_k_togglePreview(bool on)
00556 {
00557 if (on) {
00558 viewKind = viewKind | KFile::PreviewContents;
00559 if (preview == 0) {
00560 preview = new KFileMetaPreview(parent);
00561 actionCollection->action("preview")->setChecked(true);
00562 splitter->addWidget(preview);
00563 }
00564
00565 preview->show();
00566
00567 QMetaObject::invokeMethod(parent, "_k_assureVisibleSelection", Qt::QueuedConnection);
00568 if (itemView != 0) {
00569 const QModelIndex index = itemView->selectionModel()->currentIndex();
00570 if (index.isValid()) {
00571 _k_triggerPreview(index);
00572 }
00573 }
00574 } else if (preview != 0) {
00575 viewKind = viewKind & ~KFile::PreviewContents;
00576 preview->hide();
00577 }
00578 }
00579
00580 void KDirOperator::Private::_k_slotSortByName()
00581 {
00582 parent->sortByName();
00583 triggerSorting();
00584 }
00585
00586 void KDirOperator::Private::_k_slotSortBySize()
00587 {
00588 parent->sortBySize();
00589 triggerSorting();
00590 }
00591
00592 void KDirOperator::Private::_k_slotSortByDate()
00593 {
00594 parent->sortByDate();
00595 triggerSorting();
00596 }
00597
00598 void KDirOperator::Private::_k_slotSortByType()
00599 {
00600 parent->sortByType();
00601 triggerSorting();
00602 }
00603
00604 void KDirOperator::Private::_k_slotSortReversed()
00605 {
00606 parent->sortReversed();
00607 triggerSorting();
00608 }
00609
00610 void KDirOperator::Private::_k_slotToggleDirsFirst()
00611 {
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 }
00623
00624 void KDirOperator::Private::_k_slotToggleIgnoreCase()
00625 {
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 }
00637
00638 void KDirOperator::mkdir()
00639 {
00640 bool ok;
00641 QString where = url().pathOrUrl();
00642 QString name = i18n("New Folder");
00643 #ifdef Q_WS_WIN
00644 if (url().isLocalFile() && QFileInfo(url().toLocalFile() + name).exists())
00645 #else
00646 if (url().isLocalFile() && QFileInfo(url().path(KUrl::AddTrailingSlash) + name).exists())
00647 #endif
00648 name = KIO::RenameDialog::suggestName(url(), name);
00649
00650 QString folder = KInputDialog::getText(i18n("New Folder"),
00651 i18n("Create new folder in:\n%1" , where),
00652 name, &ok, this);
00653 if (ok)
00654 KDirOperator::mkdir(KIO::encodeFileName(folder), true);
00655 }
00656
00657 bool KDirOperator::mkdir(const QString& directory, bool enterDirectory)
00658 {
00659
00660
00661
00662
00663 bool writeOk = false;
00664 bool exists = false;
00665 KUrl url(d->currUrl);
00666
00667 const QStringList dirs = directory.split(QDir::separator(), QString::SkipEmptyParts);
00668 QStringList::ConstIterator it = dirs.begin();
00669
00670 for (; it != dirs.end(); ++it) {
00671 url.addPath(*it);
00672 exists = KIO::NetAccess::exists(url, KIO::NetAccess::DestinationSide, 0);
00673 writeOk = !exists && KIO::NetAccess::mkdir(url, topLevelWidget());
00674 }
00675
00676 if (exists) {
00677 KMessageBox::sorry(d->itemView, i18n("A file or folder named %1 already exists.", url.pathOrUrl()));
00678 enterDirectory = false;
00679 } else if (!writeOk) {
00680 KMessageBox::sorry(d->itemView, i18n("You do not have permission to "
00681 "create that folder."));
00682 } else if (enterDirectory) {
00683 setUrl(url, true);
00684 }
00685
00686 return writeOk;
00687 }
00688
00689 KIO::DeleteJob * KDirOperator::del(const KFileItemList& items,
00690 QWidget *parent,
00691 bool ask, bool showProgress)
00692 {
00693 if (items.isEmpty()) {
00694 KMessageBox::information(parent,
00695 i18n("You did not select a file to delete."),
00696 i18n("Nothing to Delete"));
00697 return 0L;
00698 }
00699
00700 if (parent == 0) {
00701 parent = this;
00702 }
00703
00704 KUrl::List urls;
00705 QStringList files;
00706 foreach (const KFileItem &item, items) {
00707 const KUrl url = item.url();
00708 urls.append(url);
00709 files.append(url.pathOrUrl());
00710 }
00711
00712 bool doIt = !ask;
00713 if (ask) {
00714 int ret;
00715 if (items.count() == 1) {
00716 ret = KMessageBox::warningContinueCancel(parent,
00717 i18n("<qt>Do you really want to delete\n <b>'%1'</b>?</qt>" ,
00718 files.first()),
00719 i18n("Delete File"),
00720 KStandardGuiItem::del(),
00721 KStandardGuiItem::cancel(), "AskForDelete");
00722 } else
00723 ret = KMessageBox::warningContinueCancelList(parent,
00724 i18np("Do you really want to delete this item?", "Do you really want to delete these %1 items?", items.count()),
00725 files,
00726 i18n("Delete Files"),
00727 KStandardGuiItem::del(),
00728 KStandardGuiItem::cancel(), "AskForDelete");
00729 doIt = (ret == KMessageBox::Continue);
00730 }
00731
00732 if (doIt) {
00733 KIO::JobFlags flags = showProgress ? KIO::DefaultFlags : KIO::HideProgressInfo;
00734 KIO::DeleteJob *job = KIO::del(urls, flags);
00735 job->ui()->setWindow(topLevelWidget());
00736 job->ui()->setAutoErrorHandlingEnabled(true);
00737 return job;
00738 }
00739
00740 return 0L;
00741 }
00742
00743 void KDirOperator::deleteSelected()
00744 {
00745 const KFileItemList list = selectedItems();
00746 if (!list.isEmpty()) {
00747 del(list, this);
00748 }
00749 }
00750
00751 KIO::CopyJob * KDirOperator::trash(const KFileItemList& items,
00752 QWidget *parent,
00753 bool ask, bool showProgress)
00754 {
00755 if (items.isEmpty()) {
00756 KMessageBox::information(parent,
00757 i18n("You did not select a file to trash."),
00758 i18n("Nothing to Trash"));
00759 return 0L;
00760 }
00761
00762 KUrl::List urls;
00763 QStringList files;
00764 foreach (const KFileItem &item, items) {
00765 const KUrl url = item.url();
00766 urls.append(url);
00767 files.append(url.pathOrUrl());
00768 }
00769
00770 bool doIt = !ask;
00771 if (ask) {
00772 int ret;
00773 if (items.count() == 1) {
00774 ret = KMessageBox::warningContinueCancel(parent,
00775 i18n("<qt>Do you really want to trash\n <b>'%1'</b>?</qt>" ,
00776 files.first()),
00777 i18n("Trash File"),
00778 KGuiItem(i18nc("to trash", "&Trash"), "user-trash"),
00779 KStandardGuiItem::cancel(), "AskForTrash");
00780 } else
00781 ret = KMessageBox::warningContinueCancelList(parent,
00782 i18np("translators: not called for n == 1", "Do you really want to trash these %1 items?", items.count()),
00783 files,
00784 i18n("Trash Files"),
00785 KGuiItem(i18nc("to trash", "&Trash"), "user-trash"),
00786 KStandardGuiItem::cancel(), "AskForTrash");
00787 doIt = (ret == KMessageBox::Continue);
00788 }
00789
00790 if (doIt) {
00791 KIO::JobFlags flags = showProgress ? KIO::DefaultFlags : KIO::HideProgressInfo;
00792 KIO::CopyJob *job = KIO::trash(urls, flags);
00793 job->ui()->setWindow(topLevelWidget());
00794 job->ui()->setAutoErrorHandlingEnabled(true);
00795 return job;
00796 }
00797
00798 return 0L;
00799 }
00800
00801 void KDirOperator::trashSelected()
00802 {
00803 if (d->itemView == 0) {
00804 return;
00805 }
00806
00807 if (QApplication::keyboardModifiers() & Qt::ShiftModifier) {
00808 deleteSelected();
00809 return;
00810 }
00811
00812 const KFileItemList list = selectedItems();
00813 if (!list.isEmpty()) {
00814 trash(list, this);
00815 }
00816 }
00817
00818 void KDirOperator::close()
00819 {
00820 resetCursor();
00821 d->pendingMimeTypes.clear();
00822 d->completion.clear();
00823 d->dirCompletion.clear();
00824 d->completeListDirty = true;
00825 d->dirLister->stop();
00826 }
00827
00828 void KDirOperator::Private::checkPath(const QString &, bool )
00829 {
00830 #if 0
00831
00832 QString text = _txt;
00833
00834
00835 text = text.trimmed();
00836
00837
00838 if (text.find(':') < 0 && text[0] != '/')
00839 text.insert(0, d->currUrl);
00840
00841
00842
00843 if (!selection.isNull()) {
00844 int position = text.lastIndexOf('/');
00845 ASSERT(position >= 0);
00846 QString filename = text.mid(position + 1, text.length());
00847 if (filename != selection)
00848 selection = QString();
00849 }
00850
00851 KUrl u(text);
00852 bool filenameEntered = false;
00853
00854 if (u.isLocalFile()) {
00855
00856 KFileItem i("", u.toLocalFile());
00857 if (i.isDir())
00858 setUrl(text, true);
00859 else {
00860 if (takeFiles)
00861 if (acceptOnlyExisting && !i.isFile())
00862 warning("you entered an invalid URL");
00863 else
00864 filenameEntered = true;
00865 }
00866 } else
00867 setUrl(text, true);
00868
00869 if (filenameEntered) {
00870 filename_ = u.url();
00871 emit fileSelected(filename_);
00872
00873 QApplication::restoreOverrideCursor();
00874
00875 accept();
00876 }
00877 #endif
00878 kDebug(kfile_area) << "TODO KDirOperator::checkPath()";
00879 }
00880
00881 void KDirOperator::setUrl(const KUrl& _newurl, bool clearforward)
00882 {
00883 KUrl newurl;
00884
00885 if (!_newurl.isValid())
00886 newurl.setPath(QDir::homePath());
00887 else
00888 newurl = _newurl;
00889
00890 newurl.adjustPath( KUrl::AddTrailingSlash );
00891 #ifdef Q_WS_WIN
00892 QString pathstr = newurl.toLocalFile();
00893 #else
00894 QString pathstr = newurl.path();
00895 #endif
00896 newurl.setPath(pathstr);
00897
00898
00899 if (newurl.equals(d->currUrl, KUrl::CompareWithoutTrailingSlash))
00900 return;
00901
00902 if (!Private::isReadable(newurl)) {
00903
00904 newurl.cd(QLatin1String(".."));
00905 KIO::UDSEntry entry;
00906 bool res = KIO::NetAccess::stat(newurl, entry, this);
00907 KFileItem i(entry, newurl);
00908 if ((!res || !Private::isReadable(newurl)) && i.isDir()) {
00909 resetCursor();
00910 KMessageBox::error(d->itemView,
00911 i18n("The specified folder does not exist "
00912 "or was not readable."));
00913 return;
00914 } else if (!i.isDir()) {
00915 return;
00916 }
00917 }
00918
00919 if (clearforward) {
00920
00921 d->backStack.push(new KUrl(d->currUrl));
00922 qDeleteAll(d->forwardStack);
00923 d->forwardStack.clear();
00924 }
00925
00926 d->lastURL = d->currUrl.url(KUrl::RemoveTrailingSlash);
00927 d->currUrl = newurl;
00928
00929 pathChanged();
00930 emit urlEntered(newurl);
00931
00932
00933 QAction* forwardAction = d->actionCollection->action("forward");
00934 forwardAction->setEnabled(!d->forwardStack.isEmpty());
00935
00936 QAction* backAction = d->actionCollection->action("back");
00937 backAction->setEnabled(!d->backStack.isEmpty());
00938
00939 QAction* upAction = d->actionCollection->action("up");
00940 upAction->setEnabled(!isRoot());
00941
00942 d->openUrl(newurl);
00943 }
00944
00945 void KDirOperator::updateDir()
00946 {
00947 d->dirLister->emitChanges();
00948 }
00949
00950 void KDirOperator::rereadDir()
00951 {
00952 pathChanged();
00953 d->openUrl(d->currUrl, KDirLister::Reload);
00954 }
00955
00956
00957 bool KDirOperator::Private::openUrl(const KUrl& url, KDirLister::OpenUrlFlags flags)
00958 {
00959 bool result = dirLister->openUrl(url, flags);
00960 if (!result)
00961 _k_slotCanceled();
00962
00963 return result;
00964 }
00965
00966 int KDirOperator::Private::sortColumn() const
00967 {
00968 int column = KDirModel::Name;
00969 if (KFile::isSortByDate(sorting)) {
00970 column = KDirModel::ModifiedTime;
00971 } else if (KFile::isSortBySize(sorting)) {
00972 column = KDirModel::Size;
00973 } else if (KFile::isSortByType(sorting)) {
00974 column = KDirModel::Type;
00975 } else {
00976 Q_ASSERT(KFile::isSortByName(sorting));
00977 }
00978
00979 return column;
00980 }
00981
00982 Qt::SortOrder KDirOperator::Private::sortOrder() const
00983 {
00984 return (sorting & QDir::Reversed) ? Qt::DescendingOrder :
00985 Qt::AscendingOrder;
00986 }
00987
00988 void KDirOperator::Private::triggerSorting()
00989 {
00990 proxyModel->sort(sortColumn(), sortOrder());
00991
00992
00993
00994
00995
00996
00997
00998 QTreeView* treeView = qobject_cast<QTreeView*>(itemView);
00999 if (treeView != 0) {
01000 QHeaderView* headerView = treeView->header();
01001 headerView->blockSignals(true);
01002 headerView->setSortIndicator(sortColumn(), sortOrder());
01003 headerView->blockSignals(false);
01004 }
01005
01006 _k_assureVisibleSelection();
01007 }
01008
01009
01010 void KDirOperator::pathChanged()
01011 {
01012 if (d->itemView == 0)
01013 return;
01014
01015 d->pendingMimeTypes.clear();
01016
01017 d->completion.clear();
01018 d->dirCompletion.clear();
01019
01020
01021 QApplication::restoreOverrideCursor();
01022
01023
01024 QApplication::setOverrideCursor(Qt::WaitCursor);
01025
01026 if (!Private::isReadable(d->currUrl)) {
01027 KMessageBox::error(d->itemView,
01028 i18n("The specified folder does not exist "
01029 "or was not readable."));
01030 if (d->backStack.isEmpty())
01031 home();
01032 else
01033 back();
01034 }
01035 }
01036
01037 void KDirOperator::Private::_k_slotRedirected(const KUrl& newURL)
01038 {
01039 currUrl = newURL;
01040 pendingMimeTypes.clear();
01041 completion.clear();
01042 dirCompletion.clear();
01043 completeListDirty = true;
01044 emit parent->urlEntered(newURL);
01045 }
01046
01047
01048 void KDirOperator::back()
01049 {
01050 if (d->backStack.isEmpty())
01051 return;
01052
01053 d->forwardStack.push(new KUrl(d->currUrl));
01054
01055 KUrl *s = d->backStack.pop();
01056
01057 setUrl(*s, false);
01058 delete s;
01059 }
01060
01061
01062 void KDirOperator::forward()
01063 {
01064 if (d->forwardStack.isEmpty())
01065 return;
01066
01067 d->backStack.push(new KUrl(d->currUrl));
01068
01069 KUrl *s = d->forwardStack.pop();
01070 setUrl(*s, false);
01071 delete s;
01072 }
01073
01074 KUrl KDirOperator::url() const
01075 {
01076 return d->currUrl;
01077 }
01078
01079 void KDirOperator::cdUp()
01080 {
01081 KUrl tmp(d->currUrl);
01082 tmp.cd(QLatin1String(".."));
01083 setUrl(tmp, true);
01084 }
01085
01086 void KDirOperator::home()
01087 {
01088 KUrl u;
01089 u.setPath(QDir::homePath());
01090 setUrl(u, true);
01091 }
01092
01093 void KDirOperator::clearFilter()
01094 {
01095 d->dirLister->setNameFilter(QString());
01096 d->dirLister->clearMimeFilter();
01097 checkPreviewSupport();
01098 }
01099
01100 void KDirOperator::setNameFilter(const QString& filter)
01101 {
01102 d->dirLister->setNameFilter(filter);
01103 checkPreviewSupport();
01104 }
01105
01106 QString KDirOperator::nameFilter() const
01107 {
01108 return d->dirLister->nameFilter();
01109 }
01110
01111 void KDirOperator::setMimeFilter(const QStringList& mimetypes)
01112 {
01113 d->dirLister->setMimeFilter(mimetypes);
01114 checkPreviewSupport();
01115 }
01116
01117 QStringList KDirOperator::mimeFilter() const
01118 {
01119 return d->dirLister->mimeFilters();
01120 }
01121
01122 bool KDirOperator::checkPreviewSupport()
01123 {
01124 KToggleAction *previewAction = static_cast<KToggleAction*>(d->actionCollection->action("preview"));
01125
01126 bool hasPreviewSupport = false;
01127 KConfigGroup cg(KGlobal::config(), ConfigGroup);
01128 if (cg.readEntry("Show Default Preview", true))
01129 hasPreviewSupport = d->checkPreviewInternal();
01130
01131 previewAction->setEnabled(hasPreviewSupport);
01132 return hasPreviewSupport;
01133 }
01134
01135 void KDirOperator::activatedMenu(const KFileItem &item, const QPoint &pos)
01136 {
01137 Q_UNUSED(item);
01138 setupMenu();
01139 updateSelectionDependentActions();
01140
01141 d->actionMenu->menu()->exec(pos);
01142 }
01143
01144 void KDirOperator::changeEvent(QEvent *event)
01145 {
01146 QWidget::changeEvent(event);
01147
01148 if (event->type() == QEvent::FontChange) {
01149
01150 KDirOperatorIconView *iconView = dynamic_cast<KDirOperatorIconView*>(d->itemView);
01151
01152 if (!iconView) {
01153 return;
01154 }
01155
01156 QFontMetrics metrics(font());
01157 const int fontHeight = metrics.height();
01158 iconView->setGridSize(QSize(fontHeight * 10, fontHeight + 4));
01159 }
01160 }
01161
01162 bool KDirOperator::eventFilter(QObject *watched, QEvent *event)
01163 {
01164 Q_UNUSED(watched);
01165
01166
01167
01168 if ((event->type() == QEvent::MouseMove) && (d->preview != 0)) {
01169 const QModelIndex hoveredIndex = d->itemView->indexAt(d->itemView->viewport()->mapFromGlobal(QCursor::pos()));
01170
01171 if (d->lastHoveredIndex == hoveredIndex)
01172 return false;
01173
01174 d->lastHoveredIndex = hoveredIndex;
01175
01176 const QModelIndex focusedIndex = d->itemView->selectionModel() ? d->itemView->selectionModel()->currentIndex()
01177 : QModelIndex();
01178
01179 if (!hoveredIndex.isValid() && focusedIndex.isValid() &&
01180 d->itemView->selectionModel()->isSelected(focusedIndex) &&
01181 (d->lastHoveredIndex != focusedIndex)) {
01182 const QModelIndex sourceFocusedIndex = d->proxyModel->mapToSource(focusedIndex);
01183 const KFileItem item = d->dirModel->itemForIndex(sourceFocusedIndex);
01184 if (!item.isNull()) {
01185 d->preview->showPreview(item.url());
01186 }
01187 }
01188 }
01189 else if ((event->type() == QEvent::MouseButtonRelease) && (d->preview != 0)) {
01190 const QModelIndex hoveredIndex = d->itemView->indexAt(d->itemView->viewport()->mapFromGlobal(QCursor::pos()));
01191 const QModelIndex focusedIndex = d->itemView->selectionModel() ? d->itemView->selectionModel()->currentIndex()
01192 : QModelIndex();
01193
01194 if (((!focusedIndex.isValid()) ||
01195 !d->itemView->selectionModel()->isSelected(focusedIndex)) &&
01196 (!hoveredIndex.isValid())) {
01197 d->preview->clearPreview();
01198 }
01199 }
01200
01201 return false;
01202 }
01203
01204 bool KDirOperator::Private::checkPreviewInternal() const
01205 {
01206 const QStringList supported = KIO::PreviewJob::supportedMimeTypes();
01207
01208 if (parent->dirOnlyMode() && supported.indexOf("inode/directory") == -1)
01209 return false;
01210
01211 QStringList mimeTypes = dirLister->mimeFilters();
01212 const QStringList nameFilter = dirLister->nameFilter().split(" ", QString::SkipEmptyParts);
01213
01214 if (mimeTypes.isEmpty() && nameFilter.isEmpty() && !supported.isEmpty())
01215 return true;
01216 else {
01217 QRegExp r;
01218 r.setPatternSyntax(QRegExp::Wildcard);
01219
01220 if (!mimeTypes.isEmpty()) {
01221 QStringList::ConstIterator it = supported.begin();
01222
01223 for (; it != supported.end(); ++it) {
01224 r.setPattern(*it);
01225
01226 QStringList result = mimeTypes.filter(r);
01227 if (!result.isEmpty()) {
01228 return true;
01229 }
01230 }
01231 }
01232
01233 if (!nameFilter.isEmpty()) {
01234
01235 QStringList::const_iterator it1 = nameFilter.begin();
01236 for (; it1 != nameFilter.end(); ++it1) {
01237 if ((*it1) == "*") {
01238 return true;
01239 }
01240
01241 KMimeType::Ptr mt = KMimeType::findByPath(*it1, 0, true );
01242 if (!mt)
01243 continue;
01244 QString mime = mt->name();
01245
01246
01247
01248 QStringList::ConstIterator it2 = supported.begin();
01249 for (; it2 != supported.end(); ++it2) {
01250 r.setPattern(*it2);
01251 if (r.indexIn(mime) != -1) {
01252 return true;
01253 }
01254 }
01255 }
01256 }
01257 }
01258
01259 return false;
01260 }
01261
01262 QAbstractItemView* KDirOperator::createView(QWidget* parent, KFile::FileView viewKind)
01263 {
01264 QAbstractItemView *itemView = 0;
01265 if (KFile::isDetailView(viewKind)) {
01266 KDirOperatorDetailView *detailView = new KDirOperatorDetailView(parent);
01267 connect(detailView->header(), SIGNAL(sortIndicatorChanged (int, Qt::SortOrder)),
01268 this, SLOT(_k_synchronizeSortingState(int, Qt::SortOrder)));
01269 itemView = detailView;
01270 } else {
01271 itemView = new KDirOperatorIconView(parent);
01272 }
01273
01274 return itemView;
01275 }
01276
01277 void KDirOperator::setAcceptDrops(bool b)
01278 {
01279
01280
01281
01282 QWidget::setAcceptDrops(b);
01283 }
01284
01285 void KDirOperator::setDropOptions(int options)
01286 {
01287 d->dropOptions = options;
01288
01289
01290
01291 }
01292
01293 void KDirOperator::setView(KFile::FileView viewKind)
01294 {
01295 bool preview = (KFile::isPreviewInfo(viewKind) || KFile::isPreviewContents(viewKind));
01296
01297 if (viewKind == KFile::Default) {
01298 if (KFile::isDetailView((KFile::FileView)d->defaultView)) {
01299 viewKind = KFile::Detail;
01300 } else {
01301 viewKind = KFile::Simple;
01302 }
01303
01304 const KFile::FileView defaultViewKind = static_cast<KFile::FileView>(d->defaultView);
01305 preview = (KFile::isPreviewInfo(defaultViewKind) || KFile::isPreviewContents(defaultViewKind))
01306 && d->actionCollection->action("preview")->isEnabled();
01307 }
01308
01309 d->viewKind = static_cast<int>(viewKind);
01310 viewKind = static_cast<KFile::FileView>(d->viewKind);
01311
01312 QAbstractItemView *newView = createView(this, viewKind);
01313 setView(newView);
01314
01315 d->_k_togglePreview(preview);
01316 }
01317
01318 QAbstractItemView * KDirOperator::view() const
01319 {
01320 return d->itemView;
01321 }
01322
01323 KFile::Modes KDirOperator::mode() const
01324 {
01325 return d->mode;
01326 }
01327
01328 void KDirOperator::setMode(KFile::Modes mode)
01329 {
01330 if (d->mode == mode)
01331 return;
01332
01333 d->mode = mode;
01334
01335 d->dirLister->setDirOnlyMode(dirOnlyMode());
01336
01337
01338 setView(static_cast<KFile::FileView>(d->viewKind));
01339 }
01340
01341 void KDirOperator::setView(QAbstractItemView *view)
01342 {
01343 if (view == d->itemView) {
01344 return;
01345 }
01346
01347
01348 d->pendingMimeTypes.clear();
01349 const bool listDir = (d->itemView == 0);
01350
01351 if (d->mode & KFile::Files) {
01352 view->setSelectionMode(QAbstractItemView::ExtendedSelection);
01353 } else {
01354 view->setSelectionMode(QAbstractItemView::SingleSelection);
01355 }
01356
01357 QItemSelectionModel *selectionModel = 0;
01358 if ((d->itemView != 0) && d->itemView->selectionModel()->hasSelection()) {
01359
01360
01361 const QItemSelection selection = d->itemView->selectionModel()->selection();
01362 selectionModel = new QItemSelectionModel(d->proxyModel, this);
01363 selectionModel->select(selection, QItemSelectionModel::Select);
01364 }
01365
01366 delete d->itemView;
01367 d->itemView = view;
01368 d->itemView->setModel(d->proxyModel);
01369
01370 view->viewport()->installEventFilter(this);
01371
01372 KFileItemDelegate *delegate = new KFileItemDelegate(d->itemView);
01373 d->itemView->setItemDelegate(delegate);
01374 d->itemView->viewport()->setAttribute(Qt::WA_Hover);
01375 d->itemView->setContextMenuPolicy(Qt::CustomContextMenu);
01376 d->itemView->setMouseTracking(true);
01377
01378
01379 connect(d->itemView, SIGNAL(activated(const QModelIndex&)),
01380 this, SLOT(_k_slotActivated(const QModelIndex&)));
01381 connect(d->itemView, SIGNAL(pressed(const QModelIndex&)),
01382 this, SLOT(_k_slotPressed(const QModelIndex&)));
01383 connect(d->itemView, SIGNAL(clicked(const QModelIndex&)),
01384 this, SLOT(_k_slotClicked(const QModelIndex&)));
01385 connect(d->itemView, SIGNAL(doubleClicked(const QModelIndex&)),
01386 this, SLOT(_k_slotDoubleClicked(const QModelIndex&)));
01387 connect(d->itemView, SIGNAL(customContextMenuRequested(const QPoint&)),
01388 this, SLOT(_k_openContextMenu(const QPoint&)));
01389 connect(d->itemView, SIGNAL(entered(const QModelIndex&)),
01390 this, SLOT(_k_triggerPreview(const QModelIndex&)));
01391
01392 const bool descending = d->actionCollection->action("descending")->isChecked();
01393 if (!descending && d->sorting & QDir::Reversed) {
01394 d->sorting = d->sorting & ~QDir::Reversed;
01395 } else if (descending && !(d->sorting & QDir::Reversed)) {
01396 d->sorting = d->sorting | QDir::Reversed;
01397 }
01398 d->triggerSorting();
01399
01400 updateViewActions();
01401 d->splitter->insertWidget(0, d->itemView);
01402
01403 d->splitter->resize(size());
01404 d->itemView->show();
01405
01406 if (listDir) {
01407 QApplication::setOverrideCursor(Qt::WaitCursor);
01408 d->openUrl(d->currUrl);
01409 }
01410
01411 if (selectionModel != 0) {
01412 d->itemView->setSelectionModel(selectionModel);
01413 QMetaObject::invokeMethod(this, "_k_assureVisibleSelection", Qt::QueuedConnection);
01414 }
01415 connect(d->itemView->selectionModel(),
01416 SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)),
01417 this, SLOT(_k_triggerPreview(const QModelIndex&)));
01418 connect(d->itemView->selectionModel(),
01419 SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
01420 this, SLOT(_k_slotSelectionChanged()));
01421
01422 emit viewChanged(view);
01423 }
01424
01425 void KDirOperator::setDirLister(KDirLister *lister)
01426 {
01427 if (lister == d->dirLister)
01428 return;
01429
01430 delete d->dirModel;
01431 d->dirModel = 0;
01432
01433 delete d->proxyModel;
01434 d->proxyModel = 0;
01435
01436
01437 d->dirLister = lister;
01438
01439 d->dirModel = new KDirModel();
01440 d->dirModel->setDirLister(d->dirLister);
01441 d->dirModel->setDropsAllowed(KDirModel::DropOnDirectory);
01442
01443 d->proxyModel = new KDirSortFilterProxyModel(this);
01444 d->proxyModel->setSourceModel(d->dirModel);
01445
01446 d->dirLister->setAutoUpdate(true);
01447 d->dirLister->setDelayedMimeTypes(true);
01448
01449 QWidget* mainWidget = topLevelWidget();
01450 d->dirLister->setMainWindow(mainWidget);
01451 kDebug(kfile_area) << "mainWidget=" << mainWidget;
01452
01453 connect(d->dirLister, SIGNAL(percent(int)),
01454 SLOT(_k_slotProgress(int)));
01455 connect(d->dirLister, SIGNAL(started(const KUrl&)), SLOT(_k_slotStarted()));
01456 connect(d->dirLister, SIGNAL(completed()), SLOT(_k_slotIOFinished()));
01457 connect(d->dirLister, SIGNAL(canceled()), SLOT(_k_slotCanceled()));
01458 connect(d->dirLister, SIGNAL(redirection(const KUrl&)),
01459 SLOT(_k_slotRedirected(const KUrl&)));
01460 }
01461
01462 void KDirOperator::selectDir(const KFileItem &item)
01463 {
01464 setUrl(item.targetUrl(), true);
01465 }
01466
01467 void KDirOperator::selectFile(const KFileItem &item)
01468 {
01469 QApplication::restoreOverrideCursor();
01470
01471 emit fileSelected(item);
01472 }
01473
01474 void KDirOperator::highlightFile(const KFileItem &item)
01475 {
01476 if ((d->preview != 0) && !item.isNull()) {
01477 d->preview->showPreview(item.url());
01478 }
01479
01480 emit fileHighlighted(item);
01481 }
01482
01483 void KDirOperator::setCurrentItem(const QString& filename)
01484 {
01485 KFileItem item;
01486 if ( !filename.isNull() ) {
01487 item = d->dirLister->findByName(filename);
01488 }
01489 setCurrentItem(item);
01490 }
01491
01492 void KDirOperator::setCurrentItem(const KFileItem& item)
01493 {
01494 if (d->itemView == 0) {
01495 return;
01496 }
01497
01498 QItemSelectionModel *selModel = d->itemView->selectionModel();
01499 if (selModel) {
01500 selModel->clear();
01501 if (!item.isNull()) {
01502 const QModelIndex dirIndex = d->dirModel->indexForItem(item);
01503 const QModelIndex proxyIndex = d->proxyModel->mapFromSource(dirIndex);
01504 selModel->setCurrentIndex(proxyIndex, QItemSelectionModel::SelectCurrent);
01505 QMetaObject::invokeMethod(this, "_k_assureVisibleSelection", Qt::QueuedConnection);
01506 }
01507 }
01508 }
01509
01510 QString KDirOperator::makeCompletion(const QString& string)
01511 {
01512 if (string.isEmpty()) {
01513 d->itemView->selectionModel()->clear();
01514 return QString();
01515 }
01516
01517 prepareCompletionObjects();
01518 return d->completion.makeCompletion(string);
01519 }
01520
01521 QString KDirOperator::makeDirCompletion(const QString& string)
01522 {
01523 if (string.isEmpty()) {
01524 d->itemView->selectionModel()->clear();
01525 return QString();
01526 }
01527
01528 prepareCompletionObjects();
01529 return d->dirCompletion.makeCompletion(string);
01530 }
01531
01532 void KDirOperator::prepareCompletionObjects()
01533 {
01534 if (d->itemView == 0) {
01535 return;
01536 }
01537
01538 if (d->completeListDirty) {
01539 const KFileItemList itemList = d->dirLister->items();
01540 foreach (const KFileItem &item, itemList) {
01541 d->completion.addItem(item.name());
01542 if (item.isDir()) {
01543 d->dirCompletion.addItem(item.name());
01544 }
01545 }
01546 d->completeListDirty = false;
01547 }
01548 }
01549
01550 void KDirOperator::slotCompletionMatch(const QString& match)
01551 {
01552 setCurrentItem(match);
01553 emit completion(match);
01554 }
01555
01556 void KDirOperator::setupActions()
01557 {
01558 d->actionCollection = new KActionCollection(this);
01559 d->actionCollection->setObjectName("KDirOperator::actionCollection");
01560
01561 d->actionMenu = new KActionMenu(i18n("Menu"), this);
01562 d->actionCollection->addAction("popupMenu", d->actionMenu);
01563
01564 QAction* upAction = d->actionCollection->addAction(KStandardAction::Up, "up", this, SLOT(cdUp()));
01565 upAction->setText(i18n("Parent Folder"));
01566
01567 d->actionCollection->addAction(KStandardAction::Back, "back", this, SLOT(back()));
01568
01569 d->actionCollection->addAction(KStandardAction::Forward, "forward", this, SLOT(forward()));
01570
01571 QAction* homeAction = d->actionCollection->addAction(KStandardAction::Home, "home", this, SLOT(home()));
01572 homeAction->setText(i18n("Home Folder"));
01573
01574 KAction* reloadAction = d->actionCollection->addAction(KStandardAction::Redisplay, "reload", this, SLOT(rereadDir()));
01575 reloadAction->setText(i18n("Reload"));
01576 reloadAction->setShortcuts(KStandardShortcut::shortcut(KStandardShortcut::Reload));
01577
01578 KAction* mkdirAction = new KAction(i18n("New Folder..."), this);
01579 d->actionCollection->addAction("mkdir", mkdirAction);
01580 mkdirAction->setIcon(KIcon(QLatin1String("folder-new")));
01581 connect(mkdirAction, SIGNAL(triggered(bool)), this, SLOT(mkdir()));
01582
01583 KAction* trash = new KAction(i18n("Move to Trash"), this);
01584 d->actionCollection->addAction("trash", trash);
01585 trash->setIcon(KIcon("user-trash"));
01586 trash->setShortcuts(KShortcut(Qt::Key_Delete));
01587 connect(trash, SIGNAL(triggered(bool)), SLOT(trashSelected()));
01588
01589 KAction* action = new KAction(i18n("Delete"), this);
01590 d->actionCollection->addAction("delete", action);
01591 action->setIcon(KIcon("edit-delete"));
01592 action->setShortcuts(KShortcut(Qt::SHIFT + Qt::Key_Delete));
01593 connect(action, SIGNAL(triggered(bool)), this, SLOT(deleteSelected()));
01594
01595
01596 KActionMenu *sortMenu = new KActionMenu(i18n("Sorting"), this);
01597 d->actionCollection->addAction("sorting menu", sortMenu);
01598
01599 KToggleAction *byNameAction = new KToggleAction(i18n("By Name"), this);
01600 d->actionCollection->addAction("by name", byNameAction);
01601 connect(byNameAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortByName()));
01602
01603 KToggleAction *bySizeAction = new KToggleAction(i18n("By Size"), this);
01604 d->actionCollection->addAction("by size", bySizeAction);
01605 connect(bySizeAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortBySize()));
01606
01607 KToggleAction *byDateAction = new KToggleAction(i18n("By Date"), this);
01608 d->actionCollection->addAction("by date", byDateAction);
01609 connect(byDateAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortByDate()));
01610
01611 KToggleAction *byTypeAction = new KToggleAction(i18n("By Type"), this);
01612 d->actionCollection->addAction("by type", byTypeAction);
01613 connect(byTypeAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortByType()));
01614
01615 KToggleAction *descendingAction = new KToggleAction(i18n("Descending"), this);
01616 d->actionCollection->addAction("descending", descendingAction);
01617 connect(descendingAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortReversed()));
01618
01619 QActionGroup* sortGroup = new QActionGroup(this);
01620 byNameAction->setActionGroup(sortGroup);
01621 bySizeAction->setActionGroup(sortGroup);
01622 byDateAction->setActionGroup(sortGroup);
01623 byTypeAction->setActionGroup(sortGroup);
01624
01625 KToggleAction *shortAction = new KToggleAction(i18n("Short View"), this);
01626 d->actionCollection->addAction("short view", shortAction);
01627 shortAction->setIcon(KIcon(QLatin1String("view-list-icons")));
01628 connect(shortAction, SIGNAL(triggered()), SLOT(_k_slotSimpleView()));
01629
01630 KToggleAction *detailedAction = new KToggleAction(i18n("Detailed View"), this);
01631 d->actionCollection->addAction("detailed view", detailedAction);
01632 detailedAction->setIcon(KIcon(QLatin1String("view-list-details")));
01633 connect(detailedAction, SIGNAL(triggered ()), SLOT(_k_slotDetailedView()));
01634
01635 QActionGroup* viewGroup = new QActionGroup(this);
01636 shortAction->setActionGroup(viewGroup);
01637 detailedAction->setActionGroup(viewGroup);
01638
01639 KToggleAction *showHiddenAction = new KToggleAction(i18n("Show Hidden Files"), this);
01640 d->actionCollection->addAction("show hidden", showHiddenAction);
01641 connect(showHiddenAction, SIGNAL(toggled(bool)), SLOT(_k_slotToggleHidden(bool)));
01642
01643 KToggleAction *previewAction = new KToggleAction(i18n("Show Preview"), this);
01644 d->actionCollection->addAction("preview", previewAction);
01645 previewAction->setIcon(KIcon("view-preview"));
01646 connect(previewAction, SIGNAL(toggled(bool)),
01647 SLOT(_k_togglePreview(bool)));
01648
01649 action = new KAction(i18n("Properties"), this);
01650 d->actionCollection->addAction("properties", action);
01651 action->setIcon(KIcon("document-properties"));
01652 action->setShortcut(KShortcut(Qt::ALT + Qt::Key_Return));
01653 connect(action, SIGNAL(triggered(bool)), this, SLOT(_k_slotProperties()));
01654
01655
01656 KActionMenu* viewMenu = new KActionMenu(i18n("&View"), this);
01657 d->actionCollection->addAction("view menu", viewMenu);
01658 viewMenu->addAction(shortAction);
01659 viewMenu->addAction(detailedAction);
01660
01661
01662
01663 d->actionCollection->addAssociatedWidget(parentWidget());
01664 foreach (QAction* action, d->actionCollection->actions())
01665 action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
01666 }
01667
01668 void KDirOperator::setupMenu()
01669 {
01670 setupMenu(SortActions | ViewActions | FileActions);
01671 }
01672
01673 void KDirOperator::setupMenu(int whichActions)
01674 {
01675
01676 KActionMenu *sortMenu = static_cast<KActionMenu*>(d->actionCollection->action("sorting menu"));
01677 sortMenu->menu()->clear();
01678 sortMenu->addAction(d->actionCollection->action("by name"));
01679 sortMenu->addAction(d->actionCollection->action("by size"));
01680 sortMenu->addAction(d->actionCollection->action("by date"));
01681 sortMenu->addAction(d->actionCollection->action("by type"));
01682 sortMenu->addSeparator();
01683 sortMenu->addAction(d->actionCollection->action("descending"));
01684
01685
01686 d->actionMenu->menu()->clear();
01687 if (whichActions & NavActions) {
01688 d->actionMenu->addAction(d->actionCollection->action("up"));
01689 d->actionMenu->addAction(d->actionCollection->action("back"));
01690 d->actionMenu->addAction(d->actionCollection->action("forward"));
01691 d->actionMenu->addAction(d->actionCollection->action("home"));
01692 d->actionMenu->addSeparator();
01693 }
01694
01695 if (whichActions & FileActions) {
01696 d->actionMenu->addAction(d->actionCollection->action("mkdir"));
01697 if (d->currUrl.isLocalFile() && !(QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
01698 d->actionMenu->addAction(d->actionCollection->action("trash"));
01699 }
01700 KConfigGroup cg(KGlobal::config(), QLatin1String("KDE"));
01701 const bool del = !d->currUrl.isLocalFile() ||
01702 (QApplication::keyboardModifiers() & Qt::ShiftModifier) ||
01703 cg.readEntry("ShowDeleteCommand", false);
01704 if (del) {
01705 d->actionMenu->addAction(d->actionCollection->action("delete"));
01706 }
01707 d->actionMenu->addSeparator();
01708 }
01709
01710 if (whichActions & SortActions) {
01711 d->actionMenu->addAction(sortMenu);
01712 if (!(whichActions & ViewActions)) {
01713 d->actionMenu->addSeparator();
01714 }
01715 }
01716
01717 if (whichActions & ViewActions) {
01718 d->actionMenu->addAction(d->actionCollection->action("view menu"));
01719 d->actionMenu->addSeparator();
01720 }
01721
01722 if (whichActions & FileActions) {
01723 d->actionMenu->addAction(d->actionCollection->action("properties"));
01724 }
01725 }
01726
01727 void KDirOperator::updateSortActions()
01728 {
01729 if (KFile::isSortByName(d->sorting)) {
01730 d->actionCollection->action("by name")->setChecked(true);
01731 } else if (KFile::isSortByDate(d->sorting)) {
01732 d->actionCollection->action("by date")->setChecked(true);
01733 } else if (KFile::isSortBySize(d->sorting)) {
01734 d->actionCollection->action("by size")->setChecked(true);
01735 } else if (KFile::isSortByType(d->sorting)) {
01736 d->actionCollection->action("by type")->setChecked(true);
01737 }
01738 d->actionCollection->action("descending")->setChecked(d->sorting & QDir::Reversed);
01739 }
01740
01741 void KDirOperator::updateViewActions()
01742 {
01743 KFile::FileView fv = static_cast<KFile::FileView>(d->viewKind);
01744
01745
01746
01747
01748
01749 d->actionCollection->action("short view")->setChecked(KFile::isSimpleView(fv));
01750 d->actionCollection->action("detailed view")->setChecked(KFile::isDetailView(fv));
01751 }
01752
01753 void KDirOperator::readConfig(const KConfigGroup& configGroup)
01754 {
01755 d->defaultView = 0;
01756 QDir::SortFlags sorting = QDir::Name;
01757
01758 QString viewStyle = configGroup.readEntry("View Style", "Simple");
01759 if (viewStyle == QLatin1String("Detail")) {
01760 d->defaultView |= KFile::Detail;
01761 } else {
01762 d->defaultView |= KFile::Simple;
01763 }
01764
01765
01766
01767
01768
01769 if (configGroup.readEntry(QLatin1String("Show Preview"), false)) {
01770 d->defaultView |= KFile::PreviewContents;
01771 }
01772 d->previewWidth = configGroup.readEntry(QLatin1String("Preview Width"), 100);
01773
01774 if (configGroup.readEntry(QLatin1String("Sort directories first"),
01775 DefaultDirsFirst)) {
01776 sorting |= QDir::DirsFirst;
01777 }
01778
01779 QString name = QLatin1String("Name");
01780 QString sortBy = configGroup.readEntry(QLatin1String("Sort by"), name);
01781 if (sortBy == name) {
01782 sorting |= QDir::Name;
01783 } else if (sortBy == QLatin1String("Size")) {
01784 sorting |= QDir::Size;
01785 } else if (sortBy == QLatin1String("Date")) {
01786 sorting |= QDir::Time;
01787 } else if (sortBy == QLatin1String("Type")) {
01788 sorting |= QDir::Type;
01789 }
01790
01791 d->sorting = sorting;
01792 setSorting(d->sorting);
01793
01794 if (configGroup.readEntry(QLatin1String("Show hidden files"),
01795 DefaultShowHidden)) {
01796 d->actionCollection->action("show hidden")->setChecked(true);
01797 d->dirLister->setShowingDotFiles(true);
01798 }
01799 const bool descending = configGroup.readEntry(QLatin1String("Sort reversed"),
01800 DefaultSortReversed);
01801 d->actionCollection->action("descending")->setChecked(descending);
01802 if (descending) {
01803 d->sorting = d->sorting | QDir::Reversed;
01804 }
01805 }
01806
01807 void KDirOperator::writeConfig(KConfigGroup& configGroup)
01808 {
01809 QString sortBy = QLatin1String("Name");
01810 if (KFile::isSortBySize(d->sorting)) {
01811 sortBy = QLatin1String("Size");
01812 } else if (KFile::isSortByDate(d->sorting)) {
01813 sortBy = QLatin1String("Date");
01814 } else if (KFile::isSortByType(d->sorting)) {
01815 sortBy = QLatin1String("Type");
01816 }
01817
01818 configGroup.writeEntry(QLatin1String("Sort by"), sortBy);
01819
01820 configGroup.writeEntry(QLatin1String("Sort reversed"),
01821 d->actionCollection->action("descending")->isChecked());
01822
01823
01824 bool appSpecificPreview = false;
01825 if (d->preview) {
01826 KFileMetaPreview *tmp = dynamic_cast<KFileMetaPreview*>(d->preview);
01827 appSpecificPreview = (tmp == 0);
01828 }
01829
01830 if (!appSpecificPreview) {
01831 KToggleAction *previewAction = static_cast<KToggleAction*>(d->actionCollection->action("preview"));
01832 if (previewAction->isEnabled()) {
01833 bool hasPreview = previewAction->isChecked();
01834 configGroup.writeEntry(QLatin1String("Show Preview"), hasPreview);
01835
01836 if (hasPreview) {
01837
01838 QList<int> sizes = d->splitter->sizes();
01839 Q_ASSERT(sizes.count() == 2);
01840 configGroup.writeEntry(QLatin1String("Preview Width"), sizes[1]);
01841 }
01842 }
01843 }
01844
01845 configGroup.writeEntry(QLatin1String("Show hidden files"),
01846 d->actionCollection->action("show hidden")->isChecked());
01847
01848 KFile::FileView fv = static_cast<KFile::FileView>(d->viewKind);
01849 QString style;
01850 if (KFile::isDetailView(fv))
01851 style = QLatin1String("Detail");
01852 else if (KFile::isSimpleView(fv))
01853 style = QLatin1String("Simple");
01854 configGroup.writeEntry(QLatin1String("View Style"), style);
01855
01856 }
01857
01858 void KDirOperator::resizeEvent(QResizeEvent *)
01859 {
01860
01861
01862 QList<int> sizes = d->splitter->sizes();
01863 const bool hasPreview = (sizes.count() == 2);
01864 const bool restorePreviewWidth = hasPreview && (d->previewWidth != sizes[1]);
01865
01866 d->splitter->resize(size());
01867
01868 sizes = d->splitter->sizes();
01869 if (restorePreviewWidth) {
01870 const int availableWidth = sizes[0] + sizes[1];
01871 sizes[0] = availableWidth - d->previewWidth;
01872 sizes[1] = d->previewWidth;
01873 d->splitter->setSizes(sizes);
01874 }
01875 if (hasPreview) {
01876 d->previewWidth = sizes[1];
01877 }
01878
01879 if (d->progressBar->parent() == this) {
01880
01881 d->progressBar->move(2, height() - d->progressBar->height() - 2);
01882 }
01883 }
01884
01885 void KDirOperator::setOnlyDoubleClickSelectsFiles(bool enable)
01886 {
01887 d->onlyDoubleClickSelectsFiles = enable;
01888
01889
01890
01891
01892 }
01893
01894 bool KDirOperator::onlyDoubleClickSelectsFiles() const
01895 {
01896 return d->onlyDoubleClickSelectsFiles;
01897 }
01898
01899 void KDirOperator::Private::_k_slotStarted()
01900 {
01901 progressBar->setValue(0);
01902
01903 progressDelayTimer->setSingleShot(true);
01904 progressDelayTimer->start(1000);
01905 }
01906
01907 void KDirOperator::Private::_k_slotShowProgress()
01908 {
01909 progressBar->raise();
01910 progressBar->show();
01911 QApplication::flush();
01912 }
01913
01914 void KDirOperator::Private::_k_slotProgress(int percent)
01915 {
01916 progressBar->setValue(percent);
01917
01918 if (progressBar->isVisible())
01919 QApplication::flush();
01920 }
01921
01922
01923 void KDirOperator::Private::_k_slotIOFinished()
01924 {
01925 progressDelayTimer->stop();
01926 _k_slotProgress(100);
01927 progressBar->hide();
01928 emit parent->finishedLoading();
01929 parent->resetCursor();
01930
01931 if (preview) {
01932 preview->clearPreview();
01933 }
01934 }
01935
01936 void KDirOperator::Private::_k_slotCanceled()
01937 {
01938 emit parent->finishedLoading();
01939 parent->resetCursor();
01940 }
01941
01942 QProgressBar * KDirOperator::progressBar() const
01943 {
01944 return d->progressBar;
01945 }
01946
01947 void KDirOperator::clearHistory()
01948 {
01949 qDeleteAll(d->backStack);
01950 d->backStack.clear();
01951 d->actionCollection->action("back")->setEnabled(false);
01952
01953 qDeleteAll(d->forwardStack);
01954 d->forwardStack.clear();
01955 d->actionCollection->action("forward")->setEnabled(false);
01956 }
01957
01958 void KDirOperator::setEnableDirHighlighting(bool enable)
01959 {
01960 d->dirHighlighting = enable;
01961 }
01962
01963 bool KDirOperator::dirHighlighting() const
01964 {
01965 return d->dirHighlighting;
01966 }
01967
01968 bool KDirOperator::dirOnlyMode() const
01969 {
01970 return dirOnlyMode(d->mode);
01971 }
01972
01973 bool KDirOperator::dirOnlyMode(uint mode)
01974 {
01975 return ((mode & KFile::Directory) &&
01976 (mode & (KFile::File | KFile::Files)) == 0);
01977 }
01978
01979 void KDirOperator::Private::_k_slotProperties()
01980 {
01981 if (itemView == 0) {
01982 return;
01983 }
01984
01985 const KFileItemList list = parent->selectedItems();
01986 if (!list.isEmpty()) {
01987 KPropertiesDialog dialog(list, parent);
01988 dialog.exec();
01989 }
01990 }
01991
01992 void KDirOperator::Private::_k_slotPressed(const QModelIndex&)
01993 {
01994
01995
01996
01997 const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
01998 leftButtonPressed = (QApplication::mouseButtons() & Qt::LeftButton) &&
01999 !(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier);
02000 }
02001
02002 void KDirOperator::Private::_k_slotClicked(const QModelIndex& index)
02003 {
02004 if (!leftButtonPressed || (index.column() != KDirModel::Name)) {
02005 return;
02006 }
02007
02008 if (!parent->onlyDoubleClickSelectsFiles())
02009 _k_slotDoubleClicked(index);
02010 else
02011 _k_slotActivated(index);
02012 }
02013
02014 void KDirOperator::Private::_k_slotActivated(const QModelIndex& index)
02015 {
02016 const QModelIndex dirIndex = proxyModel->mapToSource(index);
02017 KFileItem item = dirModel->itemForIndex(dirIndex);
02018 bool selectDir = false;
02019
02020 const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
02021 if (item.isNull() || (modifiers & Qt::ShiftModifier) || (modifiers & Qt::ControlModifier))
02022 return;
02023
02024 if (item.isDir()) {
02025 const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
02026 selectDir = KGlobalSettings::singleClick() &&
02027 !(modifiers & Qt::ShiftModifier) &&
02028 !(modifiers & Qt::ControlModifier);
02029 }
02030
02031 if (selectDir) {
02032 parent->selectDir(item);
02033 } else {
02034 parent->selectFile(item);
02035 }
02036 }
02037
02038 void KDirOperator::Private::_k_slotDoubleClicked(const QModelIndex& index)
02039 {
02040 if (!leftButtonPressed) {
02041 return;
02042 }
02043
02044 const QModelIndex dirIndex = proxyModel->mapToSource(index);
02045 KFileItem item = dirModel->itemForIndex(dirIndex);
02046
02047 if (item.isNull())
02048 return;
02049
02050 if (item.isDir()) {
02051 parent->selectDir(item);
02052 } else {
02053 parent->selectFile(item);
02054 }
02055 }
02056
02057 void KDirOperator::Private::_k_slotSelectionChanged()
02058 {
02059 if (itemView == 0) {
02060 return;
02061 }
02062
02063
02064
02065
02066 const bool multiSelectionMode = (itemView->selectionMode() == QAbstractItemView::ExtendedSelection);
02067 const bool hasSelection = itemView->selectionModel()->hasSelection();
02068 if (multiSelectionMode || !hasSelection) {
02069 KFileItem nullItem;
02070 parent->highlightFile(nullItem);
02071 }
02072 else {
02073 KFileItem selectedItem = parent->selectedItems().first();
02074 parent->highlightFile(selectedItem);
02075 }
02076 }
02077
02078 void KDirOperator::Private::_k_openContextMenu(const QPoint& pos)
02079 {
02080 leftButtonPressed = false;
02081
02082 const QModelIndex proxyIndex = itemView->indexAt(pos);
02083 const QModelIndex dirIndex = proxyModel->mapToSource(proxyIndex);
02084 KFileItem item = dirModel->itemForIndex(dirIndex);
02085
02086 if (item.isNull())
02087 return;
02088
02089 parent->activatedMenu(item, QCursor::pos());
02090 }
02091
02092 void KDirOperator::Private::_k_triggerPreview(const QModelIndex& index)
02093 {
02094 if ((preview != 0) && index.isValid() && (index.column() == KDirModel::Name)) {
02095 const QModelIndex dirIndex = proxyModel->mapToSource(index);
02096 const KFileItem item = dirModel->itemForIndex(dirIndex);
02097
02098 if (item.isNull())
02099 return;
02100
02101 if (!item.isDir()) {
02102 previewUrl = item.url();
02103 _k_showPreview();
02104 } else {
02105 preview->clearPreview();
02106 }
02107 }
02108 }
02109
02110 void KDirOperator::Private::_k_showPreview()
02111 {
02112 if (preview != 0) {
02113 preview->showPreview(previewUrl);
02114 }
02115 }
02116
02117 void KDirOperator::Private::_k_slotSplitterMoved(int, int)
02118 {
02119 const QList<int> sizes = splitter->sizes();
02120 if (sizes.count() == 2) {
02121
02122 previewWidth = sizes[1];
02123 }
02124 }
02125
02126 void KDirOperator::Private::_k_assureVisibleSelection()
02127 {
02128 if (itemView == 0) {
02129 return;
02130 }
02131
02132 QItemSelectionModel* selModel = itemView->selectionModel();
02133 if (selModel->hasSelection()) {
02134 const QModelIndex index = selModel->currentIndex();
02135 itemView->scrollTo(index, QAbstractItemView::PositionAtCenter);
02136 _k_triggerPreview(index);
02137 }
02138 }
02139
02140
02141 void KDirOperator::Private::_k_synchronizeSortingState(int logicalIndex, Qt::SortOrder order)
02142 {
02143 switch (logicalIndex) {
02144 case KDirModel::Name: parent->sortByName(); break;
02145 case KDirModel::Size: parent->sortBySize(); break;
02146 case KDirModel::ModifiedTime: parent->sortByDate(); break;
02147 case KDirModel::Type: parent->sortByType(); break;
02148 }
02149
02150 const bool descending = actionCollection->action("descending")->isChecked();
02151 const bool reverseSorting = ((order == Qt::AscendingOrder) && descending) ||
02152 ((order == Qt::DescendingOrder) && !descending);
02153 if (reverseSorting) {
02154 parent->sortReversed();
02155 }
02156
02157 proxyModel->sort(sortColumn(), sortOrder());
02158 QMetaObject::invokeMethod(parent, "_k_assureVisibleSelection", Qt::QueuedConnection);
02159 }
02160
02161 void KDirOperator::setViewConfig(KConfigGroup& configGroup)
02162 {
02163 delete d->configGroup;
02164 d->configGroup = new KConfigGroup(configGroup);
02165 }
02166
02167 KConfigGroup* KDirOperator::viewConfigGroup() const
02168 {
02169 return d->configGroup;
02170 }
02171
02172 void KDirOperator::setShowHiddenFiles(bool s)
02173 {
02174 d->actionCollection->action("show hidden")->setChecked(s);
02175 }
02176
02177 bool KDirOperator::showHiddenFiles() const
02178 {
02179 return d->actionCollection->action("show hidden")->isChecked();
02180 }
02181
02182
02183 #include <dirent.h>
02184 bool KDirOperator::Private::isReadable(const KUrl& url)
02185 {
02186 if (!url.isLocalFile())
02187 return true;
02188
02189 KDE_struct_stat buf;
02190 #ifdef Q_WS_WIN
02191 QString ts = url.toLocalFile();
02192 #else
02193 QString ts = url.path(KUrl::AddTrailingSlash);
02194 #endif
02195 bool readable = (KDE_stat(QFile::encodeName(ts), &buf) == 0);
02196 if (readable) {
02197 DIR *test;
02198 test = opendir(QFile::encodeName(ts));
02199 readable = (test != 0);
02200 if (test)
02201 closedir(test);
02202 }
02203 return readable;
02204 }
02205
02206 #include "kdiroperator.moc"