[PATCH] sorted kfiletreeviews
Benjamin K. Stuhl
benjamin.stuhl at colorado.edu
Sun Dec 2 18:58:01 GMT 2007
Hi Rafael,
I saw you wrestling with this, so I thought I'd take a stab at it.
This patch works for me -- the important part is setting _k_expanded()
as a queued slot, so that the proxy model is updated before we try to
map the new index through it. Comments? OK to commit?
Enjoy,
-- BKS
Index: kdelibs/kfile/kfiletreeview.cpp
===================================================================
--- kdelibs/kfile/kfiletreeview.cpp (revision 744111)
+++ kdelibs/kfile/kfiletreeview.cpp (working copy)
@@ -25,6 +25,7 @@
#include <kdirlister.h>
#include <kdirmodel.h>
+#include <kdirsortfilterproxymodel.h>
#include <kfileitemdelegate.h>
#include <kurl.h>
@@ -32,64 +33,77 @@
{
public:
Private(KFileTreeView *parent)
- : mParent(parent)
+ : q(parent)
{
}
- KUrl urlForIndex(const QModelIndex &index) const;
+ KUrl urlForProxyIndex(const QModelIndex &index) const;
void _k_activated(const QModelIndex&);
void _k_currentChanged(const QModelIndex&, const QModelIndex&);
void _k_expanded(const QModelIndex&);
- KFileTreeView *mParent;
- KDirModel *mModel;
+ KFileTreeView *q;
+ KDirModel *mSourceModel;
+ KDirSortFilterProxyModel *mProxyModel;
};
-KUrl KFileTreeView::Private::urlForIndex(const QModelIndex &index) const
+// we need to be able to queue model indicies, so declare it as a Qt metatype
+Q_DECLARE_METATYPE(QModelIndex)
+
+KUrl KFileTreeView::Private::urlForProxyIndex(const QModelIndex &index) const
{
- const KFileItem item = mModel->itemForIndex(index);
+ const KFileItem item = mSourceModel->itemForIndex(mProxyModel->mapToSource(index));
return !item.isNull() ? item.url() : KUrl();
}
void KFileTreeView::Private::_k_activated(const QModelIndex &index)
{
- const KUrl url = urlForIndex(index);
+ const KUrl url = urlForProxyIndex(index);
if (url.isValid())
- emit mParent->activated(url);
+ emit q->activated(url);
}
void KFileTreeView::Private::_k_currentChanged(const QModelIndex ¤tIndex, const QModelIndex&)
{
- const KUrl url = urlForIndex(currentIndex);
+ const KUrl url = urlForProxyIndex(currentIndex);
if (url.isValid())
- emit mParent->currentChanged(url);
+ emit q->currentChanged(url);
}
-void KFileTreeView::Private::_k_expanded(const QModelIndex &index)
+void KFileTreeView::Private::_k_expanded(const QModelIndex &baseIndex)
{
- mParent->selectionModel()->clearSelection();
- mParent->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
- mParent->scrollTo(index);
+ QModelIndex index = mProxyModel->mapFromSource(baseIndex);
+
+ q->selectionModel()->clearSelection();
+ q->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
+ q->scrollTo(index);
}
KFileTreeView::KFileTreeView(QWidget *parent)
: QTreeView(parent), d(new Private(this))
{
- d->mModel = new KDirModel(this);
+ d->mSourceModel = new KDirModel(this);
+ d->mProxyModel = new KDirSortFilterProxyModel(this);
+ d->mProxyModel->setSourceModel(d->mSourceModel);
- setModel(d->mModel);
+ setModel(d->mProxyModel);
setItemDelegate(new KFileItemDelegate(this));
- d->mModel->dirLister()->openUrl(KUrl(QDir::root().absolutePath()), KDirLister::Keep);
+ d->mSourceModel->dirLister()->openUrl(KUrl(QDir::root().absolutePath()), KDirLister::Keep);
connect(this, SIGNAL(activated(const QModelIndex&)),
this, SLOT(_k_activated(const QModelIndex&)));
connect(selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
this, SLOT(_k_currentChanged(const QModelIndex&, const QModelIndex&)));
- connect(d->mModel, SIGNAL(expand(const QModelIndex&)),
- this, SLOT(_k_expanded(const QModelIndex&)));
+
+ // this must be a queued connection, because we need to be able to map indicies
+ // in it, and we can't do that until the expansion is complete
+ // QModelIndex is not registered by default, so do it here
+ qRegisterMetaType<QModelIndex>();
+ connect(d->mSourceModel, SIGNAL(expand(const QModelIndex&)),
+ this, SLOT(_k_expanded(const QModelIndex&)), Qt::QueuedConnection);
}
KFileTreeView::~KFileTreeView()
@@ -99,7 +113,7 @@
KUrl KFileTreeView::currentUrl() const
{
- return d->urlForIndex(currentIndex());
+ return d->urlForProxyIndex(currentIndex());
}
KUrl KFileTreeView::selectedUrl() const
@@ -110,7 +124,7 @@
const QItemSelection selection = selectionModel()->selection();
const QModelIndex firstIndex = selection.indexes().first();
- return d->urlForIndex(firstIndex);
+ return d->urlForProxyIndex(firstIndex);
}
KUrl::List KFileTreeView::selectedUrls() const
@@ -122,7 +136,7 @@
const QModelIndexList indexes = selectionModel()->selection().indexes();
foreach (const QModelIndex index, indexes) {
- const KUrl url = d->urlForIndex(index);
+ const KUrl url = d->urlForProxyIndex(index);
if (url.isValid())
urls.append(url);
}
@@ -132,37 +146,39 @@
KUrl KFileTreeView::rootUrl() const
{
- return d->mModel->dirLister()->url();
+ return d->mSourceModel->dirLister()->url();
}
void KFileTreeView::setDirOnlyMode(bool enabled)
{
- d->mModel->dirLister()->setDirOnlyMode(enabled);
- d->mModel->dirLister()->openUrl(d->mModel->dirLister()->url());
+ d->mSourceModel->dirLister()->setDirOnlyMode(enabled);
+ d->mSourceModel->dirLister()->openUrl(d->mSourceModel->dirLister()->url());
}
void KFileTreeView::setShowHiddenFiles(bool enabled)
{
- d->mModel->dirLister()->setShowingDotFiles(enabled);
- d->mModel->dirLister()->openUrl(d->mModel->dirLister()->url());
+ d->mSourceModel->dirLister()->setShowingDotFiles(enabled);
+ d->mSourceModel->dirLister()->openUrl(d->mSourceModel->dirLister()->url());
}
void KFileTreeView::setCurrentUrl(const KUrl &url)
{
- QModelIndex index = d->mModel->indexForUrl(url);
+ QModelIndex baseIndex = d->mSourceModel->indexForUrl(url);
- if (!index.isValid()) {
- d->mModel->expandToUrl(url);
+ if (!baseIndex.isValid()) {
+ d->mSourceModel->expandToUrl(url);
return;
}
+
+ QModelIndex proxyIndex = d->mProxyModel->mapFromSource(baseIndex);
selectionModel()->clearSelection();
- selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
- scrollTo(index);
+ selectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::SelectCurrent);
+ scrollTo(proxyIndex);
}
void KFileTreeView::setRootUrl(const KUrl &url)
{
- d->mModel->dirLister()->openUrl(url);
+ d->mSourceModel->dirLister()->openUrl(url);
}
#include "kfiletreeview.moc"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20071202/f219f530/attachment.sig>
More information about the kde-core-devel
mailing list