333 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			333 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**
 | 
						|
  * 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.
 | 
						|
  */
 | 
						|
 | 
						|
#ifndef KCATEGORIZEDVIEW_H
 | 
						|
#define KCATEGORIZEDVIEW_H
 | 
						|
 | 
						|
#include <QListView>
 | 
						|
 | 
						|
#include <groupview_config.h>
 | 
						|
 | 
						|
class KCategoryDrawer;
 | 
						|
 | 
						|
/**
 | 
						|
  * @short Item view for listing items in a categorized fashion optionally
 | 
						|
  *
 | 
						|
  * KCategorizedView basically has the same functionality as QListView, only that it also lets you
 | 
						|
  * layout items in a way that they are categorized visually.
 | 
						|
  *
 | 
						|
  * For it to work you will need to set a KCategorizedSortFilterProxyModel and a KCategoryDrawer
 | 
						|
  * with methods setModel() and setCategoryDrawer() respectively. Also, the model will need to be
 | 
						|
  * flagged as categorized with KCategorizedSortFilterProxyModel::setCategorizedModel(true).
 | 
						|
  *
 | 
						|
  * The way it works (if categorization enabled):
 | 
						|
  *
 | 
						|
  *     - When sorting, it does more things than QListView does. It will ask the model for the
 | 
						|
  *       special role CategorySortRole (@see KCategorizedSortFilterProxyModel). This can return
 | 
						|
  *       a QString or an int in order to tell the view the order of categories. In this sense, for
 | 
						|
  *       instance, if we are sorting by name ascending, "A" would be before than "B". If we are
 | 
						|
  *       sorting by size ascending, 512 bytes would be before 1024 bytes. This way categories are
 | 
						|
  *       also sorted.
 | 
						|
  *
 | 
						|
  *     - When the view has to paint, it will ask the model with the role CategoryDisplayRole
 | 
						|
  *       (@see KCategorizedSortFilterProxyModel). It will for instance return "F" for "foo.pdf" if
 | 
						|
  *       we are sorting by name ascending, or "Small" if a certain item has 100 bytes, for example.
 | 
						|
  *
 | 
						|
  * For drawing categories, KCategoryDrawer will be used. You can inherit this class to do your own
 | 
						|
  * drawing.
 | 
						|
  *
 | 
						|
  * @note All examples cited before talk about filesystems and such, but have present that this
 | 
						|
  *       is a completely generic class, and it can be used for whatever your purpose is. For
 | 
						|
  *       instance when talking about animals, you can separate them by "Mammal" and "Oviparous". In
 | 
						|
  *       this very case, for example, the CategorySortRole and the CategoryDisplayRole could be the
 | 
						|
  *       same ("Mammal" and "Oviparous").
 | 
						|
  *
 | 
						|
  * @note There is a really performance boost if CategorySortRole returns an int instead of a QString.
 | 
						|
  *       Have present that this role is asked (n * log n) times when sorting and compared. Comparing
 | 
						|
  *       ints is always faster than comparing strings, whithout mattering how fast the string
 | 
						|
  *       comparison is. Consider thinking of a way of returning ints instead of QStrings if your
 | 
						|
  *       model can contain a high number of items.
 | 
						|
  *
 | 
						|
  * @warning Note that for really drawing items in blocks you will need some things to be done:
 | 
						|
  *             - The model set to this view has to be (or inherit if you want to do special stuff
 | 
						|
  *               in it) KCategorizedSortFilterProxyModel.
 | 
						|
  *             - This model needs to be set setCategorizedModel to true.
 | 
						|
  *             - Set a category drawer by calling setCategoryDrawer.
 | 
						|
  *
 | 
						|
  * @see KCategorizedSortFilterProxyModel, KCategoryDrawer
 | 
						|
  *
 | 
						|
  * @author Rafael Fernández López <ereslibre@kde.org>
 | 
						|
  */
 | 
						|
