Spreadsheet: Removed own expression parser and instead use the one in App.
This commit is contained in:
@@ -151,17 +151,17 @@ App::DocumentObjectExecReturn *FeatureViewSpreadsheet::execute(void)
|
||||
float coloffset = 0.0;
|
||||
float cellheight = 100;
|
||||
float cellwidth = 100;
|
||||
std::string celltext;
|
||||
std::string celltext;
|
||||
Spreadsheet::Sheet* sheet = static_cast<Spreadsheet::Sheet*>(link);
|
||||
std::vector<std::string> skiplist;
|
||||
for (std::vector<std::string>::const_iterator col = columns.begin(); col != columns.end(); ++col) {
|
||||
for (std::vector<std::string>::const_iterator col = columns.begin(); col != columns.end(); ++col) {
|
||||
// create a group for each column
|
||||
result << " <g id=\"" << ViewName << "_col" << (*col) << "\">" << endl;
|
||||
for (std::vector<int>::const_iterator row = rows.begin(); row != rows.end(); ++row) {
|
||||
// get cell size
|
||||
std::stringstream srow;
|
||||
srow << (*row);
|
||||
Spreadsheet::CellAddress address((*col) + srow.str());
|
||||
App::CellAddress address((*col) + srow.str());
|
||||
cellwidth = sheet->getColumnWidth(address.col());
|
||||
cellheight = sheet->getRowHeight(address.row());
|
||||
celltext = "";
|
||||
@@ -216,7 +216,7 @@ App::DocumentObjectExecReturn *FeatureViewSpreadsheet::execute(void)
|
||||
if (cell->getSpans(rowspan,colspan)) {
|
||||
for (int i=0; i<colspan; ++i) {
|
||||
for (int j=0; j<rowspan; ++j) {
|
||||
Spreadsheet::CellAddress nextcell(address.row()+j,address.col()+i);
|
||||
App::CellAddress nextcell(address.row()+j,address.col()+i);
|
||||
if (i > 0)
|
||||
cellwidth = cellwidth + sheet->getColumnWidth(nextcell.col());
|
||||
if (j > 0)
|
||||
@@ -227,7 +227,7 @@ App::DocumentObjectExecReturn *FeatureViewSpreadsheet::execute(void)
|
||||
}
|
||||
}
|
||||
cell->getAlignment(alignment);
|
||||
}
|
||||
}
|
||||
// skip cell if found in skiplist
|
||||
if (std::find(skiplist.begin(), skiplist.end(), address.toString()) == skiplist.end()) {
|
||||
result << " <rect x=\"" << coloffset << "\" y=\"" << rowoffset << "\" width=\"" << cellwidth
|
||||
@@ -241,7 +241,7 @@ App::DocumentObjectExecReturn *FeatureViewSpreadsheet::execute(void)
|
||||
result << " <text text-anchor=\"end\" style=\"" << textstyle << "\" x=\"" << coloffset + (cellwidth - FontSize.getValue()/2) << "\" y=\"" << rowoffset + 0.75 * cellheight << "\" font-family=\"" ;
|
||||
result << Font.getValue() << "\"" << " font-size=\"" << FontSize.getValue() << "\""
|
||||
<< " fill=\"" << fcolor << "\">" << celltext << "</text>" << endl;
|
||||
}
|
||||
}
|
||||
rowoffset = rowoffset + cellheight;
|
||||
}
|
||||
result << " </g>" << endl;
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include "Sheet.h"
|
||||
#include "SpreadsheetExpression.h"
|
||||
|
||||
|
||||
namespace Spreadsheet {
|
||||
class Module : public Py::ExtensionModule<Module>
|
||||
@@ -46,8 +44,6 @@ PyMODINIT_FUNC initSpreadsheet() {
|
||||
Spreadsheet::PropertySheet::init();
|
||||
|
||||
Spreadsheet::Sheet::init();
|
||||
Spreadsheet::AggregateFunctionExpression::init();
|
||||
Spreadsheet::RangeExpression::init();
|
||||
|
||||
new Spreadsheet::Module();
|
||||
Base::Console().Log("Loading Spreadsheet module... done\n");
|
||||
|
||||
@@ -17,8 +17,6 @@ set(Spreadsheet_LIBS
|
||||
)
|
||||
|
||||
set(Spreadsheet_SRCS
|
||||
SpreadsheetExpression.cpp
|
||||
SpreadsheetExpression.h
|
||||
Cell.cpp
|
||||
Cell.h
|
||||
DisplayUnit.h
|
||||
@@ -44,8 +42,6 @@ set(Spreadsheet_SRCS
|
||||
SheetObserver.h
|
||||
Utils.cpp
|
||||
Utils.h
|
||||
Range.h
|
||||
Range.cpp
|
||||
AppSpreadsheet.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Writer.h>
|
||||
#include "SpreadsheetExpression.h"
|
||||
#include <App/Expression.h>
|
||||
#include "Sheet.h"
|
||||
#include <iomanip>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
using namespace App;
|
||||
using namespace Base;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
@@ -216,7 +217,7 @@ void Cell::setContent(const char * value)
|
||||
if (value != 0) {
|
||||
if (*value == '=') {
|
||||
try {
|
||||
expr = Spreadsheet::ExpressionParser::parse(owner->sheet(), value + 1);
|
||||
expr = App::ExpressionParser::parse(owner->sheet(), value + 1);
|
||||
}
|
||||
catch (Base::Exception & e) {
|
||||
expr = new App::StringExpression(owner->sheet(), value);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <App/Material.h>
|
||||
#include <App/Range.h>
|
||||
#include "DisplayUnit.h"
|
||||
#include "Utils.h"
|
||||
|
||||
@@ -49,7 +50,7 @@ class SpreadsheetExport Cell {
|
||||
|
||||
public:
|
||||
|
||||
Cell(const CellAddress & _address, PropertySheet * _owner);
|
||||
Cell(const App::CellAddress & _address, PropertySheet * _owner);
|
||||
|
||||
Cell(const Cell & other);
|
||||
|
||||
@@ -101,7 +102,7 @@ public:
|
||||
|
||||
bool hasException() const { return isUsed(EXCEPTION_SET) || isUsed(PARSE_EXCEPTION_SET) || isUsed(RESOLVE_EXCEPTION_SET); }
|
||||
|
||||
void moveAbsolute(CellAddress newAddress);
|
||||
void moveAbsolute(App::CellAddress newAddress);
|
||||
|
||||
void restore(Base::XMLReader &reader);
|
||||
|
||||
@@ -117,7 +118,7 @@ public:
|
||||
|
||||
void visit(App::ExpressionVisitor & v);
|
||||
|
||||
CellAddress getAddress() const { return address; }
|
||||
App::CellAddress getAddress() const { return address; }
|
||||
|
||||
/* Alignment */
|
||||
static const int ALIGNMENT_LEFT;
|
||||
@@ -172,7 +173,7 @@ private:
|
||||
static const int PARSE_EXCEPTION_SET;
|
||||
static const int RESOLVE_EXCEPTION_SET;
|
||||
|
||||
CellAddress address;
|
||||
App::CellAddress address;
|
||||
PropertySheet * owner;
|
||||
|
||||
int used;
|
||||
@@ -187,7 +188,7 @@ private:
|
||||
int rowSpan;
|
||||
int colSpan;
|
||||
std::string exceptionStr;
|
||||
CellAddress anchor;
|
||||
App::CellAddress anchor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -1,75 +0,0 @@
|
||||
/* A Bison parser, made by GNU Bison 2.5. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
FUNC = 258,
|
||||
ONE = 259,
|
||||
NUM = 260,
|
||||
IDENTIFIER = 261,
|
||||
UNIT = 262,
|
||||
INTEGER = 263,
|
||||
CONSTANT = 264,
|
||||
CELLADDRESS = 265,
|
||||
EQ = 266,
|
||||
NEQ = 267,
|
||||
LT = 268,
|
||||
GT = 269,
|
||||
GTE = 270,
|
||||
LTE = 271,
|
||||
STRING = 272,
|
||||
MINUSSIGN = 273,
|
||||
PROPERTY_REF = 274,
|
||||
DOCUMENT = 275,
|
||||
OBJECT = 276,
|
||||
EXPONENT = 277,
|
||||
NEG = 278,
|
||||
POS = 279
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
/* Parser for the FreeCAD Units language */
|
||||
/* (c) 2010 Juergen Riegel LGPL */
|
||||
/* (c) 2015 Eivind Kvedalen LGPL */
|
||||
|
||||
/* Represents the many different ways we can access our data */
|
||||
|
||||
%{
|
||||
|
||||
#define YYSTYPE App::ExpressionParser::semantic_type
|
||||
|
||||
std::stack<FunctionExpression::Function> functions; /**< Function identifier */
|
||||
|
||||
//#define YYSTYPE yystype
|
||||
#define yyparse ExpressionParser_yyparse
|
||||
#define yyerror ExpressionParser_yyerror
|
||||
%}
|
||||
|
||||
/* Bison declarations. */
|
||||
%token FUNC
|
||||
%token ONE
|
||||
%token NUM
|
||||
%token IDENTIFIER
|
||||
%token UNIT
|
||||
%token INTEGER
|
||||
%token CONSTANT
|
||||
%token CELLADDRESS
|
||||
%token EQ NEQ LT GT GTE LTE
|
||||
%token STRING MINUSSIGN PROPERTY_REF
|
||||
%token DOCUMENT OBJECT
|
||||
%token EXPONENT
|
||||
%type <arguments> args
|
||||
%type <expr> input exp unit_exp cond
|
||||
%type <quantity> UNIT
|
||||
%type <string> STRING IDENTIFIER CELLADDRESS
|
||||
%type <ivalue> INTEGER
|
||||
%type <string> PROPERTY_REF
|
||||
%type <fvalue> ONE
|
||||
%type <fvalue> NUM
|
||||
%type <constant> CONSTANT
|
||||
%type <expr> num
|
||||
%type <expr> basic_num
|
||||
%type <expr> range
|
||||
%type <path> identifier
|
||||
%type <components> path subpath
|
||||
%type <func> FUNC
|
||||
%type <string_or_identifier> document
|
||||
%type <string_or_identifier> object
|
||||
%type <ivalue> integer
|
||||
%left ONE
|
||||
%left NUM
|
||||
%left INTEGER
|
||||
%left CONSTANT
|
||||
%left EQ NEQ LT GT GTE LTE
|
||||
%left '?' ':'
|
||||
%left MINUSSIGN '+'
|
||||
%left '*' '/'
|
||||
%left NEG /* negation--unary minus */
|
||||
%left POS /* unary plus */
|
||||
%right '^' /* exponentiation */
|
||||
%right EXPONENT
|
||||
|
||||
%destructor { delete $$; } exp cond unit_exp
|
||||
%destructor { std::vector<Expression*>::const_iterator i = $$.begin(); while (i != $$.end()) { delete *i; ++i; } } args
|
||||
|
||||
%start input
|
||||
|
||||
%%
|
||||
|
||||
input: exp { ScanResult = $1; valueExpression = true; }
|
||||
| unit_exp { ScanResult = $1; unitExpression = true; }
|
||||
;
|
||||
|
||||
exp: num { $$ = $1; }
|
||||
| STRING { $$ = new StringExpression(DocumentObject, $1); }
|
||||
| identifier { $$ = new VariableExpression(DocumentObject, $1); }
|
||||
| MINUSSIGN exp %prec NEG { $$ = new OperatorExpression(DocumentObject, $2, OperatorExpression::NEG, new NumberExpression(DocumentObject, -1)); }
|
||||
| '+' exp %prec POS { $$ = new OperatorExpression(DocumentObject, $2, OperatorExpression::POS, new NumberExpression(DocumentObject, 1)); }
|
||||
| exp '+' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::ADD, $3); }
|
||||
| exp MINUSSIGN exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::SUB, $3); }
|
||||
| exp '*' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MUL, $3); }
|
||||
| exp '/' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); }
|
||||
| exp '/' unit_exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); }
|
||||
| exp '^' exp %prec EXPONENT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, $3); }
|
||||
| '(' exp ')' { $$ = $2; }
|
||||
| FUNC args ')' { $$ = new AggregateFunctionExpression(DocumentObject, $1, $2); }
|
||||
| cond '?' exp ':' exp { $$ = new ConditionalExpression(DocumentObject, $1, $3, $5); }
|
||||
;
|
||||
|
||||
basic_num: ONE { $$ = new NumberExpression(DocumentObject, $1); }
|
||||
| NUM { $$ = new NumberExpression(DocumentObject, $1); }
|
||||
| INTEGER { $$ = new NumberExpression(DocumentObject, (double)$1); }
|
||||
;
|
||||
|
||||
num: basic_num { $$ = $1; }
|
||||
| CONSTANT { $$ = new ConstantExpression(DocumentObject, $1.name, $1.fvalue); }
|
||||
| basic_num unit_exp %prec EXPONENT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::UNIT, $2); }
|
||||
| CONSTANT unit_exp { $$ = new OperatorExpression(DocumentObject, new ConstantExpression(DocumentObject, $1.name, $1.fvalue), OperatorExpression::UNIT, $2); }
|
||||
;
|
||||
|
||||
args: exp { $$.push_back($1); }
|
||||
| range { $$.push_back($1); }
|
||||
| args ',' exp { $1.push_back($3); $$ = $1; }
|
||||
| args ';' exp { $1.push_back($3); $$ = $1; }
|
||||
;
|
||||
|
||||
range: CELLADDRESS ':' CELLADDRESS { $$ = new RangeExpression(DocumentObject, $1, $3); }
|
||||
| CELLADDRESS ':' IDENTIFIER { $$ = new RangeExpression(DocumentObject, $1, $3); }
|
||||
| IDENTIFIER ':' CELLADDRESS { $$ = new RangeExpression(DocumentObject, $1, $3); }
|
||||
| IDENTIFIER ':' IDENTIFIER { $$ = new RangeExpression(DocumentObject, $1, $3); }
|
||||
;
|
||||
|
||||
cond: exp EQ exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::EQ, $3); }
|
||||
| exp NEQ exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::NEQ, $3); }
|
||||
| exp LT exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::LT, $3); }
|
||||
| exp GT exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::GT, $3); }
|
||||
| exp GTE exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::GTE, $3); }
|
||||
| exp LTE exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::LTE, $3); }
|
||||
;
|
||||
|
||||
unit_exp: UNIT { $$ = new UnitExpression(DocumentObject, $1.scaler, $1.unitStr ); }
|
||||
| ONE '/' unit_exp { $$ = new OperatorExpression(DocumentObject, new NumberExpression(DocumentObject, $1), OperatorExpression::DIV, $3); }
|
||||
| unit_exp '/' unit_exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); }
|
||||
| unit_exp '*' unit_exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MUL, $3); }
|
||||
| unit_exp '^' basic_num %prec EXPONENT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, $3); }
|
||||
| unit_exp '^' MINUSSIGN basic_num %prec EXPONENT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, new OperatorExpression(DocumentObject, $4, OperatorExpression::NEG, new NumberExpression(DocumentObject, -1))); }
|
||||
| '(' unit_exp ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
identifier: path { /* Path to property within document object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$$.addComponents($1);
|
||||
}
|
||||
| object '.' path { /* Path to property within document object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$$.setDocumentObjectName($1, true);
|
||||
$$.addComponents($3);
|
||||
}
|
||||
| document '#' path { /* Path to property from an external document, within a named document object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$$.setDocumentName($1, true);
|
||||
$$.addComponents($3);
|
||||
}
|
||||
| document '#' object '.' path { /* Path to property from an external document, within a named document object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$$.setDocumentName($1, true);
|
||||
$$.setDocumentObjectName($3, true);
|
||||
$$.addComponents($5);
|
||||
}
|
||||
;
|
||||
|
||||
integer: INTEGER { $$ = $1; }
|
||||
| ONE { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
path: IDENTIFIER { $$.push_front(ObjectIdentifier::Component::SimpleComponent($1)); }
|
||||
| CELLADDRESS { $$.push_front(ObjectIdentifier::Component::SimpleComponent($1)); }
|
||||
| IDENTIFIER '[' integer ']' { $$.push_front(ObjectIdentifier::Component::ArrayComponent($1, $3)); }
|
||||
| IDENTIFIER '[' integer ']' '.' subpath { $6.push_front(ObjectIdentifier::Component::ArrayComponent($1, $3)); $$ = $6; }
|
||||
| IDENTIFIER '[' STRING ']' { $$.push_front(ObjectIdentifier::Component::MapComponent($1, ObjectIdentifier::String($3, true))); }
|
||||
| IDENTIFIER '[' IDENTIFIER ']' { $$.push_front(ObjectIdentifier::Component::MapComponent($1, $3)); }
|
||||
| IDENTIFIER '[' STRING ']' '.' subpath { $6.push_front(ObjectIdentifier::Component::MapComponent($1, ObjectIdentifier::String($3, true))); $$ = $6; }
|
||||
| IDENTIFIER '[' IDENTIFIER ']' '.' subpath { $6.push_front(ObjectIdentifier::Component::MapComponent($1, $3)); $$ = $6; }
|
||||
| IDENTIFIER '.' subpath { $3.push_front(ObjectIdentifier::Component::SimpleComponent($1)); $$ = $3; }
|
||||
;
|
||||
|
||||
subpath: IDENTIFIER { $$.push_front(ObjectIdentifier::Component::SimpleComponent($1)); }
|
||||
| STRING { $$.push_front(ObjectIdentifier::Component::SimpleComponent($1)); }
|
||||
| CELLADDRESS { $$.push_front(ObjectIdentifier::Component::SimpleComponent($1)); }
|
||||
| IDENTIFIER '[' integer ']' { $$.push_front(ObjectIdentifier::Component::ArrayComponent($1, $3)); }
|
||||
| IDENTIFIER '[' integer ']' '.' subpath { $6.push_front(ObjectIdentifier::Component::ArrayComponent($1, $3)); $$ = $6; }
|
||||
| IDENTIFIER '[' STRING ']' { $$.push_front(ObjectIdentifier::Component::MapComponent($1, ObjectIdentifier::String($3, true))); }
|
||||
| IDENTIFIER '[' IDENTIFIER ']' { $$.push_front(ObjectIdentifier::Component::MapComponent($1, $3)); }
|
||||
| IDENTIFIER '[' STRING ']' '.' subpath { $6.push_front(ObjectIdentifier::Component::MapComponent($1, ObjectIdentifier::String($3, true))); $$ = $6; }
|
||||
| IDENTIFIER '[' IDENTIFIER ']' '.' subpath { $6.push_front(ObjectIdentifier::Component::MapComponent($1, $3)); $$ = $6; }
|
||||
| IDENTIFIER '.' subpath { $3.push_front(ObjectIdentifier::Component::SimpleComponent($1)); $$ = $3; }
|
||||
;
|
||||
|
||||
document: STRING { $$ = ObjectIdentifier::String($1, true); }
|
||||
| IDENTIFIER { $$ = ObjectIdentifier::String($1); }
|
||||
;
|
||||
|
||||
object: STRING { $$ = ObjectIdentifier::String($1, true); }
|
||||
| CELLADDRESS { $$ = ObjectIdentifier::String($1, true); }
|
||||
;
|
||||
|
||||
%%
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "PropertyColumnWidths.h"
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <App/Range.h>
|
||||
#include "Utils.h"
|
||||
#include <PropertyColumnWidthsPy.h>
|
||||
|
||||
@@ -132,7 +133,7 @@ void PropertyColumnWidths::Restore(Base::XMLReader &reader)
|
||||
|
||||
try {
|
||||
if (name && width) {
|
||||
int col = decodeColumn(name);
|
||||
int col = App::decodeColumn(name);
|
||||
int colWidth = atoi(width);
|
||||
|
||||
setValue(col, colWidth);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "PropertyRowHeights.h"
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <App/Range.h>
|
||||
#include "Utils.h"
|
||||
#include <PropertyRowHeightsPy.h>
|
||||
|
||||
@@ -126,7 +127,7 @@ void PropertyRowHeights::Restore(Base::XMLReader &reader)
|
||||
|
||||
try {
|
||||
if (name && height) {
|
||||
int row = decodeRow(name);
|
||||
int row = App::decodeRow(name);
|
||||
int rowHeight = atoi(height);
|
||||
|
||||
setValue(row, rowHeight);
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include <Base/PyObjectBase.h>
|
||||
#include "PropertySheet.h"
|
||||
#include "Sheet.h"
|
||||
#include "SpreadsheetExpression.h"
|
||||
#include "Utils.h"
|
||||
#include <PropertySheetPy.h>
|
||||
#include <App/ExpressionVisitors.h>
|
||||
@@ -158,7 +157,7 @@ bool PropertySheet::isValidAlias(const std::string &candidate)
|
||||
const boost::sub_match<const char *> rowstr = cm[2];
|
||||
|
||||
// A valid cell address?
|
||||
if (Spreadsheet::validRow(rowstr.str()) >= 0 && Spreadsheet::validColumn(colstr.str()) >= 0)
|
||||
if (App::validRow(rowstr.str()) >= 0 && App::validColumn(colstr.str()) >= 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -53,55 +53,55 @@ public:
|
||||
|
||||
virtual void Restore(Base::XMLReader & reader);
|
||||
|
||||
Cell *createCell(CellAddress address);
|
||||
Cell *createCell(App::CellAddress address);
|
||||
|
||||
void setValue() { }
|
||||
|
||||
void setContent(CellAddress address, const char * value);
|
||||
void setContent(App::CellAddress address, const char * value);
|
||||
|
||||
void setAlignment(CellAddress address, int _alignment);
|
||||
void setAlignment(App::CellAddress address, int _alignment);
|
||||
|
||||
void setStyle(CellAddress address, const std::set<std::string> & _style);
|
||||
void setStyle(App::CellAddress address, const std::set<std::string> & _style);
|
||||
|
||||
void setForeground(CellAddress address, const App::Color &color);
|
||||
void setForeground(App::CellAddress address, const App::Color &color);
|
||||
|
||||
void setBackground(CellAddress address, const App::Color &color);
|
||||
void setBackground(App::CellAddress address, const App::Color &color);
|
||||
|
||||
void setDisplayUnit(CellAddress address, const std::string & unit);
|
||||
void setDisplayUnit(App::CellAddress address, const std::string & unit);
|
||||
|
||||
void setAlias(CellAddress address, const std::string &alias);
|
||||
void setAlias(App::CellAddress address, const std::string &alias);
|
||||
|
||||
void setComputedUnit(CellAddress address, const Base::Unit & unit);
|
||||
void setComputedUnit(App::CellAddress address, const Base::Unit & unit);
|
||||
|
||||
void setSpans(CellAddress address, int rows, int columns);
|
||||
void setSpans(App::CellAddress address, int rows, int columns);
|
||||
|
||||
void clear(CellAddress address);
|
||||
void clear(App::CellAddress address);
|
||||
|
||||
void clear();
|
||||
|
||||
Cell * getValue(CellAddress key);
|
||||
Cell * getValue(App::CellAddress key);
|
||||
|
||||
const Cell * getValue(CellAddress key) const;
|
||||
const Cell * getValue(App::CellAddress key) const;
|
||||
|
||||
const Cell * getValueFromAlias(const std::string &alias) const;
|
||||
|
||||
bool isValidAlias(const std::string &candidate);
|
||||
|
||||
std::set<CellAddress> getUsedCells() const;
|
||||
std::set<App::CellAddress> getUsedCells() const;
|
||||
|
||||
Sheet * sheet() const { return owner; }
|
||||
|
||||
const std::set<CellAddress> & getDirty() { return dirty; }
|
||||
const std::set<App::CellAddress> & getDirty() { return dirty; }
|
||||
|
||||
void setDirty(CellAddress address);
|
||||
void setDirty(App::CellAddress address);
|
||||
|
||||
void clearDirty(CellAddress key) { dirty.erase(key); }
|
||||
void clearDirty(App::CellAddress key) { dirty.erase(key); }
|
||||
|
||||
void clearDirty() { dirty.clear(); purgeTouched(); }
|
||||
|
||||
bool isDirty() const { return dirty.size() > 0; }
|
||||
|
||||
void moveCell(CellAddress currPos, CellAddress newPos, std::map<App::ObjectIdentifier, App::ObjectIdentifier> &renames);
|
||||
void moveCell(App::CellAddress currPos, App::CellAddress newPos, std::map<App::ObjectIdentifier, App::ObjectIdentifier> &renames);
|
||||
|
||||
void insertRows(int row, int count);
|
||||
|
||||
@@ -113,23 +113,23 @@ public:
|
||||
|
||||
virtual unsigned int getMemSize (void) const;
|
||||
|
||||
bool mergeCells(CellAddress from, CellAddress to);
|
||||
bool mergeCells(App::CellAddress from, App::CellAddress to);
|
||||
|
||||
void splitCell(CellAddress address);
|
||||
void splitCell(App::CellAddress address);
|
||||
|
||||
void getSpans(CellAddress address, int &rows, int &cols) const;
|
||||
void getSpans(App::CellAddress address, int &rows, int &cols) const;
|
||||
|
||||
bool isMergedCell(CellAddress address) const;
|
||||
bool isMergedCell(App::CellAddress address) const;
|
||||
|
||||
bool isHidden(CellAddress address) const;
|
||||
bool isHidden(App::CellAddress address) const;
|
||||
|
||||
const std::set< CellAddress > & getDeps(const std::string & name) const;
|
||||
const std::set< App::CellAddress > & getDeps(const std::string & name) const;
|
||||
|
||||
const std::set<std::string> &getDeps(CellAddress pos) const;
|
||||
const std::set<std::string> &getDeps(App::CellAddress pos) const;
|
||||
|
||||
const std::set<App::DocumentObject*> & getDocDeps() const { return docDeps; }
|
||||
|
||||
void recomputeDependencies(CellAddress key);
|
||||
void recomputeDependencies(App::CellAddress key);
|
||||
|
||||
PyObject *getPyObject(void);
|
||||
|
||||
@@ -161,24 +161,24 @@ private:
|
||||
|
||||
friend class Sheet;
|
||||
|
||||
Cell *cellAt(CellAddress address);
|
||||
Cell *cellAt(App::CellAddress address);
|
||||
|
||||
Cell *nonNullCellAt(CellAddress address);
|
||||
Cell *nonNullCellAt(App::CellAddress address);
|
||||
|
||||
const Cell *cellAt(CellAddress address) const;
|
||||
const Cell *cellAt(App::CellAddress address) const;
|
||||
|
||||
bool colSortFunc(const CellAddress &a, const CellAddress &b);
|
||||
bool colSortFunc(const App::CellAddress &a, const App::CellAddress &b);
|
||||
|
||||
bool rowSortFunc(const CellAddress &a, const CellAddress &b);
|
||||
bool rowSortFunc(const App::CellAddress &a, const App::CellAddress &b);
|
||||
|
||||
/*! Set of cells that have been marked dirty */
|
||||
std::set<CellAddress> dirty;
|
||||
std::set<App::CellAddress> dirty;
|
||||
|
||||
/*! Cell data in this property */
|
||||
std::map<CellAddress, Cell*> data;
|
||||
std::map<App::CellAddress, Cell*> data;
|
||||
|
||||
/*! Merged cells; cell -> anchor cell */
|
||||
std::map<CellAddress, CellAddress> mergedCells;
|
||||
std::map<App::CellAddress, App::CellAddress> mergedCells;
|
||||
|
||||
/*! Owner of this property */
|
||||
Sheet * owner;
|
||||
@@ -187,9 +187,9 @@ private:
|
||||
* Cell dependency tracking
|
||||
*/
|
||||
|
||||
void addDependencies(CellAddress key);
|
||||
void addDependencies(App::CellAddress key);
|
||||
|
||||
void removeDependencies(CellAddress key);
|
||||
void removeDependencies(App::CellAddress key);
|
||||
|
||||
void recomputeDependants(const App::Property * prop);
|
||||
|
||||
@@ -200,18 +200,18 @@ private:
|
||||
/*! Cell dependencies, i.e when a change occurs to property given in key,
|
||||
the set of addresses needs to be recomputed.
|
||||
*/
|
||||
std::map<std::string, std::set< CellAddress > > propertyNameToCellMap;
|
||||
std::map<std::string, std::set< App::CellAddress > > propertyNameToCellMap;
|
||||
|
||||
/*! Properties this cell depends on */
|
||||
std::map<CellAddress, std::set< std::string > > cellToPropertyNameMap;
|
||||
std::map<App::CellAddress, std::set< std::string > > cellToPropertyNameMap;
|
||||
|
||||
/*! Cell dependencies, i.e when a change occurs to documentObject given in key,
|
||||
the set of addresses needs to be recomputed.
|
||||
*/
|
||||
std::map<std::string, std::set< CellAddress > > documentObjectToCellMap;
|
||||
std::map<std::string, std::set< App::CellAddress > > documentObjectToCellMap;
|
||||
|
||||
/*! DocumentObject this cell depends on */
|
||||
std::map<CellAddress, std::set< std::string > > cellToDocumentObjectMap;
|
||||
std::map<App::CellAddress, std::set< std::string > > cellToDocumentObjectMap;
|
||||
|
||||
/*! Other document objects the sheet depends on */
|
||||
std::set<App::DocumentObject*> docDeps;
|
||||
@@ -223,10 +223,10 @@ private:
|
||||
std::map<const App::Document*, std::string> documentName;
|
||||
|
||||
/*! Mapping of cell position to alias property */
|
||||
std::map<CellAddress, std::string> aliasProp;
|
||||
std::map<App::CellAddress, std::string> aliasProp;
|
||||
|
||||
/*! Mapping of alias property to cell position */
|
||||
std::map<std::string, CellAddress> revAliasProp;
|
||||
std::map<std::string, App::CellAddress> revAliasProp;
|
||||
|
||||
/*! The associated python object */
|
||||
Py::Object PythonObject;
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Eivind Kvedalen (eivind@kvedalen.name) 2015 *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#include "Range.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace Spreadsheet;
|
||||
|
||||
Range::Range(const char * range)
|
||||
{
|
||||
std::string from;
|
||||
std::string to;
|
||||
|
||||
assert(range != NULL);
|
||||
|
||||
if (strchr(range, ':') == NULL) {
|
||||
from = range;
|
||||
to = range;
|
||||
}
|
||||
else {
|
||||
std::string s = range;
|
||||
from = s.substr(0, s.find(':'));
|
||||
to = s.substr(s.find(':') + 1);
|
||||
}
|
||||
|
||||
CellAddress begin(from);
|
||||
CellAddress end(to);
|
||||
|
||||
row_begin = begin.row();
|
||||
col_begin = begin.col();
|
||||
row_end = end.row();
|
||||
col_end = end.col();
|
||||
|
||||
row_curr = row_begin;
|
||||
col_curr = col_begin;
|
||||
}
|
||||
|
||||
Range::Range(int _row_begin, int _col_begin, int _row_end, int _col_end)
|
||||
: row_curr(_row_begin)
|
||||
, col_curr(_col_begin)
|
||||
, row_begin(_row_begin)
|
||||
, col_begin(_col_begin)
|
||||
, row_end(_row_end)
|
||||
, col_end(_col_end)
|
||||
{
|
||||
}
|
||||
|
||||
Range::Range(const CellAddress &from, const CellAddress &to)
|
||||
: row_curr(from.row())
|
||||
, col_curr(from.col())
|
||||
, row_begin(from.row())
|
||||
, col_begin(from.col())
|
||||
, row_end(to.row())
|
||||
, col_end(to.col())
|
||||
{
|
||||
}
|
||||
|
||||
bool Range::next()
|
||||
{
|
||||
if (row_curr < row_end) {
|
||||
row_curr++;
|
||||
|
||||
return true;
|
||||
}
|
||||
if (col_curr < col_end) {
|
||||
if (row_curr == row_end + 1)
|
||||
return false;
|
||||
row_curr = row_begin;
|
||||
++col_curr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Eivind Kvedalen (eivind@kvedalen.name) 2015 *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef RANGE_H
|
||||
#define RANGE_H
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
/**
|
||||
* @brief The Range class is a spreadsheet range iterator. It takes
|
||||
* a starting (row, col) and an ending (row, col). Notice that ranges
|
||||
* are always at least one element. The next() functions is therefore
|
||||
* used e.g as follows:
|
||||
*
|
||||
* do {
|
||||
* ...
|
||||
* while (range.next());
|
||||
*
|
||||
*/
|
||||
|
||||
class SpreadsheetExport Range {
|
||||
public:
|
||||
Range(const char *range);
|
||||
|
||||
Range(int _row_begin, int _col_begin, int _row_end, int _col_end);
|
||||
|
||||
Range(const CellAddress & from, const CellAddress & to);
|
||||
|
||||
bool next();
|
||||
|
||||
/** Current row */
|
||||
inline int row() const { return row_curr; }
|
||||
|
||||
/** Current column */
|
||||
inline int column() const { return col_curr; }
|
||||
|
||||
/** Position of start of range */
|
||||
inline CellAddress from() const { return CellAddress(row_begin, col_begin); }
|
||||
|
||||
/** Position of end of range */
|
||||
inline CellAddress to() const { return CellAddress(row_end, col_end); }
|
||||
|
||||
/** Start of range as a string */
|
||||
inline std::string fromCellString() const { return CellAddress(row_begin, col_begin).toString(); }
|
||||
|
||||
/** End of range as a string */
|
||||
inline std::string toCellString() const { return CellAddress(row_end, col_end).toString(); }
|
||||
|
||||
/** Current cell as a string */
|
||||
inline std::string address() const { return CellAddress(row_curr, col_curr).toString(); }
|
||||
|
||||
/** The raneg as a string */
|
||||
inline std::string rangeString() const {
|
||||
return CellAddress(row_begin, col_begin).toString() + ":" + CellAddress(row_end, col_end).toString();
|
||||
}
|
||||
|
||||
CellAddress operator*() const { return CellAddress(row_curr, col_curr); }
|
||||
|
||||
/** Number of elements in range */
|
||||
inline int size() const { return (row_end - row_begin + 1) * (col_end - col_begin + 1); }
|
||||
|
||||
private:
|
||||
int row_curr, col_curr;
|
||||
int row_begin, col_begin;
|
||||
int row_end, col_end;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // RANGE_H
|
||||
@@ -38,11 +38,9 @@
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Tools.h>
|
||||
#include "SpreadsheetExpression.h"
|
||||
#include "Sheet.h"
|
||||
#include "SheetObserver.h"
|
||||
#include "Utils.h"
|
||||
#include "Range.h"
|
||||
#include "SheetPy.h"
|
||||
#include <ostream>
|
||||
#include <fstream>
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <App/PropertyStandard.h>
|
||||
#include <App/DynamicProperty.h>
|
||||
#include <App/Material.h>
|
||||
#include <App/Range.h>
|
||||
#include <Base/Unit.h>
|
||||
#include <map>
|
||||
#include "PropertySheet.h"
|
||||
@@ -43,12 +44,12 @@
|
||||
#include "PropertyRowHeights.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
namespace Spreadsheet
|
||||
{
|
||||
|
||||
class Sheet;
|
||||
class Cell;
|
||||
class Range;
|
||||
class SheetObserver;
|
||||
|
||||
/** Spreadsheet quantity property
|
||||
@@ -86,25 +87,25 @@ public:
|
||||
|
||||
bool exportToFile(const std::string & filename, char delimiter = '\t', char quoteChar = '\0', char escapeChar = '\\') const;
|
||||
|
||||
bool mergeCells(const Range &range);
|
||||
bool mergeCells(const App::Range &range);
|
||||
|
||||
void splitCell(CellAddress address);
|
||||
void splitCell(App::CellAddress address);
|
||||
|
||||
Cell * getCell(CellAddress address);
|
||||
Cell * getCell(App::CellAddress address);
|
||||
|
||||
Cell *getNewCell(CellAddress address);
|
||||
Cell *getNewCell(App::CellAddress address);
|
||||
|
||||
void setCell(const char *address, const char *value);
|
||||
|
||||
void setCell(CellAddress address, const char *value);
|
||||
void setCell(App::CellAddress address, const char *value);
|
||||
|
||||
void clearAll();
|
||||
|
||||
void clear(CellAddress address, bool all = true);
|
||||
void clear(App::CellAddress address, bool all = true);
|
||||
|
||||
void getSpans(CellAddress address, int & rows, int & cols) const;
|
||||
void getSpans(App::CellAddress address, int & rows, int & cols) const;
|
||||
|
||||
bool isMergedCell(CellAddress address) const;
|
||||
bool isMergedCell(App::CellAddress address) const;
|
||||
|
||||
void setColumnWidth(int col, int width);
|
||||
|
||||
@@ -124,31 +125,31 @@ public:
|
||||
|
||||
void removeRows(int row, int count);
|
||||
|
||||
void setContent(CellAddress address, const char * value);
|
||||
void setContent(App::CellAddress address, const char * value);
|
||||
|
||||
void setAlignment(CellAddress address, int alignment);
|
||||
void setAlignment(App::CellAddress address, int alignment);
|
||||
|
||||
void setStyle(CellAddress address, const std::set<std::string> & style);
|
||||
void setStyle(App::CellAddress address, const std::set<std::string> & style);
|
||||
|
||||
void setForeground(CellAddress address, const App::Color &color);
|
||||
void setForeground(App::CellAddress address, const App::Color &color);
|
||||
|
||||
void setBackground(CellAddress address, const App::Color &color);
|
||||
void setBackground(App::CellAddress address, const App::Color &color);
|
||||
|
||||
void setDisplayUnit(CellAddress address, const std::string & unit);
|
||||
void setDisplayUnit(App::CellAddress address, const std::string & unit);
|
||||
|
||||
void setComputedUnit(CellAddress address, const Base::Unit & unit);
|
||||
void setComputedUnit(App::CellAddress address, const Base::Unit & unit);
|
||||
|
||||
void setAlias(CellAddress address, const std::string & alias);
|
||||
void setAlias(App::CellAddress address, const std::string & alias);
|
||||
|
||||
std::string getAddressFromAlias(const std::string & alias) const;
|
||||
|
||||
bool isValidAlias(const std::string &candidate);
|
||||
|
||||
void setSpans(CellAddress address, int rows, int columns);
|
||||
void setSpans(App::CellAddress address, int rows, int columns);
|
||||
|
||||
std::set<std::string> dependsOn(CellAddress address) const;
|
||||
std::set<std::string> dependsOn(App::CellAddress address) const;
|
||||
|
||||
void providesTo(CellAddress address, std::set<std::string> & result) const;
|
||||
void providesTo(App::CellAddress address, std::set<std::string> & result) const;
|
||||
|
||||
PyObject *getPyObject();
|
||||
|
||||
@@ -160,7 +161,7 @@ public:
|
||||
|
||||
App::DocumentObjectExecReturn *execute(void);
|
||||
|
||||
void getCellAddress(const App::Property *prop, CellAddress &address);
|
||||
void getCellAddress(const App::Property *prop, App::CellAddress &address);
|
||||
|
||||
std::map<int, int> getColumnWidths() const;
|
||||
|
||||
@@ -168,9 +169,9 @@ public:
|
||||
|
||||
// Signals
|
||||
|
||||
boost::signal<void (Spreadsheet::CellAddress)> cellUpdated;
|
||||
boost::signal<void (App::CellAddress)> cellUpdated;
|
||||
|
||||
boost::signal<void (Spreadsheet::CellAddress)> cellSpanChanged;
|
||||
boost::signal<void (App::CellAddress)> cellSpanChanged;
|
||||
|
||||
boost::signal<void (int, int)> columnWidthChanged;
|
||||
|
||||
@@ -231,7 +232,7 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
void providesTo(CellAddress address, std::set<CellAddress> & result) const;
|
||||
void providesTo(App::CellAddress address, std::set<App::CellAddress> & result) const;
|
||||
|
||||
void onDocumentRestored();
|
||||
|
||||
@@ -239,25 +240,25 @@ protected:
|
||||
|
||||
void onRenamedDocument(const App::Document & document);
|
||||
|
||||
void recomputeCell(CellAddress p);
|
||||
void recomputeCell(App::CellAddress p);
|
||||
|
||||
App::Property *getProperty(CellAddress key) const;
|
||||
App::Property *getProperty(App::CellAddress key) const;
|
||||
|
||||
App::Property *getProperty(const char * addr) const;
|
||||
|
||||
void updateAlias(CellAddress key);
|
||||
void updateAlias(App::CellAddress key);
|
||||
|
||||
void updateProperty(CellAddress key);
|
||||
void updateProperty(App::CellAddress key);
|
||||
|
||||
App::Property *setStringProperty(CellAddress key, const std::string & value) ;
|
||||
App::Property *setStringProperty(App::CellAddress key, const std::string & value) ;
|
||||
|
||||
App::Property *setFloatProperty(CellAddress key, double value);
|
||||
App::Property *setFloatProperty(App::CellAddress key, double value);
|
||||
|
||||
App::Property *setQuantityProperty(CellAddress key, double value, const Base::Unit &unit);
|
||||
App::Property *setQuantityProperty(App::CellAddress key, double value, const Base::Unit &unit);
|
||||
|
||||
void renamedDocumentObject(const App::DocumentObject * docObj);
|
||||
|
||||
void aliasRemoved(CellAddress address, const std::string &alias);
|
||||
void aliasRemoved(App::CellAddress address, const std::string &alias);
|
||||
|
||||
void removeAliases();
|
||||
|
||||
@@ -267,13 +268,13 @@ protected:
|
||||
App::DynamicProperty props;
|
||||
|
||||
/* Mapping of properties to cell position */
|
||||
std::map<const App::Property*, CellAddress > propAddress;
|
||||
std::map<const App::Property*, App::CellAddress > propAddress;
|
||||
|
||||
/* Removed (unprocessed) aliases */
|
||||
std::map<CellAddress, std::string> removedAliases;
|
||||
std::map<App::CellAddress, std::string> removedAliases;
|
||||
|
||||
/* Set of cells with errors */
|
||||
std::set<CellAddress> cellErrors;
|
||||
std::set<App::CellAddress> cellErrors;
|
||||
|
||||
/* Properties */
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
#include "Utils.h"
|
||||
#include "Range.h"
|
||||
#include <App/Range.h>
|
||||
|
||||
// inclusion of the generated files (generated out of SheetPy.xml)
|
||||
#include "SheetPy.h"
|
||||
|
||||
@@ -1,485 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Eivind Kvedalen (eivind@kvedalen.name) 2015 *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifdef __GNUC__
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "Base/Exception.h"
|
||||
#include <Base/Interpreter.h>
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentPy.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/PropertyUnits.h>
|
||||
#include <Base/QuantityPy.h>
|
||||
#include <QStringList>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stack>
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
#include "SpreadsheetExpression.h"
|
||||
#include <Base/Unit.h>
|
||||
#include <App/PropertyUnits.h>
|
||||
#include "Utils.h"
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#ifndef M_E
|
||||
#define M_E 2.71828182845904523536
|
||||
#endif
|
||||
#ifndef DOUBLE_MAX
|
||||
# define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/
|
||||
#endif
|
||||
#ifndef DOUBLE_MIN
|
||||
# define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define strtoll _strtoi64
|
||||
#pragma warning(disable : 4003)
|
||||
#pragma warning(disable : 4065)
|
||||
#endif
|
||||
|
||||
using namespace App;
|
||||
using namespace Base;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
//
|
||||
// FunctionExpression class. This class handles functions with one or two parameters.
|
||||
//
|
||||
|
||||
TYPESYSTEM_SOURCE(Spreadsheet::AggregateFunctionExpression, App::FunctionExpression);
|
||||
|
||||
AggregateFunctionExpression::AggregateFunctionExpression(const DocumentObject *_owner,
|
||||
App::FunctionExpression::Function _f,
|
||||
std::vector<Expression *> _args)
|
||||
: FunctionExpression(_owner, static_cast<FunctionExpression::Function>(_f), _args)
|
||||
{
|
||||
}
|
||||
|
||||
AggregateFunctionExpression::~AggregateFunctionExpression()
|
||||
{
|
||||
}
|
||||
|
||||
Expression *AggregateFunctionExpression::copy() const
|
||||
{
|
||||
std::vector<Expression*>::const_iterator i = args.begin();
|
||||
std::vector<Expression*> a;
|
||||
|
||||
while (i != args.end()) {
|
||||
a.push_back((*i)->copy());
|
||||
++i;
|
||||
}
|
||||
|
||||
return new AggregateFunctionExpression(owner, f, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate function. Returns a NumberExpression if evaluation is successfuly.
|
||||
* Throws an exception if something fails.
|
||||
*
|
||||
* @returns A NumberExpression with the result.
|
||||
*/
|
||||
|
||||
Expression * AggregateFunctionExpression::eval() const
|
||||
{
|
||||
switch (static_cast<Function>(f)) {
|
||||
case SUM:
|
||||
case AVERAGE:
|
||||
case STDDEV:
|
||||
case COUNT:
|
||||
case MIN:
|
||||
case MAX:
|
||||
{
|
||||
RangeExpression * v = freecad_dynamic_cast<RangeExpression>(args[0]);
|
||||
Quantity q;
|
||||
Quantity mean;
|
||||
Quantity M2;
|
||||
|
||||
int n = 0;
|
||||
bool first = true;
|
||||
|
||||
if (!v)
|
||||
throw Exception("Expected range as argument");
|
||||
|
||||
Range range(v->getRange());
|
||||
|
||||
do {
|
||||
Property * p = owner->getPropertyByName(range.address().c_str());
|
||||
PropertyQuantity * qp;
|
||||
PropertyFloat * fp;
|
||||
Quantity value;
|
||||
|
||||
if (!p)
|
||||
continue;
|
||||
|
||||
if ((qp = freecad_dynamic_cast<PropertyQuantity>(p)) != 0)
|
||||
value = qp->getQuantityValue();
|
||||
else if ((fp = freecad_dynamic_cast<PropertyFloat>(p)) != 0)
|
||||
value = fp->getValue();
|
||||
else
|
||||
throw Exception("Invalid property type for aggregate");
|
||||
|
||||
if (first) {
|
||||
q.setUnit(value.getUnit());
|
||||
mean.setUnit(value.getUnit());
|
||||
M2.setUnit(value.getUnit());
|
||||
}
|
||||
|
||||
switch (static_cast<Function>(f)) {
|
||||
case AVERAGE:
|
||||
n++;
|
||||
case SUM:
|
||||
q = q + value;
|
||||
break;
|
||||
case STDDEV: {
|
||||
n++;
|
||||
|
||||
const Quantity delta = value - mean;
|
||||
mean = mean + delta / n;
|
||||
M2 = M2 + delta * (value - mean);
|
||||
break;
|
||||
}
|
||||
case COUNT:
|
||||
q = q + 1;
|
||||
break;
|
||||
case MIN:
|
||||
if (first || value < q)
|
||||
q = value;
|
||||
break;
|
||||
case MAX:
|
||||
if (first || value > q)
|
||||
q = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
first = false;
|
||||
} while (range.next());
|
||||
|
||||
switch (static_cast<Function>(f)) {
|
||||
case AVERAGE:
|
||||
q = q / (double)n;
|
||||
break;
|
||||
case STDDEV:
|
||||
if (n < 2)
|
||||
q = Quantity();
|
||||
else
|
||||
q = (M2 / (n - 1.0)).pow(Quantity(0.5));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return new NumberExpression(owner, q);
|
||||
}
|
||||
default:
|
||||
return App::FunctionExpression::eval();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a string representation of the expression.
|
||||
*
|
||||
* @returns A string representing the expression.
|
||||
*/
|
||||
|
||||
std::string AggregateFunctionExpression::toString() const
|
||||
{
|
||||
switch (static_cast<Function>(f)) {
|
||||
case SUM:
|
||||
return "sum(" + args[0]->toString() + ")";
|
||||
case COUNT:
|
||||
return "count(" + args[0]->toString() + ")";
|
||||
case AVERAGE:
|
||||
return "average(" + args[0]->toString() + ")";
|
||||
case STDDEV:
|
||||
return "stddev(" + args[0]->toString() + ")";
|
||||
case MIN:
|
||||
return "min(" + args[0]->toString() + ")";
|
||||
case MAX:
|
||||
return "max(" + args[0]->toString() + ")";
|
||||
default:
|
||||
return App::FunctionExpression::toString();
|
||||
}
|
||||
}
|
||||
|
||||
TYPESYSTEM_SOURCE(Spreadsheet::RangeExpression, App::Expression);
|
||||
|
||||
RangeExpression::RangeExpression(const DocumentObject *_owner, const std::string &begin, const std::string &end)
|
||||
: Expression(_owner)
|
||||
, range((begin + ":" + end).c_str())
|
||||
{
|
||||
}
|
||||
|
||||
bool RangeExpression::isTouched() const
|
||||
{
|
||||
Range i(range);
|
||||
|
||||
do {
|
||||
Property * prop = owner->getPropertyByName(i.address().c_str());
|
||||
|
||||
if (prop && prop->isTouched())
|
||||
return true;
|
||||
} while (i.next());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Expression *RangeExpression::eval() const
|
||||
{
|
||||
throw Exception("Range expression cannot be evaluated");
|
||||
}
|
||||
|
||||
std::string RangeExpression::toString() const
|
||||
{
|
||||
return range.rangeString();
|
||||
}
|
||||
|
||||
Expression *RangeExpression::copy() const
|
||||
{
|
||||
return new RangeExpression(owner, range.fromCellString(), range.toCellString());
|
||||
}
|
||||
|
||||
void RangeExpression::getDeps(std::set<ObjectIdentifier> &props) const
|
||||
{
|
||||
Range i(range);
|
||||
|
||||
do {
|
||||
props.insert(ObjectIdentifier(owner, i.address()));
|
||||
} while (i.next());
|
||||
}
|
||||
|
||||
Expression *RangeExpression::simplify() const
|
||||
{
|
||||
return copy();
|
||||
}
|
||||
|
||||
void RangeExpression::setRange(const Range &r)
|
||||
{
|
||||
range = r;
|
||||
}
|
||||
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
namespace ExpressionParser {
|
||||
|
||||
/**
|
||||
* Error function for parser. Throws a generic Base::Exception with the parser error.
|
||||
*/
|
||||
|
||||
void ExpressionParser_yyerror(char *errorinfo)
|
||||
{
|
||||
}
|
||||
|
||||
/* helper function for tuning number strings with groups in a locale agnostic way... */
|
||||
double num_change(char* yytext,char dez_delim,char grp_delim)
|
||||
{
|
||||
double ret_val;
|
||||
char temp[40];
|
||||
int i = 0;
|
||||
for(char* c=yytext;*c!='\0';c++){
|
||||
// skipp group delimiter
|
||||
if(*c==grp_delim) continue;
|
||||
// check for a dez delimiter othere then dot
|
||||
if(*c==dez_delim && dez_delim !='.')
|
||||
temp[i++] = '.';
|
||||
else
|
||||
temp[i++] = *c;
|
||||
// check buffor overflow
|
||||
if (i>39) return 0.0;
|
||||
}
|
||||
temp[i] = '\0';
|
||||
|
||||
errno = 0;
|
||||
ret_val = strtod( temp, NULL );
|
||||
if (ret_val == 0 && errno == ERANGE)
|
||||
throw Base::Exception("Number underflow.");
|
||||
if (ret_val == HUGE_VAL || ret_val == -HUGE_VAL)
|
||||
throw Base::Exception("Number overflow.");
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static Expression * ScanResult = 0; /**< The resulting expression after a successful parsing */
|
||||
static const DocumentObject * DocumentObject = 0; /**< The DocumentObject that will own the expression */
|
||||
static bool unitExpression = false; /**< True if the parsed string is a unit only */
|
||||
static bool valueExpression = false; /**< True if the parsed string is a full expression */
|
||||
static std::stack<std::string> labels; /**< Label string primitive */
|
||||
static std::map<std::string, FunctionExpression::Function> registered_functions; /**< Registerd functions */
|
||||
|
||||
// show the parser the lexer method
|
||||
#undef YYTOKENTYPE
|
||||
#undef YYSTYPE
|
||||
#undef YYSTYPE_ISDECLARED
|
||||
#define yylex ExpressionParserlex
|
||||
int ExpressionParserlex(void);
|
||||
|
||||
// Parser, defined in ExpressionParser.y
|
||||
#include <Mod/Spreadsheet/App/ExpressionParser.tab.c>
|
||||
#include <Mod/Spreadsheet/App/ExpressionParser.tab.h>
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
// Scanner, defined in ExpressionParser.l
|
||||
#include <Mod/Spreadsheet/App/lex.ExpressionParser.c>
|
||||
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||
#ifdef _MSC_VER
|
||||
# define strdup _strdup
|
||||
#endif
|
||||
|
||||
static void initParser(const App::DocumentObject *owner)
|
||||
{
|
||||
static bool has_registered_functions = false;
|
||||
|
||||
using namespace Spreadsheet::ExpressionParser;
|
||||
|
||||
ScanResult = 0;
|
||||
Spreadsheet::ExpressionParser::DocumentObject = owner;
|
||||
labels = std::stack<std::string>();
|
||||
unitExpression = valueExpression = false;
|
||||
|
||||
if (!has_registered_functions) {
|
||||
registered_functions["acos"] = FunctionExpression::ACOS;
|
||||
registered_functions["asin"] = FunctionExpression::ASIN;
|
||||
registered_functions["atan"] = FunctionExpression::ATAN;
|
||||
registered_functions["abs"] = FunctionExpression::ABS;
|
||||
registered_functions["exp"] = FunctionExpression::EXP;
|
||||
registered_functions["log"] = FunctionExpression::LOG;
|
||||
registered_functions["log10"] = FunctionExpression::LOG10;
|
||||
registered_functions["sin"] = FunctionExpression::SIN;
|
||||
registered_functions["sinh"] = FunctionExpression::SINH;
|
||||
registered_functions["tan"] = FunctionExpression::TAN;
|
||||
registered_functions["tanh"] = FunctionExpression::TANH;
|
||||
registered_functions["sqrt"] = FunctionExpression::SQRT;
|
||||
registered_functions["cos"] = FunctionExpression::COS;
|
||||
registered_functions["cosh"] = FunctionExpression::COSH;
|
||||
registered_functions["atan2"] = FunctionExpression::ATAN2;
|
||||
registered_functions["mod"] = FunctionExpression::MOD;
|
||||
registered_functions["pow"] = FunctionExpression::POW;
|
||||
registered_functions["round"] = FunctionExpression::ROUND;
|
||||
registered_functions["trunc"] = FunctionExpression::TRUNC;
|
||||
registered_functions["ceil"] = FunctionExpression::CEIL;
|
||||
registered_functions["floor"] = FunctionExpression::FLOOR;
|
||||
|
||||
// Aggregates
|
||||
registered_functions["sum"] = static_cast<FunctionExpression::Function>(AggregateFunctionExpression::SUM);
|
||||
registered_functions["count"] = static_cast<FunctionExpression::Function>(AggregateFunctionExpression::COUNT);
|
||||
registered_functions["average"] = static_cast<FunctionExpression::Function>(AggregateFunctionExpression::AVERAGE);
|
||||
registered_functions["stddev"] = static_cast<FunctionExpression::Function>(AggregateFunctionExpression::STDDEV);
|
||||
registered_functions["min"] = static_cast<FunctionExpression::Function>(AggregateFunctionExpression::MIN);
|
||||
registered_functions["max"] = static_cast<FunctionExpression::Function>(AggregateFunctionExpression::MAX);
|
||||
|
||||
has_registered_functions = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the expression given by \a buffer, and use \a owner as the owner of the
|
||||
* returned expression. If the parser fails for some reason, and exception is thrown.
|
||||
*
|
||||
* @param owner The DocumentObject that will own the expression.
|
||||
* @param buffer The sting buffer to parse.
|
||||
*
|
||||
* @returns A pointer to an expression.
|
||||
*
|
||||
*/
|
||||
|
||||
Expression * parse(const App::DocumentObject *owner, const char* buffer)
|
||||
{
|
||||
// parse from buffer
|
||||
ExpressionParser::YY_BUFFER_STATE my_string_buffer = ExpressionParser_scan_string (buffer);
|
||||
|
||||
initParser(owner);
|
||||
|
||||
// run the parser
|
||||
int result = ExpressionParser::ExpressionParser_yyparse ();
|
||||
|
||||
// free the scan buffer
|
||||
ExpressionParser::ExpressionParser_delete_buffer (my_string_buffer);
|
||||
|
||||
if (result != 0)
|
||||
throw Base::Exception("Failed to parse expression.");
|
||||
|
||||
if (ScanResult == 0)
|
||||
throw Base::Exception("Unknown error in expression");
|
||||
|
||||
if (valueExpression)
|
||||
return ScanResult;
|
||||
else {
|
||||
delete ScanResult;
|
||||
throw Expression::Exception("Expression can not evaluate to a value.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
UnitExpression * parseUnit(const App::DocumentObject *owner, const char* buffer)
|
||||
{
|
||||
// parse from buffer
|
||||
ExpressionParser::YY_BUFFER_STATE my_string_buffer = ExpressionParser_scan_string (buffer);
|
||||
|
||||
initParser(owner);
|
||||
|
||||
// run the parser
|
||||
int result = ExpressionParser::ExpressionParser_yyparse ();
|
||||
|
||||
// free the scan buffer
|
||||
ExpressionParser::ExpressionParser_delete_buffer (my_string_buffer);
|
||||
|
||||
if (result != 0)
|
||||
throw Base::Exception("Failed to parse expression.");
|
||||
|
||||
if (ScanResult == 0)
|
||||
throw Base::Exception("Unknown error in expression");
|
||||
|
||||
// Simplify expression
|
||||
Expression * simplified = ScanResult->simplify();
|
||||
delete ScanResult;
|
||||
|
||||
if (unitExpression) {
|
||||
NumberExpression * num = freecad_dynamic_cast<NumberExpression>(simplified);
|
||||
|
||||
if (num) {
|
||||
simplified = new UnitExpression(num->getOwner(), num->getQuantity());
|
||||
delete num;
|
||||
}
|
||||
return freecad_dynamic_cast<UnitExpression>(simplified);
|
||||
}
|
||||
else {
|
||||
delete simplified;
|
||||
throw Expression::Exception("Expression is not a unit.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Eivind Kvedalen (eivind@kvedalen.name) 2015 *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SPREADSHEET_EXPRESSION_H
|
||||
#define SPREADSHEET_EXPRESSION_H
|
||||
|
||||
#include <string>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Unit.h>
|
||||
#include <App/Property.h>
|
||||
#include <Base/BaseClass.h>
|
||||
#include <Base/Quantity.h>
|
||||
#include <Mod/Spreadsheet/App/Range.h>
|
||||
#include <set>
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
class SpreadsheetExport RangeExpression : public App::Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
RangeExpression(const App::DocumentObject * _owner = 0, const std::string & begin = std::string(), const std::string & end = std::string());
|
||||
|
||||
virtual ~RangeExpression() { }
|
||||
|
||||
virtual bool isTouched() const;
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
virtual Expression * copy() const;
|
||||
|
||||
virtual int priority() const { return 20; }
|
||||
|
||||
virtual void getDeps(std::set<App::ObjectIdentifier> &props) const;
|
||||
|
||||
virtual App::Expression * simplify() const;
|
||||
|
||||
Range getRange() const { return range; }
|
||||
|
||||
void setRange(const Range & r);
|
||||
|
||||
protected:
|
||||
Range range;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing various functions, e.g sin, cos, etc.
|
||||
*
|
||||
*/
|
||||
|
||||
class SpreadsheetExport AggregateFunctionExpression : public App::FunctionExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
enum Function {
|
||||
NONE,
|
||||
|
||||
// Aggregates
|
||||
SUM = App::FunctionExpression::LAST,
|
||||
AVERAGE,
|
||||
STDDEV,
|
||||
COUNT,
|
||||
MIN,
|
||||
MAX
|
||||
};
|
||||
|
||||
AggregateFunctionExpression(const App::DocumentObject *_owner = 0,
|
||||
App::FunctionExpression::Function _f = App::FunctionExpression::NONE,
|
||||
std::vector<Expression *> _args = std::vector<Expression*>());
|
||||
|
||||
virtual ~AggregateFunctionExpression();
|
||||
|
||||
virtual Expression * copy() const;
|
||||
|
||||
virtual App::Expression * eval() const;
|
||||
|
||||
virtual std::string toString() const;
|
||||
};
|
||||
|
||||
namespace ExpressionParser {
|
||||
SpreadsheetExport App::Expression * parse(const App::DocumentObject *owner, const char *buffer);
|
||||
SpreadsheetExport App::UnitExpression * parseUnit(const App::DocumentObject *owner, const char *buffer);
|
||||
SpreadsheetExport App::ObjectIdentifier parsePath(const App::DocumentObject *owner, const char* buffer);
|
||||
}
|
||||
|
||||
}
|
||||
#endif // EXPRESSION_H
|
||||
@@ -32,9 +32,6 @@
|
||||
#include <Base/Exception.h>
|
||||
#include "Sheet.h"
|
||||
|
||||
const int Spreadsheet::CellAddress::MAX_ROWS = 16384;
|
||||
const int Spreadsheet::CellAddress::MAX_COLUMNS = 26 * 26 + 26;
|
||||
|
||||
/**
|
||||
* Encode \a col as a string.
|
||||
*
|
||||
@@ -74,126 +71,6 @@ std::string Spreadsheet::rowName(int row)
|
||||
return s.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a row specification into a 0-based integer.
|
||||
*
|
||||
* @param rowstr Row specified as a string, with "1" being the first row.
|
||||
*
|
||||
* @returns The row.
|
||||
*/
|
||||
|
||||
int Spreadsheet::decodeRow(const std::string &rowstr)
|
||||
{
|
||||
int row = validRow(rowstr);
|
||||
|
||||
if (row >= 0)
|
||||
return row;
|
||||
else
|
||||
throw Base::Exception("Invalid row specification.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a column specification into a 0-based integer.
|
||||
*
|
||||
* @param colstr Column specified as a string, with "A" begin the first column.
|
||||
*
|
||||
* @returns The column.
|
||||
*
|
||||
*/
|
||||
|
||||
int Spreadsheet::decodeColumn(const std::string &colstr)
|
||||
{
|
||||
int col = validColumn(colstr);
|
||||
|
||||
if (col >= 0)
|
||||
return col;
|
||||
else
|
||||
throw Base::Exception("Invalid column specification");
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine wheter a row specification is valid or not.
|
||||
*
|
||||
* @param rowstr Row specified as a string, with "1" being the first row.
|
||||
*
|
||||
* @returns 0 or positive on success, -1 on error.
|
||||
*/
|
||||
|
||||
int Spreadsheet::validRow(const std::string &rowstr)
|
||||
{
|
||||
char * end;
|
||||
int i = strtol(rowstr.c_str(), &end, 10);
|
||||
|
||||
if (i <0 || i >= CellAddress::MAX_ROWS || *end)
|
||||
return -1;
|
||||
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a column specification is valid or not.
|
||||
*
|
||||
* @param colstr Column specified as a string, with "A" begin the first column.
|
||||
*
|
||||
* @returns 0 or positive on success, -1 on error.
|
||||
*
|
||||
*/
|
||||
|
||||
int Spreadsheet::validColumn(const std::string &colstr)
|
||||
{
|
||||
int col = 0;
|
||||
|
||||
if (colstr.length() == 1) {
|
||||
if ((colstr[0] >= 'A' && colstr[0] <= 'Z'))
|
||||
col = colstr[0] - 'A';
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
col = 0;
|
||||
for (std::string::const_reverse_iterator i = colstr.rbegin(); i != colstr.rend(); ++i) {
|
||||
int v;
|
||||
|
||||
if ((*i >= 'A' && *i <= 'Z'))
|
||||
v = *i - 'A';
|
||||
else
|
||||
return -1;
|
||||
|
||||
col = col * 26 + v;
|
||||
}
|
||||
col += 26;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string address into integer \a row and \a column.
|
||||
* row and col are 0-based.
|
||||
*
|
||||
* This function will throw an exception if the specified \a address is invalid.
|
||||
*
|
||||
* @param address Address to parse.
|
||||
* @param row Reference to integer where row position is stored.
|
||||
* @param col Reference to integer where col position is stored.
|
||||
*
|
||||
*/
|
||||
|
||||
Spreadsheet::CellAddress Spreadsheet::stringToAddress(const char * strAddress)
|
||||
{
|
||||
static const boost::regex e("\\${0,1}([A-Z]{1,2})\\${0,1}([0-9]{1,5})");
|
||||
boost::cmatch cm;
|
||||
|
||||
Q_ASSERT(strAddress != 0);
|
||||
|
||||
if (boost::regex_match(strAddress, cm, e)) {
|
||||
const boost::sub_match<const char *> colstr = cm[1];
|
||||
const boost::sub_match<const char *> rowstr = cm[2];
|
||||
|
||||
return CellAddress(Spreadsheet::decodeRow(rowstr.str()), Spreadsheet::decodeColumn(colstr.str()));
|
||||
}
|
||||
else
|
||||
throw Base::Exception("Invalid cell specifier.");
|
||||
}
|
||||
|
||||
void Spreadsheet::createRectangles(std::set<std::pair<int, int> > & cells, std::map<std::pair<int, int>, std::pair<int, int> > & rectangles)
|
||||
{
|
||||
@@ -349,28 +226,3 @@ std::string Spreadsheet::unquote(const std::string & input)
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert given \a cell address into its string representation.
|
||||
*
|
||||
* @returns Address given as a string.
|
||||
*/
|
||||
|
||||
std::string Spreadsheet::CellAddress::toString() const
|
||||
{
|
||||
std::stringstream s;
|
||||
|
||||
if (col() < 26)
|
||||
s << (char)('A' + col());
|
||||
else {
|
||||
int colnum = col() - 26;
|
||||
|
||||
s << (char)('A' + (colnum / 26));
|
||||
s << (char)('A' + (colnum % 26));
|
||||
}
|
||||
|
||||
s << (row() + 1);
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
@@ -31,60 +31,13 @@
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
struct CellAddress;
|
||||
|
||||
SpreadsheetExport std::string columnName(int col);
|
||||
SpreadsheetExport std::string rowName(int row);
|
||||
int decodeColumn(const std::string &colstr);
|
||||
int decodeRow(const std::string &rowstr);
|
||||
int validColumn(const std::string &colstr);
|
||||
int validRow(const std::string &rowstr);
|
||||
|
||||
SpreadsheetExport CellAddress stringToAddress(const char *strAddress);
|
||||
SpreadsheetExport void createRectangles(std::set<std::pair<int, int> > & cells, std::map<std::pair<int, int>, std::pair<int, int> > & rectangles);
|
||||
SpreadsheetExport std::string quote(const std::string &input);
|
||||
SpreadsheetExport std::string unquote(const std::string & input);
|
||||
|
||||
struct SpreadsheetExport CellAddress {
|
||||
|
||||
CellAddress(int row = -1, int col = -1) : _row(row), _col(col) { }
|
||||
|
||||
CellAddress(const char * address) {
|
||||
*this = stringToAddress(address);
|
||||
}
|
||||
|
||||
CellAddress(const std::string & address) {
|
||||
*this = stringToAddress(address.c_str());
|
||||
}
|
||||
|
||||
inline int row() const { return _row; }
|
||||
|
||||
inline int col() const { return _col; }
|
||||
|
||||
inline bool operator<(const CellAddress & other) const { return asInt() < other.asInt(); }
|
||||
|
||||
inline bool operator==(const CellAddress & other) const { return asInt() == other.asInt(); }
|
||||
|
||||
inline bool operator!=(const CellAddress & other) const { return asInt() != other.asInt(); }
|
||||
|
||||
inline bool isValid() { return (row() >=0 && row() < MAX_ROWS && col() >= 0 && col() < MAX_COLUMNS); }
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
// Static members
|
||||
|
||||
static const int MAX_ROWS;
|
||||
|
||||
static const int MAX_COLUMNS;
|
||||
|
||||
protected:
|
||||
|
||||
inline unsigned int asInt() const { return ((_row << 16) | _col); }
|
||||
|
||||
short _row;
|
||||
short _col;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // UTILS_H
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include "SpreadsheetView.h"
|
||||
#include "../App/Sheet.h"
|
||||
#include "../App/Range.h"
|
||||
#include <App/Range.h>
|
||||
#include "ViewProviderSpreadsheet.h"
|
||||
#include "PropertiesDialog.h"
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
using namespace Base;
|
||||
using namespace App;
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
@@ -793,7 +794,7 @@ void CmdSpreadsheetSetAlias::activated(int iMsg)
|
||||
QModelIndexList selection = sheetView->selectedIndexes();
|
||||
|
||||
if (selection.size() == 1) {
|
||||
std::vector<Spreadsheet::Range> range;
|
||||
std::vector<Range> range;
|
||||
|
||||
range.push_back(Range(selection[0].row(), selection[0].column(),
|
||||
selection[0].row(), selection[0].column()));
|
||||
|
||||
@@ -24,8 +24,7 @@
|
||||
#include "PreCompiled.h"
|
||||
#include "PropertiesDialog.h"
|
||||
#include <Base/Tools.h>
|
||||
#include <Mod/Spreadsheet/App/SpreadsheetExpression.h>
|
||||
#include <Mod/Spreadsheet/App/Range.h>
|
||||
#include <App/Range.h>
|
||||
#include <Gui/Command.h>
|
||||
#include "ui_PropertiesDialog.h"
|
||||
|
||||
@@ -185,7 +184,7 @@ void PropertiesDialog::displayUnitChanged(const QString & text)
|
||||
|
||||
QPalette palette = ui->displayUnit->palette();
|
||||
try {
|
||||
std::auto_ptr<UnitExpression> e(Spreadsheet::ExpressionParser::parseUnit(sheet, text.toUtf8().constData()));
|
||||
std::auto_ptr<UnitExpression> e(App::ExpressionParser::parseUnit(sheet, text.toUtf8().constData()));
|
||||
|
||||
displayUnit = DisplayUnit(text.toUtf8().constData(), e->getUnit(), e->getScaler());
|
||||
palette.setColor(QPalette::Text, Qt::black);
|
||||
|
||||
@@ -37,7 +37,7 @@ class PropertiesDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PropertiesDialog(Spreadsheet::Sheet *_sheet, const std::vector<Spreadsheet::Range> & _ranges, QWidget *parent = 0);
|
||||
explicit PropertiesDialog(Spreadsheet::Sheet *_sheet, const std::vector<App::Range> & _ranges, QWidget *parent = 0);
|
||||
~PropertiesDialog();
|
||||
|
||||
void apply();
|
||||
@@ -52,7 +52,7 @@ private Q_SLOTS:
|
||||
void aliasChanged(const QString &text);
|
||||
private:
|
||||
Spreadsheet::Sheet * sheet;
|
||||
std::vector<Spreadsheet::Range> ranges;
|
||||
std::vector<App::Range> ranges;
|
||||
Ui::PropertiesDialog *ui;
|
||||
App::Color foregroundColor;
|
||||
App::Color backgroundColor;
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
#include <Gui/Application.h>
|
||||
#include "SheetModel.h"
|
||||
#include <Mod/Spreadsheet/App/SpreadsheetExpression.h>
|
||||
#include <Mod/Spreadsheet/App/Utils.h>
|
||||
#include "../App/Sheet.h"
|
||||
#include <Gui/Command.h>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <QAbstractTableModel>
|
||||
#include <boost/signals/connection.hpp>
|
||||
#include <Mod/Spreadsheet/App/Utils.h>
|
||||
#include <App/Range.h>
|
||||
|
||||
namespace Spreadsheet {
|
||||
class Sheet;
|
||||
@@ -49,7 +50,7 @@ public:
|
||||
Qt::ItemFlags flags(const QModelIndex &) const;
|
||||
|
||||
private:
|
||||
void cellUpdated(Spreadsheet::CellAddress address);
|
||||
void cellUpdated(App::CellAddress address);
|
||||
|
||||
boost::BOOST_SIGNALS_NAMESPACE::scoped_connection cellUpdatedConnection;
|
||||
Spreadsheet::Sheet * sheet;
|
||||
|
||||
@@ -29,13 +29,14 @@
|
||||
#include <Gui/Command.h>
|
||||
#include <boost/bind.hpp>
|
||||
#include "../App/Utils.h"
|
||||
#include "../App/Range.h"
|
||||
#include <App/Range.h>
|
||||
#include "SheetTableView.h"
|
||||
#include "LineEdit.h"
|
||||
#include "PropertiesDialog.h"
|
||||
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
using namespace App;
|
||||
|
||||
void SheetViewHeader::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
@@ -236,7 +237,7 @@ SheetTableView::~SheetTableView()
|
||||
|
||||
}
|
||||
|
||||
void SheetTableView::updateCellSpan(Spreadsheet::CellAddress address)
|
||||
void SheetTableView::updateCellSpan(CellAddress address)
|
||||
{
|
||||
int rows, cols;
|
||||
|
||||
|
||||
@@ -53,10 +53,10 @@ public:
|
||||
|
||||
void edit(const QModelIndex &index);
|
||||
void setSheet(Spreadsheet::Sheet *_sheet);
|
||||
std::vector<Spreadsheet::Range> selectedRanges() const;
|
||||
std::vector<App::Range> selectedRanges() const;
|
||||
protected Q_SLOTS:
|
||||
void commitData(QWidget *editor);
|
||||
void updateCellSpan(Spreadsheet::CellAddress address);
|
||||
void updateCellSpan(App::CellAddress address);
|
||||
void insertRows();
|
||||
void removeRows();
|
||||
void insertColumns();
|
||||
|
||||
@@ -37,9 +37,8 @@
|
||||
|
||||
#include "SpreadsheetView.h"
|
||||
#include "SpreadsheetDelegate.h"
|
||||
#include <Mod/Spreadsheet/App/SpreadsheetExpression.h>
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
#include <Mod/Spreadsheet/App/Range.h>
|
||||
#include <App/Range.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Document.h>
|
||||
@@ -57,6 +56,7 @@
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
using namespace Gui;
|
||||
using namespace App;
|
||||
|
||||
/* TRANSLATOR SpreadsheetGui::SheetView */
|
||||
|
||||
@@ -120,7 +120,7 @@ SheetView::SheetView(Gui::Document *pcDocument, App::DocumentObject *docObj, QWi
|
||||
|
||||
SheetView::~SheetView()
|
||||
{
|
||||
Application::Instance->detachView(this);
|
||||
Gui::Application::Instance->detachView(this);
|
||||
//delete delegate;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
|
||||
Spreadsheet::Sheet * getSheet() { return sheet; }
|
||||
|
||||
std::vector<Spreadsheet::Range> selectedRanges() const;
|
||||
std::vector<App::Range> selectedRanges() const;
|
||||
|
||||
QModelIndexList selectedIndexes() const;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "SpreadsheetView.h"
|
||||
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
#include <Mod/Spreadsheet/App/Range.h>
|
||||
#include <App/Range.h>
|
||||
#include <App/Document.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Application.h>
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
using namespace Base;
|
||||
using namespace Gui;
|
||||
using namespace App;
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
|
||||
@@ -37,10 +37,11 @@
|
||||
#include <QToolBar>
|
||||
#include "qtcolorpicker.h"
|
||||
#include "Mod/Spreadsheet/App/Sheet.h"
|
||||
#include "Mod/Spreadsheet/App/Range.h"
|
||||
#include <App/Range.h>
|
||||
#include "Mod/Spreadsheet/Gui/SpreadsheetView.h"
|
||||
|
||||
using namespace Base;
|
||||
using namespace App;
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user