File indexing completed on 2024-05-19 15:46:52

0001 /*
0002     SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KDEVPLATFORM_PLUGIN_EXPANDING_WIDGET_MODEL_H
0008 #define KDEVPLATFORM_PLUGIN_EXPANDING_WIDGET_MODEL_H
0009 
0010 #include <QAbstractTableModel>
0011 #include <QPointer>
0012 
0013 class ExpandingDelegate;
0014 class ExpandingTree;
0015 
0016 class QTreeView;
0017 
0018 /**
0019  * Cares about expanding/un-expanding items in a tree-view together with ExpandingDelegate
0020  */
0021 class ExpandingWidgetModel
0022     : public QAbstractTableModel
0023 {
0024     Q_OBJECT
0025 public:
0026 
0027     explicit ExpandingWidgetModel(QWidget* parent);
0028     ~ExpandingWidgetModel() override;
0029 
0030     enum ExpandingType {
0031         NotExpandable = 0,
0032         Expandable,
0033         Expanded
0034     };
0035 
0036     ///The following three are convenience-functions for the current item that could be replaced by the later ones
0037     ///@return whether the current item can be expanded
0038     bool canExpandCurrentItem() const;
0039     ///@return whether the current item can be collapsed
0040     bool canCollapseCurrentItem() const;
0041     ///Expand/collapse the current item
0042     void setCurrentItemExpanded(bool);
0043 
0044     void clearMatchQualities();
0045 
0046     ///Unexpand all rows and clear all cached information about them(this includes deleting the expanding-widgets)
0047     void clearExpanding();
0048 
0049     ///@return whether the row given through index is expandable
0050     bool isExpandable(const QModelIndex& index) const;
0051 
0052     enum ExpansionType {
0053         NotExpanded = 0,
0054         ExpandDownwards, //The additional(expanded) information is shown UNDER the original information
0055         ExpandUpwards //The additional(expanded) information is shown ABOVE the original information
0056     };
0057 
0058     ///Returns whether the given index is currently partially expanded. Does not do any other checks like calling models for data.
0059     ExpansionType isPartiallyExpanded(const QModelIndex& index) const;
0060 
0061     ///@return whether row is currently expanded
0062     bool isExpanded(const QModelIndex& row) const;
0063     ///Change the expand-state of the row given through index. The display will be updated.
0064     void setExpanded(const QModelIndex& index, bool expanded);
0065 
0066     ///Returns the total height added through all open expanding-widgets
0067     int expandingWidgetsHeight() const;
0068 
0069     ///@return the expanding-widget for the given row, if available. Expanding-widgets are in best case available for all expanded rows.
0070     ///This does not return the partially-expand widget.
0071     QWidget* expandingWidget(const QModelIndex& row) const;
0072 
0073     ///Amount by which the height of a row increases when it is partially expanded
0074     int partiallyExpandWidgetHeight() const;
0075     /**
0076      * Notifies underlying models that the item was selected, collapses any previous partially expanded line,
0077      * checks whether this line should be partially expanded, and eventually does it.
0078      * Does nothing when nothing needs to be done.
0079      * Does NOT show the expanding-widget. That is done immediately when painting by ExpandingDelegate,
0080      * to reduce flickering. @see showPartialExpandWidget()
0081      * @param row The row
0082      * */
0083     ///
0084     virtual void rowSelected(const QModelIndex& row);
0085 
0086     /// Returns the rectangle for the partially expanded part of the given row
0087     /// TODO: Do this via QAIM roles?
0088     QRect partialExpandRect(const QModelIndex& row) const;
0089 
0090     /// TODO: Do this via QAIM roles?
0091     QString partialExpandText(const QModelIndex& row) const;
0092 
0093     ///Places and shows the expanding-widget for the given row, if it should be visible and is valid.
0094     ///Also shows the partial-expanding-widget when it should be visible.
0095     void placeExpandingWidget(const QModelIndex& row);
0096 
0097     virtual QTreeView* treeView() const = 0;
0098 
0099     ///Should return true if the given row should be painted like a contained item(as opposed to label-rows etc.)
0100     virtual bool indexIsItem(const QModelIndex& index) const = 0;
0101 
0102     ///Does not request data from index, this only returns local data like highlighting for expanded rows and similar
0103     QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const override;
0104 
0105     ///Returns the first row that is currently partially expanded.
0106     QModelIndex partiallyExpandedRow() const;
0107 
0108     ///Returns the match-color for the given index, or zero if match-quality could not be computed.
0109     uint matchColor(const QModelIndex& index) const;
0110 public Q_SLOTS:
0111     ///Place or hides all expanding-widgets to the correct positions. Should be called after the view was scrolled.
0112     void placeExpandingWidgets();
0113 protected:
0114     /**
0115      * @return the context-match quality from 0 to 10 if it could be determined, else -1
0116      * */
0117     virtual int contextMatchQuality(const QModelIndex& index) const = 0;
0118 
0119     QModelIndex mapFromSource(const QModelIndex& index) const;
0120     QModelIndex mapToSource(const QModelIndex& index) const;
0121 
0122     //Does not update the view
0123     void partiallyUnExpand(const QModelIndex& index);
0124     //Finds out the basic height of the row represented by the given index. Basic means without respecting any expansion.
0125     int basicRowHeight(const QModelIndex& index) const;
0126 private:
0127     friend ExpandingDelegate;
0128     friend ExpandingTree;
0129 
0130     QMap<QModelIndex, ExpansionType> m_partiallyExpanded;
0131     // Store expanding-widgets and cache whether items can be expanded
0132     mutable QMap<QModelIndex, ExpandingType> m_expandState;
0133     QMap<QModelIndex, QPointer<QWidget> > m_expandingWidgets;  //Map rows to their expanding-widgets
0134     QMap<QModelIndex, int> m_contextMatchQualities;   //Map rows to their context-match qualities(undefined if unknown, else 0 to 10). Not used yet, eventually remove.
0135 };
0136 
0137 /**
0138  * Helper-function to merge custom-highlighting variant-lists.
0139  *
0140  * @param strings A list of strings that should be merged
0141  * @param highlights One variant-list for highlighting, as described in the kde header ktextedtor/codecompletionmodel.h
0142  * @param gapBetweenStrings How many signs are inserted between 2 strings?
0143  * */
0144 QList<QVariant> mergeCustomHighlighting(const QStringList& strings, const QList<QVariantList>& highlights, int gapBetweenStrings = 0);
0145 #endif