File indexing completed on 2024-05-05 16:08:27

0001 /*
0002    This file is part of the KDE project
0003 
0004    Copyright (C) 2007 Tobias Koenig <tokoe@kde.org>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 
0011    This library is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    Library General Public License for more details.
0015 
0016    You should have received a copy of the GNU Library General Public License
0017    along with this library; see the file COPYING.LIB.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019    Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #include "kfiletreeview_p.h"
0023 
0024 #include <QDir>
0025 #include <QContextMenuEvent>
0026 #include <QMenu>
0027 #include <QUrl>
0028 
0029 #include <kdirlister.h>
0030 #include <kdirmodel.h>
0031 #include <kdirsortfilterproxymodel.h>
0032 #include <kfileitemdelegate.h>
0033 #include <klocalizedstring.h>
0034 #include <ktoggleaction.h>
0035 
0036 class Q_DECL_HIDDEN KFileTreeView::Private
0037 {
0038 public:
0039     Private(KFileTreeView *parent)
0040         : q(parent)
0041     {
0042     }
0043 
0044     QUrl urlForProxyIndex(const QModelIndex &index) const;
0045 
0046     void _k_activated(const QModelIndex &);
0047     void _k_currentChanged(const QModelIndex &, const QModelIndex &);
0048     void _k_expanded(const QModelIndex &);
0049 
0050     KFileTreeView *q;
0051     KDirModel *mSourceModel;
0052     KDirSortFilterProxyModel *mProxyModel;
0053 };
0054 
0055 QUrl KFileTreeView::Private::urlForProxyIndex(const QModelIndex &index) const
0056 {
0057     const KFileItem item = mSourceModel->itemForIndex(mProxyModel->mapToSource(index));
0058 
0059     return !item.isNull() ? item.url() : QUrl();
0060 }
0061 
0062 void KFileTreeView::Private::_k_activated(const QModelIndex &index)
0063 {
0064     const QUrl url = urlForProxyIndex(index);
0065     if (url.isValid()) {
0066         emit q->activated(url);
0067     }
0068 }
0069 
0070 void KFileTreeView::Private::_k_currentChanged(const QModelIndex &currentIndex, const QModelIndex &)
0071 {
0072     const QUrl url = urlForProxyIndex(currentIndex);
0073     if (url.isValid()) {
0074         emit q->currentChanged(url);
0075     }
0076 }
0077 
0078 void KFileTreeView::Private::_k_expanded(const QModelIndex &baseIndex)
0079 {
0080     QModelIndex index = mProxyModel->mapFromSource(baseIndex);
0081 
0082     q->selectionModel()->clearSelection();
0083     q->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
0084     q->scrollTo(index);
0085 }
0086 
0087 KFileTreeView::KFileTreeView(QWidget *parent)
0088     : QTreeView(parent), d(new Private(this))
0089 {
0090     d->mSourceModel = new KDirModel(this);
0091     d->mProxyModel = new KDirSortFilterProxyModel(this);
0092     d->mProxyModel->setSourceModel(d->mSourceModel);
0093 
0094     setModel(d->mProxyModel);
0095     setItemDelegate(new KFileItemDelegate(this));
0096     setLayoutDirection(Qt::LeftToRight);
0097 
0098     d->mSourceModel->dirLister()->openUrl(QUrl::fromLocalFile(QDir::root().absolutePath()), KDirLister::Keep);
0099 
0100     connect(this, SIGNAL(activated(QModelIndex)),
0101             this, SLOT(_k_activated(QModelIndex)));
0102     connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
0103             this, SLOT(_k_currentChanged(QModelIndex,QModelIndex)));
0104 
0105     connect(d->mSourceModel, SIGNAL(expand(QModelIndex)),
0106             this, SLOT(_k_expanded(QModelIndex)));
0107 }
0108 
0109 KFileTreeView::~KFileTreeView()
0110 {
0111     delete d;
0112 }
0113 
0114 QUrl KFileTreeView::currentUrl() const
0115 {
0116     return d->urlForProxyIndex(currentIndex());
0117 }
0118 
0119 QUrl KFileTreeView::selectedUrl() const
0120 {
0121     if (!selectionModel()->hasSelection()) {
0122         return QUrl();
0123     }
0124 
0125     const QItemSelection selection = selectionModel()->selection();
0126     const QModelIndex firstIndex = selection.indexes().first();
0127 
0128     return d->urlForProxyIndex(firstIndex);
0129 }
0130 
0131 QList<QUrl> KFileTreeView::selectedUrls() const
0132 {
0133     QList<QUrl> urls;
0134 
0135     if (!selectionModel()->hasSelection()) {
0136         return urls;
0137     }
0138 
0139     const QModelIndexList indexes = selectionModel()->selection().indexes();
0140     foreach (const QModelIndex &index, indexes) {
0141         const QUrl url = d->urlForProxyIndex(index);
0142         if (url.isValid()) {
0143             urls.append(url);
0144         }
0145     }
0146 
0147     return urls;
0148 }
0149 
0150 QUrl KFileTreeView::rootUrl() const
0151 {
0152     return d->mSourceModel->dirLister()->url();
0153 }
0154 
0155 void KFileTreeView::setDirOnlyMode(bool enabled)
0156 {
0157     d->mSourceModel->dirLister()->setDirOnlyMode(enabled);
0158     d->mSourceModel->dirLister()->openUrl(d->mSourceModel->dirLister()->url());
0159 }
0160 
0161 void KFileTreeView::setShowHiddenFiles(bool enabled)
0162 {
0163     QUrl url = currentUrl();
0164     d->mSourceModel->dirLister()->setShowingDotFiles(enabled);
0165     d->mSourceModel->dirLister()->openUrl(d->mSourceModel->dirLister()->url());
0166     setCurrentUrl(url);
0167 }
0168 
0169 void KFileTreeView::setCurrentUrl(const QUrl &url)
0170 {
0171     QModelIndex baseIndex = d->mSourceModel->indexForUrl(url);
0172 
0173     if (!baseIndex.isValid()) {
0174         d->mSourceModel->expandToUrl(url);
0175         return;
0176     }
0177 
0178     QModelIndex proxyIndex = d->mProxyModel->mapFromSource(baseIndex);
0179     selectionModel()->clearSelection();
0180     selectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::SelectCurrent);
0181     scrollTo(proxyIndex);
0182 }
0183 
0184 void KFileTreeView::setRootUrl(const QUrl &url)
0185 {
0186     d->mSourceModel->dirLister()->openUrl(url);
0187 }
0188 
0189 void KFileTreeView::contextMenuEvent(QContextMenuEvent *event)
0190 {
0191     QMenu menu;
0192     KToggleAction *showHiddenAction = new KToggleAction(i18n("Show Hidden Folders"), &menu);
0193     showHiddenAction->setChecked(d->mSourceModel->dirLister()->showingDotFiles());
0194     connect(showHiddenAction, SIGNAL(toggled(bool)), this, SLOT(setShowHiddenFiles(bool)));
0195 
0196     menu.addAction(showHiddenAction);
0197     menu.exec(event->globalPos());
0198 }
0199 
0200 bool KFileTreeView::showHiddenFiles() const
0201 {
0202     return d->mSourceModel->dirLister()->showingDotFiles();
0203 }
0204 
0205 QSize KFileTreeView::sizeHint() const
0206 {
0207     // This size makes KDirSelectDialog pop up just under 800x600 by default :-)
0208     return QSize(680, 500);
0209 }
0210 
0211 #include "moc_kfiletreeview_p.cpp"
0212