Warning, /office/calligra/sheets/doc/Dependencies.dox is written in an unsupported language. File is not indexed.

0001 /**
0002 \page dependencies Dependency Handling
0003 \author Ariya Hidayat (<a href="mailto:ariya@kde.org">ariya@kde.org</a>)
0004 \date 2004
0005 
0006 \par Status:
0007     FINISHED; NEEDS UPDATE (RecalcManager)
0008 
0009 <p>When a cell holds a formula, then it is likely that it depends on other
0010 cell(s) for calculating the result. For example, if cell A11 has the formula
0011 &quot;=SUM(A1:A10)&quot;, this means that values in cells A1, A2, A3, until
0012 A10 must be correctly calculated first before the sum can be obtained for
0013 cell A11. This is called <i>dependency</i>.</p>
0014 
0015 <p>As for now, Calligra Sheets tries to manage dependency by storing the dependent
0016 cells or ranges in the cell itself. This is not too efficient. If a cell
0017 is very simple, i.e. stored only value, not formula, such scheme will just
0018 waste a couple of bytes of pointers for the dependency data structure.
0019 It is much more wiser to simply create one <i>dependency manager</i> for each
0020 worksheet; it should be responsible for maintaining and handling cell
0021 dependencies for that sheet. Also Calligra Sheets always stores ranges which depend
0022 on one particular cell and ranges whose one of its dependent is that cell
0023 (and these are all in the cell structure itself). This is not necessary as
0024 that information is redundant. The dependency manager should be able to handle
0025 both cases.</p>
0026 
0027 <p>Let us have a look at this simple example:</p>
0028 
0029 <table cellspacing="0" cellpadding="3" border="1">
0030 <tr>
0031   <td align="center">&nbsp;</td>
0032   <td align="center">A</td>
0033   <td align="center">B</td>
0034   <td align="center">C</td>
0035   <td align="center">D</td>
0036 </tr>
0037 <tr>
0038   <td align="center">1</td>
0039   <td align="right">14</td>
0040   <td align="right">36</td>
0041   <td align="right">&nbsp;</td>
0042   <td align="right">&nbsp;</td>
0043 </tr>
0044 <tr>
0045   <td align="center">2</td>
0046   <td align="right">3</td>
0047   <td align="right">&nbsp;</td>
0048   <td align="right">&nbsp;</td>
0049   <td align="right">&nbsp;</td>
0050 </tr>
0051 <tr>
0052   <td align="center">3</td>
0053   <td align="right">77</td>
0054   <td align="right">&nbsp;</td>
0055   <td align="right">&nbsp;</td>
0056   <td align="right">&nbsp;</td>
0057 </tr>
0058 <tr>
0059   <td align="center">4</td>
0060   <td align="right">=SUM(<b>A1:A3</b>)</td>
0061   <td align="right">=A4+SUM(<b>B1:B3</b>)</td>
0062   <td align="right">=100*<b>B4</b></td>
0063   <td align="right">&nbsp;</td>
0064 </tr>
0065 </table>
0066 
0067 <p>Such sheet should produce dependencies like:</p>
0068 
0069 <table cellspacing="0" cellpadding="3" border="1">
0070 <tr>
0071   <td><b>Reference</b></td>
0072   <td><b>Dependent(s)</b></td>
0073 </tr>
0074 <tr>
0075   <td>A4</td>
0076   <td>A1:A3</td>
0077 </tr>
0078 <tr>
0079   <td>B4</td>
0080   <td>A4 and B1:B3</td>
0081 </tr>
0082 <tr>
0083   <td>C4</td>
0084   <td>B4</td>
0085 </tr>
0086 </table>
0087 
0088 <p>When we want to recalculate cell B4, from the dependencies shown above we
0089 may know that first we need to know values of cell A4 and range B1:B3. Further on,
0090 cell A4 needs to know values of cells in range A1:A3. Therefore, <i>given one reference
0091 cell</i> (e.g. B4), the dependency manager must be able to <i>return all
0092 dependents, cells and/or ranges</i> (e.g. A4, B1:B3). Do we need to go
0093 recursively when searching for dependencies? That really depends on the
0094 implementation, but it is not a big problem, though.</p>
0095 
0096 <p>In another case, say the user has changed cell A3 so we need to update the
0097 calculation. We should not recalculate the whole sheet because it wastes time.
0098 We just need to recalculate cells that depend on A3, in this case A4, B4 and C4.
0099 So the dependency manager has another responsibility: <i>given a cell</i>
0100 it should <i>find all cells and/or ranges which depend on that particular
0101 cell</i>. It is a matter of iterating over all dependencies and checking
0102 whether the cell is within the dependent(s) and returning the reference cell.
0103 In this example, cell A3 is in the range A1:A3, a dependent range of cell A4.
0104 Hence, we just return A4. Recursive or not, we can either continue finding
0105 dependents of A4 or just stop here.</p>
0106 
0107 <p>Note also that dependency manager should not store cell pointers, but rather
0108 only the location of the cell (i.e. the sheet that owns the cell, row number and
0109 column number). This is because on some cases the dependent cell may not exist
0110 yet. As illustrated in the example, dependents of cell B4 are A4, B1, B2 and B3
0111 but here cells B2 and B3 are still empty. Of course, when we just want to
0112 know which cells we need to recalculate for one reference cell, the dependency
0113 manager is allowed to return only non-empty cells (e.g. A4 and B1 in our case)
0114 as empty cells have no effect and will not be recalculated anyway.</p>
0115 
0116 <p>By the same manner, dependency manager can also held responsible when
0117 chart comes into play. Any charts placed in the sheet (that are actually KChart
0118 parts) depend on some values of the cells. An action by the user to changing
0119 those cells, directly or indirectly, should trigger the update of the respective
0120 charts.</p>
0121 
0122 <p>Inter-sheet dependencies can be well handled if we store the owner of
0123 each dependent. This is not shown yet in the explanation above to avoid
0124 unnecessary complication. But let have one example now: if Sheet2!A1 is
0125 &quot;=SUM(Sheet1!A1:A10)&quot; then changing Sheet1!A1 (the dependent)
0126 means updating Sheet2!A1 (the reference). Of course during recalculation we
0127 must take care that all sheets in the document must be processed, even though
0128 only one single cell in one sheet has been changed.</p>
0129 
0130 */