File indexing completed on 2024-04-28 16:21:21

0001 /* This file is part of the KDE project
0002    Copyright 2006-2007 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
0003    Copyright 2004 Tomas Mecir <mecirt@gmail.com>
0004 
0005    This library is free software; you can redistribute it and/or
0006    modify it under the terms of the GNU Library General Public
0007    License as published by the Free Software Foundation; either
0008    version 2 of the License, or (at your option) any later version.
0009 
0010    This library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public License
0016    along with this library; see the file COPYING.LIB.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018    Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #ifndef KSPREAD_DEPENDENCY_MANAGER_P
0022 #define KSPREAD_DEPENDENCY_MANAGER_P
0023 
0024 // Local
0025 #include "DependencyManager.h"
0026 
0027 #include <QHash>
0028 #include <QList>
0029 
0030 #include "Cell.h"
0031 #include "Region.h"
0032 #include "RTree.h"
0033 
0034 namespace Calligra
0035 {
0036 namespace Sheets
0037 {
0038 class Formula;
0039 class Map;
0040 class Sheet;
0041 
0042 class Q_DECL_HIDDEN DependencyManager::Private
0043 {
0044 public:
0045     /**
0046      * Clears internal structures.
0047      */
0048     void reset();
0049 
0050     /**
0051      * Generates the dependencies of \p cell .
0052      * First, it removes the old providing region. Then, the new providing
0053      * region is computed. Finally, adds \p cell as consumer and the new
0054      * providing region to the data structures.
0055      * \see removeDependencies
0056      * \see computeDependencies
0057      */
0058     void generateDependencies(const Cell& cell, const Formula& formula);
0059 
0060     /**
0061      * Computes the reference depth.
0062      * Depth means the maximum depth of all cells this cell depends on plus one,
0063      * while a cell, which do not refer to other cells, has a depth
0064      * of zero.
0065      *
0066      * Examples:
0067      * \li A1: '=1.0'
0068      * \li A2: '=A1+A1'
0069      * \li A3: '=A1+A1+A2'
0070      *
0071      * \li depth(A1) = 0
0072      * \li depth(A2) = 1
0073      * \li depth(A3) = 2
0074      */
0075     int computeDepth(Cell cell) const;
0076 
0077     /**
0078      * Used in the recalculation events for changed regions.
0079      * Determines the reference depth for each position in \p region .
0080      *
0081      * \see computeDepth
0082      * \see generateDepths(Cell cell)
0083      */
0084     void generateDepths(const Region& region);
0085 
0086     /**
0087      * Generates the depth of cell and all of its consumers.
0088      * Calls itself recursively for the cell's consuming cells.
0089      */
0090     void generateDepths(Cell cell, QSet<Cell>& computedDepths);
0091 
0092     /**
0093      * Returns the region, that consumes the value of \p cell.
0094      * \see DependencyManager::consumingRegion(const Cell&)
0095      * \return region consuming \p cell 's value
0096      */
0097     Region consumingRegion(const Cell& cell) const;
0098 
0099     void namedAreaModified(const QString& name);
0100 
0101     /**
0102      * Removes all dependencies of \p cell .
0103      */
0104     void removeDependencies(const Cell& cell);
0105 
0106     /**
0107      * Removes the depths of \p cell and all its consumers.
0108      */
0109     void removeDepths(const Cell& cell);
0110 
0111     /**
0112      * Computes and stores the dependencies.
0113      *
0114      * Parses \p formula and adds each contained reference to a
0115      * cell, a cell range or a named area to the providing regions
0116      * of \p cell.
0117      * Additionally, the opposite direction is also stored:
0118      * Each consumed region, i.e. each reference, points to \p cell.
0119      *
0120      * The \p formula has to belong to \p cell. It would have been
0121      * possible to look it up from \p cell, but is passed separately
0122      * for performance reasons.
0123      * Do not call this method for a \p cell not containing a \p formula.
0124      */
0125     void computeDependencies(const Cell& cell, const Formula& formula);
0126 
0127     enum Direction { Forward, Backward };
0128     /**
0129      * Removes the circular dependency flag from \p region and all their dependencies.
0130      */
0131     void removeCircularDependencyFlags(const Region& region, Direction direction);
0132 
0133     /**
0134      * For debugging/testing purposes.
0135      */
0136     void dump() const;
0137 
0138     const Map* map;
0139     // stores providing regions ordered by their consuming cell locations
0140     // use QMap rather then QHash cause it's faster for our use-case
0141     QMap<Cell, Region> providers;
0142     // stores consuming cell locations ordered by their providing regions
0143     QHash<Sheet*, RTree<Cell>*> consumers;
0144     // stores consuming cell locations ordered by their providing named area
0145     // (in addition to the general storage of the consuming cell locations)
0146     QHash<QString, QList<Cell> > namedAreaConsumers;
0147     /*
0148      * Stores cells with its reference depth.
0149      * Depth means the maximum depth of all cells this cell depends on plus one,
0150      * while a cell which has a formula without cell references has a depth
0151      * of zero.
0152      *
0153      * Examples:
0154      * \li A1: '=1.0'
0155      * \li A2: '=A1+A1'
0156      * \li A3: '=A1+A1+A2'
0157      *
0158      * \li depth(A1) = 0
0159      * \li depth(A2) = 1
0160      * \li depth(A3) = 2
0161      */
0162     // use QMap rather then QHash cause it's faster for our use-case
0163     QMap<Cell, int> depths;
0164 };
0165 
0166 } // namespace Sheets
0167 } // namespace Calligra
0168 
0169 #endif // KSPREAD_DEPENDENCY_MANAGER_P