| /**************************************************************************** |
| ** |
| ** 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; |
| } |