mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 10:22:48 +00:00

it shall be delayed without the feature (which it was anyway) Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2482 lines
75 KiB
C++
2482 lines
75 KiB
C++
/* This file is part of the KDE libraries
|
|
Copyright (C) 1999,2000 Stephan Kulow <coolo@kde.org>
|
|
1999,2000,2001,2002,2003 Carsten Pfeiffer <pfeiffer@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "kdiroperator.h"
|
|
#include <kprotocolmanager.h>
|
|
#include "kdirmodel.h"
|
|
#include "kdiroperatordetailview_p.h"
|
|
#include "kdirsortfilterproxymodel.h"
|
|
#include "kfileitem.h"
|
|
#include "kimagefilepreview.h"
|
|
#include "knewfilemenu.h"
|
|
#include "ktoolinvocation.h"
|
|
|
|
#include <config-kfile.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <QtCore/QStack>
|
|
#include <QtCore/QDir>
|
|
#include <QtCore/QRegExp>
|
|
#include <QtCore/QTimer>
|
|
#include <QtCore/QAbstractItemModel>
|
|
#include <QtGui/QApplication>
|
|
#include <QtGui/QDialog>
|
|
#include <QtGui/QHeaderView>
|
|
#include <QtGui/QLabel>
|
|
#include <QtGui/QLayout>
|
|
#include <QtGui/QListView>
|
|
#include <QtGui/qevent.h>
|
|
#include <QtGui/QTreeView>
|
|
#include <QtGui/QPushButton>
|
|
#include <QtGui/QProgressBar>
|
|
#include <QtGui/QScrollBar>
|
|
#include <QtGui/QSplitter>
|
|
#include <QtGui/qevent.h>
|
|
|
|
#include <kaction.h>
|
|
#include <kapplication.h>
|
|
#include <kdebug.h>
|
|
#include <kdialog.h>
|
|
#include <kdirlister.h>
|
|
#include <kfileitemdelegate.h>
|
|
#include <kicon.h>
|
|
#include <kinputdialog.h>
|
|
#include <klocale.h>
|
|
#include <kmessagebox.h>
|
|
#include <kmenu.h>
|
|
#include <kstandardaction.h>
|
|
#include <kio/job.h>
|
|
#include <kio/deletejob.h>
|
|
#include <kio/copyjob.h>
|
|
#include <kio/jobuidelegate.h>
|
|
#include <kio/jobclasses.h>
|
|
#include <kio/netaccess.h>
|
|
#include <kio/previewjob.h>
|
|
#include <kio/renamedialog.h>
|
|
#include <kfilepreviewgenerator.h>
|
|
#include <kpropertiesdialog.h>
|
|
#include <kstandardshortcut.h>
|
|
#include <kde_file.h>
|
|
#include <kactioncollection.h>
|
|
#include <ktoggleaction.h>
|
|
#include <kactionmenu.h>
|
|
#include <kconfiggroup.h>
|
|
#include <kdeversion.h>
|
|
|
|
// QDir::SortByMask is not only undocumented, it also omits QDir::Type which is another
|
|
// sorting mode.
|
|
static const int QDirSortMask = QDir::SortByMask | QDir::Type;
|
|
|
|
/**
|
|
* Default icon view for KDirOperator using
|
|
* custom view options.
|
|
*/
|
|
class KDirOperatorIconView : public QListView
|
|
{
|
|
public:
|
|
KDirOperatorIconView(KDirOperator *dirOperator, QWidget *parent = 0);
|
|
virtual ~KDirOperatorIconView();
|
|
|
|
protected:
|
|
virtual QStyleOptionViewItem viewOptions() const;
|
|
virtual void dragEnterEvent(QDragEnterEvent* event);
|
|
virtual void mousePressEvent(QMouseEvent *event);
|
|
virtual void wheelEvent(QWheelEvent *event);
|
|
|
|
private:
|
|
KDirOperator *ops;
|
|
};
|
|
|
|
KDirOperatorIconView::KDirOperatorIconView(KDirOperator *dirOperator, QWidget *parent) :
|
|
QListView(parent),
|
|
ops(dirOperator)
|
|
{
|
|
setViewMode(QListView::IconMode);
|
|
setFlow(QListView::TopToBottom);
|
|
setResizeMode(QListView::Adjust);
|
|
setSpacing(0);
|
|
setMovement(QListView::Static);
|
|
setDragDropMode(QListView::DragOnly);
|
|
setVerticalScrollMode(QListView::ScrollPerPixel);
|
|
setHorizontalScrollMode(QListView::ScrollPerPixel);
|
|
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
setWordWrap(true);
|
|
setIconSize(QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall));
|
|
}
|
|
|
|
KDirOperatorIconView::~KDirOperatorIconView()
|
|
{
|
|
}
|
|
|
|
QStyleOptionViewItem KDirOperatorIconView::viewOptions() const
|
|
{
|
|
QStyleOptionViewItem viewOptions = QListView::viewOptions();
|
|
viewOptions.showDecorationSelected = true;
|
|
viewOptions.decorationPosition = ops->decorationPosition();
|
|
if (viewOptions.decorationPosition == QStyleOptionViewItem::Left) {
|
|
viewOptions.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter;
|
|
} else {
|
|
viewOptions.displayAlignment = Qt::AlignCenter;
|
|
}
|
|
|
|
return viewOptions;
|
|
}
|
|
|
|
void KDirOperatorIconView::dragEnterEvent(QDragEnterEvent* event)
|
|
{
|
|
if (event->mimeData()->hasUrls()) {
|
|
event->acceptProposedAction();
|
|
}
|
|
}
|
|
|
|
void KDirOperatorIconView::mousePressEvent(QMouseEvent *event)
|
|
{
|
|
if (!indexAt(event->pos()).isValid()) {
|
|
const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
|
|
if (!(modifiers & Qt::ShiftModifier) && !(modifiers & Qt::ControlModifier)) {
|
|
clearSelection();
|
|
}
|
|
}
|
|
|
|
QListView::mousePressEvent(event);
|
|
}
|
|
|
|
void KDirOperatorIconView::wheelEvent(QWheelEvent *event)
|
|
{
|
|
QListView::wheelEvent(event);
|
|
|
|
// apply the vertical wheel event to the horizontal scrollbar, as
|
|
// the items are aligned from left to right
|
|
if (event->orientation() == Qt::Vertical) {
|
|
QWheelEvent horizEvent(event->pos(),
|
|
event->delta(),
|
|
event->buttons(),
|
|
event->modifiers(),
|
|
Qt::Horizontal);
|
|
QApplication::sendEvent(horizontalScrollBar(), &horizEvent);
|
|
}
|
|
}
|
|
|
|
void KDirOperator::keyPressEvent(QKeyEvent *e)
|
|
{
|
|
if (!(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter )) {
|
|
QWidget::keyPressEvent(e);
|
|
}
|
|
}
|
|
|
|
class KDirOperator::Private
|
|
{
|
|
public:
|
|
Private( KDirOperator *parent );
|
|
~Private();
|
|
|
|
enum InlinePreviewState {
|
|
ForcedToFalse = 0,
|
|
ForcedToTrue,
|
|
NotForced
|
|
};
|
|
|
|
// private methods
|
|
bool checkPreviewInternal() const;
|
|
bool openUrl(const KUrl &url);
|
|
int sortColumn() const;
|
|
Qt::SortOrder sortOrder() const;
|
|
void updateSorting(QDir::SortFlags sort);
|
|
|
|
KFile::FileView allViews();
|
|
|
|
// private slots
|
|
void _k_slotDetailedView();
|
|
void _k_slotSimpleView();
|
|
void _k_slotToggleHidden(bool);
|
|
void _k_togglePreview(bool);
|
|
void _k_toggleInlinePreviews(bool);
|
|
void _k_slotOpenFileManager();
|
|
void _k_slotSortByName();
|
|
void _k_slotSortBySize();
|
|
void _k_slotSortByDate();
|
|
void _k_slotSortByType();
|
|
void _k_slotSortReversed(bool doReverse);
|
|
void _k_slotToggleDirsFirst();
|
|
void _k_slotToggleIgnoreCase();
|
|
void _k_slotStarted();
|
|
void _k_slotProgress(ulong);
|
|
void _k_slotShowProgress();
|
|
void _k_slotIOFinished();
|
|
void _k_slotCanceled();
|
|
void _k_slotRedirected(const KUrl&);
|
|
void _k_slotProperties();
|
|
void _k_slotActivated(const QModelIndex&);
|
|
void _k_slotSelectionChanged();
|
|
void _k_openContextMenu(const QPoint&);
|
|
void _k_triggerPreview(const QModelIndex&);
|
|
void _k_showPreview();
|
|
void _k_slotSplitterMoved(int, int);
|
|
void _k_assureVisibleSelection();
|
|
void _k_synchronizeSortingState(int, Qt::SortOrder);
|
|
void _k_slotChangeDecorationPosition();
|
|
void _k_slotExpandToUrl(const QModelIndex&);
|
|
void _k_slotItemsChanged();
|
|
void _k_slotDirectoryCreated(const KUrl&);
|
|
|
|
void updateListViewGrid();
|
|
int iconSizeForViewType(QAbstractItemView *itemView) const;
|
|
|
|
// private members
|
|
KDirOperator *parent;
|
|
QStack<KUrl*> backStack; ///< Contains all URLs you can reach with the back button.
|
|
QStack<KUrl*> forwardStack; ///< Contains all URLs you can reach with the forward button.
|
|
|
|
QModelIndex lastHoveredIndex;
|
|
|
|
KDirLister *dirLister;
|
|
KUrl currUrl;
|
|
|
|
KCompletion completion;
|
|
KCompletion dirCompletion;
|
|
bool completeListDirty;
|
|
QDir::SortFlags sorting;
|
|
QStyleOptionViewItem::Position decorationPosition;
|
|
|
|
QSplitter *splitter;
|
|
|
|
QAbstractItemView *itemView;
|
|
KDirModel *dirModel;
|
|
KDirSortFilterProxyModel *proxyModel;
|
|
|
|
KFileItemList pendingMimeTypes;
|
|
|
|
// the enum KFile::FileView as an int
|
|
int viewKind;
|
|
int defaultView;
|
|
|
|
KFile::Modes mode;
|
|
QProgressBar *progressBar;
|
|
|
|
KPreviewWidgetBase *preview;
|
|
KUrl previewUrl;
|
|
int previewWidth;
|
|
|
|
bool dirHighlighting;
|
|
bool onlyDoubleClickSelectsFiles;
|
|
QString lastURL; // used for highlighting a directory on cdUp
|
|
QTimer *progressDelayTimer;
|
|
|
|
KActionMenu *actionMenu;
|
|
KActionCollection *actionCollection;
|
|
|
|
KNewFileMenu *newFileMenu;
|
|
|
|
KConfigGroup *configGroup;
|
|
|
|
KFilePreviewGenerator *previewGenerator;
|
|
|
|
bool showPreviews;
|
|
int iconsZoom;
|
|
|
|
bool isSaving;
|
|
|
|
KActionMenu *decorationMenu;
|
|
KToggleAction *leftAction;
|
|
KUrl::List itemsToBeSetAsCurrent;
|
|
bool shouldFetchForItems;
|
|
InlinePreviewState inlinePreviewState;
|
|
};
|
|
|
|
KDirOperator::Private::Private(KDirOperator *_parent) :
|
|
parent(_parent),
|
|
dirLister(0),
|
|
decorationPosition(QStyleOptionViewItem::Left),
|
|
splitter(0),
|
|
itemView(0),
|
|
dirModel(0),
|
|
proxyModel(0),
|
|
progressBar(0),
|
|
preview(0),
|
|
previewUrl(),
|
|
previewWidth(0),
|
|
dirHighlighting(false),
|
|
onlyDoubleClickSelectsFiles(!KGlobalSettings::singleClick()),
|
|
progressDelayTimer(0),
|
|
actionMenu(0),
|
|
actionCollection(0),
|
|
newFileMenu(0),
|
|
configGroup(0),
|
|
previewGenerator(0),
|
|
showPreviews(false),
|
|
iconsZoom(0),
|
|
isSaving(false),
|
|
decorationMenu(0),
|
|
leftAction(0),
|
|
shouldFetchForItems(false),
|
|
inlinePreviewState(NotForced)
|
|
{
|
|
}
|
|
|
|
KDirOperator::Private::~Private()
|
|
{
|
|
delete itemView;
|
|
itemView = 0;
|
|
|
|
// TODO:
|
|
// if (configGroup) {
|
|
// itemView->writeConfig(configGroup);
|
|
// }
|
|
|
|
qDeleteAll(backStack);
|
|
qDeleteAll(forwardStack);
|
|
delete preview;
|
|
preview = 0;
|
|
|
|
delete proxyModel;
|
|
proxyModel = 0;
|
|
delete dirModel;
|
|
dirModel = 0;
|
|
dirLister = 0; // deleted by KDirModel
|
|
delete configGroup;
|
|
configGroup = 0;
|
|
|
|
delete progressDelayTimer;
|
|
progressDelayTimer = 0;
|
|
}
|
|
|
|
KDirOperator::KDirOperator(const KUrl& _url, QWidget *parent) :
|
|
QWidget(parent),
|
|
d(new Private(this))
|
|
{
|
|
d->splitter = new QSplitter(this);
|
|
d->splitter->setChildrenCollapsible(false);
|
|
connect(d->splitter, SIGNAL(splitterMoved(int,int)),
|
|
this, SLOT(_k_slotSplitterMoved(int,int)));
|
|
|
|
d->preview = 0;
|
|
|
|
d->mode = KFile::File;
|
|
d->viewKind = KFile::Simple;
|
|
|
|
if (_url.isEmpty()) { // no dir specified -> current dir
|
|
d->currUrl = QUrl::fromLocalFile(QDir::currentPath());
|
|
} else {
|
|
d->currUrl = _url;
|
|
if (d->currUrl.protocol().isEmpty()) {
|
|
d->currUrl.setScheme(QLatin1String("file"));
|
|
}
|
|
}
|
|
|
|
// We set the direction of this widget to LTR, since even on RTL desktops
|
|
// viewing directory listings in RTL mode makes people's head explode.
|
|
// Is this the correct place? Maybe it should be in some lower level widgets...?
|
|
setLayoutDirection(Qt::LeftToRight);
|
|
setDirLister(new KDirLister());
|
|
|
|
connect(&d->completion, SIGNAL(match(QString)),
|
|
SLOT(slotCompletionMatch(QString)));
|
|
|
|
d->progressBar = new QProgressBar(this);
|
|
d->progressBar->setObjectName("d->progressBar");
|
|
d->progressBar->adjustSize();
|
|
d->progressBar->move(2, height() - d->progressBar->height() - 2);
|
|
|
|
d->progressDelayTimer = new QTimer(this);
|
|
d->progressDelayTimer->setObjectName(QLatin1String("d->progressBar delay timer"));
|
|
connect(d->progressDelayTimer, SIGNAL(timeout()),
|
|
SLOT(_k_slotShowProgress()));
|
|
|
|
d->completeListDirty = false;
|
|
|
|
// action stuff
|
|
setupActions();
|
|
setupMenu();
|
|
|
|
d->sorting = QDir::NoSort; //so updateSorting() doesn't think nothing has changed
|
|
d->updateSorting(QDir::Name | QDir::DirsFirst);
|
|
|
|
setFocusPolicy(Qt::WheelFocus);
|
|
}
|
|
|
|
KDirOperator::~KDirOperator()
|
|
{
|
|
resetCursor();
|
|
disconnect(d->dirLister, 0, this, 0);
|
|
delete d;
|
|
}
|
|
|
|
|
|
void KDirOperator::setSorting(QDir::SortFlags spec)
|
|
{
|
|
d->updateSorting(spec);
|
|
}
|
|
|
|
QDir::SortFlags KDirOperator::sorting() const
|
|
{
|
|
return d->sorting;
|
|
}
|
|
|
|
bool KDirOperator::isRoot() const
|
|
{
|
|
return url().path() == QString(QLatin1Char('/'));
|
|
}
|
|
|
|
KDirLister *KDirOperator::dirLister() const
|
|
{
|
|
return d->dirLister;
|
|
}
|
|
|
|
void KDirOperator::resetCursor()
|
|
{
|
|
if (qApp)
|
|
QApplication::restoreOverrideCursor();
|
|
d->progressBar->hide();
|
|
}
|
|
|
|
void KDirOperator::sortByName()
|
|
{
|
|
d->updateSorting((d->sorting & ~QDirSortMask) | QDir::Name);
|
|
}
|
|
|
|
void KDirOperator::sortBySize()
|
|
{
|
|
d->updateSorting((d->sorting & ~QDirSortMask) | QDir::Size);
|
|
}
|
|
|
|
void KDirOperator::sortByDate()
|
|
{
|
|
d->updateSorting((d->sorting & ~QDirSortMask) | QDir::Time);
|
|
}
|
|
|
|
void KDirOperator::sortByType()
|
|
{
|
|
d->updateSorting((d->sorting & ~QDirSortMask) | QDir::Type);
|
|
}
|
|
|
|
void KDirOperator::sortReversed()
|
|
{
|
|
// toggle it, hence the inversion of current state
|
|
d->_k_slotSortReversed(!(d->sorting & QDir::Reversed));
|
|
}
|
|
|
|
void KDirOperator::toggleDirsFirst()
|
|
{
|
|
d->_k_slotToggleDirsFirst();
|
|
}
|
|
|
|
void KDirOperator::toggleIgnoreCase()
|
|
{
|
|
if (d->proxyModel != 0) {
|
|
Qt::CaseSensitivity cs = d->proxyModel->sortCaseSensitivity();
|
|
cs = (cs == Qt::CaseSensitive) ? Qt::CaseInsensitive : Qt::CaseSensitive;
|
|
d->proxyModel->setSortCaseSensitivity(cs);
|
|
}
|
|
}
|
|
|
|
void KDirOperator::updateSelectionDependentActions()
|
|
{
|
|
const bool hasSelection = (d->itemView != 0) &&
|
|
d->itemView->selectionModel()->hasSelection();
|
|
d->actionCollection->action("trash")->setEnabled(hasSelection);
|
|
d->actionCollection->action("delete")->setEnabled(hasSelection);
|
|
d->actionCollection->action("properties")->setEnabled(hasSelection);
|
|
}
|
|
|
|
void KDirOperator::setPreviewWidget(KPreviewWidgetBase *w)
|
|
{
|
|
const bool showPreview = (w != 0);
|
|
if (showPreview) {
|
|
d->viewKind = (d->viewKind | KFile::PreviewContents);
|
|
} else {
|
|
d->viewKind = (d->viewKind & ~KFile::PreviewContents);
|
|
}
|
|
|
|
delete d->preview;
|
|
d->preview = w;
|
|
|
|
if (w) {
|
|
d->splitter->addWidget(w);
|
|
}
|
|
|
|
KToggleAction *previewAction = static_cast<KToggleAction*>(d->actionCollection->action("preview"));
|
|
previewAction->setEnabled(showPreview);
|
|
previewAction->setChecked(showPreview);
|
|
setView(static_cast<KFile::FileView>(d->viewKind));
|
|
}
|
|
|
|
KFileItemList KDirOperator::selectedItems() const
|
|
{
|
|
KFileItemList itemList;
|
|
if (d->itemView == 0) {
|
|
return itemList;
|
|
}
|
|
|
|
const QItemSelection selection = d->proxyModel->mapSelectionToSource(d->itemView->selectionModel()->selection());
|
|
|
|
const QModelIndexList indexList = selection.indexes();
|
|
foreach(const QModelIndex &index, indexList) {
|
|
KFileItem item = d->dirModel->itemForIndex(index);
|
|
if (!item.isNull()) {
|
|
itemList.append(item);
|
|
}
|
|
}
|
|
|
|
return itemList;
|
|
}
|
|
|
|
bool KDirOperator::isSelected(const KFileItem &item) const
|
|
{
|
|
if ((item.isNull()) || (d->itemView == 0)) {
|
|
return false;
|
|
}
|
|
|
|
const QModelIndex dirIndex = d->dirModel->indexForItem(item);
|
|
const QModelIndex proxyIndex = d->proxyModel->mapFromSource(dirIndex);
|
|
return d->itemView->selectionModel()->isSelected(proxyIndex);
|
|
}
|
|
|
|
int KDirOperator::numDirs() const
|
|
{
|
|
return (d->dirLister == 0) ? 0 : 1;
|
|
}
|
|
|
|
int KDirOperator::numFiles() const
|
|
{
|
|
return (d->dirLister == 0) ? 0 : d->dirLister->items().count() - numDirs();
|
|
}
|
|
|
|
KCompletion * KDirOperator::completionObject() const
|
|
{
|
|
return const_cast<KCompletion *>(&d->completion);
|
|
}
|
|
|
|
KCompletion *KDirOperator::dirCompletionObject() const
|
|
{
|
|
return const_cast<KCompletion *>(&d->dirCompletion);
|
|
}
|
|
|
|
KActionCollection * KDirOperator::actionCollection() const
|
|
{
|
|
return d->actionCollection;
|
|
}
|
|
|
|
KFile::FileView KDirOperator::Private::allViews() {
|
|
return static_cast<KFile::FileView>(KFile::Simple | KFile::Detail);
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotDetailedView()
|
|
{
|
|
KFile::FileView view = static_cast<KFile::FileView>((viewKind & ~allViews()) | KFile::Detail);
|
|
parent->setView(view);
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotSimpleView()
|
|
{
|
|
KFile::FileView view = static_cast<KFile::FileView>((viewKind & ~allViews()) | KFile::Simple);
|
|
parent->setView(view);
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotToggleHidden(bool show)
|
|
{
|
|
dirLister->setShowingDotFiles(show);
|
|
parent->updateDir();
|
|
_k_assureVisibleSelection();
|
|
}
|
|
|
|
void KDirOperator::Private::_k_togglePreview(bool on)
|
|
{
|
|
if (on) {
|
|
viewKind = viewKind | KFile::PreviewContents;
|
|
if (preview == 0) {
|
|
preview = new KImageFilePreview(parent);
|
|
actionCollection->action("preview")->setChecked(true);
|
|
splitter->addWidget(preview);
|
|
}
|
|
|
|
preview->show();
|
|
|
|
QMetaObject::invokeMethod(parent, "_k_assureVisibleSelection", Qt::QueuedConnection);
|
|
if (itemView != 0) {
|
|
const QModelIndex index = itemView->selectionModel()->currentIndex();
|
|
if (index.isValid()) {
|
|
_k_triggerPreview(index);
|
|
}
|
|
}
|
|
} else if (preview != 0) {
|
|
viewKind = viewKind & ~KFile::PreviewContents;
|
|
preview->hide();
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_toggleInlinePreviews(bool show)
|
|
{
|
|
if (showPreviews == show) {
|
|
return;
|
|
}
|
|
|
|
showPreviews = show;
|
|
|
|
if (!previewGenerator) {
|
|
return;
|
|
}
|
|
|
|
previewGenerator->setPreviewShown(show);
|
|
|
|
if (!show) {
|
|
// remove all generated previews
|
|
QAbstractItemModel *model = dirModel;
|
|
for (int i = 0; i < model->rowCount(); ++i) {
|
|
QModelIndex index = model->index(i, 0);
|
|
const KFileItem item = dirModel->itemForIndex(index);
|
|
const_cast<QAbstractItemModel*>(index.model())->setData(index, KIcon(item.iconName()), Qt::DecorationRole);
|
|
}
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotOpenFileManager()
|
|
{
|
|
KToolInvocation::self()->startServiceForUrl(currUrl.url(), parent);
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotSortByName()
|
|
{
|
|
parent->sortByName();
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotSortBySize()
|
|
{
|
|
parent->sortBySize();
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotSortByDate()
|
|
{
|
|
parent->sortByDate();
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotSortByType()
|
|
{
|
|
parent->sortByType();
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotSortReversed(bool doReverse)
|
|
{
|
|
QDir::SortFlags s = sorting & ~QDir::Reversed;
|
|
if (doReverse) {
|
|
s |= QDir::Reversed;
|
|
}
|
|
updateSorting(s);
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotToggleDirsFirst()
|
|
{
|
|
QDir::SortFlags s = (sorting ^ QDir::DirsFirst);
|
|
updateSorting(s);
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotToggleIgnoreCase()
|
|
{
|
|
// TODO: port to Qt4's QAbstractItemView
|
|
/*if ( !d->fileView )
|
|
return;
|
|
|
|
QDir::SortFlags sorting = d->fileView->sorting();
|
|
if ( !KFile::isSortCaseInsensitive( sorting ) )
|
|
d->fileView->setSorting( sorting | QDir::IgnoreCase );
|
|
else
|
|
d->fileView->setSorting( sorting & ~QDir::IgnoreCase );
|
|
d->sorting = d->fileView->sorting();*/
|
|
}
|
|
|
|
void KDirOperator::mkdir()
|
|
{
|
|
d->newFileMenu->setPopupFiles(url());
|
|
d->newFileMenu->setViewShowsHiddenFiles(showHiddenFiles());
|
|
d->newFileMenu->createDirectory();
|
|
}
|
|
|
|
bool KDirOperator::mkdir(const QString& directory, bool enterDirectory)
|
|
{
|
|
// Creates "directory", relative to the current directory (d->currUrl).
|
|
// The given path may contain any number directories, existent or not.
|
|
// They will all be created, if possible.
|
|
|
|
bool writeOk = false;
|
|
bool exists = false;
|
|
KUrl url(d->currUrl);
|
|
|
|
const QStringList dirs = directory.split('/', QString::SkipEmptyParts);
|
|
QStringList::ConstIterator it = dirs.begin();
|
|
|
|
for (; it != dirs.end(); ++it) {
|
|
url.addPath(*it);
|
|
exists = KIO::NetAccess::exists(url, KIO::NetAccess::DestinationSide, this);
|
|
writeOk = !exists && KIO::NetAccess::mkdir(url, this);
|
|
}
|
|
|
|
if (exists) { // url was already existent
|
|
KMessageBox::sorry(d->itemView, i18n("A file or folder named %1 already exists.", url.pathOrUrl()));
|
|
} else if (!writeOk) {
|
|
KMessageBox::sorry(d->itemView, i18n("You do not have permission to "
|
|
"create that folder."));
|
|
} else if (enterDirectory) {
|
|
setUrl(url, true);
|
|
}
|
|
|
|
return writeOk;
|
|
}
|
|
|
|
KIO::DeleteJob * KDirOperator::del(const KFileItemList& items,
|
|
QWidget *parent,
|
|
bool ask, bool showProgress)
|
|
{
|
|
if (items.isEmpty()) {
|
|
KMessageBox::information(parent,
|
|
i18n("You did not select a file to delete."),
|
|
i18n("Nothing to Delete"));
|
|
return 0L;
|
|
}
|
|
|
|
if (parent == 0) {
|
|
parent = this;
|
|
}
|
|
|
|
KUrl::List urls;
|
|
QStringList files;
|
|
foreach (const KFileItem &item, items) {
|
|
const KUrl url = item.url();
|
|
urls.append(url);
|
|
files.append(url.pathOrUrl());
|
|
}
|
|
|
|
bool doIt = !ask;
|
|
if (ask) {
|
|
int ret;
|
|
if (items.count() == 1) {
|
|
ret = KMessageBox::warningContinueCancel(parent,
|
|
i18n("<qt>Do you really want to delete\n <b>'%1'</b>?</qt>" ,
|
|
files.first()),
|
|
i18n("Delete File"),
|
|
KStandardGuiItem::del(),
|
|
KStandardGuiItem::cancel(), "AskForDelete");
|
|
} else
|
|
ret = KMessageBox::warningContinueCancelList(parent,
|
|
i18np("Do you really want to delete this item?", "Do you really want to delete these %1 items?", items.count()),
|
|
files,
|
|
i18n("Delete Files"),
|
|
KStandardGuiItem::del(),
|
|
KStandardGuiItem::cancel(), "AskForDelete");
|
|
doIt = (ret == KMessageBox::Continue);
|
|
}
|
|
|
|
if (doIt) {
|
|
KIO::JobFlags flags = showProgress ? KIO::DefaultFlags : KIO::HideProgressInfo;
|
|
KIO::DeleteJob *job = KIO::del(urls, flags);
|
|
job->ui()->setWindow(this);
|
|
job->ui()->setAutoErrorHandlingEnabled(true);
|
|
return job;
|
|
}
|
|
|
|
return 0L;
|
|
}
|
|
|
|
void KDirOperator::deleteSelected()
|
|
{
|
|
const KFileItemList list = selectedItems();
|
|
if (!list.isEmpty()) {
|
|
del(list, this);
|
|
}
|
|
}
|
|
|
|
KIO::CopyJob * KDirOperator::trash(const KFileItemList& items,
|
|
QWidget *parent,
|
|
bool ask, bool showProgress)
|
|
{
|
|
if (items.isEmpty()) {
|
|
KMessageBox::information(parent,
|
|
i18n("You did not select a file to trash."),
|
|
i18n("Nothing to Trash"));
|
|
return 0L;
|
|
}
|
|
|
|
KUrl::List urls;
|
|
QStringList files;
|
|
foreach (const KFileItem &item, items) {
|
|
const KUrl url = item.url();
|
|
urls.append(url);
|
|
files.append(url.pathOrUrl());
|
|
}
|
|
|
|
bool doIt = !ask;
|
|
if (ask) {
|
|
int ret;
|
|
if (items.count() == 1) {
|
|
ret = KMessageBox::warningContinueCancel(parent,
|
|
i18n("<qt>Do you really want to trash\n <b>'%1'</b>?</qt>" ,
|
|
files.first()),
|
|
i18n("Trash File"),
|
|
KGuiItem(i18nc("to trash", "&Trash"), "user-trash"),
|
|
KStandardGuiItem::cancel(), "AskForTrash");
|
|
} else
|
|
ret = KMessageBox::warningContinueCancelList(parent,
|
|
i18np("translators: not called for n == 1", "Do you really want to trash these %1 items?", items.count()),
|
|
files,
|
|
i18n("Trash Files"),
|
|
KGuiItem(i18nc("to trash", "&Trash"), "user-trash"),
|
|
KStandardGuiItem::cancel(), "AskForTrash");
|
|
doIt = (ret == KMessageBox::Continue);
|
|
}
|
|
|
|
if (doIt) {
|
|
KIO::JobFlags flags = showProgress ? KIO::DefaultFlags : KIO::HideProgressInfo;
|
|
KIO::CopyJob *job = KIO::trash(urls, flags);
|
|
job->ui()->setWindow(this);
|
|
job->ui()->setAutoErrorHandlingEnabled(true);
|
|
return job;
|
|
}
|
|
|
|
return 0L;
|
|
}
|
|
|
|
KFilePreviewGenerator *KDirOperator::previewGenerator() const
|
|
{
|
|
return d->previewGenerator;
|
|
}
|
|
|
|
void KDirOperator::setInlinePreviewShown(bool show)
|
|
{
|
|
d->inlinePreviewState = show ? Private::ForcedToTrue : Private::ForcedToFalse;
|
|
}
|
|
|
|
bool KDirOperator::isInlinePreviewShown() const
|
|
{
|
|
return d->showPreviews;
|
|
}
|
|
|
|
int KDirOperator::iconsZoom() const
|
|
{
|
|
return d->iconsZoom;
|
|
}
|
|
|
|
void KDirOperator::setIsSaving(bool isSaving)
|
|
{
|
|
d->isSaving = isSaving;
|
|
}
|
|
|
|
bool KDirOperator::isSaving() const
|
|
{
|
|
return d->isSaving;
|
|
}
|
|
|
|
void KDirOperator::trashSelected()
|
|
{
|
|
if (d->itemView == 0) {
|
|
return;
|
|
}
|
|
|
|
if (QApplication::keyboardModifiers() & Qt::ShiftModifier) {
|
|
deleteSelected();
|
|
return;
|
|
}
|
|
|
|
const KFileItemList list = selectedItems();
|
|
if (!list.isEmpty()) {
|
|
trash(list, this);
|
|
}
|
|
}
|
|
|
|
void KDirOperator::setIconsZoom(int _value)
|
|
{
|
|
if (d->iconsZoom == _value) {
|
|
return;
|
|
}
|
|
|
|
int value = _value;
|
|
value = qMin(100, value);
|
|
value = qMax(0, value);
|
|
|
|
d->iconsZoom = value;
|
|
|
|
if (!d->previewGenerator) {
|
|
return;
|
|
}
|
|
|
|
const int maxSize = KIconLoader::SizeEnormous - KIconLoader::SizeSmall;
|
|
const int val = (maxSize * value / 100) + KIconLoader::SizeSmall;
|
|
d->itemView->setIconSize(QSize(val, val));
|
|
d->updateListViewGrid();
|
|
d->previewGenerator->updateIcons();
|
|
|
|
emit currentIconSizeChanged(value);
|
|
}
|
|
|
|
void KDirOperator::close()
|
|
{
|
|
resetCursor();
|
|
d->pendingMimeTypes.clear();
|
|
d->completion.clear();
|
|
d->dirCompletion.clear();
|
|
d->completeListDirty = true;
|
|
d->dirLister->stop();
|
|
}
|
|
|
|
void KDirOperator::setUrl(const KUrl& _newurl, bool clearforward)
|
|
{
|
|
KUrl newurl(_newurl);
|
|
|
|
if (!newurl.isValid()) {
|
|
newurl = QUrl::fromLocalFile(QDir::homePath());
|
|
}
|
|
newurl.adjustPath(KUrl::RemoveTrailingSlash);
|
|
|
|
// already set
|
|
if (newurl.equals(d->currUrl)) {
|
|
return;
|
|
}
|
|
|
|
// TODO: something is trying to set relative file path, that is ugly
|
|
// workaround for it and the caller should set the full path
|
|
if (newurl.isRelative()) {
|
|
newurl.setPath(d->currUrl.prettyUrl() + "/" + newurl.prettyUrl());
|
|
}
|
|
|
|
QDir urldir(newurl.toLocalFile());
|
|
if (!urldir.exists() || !urldir.isReadable()) {
|
|
// maybe newurl is a file? check its parent directory
|
|
newurl.setPath(newurl.directory());
|
|
// parent is current
|
|
if (newurl.equals(d->currUrl)) {
|
|
return;
|
|
}
|
|
|
|
urldir.setPath(newurl.toLocalFile());
|
|
if (!urldir.exists() || !urldir.isReadable()) {
|
|
resetCursor();
|
|
KMessageBox::error(d->itemView,
|
|
i18n("The specified folder does not exist or was not readable."));
|
|
return;
|
|
}
|
|
newurl.setPath(urldir.path());
|
|
}
|
|
newurl.adjustPath(KUrl::RemoveTrailingSlash);
|
|
|
|
if (clearforward) {
|
|
// autodelete should remove this one
|
|
d->backStack.push(new KUrl(d->currUrl));
|
|
qDeleteAll(d->forwardStack);
|
|
d->forwardStack.clear();
|
|
}
|
|
|
|
d->lastURL = d->currUrl.url();
|
|
d->currUrl = newurl;
|
|
|
|
pathChanged();
|
|
emit urlEntered(newurl);
|
|
|
|
// enable/disable actions
|
|
QAction* forwardAction = d->actionCollection->action("forward");
|
|
forwardAction->setEnabled(!d->forwardStack.isEmpty());
|
|
|
|
QAction* backAction = d->actionCollection->action("back");
|
|
backAction->setEnabled(!d->backStack.isEmpty());
|
|
|
|
QAction* upAction = d->actionCollection->action("up");
|
|
upAction->setEnabled(!isRoot());
|
|
|
|
d->openUrl(newurl);
|
|
}
|
|
|
|
void KDirOperator::updateDir()
|
|
{
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
d->dirLister->updateDirectory();
|
|
QApplication::restoreOverrideCursor();
|
|
}
|
|
|
|
void KDirOperator::rereadDir()
|
|
{
|
|
pathChanged();
|
|
d->openUrl(d->currUrl);
|
|
}
|
|
|
|
|
|
bool KDirOperator::Private::openUrl(const KUrl &url)
|
|
{
|
|
const bool result = KProtocolManager::supportsListing(url) && dirLister->openUrl(url);
|
|
if (!result) // in that case, neither completed() nor canceled() will be emitted by KDL
|
|
_k_slotCanceled();
|
|
|
|
return result;
|
|
}
|
|
|
|
int KDirOperator::Private::sortColumn() const
|
|
{
|
|
int column = KDirModel::Name;
|
|
if (KFile::isSortByDate(sorting)) {
|
|
column = KDirModel::ModifiedTime;
|
|
} else if (KFile::isSortBySize(sorting)) {
|
|
column = KDirModel::Size;
|
|
} else if (KFile::isSortByType(sorting)) {
|
|
column = KDirModel::Type;
|
|
} else {
|
|
Q_ASSERT(KFile::isSortByName(sorting));
|
|
}
|
|
|
|
return column;
|
|
}
|
|
|
|
Qt::SortOrder KDirOperator::Private::sortOrder() const
|
|
{
|
|
return (sorting & QDir::Reversed) ? Qt::DescendingOrder :
|
|
Qt::AscendingOrder;
|
|
}
|
|
|
|
void KDirOperator::Private::updateSorting(QDir::SortFlags sort)
|
|
{
|
|
kDebug() << "changing sort flags from" << sorting << "to" << sort;
|
|
if (sort == sorting) {
|
|
return;
|
|
}
|
|
|
|
if ((sorting ^ sort) & QDir::DirsFirst) {
|
|
// The "Folders First" setting has been changed.
|
|
// We need to make sure that the files and folders are really re-sorted.
|
|
// Without the following intermediate "fake resorting",
|
|
// QSortFilterProxyModel::sort(int column, Qt::SortOrder order)
|
|
// would do nothing because neither the column nor the sort order have been changed.
|
|
Qt::SortOrder tmpSortOrder = (sortOrder() == Qt::AscendingOrder ? Qt::DescendingOrder : Qt::AscendingOrder);
|
|
proxyModel->sort(sortOrder(), tmpSortOrder);
|
|
proxyModel->setSortFoldersFirst(sort & QDir::DirsFirst);
|
|
}
|
|
|
|
sorting = sort;
|
|
parent->updateSortActions();
|
|
proxyModel->sort(sortColumn(), sortOrder());
|
|
|
|
// TODO: The headers from QTreeView don't take care about a sorting
|
|
// change of the proxy model hence they must be updated the manually.
|
|
// This is done here by a qobject_cast, but it would be nicer to:
|
|
// - provide a signal 'sortingChanged()'
|
|
// - connect KDirOperatorDetailView() with this signal and update the
|
|
// header internally
|
|
QTreeView* treeView = qobject_cast<QTreeView*>(itemView);
|
|
if (treeView != 0) {
|
|
QHeaderView* headerView = treeView->header();
|
|
headerView->blockSignals(true);
|
|
headerView->setSortIndicator(sortColumn(), sortOrder());
|
|
headerView->blockSignals(false);
|
|
}
|
|
|
|
_k_assureVisibleSelection();
|
|
}
|
|
|
|
// Protected
|
|
void KDirOperator::pathChanged()
|
|
{
|
|
if (d->itemView == 0)
|
|
return;
|
|
|
|
d->pendingMimeTypes.clear();
|
|
//d->fileView->clear(); TODO
|
|
d->completion.clear();
|
|
d->dirCompletion.clear();
|
|
|
|
// it may be, that we weren't ready at this time
|
|
QApplication::restoreOverrideCursor();
|
|
|
|
// when KIO::Job emits finished, the slot will restore the cursor
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
|
|
QDir urldir(d->currUrl.toLocalFile());
|
|
if (!urldir.isReadable()) {
|
|
KMessageBox::error(d->itemView,
|
|
i18n("The specified folder does not exist or was not readable."));
|
|
if (d->backStack.isEmpty())
|
|
home();
|
|
else
|
|
back();
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotRedirected(const KUrl& newURL)
|
|
{
|
|
currUrl = newURL;
|
|
pendingMimeTypes.clear();
|
|
completion.clear();
|
|
dirCompletion.clear();
|
|
completeListDirty = true;
|
|
emit parent->urlEntered(newURL);
|
|
}
|
|
|
|
// Code pinched from kfm then hacked
|
|
void KDirOperator::back()
|
|
{
|
|
if (d->backStack.isEmpty())
|
|
return;
|
|
|
|
d->forwardStack.push(new KUrl(d->currUrl));
|
|
|
|
KUrl *s = d->backStack.pop();
|
|
|
|
setUrl(*s, false);
|
|
delete s;
|
|
}
|
|
|
|
// Code pinched from kfm then hacked
|
|
void KDirOperator::forward()
|
|
{
|
|
if (d->forwardStack.isEmpty())
|
|
return;
|
|
|
|
d->backStack.push(new KUrl(d->currUrl));
|
|
|
|
KUrl *s = d->forwardStack.pop();
|
|
setUrl(*s, false);
|
|
delete s;
|
|
}
|
|
|
|
KUrl KDirOperator::url() const
|
|
{
|
|
return d->currUrl;
|
|
}
|
|
|
|
void KDirOperator::cdUp()
|
|
{
|
|
setUrl(d->currUrl.upUrl(), true);
|
|
}
|
|
|
|
void KDirOperator::home()
|
|
{
|
|
KUrl u = QUrl::fromLocalFile(QDir::homePath());
|
|
setUrl(u, true);
|
|
}
|
|
|
|
void KDirOperator::clearFilter()
|
|
{
|
|
d->dirLister->setNameFilter(QString());
|
|
d->dirLister->clearMimeFilter();
|
|
checkPreviewSupport();
|
|
}
|
|
|
|
void KDirOperator::setNameFilter(const QString& filter)
|
|
{
|
|
d->dirLister->setNameFilter(filter);
|
|
checkPreviewSupport();
|
|
}
|
|
|
|
QString KDirOperator::nameFilter() const
|
|
{
|
|
return d->dirLister->nameFilter();
|
|
}
|
|
|
|
void KDirOperator::setMimeFilter(const QStringList& mimetypes)
|
|
{
|
|
d->dirLister->setMimeFilter(mimetypes);
|
|
checkPreviewSupport();
|
|
}
|
|
|
|
QStringList KDirOperator::mimeFilter() const
|
|
{
|
|
return d->dirLister->mimeFilters();
|
|
}
|
|
|
|
void KDirOperator::setNewFileMenuSupportedMimeTypes(const QStringList& mimeTypes)
|
|
{
|
|
d->newFileMenu->setSupportedMimeTypes(mimeTypes);
|
|
}
|
|
|
|
QStringList KDirOperator::newFileMenuSupportedMimeTypes() const
|
|
{
|
|
return d->newFileMenu->supportedMimeTypes();
|
|
}
|
|
|
|
bool KDirOperator::checkPreviewSupport()
|
|
{
|
|
KToggleAction *previewAction = static_cast<KToggleAction*>(d->actionCollection->action("preview"));
|
|
|
|
bool hasPreviewSupport = false;
|
|
KConfigGroup cg(KGlobal::config(), ConfigGroup);
|
|
if (cg.readEntry("Show Default Preview", true))
|
|
hasPreviewSupport = d->checkPreviewInternal();
|
|
|
|
previewAction->setEnabled(hasPreviewSupport);
|
|
return hasPreviewSupport;
|
|
}
|
|
|
|
void KDirOperator::activatedMenu(const KFileItem &item, const QPoint &pos)
|
|
{
|
|
Q_UNUSED(item);
|
|
updateSelectionDependentActions();
|
|
|
|
d->newFileMenu->setPopupFiles(url());
|
|
d->newFileMenu->setViewShowsHiddenFiles(showHiddenFiles());
|
|
d->newFileMenu->checkUpToDate();
|
|
|
|
emit contextMenuAboutToShow( item, d->actionMenu->menu() );
|
|
|
|
d->actionMenu->menu()->exec(pos);
|
|
}
|
|
|
|
bool KDirOperator::eventFilter(QObject *watched, QEvent *event)
|
|
{
|
|
// If we are not hovering any items, check if there is a current index
|
|
// set. In that case, we show the preview of that item.
|
|
switch(event->type()) {
|
|
case QEvent::MouseMove: {
|
|
if (d->preview && !d->preview->isHidden()) {
|
|
const QModelIndex hoveredIndex = d->itemView->indexAt(d->itemView->viewport()->mapFromGlobal(QCursor::pos()));
|
|
|
|
if (d->lastHoveredIndex == hoveredIndex)
|
|
return QWidget::eventFilter(watched, event);
|
|
|
|
d->lastHoveredIndex = hoveredIndex;
|
|
|
|
const QModelIndex focusedIndex = d->itemView->selectionModel() ? d->itemView->selectionModel()->currentIndex()
|
|
: QModelIndex();
|
|
|
|
if (!hoveredIndex.isValid() && focusedIndex.isValid() &&
|
|
d->itemView->selectionModel()->isSelected(focusedIndex) &&
|
|
(d->lastHoveredIndex != focusedIndex)) {
|
|
const QModelIndex sourceFocusedIndex = d->proxyModel->mapToSource(focusedIndex);
|
|
const KFileItem item = d->dirModel->itemForIndex(sourceFocusedIndex);
|
|
if (!item.isNull()) {
|
|
d->preview->showPreview(item.url());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case QEvent::MouseButtonRelease: {
|
|
if (d->preview != 0 && !d->preview->isHidden()) {
|
|
const QModelIndex hoveredIndex = d->itemView->indexAt(d->itemView->viewport()->mapFromGlobal(QCursor::pos()));
|
|
const QModelIndex focusedIndex = d->itemView->selectionModel() ? d->itemView->selectionModel()->currentIndex()
|
|
: QModelIndex();
|
|
|
|
if (((!focusedIndex.isValid()) ||
|
|
!d->itemView->selectionModel()->isSelected(focusedIndex)) &&
|
|
(!hoveredIndex.isValid())) {
|
|
d->preview->clearPreview();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case QEvent::Wheel: {
|
|
QWheelEvent *evt = static_cast<QWheelEvent*>(event);
|
|
if (evt->modifiers() & Qt::ControlModifier) {
|
|
if (evt->delta() > 0) {
|
|
setIconsZoom(d->iconsZoom + 10);
|
|
} else {
|
|
setIconsZoom(d->iconsZoom - 10);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return QWidget::eventFilter(watched, event);
|
|
}
|
|
|
|
bool KDirOperator::Private::checkPreviewInternal() const
|
|
{
|
|
const QStringList supported = KIO::PreviewJob::supportedMimeTypes();
|
|
// no preview support for directories?
|
|
if (parent->dirOnlyMode() && supported.indexOf("inode/directory") == -1)
|
|
return false;
|
|
|
|
const QStringList mimeTypes = dirLister->mimeFilters();
|
|
const QStringList nameFilter = dirLister->nameFilter().split(' ', QString::SkipEmptyParts);
|
|
|
|
if (mimeTypes.isEmpty() && nameFilter.isEmpty() && !supported.isEmpty()) {
|
|
return true;
|
|
} else {
|
|
QRegExp r;
|
|
r.setPatternSyntax(QRegExp::Wildcard); // the "mimetype" can be "image/*"
|
|
|
|
foreach(const QString &it, supported) {
|
|
r.setPattern(it);
|
|
|
|
const QStringList result = mimeTypes.filter(r);
|
|
if (!result.isEmpty()) { // matches! -> we want previews
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// find the mimetypes of all the filter-patterns
|
|
foreach(const QString &it1, nameFilter) {
|
|
if (it1 == "*") {
|
|
return true;
|
|
}
|
|
|
|
KMimeType::Ptr mt = KMimeType::findByUrl(KUrl(it1), 0, true /*fast mode, no file contents exist*/);
|
|
if (!mt)
|
|
continue;
|
|
const QString mime = mt->name();
|
|
|
|
// the "mimetypes" we get from the PreviewJob can be "image/*"
|
|
// so we need to check in wildcard mode
|
|
foreach(const QString &it2, supported) {
|
|
r.setPattern(it2);
|
|
if (r.indexIn(mime) != -1) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
QAbstractItemView* KDirOperator::createView(QWidget* parent, KFile::FileView viewKind)
|
|
{
|
|
QAbstractItemView *itemView = 0;
|
|
if (KFile::isDetailView(viewKind)) {
|
|
KDirOperatorDetailView *detailView = new KDirOperatorDetailView(parent);
|
|
detailView->setViewMode(viewKind);
|
|
itemView = detailView;
|
|
} else {
|
|
itemView = new KDirOperatorIconView(this, parent);
|
|
}
|
|
|
|
return itemView;
|
|
}
|
|
|
|
void KDirOperator::setAcceptDrops(bool b)
|
|
{
|
|
// TODO:
|
|
//if (d->itemView)
|
|
// d->itemView->setAcceptDrops(b);
|
|
QWidget::setAcceptDrops(b);
|
|
}
|
|
|
|
void KDirOperator::setView(KFile::FileView viewKind)
|
|
{
|
|
bool preview = (KFile::isPreviewInfo(viewKind) || KFile::isPreviewContents(viewKind));
|
|
|
|
if (viewKind == KFile::Default) {
|
|
if (KFile::isDetailView((KFile::FileView)d->defaultView)) {
|
|
viewKind = KFile::Detail;
|
|
} else {
|
|
viewKind = KFile::Simple;
|
|
}
|
|
|
|
const KFile::FileView defaultViewKind = static_cast<KFile::FileView>(d->defaultView);
|
|
preview = (KFile::isPreviewInfo(defaultViewKind) || KFile::isPreviewContents(defaultViewKind))
|
|
&& d->actionCollection->action("preview")->isEnabled();
|
|
}
|
|
|
|
d->viewKind = static_cast<int>(viewKind);
|
|
viewKind = static_cast<KFile::FileView>(d->viewKind);
|
|
|
|
QAbstractItemView *newView = createView(this, viewKind);
|
|
setView(newView);
|
|
|
|
d->_k_togglePreview(preview);
|
|
}
|
|
|
|
QAbstractItemView * KDirOperator::view() const
|
|
{
|
|
return d->itemView;
|
|
}
|
|
|
|
KFile::Modes KDirOperator::mode() const
|
|
{
|
|
return d->mode;
|
|
}
|
|
|
|
void KDirOperator::setMode(KFile::Modes mode)
|
|
{
|
|
if (d->mode == mode)
|
|
return;
|
|
|
|
d->mode = mode;
|
|
|
|
d->dirLister->setDirOnlyMode(dirOnlyMode());
|
|
|
|
// reset the view with the different mode
|
|
if (d->itemView != 0)
|
|
setView(static_cast<KFile::FileView>(d->viewKind));
|
|
}
|
|
|
|
void KDirOperator::setView(QAbstractItemView *view)
|
|
{
|
|
if (view == d->itemView) {
|
|
return;
|
|
}
|
|
|
|
// TODO: do a real timer and restart it after that
|
|
d->pendingMimeTypes.clear();
|
|
const bool listDir = (d->itemView == 0);
|
|
|
|
if (d->mode & KFile::Files) {
|
|
view->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
} else {
|
|
view->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
}
|
|
|
|
QItemSelectionModel *selectionModel = 0;
|
|
if ((d->itemView != 0) && d->itemView->selectionModel()->hasSelection()) {
|
|
// remember the selection of the current item view and apply this selection
|
|
// to the new view later
|
|
const QItemSelection selection = d->itemView->selectionModel()->selection();
|
|
selectionModel = new QItemSelectionModel(d->proxyModel, this);
|
|
selectionModel->select(selection, QItemSelectionModel::Select);
|
|
}
|
|
|
|
setFocusProxy(0);
|
|
delete d->itemView;
|
|
d->itemView = view;
|
|
d->itemView->setModel(d->proxyModel);
|
|
setFocusProxy(d->itemView);
|
|
|
|
view->viewport()->installEventFilter(this);
|
|
|
|
KFileItemDelegate *delegate = new KFileItemDelegate(d->itemView);
|
|
d->itemView->setItemDelegate(delegate);
|
|
d->itemView->viewport()->setAttribute(Qt::WA_Hover);
|
|
d->itemView->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
d->itemView->setMouseTracking(true);
|
|
//d->itemView->setAcceptDrops(acceptDrops());
|
|
|
|
// first push our settings to the view, then listen for changes from the view
|
|
QTreeView* treeView = qobject_cast<QTreeView*>(d->itemView);
|
|
if (treeView) {
|
|
QHeaderView* headerView = treeView->header();
|
|
headerView->setSortIndicator(d->sortColumn(), d->sortOrder());
|
|
connect(headerView, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
|
|
this, SLOT(_k_synchronizeSortingState(int,Qt::SortOrder)));
|
|
}
|
|
|
|
connect(d->itemView, SIGNAL(activated(QModelIndex)),
|
|
this, SLOT(_k_slotActivated(QModelIndex)));
|
|
connect(d->itemView, SIGNAL(customContextMenuRequested(QPoint)),
|
|
this, SLOT(_k_openContextMenu(QPoint)));
|
|
connect(d->itemView, SIGNAL(entered(QModelIndex)),
|
|
this, SLOT(_k_triggerPreview(QModelIndex)));
|
|
|
|
updateViewActions();
|
|
d->splitter->insertWidget(0, d->itemView);
|
|
|
|
d->splitter->resize(size());
|
|
d->itemView->show();
|
|
|
|
if (listDir) {
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
d->openUrl(d->currUrl);
|
|
}
|
|
|
|
if (selectionModel != 0) {
|
|
d->itemView->setSelectionModel(selectionModel);
|
|
QMetaObject::invokeMethod(this, "_k_assureVisibleSelection", Qt::QueuedConnection);
|
|
}
|
|
|
|
connect(d->itemView->selectionModel(),
|
|
SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
|
this, SLOT(_k_triggerPreview(QModelIndex)));
|
|
connect(d->itemView->selectionModel(),
|
|
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
|
this, SLOT(_k_slotSelectionChanged()));
|
|
|
|
// if we cannot cast it to a QListView, disable the "Icon Position" menu. Note that this check
|
|
// needs to be done here, and not in createView, since we can be set an external view
|
|
d->decorationMenu->setEnabled(qobject_cast<QListView*>(d->itemView));
|
|
|
|
d->shouldFetchForItems = qobject_cast<QTreeView*>(view);
|
|
if (d->shouldFetchForItems) {
|
|
connect(d->dirModel, SIGNAL(expand(QModelIndex)), this, SLOT(_k_slotExpandToUrl(QModelIndex)));
|
|
} else {
|
|
d->itemsToBeSetAsCurrent.clear();
|
|
}
|
|
|
|
const bool previewForcedToTrue = d->inlinePreviewState == Private::ForcedToTrue;
|
|
const bool previewShown = d->inlinePreviewState == Private::NotForced ? d->showPreviews : previewForcedToTrue;
|
|
d->previewGenerator = new KFilePreviewGenerator(d->itemView);
|
|
const int maxSize = KIconLoader::SizeEnormous - KIconLoader::SizeSmall;
|
|
const int val = (maxSize * d->iconsZoom / 100) + KIconLoader::SizeSmall;
|
|
d->itemView->setIconSize(previewForcedToTrue ? QSize(KIconLoader::SizeHuge, KIconLoader::SizeHuge) : QSize(val, val));
|
|
d->previewGenerator->setPreviewShown(previewShown);
|
|
d->actionCollection->action("inline preview")->setChecked(previewShown);
|
|
|
|
// ensure we change everything needed
|
|
d->_k_slotChangeDecorationPosition();
|
|
|
|
emit viewChanged(view);
|
|
|
|
const int zoom = previewForcedToTrue ? (KIconLoader::SizeHuge - KIconLoader::SizeSmall + 1) * 100 / maxSize : d->iconSizeForViewType(view);
|
|
|
|
// this will make d->iconsZoom be updated, since setIconsZoom slot will be called
|
|
emit currentIconSizeChanged(zoom);
|
|
}
|
|
|
|
void KDirOperator::setDirLister(KDirLister *lister)
|
|
{
|
|
if (lister == d->dirLister) // sanity check
|
|
return;
|
|
|
|
delete d->dirModel;
|
|
d->dirModel = 0;
|
|
|
|
delete d->proxyModel;
|
|
d->proxyModel = 0;
|
|
|
|
//delete d->dirLister; // deleted by KDirModel already, which took ownership
|
|
d->dirLister = lister;
|
|
|
|
d->dirModel = new KDirModel();
|
|
d->dirModel->setDirLister(d->dirLister);
|
|
d->dirModel->setDropsAllowed(KDirModel::DropOnDirectory);
|
|
|
|
d->shouldFetchForItems = qobject_cast<QTreeView*>(d->itemView);
|
|
if (d->shouldFetchForItems) {
|
|
connect(d->dirModel, SIGNAL(expand(QModelIndex)), this, SLOT(_k_slotExpandToUrl(QModelIndex)));
|
|
} else {
|
|
d->itemsToBeSetAsCurrent.clear();
|
|
}
|
|
|
|
d->proxyModel = new KDirSortFilterProxyModel(this);
|
|
d->proxyModel->setSourceModel(d->dirModel);
|
|
|
|
d->dirLister->setAutoUpdate(true);
|
|
|
|
QWidget* mainWidget = window();
|
|
d->dirLister->setMainWindow(mainWidget);
|
|
kDebug() << "mainWidget=" << mainWidget;
|
|
|
|
connect(d->dirLister, SIGNAL(percent(ulong)),
|
|
SLOT(_k_slotProgress(ulong)));
|
|
connect(d->dirLister, SIGNAL(started()), SLOT(_k_slotStarted()));
|
|
connect(d->dirLister, SIGNAL(completed()), SLOT(_k_slotIOFinished()));
|
|
connect(d->dirLister, SIGNAL(canceled()), SLOT(_k_slotCanceled()));
|
|
connect(d->dirLister, SIGNAL(redirection(KUrl)),
|
|
SLOT(_k_slotRedirected(KUrl)));
|
|
connect(d->dirLister, SIGNAL(itemsAdded(KFileItemList)), SLOT(_k_slotItemsChanged()));
|
|
connect(d->dirLister, SIGNAL(itemsDeleted(KFileItemList)), SLOT(_k_slotItemsChanged()));
|
|
connect(d->dirLister, SIGNAL(clear()), SLOT(_k_slotItemsChanged()));
|
|
}
|
|
|
|
void KDirOperator::selectDir(const KFileItem &item)
|
|
{
|
|
setUrl(item.targetUrl(), true);
|
|
}
|
|
|
|
void KDirOperator::selectFile(const KFileItem &item)
|
|
{
|
|
QApplication::restoreOverrideCursor();
|
|
|
|
emit fileSelected(item);
|
|
}
|
|
|
|
void KDirOperator::highlightFile(const KFileItem &item)
|
|
{
|
|
if ((d->preview != 0 && !d->preview->isHidden()) && !item.isNull()) {
|
|
d->preview->showPreview(item.url());
|
|
}
|
|
|
|
emit fileHighlighted(item);
|
|
}
|
|
|
|
void KDirOperator::setCurrentItem(const QString& url)
|
|
{
|
|
KFileItem item = d->dirLister->findByUrl(url);
|
|
if (d->shouldFetchForItems && item.isNull()) {
|
|
d->itemsToBeSetAsCurrent << url;
|
|
d->dirModel->expandToUrl(url);
|
|
return;
|
|
}
|
|
|
|
setCurrentItem(item);
|
|
}
|
|
|
|
void KDirOperator::setCurrentItem(const KFileItem& item)
|
|
{
|
|
if (!d->itemView) {
|
|
return;
|
|
}
|
|
|
|
QItemSelectionModel *selModel = d->itemView->selectionModel();
|
|
if (selModel) {
|
|
selModel->clear();
|
|
if (!item.isNull()) {
|
|
const QModelIndex dirIndex = d->dirModel->indexForItem(item);
|
|
const QModelIndex proxyIndex = d->proxyModel->mapFromSource(dirIndex);
|
|
selModel->setCurrentIndex(proxyIndex, QItemSelectionModel::Select);
|
|
}
|
|
}
|
|
}
|
|
|
|
void KDirOperator::setCurrentItems(const QStringList& urls)
|
|
{
|
|
if (!d->itemView) {
|
|
return;
|
|
}
|
|
|
|
KFileItemList itemList;
|
|
foreach (const QString &url, urls) {
|
|
KFileItem item = d->dirLister->findByUrl(url);
|
|
if (d->shouldFetchForItems && item.isNull()) {
|
|
d->itemsToBeSetAsCurrent << url;
|
|
d->dirModel->expandToUrl(url);
|
|
continue;
|
|
}
|
|
itemList << item;
|
|
}
|
|
|
|
setCurrentItems(itemList);
|
|
}
|
|
|
|
void KDirOperator::setCurrentItems(const KFileItemList& items)
|
|
{
|
|
if (d->itemView == 0) {
|
|
return;
|
|
}
|
|
|
|
QItemSelectionModel *selModel = d->itemView->selectionModel();
|
|
if (selModel) {
|
|
selModel->clear();
|
|
QModelIndex proxyIndex;
|
|
foreach (const KFileItem &item, items) {
|
|
if (!item.isNull()) {
|
|
const QModelIndex dirIndex = d->dirModel->indexForItem(item);
|
|
proxyIndex = d->proxyModel->mapFromSource(dirIndex);
|
|
selModel->select(proxyIndex, QItemSelectionModel::Select);
|
|
}
|
|
}
|
|
if (proxyIndex.isValid()) {
|
|
selModel->setCurrentIndex(proxyIndex, QItemSelectionModel::NoUpdate);
|
|
}
|
|
}
|
|
}
|
|
|
|
QString KDirOperator::makeCompletion(const QString& string)
|
|
{
|
|
if (string.isEmpty()) {
|
|
d->itemView->selectionModel()->clear();
|
|
return QString();
|
|
}
|
|
|
|
prepareCompletionObjects();
|
|
return d->completion.makeCompletion(string);
|
|
}
|
|
|
|
QString KDirOperator::makeDirCompletion(const QString& string)
|
|
{
|
|
if (string.isEmpty()) {
|
|
d->itemView->selectionModel()->clear();
|
|
return QString();
|
|
}
|
|
|
|
prepareCompletionObjects();
|
|
return d->dirCompletion.makeCompletion(string);
|
|
}
|
|
|
|
void KDirOperator::prepareCompletionObjects()
|
|
{
|
|
if (d->itemView == 0) {
|
|
return;
|
|
}
|
|
|
|
if (d->completeListDirty) { // create the list of all possible completions
|
|
const KFileItemList itemList = d->dirLister->items();
|
|
foreach (const KFileItem &item, itemList) {
|
|
d->completion.addItem(item.name());
|
|
if (item.isDir()) {
|
|
d->dirCompletion.addItem(item.name());
|
|
}
|
|
}
|
|
d->completeListDirty = false;
|
|
}
|
|
}
|
|
|
|
void KDirOperator::slotCompletionMatch(const QString& match)
|
|
{
|
|
setCurrentItem(match);
|
|
emit completion(match);
|
|
}
|
|
|
|
void KDirOperator::setupActions()
|
|
{
|
|
d->actionCollection = new KActionCollection(this);
|
|
d->actionCollection->setObjectName("KDirOperator::actionCollection");
|
|
|
|
d->actionMenu = new KActionMenu(i18n("Menu"), this);
|
|
d->actionCollection->addAction("popupMenu", d->actionMenu);
|
|
|
|
QAction* upAction = d->actionCollection->addAction(KStandardAction::Up, "up", this, SLOT(cdUp()));
|
|
upAction->setText(i18n("Parent Folder"));
|
|
|
|
d->actionCollection->addAction(KStandardAction::Back, "back", this, SLOT(back()));
|
|
|
|
d->actionCollection->addAction(KStandardAction::Forward, "forward", this, SLOT(forward()));
|
|
|
|
QAction* homeAction = d->actionCollection->addAction(KStandardAction::Home, "home", this, SLOT(home()));
|
|
homeAction->setText(i18n("Home Folder"));
|
|
|
|
KAction* reloadAction = d->actionCollection->addAction(KStandardAction::Redisplay, "reload", this, SLOT(rereadDir()));
|
|
reloadAction->setText(i18n("Reload"));
|
|
reloadAction->setShortcut(KStandardShortcut::shortcut(KStandardShortcut::Reload));
|
|
|
|
KAction* mkdirAction = new KAction(i18n("New Folder..."), this);
|
|
d->actionCollection->addAction("mkdir", mkdirAction);
|
|
mkdirAction->setIcon(KIcon(QLatin1String("folder-new")));
|
|
connect(mkdirAction, SIGNAL(triggered(bool)), this, SLOT(mkdir()));
|
|
|
|
KAction* trash = new KAction(i18n("Move to Trash"), this);
|
|
d->actionCollection->addAction("trash", trash);
|
|
trash->setIcon(KIcon("user-trash"));
|
|
trash->setShortcut(QKeySequence(Qt::Key_Delete));
|
|
connect(trash, SIGNAL(triggered(bool)), SLOT(trashSelected()));
|
|
|
|
KAction* action = new KAction(i18n("Delete"), this);
|
|
d->actionCollection->addAction("delete", action);
|
|
action->setIcon(KIcon("edit-delete"));
|
|
action->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Delete));
|
|
connect(action, SIGNAL(triggered(bool)), this, SLOT(deleteSelected()));
|
|
|
|
// the sort menu actions
|
|
KActionMenu *sortMenu = new KActionMenu(i18n("Sorting"), this);
|
|
d->actionCollection->addAction("sorting menu", sortMenu);
|
|
|
|
KToggleAction *byNameAction = new KToggleAction(i18n("By Name"), this);
|
|
d->actionCollection->addAction("by name", byNameAction);
|
|
connect(byNameAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortByName()));
|
|
|
|
KToggleAction *bySizeAction = new KToggleAction(i18n("By Size"), this);
|
|
d->actionCollection->addAction("by size", bySizeAction);
|
|
connect(bySizeAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortBySize()));
|
|
|
|
KToggleAction *byDateAction = new KToggleAction(i18n("By Date"), this);
|
|
d->actionCollection->addAction("by date", byDateAction);
|
|
connect(byDateAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortByDate()));
|
|
|
|
KToggleAction *byTypeAction = new KToggleAction(i18n("By Type"), this);
|
|
d->actionCollection->addAction("by type", byTypeAction);
|
|
connect(byTypeAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortByType()));
|
|
|
|
KToggleAction *descendingAction = new KToggleAction(i18n("Descending"), this);
|
|
d->actionCollection->addAction("descending", descendingAction);
|
|
connect(descendingAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotSortReversed(bool)));
|
|
|
|
KToggleAction *dirsFirstAction = new KToggleAction(i18n("Folders First"), this);
|
|
d->actionCollection->addAction("dirs first", dirsFirstAction);
|
|
connect(dirsFirstAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotToggleDirsFirst()));
|
|
|
|
QActionGroup* sortGroup = new QActionGroup(this);
|
|
byNameAction->setActionGroup(sortGroup);
|
|
bySizeAction->setActionGroup(sortGroup);
|
|
byDateAction->setActionGroup(sortGroup);
|
|
byTypeAction->setActionGroup(sortGroup);
|
|
|
|
d->decorationMenu = new KActionMenu(i18n("Icon Position"), this);
|
|
d->actionCollection->addAction("decoration menu", d->decorationMenu);
|
|
|
|
d->leftAction = new KToggleAction(i18n("Next to File Name"), this);
|
|
d->actionCollection->addAction("decorationAtLeft", d->leftAction);
|
|
connect(d->leftAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotChangeDecorationPosition()));
|
|
|
|
KToggleAction *topAction = new KToggleAction(i18n("Above File Name"), this);
|
|
d->actionCollection->addAction("decorationAtTop", topAction);
|
|
connect(topAction, SIGNAL(triggered(bool)), this, SLOT(_k_slotChangeDecorationPosition()));
|
|
|
|
d->decorationMenu->addAction(d->leftAction);
|
|
d->decorationMenu->addAction(topAction);
|
|
|
|
QActionGroup* decorationGroup = new QActionGroup(this);
|
|
d->leftAction->setActionGroup(decorationGroup);
|
|
topAction->setActionGroup(decorationGroup);
|
|
|
|
KToggleAction *shortAction = new KToggleAction(i18n("Short View"), this);
|
|
d->actionCollection->addAction("short view", shortAction);
|
|
shortAction->setIcon(KIcon(QLatin1String("view-list-icons")));
|
|
connect(shortAction, SIGNAL(triggered()), SLOT(_k_slotSimpleView()));
|
|
|
|
KToggleAction *detailedAction = new KToggleAction(i18n("Detailed View"), this);
|
|
d->actionCollection->addAction("detailed view", detailedAction);
|
|
detailedAction->setIcon(KIcon(QLatin1String("view-list-details")));
|
|
connect(detailedAction, SIGNAL(triggered()), SLOT(_k_slotDetailedView()));
|
|
|
|
QActionGroup* viewGroup = new QActionGroup(this);
|
|
shortAction->setActionGroup(viewGroup);
|
|
detailedAction->setActionGroup(viewGroup);
|
|
|
|
KToggleAction *showHiddenAction = new KToggleAction(i18n("Show Hidden Files"), this);
|
|
d->actionCollection->addAction("show hidden", showHiddenAction);
|
|
connect(showHiddenAction, SIGNAL(toggled(bool)), SLOT(_k_slotToggleHidden(bool)));
|
|
|
|
KToggleAction *previewAction = new KToggleAction(i18n("Show Aside Preview"), this);
|
|
d->actionCollection->addAction("preview", previewAction);
|
|
connect(previewAction, SIGNAL(toggled(bool)),
|
|
SLOT(_k_togglePreview(bool)));
|
|
|
|
KToggleAction *inlinePreview = new KToggleAction(KIcon("view-preview"),
|
|
i18n("Show Preview"), this);
|
|
d->actionCollection->addAction("inline preview", inlinePreview);
|
|
connect(inlinePreview, SIGNAL(toggled(bool)), SLOT(_k_toggleInlinePreviews(bool)));
|
|
|
|
KAction *fileManager = new KAction(i18n("Open File Manager"), this);
|
|
d->actionCollection->addAction("file manager", fileManager);
|
|
fileManager->setIcon(KIcon(QLatin1String("system-file-manager")));
|
|
connect(fileManager, SIGNAL(triggered()), SLOT(_k_slotOpenFileManager()));
|
|
|
|
action = new KAction(i18n("Properties"), this);
|
|
d->actionCollection->addAction("properties", action);
|
|
action->setIcon(KIcon("document-properties"));
|
|
action->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Return));
|
|
connect(action, SIGNAL(triggered(bool)), this, SLOT(_k_slotProperties()));
|
|
|
|
// the view menu actions
|
|
KActionMenu* viewMenu = new KActionMenu(i18n("&View"), this);
|
|
d->actionCollection->addAction("view menu", viewMenu);
|
|
viewMenu->addAction(shortAction);
|
|
viewMenu->addAction(detailedAction);
|
|
// TODO: QAbstractItemView does not offer an action collection. Provide
|
|
// an interface to add a custom action collection.
|
|
|
|
d->newFileMenu = new KNewFileMenu(d->actionCollection, "new", this);
|
|
connect(d->newFileMenu, SIGNAL(directoryCreated(KUrl)), this, SLOT(_k_slotDirectoryCreated(KUrl)));
|
|
|
|
d->actionCollection->addAssociatedWidget(this);
|
|
foreach (QAction* action, d->actionCollection->actions())
|
|
action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
|
}
|
|
|
|
void KDirOperator::setupMenu()
|
|
{
|
|
setupMenu(SortActions | ViewActions | FileActions);
|
|
}
|
|
|
|
void KDirOperator::setupMenu(int whichActions)
|
|
{
|
|
// first fill the submenus (sort and view)
|
|
KActionMenu *sortMenu = static_cast<KActionMenu*>(d->actionCollection->action("sorting menu"));
|
|
sortMenu->menu()->clear();
|
|
sortMenu->addAction(d->actionCollection->action("by name"));
|
|
sortMenu->addAction(d->actionCollection->action("by size"));
|
|
sortMenu->addAction(d->actionCollection->action("by date"));
|
|
sortMenu->addAction(d->actionCollection->action("by type"));
|
|
sortMenu->addSeparator();
|
|
sortMenu->addAction(d->actionCollection->action("descending"));
|
|
sortMenu->addAction(d->actionCollection->action("dirs first"));
|
|
|
|
// now plug everything into the popupmenu
|
|
d->actionMenu->menu()->clear();
|
|
if (whichActions & NavActions) {
|
|
d->actionMenu->addAction(d->actionCollection->action("up"));
|
|
d->actionMenu->addAction(d->actionCollection->action("back"));
|
|
d->actionMenu->addAction(d->actionCollection->action("forward"));
|
|
d->actionMenu->addAction(d->actionCollection->action("home"));
|
|
d->actionMenu->addSeparator();
|
|
}
|
|
|
|
if (whichActions & FileActions) {
|
|
d->actionMenu->addAction(d->actionCollection->action("new"));
|
|
if (d->currUrl.isLocalFile() && !(QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
|
|
d->actionMenu->addAction(d->actionCollection->action("trash"));
|
|
}
|
|
KConfigGroup cg(KGlobal::config(), QLatin1String("KDE"));
|
|
const bool del = !d->currUrl.isLocalFile() ||
|
|
(QApplication::keyboardModifiers() & Qt::ShiftModifier) ||
|
|
cg.readEntry("ShowDeleteCommand", false);
|
|
if (del) {
|
|
d->actionMenu->addAction(d->actionCollection->action("delete"));
|
|
}
|
|
d->actionMenu->addSeparator();
|
|
}
|
|
|
|
if (whichActions & SortActions) {
|
|
d->actionMenu->addAction(sortMenu);
|
|
if (!(whichActions & ViewActions)) {
|
|
d->actionMenu->addSeparator();
|
|
}
|
|
}
|
|
|
|
if (whichActions & ViewActions) {
|
|
d->actionMenu->addAction(d->actionCollection->action("view menu"));
|
|
d->actionMenu->addSeparator();
|
|
}
|
|
|
|
if (whichActions & FileActions) {
|
|
d->actionMenu->addAction(d->actionCollection->action("file manager"));
|
|
d->actionMenu->addAction(d->actionCollection->action("properties"));
|
|
}
|
|
}
|
|
|
|
void KDirOperator::updateSortActions()
|
|
{
|
|
if (KFile::isSortByName(d->sorting)) {
|
|
d->actionCollection->action("by name")->setChecked(true);
|
|
} else if (KFile::isSortByDate(d->sorting)) {
|
|
d->actionCollection->action("by date")->setChecked(true);
|
|
} else if (KFile::isSortBySize(d->sorting)) {
|
|
d->actionCollection->action("by size")->setChecked(true);
|
|
} else if (KFile::isSortByType(d->sorting)) {
|
|
d->actionCollection->action("by type")->setChecked(true);
|
|
}
|
|
d->actionCollection->action("descending")->setChecked(d->sorting & QDir::Reversed);
|
|
d->actionCollection->action("dirs first")->setChecked(d->sorting & QDir::DirsFirst);
|
|
}
|
|
|
|
void KDirOperator::updateViewActions()
|
|
{
|
|
KFile::FileView fv = static_cast<KFile::FileView>(d->viewKind);
|
|
|
|
//QAction *separateDirs = d->actionCollection->action("separate dirs");
|
|
//separateDirs->setChecked(KFile::isSeparateDirs(fv) &&
|
|
// separateDirs->isEnabled());
|
|
|
|
d->actionCollection->action("short view")->setChecked(KFile::isSimpleView(fv));
|
|
d->actionCollection->action("detailed view")->setChecked(KFile::isDetailView(fv));
|
|
}
|
|
|
|
void KDirOperator::readConfig(const KConfigGroup& configGroup)
|
|
{
|
|
d->defaultView = 0;
|
|
QString viewStyle = configGroup.readEntry("View Style", "Simple");
|
|
if (viewStyle == QLatin1String("Detail")) {
|
|
d->defaultView |= KFile::Detail;
|
|
} else {
|
|
d->defaultView |= KFile::Simple;
|
|
}
|
|
//if (configGroup.readEntry(QLatin1String("Separate Directories"),
|
|
// DefaultMixDirsAndFiles)) {
|
|
// d->defaultView |= KFile::SeparateDirs;
|
|
//}
|
|
if (configGroup.readEntry(QLatin1String("Show Preview"), false)) {
|
|
d->defaultView |= KFile::PreviewContents;
|
|
}
|
|
|
|
d->previewWidth = configGroup.readEntry(QLatin1String("Preview Width"), 100);
|
|
|
|
if (configGroup.readEntry(QLatin1String("Show hidden files"),
|
|
DefaultShowHidden)) {
|
|
d->actionCollection->action("show hidden")->setChecked(true);
|
|
d->dirLister->setShowingDotFiles(true);
|
|
}
|
|
|
|
QDir::SortFlags sorting = QDir::Name;
|
|
if (configGroup.readEntry(QLatin1String("Sort directories first"),
|
|
DefaultDirsFirst)) {
|
|
sorting |= QDir::DirsFirst;
|
|
}
|
|
QString name = QLatin1String("Name");
|
|
QString sortBy = configGroup.readEntry(QLatin1String("Sort by"), name);
|
|
if (sortBy == name) {
|
|
sorting |= QDir::Name;
|
|
} else if (sortBy == QLatin1String("Size")) {
|
|
sorting |= QDir::Size;
|
|
} else if (sortBy == QLatin1String("Date")) {
|
|
sorting |= QDir::Time;
|
|
} else if (sortBy == QLatin1String("Type")) {
|
|
sorting |= QDir::Type;
|
|
}
|
|
if (configGroup.readEntry(QLatin1String("Sort reversed"), DefaultSortReversed)) {
|
|
sorting |= QDir::Reversed;
|
|
}
|
|
d->updateSorting(sorting);
|
|
|
|
if (d->inlinePreviewState == Private::NotForced) {
|
|
d->showPreviews = configGroup.readEntry(QLatin1String("Previews"), false);
|
|
}
|
|
QStyleOptionViewItem::Position pos = (QStyleOptionViewItem::Position) configGroup.readEntry(QLatin1String("Decoration position"), (int) QStyleOptionViewItem::Left);
|
|
setDecorationPosition(pos);
|
|
}
|
|
|
|
void KDirOperator::writeConfig(KConfigGroup& configGroup)
|
|
{
|
|
QString sortBy = QLatin1String("Name");
|
|
if (KFile::isSortBySize(d->sorting)) {
|
|
sortBy = QLatin1String("Size");
|
|
} else if (KFile::isSortByDate(d->sorting)) {
|
|
sortBy = QLatin1String("Date");
|
|
} else if (KFile::isSortByType(d->sorting)) {
|
|
sortBy = QLatin1String("Type");
|
|
}
|
|
|
|
configGroup.writeEntry(QLatin1String("Sort by"), sortBy);
|
|
|
|
configGroup.writeEntry(QLatin1String("Sort reversed"),
|
|
d->actionCollection->action("descending")->isChecked());
|
|
|
|
configGroup.writeEntry(QLatin1String("Sort directories first"),
|
|
d->actionCollection->action("dirs first")->isChecked());
|
|
|
|
// don't save the preview when an application specific preview is in use.
|
|
bool appSpecificPreview = false;
|
|
if (d->preview) {
|
|
KImageFilePreview *tmp = qobject_cast<KImageFilePreview*>(d->preview);
|
|
appSpecificPreview = (tmp == 0);
|
|
}
|
|
|
|
if (!appSpecificPreview) {
|
|
KToggleAction *previewAction = static_cast<KToggleAction*>(d->actionCollection->action("preview"));
|
|
if (previewAction->isEnabled()) {
|
|
bool hasPreview = previewAction->isChecked();
|
|
configGroup.writeEntry(QLatin1String("Show Preview"), hasPreview);
|
|
|
|
if (hasPreview) {
|
|
// remember the width of the preview widget
|
|
QList<int> sizes = d->splitter->sizes();
|
|
Q_ASSERT(sizes.count() == 2);
|
|
configGroup.writeEntry(QLatin1String("Preview Width"), sizes[1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
configGroup.writeEntry(QLatin1String("Show hidden files"),
|
|
d->actionCollection->action("show hidden")->isChecked());
|
|
|
|
KFile::FileView fv = static_cast<KFile::FileView>(d->viewKind);
|
|
QString style;
|
|
if (KFile::isDetailView(fv))
|
|
style = QLatin1String("Detail");
|
|
else if (KFile::isSimpleView(fv))
|
|
style = QLatin1String("Simple");
|
|
configGroup.writeEntry(QLatin1String("View Style"), style);
|
|
|
|
if (d->inlinePreviewState == Private::NotForced) {
|
|
configGroup.writeEntry(QLatin1String("Previews"), d->showPreviews);
|
|
if (qobject_cast<QListView*>(d->itemView)) {
|
|
configGroup.writeEntry(QLatin1String("listViewIconSize"), d->iconsZoom);
|
|
} else {
|
|
configGroup.writeEntry(QLatin1String("detailedViewIconSize"), d->iconsZoom);
|
|
}
|
|
}
|
|
|
|
configGroup.writeEntry(QLatin1String("Decoration position"), (int) d->decorationPosition);
|
|
}
|
|
|
|
void KDirOperator::resizeEvent(QResizeEvent *)
|
|
{
|
|
// resize the splitter and assure that the width of
|
|
// the preview widget is restored
|
|
QList<int> sizes = d->splitter->sizes();
|
|
const bool hasPreview = (sizes.count() == 2);
|
|
|
|
d->splitter->resize(size());
|
|
sizes = d->splitter->sizes();
|
|
|
|
const bool restorePreviewWidth = hasPreview && (d->previewWidth != sizes[1]);
|
|
if (restorePreviewWidth) {
|
|
const int availableWidth = sizes[0] + sizes[1];
|
|
sizes[0] = availableWidth - d->previewWidth;
|
|
sizes[1] = d->previewWidth;
|
|
d->splitter->setSizes(sizes);
|
|
}
|
|
if (hasPreview) {
|
|
d->previewWidth = sizes[1];
|
|
}
|
|
|
|
if (d->progressBar->parent() == this) {
|
|
// might be reparented into a statusbar
|
|
d->progressBar->move(2, height() - d->progressBar->height() - 2);
|
|
}
|
|
}
|
|
|
|
void KDirOperator::setOnlyDoubleClickSelectsFiles(bool enable)
|
|
{
|
|
d->onlyDoubleClickSelectsFiles = enable;
|
|
// TODO: port to Qt4's QAbstractItemModel
|
|
//if (d->itemView != 0) {
|
|
// d->itemView->setOnlyDoubleClickSelectsFiles(enable);
|
|
//}
|
|
}
|
|
|
|
bool KDirOperator::onlyDoubleClickSelectsFiles() const
|
|
{
|
|
return d->onlyDoubleClickSelectsFiles;
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotStarted()
|
|
{
|
|
progressBar->setValue(0);
|
|
// delay showing the progressbar for one second
|
|
progressDelayTimer->setSingleShot(true);
|
|
progressDelayTimer->start(1000);
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotShowProgress()
|
|
{
|
|
progressBar->raise();
|
|
progressBar->show();
|
|
QApplication::flush();
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotProgress(ulong percent)
|
|
{
|
|
progressBar->setValue(percent);
|
|
// we have to redraw this as fast as possible
|
|
if (progressBar->isVisible())
|
|
QApplication::flush();
|
|
}
|
|
|
|
|
|
void KDirOperator::Private::_k_slotIOFinished()
|
|
{
|
|
progressDelayTimer->stop();
|
|
_k_slotProgress(100);
|
|
progressBar->hide();
|
|
emit parent->finishedLoading();
|
|
parent->resetCursor();
|
|
|
|
if (preview) {
|
|
preview->clearPreview();
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotCanceled()
|
|
{
|
|
emit parent->finishedLoading();
|
|
parent->resetCursor();
|
|
}
|
|
|
|
QProgressBar * KDirOperator::progressBar() const
|
|
{
|
|
return d->progressBar;
|
|
}
|
|
|
|
void KDirOperator::clearHistory()
|
|
{
|
|
qDeleteAll(d->backStack);
|
|
d->backStack.clear();
|
|
d->actionCollection->action("back")->setEnabled(false);
|
|
|
|
qDeleteAll(d->forwardStack);
|
|
d->forwardStack.clear();
|
|
d->actionCollection->action("forward")->setEnabled(false);
|
|
}
|
|
|
|
void KDirOperator::setEnableDirHighlighting(bool enable)
|
|
{
|
|
d->dirHighlighting = enable;
|
|
}
|
|
|
|
bool KDirOperator::dirHighlighting() const
|
|
{
|
|
return d->dirHighlighting;
|
|
}
|
|
|
|
bool KDirOperator::dirOnlyMode() const
|
|
{
|
|
return dirOnlyMode(d->mode);
|
|
}
|
|
|
|
bool KDirOperator::dirOnlyMode(uint mode)
|
|
{
|
|
return ((mode & KFile::Directory) &&
|
|
(mode & (KFile::File | KFile::Files)) == 0);
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotProperties()
|
|
{
|
|
if (itemView == 0) {
|
|
return;
|
|
}
|
|
|
|
const KFileItemList list = parent->selectedItems();
|
|
if (!list.isEmpty()) {
|
|
KPropertiesDialog dialog(list, parent);
|
|
dialog.exec();
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotActivated(const QModelIndex& index)
|
|
{
|
|
const QModelIndex dirIndex = proxyModel->mapToSource(index);
|
|
KFileItem item = dirModel->itemForIndex(dirIndex);
|
|
|
|
const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
|
|
if (item.isNull() || (modifiers & Qt::ShiftModifier) || (modifiers & Qt::ControlModifier))
|
|
return;
|
|
|
|
if (item.isDir()) {
|
|
parent->selectDir(item);
|
|
} else {
|
|
parent->selectFile(item);
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotSelectionChanged()
|
|
{
|
|
if (itemView == 0) {
|
|
return;
|
|
}
|
|
|
|
// In the multiselection mode each selection change is indicated by
|
|
// emitting a null item. Also when the selection has been cleared, a
|
|
// null item must be emitted.
|
|
const bool multiSelectionMode = (itemView->selectionMode() == QAbstractItemView::ExtendedSelection);
|
|
const bool hasSelection = itemView->selectionModel()->hasSelection();
|
|
if (multiSelectionMode || !hasSelection) {
|
|
KFileItem nullItem;
|
|
parent->highlightFile(nullItem);
|
|
}
|
|
else {
|
|
KFileItem selectedItem = parent->selectedItems().first();
|
|
parent->highlightFile(selectedItem);
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_openContextMenu(const QPoint& pos)
|
|
{
|
|
const QModelIndex proxyIndex = itemView->indexAt(pos);
|
|
const QModelIndex dirIndex = proxyModel->mapToSource(proxyIndex);
|
|
KFileItem item = dirModel->itemForIndex(dirIndex);
|
|
|
|
if (item.isNull())
|
|
return;
|
|
|
|
parent->activatedMenu(item, QCursor::pos());
|
|
}
|
|
|
|
void KDirOperator::Private::_k_triggerPreview(const QModelIndex& index)
|
|
{
|
|
if ((preview != 0 && !preview->isHidden()) && index.isValid() && (index.column() == KDirModel::Name)) {
|
|
const QModelIndex dirIndex = proxyModel->mapToSource(index);
|
|
const KFileItem item = dirModel->itemForIndex(dirIndex);
|
|
|
|
if (item.isNull())
|
|
return;
|
|
|
|
if (!item.isDir()) {
|
|
previewUrl = item.url();
|
|
_k_showPreview();
|
|
} else {
|
|
preview->clearPreview();
|
|
}
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_showPreview()
|
|
{
|
|
if (preview != 0) {
|
|
preview->showPreview(previewUrl);
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotSplitterMoved(int, int)
|
|
{
|
|
const QList<int> sizes = splitter->sizes();
|
|
if (sizes.count() == 2) {
|
|
// remember the width of the preview widget (see KDirOperator::resizeEvent())
|
|
previewWidth = sizes[1];
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_assureVisibleSelection()
|
|
{
|
|
if (itemView == 0) {
|
|
return;
|
|
}
|
|
|
|
QItemSelectionModel* selModel = itemView->selectionModel();
|
|
if (selModel->hasSelection()) {
|
|
const QModelIndex index = selModel->currentIndex();
|
|
itemView->scrollTo(index, QAbstractItemView::EnsureVisible);
|
|
_k_triggerPreview(index);
|
|
}
|
|
}
|
|
|
|
|
|
void KDirOperator::Private::_k_synchronizeSortingState(int logicalIndex, Qt::SortOrder order)
|
|
{
|
|
QDir::SortFlags newSort = sorting & ~(QDirSortMask | QDir::Reversed);
|
|
|
|
switch (logicalIndex) {
|
|
case KDirModel::Name:
|
|
newSort |= QDir::Name;
|
|
break;
|
|
case KDirModel::Size:
|
|
newSort |= QDir::Size;
|
|
break;
|
|
case KDirModel::ModifiedTime:
|
|
newSort |= QDir::Time;
|
|
break;
|
|
case KDirModel::Type:
|
|
newSort |= QDir::Type;
|
|
break;
|
|
default:
|
|
Q_ASSERT(false);
|
|
}
|
|
|
|
if (order == Qt::DescendingOrder) {
|
|
newSort |= QDir::Reversed;
|
|
}
|
|
|
|
updateSorting(newSort);
|
|
|
|
QMetaObject::invokeMethod(parent, "_k_assureVisibleSelection", Qt::QueuedConnection);
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotChangeDecorationPosition()
|
|
{
|
|
if (!itemView) {
|
|
return;
|
|
}
|
|
|
|
QListView *view = qobject_cast<QListView*>(itemView);
|
|
|
|
if (!view) {
|
|
return;
|
|
}
|
|
|
|
const bool leftChecked = actionCollection->action("decorationAtLeft")->isChecked();
|
|
|
|
if (leftChecked) {
|
|
decorationPosition = QStyleOptionViewItem::Left;
|
|
view->setFlow(QListView::TopToBottom);
|
|
} else {
|
|
decorationPosition = QStyleOptionViewItem::Top;
|
|
view->setFlow(QListView::LeftToRight);
|
|
}
|
|
|
|
updateListViewGrid();
|
|
|
|
itemView->update();
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotExpandToUrl(const QModelIndex &index)
|
|
{
|
|
QTreeView *treeView = qobject_cast<QTreeView*>(itemView);
|
|
|
|
if (!treeView) {
|
|
return;
|
|
}
|
|
|
|
const KFileItem item = dirModel->itemForIndex(index);
|
|
|
|
if (item.isNull()) {
|
|
return;
|
|
}
|
|
|
|
if (!item.isDir()) {
|
|
const QModelIndex proxyIndex = proxyModel->mapFromSource(index);
|
|
|
|
KUrl::List::Iterator it = itemsToBeSetAsCurrent.begin();
|
|
while (it != itemsToBeSetAsCurrent.end()) {
|
|
const KUrl url = *it;
|
|
if (url.isParentOf(item.url())) {
|
|
const KFileItem _item = dirLister->findByUrl(url);
|
|
if (!_item.isNull() && _item.isDir()) {
|
|
const QModelIndex _index = dirModel->indexForItem(_item);
|
|
const QModelIndex _proxyIndex = proxyModel->mapFromSource(_index);
|
|
treeView->expand(_proxyIndex);
|
|
|
|
// if we have expanded the last parent of this item, select it
|
|
if (item.url().directory() == url.path(KUrl::RemoveTrailingSlash)) {
|
|
treeView->selectionModel()->select(proxyIndex, QItemSelectionModel::Select);
|
|
}
|
|
}
|
|
it = itemsToBeSetAsCurrent.erase(it);
|
|
} else {
|
|
++it;
|
|
}
|
|
}
|
|
} else if (!itemsToBeSetAsCurrent.contains(item.url())) {
|
|
itemsToBeSetAsCurrent << item.url();
|
|
}
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotItemsChanged()
|
|
{
|
|
completeListDirty = true;
|
|
}
|
|
|
|
void KDirOperator::Private::updateListViewGrid()
|
|
{
|
|
if (!itemView) {
|
|
return;
|
|
}
|
|
|
|
QListView *view = qobject_cast<QListView*>(itemView);
|
|
|
|
if (!view) {
|
|
return;
|
|
}
|
|
|
|
const bool leftChecked = actionCollection->action("decorationAtLeft")->isChecked();
|
|
|
|
if (leftChecked) {
|
|
view->setGridSize(QSize());
|
|
KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate*>(view->itemDelegate());
|
|
if (delegate) {
|
|
delegate->setMaximumSize(QSize());
|
|
}
|
|
} else {
|
|
const QFontMetrics metrics(itemView->viewport()->font());
|
|
int size = itemView->iconSize().height() + metrics.height() * 2;
|
|
// some heuristics for good looking. let's guess width = height * (3 / 2) is nice
|
|
view->setGridSize(QSize(size * (3.0 / 2.0), size + metrics.height()));
|
|
KFileItemDelegate *delegate = qobject_cast<KFileItemDelegate*>(view->itemDelegate());
|
|
if (delegate) {
|
|
delegate->setMaximumSize(QSize(size * (3.0 / 2.0), size + metrics.height()));
|
|
}
|
|
}
|
|
}
|
|
|
|
int KDirOperator::Private::iconSizeForViewType(QAbstractItemView *itemView) const
|
|
{
|
|
if (!itemView || !configGroup) {
|
|
return 0;
|
|
}
|
|
|
|
if (qobject_cast<QListView*>(itemView)) {
|
|
return configGroup->readEntry("listViewIconSize", 0);
|
|
} else {
|
|
return configGroup->readEntry("detailedViewIconSize", 0);
|
|
}
|
|
}
|
|
|
|
void KDirOperator::setViewConfig(KConfigGroup& configGroup)
|
|
{
|
|
delete d->configGroup;
|
|
d->configGroup = new KConfigGroup(configGroup);
|
|
}
|
|
|
|
KConfigGroup* KDirOperator::viewConfigGroup() const
|
|
{
|
|
return d->configGroup;
|
|
}
|
|
|
|
void KDirOperator::setShowHiddenFiles(bool s)
|
|
{
|
|
d->actionCollection->action("show hidden")->setChecked(s);
|
|
}
|
|
|
|
bool KDirOperator::showHiddenFiles() const
|
|
{
|
|
return d->actionCollection->action("show hidden")->isChecked();
|
|
}
|
|
|
|
QStyleOptionViewItem::Position KDirOperator::decorationPosition() const
|
|
{
|
|
return d->decorationPosition;
|
|
}
|
|
|
|
void KDirOperator::setDecorationPosition(QStyleOptionViewItem::Position position)
|
|
{
|
|
d->decorationPosition = position;
|
|
const bool decorationAtLeft = d->decorationPosition == QStyleOptionViewItem::Left;
|
|
d->actionCollection->action("decorationAtLeft")->setChecked(decorationAtLeft);
|
|
d->actionCollection->action("decorationAtTop")->setChecked(!decorationAtLeft);
|
|
}
|
|
|
|
void KDirOperator::Private::_k_slotDirectoryCreated(const KUrl& url)
|
|
{
|
|
parent->setUrl(url, true);
|
|
}
|
|
|
|
#include "moc_kdiroperator.cpp"
|