File indexing completed on 2024-11-24 05:00:55
0001 /* 0002 This file is part of the KDE project 0003 0004 SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "kfiletreeview_p.h" 0010 0011 #include <QContextMenuEvent> 0012 #include <QDir> 0013 #include <QMenu> 0014 #include <QUrl> 0015 0016 #include <kdirlister.h> 0017 #include <kdirmodel.h> 0018 #include <kdirsortfilterproxymodel.h> 0019 #include <kfileitemdelegate.h> 0020 #include <klocalizedstring.h> 0021 #include <ktoggleaction.h> 0022 0023 class KFileTreeView::Private 0024 { 0025 public: 0026 Private(KFileTreeView *parent) 0027 : q(parent) 0028 { 0029 } 0030 0031 QUrl urlForProxyIndex(const QModelIndex &index) const; 0032 0033 void activated(const QModelIndex &); 0034 void currentChanged(const QModelIndex &, const QModelIndex &); 0035 void expanded(const QModelIndex &); 0036 0037 KFileTreeView *const q; 0038 KDirModel *mSourceModel = nullptr; 0039 KDirSortFilterProxyModel *mProxyModel = nullptr; 0040 }; 0041 0042 QUrl KFileTreeView::Private::urlForProxyIndex(const QModelIndex &index) const 0043 { 0044 const KFileItem item = mSourceModel->itemForIndex(mProxyModel->mapToSource(index)); 0045 0046 return !item.isNull() ? item.url() : QUrl(); 0047 } 0048 0049 void KFileTreeView::Private::activated(const QModelIndex &index) 0050 { 0051 const QUrl url = urlForProxyIndex(index); 0052 if (url.isValid()) { 0053 Q_EMIT q->activated(url); 0054 } 0055 } 0056 0057 void KFileTreeView::Private::currentChanged(const QModelIndex ¤tIndex, const QModelIndex &) 0058 { 0059 const QUrl url = urlForProxyIndex(currentIndex); 0060 if (url.isValid()) { 0061 Q_EMIT q->currentUrlChanged(url); 0062 } 0063 } 0064 0065 void KFileTreeView::Private::expanded(const QModelIndex &baseIndex) 0066 { 0067 QModelIndex index = mProxyModel->mapFromSource(baseIndex); 0068 0069 q->setExpanded(index, true); 0070 q->selectionModel()->clearSelection(); 0071 q->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent); 0072 q->scrollTo(index); 0073 } 0074 0075 KFileTreeView::KFileTreeView(QWidget *parent) 0076 : QTreeView(parent) 0077 , d(new Private(this)) 0078 { 0079 d->mSourceModel = new KDirModel(this); 0080 d->mProxyModel = new KDirSortFilterProxyModel(this); 0081 d->mProxyModel->setSourceModel(d->mSourceModel); 0082 0083 setModel(d->mProxyModel); 0084 setItemDelegate(new KFileItemDelegate(this)); 0085 setLayoutDirection(Qt::LeftToRight); 0086 0087 d->mSourceModel->dirLister()->openUrl(QUrl::fromLocalFile(QDir::root().absolutePath()), KDirLister::Keep); 0088 0089 connect(this, &QAbstractItemView::activated, this, [this](const QModelIndex &index) { 0090 d->activated(index); 0091 }); 0092 0093 connect(selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &previous) { 0094 d->currentChanged(current, previous); 0095 }); 0096 0097 connect(d->mSourceModel, &KDirModel::expand, this, [this](const QModelIndex &index) { 0098 d->expanded(index); 0099 }); 0100 } 0101 0102 KFileTreeView::~KFileTreeView() 0103 { 0104 delete d; 0105 } 0106 0107 QUrl KFileTreeView::currentUrl() const 0108 { 0109 return d->urlForProxyIndex(currentIndex()); 0110 } 0111 0112 QUrl KFileTreeView::selectedUrl() const 0113 { 0114 if (!selectionModel()->hasSelection()) { 0115 return QUrl(); 0116 } 0117 0118 const QItemSelection selection = selectionModel()->selection(); 0119 const QModelIndex firstIndex = selection.indexes().first(); 0120 0121 return d->urlForProxyIndex(firstIndex); 0122 } 0123 0124 QList<QUrl> KFileTreeView::selectedUrls() const 0125 { 0126 QList<QUrl> urls; 0127 0128 if (!selectionModel()->hasSelection()) { 0129 return urls; 0130 } 0131 0132 const QModelIndexList indexes = selectionModel()->selection().indexes(); 0133 foreach (const QModelIndex &index, indexes) { 0134 const QUrl url = d->urlForProxyIndex(index); 0135 if (url.isValid()) { 0136 urls.append(url); 0137 } 0138 } 0139 0140 return urls; 0141 } 0142 0143 QUrl KFileTreeView::rootUrl() const 0144 { 0145 return d->mSourceModel->dirLister()->url(); 0146 } 0147 0148 void KFileTreeView::setDirOnlyMode(bool enabled) 0149 { 0150 d->mSourceModel->dirLister()->setDirOnlyMode(enabled); 0151 d->mSourceModel->dirLister()->openUrl(d->mSourceModel->dirLister()->url()); 0152 } 0153 0154 void KFileTreeView::setShowHiddenFiles(bool enabled) 0155 { 0156 QUrl url = currentUrl(); 0157 d->mSourceModel->dirLister()->setShowHiddenFiles(enabled); 0158 d->mSourceModel->dirLister()->openUrl(d->mSourceModel->dirLister()->url()); 0159 setCurrentUrl(url); 0160 } 0161 0162 void KFileTreeView::setCurrentUrl(const QUrl &url) 0163 { 0164 const QModelIndex baseIndex = d->mSourceModel->indexForUrl(url); 0165 0166 if (!baseIndex.isValid()) { 0167 d->mSourceModel->expandToUrl(url); 0168 return; 0169 } 0170 0171 const QModelIndex proxyIndex = d->mProxyModel->mapFromSource(baseIndex); 0172 selectionModel()->clearSelection(); 0173 selectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::SelectCurrent); 0174 scrollTo(proxyIndex); 0175 } 0176 0177 void KFileTreeView::setRootUrl(const QUrl &url) 0178 { 0179 d->mSourceModel->dirLister()->openUrl(url); 0180 } 0181 0182 void KFileTreeView::contextMenuEvent(QContextMenuEvent *event) 0183 { 0184 QMenu menu; 0185 KToggleAction *showHiddenAction = new KToggleAction(i18n("Show Hidden Folders"), &menu); 0186 showHiddenAction->setChecked(d->mSourceModel->dirLister()->showHiddenFiles()); 0187 connect(showHiddenAction, &QAction::toggled, this, &KFileTreeView::setShowHiddenFiles); 0188 0189 menu.addAction(showHiddenAction); 0190 menu.exec(event->globalPos()); 0191 } 0192 0193 bool KFileTreeView::showHiddenFiles() const 0194 { 0195 return d->mSourceModel->dirLister()->showHiddenFiles(); 0196 } 0197 0198 QSize KFileTreeView::sizeHint() const 0199 { 0200 // This size makes KDirSelectDialog pop up just under 800x600 by default :-) 0201 return QSize(680, 500); 0202 } 0203 0204 #include "moc_kfiletreeview_p.cpp"