aboutsummaryrefslogtreecommitdiff
path: root/depends/groupview/src
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2014-02-04 00:43:18 +0100
committerPetr Mrázek <peterix@gmail.com>2014-02-04 00:43:18 +0100
commita17caba2c9c2aa5960581db01e4b66472a9c019c (patch)
treebc28f52c07bc7917a72649d2877b626e82f1ed9a /depends/groupview/src
parentb4b6091372310f4a811180cffde3ea5611881e6c (diff)
downloadPrismLauncher-a17caba2c9c2aa5960581db01e4b66472a9c019c.tar.gz
PrismLauncher-a17caba2c9c2aa5960581db01e4b66472a9c019c.tar.bz2
PrismLauncher-a17caba2c9c2aa5960581db01e4b66472a9c019c.zip
Nuke.
Diffstat (limited to 'depends/groupview/src')
-rw-r--r--depends/groupview/src/categorizedsortfilterproxymodel.cpp168
-rw-r--r--depends/groupview/src/categorizedsortfilterproxymodel_p.h48
-rw-r--r--depends/groupview/src/categorizedview.cpp1692
-rw-r--r--depends/groupview/src/categorizedview_p.h160
-rw-r--r--depends/groupview/src/categorydrawer.cpp231
5 files changed, 0 insertions, 2299 deletions
diff --git a/depends/groupview/src/categorizedsortfilterproxymodel.cpp b/depends/groupview/src/categorizedsortfilterproxymodel.cpp
deleted file mode 100644
index 09da9dd3..00000000
--- a/depends/groupview/src/categorizedsortfilterproxymodel.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * This file is part of the KDE project
- * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
- * Copyright (C) 2007 John Tapsell <tapsell@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "categorizedsortfilterproxymodel.h"
-#include "categorizedsortfilterproxymodel_p.h"
-
-#include <limits.h>
-
-#include <QItemSelection>
-#include <QStringList>
-#include <QSize>
-
-KCategorizedSortFilterProxyModel::KCategorizedSortFilterProxyModel ( QObject *parent )
- : QSortFilterProxyModel ( parent )
- , d ( new Private() )
-{
-}
-
-KCategorizedSortFilterProxyModel::~KCategorizedSortFilterProxyModel()
-{
- delete d;
-}
-
-void KCategorizedSortFilterProxyModel::sort ( int column, Qt::SortOrder order )
-{
- d->sortColumn = column;
- d->sortOrder = order;
-
- QSortFilterProxyModel::sort ( column, order );
-}
-
-bool KCategorizedSortFilterProxyModel::isCategorizedModel() const
-{
- return d->categorizedModel;
-}
-
-void KCategorizedSortFilterProxyModel::setCategorizedModel ( bool categorizedModel )
-{
- if ( categorizedModel == d->categorizedModel )
- {
- return;
- }
-
- d->categorizedModel = categorizedModel;
-
- invalidate();
-}
-
-int KCategorizedSortFilterProxyModel::sortColumn() const
-{
- return d->sortColumn;
-}
-
-Qt::SortOrder KCategorizedSortFilterProxyModel::sortOrder() const
-{
- return d->sortOrder;
-}
-
-void KCategorizedSortFilterProxyModel::setSortCategoriesByNaturalComparison ( bool sortCategoriesByNaturalComparison )
-{
- if ( sortCategoriesByNaturalComparison == d->sortCategoriesByNaturalComparison )
- {
- return;
- }
-
- d->sortCategoriesByNaturalComparison = sortCategoriesByNaturalComparison;
-
- invalidate();
-}
-
-bool KCategorizedSortFilterProxyModel::sortCategoriesByNaturalComparison() const
-{
- return d->sortCategoriesByNaturalComparison;
-}
-
-bool KCategorizedSortFilterProxyModel::lessThan ( const QModelIndex &left, const QModelIndex &right ) const
-{
- if ( d->categorizedModel )
- {
- int compare = compareCategories ( left, right );
-
- if ( compare > 0 ) // left is greater than right
- {
- return false;
- }
- else if ( compare < 0 ) // left is less than right
- {
- return true;
- }
- }
-
- return subSortLessThan ( left, right );
-}
-
-bool KCategorizedSortFilterProxyModel::subSortLessThan ( const QModelIndex &left, const QModelIndex &right ) const
-{
- return QSortFilterProxyModel::lessThan ( left, right );
-}
-
-int KCategorizedSortFilterProxyModel::compareCategories ( const QModelIndex &left, const QModelIndex &right ) const
-{
- QVariant l = ( left.model() ? left.model()->data ( left, CategorySortRole ) : QVariant() );
- QVariant r = ( right.model() ? right.model()->data ( right, CategorySortRole ) : QVariant() );
-
- Q_ASSERT ( l.isValid() );
- Q_ASSERT ( r.isValid() );
- Q_ASSERT ( l.type() == r.type() );
-
- if ( l.type() == QVariant::String )
- {
- QString lstr = l.toString();
- QString rstr = r.toString();
-
- /*
- if ( d->sortCategoriesByNaturalComparison )
- {
- return KStringHandler::naturalCompare ( lstr, rstr );
- }
- else
- {
- */
- if ( lstr < rstr )
- {
- return -1;
- }
-
- if ( lstr > rstr )
- {
- return 1;
- }
-
- return 0;
- //}
- }
-
- qlonglong lint = l.toLongLong();
- qlonglong rint = r.toLongLong();
-
- if ( lint < rint )
- {
- return -1;
- }
-
- if ( lint > rint )
- {
- return 1;
- }
-
- return 0;
-}
diff --git a/depends/groupview/src/categorizedsortfilterproxymodel_p.h b/depends/groupview/src/categorizedsortfilterproxymodel_p.h
deleted file mode 100644
index d7e7c9a0..00000000
--- a/depends/groupview/src/categorizedsortfilterproxymodel_p.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * This file is part of the KDE project
- * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
- * Copyright (C) 2007 John Tapsell <tapsell@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef KCATEGORIZEDSORTFILTERPROXYMODEL_P_H
-#define KCATEGORIZEDSORTFILTERPROXYMODEL_P_H
-
-class KCategorizedSortFilterProxyModel;
-
-class KCategorizedSortFilterProxyModel::Private
-{
-public:
- Private()
- : sortColumn ( 0 )
- , sortOrder ( Qt::AscendingOrder )
- , categorizedModel ( false )
- , sortCategoriesByNaturalComparison ( true )
- {
- }
-
- ~Private()
- {
- }
-
- int sortColumn;
- Qt::SortOrder sortOrder;
- bool categorizedModel;
- bool sortCategoriesByNaturalComparison;
-};
-
-#endif
diff --git a/depends/groupview/src/categorizedview.cpp b/depends/groupview/src/categorizedview.cpp
deleted file mode 100644
index 1345205c..00000000
--- a/depends/groupview/src/categorizedview.cpp
+++ /dev/null
@@ -1,1692 +0,0 @@
-/**
- * This file is part of the KDE project
- * Copyright (C) 2007, 2009 Rafael Fernández López <ereslibre@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-/**
- * IMPLEMENTATION NOTES:
- *
- * QListView::setRowHidden() and QListView::isRowHidden() are not taken into
- * account. This methods should actually not exist. This effect should be handled
- * by an hypothetical QSortFilterProxyModel which filters out the desired rows.
- *
- * In case this needs to be implemented, contact me, but I consider this a faulty
- * design.
- */
-
-#include "categorizedview.h"
-#include "categorizedview_p.h"
-
-#include <math.h> // trunc on C99 compliant systems
-//#include <kdefakes.h> // trunc for not C99 compliant systems
-
-#include <QPainter>
-#include <QScrollBar>
-#include <QPaintEvent>
-
-#include "categorydrawer.h"
-#include "categorizedsortfilterproxymodel.h"
-
-//BEGIN: Private part
-
-struct KCategorizedView::Private::Item
-{
- Item()
- : topLeft ( QPoint() )
- , size ( QSize() )
- {
- }
-
- QPoint topLeft;
- QSize size;
-};
-
-struct KCategorizedView::Private::Block
-{
- bool operator!= ( const Block &rhs ) const
- {
- return firstIndex != rhs.firstIndex;
- }
-
- static bool lessThan ( const Block &left, const Block &right )
- {
- Q_ASSERT ( left.firstIndex.isValid() );
- Q_ASSERT ( right.firstIndex.isValid() );
- return left.firstIndex.row() < right.firstIndex.row();
- }
-
- QPoint topLeft;
- int height = -1;
- QPersistentModelIndex firstIndex;
- // if we have n elements on this block, and we inserted an element at position i. The quarantine
- // will start at index (i, column, parent). This means that for all elements j where i <= j <= n, the
- // visual rect position of item j will have to be recomputed (cannot use the cached point). The quarantine
- // will only affect the current block, since the rest of blocks can be affected only in the way
- // that the whole block will have different offset, but items will keep the same relative position
- // in terms of their parent blocks.
- QPersistentModelIndex quarantineStart;
- QList<Item> items;
-
- // this affects the whole block, not items separately. items contain the topLeft point relative
- // to the block. Because of insertions or removals a whole block can be moved, so the whole block
- // will enter in quarantine, what is faster than moving all items in absolute terms.
- bool outOfQuarantine = false;
-
- // should we alternate its color ? is just a hint, could not be used
- bool alternate = false;
- bool collapsed = false;
-};
-
-KCategorizedView::Private::Private ( KCategorizedView *q )
- : q ( q )
- , hoveredBlock ( new Block() )
-{
-}
-
-KCategorizedView::Private::~Private()
-{
- delete hoveredBlock;
-}
-
-bool KCategorizedView::Private::isCategorized() const
-{
- return proxyModel && categoryDrawer && proxyModel->isCategorizedModel();
-}
-
-QStyleOptionViewItemV4 KCategorizedView::Private::blockRect ( const QModelIndex &representative )
-{
- QStyleOptionViewItemV4 option ( q->viewOptions() );
- const int height = categoryDrawer->categoryHeight ( representative, option );
- const QString categoryDisplay = representative.data ( KCategorizedSortFilterProxyModel::CategoryDisplayRole ).toString();
- QPoint pos = blockPosition ( categoryDisplay );
- pos.ry() -= height;
- option.rect.setTopLeft ( pos );
- option.rect.setWidth ( viewportWidth() + categoryDrawer->leftMargin() + categoryDrawer->rightMargin() );
- option.rect.setHeight ( height + blockHeight ( categoryDisplay ) );
- option.rect = mapToViewport ( option.rect );
-
- return option;
-}
-
-QPair<QModelIndex, QModelIndex> KCategorizedView::Private::intersectingIndexesWithRect ( const QRect &_rect ) const
-{
- const int rowCount = proxyModel->rowCount();
-
- const QRect rect = _rect.normalized();
-
- // binary search to find out the top border
- int bottom = 0;
- int top = rowCount - 1;
- while ( bottom <= top )
- {
- const int middle = ( bottom + top ) / 2;
- const QModelIndex index = proxyModel->index ( middle, q->modelColumn(), q->rootIndex() );
- QRect itemRect = q->visualRect ( index );
- const int verticalOff = q->verticalOffset();
- const int horizontalOff = q->horizontalOffset();
- itemRect.topLeft().ry() += verticalOff;
- itemRect.topLeft().rx() += horizontalOff;
- itemRect.bottomRight().ry() += verticalOff;
- itemRect.bottomRight().rx() += horizontalOff;
- if ( itemRect.bottomRight().y() <= rect.topLeft().y() )
- {
- bottom = middle + 1;
- }
- else
- {
- top = middle - 1;
- }
- }
-
- const QModelIndex bottomIndex = proxyModel->index ( bottom, q->modelColumn(), q->rootIndex() );
-
- // binary search to find out the bottom border
- bottom = 0;
- top = rowCount - 1;
- while ( bottom <= top )
- {
- const int middle = ( bottom + top ) / 2;
- const QModelIndex index = proxyModel->index ( middle, q->modelColumn(), q->rootIndex() );
- QRect itemRect = q->visualRect ( index );
- const int verticalOff = q->verticalOffset();
- const int horizontalOff = q->horizontalOffset();
- itemRect.topLeft().ry() += verticalOff;
- itemRect.topLeft().rx() += horizontalOff;
- itemRect.bottomRight().ry() += verticalOff;
- itemRect.bottomRight().rx() += horizontalOff;
- if ( itemRect.topLeft().y() <= rect.bottomRight().y() )
- {
- bottom = middle + 1;
- }
- else
- {
- top = middle - 1;
- }
- }
-
- const QModelIndex topIndex = proxyModel->index ( top, q->modelColumn(), q->rootIndex() );
-
- return qMakePair ( bottomIndex, topIndex );
-}
-
-QPoint KCategorizedView::Private::blockPosition ( const QString &category )
-{
- Block &block = blocks[category];
-
- if ( block.outOfQuarantine && !block.topLeft.isNull() )
- {
- return block.topLeft;
- }
-
- QPoint res ( categorySpacing, 0 );
-
- const QModelIndex index = block.firstIndex;
-
- for ( QHash<QString, Private::Block>::Iterator it = blocks.begin(); it != blocks.end(); ++it )
- {
- Block &block = *it;
- const QModelIndex categoryIndex = block.firstIndex;
- if ( index.row() < categoryIndex.row() )
- {
- continue;
- }
- res.ry() += categoryDrawer->categoryHeight ( categoryIndex, q->viewOptions() ) + categorySpacing;
- if ( index.row() == categoryIndex.row() )
- {
- continue;
- }
- res.ry() += blockHeight ( it.key() );
- }
-
- block.outOfQuarantine = true;
- block.topLeft = res;
-
- return res;
-}
-
-int KCategorizedView::Private::blockHeight ( const QString &category )
-{
- Block &block = blocks[category];
-
- if ( block.collapsed )
- {
- return 0;
- }
-
- if ( block.height > -1 )
- {
- return block.height;
- }
-
- const QModelIndex firstIndex = block.firstIndex;
- const QModelIndex lastIndex = proxyModel->index ( firstIndex.row() + block.items.count() - 1, q->modelColumn(), q->rootIndex() );
- const QRect topLeft = q->visualRect ( firstIndex );
- QRect bottomRight = q->visualRect ( lastIndex );
-
- if ( hasGrid() )
- {
- bottomRight.setHeight ( qMax ( bottomRight.height(), q->gridSize().height() ) );
- }
- else
- {
- if ( !q->uniformItemSizes() )
- {
- bottomRight.setHeight ( highestElementInLastRow ( block ) + q->spacing() * 2 );
- }
- }
-
- const int height = bottomRight.bottomRight().y() - topLeft.topLeft().y() + 1;
- block.height = height;
-
- return height;
-}
-
-int KCategorizedView::Private::viewportWidth() const
-{
- return q->viewport()->width() - categorySpacing * 2 - categoryDrawer->leftMargin() - categoryDrawer->rightMargin();
-}
-
-void KCategorizedView::Private::regenerateAllElements()
-{
- for ( QHash<QString, Block>::Iterator it = blocks.begin(); it != blocks.end(); ++it )
- {
- Block &block = *it;
- block.outOfQuarantine = false;
- block.quarantineStart = block.firstIndex;
- block.height = -1;
- }
-}
-
-void KCategorizedView::Private::rowsInserted ( const QModelIndex &parent, int start, int end )
-{
- if ( !isCategorized() )
- {
- return;
- }
-
- for ( int i = start; i <= end; ++i )
- {
- const QModelIndex index = proxyModel->index ( i, q->modelColumn(), parent );
-
- Q_ASSERT ( index.isValid() );
-
- const QString category = categoryForIndex ( index );
-
- Block &block = blocks[category];
-
- //BEGIN: update firstIndex
- // save as firstIndex in block if
- // - it forced the category creation (first element on this category)
- // - it is before the first row on that category
- const QModelIndex firstIndex = block.firstIndex;
- if ( !firstIndex.isValid() || index.row() < firstIndex.row() )
- {
- block.firstIndex = index;
- }
- //END: update firstIndex
-
- Q_ASSERT ( block.firstIndex.isValid() );
-
- const int firstIndexRow = block.firstIndex.row();
-
- block.items.insert ( index.row() - firstIndexRow, Private::Item() );
- block.height = -1;
-
- q->visualRect ( index );
- q->viewport()->update();
- }
-
- //BEGIN: update the items that are in quarantine in affected categories
- {
- const QModelIndex lastIndex = proxyModel->index ( end, q->modelColumn(), parent );
- const QString category = categoryForIndex ( lastIndex );
- Private::Block &block = blocks[category];
- block.quarantineStart = block.firstIndex;
- }
- //END: update the items that are in quarantine in affected categories
-
- //BEGIN: mark as in quarantine those categories that are under the affected ones
- {
- const QModelIndex firstIndex = proxyModel->index ( start, q->modelColumn(), parent );
- const QString category = categoryForIndex ( firstIndex );
- const QModelIndex firstAffectedCategory = blocks[category].firstIndex;
- //BEGIN: order for marking as alternate those blocks that are alternate
- QList<Block> blockList = blocks.values();
- qSort ( blockList.begin(), blockList.end(), Block::lessThan );
- QList<int> firstIndexesRows;
- foreach ( const Block &block, blockList )
- {
- firstIndexesRows << block.firstIndex.row();
- }
- //END: order for marking as alternate those blocks that are alternate
- for ( QHash<QString, Private::Block>::Iterator it = blocks.begin(); it != blocks.end(); ++it )
- {
- Private::Block &block = *it;
- if ( block.firstIndex.row() > firstAffectedCategory.row() )
- {
- block.outOfQuarantine = false;
- block.alternate = firstIndexesRows.indexOf ( block.firstIndex.row() ) % 2;
- }
- else if ( block.firstIndex.row() == firstAffectedCategory.row() )
- {
- block.alternate = firstIndexesRows.indexOf ( block.firstIndex.row() ) % 2;
- }
- }
- }
- //END: mark as in quarantine those categories that are under the affected ones
-}
-
-QRect KCategorizedView::Private::mapToViewport ( const QRect &rect ) const
-{
- const int dx = -q->horizontalOffset();
- const int dy = -q->verticalOffset();
- return rect.adjusted ( dx, dy, dx, dy );
-}
-
-QRect KCategorizedView::Private::mapFromViewport ( const QRect &rect ) const
-{
- const int dx = q->horizontalOffset();
- const int dy = q->verticalOffset();
- return rect.adjusted ( dx, dy, dx, dy );
-}
-
-int KCategorizedView::Private::highestElementInLastRow ( const Block &block ) const
-{
- //Find the highest element in the last row
- const QModelIndex lastIndex = proxyModel->index ( block.firstIndex.row() + block.items.count() - 1, q->modelColumn(), q->rootIndex() );
- const QRect prevRect = q->visualRect ( lastIndex );
- int res = prevRect.height();
- QModelIndex prevIndex = proxyModel->index ( lastIndex.row() - 1, q->modelColumn(), q->rootIndex() );
- if ( !prevIndex.isValid() )
- {
- return res;
- }
- Q_FOREVER
- {
- const QRect tempRect = q->visualRect ( prevIndex );
- if ( tempRect.topLeft().y() < prevRect.topLeft().y() )
- {
- break;
- }
- res = qMax ( res, tempRect.height() );
- if ( prevIndex == block.firstIndex )
- {
- break;
- }
- prevIndex = proxyModel->index ( prevIndex.row() - 1, q->modelColumn(), q->rootIndex() );
- }
-
- return res;
-}
-
-bool KCategorizedView::Private::hasGrid() const
-{
- const QSize gridSize = q->gridSize();
- return gridSize.isValid() && !gridSize.isNull();
-}
-
-QString KCategorizedView::Private::categoryForIndex ( const QModelIndex &index ) const
-{
- const QModelIndex categoryIndex = index.model()->index ( index.row(), proxyModel->sortColumn(), index.parent() );
- return categoryIndex.data ( KCategorizedSortFilterProxyModel::CategoryDisplayRole ).toString();
-}
-
-void KCategorizedView::Private::leftToRightVisualRect ( const QModelIndex &index, Item &item,
- const Block &block, const QPoint &blockPos ) const
-{
- const int firstIndexRow = block.firstIndex.row();
-
- if ( hasGrid() )
- {
- const int relativeRow = index.row() - firstIndexRow;
- const int maxItemsPerRow = qMax ( viewportWidth() / q->gridSize().width(), 1 );
- if ( q->layoutDirection() == Qt::LeftToRight )
- {
- item.topLeft.rx() = ( relativeRow % maxItemsPerRow ) * q->gridSize().width() + blockPos.x() + categoryDrawer->leftMargin();
- }
- else
- {
- item.topLeft.rx() = viewportWidth() - ( ( relativeRow % maxItemsPerRow ) + 1 ) * q->gridSize().width() + categoryDrawer->leftMargin() + categorySpacing;
- }
- item.topLeft.ry() = ( relativeRow / maxItemsPerRow ) * q->gridSize().height();
- }
- else
- {
- if ( q->uniformItemSizes() /*|| q->uniformItemWidths()*/ )
- {
- const int relativeRow = index.row() - firstIndexRow;
- const QSize itemSize = q->sizeHintForIndex ( index );
- //HACK: Why is the -2 needed?
- const int maxItemsPerRow = qMax ( ( viewportWidth() - q->spacing() - 2 ) / ( itemSize.width() + q->spacing() ), 1 );
- if ( q->layoutDirection() == Qt::LeftToRight )
- {
- item.topLeft.rx() = ( relativeRow % maxItemsPerRow ) * itemSize.width() + blockPos.x() + categoryDrawer->leftMargin();
- }
- else
- {
- item.topLeft.rx() = viewportWidth() - ( relativeRow % maxItemsPerRow ) * itemSize.width() + categoryDrawer->leftMargin() + categorySpacing;
- }
- item.topLeft.ry() = ( relativeRow / maxItemsPerRow ) * itemSize.height();
- }
- else
- {
- const QSize currSize = q->sizeHintForIndex ( index );
- if ( index != block.firstIndex )
- {
- const int viewportW = viewportWidth() - q->spacing();
- QModelIndex prevIndex = proxyModel->index ( index.row() - 1, q->modelColumn(), q->rootIndex() );
- QRect prevRect = q->visualRect ( prevIndex );
- prevRect = mapFromViewport ( prevRect );
- if ( ( prevRect.bottomRight().x() + 1 ) + currSize.width() - blockPos.x() + q->spacing() > viewportW )
- {
- // we have to check the whole previous row, and see which one was the
- // highest.
- Q_FOREVER
- {
- prevIndex = proxyModel->index ( prevIndex.row() - 1, q->modelColumn(), q->rootIndex() );
- QRect tempRect = q->visualRect ( prevIndex );
- tempRect = mapFromViewport ( tempRect );
- if ( tempRect.topLeft().y() < prevRect.topLeft().y() )
- {
- break;
- }
- if ( tempRect.bottomRight().y() > prevRect.bottomRight().y() )
- {
- prevRect = tempRect;
- }
- if ( prevIndex == block.firstIndex )
- {
- break;
- }
- }
- if ( q->layoutDirection() == Qt::LeftToRight )
- {
- item.topLeft.rx() = categoryDrawer->leftMargin() + blockPos.x() + q->spacing();
- }
- else
- {
- item.topLeft.rx() = viewportWidth() - currSize.width() + categoryDrawer->leftMargin() + categorySpacing;
- }
- item.topLeft.ry() = ( prevRect.bottomRight().y() + 1 ) + q->spacing() - blockPos.y();
- }
- else
- {
- if ( q->layoutDirection() == Qt::LeftToRight )
- {
- item.topLeft.rx() = ( prevRect.bottomRight().x() + 1 ) + q->spacing();
- }
- else
- {
- item.topLeft.rx() = ( prevRect.bottomLeft().x() - 1 ) - q->spacing() - item.size.width() + categoryDrawer->leftMargin() + categorySpacing;
- }
- item.topLeft.ry() = prevRect.topLeft().y() - blockPos.y();
- }
- }
- else
- {
- if ( q->layoutDirection() == Qt::LeftToRight )
- {
- item.topLeft.rx() = blockPos.x() + categoryDrawer->leftMargin() + q->spacing();
- }
- else
- {
- item.topLeft.rx() = viewportWidth() - currSize.width() + categoryDrawer->leftMargin() + categorySpacing;
- }
- item.topLeft.ry() = q->spacing();
- }
- }
- }
- item.size = q->sizeHintForIndex ( index );
-}
-
-void KCategorizedView::Private::topToBottomVisualRect ( const QModelIndex &index, Item &item,
- const Block &block, const QPoint &blockPos ) const
-{
- const int firstIndexRow = block.firstIndex.row();
-
- if ( hasGrid() )
- {
- const int relativeRow = index.row() - firstIndexRow;
- item.topLeft.rx() = blockPos.x() + categoryDrawer->leftMargin();
- item.topLeft.ry() = relativeRow * q->gridSize().height();
- }
- else
- {
- if ( q->uniformItemSizes() )
- {
- const int relativeRow = index.row() - firstIndexRow;
- const QSize itemSize = q->sizeHintForIndex ( index );
- item.topLeft.rx() = blockPos.x() + categoryDrawer->leftMargin();
- item.topLeft.ry() = relativeRow * itemSize.height();
- }
- else
- {
- if ( index != block.firstIndex )
- {
- QModelIndex prevIndex = proxyModel->index ( index.row() - 1, q->modelColumn(), q->rootIndex() );
- QRect prevRect = q->visualRect ( prevIndex );
- prevRect = mapFromViewport ( prevRect );
- item.topLeft.rx() = blockPos.x() + categoryDrawer->leftMargin() + q->spacing();
- item.topLeft.ry() = ( prevRect.bottomRight().y() + 1 ) + q->spacing() - blockPos.y();
- }
- else
- {
- item.topLeft.rx() = blockPos.x() + categoryDrawer->leftMargin() + q->spacing();
- item.topLeft.ry() = q->spacing();
- }
- }
- }
- item.size = q->sizeHintForIndex ( index );
- item.size.setWidth ( viewportWidth() );
-}
-
-void KCategorizedView::Private::_k_slotCollapseOrExpandClicked ( QModelIndex )
-{
-}
-
-//END: Private part
-
-//BEGIN: Public part
-
-KCategorizedView::KCategorizedView ( QWidget *parent )
- : QListView ( parent )
- , d ( new Private ( this ) )
-{
-}
-
-KCategorizedView::~KCategorizedView()
-{
- delete d;
-}
-
-void KCategorizedView::setModel ( QAbstractItemModel *model )
-{
- if ( d->proxyModel == model )
- {
- return;
- }
-
- d->blocks.clear();
-
- if ( d->proxyModel )
- {
- disconnect ( d->proxyModel, SIGNAL ( layoutChanged() ), this, SLOT ( slotLayoutChanged() ) );
- }
-
- d->proxyModel = dynamic_cast<KCategorizedSortFilterProxyModel*> ( model );
-
- if ( d->proxyModel )
- {
- connect ( d->proxyModel, SIGNAL ( layoutChanged() ), this, SLOT ( slotLayoutChanged() ) );
- }
-
- QListView::setModel ( model );
-
- // if the model already had information inserted, update our data structures to it
- if ( model->rowCount() )
- {
- slotLayoutChanged();
- }
-}
-
-
-void KCategorizedView::setUniformItemWidths(bool enable)
-{
- d->constantItemWidth = enable;
-}
-
-
-bool KCategorizedView::uniformItemWidths() const
-{
- return d->constantItemWidth;
-}
-
-void KCategorizedView::setGridSize ( const QSize &size )
-{
- setGridSizeOwn ( size );
-}
-
-void KCategorizedView::setGridSizeOwn ( const QSize &size )
-{
- d->regenerateAllElements();
- QListView::setGridSize ( size );
-}
-
-QRect KCategorizedView::visualRect ( const QModelIndex &index ) const
-{
- if ( !d->isCategorized() )
- {
- return QListView::visualRect ( index );
- }
-
- if ( !index.isValid() )
- {
- return QRect();
- }
-
- const QString category = d->categoryForIndex ( index );
-
- if ( !d->blocks.contains ( category ) )
- {
- return QRect();
- }
-
- Private::Block &block = d->blocks[category];
- const int firstIndexRow = block.firstIndex.row();
-
- Q_ASSERT ( block.firstIndex.isValid() );
-
- if ( index.row() - firstIndexRow < 0 || index.row() - firstIndexRow >= block.items.count() )
- {
- return QRect();
- }
-
- const QPoint blockPos = d->blockPosition ( category );
-
- Private::Item &ritem = block.items[index.row() - firstIndexRow];
-
- if ( ritem.topLeft.isNull() || ( block.quarantineStart.isValid() &&
- index.row() >= block.quarantineStart.row() ) )
- {
- if ( flow() == LeftToRight )
- {
- d->leftToRightVisualRect ( index, ritem, block, blockPos );
- }
- else
- {
- d->topToBottomVisualRect ( index, ritem, block, blockPos );
- }
-
- //BEGIN: update the quarantine start
- const bool wasLastIndex = ( index.row() == ( block.firstIndex.row() + block.items.count() - 1 ) );
- if ( index.row() == block.quarantineStart.row() )
- {
- if ( wasLastIndex )
- {
- block.quarantineStart = QModelIndex();
- }
- else
- {
- const QModelIndex nextIndex = d->proxyModel->index ( index.row() + 1, modelColumn(), rootIndex() );
- block.quarantineStart = nextIndex;
- }
- }
- //END: update the quarantine start
- }
-
- // we get now the absolute position through the relative position of the parent block. do not
- // save this on ritem, since this would override the item relative position in block terms.
- Private::Item item ( ritem );
- item.topLeft.ry() += blockPos.y();
-
- const QSize sizeHint = item.size;
-
- if ( d->hasGrid() )
- {
- const QSize sizeGrid = gridSize();
- const QSize resultingSize = sizeHint.boundedTo ( sizeGrid );
- QRect res ( item.topLeft.x() + ( ( sizeGrid.width() - resultingSize.width() ) / 2 ),
- item.topLeft.y(), resultingSize.width(), resultingSize.height() );
- if ( block.collapsed )
- {
- // we can still do binary search, while we "hide" items. We move those items in collapsed
- // blocks to the left and set a 0 height.
- res.setLeft ( -resultingSize.width() );
- res.setHeight ( 0 );
- }
- return d->mapToViewport ( res );
- }
-
- QRect res ( item.topLeft.x(), item.topLeft.y(), sizeHint.width(), sizeHint.height() );
- if ( block.collapsed )
- {
- // we can still do binary search, while we "hide" items. We move those items in collapsed
- // blocks to the left and set a 0 height.
- res.setLeft ( -sizeHint.width() );
- res.setHeight ( 0 );
- }
- return d->mapToViewport ( res );
-}
-
-KCategoryDrawer *KCategorizedView::categoryDrawer() const
-{
- return d->categoryDrawer;
-}
-
-void KCategorizedView::setCategoryDrawer ( KCategoryDrawer *categoryDrawer )
-{
- disconnect ( d->categoryDrawer, SIGNAL ( collapseOrExpandClicked ( QModelIndex ) ),
- this, SLOT ( slotCollapseOrExpandClicked ( QModelIndex ) ) );
- d->categoryDrawer = categoryDrawer;
-
- connect ( d->categoryDrawer, SIGNAL ( collapseOrExpandClicked ( QModelIndex ) ),
- this, SLOT ( slotCollapseOrExpandClicked ( QModelIndex ) ) );
-}
-
-int KCategorizedView::categorySpacing() const
-{
- return d->categorySpacing;
-}
-
-void KCategorizedView::setCategorySpacing ( int categorySpacing )
-{
- if ( d->categorySpacing == categorySpacing )
- {
- return;
- }
-
- d->categorySpacing = categorySpacing;
-
- for ( QHash<QString, Private::Block>::Iterator it = d->blocks.begin(); it != d->blocks.end(); ++it )
- {
- Private::Block &block = *it;
- block.outOfQuarantine = false;
- }
-}
-
-bool KCategorizedView::alternatingBlockColors() const
-{
- return d->alternatingBlockColors;
-}
-
-void KCategorizedView::setAlternatingBlockColors ( bool enable )
-{
- d->alternatingBlockColors = enable;
-}
-
-bool KCategorizedView::collapsibleBlocks() const
-{
- return d->collapsibleBlocks;
-}
-
-void KCategorizedView::setCollapsibleBlocks ( bool enable )
-{
- d->collapsibleBlocks = enable;
-}
-
-QModelIndexList KCategorizedView::block ( const QString &category )
-{
- QModelIndexList res;
- const Private::Block &block = d->blocks[category];
- if ( block.height == -1 )
- {
- return res;
- }
- QModelIndex current = block.firstIndex;
- const int first = current.row();
- for ( int i = 1; i <= block.items.count(); ++i )
- {
- if ( current.isValid() )
- {
- res << current;
- }
- current = d->proxyModel->index ( first + i, modelColumn(), rootIndex() );
- }
- return res;
-}
-
-QModelIndexList KCategorizedView::block ( const QModelIndex &representative )
-{
- return block ( representative.data ( KCategorizedSortFilterProxyModel::CategoryDisplayRole ).toString() );
-}
-
-QModelIndex KCategorizedView::indexAt ( const QPoint &point ) const
-{
- if ( !d->isCategorized() )
- {
- return QListView::indexAt ( point );
- }
-
- const int rowCount = d->proxyModel->rowCount();
- if ( !rowCount )
- {
- return QModelIndex();
- }
-
- // Binary search that will try to spot if there is an index under point
- int bottom = 0;
- int top = rowCount - 1;
- while ( bottom <= top )
- {
- const int middle = ( bottom + top ) / 2;
- const QModelIndex index = d->proxyModel->index ( middle, modelColumn(), rootIndex() );
- QRect rect = visualRect ( index );
- const int verticalOff = verticalOffset();
- int horizontalOff = horizontalOffset();
- if ( layoutDirection() == Qt::RightToLeft )
- {