/**************************************************************************** | |
** | |
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | |
** All rights reserved. | |
** Contact: Nokia Corporation (qt-info@nokia.com) | |
** | |
** This file is part of the Qt Assistant of the Qt Toolkit. | |
** | |
** $QT_BEGIN_LICENSE:LGPL$ | |
** GNU Lesser General Public License Usage | |
** This file may be used under the terms of the GNU Lesser General Public | |
** License version 2.1 as published by the Free Software Foundation and | |
** appearing in the file LICENSE.LGPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU Lesser | |
** General Public License version 2.1 requirements will be met: | |
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
** | |
** In addition, as a special exception, Nokia gives you certain additional | |
** rights. These rights are described in the Nokia Qt LGPL Exception | |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | |
** | |
** GNU General Public License Usage | |
** Alternatively, this file may be used under the terms of the GNU General | |
** Public License version 3.0 as published by the Free Software Foundation | |
** and appearing in the file LICENSE.GPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU General | |
** Public License version 3.0 requirements will be met: | |
** http://www.gnu.org/copyleft/gpl.html. | |
** | |
** Other Usage | |
** Alternatively, this file may be used in accordance with the terms and | |
** conditions contained in a signed written agreement between you and Nokia. | |
** | |
** | |
** | |
** | |
** | |
** $QT_END_LICENSE$ | |
** | |
****************************************************************************/ | |
#include "bookmarkfiltermodel.h" | |
#include "bookmarkitem.h" | |
#include "bookmarkmodel.h" | |
BookmarkFilterModel::BookmarkFilterModel(QObject *parent) | |
: QAbstractProxyModel(parent) | |
, hideBookmarks(true) | |
, sourceModel(0) | |
{ | |
} | |
void | |
BookmarkFilterModel::setSourceModel(QAbstractItemModel *_sourceModel) | |
{ | |
beginResetModel(); | |
QAbstractProxyModel::setSourceModel(sourceModel); | |
sourceModel = qobject_cast<BookmarkModel*> (_sourceModel); | |
connect(sourceModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, | |
SLOT(changed(QModelIndex, QModelIndex))); | |
connect(sourceModel, SIGNAL(rowsInserted(QModelIndex, int, int)), | |
this, SLOT(rowsInserted(QModelIndex, int, int))); | |
connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), | |
this, SLOT(rowsAboutToBeRemoved(QModelIndex, int, int))); | |
connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, | |
SLOT(rowsRemoved(QModelIndex, int, int))); | |
connect(sourceModel, SIGNAL(layoutAboutToBeChanged()), this, | |
SLOT(layoutAboutToBeChanged())); | |
connect(sourceModel, SIGNAL(layoutChanged()), this, | |
SLOT(layoutChanged())); | |
connect(sourceModel, SIGNAL(modelAboutToBeReset()), this, | |
SLOT(modelAboutToBeReset())); | |
connect(sourceModel, SIGNAL(modelReset()), this, SLOT(modelReset())); | |
if (sourceModel) | |
setupCache(sourceModel->index(0, 0, QModelIndex())); | |
endResetModel(); | |
} | |
int | |
BookmarkFilterModel::rowCount(const QModelIndex &index) const | |
{ | |
Q_UNUSED(index) | |
return cache.count(); | |
} | |
int | |
BookmarkFilterModel::columnCount(const QModelIndex &index) const | |
{ | |
Q_UNUSED(index) | |
if (sourceModel) | |
return sourceModel->columnCount(); | |
return 0; | |
} | |
QModelIndex | |
BookmarkFilterModel::mapToSource(const QModelIndex &proxyIndex) const | |
{ | |
const int row = proxyIndex.row(); | |
if (proxyIndex.isValid() && row >= 0 && row < cache.count()) | |
return cache[row]; | |
return QModelIndex(); | |
} | |
QModelIndex | |
BookmarkFilterModel::mapFromSource(const QModelIndex &sourceIndex) const | |
{ | |
return index(cache.indexOf(sourceIndex), 0, QModelIndex()); | |
} | |
QModelIndex | |
BookmarkFilterModel::parent(const QModelIndex &child) const | |
{ | |
Q_UNUSED(child) | |
return QModelIndex(); | |
} | |
QModelIndex | |
BookmarkFilterModel::index(int row, int column, const QModelIndex &index) const | |
{ | |
Q_UNUSED(index) | |
if (row < 0 || column < 0 || cache.count() <= row | |
|| !sourceModel || sourceModel->columnCount() <= column) { | |
return QModelIndex(); | |
} | |
return createIndex(row, 0); | |
} | |
Qt::DropActions | |
BookmarkFilterModel::supportedDropActions () const | |
{ | |
if (sourceModel) | |
return sourceModel->supportedDropActions(); | |
return Qt::IgnoreAction; | |
} | |
Qt::ItemFlags | |
BookmarkFilterModel::flags(const QModelIndex &index) const | |
{ | |
if (sourceModel) | |
return sourceModel->flags(index); | |
return Qt::NoItemFlags; | |
} | |
QVariant | |
BookmarkFilterModel::data(const QModelIndex &index, int role) const | |
{ | |
if (sourceModel) | |
return sourceModel->data(mapToSource(index), role); | |
return QVariant(); | |
} | |
bool | |
BookmarkFilterModel::setData(const QModelIndex &index, const QVariant &value, | |
int role) | |
{ | |
if (sourceModel) | |
return sourceModel->setData(mapToSource(index), value, role); | |
return false; | |
} | |
void | |
BookmarkFilterModel::filterBookmarks() | |
{ | |
if (sourceModel) { | |
beginResetModel(); | |
hideBookmarks = true; | |
setupCache(sourceModel->index(0, 0, QModelIndex())); | |
endResetModel(); | |
} | |
} | |
void | |
BookmarkFilterModel::filterBookmarkFolders() | |
{ | |
if (sourceModel) { | |
beginResetModel(); | |
hideBookmarks = false; | |
setupCache(sourceModel->index(0, 0, QModelIndex())); | |
endResetModel(); | |
} | |
} | |
void | |
BookmarkFilterModel::changed(const QModelIndex &topLeft, | |
const QModelIndex &bottomRight) | |
{ | |
emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight)); | |
} | |
void | |
BookmarkFilterModel::rowsInserted(const QModelIndex &parent, int start, int end) | |
{ | |
if (!sourceModel) | |
return; | |
QModelIndex cachePrevious = parent; | |
if (BookmarkItem *parentItem = sourceModel->itemFromIndex(parent)) { | |
BookmarkItem *newItem = parentItem->child(start); | |
// iterate over tree hirarchie to find the previous folder | |
for (int i = 0; i < parentItem->childCount(); ++i) { | |
if (BookmarkItem *child = parentItem->child(i)) { | |
const QModelIndex &tmp = sourceModel->indexFromItem(child); | |
if (tmp.data(UserRoleFolder).toBool() && child != newItem) | |
cachePrevious = tmp; | |
} | |
} | |
const QModelIndex &newIndex = sourceModel->indexFromItem(newItem); | |
const bool isFolder = newIndex.data(UserRoleFolder).toBool(); | |
if ((isFolder && hideBookmarks) || (!isFolder && !hideBookmarks)) { | |
beginInsertRows(mapFromSource(parent), start, end); | |
cache.insert(cache.indexOf(cachePrevious) + 1, newIndex); | |
endInsertRows(); | |
} | |
} | |
} | |
void | |
BookmarkFilterModel::rowsAboutToBeRemoved(const QModelIndex &parent, int start, | |
int end) | |
{ | |
if (!sourceModel) | |
return; | |
if (BookmarkItem *parentItem = sourceModel->itemFromIndex(parent)) { | |
if (BookmarkItem *child = parentItem->child(start)) { | |
indexToRemove = sourceModel->indexFromItem(child); | |
if (cache.contains(indexToRemove)) | |
beginRemoveRows(mapFromSource(parent), start, end); | |
} | |
} | |
} | |
void | |
BookmarkFilterModel::rowsRemoved(const QModelIndex &/*parent*/, int, int) | |
{ | |
if (cache.contains(indexToRemove)) { | |
cache.removeAll(indexToRemove); | |
endRemoveRows(); | |
} | |
} | |
void | |
BookmarkFilterModel::layoutAboutToBeChanged() | |
{ | |
// TODO: ??? | |
} | |
void | |
BookmarkFilterModel::layoutChanged() | |
{ | |
// TODO: ??? | |
} | |
void | |
BookmarkFilterModel::modelAboutToBeReset() | |
{ | |
beginResetModel(); | |
} | |
void | |
BookmarkFilterModel::modelReset() | |
{ | |
if (sourceModel) | |
setupCache(sourceModel->index(0, 0, QModelIndex())); | |
endResetModel(); | |
} | |
void | |
BookmarkFilterModel::setupCache(const QModelIndex &parent) | |
{ | |
cache.clear(); | |
collectItems(parent); | |
} | |
void | |
BookmarkFilterModel::collectItems(const QModelIndex &parent) | |
{ | |
if (parent.isValid()) { | |
bool isFolder = sourceModel->data(parent, UserRoleFolder).toBool(); | |
if ((isFolder && hideBookmarks) || (!isFolder && !hideBookmarks)) | |
cache.append(parent); | |
if (sourceModel->hasChildren(parent)) { | |
for (int i = 0; i < sourceModel->rowCount(parent); ++i) | |
collectItems(sourceModel->index(i, 0, parent)); | |
} | |
} | |
} | |
// -- BookmarkTreeModel | |
BookmarkTreeModel::BookmarkTreeModel(QObject *parent) | |
: QSortFilterProxyModel(parent) | |
{ | |
} | |
int | |
BookmarkTreeModel::columnCount(const QModelIndex &parent) const | |
{ | |
return qMin(1, QSortFilterProxyModel::columnCount(parent)); | |
} | |
bool | |
BookmarkTreeModel::filterAcceptsRow(int row, const QModelIndex &parent) const | |
{ | |
Q_UNUSED(row) | |
BookmarkModel *model = qobject_cast<BookmarkModel*> (sourceModel()); | |
if (model->rowCount(parent) > 0 | |
&& model->data(model->index(row, 0, parent), UserRoleFolder).toBool()) | |
return true; | |
return false; | |
} |