1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
<title>KSpread Development Notes</title>
</head>
<body>
<h1>KSpread Development Notes</h1>
<p>Maintainer: Ariya Hidayat (<a href="mailto:ariya@kde.org">ariya@kde.org</a>)</p>
<p>Some portions by Tomas Mecir (<a href="mailto: mecirt@gmail.com">mecirt@gmail.com</a>)</p>
<p>Revision: September 2004.</p>
<h2>Introduction</h2>
<p>This document contains information about internal structure of KSpread
as well as some notes of upcoming redesign. The sources for this document
are mainly the discussions which take place in calligra-devel mailing-list
and the source code itself.</p>
<h2>Manipulators</h2>
<p>Status: OUTDATED.</p>
<p>Currently, every operation on a cell or on a range of cells is quite complex.
You need to ensure correct repainting, recalculation, iterate on a range and so on.</p>
<p>To address this issue, manipulators shall be implemented. A manipulator will
implement one operation (formatting change, sequence fill, ..., ...).</p>
<p>Basically, usage of a manipulator should look like this:</p>
<p><pre>
Manipulator *manip = manipulatorManager::self()->getManip ("seqfill");
manip->setArgument ("type", 1);
... (more setArgument's)
manip->exec (selection);
</pre></p>
<p>That's all...</p>
<p>What concerns manipulator implementation, you'll derive from the base
manipulator and reimplement constructor and methods initialize()
(called just before the operation starts), processCell(), and maybe
done(). The constructor or initialize() would set some properties for
the cell-walking algorithm, and then it won't care about it anymore.
The base class will walk the range and call processCell() for each
cell, possibly creating it if it doesn't exist (if the manipulator
wants so).There will also be some methods that can be used to process
the whole range or row/column at once, if the manipulator wants to do so
(useful for, say, formatting manipulators that will be able to set attributes
of a whole range or row/col, in accordance with thoughts about format storage
below.</p>
<p>In addition, the manipulator can implement the undo/redo functionality
- the base manipulator will provide some common stuff needed to
accomplish this.</p>
<h2>Selection handling</h2>
<p>Status: OUTDATED.</p>
<p>The selection shall be an instance of some RangeList class,
or however we want to call it - this will contain a list of
cells/ranges/rows/whatever - like current selection, but will contain
more entries. This will allow easy implementation of CTRL-selections and so,
because thanks to manipulators, each operation will automatically support these.</p>
<h2>Repaint Triggering</h2>
<p>Status: OUTDATED.</p>
<p>As mentioned above, the interface between the core and the GUI needs to be kept
at minimum. Also, the number of repaints needs to be as low as possible, and repaints
should be groupped whenever possible. To achieve all this, the following approach
can be used:</p>
<p>When a cell is changed, it calls some method in KSpread::Sheet - valueChanged()
or formattingChanged(). These methods then trigger everything necessary, like
a call to the painting routine or dependency calculation.</p>
<p>This simple system would work on itself, but it would be slow. If you do
a sequence fill on A1:A1000 and you have a SUM(A1:A1000) somewhere, why would
you want to compute that SUM 1000 times, when you can simply compute it after
the sequence fill has been finished? Hence, the sheet will offer some more
methods - disableUpdates(), enableUpdates(), rangeListChanged() and
rangeListFormattingChanged(). All these will be used (solely?) by manipulators,
preferably by the base manipulator class, so that we don't have to call these
functions in each operation. After a call to disableUpdates(), there will
be no repainting and no dependency calculation. Note that a call to
enableUpdates() won't cause any repaints either, as the sheet cannot remember
all the calls (due to loss of range information). Hence, the base manipulator
class needs to call the correct rangeList*Changed method to trigger an
update in an effective way. The base manipulator needs to be configurable by
the manipulators that derive from it, so that it knows whether it changed
cell's content or formatting.</p>
<h2>Value</h2>
<p>Status: FINISHED.<br>
</p>
<p>to be written.</p>
<h2>Commands Based on KCommand<br>
</h2>
<p>Status: OUTDATED.</p>
<p>Until lately, to implement undo and redo, KSpread creates corresponding
KSpreadUndo classes for each action and runs them when the user undoes
those actions. KSpreadUndo also has redo function whose job is to redo
again the action after being undone.</p>
<p>All this needs to be converted to manipulators - these will be KCommand,
hence we should be able to undo/redo every operation (provided that the
corresponding manipulator provides methods to store/recall the undo information).</p>
<h2>Cell Storage</h2>
<p>Status: FINISHED.</p>
<p>to be written.</p>
</body></html>
|