X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/475f8b1261a6ea106ca9dd90b625ea95fe63a4c7..9aee5d22513f0367febab54b38b3a7dc58d120bb:/src/kitemviews/kitemlistview.h diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 8f6e11e38..f20180289 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -23,26 +23,27 @@ #ifndef KITEMLISTVIEW_H #define KITEMLISTVIEW_H -#include +#include "dolphin_export.h" -#include +#include #include -#include #include #include +#include #include #include class KItemListController; class KItemListGroupHeaderCreatorBase; class KItemListHeader; +class KItemListHeaderWidget; class KItemListSizeHintResolver; class KItemListRubberBand; class KItemListViewAnimation; class KItemListViewLayouter; class KItemListWidget; +class KItemListWidgetInformant; class KItemListWidgetCreatorBase; -class KItemListViewCreatorBase; class QTimer; /** @@ -52,16 +53,13 @@ class QTimer; * a GraphicsItem. Each visible item is represented by a KItemListWidget. * * The created view must be applied to the KItemListController with - * KItemListController::setView(). For showing a custom model it is not - * mandatory to derive from KItemListView, all that is necessary is - * to set a widget-creator that is capable to create KItemListWidgets - * showing the model items. A widget-creator can be set with - * KItemListView::setWidgetCreator(). + * KItemListController::setView() or with the constructor of + * KItemListController. * * @see KItemListWidget * @see KItemModelBase */ -class LIBDOLPHINPRIVATE_EXPORT KItemListView : public QGraphicsWidget +class DOLPHIN_EXPORT KItemListView : public QGraphicsWidget { Q_OBJECT @@ -72,17 +70,6 @@ public: KItemListView(QGraphicsWidget* parent = 0); virtual ~KItemListView(); - /** - * If the scroll-orientation is vertical, the items are ordered - * from top to bottom (= default setting). If the scroll-orientation - * is horizontal, the items are ordered from left to right. - */ - void setScrollOrientation(Qt::Orientation orientation); - Qt::Orientation scrollOrientation() const; - - void setItemSize(const QSizeF& size); - QSizeF itemSize() const; - /** * Offset of the scrollbar that represents the scroll-orientation * (see setScrollOrientation()). @@ -104,6 +91,8 @@ public: qreal maximumItemOffset() const; + int maximumVisibleItems() const; + void setVisibleRoles(const QList& roles); QList visibleRoles() const; @@ -144,21 +133,40 @@ public: * * itemListView->setWidgetCreator(new KItemListWidgetCreator()); * - * Note that the ownership of the widget creator is not transferred to - * the item-list view: One instance of a widget creator might get shared - * by several item-list view instances. + * The ownership of the widget creator is transferred to + * the item-list view. **/ void setWidgetCreator(KItemListWidgetCreatorBase* widgetCreator); KItemListWidgetCreatorBase* widgetCreator() const; + /** + * Sets the creator that creates a group header. Usually it is sufficient + * to implement a custom header widget X derived from KItemListGroupHeader and + * set the creator by: + * + * itemListView->setGroupHeaderCreator(new KItemListGroupHeaderCreator()); + * + * The ownership of the gropup header creator is transferred to + * the item-list view. + **/ void setGroupHeaderCreator(KItemListGroupHeaderCreatorBase* groupHeaderCreator); KItemListGroupHeaderCreatorBase* groupHeaderCreator() const; - void setStyleOption(const KItemListStyleOption& option); + /** + * @return The basic size of all items. The size of an item may be larger than + * the basic size (see KItemListView::itemSizeHint() and KItemListView::itemRect()). + */ + QSizeF itemSize() const; + const KItemListStyleOption& styleOption() const; - /** @reimp */ - virtual void setGeometry(const QRectF& rect); + virtual void setGeometry(const QRectF& rect) Q_DECL_OVERRIDE; + + /** + * @return The page step which should be used by the vertical scroll bar. + * This is the height of the view except for the header widget. + */ + qreal verticalPageStep() const; /** * @return Index of the item that is below the point \a pos. @@ -184,21 +192,14 @@ public: int lastVisibleIndex() const; /** - * @return Required size for the item with the index \p index. - * Per default KItemListView::itemSize() is returned. - * When reimplementing this method it is recommended to - * also reimplement KItemListView::itemSizeHintUpdateRequired(). - */ - virtual QSizeF itemSizeHint(int index) const; - - /** - * @param itemRanges Items that must be checked for getting the visible roles sizes. - * @return The size of each visible role in case if KItemListView::itemSize() - * is empty. This allows to have dynamic but equal role sizes between - * all items, like used in the classic "table-views". Per default an - * empty hash is returned. + * @return Calculates the required size for all items in the model. + * It might be larger than KItemListView::itemSize(). + * In this case the layout grid will be stretched to assure an + * unclipped item. + * NOTE: the logical height (width) is actually the + * width (height) if the scroll orientation is Qt::Vertical! */ - virtual QHash visibleRolesSizes(const KItemRangeList& itemRanges) const; + void calculateItemSizeHints(QVector& logicalHeightHints, qreal& logicalWidthHint) const; /** * If set to true, items having child-items can be expanded to show the child-items as @@ -253,24 +254,31 @@ public: bool isTransactionActive() const; /** - * Turns on the header if \p show is true. Per default the - * header is not shown. Usually the header is turned on when + * Turns on the header if \p visible is true. Per default the + * header is not visible. Usually the header is turned on when * showing a classic "table-view" to describe the shown columns. */ - void setHeaderShown(bool show); - bool isHeaderShown() const; + void setHeaderVisible(bool visible); + bool isHeaderVisible() const; + + /** + * @return Header of the list. The header is also available if it is not shown + * (see KItemListView::setHeaderShown()). + */ + KItemListHeader* header() const; /** * @return Pixmap that is used for a drag operation based on the - * items given by \a indexes. The default implementation returns - * a null-pixmap. + * items given by \a indexes. */ - virtual QPixmap createDragPixmap(const QSet& indexes) const; + virtual QPixmap createDragPixmap(const KItemSet& indexes) const; /** - * @reimp + * Lets the user edit the role \a role for item with the index \a index. */ - virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); + void editRole(int index, const QByteArray& role); + + virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0) Q_DECL_OVERRIDE; signals: void scrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous); @@ -306,7 +314,42 @@ signals: */ void visibleRolesChanged(const QList& current, const QList& previous); + void roleEditingCanceled(int index, const QByteArray& role, const QVariant& value); + void roleEditingFinished(int index, const QByteArray& role, const QVariant& value); + protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) Q_DECL_OVERRIDE; + void setItemSize(const QSizeF& size); + void setStyleOption(const KItemListStyleOption& option); + + /** + * If the scroll-orientation is vertical, the items are ordered + * from top to bottom (= default setting). If the scroll-orientation + * is horizontal, the items are ordered from left to right. + */ + void setScrollOrientation(Qt::Orientation orientation); + Qt::Orientation scrollOrientation() const; + + /** + * Factory method for creating a default widget-creator. The method will be used + * in case if setWidgetCreator() has not been set by the application. + * @return New instance of the widget-creator that should be used per + * default. + */ + virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const; + + /** + * Factory method for creating a default group-header-creator. The method will be used + * in case if setGroupHeaderCreator() has not been set by the application. + * @return New instance of the group-header-creator that should be used per + * default. + */ + virtual KItemListGroupHeaderCreatorBase* defaultGroupHeaderCreator() const; + + /** + * Is called when creating a new KItemListWidget instance and allows derived + * classes to do a custom initialization. + */ virtual void initializeItemListWidget(KItemListWidget* item); /** @@ -332,28 +375,32 @@ protected: virtual void onTransactionBegin(); virtual void onTransactionEnd(); - virtual bool event(QEvent* event); - virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event); - virtual void dragEnterEvent(QGraphicsSceneDragDropEvent* event); - virtual void dragMoveEvent(QGraphicsSceneDragDropEvent* event); - virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent* event); - virtual void dropEvent(QGraphicsSceneDragDropEvent* event); + virtual bool event(QEvent* event) Q_DECL_OVERRIDE; + virtual void mousePressEvent(QGraphicsSceneMouseEvent* event) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event) Q_DECL_OVERRIDE; + virtual void dragEnterEvent(QGraphicsSceneDragDropEvent* event) Q_DECL_OVERRIDE; + virtual void dragMoveEvent(QGraphicsSceneDragDropEvent* event) Q_DECL_OVERRIDE; + virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent* event) Q_DECL_OVERRIDE; + virtual void dropEvent(QGraphicsSceneDragDropEvent* event) Q_DECL_OVERRIDE; QList visibleItemListWidgets() const; + virtual void updateFont(); + virtual void updatePalette(); + protected slots: virtual void slotItemsInserted(const KItemRangeList& itemRanges); virtual void slotItemsRemoved(const KItemRangeList& itemRanges); virtual void slotItemsMoved(const KItemRange& itemRange, const QList& movedToIndexes); virtual void slotItemsChanged(const KItemRangeList& itemRanges, const QSet& roles); + virtual void slotGroupsChanged(); virtual void slotGroupedSortingChanged(bool current); virtual void slotSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous); virtual void slotSortRoleChanged(const QByteArray& current, const QByteArray& previous); virtual void slotCurrentChanged(int current, int previous); - virtual void slotSelectionChanged(const QSet& current, const QSet& previous); + virtual void slotSelectionChanged(const KItemSet& current, const KItemSet& previous); private slots: void slotAnimationFinished(QGraphicsWidget* widget, @@ -364,22 +411,22 @@ private slots: void slotRubberBandActivationChanged(bool active); /** - * Is invoked if the visible role-width of one role in the header has - * been changed by the user. It is remembered that the user has modified - * the role-width, so that it won't be changed anymore automatically to - * calculate an optimized width. + * Is invoked if the column-width of one role in the header has + * been changed by the user. The automatic resizing of columns + * will be turned off as soon as this method has been called at + * least once. */ - void slotVisibleRoleWidthChanged(const QByteArray& role, - qreal currentWidth, - qreal previousWidth); + void slotHeaderColumnWidthChanged(const QByteArray& role, + qreal currentWidth, + qreal previousWidth); /** - * Is invoked if a visible role has been moved by the user. Applies + * Is invoked if a column has been moved by the user. Applies * the moved role to the view. */ - void slotVisibleRoleMoved(const QByteArray& role, - int currentIndex, - int previousIndex); + void slotHeaderColumnMoved(const QByteArray& role, + int currentIndex, + int previousIndex); /** * Triggers the autoscrolling if autoScroll() is enabled by checking the @@ -396,6 +443,9 @@ private slots: */ void slotGeometryOfGroupHeaderParentChanged(); + void slotRoleEditingCanceled(int index, const QByteArray& role, const QVariant& value); + void slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value); + private: enum LayoutAnimationHint { @@ -480,7 +530,7 @@ private: void updateGroupHeaderLayout(KItemListWidget* widget); /** - * Recycles the group-header from the widget. + * Recycles the group-header for the widget. */ void recycleGroupHeaderForWidget(KItemListWidget* widget); @@ -498,6 +548,12 @@ private: */ int groupIndexForItem(int index) const; + /** + * Updates the alternate background for all visible items. + * @see updateAlternateBackgroundForWidget() + */ + void updateAlternateBackgrounds(); + /** * Updates the alternateBackground-property of the widget dependent * on the state of useAlternateBackgrounds() and the grouping state. @@ -512,39 +568,47 @@ private: bool useAlternateBackgrounds() const; /** - * @return The widths of each visible role that is shown in the KItemListHeader. + * @param itemRanges Items that must be checked for getting the widths of columns. + * @return The preferred width of the column of each visible role. The width will + * be respected if the width of the item size is <= 0 (see + * KItemListView::setItemSize()). Per default an empty hash + * is returned. + */ + QHash preferredColumnWidths(const KItemRangeList& itemRanges) const; + + /** + * Applies the column-widths from m_headerWidget to the layout + * of the view. */ - QHash headerRolesWidths() const; + void applyColumnWidthsFromHeader(); /** - * Updates m_visibleRolesSizes by calling KItemListView::visibleRolesSizes(). - * Nothing will be done if m_itemRect is not empty or custom header-widths - * are used (see m_useHeaderWidths). Also m_strechedVisibleRolesSizes will be adjusted - * to respect the available view-size. + * Applies the column-widths from m_headerWidget to \a widget. */ - void updateVisibleRolesSizes(const KItemRangeList& itemRanges); + void updateWidgetColumnWidths(KItemListWidget* widget); /** - * Convenience method for updateVisibleRoleSizes(KItemRangeList() << KItemRange(0, m_model->count()). + * Updates the preferred column-widths of m_groupHeaderWidget by + * invoking KItemListView::columnWidths(). */ - void updateVisibleRolesSizes(); + void updatePreferredColumnWidths(const KItemRangeList& itemRanges); /** - * Updates m_stretchedVisibleRolesSizes based on m_visibleRolesSizes and the available - * view-size. Nothing will be done if m_itemRect is not empty or custom header-widths - * are used (see m_useHeaderWidths). + * Convenience method for + * updatePreferredColumnWidths(KItemRangeList() << KItemRange(0, m_model->count()). */ - void updateStretchedVisibleRolesSizes(); + void updatePreferredColumnWidths(); /** - * @return Sum of the widths of all visible roles. + * Resizes the column-widths of m_headerWidget based on the preferred widths + * and the vailable view-size. */ - qreal visibleRolesSizesWidthSum() const; + void applyAutomaticColumnWidths(); /** - * @return Sum of the heights of all visible roles. + * @return Sum of the widths of all columns. */ - qreal visibleRolesSizesHeightSum() const; + qreal columnWidthsSum() const; /** * @return Boundaries of the header. An empty rectangle is returned @@ -576,6 +640,16 @@ private: */ bool scrollBarRequired(const QSizeF& size) const; + /** + * Shows a drop-indicator between items dependent on the given + * cursor position. The cursor position is relative the the upper left + * edge of the view. + * @return Index of the item where the dropping is done. An index of -1 + * indicates that the item has been dropped after the last item. + */ + int showDropIndicator(const QPointF& pos); + void hideDropIndicator(); + /** * Applies the height of the group header to the layouter. The height * depends on the used scroll orientation. @@ -598,6 +672,13 @@ private: */ bool hasSiblingSuccessor(int index) const; + /** + * Helper method for slotRoleEditingCanceled() and slotRoleEditingFinished(). + * Disconnects the two Signals "roleEditingCanceled" and + * "roleEditingFinished" + */ + void disconnectRoleEditingSignals(int index); + /** * Helper function for triggerAutoScrolling(). * @param pos Logical position of the mouse relative to the range. @@ -621,6 +702,7 @@ private: bool m_enabledSelectionToggles; bool m_grouped; bool m_supportsItemExpanding; + bool m_editingRole; int m_activeTransactions; // Counter for beginTransaction()/endTransaction() LayoutAnimationHint m_endTransactionAnimationHint; @@ -628,10 +710,8 @@ private: KItemListController* m_controller; KItemModelBase* m_model; QList m_visibleRoles; - QHash m_visibleRolesSizes; - QHash m_stretchedVisibleRolesSizes; - KItemListWidgetCreatorBase* m_widgetCreator; - KItemListGroupHeaderCreatorBase* m_groupHeaderCreator; + mutable KItemListWidgetCreatorBase* m_widgetCreator; + mutable KItemListGroupHeaderCreatorBase* m_groupHeaderCreator; KItemListStyleOption m_styleOption; QHash m_visibleItems; @@ -665,11 +745,22 @@ private: QTimer* m_autoScrollTimer; KItemListHeader* m_header; - bool m_useHeaderWidths; + KItemListHeaderWidget* m_headerWidget; + + // When dragging items into the view where the sort-role of the model + // is empty, a visual indicator should be shown during dragging where + // the dropping will happen. This indicator is specified by an index + // of the item. -1 means that no indicator will be shown at all. + // The m_dropIndicator is set by the KItemListController + // by KItemListView::showDropIndicator() and KItemListView::hideDropIndicator(). + QRectF m_dropIndicator; friend class KItemListContainer; // Accesses scrollBarRequired() + friend class KItemListHeader; // Accesses m_headerWidget friend class KItemListController; friend class KItemListControllerTest; + friend class KItemListViewAccessible; + friend class KItemListAccessibleCell; }; /** @@ -678,7 +769,7 @@ private: * KItemListWidgetCreatorBase and KItemListGroupHeaderCreatorBase. * @internal */ -class LIBDOLPHINPRIVATE_EXPORT KItemListCreatorBase +class DOLPHIN_EXPORT KItemListCreatorBase { public: virtual ~KItemListCreatorBase(); @@ -697,29 +788,58 @@ private: * @brief Base class for creating KItemListWidgets. * * It is recommended that applications simply use the KItemListWidgetCreator-template class. - * For a custom implementation the methods create() and recyle() must be reimplemented. - * The intention of the widget creator is to prevent repetitive and expensive instantiations and - * deletions of KItemListWidgets by recycling existing widget instances. + * For a custom implementation the methods create(), itemSizeHint() and preferredColumnWith() + * must be reimplemented. The intention of the widget creator is to prevent repetitive and + * expensive instantiations and deletions of KItemListWidgets by recycling existing widget + * instances. */ -class LIBDOLPHINPRIVATE_EXPORT KItemListWidgetCreatorBase : public KItemListCreatorBase +class DOLPHIN_EXPORT KItemListWidgetCreatorBase : public KItemListCreatorBase { public: virtual ~KItemListWidgetCreatorBase(); + virtual KItemListWidget* create(KItemListView* view) = 0; + virtual void recycle(KItemListWidget* widget); + + virtual void calculateItemSizeHints(QVector& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const = 0; + + virtual qreal preferredRoleColumnWidth(const QByteArray& role, + int index, + const KItemListView* view) const = 0; }; +/** + * @brief Template class for creating KItemListWidgets. + */ template class KItemListWidgetCreator : public KItemListWidgetCreatorBase { public: + KItemListWidgetCreator(); virtual ~KItemListWidgetCreator(); + virtual KItemListWidget* create(KItemListView* view); + + virtual void calculateItemSizeHints(QVector& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const; + + virtual qreal preferredRoleColumnWidth(const QByteArray& role, + int index, + const KItemListView* view) const; +private: + KItemListWidgetInformant* m_informant; }; +template +KItemListWidgetCreator::KItemListWidgetCreator() : + m_informant(T::createInformant()) +{ +} + template KItemListWidgetCreator::~KItemListWidgetCreator() { + delete m_informant; } template @@ -727,12 +847,26 @@ KItemListWidget* KItemListWidgetCreator::create(KItemListView* view) { KItemListWidget* widget = static_cast(popRecycleableWidget()); if (!widget) { - widget = new T(view); + widget = new T(m_informant, view); addCreatedWidget(widget); } return widget; } +template +void KItemListWidgetCreator::calculateItemSizeHints(QVector& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const +{ + return m_informant->calculateItemSizeHints(logicalHeightHints, logicalWidthHint, view); +} + +template +qreal KItemListWidgetCreator::preferredRoleColumnWidth(const QByteArray& role, + int index, + const KItemListView* view) const +{ + return m_informant->preferredRoleColumnWidth(role, index, view); +} + /** * @brief Base class for creating KItemListGroupHeaders. * @@ -741,7 +875,7 @@ KItemListWidget* KItemListWidgetCreator::create(KItemListView* view) * The intention of the group-header creator is to prevent repetitive and expensive instantiations and * deletions of KItemListGroupHeaders by recycling existing header instances. */ -class LIBDOLPHINPRIVATE_EXPORT KItemListGroupHeaderCreatorBase : public KItemListCreatorBase +class DOLPHIN_EXPORT KItemListGroupHeaderCreatorBase : public KItemListCreatorBase { public: virtual ~KItemListGroupHeaderCreatorBase();