Spreadsheet: support cell binding
Cell binding allows one to bind a range of cells of one sheet to another
range of cells of an arbitary sheet, including any empty cells in the
range.
The binding is implemented with PropertyExpressionEngine and
PropertySheet::setPathValue(), which binds a special path of
PropertySheet, such as
.cells.Bind.A1.D1
to an expression, such as
tuple(.cells, <<A2>>, <<A5>>)
The A1 and D1 in the example above specifies the binding start and end
cell address. And <<A2>> and <<A5>> are the range of cells to bind to.
Note that you can use any expression that evalutes to string for the
binding destination, e.g. <<A%d>> % B1, which uses the value inside B1
to construct the binding destination. The '.cells' in the tuple shown
above is an example to bind cells of the same PropertySheet. It can be
change to to reference to any other spreadsheet, even those outside the
current document, e.g. Document#Spreadsheet001.cells
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Tools.h>
|
||||
#include "Expression.h"
|
||||
#include "ExpressionParser.h"
|
||||
#include "ExpressionVisitors.h"
|
||||
#include "PropertyExpressionEngine.h"
|
||||
#include "PropertyStandard.h"
|
||||
@@ -477,8 +477,13 @@ void PropertyExpressionEngine::setValue(const ObjectIdentifier & path, std::shar
|
||||
|
||||
// Check if the current expression equals the new one and do nothing if so to reduce unneeded computations
|
||||
ExpressionMap::iterator it = expressions.find(usePath);
|
||||
if(it != expressions.end() && expr == it->second.expression)
|
||||
if(it != expressions.end()
|
||||
&& (expr == it->second.expression ||
|
||||
(expr && it->second.expression
|
||||
&& expr->isSame(*it->second.expression))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (expr) {
|
||||
std::string error = validateExpression(usePath, expr);
|
||||
@@ -488,9 +493,9 @@ void PropertyExpressionEngine::setValue(const ObjectIdentifier & path, std::shar
|
||||
expressions[usePath] = ExpressionInfo(expr);
|
||||
expressionChanged(usePath);
|
||||
signaller.tryInvoke();
|
||||
} else {
|
||||
} else if (it != expressions.end()) {
|
||||
AtomicPropertyChange signaller(*this);
|
||||
expressions.erase(usePath);
|
||||
expressions.erase(it);
|
||||
expressionChanged(usePath);
|
||||
signaller.tryInvoke();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user