class LIBGROUPVIEW_EXPORT KCategorizedView
 | 
						|
	: public QListView
 | 
						|
{
 | 
						|
	Q_OBJECT
 | 
						|
	Q_PROPERTY ( int categorySpacing READ categorySpacing WRITE setCategorySpacing )
 | 
						|
	Q_PROPERTY ( bool alternatingBlockColors READ alternatingBlockColors WRITE setAlternatingBlockColors )
 | 
						|
	Q_PROPERTY ( bool collapsibleBlocks READ collapsibleBlocks WRITE setCollapsibleBlocks )
 | 
						|
 | 
						|
public:
 | 
						|
	KCategorizedView ( QWidget *parent = 0 );
 | 
						|
 | 
						|
	~KCategorizedView();
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void setModel ( QAbstractItemModel *model );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Calls to setGridSizeOwn().
 | 
						|
	  */
 | 
						|
	void setGridSize ( const QSize &size );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * @warning note that setGridSize is not virtual in the base class (QListView), so if you are
 | 
						|
	  *          calling to this method, make sure you have a KCategorizedView pointer around. This
 | 
						|
	  *          means that something like:
 | 
						|
	  * @code
 | 
						|
	  *     QListView *lv = new KCategorizedView();
 | 
						|
	  *     lv->setGridSize(mySize);
 | 
						|
	  * @endcode
 | 
						|
	  *
 | 
						|
	  * will not call to the expected setGridSize method. Instead do something like this:
 | 
						|
	  *
 | 
						|
	  * @code
 | 
						|
	  *     QListView *lv;
 | 
						|
	  *     ...
 | 
						|
	  *     KCategorizedView *cv = qobject_cast<KCategorizedView*>(lv);
 | 
						|
	  *     if (cv) {
 | 
						|
	  *         cv->setGridSizeOwn(mySize);
 | 
						|
	  *     } else {
 | 
						|
	  *         lv->setGridSize(mySize);
 | 
						|
	  *     }
 | 
						|
	  * @endcode
 | 
						|
	  *
 | 
						|
	  * @note this method will call to QListView::setGridSize among other operations.
 | 
						|
	  *
 | 
						|
	  * @since 4.4
 | 
						|
	  */
 | 
						|
	void setGridSizeOwn ( const QSize &size );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual QRect visualRect ( const QModelIndex &index ) const;
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Returns the current category drawer.
 | 
						|
	  */
 | 
						|
	KCategoryDrawer *categoryDrawer() const;
 | 
						|
 | 
						|
	/**
 | 
						|
	  * The category drawer that will be used for drawing categories.
 | 
						|
	  */
 | 
						|
	void setCategoryDrawer ( KCategoryDrawer *categoryDrawer );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * @return Category spacing. The spacing between categories.
 | 
						|
	  *
 | 
						|
	  * @since 4.4
 | 
						|
	  */
 | 
						|
	int categorySpacing() const;
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Stablishes the category spacing. This is the spacing between categories.
 | 
						|
	  *
 | 
						|
	  * @since 4.4
 | 
						|
	  */
 | 
						|
	void setCategorySpacing ( int categorySpacing );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * @return Whether blocks should be drawn with alternating colors.
 | 
						|
	  *
 | 
						|
	  * @since 4.4
 | 
						|
	  */
 | 
						|
	bool alternatingBlockColors() const;
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Sets whether blocks should be drawn with alternating colors.
 | 
						|
	  *
 | 
						|
	  * @since 4.4
 | 
						|
	  */
 | 
						|
	void setAlternatingBlockColors ( bool enable );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * @return Whether blocks can be collapsed or not.
 | 
						|
	  *
 | 
						|
	  * @since 4.4
 | 
						|
	  */
 | 
						|
	bool collapsibleBlocks() const;
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Sets whether blocks can be collapsed or not.
 | 
						|
	  *
 | 
						|
	  * @since 4.4
 | 
						|
	  */
 | 
						|
	void setCollapsibleBlocks ( bool enable );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * @return Block of indexes that are into @p category.
 | 
						|
	  *
 | 
						|
	  * @since 4.5
 | 
						|
	  */
 | 
						|
	QModelIndexList block ( const QString &category );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * @return Block of indexes that are represented by @p representative.
 | 
						|
	  *
 | 
						|
	  * @since 4.5
 | 
						|
	  */
 | 
						|
	QModelIndexList block ( const QModelIndex &representative );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual QModelIndex indexAt ( const QPoint &point ) const;
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void reset();
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Signify that all item delegates size hints return the same fixed size
 | 
						|
	  */
 | 
						|
	void setUniformItemWidths(bool enable);
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Do all item delegate size hints return the same fixed size?
 | 
						|
	  */
 | 
						|
    bool uniformItemWidths() const;
 | 
						|
	
 | 
						|
protected:
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QWidget.
 | 
						|
	  */
 | 
						|
	virtual void paintEvent ( QPaintEvent *event );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QWidget.
 | 
						|
	  */
 | 
						|
	virtual void resizeEvent ( QResizeEvent *event );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void setSelection ( const QRect &rect,
 | 
						|
	                            QItemSelectionModel::SelectionFlags flags );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QWidget.
 | 
						|
	  */
 | 
						|
	virtual void mouseMoveEvent ( QMouseEvent *event );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QWidget.
 | 
						|
	  */
 | 
						|
	virtual void mousePressEvent ( QMouseEvent *event );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QWidget.
 | 
						|
	  */
 | 
						|
	virtual void mouseReleaseEvent ( QMouseEvent *event );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QWidget.
 | 
						|
	  */
 | 
						|
	virtual void leaveEvent ( QEvent *event );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void startDrag ( Qt::DropActions supportedActions );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void dragMoveEvent ( QDragMoveEvent *event );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void dragEnterEvent ( QDragEnterEvent *event );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void dragLeaveEvent ( QDragLeaveEvent *event );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void dropEvent ( QDropEvent *event );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual QModelIndex moveCursor ( CursorAction cursorAction,
 | 
						|
	                                 Qt::KeyboardModifiers modifiers );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void rowsAboutToBeRemoved ( const QModelIndex &parent,
 | 
						|
	                                    int start,
 | 
						|
	                                    int end );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void updateGeometries();
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void currentChanged ( const QModelIndex ¤t,
 | 
						|
	                              const QModelIndex &previous );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void dataChanged ( const QModelIndex &topLeft,
 | 
						|
	                           const QModelIndex &bottomRight );
 | 
						|
 | 
						|
	/**
 | 
						|
	  * Reimplemented from QAbstractItemView.
 | 
						|
	  */
 | 
						|
	virtual void rowsInserted ( const QModelIndex &parent,
 | 
						|
	                            int start,
 | 
						|
	                            int end );
 | 
						|
 | 
						|
protected Q_SLOTS:
 | 
						|
	/**
 | 
						|
	  * @internal
 | 
						|
	  * Reposition items as needed.
 | 
						|
	  */
 | 
						|
	virtual void slotLayoutChanged();
 | 
						|
	virtual void slotCollapseOrExpandClicked ( QModelIndex );
 | 
						|
 | 
						|
private:
 | 
						|
	class Private;
 | 
						|
	Private *const d;
 | 
						|
};
 | 
						|
 | 
						|
#endif // KCATEGORIZEDVIEW_H
 |