Initial implementation of Spreadsheet module (C++ version) by Eivind Kvedalen.
Various fixes for Windows by Peter Lama <peterldev94@gmail.com> Werner Mayer <wmayer@users.sourceforge.net>
52
src/Mod/Spreadsheet/App/AppSpreadsheet.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program 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. *
|
||||
* for detail see the LICENCE text file. *
|
||||
* Jrgen Riegel 2002 *
|
||||
* Eivind Kvedalen 2015 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <Python.h>
|
||||
#endif
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include "Sheet.h"
|
||||
#include "Expression.h"
|
||||
|
||||
|
||||
/* registration table */
|
||||
static struct PyMethodDef Spreadsheet_methods[] = {
|
||||
{NULL, NULL} /* end of table marker */
|
||||
};
|
||||
|
||||
/* Python entry */
|
||||
extern "C" {
|
||||
void SpreadsheetExport initSpreadsheet() {
|
||||
(void) Py_InitModule("Spreadsheet", Spreadsheet_methods); /* mod name, table ptr */
|
||||
Base::Console().Log("Loading Spreadsheet module... done\n");
|
||||
|
||||
Spreadsheet::PropertyColumnWidths::init();
|
||||
Spreadsheet::PropertyRowHeights::init();
|
||||
Spreadsheet::PropertySheet::init();
|
||||
|
||||
Spreadsheet::Sheet::init();
|
||||
Spreadsheet::Expression::init();
|
||||
Spreadsheet::UnitExpression::init();
|
||||
Spreadsheet::NumberExpression::init();
|
||||
Spreadsheet::ConstantExpression::init();
|
||||
Spreadsheet::FunctionExpression::init();
|
||||
Spreadsheet::OperatorExpression::init();
|
||||
Spreadsheet::VariableExpression::init();
|
||||
Spreadsheet::ConditionalExpression::init();
|
||||
Spreadsheet::StringExpression::init();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
69
src/Mod/Spreadsheet/App/CMakeLists.txt
Normal file
@@ -0,0 +1,69 @@
|
||||
if(WIN32)
|
||||
add_definitions(-DFCAppSpreadsheet)
|
||||
endif(WIN32)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${PYTHON_INCLUDE_PATH}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${ZLIB_INCLUDE_DIR}
|
||||
${XERCESC_INCLUDE_DIR}
|
||||
${QT_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(Spreadsheet_LIBS
|
||||
FreeCADApp
|
||||
)
|
||||
|
||||
set(Spreadsheet_SRCS
|
||||
Expression.cpp
|
||||
Expression.h
|
||||
Cell.cpp
|
||||
Cell.h
|
||||
DisplayUnit.h
|
||||
PropertySheet.cpp
|
||||
PropertySheet.h
|
||||
PropertySheetPy.xml
|
||||
PropertySheetPyImp.cpp
|
||||
PropertyColumnWidths.cpp
|
||||
PropertyColumnWidths.h
|
||||
PropertyColumnWidthsPy.xml
|
||||
PropertyColumnWidthsPyImp.cpp
|
||||
PropertyRowHeights.cpp
|
||||
PropertyRowHeights.h
|
||||
PropertyRowHeightsPy.xml
|
||||
PropertyRowHeightsPyImp.cpp
|
||||
PreCompiled.cpp
|
||||
PreCompiled.h
|
||||
Sheet.cpp
|
||||
Sheet.h
|
||||
SheetPy.xml
|
||||
SheetPyImp.cpp
|
||||
SheetObserver.cpp
|
||||
SheetObserver.h
|
||||
Utils.cpp
|
||||
Utils.h
|
||||
Range.h
|
||||
Range.cpp
|
||||
AppSpreadsheet.cpp
|
||||
)
|
||||
|
||||
generate_from_xml(SheetPy)
|
||||
generate_from_xml(PropertySheetPy)
|
||||
generate_from_xml(PropertyColumnWidthsPy)
|
||||
generate_from_xml(PropertyRowHeightsPy)
|
||||
|
||||
add_library(Spreadsheet SHARED ${Spreadsheet_SRCS})
|
||||
target_link_libraries(Spreadsheet ${Spreadsheet_LIBS})
|
||||
|
||||
|
||||
fc_target_copy_resource(Spreadsheet
|
||||
${CMAKE_SOURCE_DIR}/src/Mod/Spreadsheet
|
||||
${CMAKE_BINARY_DIR}/Mod/Spreadsheet
|
||||
Init.py)
|
||||
|
||||
SET_BIN_DIR(Spreadsheet Spreadsheet /Mod/Spreadsheet)
|
||||
SET_PYTHON_PREFIX_SUFFIX(Spreadsheet)
|
||||
|
||||
INSTALL(TARGETS Spreadsheet DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
814
src/Mod/Spreadsheet/App/Cell.cpp
Normal file
@@ -0,0 +1,814 @@
|
||||
/***************************************************************************
|
||||
* 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"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include "Cell.h"
|
||||
#include "Utils.h"
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Writer.h>
|
||||
#include "Expression.h"
|
||||
#include "Sheet.h"
|
||||
#include <iomanip>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
using namespace App;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
const int Cell::EXPRESSION_SET = 1;
|
||||
const int Cell::ALIGNMENT_SET = 4;
|
||||
const int Cell::STYLE_SET = 8;
|
||||
const int Cell::BACKGROUND_COLOR_SET = 0x10;
|
||||
const int Cell::FOREGROUND_COLOR_SET = 0x20;
|
||||
const int Cell::DISPLAY_UNIT_SET = 0x40;
|
||||
const int Cell::COMPUTED_UNIT_SET = 0x80;
|
||||
const int Cell::ALIAS_SET = 0x100;
|
||||
const int Cell::SPANS_SET = 0x200;
|
||||
const int Cell::MARK_SET = 0x40000000;
|
||||
const int Cell::EXCEPTION_SET = 0x20000000;
|
||||
const int Cell::PARSE_EXCEPTION_SET = 0x80000000;
|
||||
const int Cell::RESOLVE_EXCEPTION_SET= 0x01000000;
|
||||
const int Cell::SPANS_UPDATED = 0x10000000;
|
||||
|
||||
/* Alignment */
|
||||
const int Cell::ALIGNMENT_LEFT = 0x01;
|
||||
const int Cell::ALIGNMENT_HCENTER = 0x02;
|
||||
const int Cell::ALIGNMENT_RIGHT = 0x04;
|
||||
const int Cell::ALIGNMENT_HIMPLIED = 0x08;
|
||||
const int Cell::ALIGNMENT_HORIZONTAL = 0x0f;
|
||||
const int Cell::ALIGNMENT_TOP = 0x10;
|
||||
const int Cell::ALIGNMENT_VCENTER = 0x20;
|
||||
const int Cell::ALIGNMENT_BOTTOM = 0x40;
|
||||
const int Cell::ALIGNMENT_VIMPLIED = 0x80;
|
||||
const int Cell::ALIGNMENT_VERTICAL = 0xf0;
|
||||
|
||||
/**
|
||||
* Construct a CellContent object.
|
||||
*
|
||||
* @param _row The row of the cell in the spreadsheet that contains is.
|
||||
* @param _col The column of the cell in the spreadsheet that contains is.
|
||||
* @param _owner The spreadsheet that owns this cell.
|
||||
*
|
||||
*/
|
||||
|
||||
Cell::Cell(const CellAddress &_address, PropertySheet *_owner)
|
||||
: address(_address)
|
||||
, owner(_owner)
|
||||
, used(0)
|
||||
, expression(0)
|
||||
, alignment(ALIGNMENT_HIMPLIED | ALIGNMENT_LEFT | ALIGNMENT_VIMPLIED | ALIGNMENT_VCENTER)
|
||||
, style()
|
||||
, foregroundColor(0, 0, 0, 1)
|
||||
, backgroundColor(1, 1, 1, 1)
|
||||
, displayUnit()
|
||||
, computedUnit()
|
||||
, rowSpan(1)
|
||||
, colSpan(1)
|
||||
, anchor()
|
||||
{
|
||||
assert(address.isValid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a CellContent object.
|
||||
*
|
||||
*/
|
||||
|
||||
Cell::Cell(const Cell &other)
|
||||
: address(other.address)
|
||||
, owner(other.owner)
|
||||
, used(other.used)
|
||||
, expression(other.expression ? other.expression->copy() : 0)
|
||||
, style(other.style)
|
||||
, alignment(other.alignment)
|
||||
, foregroundColor(other.foregroundColor)
|
||||
, backgroundColor(other.backgroundColor)
|
||||
, displayUnit(other.displayUnit)
|
||||
, computedUnit(other.computedUnit)
|
||||
, colSpan(other.colSpan)
|
||||
, rowSpan(other.rowSpan)
|
||||
{
|
||||
}
|
||||
|
||||
Cell &Cell::operator =(const Cell &rhs)
|
||||
{
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
used = 0;
|
||||
address = rhs.address;
|
||||
owner = rhs.owner;
|
||||
|
||||
setExpression(rhs.expression ? rhs.expression->copy() : 0);
|
||||
setStyle(rhs.style);
|
||||
setAlignment(rhs.alignment);
|
||||
setForeground(rhs.foregroundColor);
|
||||
setBackground(rhs.backgroundColor);
|
||||
setDisplayUnit(rhs.displayUnit.stringRep);
|
||||
setComputedUnit(rhs.computedUnit);
|
||||
setSpans(rhs.rowSpan, rhs.colSpan);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Cell::~Cell()
|
||||
{
|
||||
if (expression)
|
||||
delete expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the expression tree to \a expr.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::setExpression(Expression *expr)
|
||||
{
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
/* Remove dependencies */
|
||||
owner->removeDependencies(address);
|
||||
|
||||
if (expression)
|
||||
delete expression;
|
||||
expression = expr;
|
||||
setUsed(EXPRESSION_SET, expression != 0);
|
||||
|
||||
/* Update dependencies */
|
||||
owner->addDependencies(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the expression tree.
|
||||
*
|
||||
*/
|
||||
|
||||
const Expression *Cell::getExpression() const
|
||||
{
|
||||
return expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string content.
|
||||
*
|
||||
*/
|
||||
|
||||
bool Cell::getStringContent(std::string & s) const
|
||||
{
|
||||
if (expression) {
|
||||
if (freecad_dynamic_cast<StringExpression>(expression)) {
|
||||
s = static_cast<StringExpression*>(expression)->getText();
|
||||
char * end;
|
||||
errno = 0;
|
||||
strtod(s.c_str(), &end);
|
||||
if (!*end && errno == 0)
|
||||
s = "'" + s;
|
||||
}
|
||||
else if (freecad_dynamic_cast<ConstantExpression>(expression))
|
||||
s = "=" + expression->toString();
|
||||
else if (freecad_dynamic_cast<NumberExpression>(expression))
|
||||
s = expression->toString();
|
||||
else
|
||||
s = "=" + expression->toString();
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
s = "";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Cell::setContent(const char * value)
|
||||
{
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
Expression * expr = 0;
|
||||
|
||||
setUsed(PARSE_EXCEPTION_SET, false);
|
||||
if (value != 0) {
|
||||
if (*value == '=') {
|
||||
try {
|
||||
expr = ExpressionParser::parse(owner->sheet(), value + 1);
|
||||
}
|
||||
catch (Base::Exception & e) {
|
||||
QString msg = QString::fromUtf8("ERR: %1").arg(QString::fromUtf8(e.what()));
|
||||
expr = new StringExpression(owner->sheet(), value);
|
||||
setUsed(PARSE_EXCEPTION_SET);
|
||||
}
|
||||
}
|
||||
else if (*value == '\'')
|
||||
expr = new StringExpression(owner->sheet(), value + 1);
|
||||
else if (*value != '\0') {
|
||||
char * end;
|
||||
errno = 0;
|
||||
double float_value = strtod(value, &end);
|
||||
if (!*end && errno == 0)
|
||||
expr = new NumberExpression(owner->sheet(), float_value);
|
||||
else {
|
||||
try {
|
||||
expr = ExpressionParser::parse(owner->sheet(), value);
|
||||
if (expr)
|
||||
delete expr->eval();
|
||||
}
|
||||
catch (Base::Exception & e) {
|
||||
expr = new StringExpression(owner->sheet(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setExpression(expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set alignment of this cell. Alignment is the or'ed value of
|
||||
* vertical and horizontal alignment, given by the constants
|
||||
* defined in the class.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::setAlignment(int _alignment)
|
||||
{
|
||||
if (_alignment != alignment) {
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
alignment = _alignment;
|
||||
setUsed(ALIGNMENT_SET, alignment != (ALIGNMENT_HIMPLIED | ALIGNMENT_LEFT | ALIGNMENT_VIMPLIED | ALIGNMENT_VCENTER));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alignment.
|
||||
*
|
||||
*/
|
||||
|
||||
bool Cell::getAlignment(int & _alignment) const
|
||||
{
|
||||
_alignment = alignment;
|
||||
return isUsed(ALIGNMENT_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set style to the given set \a _style.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::setStyle(const std::set<std::string> & _style)
|
||||
{
|
||||
if (_style != style) {
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
style = _style;
|
||||
setUsed(STYLE_SET, style.size() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the style of the cell.
|
||||
*
|
||||
*/
|
||||
|
||||
bool Cell::getStyle(std::set<std::string> & _style) const
|
||||
{
|
||||
_style = style;
|
||||
return isUsed(STYLE_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set foreground (i.e text) color of the cell to \a color.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::setForeground(const Color &color)
|
||||
{
|
||||
if (color != foregroundColor) {
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
foregroundColor = color;
|
||||
setUsed(FOREGROUND_COLOR_SET, foregroundColor != App::Color(0, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get foreground color of the cell.
|
||||
*
|
||||
*/
|
||||
|
||||
bool Cell::getForeground(Color &color) const
|
||||
{
|
||||
color = foregroundColor;
|
||||
return isUsed(FOREGROUND_COLOR_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set background color of the cell to \a color.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::setBackground(const Color &color)
|
||||
{
|
||||
if (color != backgroundColor) {
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
backgroundColor = color;
|
||||
setUsed(BACKGROUND_COLOR_SET, backgroundColor != App::Color(1, 1, 1, 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background color of the cell into \a color.
|
||||
*
|
||||
* @returns true if the background color was previously set.
|
||||
*
|
||||
*/
|
||||
|
||||
bool Cell::getBackground(Color &color) const
|
||||
{
|
||||
color = backgroundColor;
|
||||
return isUsed(BACKGROUND_COLOR_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display unit for the cell.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::setDisplayUnit(const std::string &unit)
|
||||
{
|
||||
DisplayUnit newDisplayUnit;
|
||||
if (unit.size() > 0) {
|
||||
std::auto_ptr<UnitExpression> e(ExpressionParser::parseUnit(owner->sheet(), unit.c_str()));
|
||||
|
||||
newDisplayUnit = DisplayUnit(unit, e->getUnit(), e->getScaler());
|
||||
}
|
||||
|
||||
if (newDisplayUnit != displayUnit) {
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
displayUnit = newDisplayUnit;
|
||||
setUsed(DISPLAY_UNIT_SET, !displayUnit.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display unit for the cell into unit.
|
||||
*
|
||||
* @returns true if the display unit was previously set.
|
||||
*
|
||||
*/
|
||||
|
||||
bool Cell::getDisplayUnit(DisplayUnit &unit) const
|
||||
{
|
||||
unit = displayUnit;
|
||||
return isUsed(DISPLAY_UNIT_SET);
|
||||
}
|
||||
|
||||
void Cell::setAlias(const std::string &n)
|
||||
{
|
||||
if (alias != n) {
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
alias = n;
|
||||
setUsed(ALIAS_SET, !alias.empty());
|
||||
}
|
||||
}
|
||||
|
||||
bool Cell::getAlias(std::string &n) const
|
||||
{
|
||||
n = alias;
|
||||
return isUsed(ALIAS_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the computed unit for the cell to \a unit.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::setComputedUnit(const Base::Unit &unit)
|
||||
{
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
computedUnit = unit;
|
||||
setUsed(COMPUTED_UNIT_SET, !computedUnit.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the computed unit into \a unit.
|
||||
*
|
||||
* @returns true if the computed unit was previously set.
|
||||
*
|
||||
*/
|
||||
|
||||
bool Cell::getComputedUnit(Base::Unit & unit) const
|
||||
{
|
||||
unit = computedUnit;
|
||||
return isUsed(COMPUTED_UNIT_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cell's row and column span to \a rows and \a columns. This
|
||||
* is done when cells are merged.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::setSpans(int rows, int columns)
|
||||
{
|
||||
if (rows != rowSpan || columns != colSpan) {
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
rowSpan = rows;
|
||||
colSpan = columns;
|
||||
setUsed(SPANS_SET, (rowSpan != 1 || colSpan != 1) );
|
||||
setUsed(SPANS_UPDATED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the row and column spans for the cell into \a rows and \a columns.
|
||||
*
|
||||
*/
|
||||
|
||||
bool Cell::getSpans(int &rows, int &columns) const
|
||||
{
|
||||
rows = rowSpan;
|
||||
columns = colSpan;
|
||||
return isUsed(SPANS_SET);
|
||||
}
|
||||
|
||||
void Cell::setException(const std::string &e)
|
||||
{
|
||||
exceptionStr = e;
|
||||
setUsed(EXCEPTION_SET);
|
||||
}
|
||||
|
||||
void Cell::setParseException(const std::string &e)
|
||||
{
|
||||
exceptionStr = e;
|
||||
setUsed(PARSE_EXCEPTION_SET);
|
||||
}
|
||||
|
||||
void Cell::setResolveException(const std::string &e)
|
||||
{
|
||||
exceptionStr = e;
|
||||
setUsed(RESOLVE_EXCEPTION_SET);
|
||||
}
|
||||
|
||||
void Cell::clearResolveException()
|
||||
{
|
||||
setUsed(RESOLVE_EXCEPTION_SET, false);
|
||||
}
|
||||
|
||||
void Cell::clearException()
|
||||
{
|
||||
if (!isUsed(PARSE_EXCEPTION_SET))
|
||||
exceptionStr = "";
|
||||
setUsed(EXCEPTION_SET, false);
|
||||
}
|
||||
|
||||
void Cell::clearDirty()
|
||||
{
|
||||
owner->clearDirty(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the cell to a new position given by \a _row and \a _col.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::moveAbsolute(CellAddress newAddress)
|
||||
{
|
||||
address = newAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore cell contents from \a reader.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::restore(Base::XMLReader &reader)
|
||||
{
|
||||
const char* style = reader.hasAttribute("style") ? reader.getAttribute("style") : 0;
|
||||
const char* alignment = reader.hasAttribute("alignment") ? reader.getAttribute("alignment") : 0;
|
||||
const char* content = reader.hasAttribute("content") ? reader.getAttribute("content") : "";
|
||||
const char* foregroundColor = reader.hasAttribute("foregroundColor") ? reader.getAttribute("foregroundColor") : 0;
|
||||
const char* backgroundColor = reader.hasAttribute("backgroundColor") ? reader.getAttribute("backgroundColor") : 0;
|
||||
const char* displayUnit = reader.hasAttribute("displayUnit") ? reader.getAttribute("displayUnit") : 0;
|
||||
const char* alias = reader.hasAttribute("alias") ? reader.getAttribute("alias") : 0;
|
||||
const char* rowSpan = reader.hasAttribute("rowSpan") ? reader.getAttribute("rowSpan") : 0;
|
||||
const char* colSpan = reader.hasAttribute("colSpan") ? reader.getAttribute("colSpan") : 0;
|
||||
|
||||
// Don't trigger multiple updates below; wait until everything is loaded by calling unfreeze() below.
|
||||
PropertySheet::Signaller signaller(*owner);
|
||||
|
||||
if (content) {
|
||||
setContent(content);
|
||||
}
|
||||
if (style) {
|
||||
using namespace boost;
|
||||
std::set<std::string> styleSet;
|
||||
|
||||
escaped_list_separator<char> e('\0', '|', '\0');
|
||||
std::string line = std::string(style);
|
||||
tokenizer<escaped_list_separator<char> > tok(line, e);
|
||||
|
||||
for(tokenizer<escaped_list_separator<char> >::iterator i = tok.begin(); i != tok.end();++i)
|
||||
styleSet.insert(*i);
|
||||
setStyle(styleSet);
|
||||
}
|
||||
if (alignment) {
|
||||
int alignmentCode = 0;
|
||||
using namespace boost;
|
||||
|
||||
escaped_list_separator<char> e('\0', '|', '\0');
|
||||
std::string line = std::string(alignment);
|
||||
tokenizer<escaped_list_separator<char> > tok(line, e);
|
||||
|
||||
for(tokenizer<escaped_list_separator<char> >::iterator i = tok.begin(); i != tok.end();++i)
|
||||
alignmentCode = decodeAlignment(*i, alignmentCode);
|
||||
|
||||
setAlignment(alignmentCode);
|
||||
}
|
||||
if (foregroundColor) {
|
||||
Color color = decodeColor(foregroundColor, Color(0, 0, 0, 1));
|
||||
|
||||
setForeground(color);
|
||||
}
|
||||
if (backgroundColor) {
|
||||
Color color = decodeColor(backgroundColor, Color(1, 1, 1, 1));
|
||||
|
||||
setBackground(color);
|
||||
}
|
||||
if (displayUnit)
|
||||
setDisplayUnit(displayUnit);
|
||||
if (alias)
|
||||
setAlias(alias);
|
||||
|
||||
if (rowSpan || colSpan) {
|
||||
int rs = rowSpan ? atoi(rowSpan) : 1;
|
||||
int cs = colSpan ? atoi(colSpan) : 1;
|
||||
|
||||
setSpans(rs, cs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save cell contents into \a writer.
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::save(Base::Writer &writer) const
|
||||
{
|
||||
if (!isUsed())
|
||||
return;
|
||||
|
||||
writer.Stream() << writer.ind() << "<Cell ";
|
||||
|
||||
writer.Stream() << "address=\"" << addressToString(address) << "\" ";
|
||||
|
||||
if (isUsed(EXPRESSION_SET)) {
|
||||
std::string content;
|
||||
|
||||
getStringContent(content);
|
||||
writer.Stream() << "content=\"" << Property::encodeAttribute(content) << "\" ";
|
||||
}
|
||||
|
||||
if (isUsed(ALIGNMENT_SET))
|
||||
writer.Stream() << "alignment=\"" << encodeAlignment(alignment) << "\" ";
|
||||
|
||||
if (isUsed(STYLE_SET))
|
||||
writer.Stream() << "style=\"" << encodeStyle(style) << "\" ";
|
||||
|
||||
if (isUsed(FOREGROUND_COLOR_SET))
|
||||
writer.Stream() << "foregroundColor=\"" << encodeColor(foregroundColor) << "\" ";
|
||||
|
||||
if (isUsed(BACKGROUND_COLOR_SET))
|
||||
writer.Stream() << "backgroundColor=\"" << encodeColor(backgroundColor) << "\" ";
|
||||
|
||||
if (isUsed(DISPLAY_UNIT_SET))
|
||||
writer.Stream() << "displayUnit=\"" << Property::encodeAttribute(displayUnit.stringRep) << "\" ";
|
||||
|
||||
if (isUsed(ALIAS_SET))
|
||||
writer.Stream() << "alias=\"" << Property::encodeAttribute(alias) << "\" ";
|
||||
|
||||
if (isUsed(SPANS_SET)) {
|
||||
writer.Stream() << "rowSpan=\"" << rowSpan<< "\" ";
|
||||
writer.Stream() << "colSpan=\"" << colSpan << "\" ";
|
||||
}
|
||||
|
||||
writer.Stream() << "/>" << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the \a used member variable with mask (bitwise or'ed).
|
||||
*
|
||||
*/
|
||||
|
||||
void Cell::setUsed(int mask, bool state)
|
||||
{
|
||||
if (state)
|
||||
used |= mask;
|
||||
else
|
||||
used &= ~mask;
|
||||
|
||||
owner->setDirty(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the bits in \a mask are set in the \a used member variable.
|
||||
*
|
||||
*/
|
||||
|
||||
bool Cell::isUsed(int mask) const
|
||||
{
|
||||
return (used & mask) == mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the any of the contents of the cell is set a non-default value.
|
||||
*
|
||||
*/
|
||||
|
||||
bool Cell::isUsed() const
|
||||
{
|
||||
return used != 0;
|
||||
}
|
||||
|
||||
void Cell::visit(ExpressionVisitor &v)
|
||||
{
|
||||
if (expression)
|
||||
v.visit(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode aligment into its internal value.
|
||||
*
|
||||
* @param itemStr Alignment as a string
|
||||
* @param alignment Current alignment. This is or'ed with the one in \a itemStr.
|
||||
*
|
||||
* @returns New alignment.
|
||||
*
|
||||
*/
|
||||
|
||||
int Cell::decodeAlignment(const std::string & itemStr, int alignment)
|
||||
{
|
||||
if (itemStr == "himplied")
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_HORIZONTAL) | Cell::ALIGNMENT_HIMPLIED;
|
||||
else if (itemStr == "left")
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_HORIZONTAL) | Cell::ALIGNMENT_LEFT;
|
||||
else if (itemStr == "center")
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_HORIZONTAL) | Cell::ALIGNMENT_HCENTER;
|
||||
else if (itemStr == "right")
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_HORIZONTAL) | Cell::ALIGNMENT_RIGHT;
|
||||
else if (itemStr == "vimplied")
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_VERTICAL) | Cell::ALIGNMENT_VIMPLIED;
|
||||
else if (itemStr == "top")
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_VERTICAL) | Cell::ALIGNMENT_TOP;
|
||||
else if (itemStr == "vcenter")
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_VERTICAL) | Cell::ALIGNMENT_VCENTER;
|
||||
else if (itemStr == "bottom")
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_VERTICAL) | Cell::ALIGNMENT_BOTTOM;
|
||||
else
|
||||
throw Base::Exception("Invalid alignment.");
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode internal alignment value as a string.
|
||||
*
|
||||
* @param alignment Alignment as a binary value.
|
||||
*
|
||||
* @returns Alignment represented as a string.
|
||||
*
|
||||
*/
|
||||
|
||||
std::string Cell::encodeAlignment(int alignment)
|
||||
{
|
||||
std::string s;
|
||||
|
||||
if (alignment & Cell::ALIGNMENT_LEFT)
|
||||
s += "left";
|
||||
if (alignment & Cell::ALIGNMENT_HCENTER)
|
||||
s += "center";
|
||||
if (alignment & Cell::ALIGNMENT_RIGHT)
|
||||
s += "right";
|
||||
if (alignment & Cell::ALIGNMENT_HIMPLIED)
|
||||
s += "|himplied";
|
||||
|
||||
if (alignment & Cell::ALIGNMENT_VERTICAL)
|
||||
s += "|";
|
||||
|
||||
if (alignment & Cell::ALIGNMENT_TOP)
|
||||
s += "top";
|
||||
if (alignment & Cell::ALIGNMENT_VCENTER)
|
||||
s += "vcenter";
|
||||
if (alignment & Cell::ALIGNMENT_BOTTOM)
|
||||
s += "bottom";
|
||||
if (alignment & Cell::ALIGNMENT_VIMPLIED)
|
||||
s += "|vimplied";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode \a color as a #rrggbbaa string.
|
||||
*
|
||||
* @param color Color to encode.
|
||||
*
|
||||
* @returns String with encoded color.
|
||||
*
|
||||
*/
|
||||
|
||||
std::string Cell::encodeColor(const Color & color)
|
||||
{
|
||||
std::stringstream tmp;
|
||||
|
||||
tmp << "#"
|
||||
<< std::hex << std::setw(2) << std::setfill('0') << int(color.r * 255.0)
|
||||
<< std::hex << std::setw(2) << std::setfill('0') << int(color.g * 255.0)
|
||||
<< std::hex << std::setw(2) << std::setfill('0') << int(color.b * 255.0)
|
||||
<< std::hex << std::setw(2) << std::setfill('0') << int(color.a * 255.0);
|
||||
|
||||
return tmp.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode set of styles as a string.
|
||||
*
|
||||
* @param style Set of string describing the style.
|
||||
*
|
||||
* @returns Set encoded as a string.
|
||||
*
|
||||
*/
|
||||
|
||||
std::string Cell::encodeStyle(const std::set<std::string> & style)
|
||||
{
|
||||
std::string s;
|
||||
std::set<std::string>::const_iterator j = style.begin();
|
||||
std::set<std::string>::const_iterator j_end = style.end();
|
||||
|
||||
while (j != j_end) {
|
||||
s += *j;
|
||||
++j;
|
||||
if (j != j_end)
|
||||
s += "|";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a string of the format #rrggbb or #rrggbbaa into a Color.
|
||||
*
|
||||
* @param color The color to decode.
|
||||
* @param defaultColor A default color in case the decoding fails.
|
||||
*
|
||||
* @returns Decoded color.
|
||||
*
|
||||
*/
|
||||
|
||||
Color Cell::decodeColor(const std::string & color, const Color & defaultColor)
|
||||
{
|
||||
if (color.size() == 7 || color.size() == 9) {
|
||||
Color c;
|
||||
|
||||
if (color[0] != '#')
|
||||
return defaultColor;
|
||||
unsigned int value = strtoul(color.c_str() + 1, 0, 16);
|
||||
|
||||
if (color.size() == 7)
|
||||
value = (value << 8) | 0xff;
|
||||
|
||||
c.setPackedValue(value);
|
||||
return c;
|
||||
}
|
||||
else
|
||||
return defaultColor;
|
||||
}
|
||||
|
||||
|
||||
190
src/Mod/Spreadsheet/App/Cell.h
Normal file
@@ -0,0 +1,190 @@
|
||||
/***************************************************************************
|
||||
* 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 CELL_H
|
||||
#define CELL_H
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <App/Material.h>
|
||||
#include "DisplayUnit.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace Base {
|
||||
class Unit;
|
||||
class XMLReader;
|
||||
class Writer;
|
||||
}
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
class PropertySheet;
|
||||
class Expression;
|
||||
class DisplayUnit;
|
||||
class ExpressionVisitor;
|
||||
|
||||
class SpreadsheetExport Cell {
|
||||
|
||||
public:
|
||||
|
||||
Cell(const CellAddress & _address, PropertySheet * _owner);
|
||||
|
||||
Cell(const Cell & other);
|
||||
|
||||
Cell& operator=( const Cell& rhs );
|
||||
|
||||
~Cell();
|
||||
|
||||
const Expression * getExpression() const;
|
||||
|
||||
bool getStringContent(std::string & s) const;
|
||||
|
||||
void setContent(const char * value);
|
||||
|
||||
void setAlignment(int _alignment);
|
||||
bool getAlignment(int & _alignment) const;
|
||||
|
||||
void setStyle(const std::set<std::string> & _style);
|
||||
bool getStyle(std::set<std::string> & style) const;
|
||||
|
||||
void setForeground(const App::Color &color);
|
||||
bool getForeground(App::Color &color) const;
|
||||
|
||||
void setBackground(const App::Color &color);
|
||||
bool getBackground(App::Color &color) const;
|
||||
|
||||
void setDisplayUnit(const std::string & unit);
|
||||
bool getDisplayUnit(DisplayUnit &unit) const;
|
||||
|
||||
void setAlias(const std::string & n);
|
||||
bool getAlias(std::string & n ) const;
|
||||
|
||||
void setComputedUnit(const Base::Unit & unit);
|
||||
bool getComputedUnit(Base::Unit & unit) const;
|
||||
|
||||
void setSpans(int rows, int columns);
|
||||
bool getSpans(int & rows, int & columns) const;
|
||||
|
||||
void setException(const std::string & e);
|
||||
|
||||
void clearException();
|
||||
|
||||
void clearDirty();
|
||||
|
||||
void setParseException(const std::string & e);
|
||||
|
||||
void setResolveException(const std::string &e);
|
||||
|
||||
void clearResolveException();
|
||||
|
||||
const std::string &getException() const { return exceptionStr; }
|
||||
|
||||
bool hasException() const { return isUsed(EXCEPTION_SET) || isUsed(PARSE_EXCEPTION_SET) || isUsed(RESOLVE_EXCEPTION_SET); }
|
||||
|
||||
void moveAbsolute(CellAddress newAddress);
|
||||
|
||||
void restore(Base::XMLReader &reader);
|
||||
|
||||
void save(Base::Writer &writer) const;
|
||||
|
||||
bool isUsed() const;
|
||||
|
||||
void mark() { setUsed(MARK_SET); }
|
||||
|
||||
bool isMarked() const { return isUsed(MARK_SET); }
|
||||
|
||||
bool spansChanged() const { return isUsed(SPANS_UPDATED); }
|
||||
|
||||
void visit(ExpressionVisitor & v);
|
||||
|
||||
/* Alignment */
|
||||
static const int ALIGNMENT_LEFT;
|
||||
static const int ALIGNMENT_HCENTER;
|
||||
static const int ALIGNMENT_RIGHT;
|
||||
static const int ALIGNMENT_HORIZONTAL;
|
||||
static const int ALIGNMENT_HIMPLIED;
|
||||
static const int ALIGNMENT_TOP;
|
||||
static const int ALIGNMENT_VCENTER;
|
||||
static const int ALIGNMENT_BOTTOM;
|
||||
static const int ALIGNMENT_VERTICAL;
|
||||
static const int ALIGNMENT_VIMPLIED;
|
||||
|
||||
/* Static functions */
|
||||
static int decodeAlignment(const std::string &itemStr, int alignment);
|
||||
static std::string encodeAlignment(int alignment);
|
||||
|
||||
static std::string encodeStyle(const std::set<std::string> &style);
|
||||
|
||||
static std::string encodeColor(const App::Color &color);
|
||||
static App::Color decodeColor(const std::string &color, const App::Color &defaultColor);
|
||||
|
||||
private:
|
||||
|
||||
//void setExpression(const Expression * expr);
|
||||
|
||||
void setExpression(Expression *expr);
|
||||
|
||||
void setUsed(int mask, bool state = true);
|
||||
|
||||
bool isUsed(int mask) const;
|
||||
|
||||
void freeze();
|
||||
|
||||
void unfreeze();
|
||||
|
||||
/* Used */
|
||||
static const int EXPRESSION_SET;
|
||||
static const int ALIGNMENT_SET;
|
||||
static const int STYLE_SET;
|
||||
static const int BACKGROUND_COLOR_SET;
|
||||
static const int FOREGROUND_COLOR_SET;
|
||||
static const int DISPLAY_UNIT_SET;
|
||||
static const int COMPUTED_UNIT_SET;
|
||||
static const int ALIAS_SET;
|
||||
static const int SPANS_SET;
|
||||
static const int MARK_SET;
|
||||
static const int SPANS_UPDATED;
|
||||
static const int EXCEPTION_SET;
|
||||
static const int PARSE_EXCEPTION_SET;
|
||||
static const int RESOLVE_EXCEPTION_SET;
|
||||
|
||||
CellAddress address;
|
||||
PropertySheet * owner;
|
||||
|
||||
int used;
|
||||
Expression * expression;
|
||||
int alignment;
|
||||
std::set<std::string> style;
|
||||
App::Color foregroundColor;
|
||||
App::Color backgroundColor;
|
||||
DisplayUnit displayUnit;
|
||||
std::string alias;
|
||||
Base::Unit computedUnit;
|
||||
int rowSpan;
|
||||
int colSpan;
|
||||
std::string exceptionStr;
|
||||
CellAddress anchor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CELL_H
|
||||
61
src/Mod/Spreadsheet/App/DisplayUnit.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/***************************************************************************
|
||||
* 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 DISPLAYUNIT_H
|
||||
#define DISPLAYUNIT_H
|
||||
|
||||
#include <string>
|
||||
#include <Base/Unit.h>
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
class DisplayUnit {
|
||||
public:
|
||||
|
||||
std::string stringRep;
|
||||
Base::Unit unit;
|
||||
double scaler;
|
||||
|
||||
DisplayUnit(const std::string _stringRep = "", const Base::Unit _unit = Base::Unit(), double _scaler = 0.0)
|
||||
: stringRep(_stringRep)
|
||||
, unit(_unit)
|
||||
, scaler(_scaler)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const DisplayUnit& c) const
|
||||
{
|
||||
return c.stringRep == stringRep && c.unit == unit && c.scaler == scaler;
|
||||
}
|
||||
|
||||
bool operator!=(const DisplayUnit& c) const
|
||||
{
|
||||
return !operator==(c);
|
||||
}
|
||||
|
||||
bool isEmpty() const { return stringRep.size() == 0; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DISPLAYUNIT_H
|
||||
1862
src/Mod/Spreadsheet/App/Expression.cpp
Normal file
548
src/Mod/Spreadsheet/App/Expression.h
Normal file
@@ -0,0 +1,548 @@
|
||||
/***************************************************************************
|
||||
* 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 EXPRESSION_H
|
||||
#define 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 Expression;
|
||||
|
||||
class SpreadsheetExport ExpressionVisitor {
|
||||
public:
|
||||
virtual ~ExpressionVisitor() {}
|
||||
virtual void visit(Expression * e) = 0;
|
||||
};
|
||||
|
||||
class SpreadsheetExport Path {
|
||||
|
||||
public:
|
||||
|
||||
class String {
|
||||
public:
|
||||
String(const std::string & s = "", bool _isRealString = false) : str(s), isString(_isRealString) { }
|
||||
|
||||
std::string getString() const { return str; }
|
||||
|
||||
operator std::string() const { return str; }
|
||||
|
||||
operator const char *() const { return str.c_str(); }
|
||||
|
||||
bool operator==(const String & other) const { return str == other.str; }
|
||||
|
||||
bool operator!=(const String & other) const { return str != other.str; }
|
||||
|
||||
bool operator>=(const String & other) const { return str >= other.str; }
|
||||
|
||||
bool operator<(const String & other) const { return str < other.str; }
|
||||
|
||||
bool operator>(const String & other) const { return str > other.str; }
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
bool isRealString() const { return isString; }
|
||||
|
||||
std::string str;
|
||||
bool isString;
|
||||
};
|
||||
|
||||
struct SpreadsheetExport Component {
|
||||
|
||||
enum typeEnum {
|
||||
SIMPLE,
|
||||
MAP,
|
||||
ARRAY
|
||||
} ;
|
||||
|
||||
std::string component;
|
||||
typeEnum type;
|
||||
int index;
|
||||
String key;
|
||||
bool keyIsString;
|
||||
|
||||
Component(const std::string & _component, typeEnum _type = SIMPLE, int _index = -1, String _key = String());
|
||||
|
||||
static Component SimpleComponent(const std::string & _component);
|
||||
|
||||
static Component ArrayComponent(const std::string & _component, int _index);
|
||||
|
||||
static Component MapComponent(const std::string & _component, const String &_key);
|
||||
|
||||
bool operator==(const Component & other) const;
|
||||
|
||||
bool isSimple() const { return type == SIMPLE; }
|
||||
|
||||
bool isMap() const { return type == MAP; }
|
||||
|
||||
bool isArray() const { return type == ARRAY; }
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
};
|
||||
|
||||
Path(const App::DocumentObject * _owner = 0, const std::string & property = std::string());
|
||||
|
||||
void addComponent(const Component &c) { components.push_back(c); resolve(); }
|
||||
|
||||
template<typename C>
|
||||
void addComponents(const C &cs) { components.insert(components.end(), cs.begin(), cs.end()); resolve(); }
|
||||
|
||||
void setDocumentName(const String & name, bool force = false) { documentName = name; documentNameSet = force; }
|
||||
|
||||
const String getDocumentName() const { return documentName; }
|
||||
|
||||
void setDocumentObjectName(const String & name, bool force = false) { documentObjectName = name; documentObjectNameSet = force; }
|
||||
|
||||
const String getDocumentObjectName() const { return documentObjectName; }
|
||||
|
||||
const std::string & getPropertyName() const { return components[propertyIndex].component; }
|
||||
|
||||
const Component & getPropertyComponent(int i) const { assert(i >=0 && i < components.size()); return components[propertyIndex + i]; }
|
||||
|
||||
const std::string & getSubComponent(int i) const { assert(i >= 1); return components[propertyIndex - 1].component; }
|
||||
|
||||
std::string getSubPathStr() const;
|
||||
|
||||
bool operator==(const Path & other) const;
|
||||
|
||||
bool operator!=(const Path & other) const { return !(operator==)(other); }
|
||||
|
||||
bool operator<(const Path &other) const;
|
||||
|
||||
int numComponents() const;
|
||||
|
||||
static Path parse(const App::DocumentObject * _owner, const char * expr);
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
void resolve();
|
||||
|
||||
void resetResolve();
|
||||
|
||||
const App::Property *getProperty() const;
|
||||
|
||||
std::string getPythonAccessor() const;
|
||||
|
||||
void renameDocumentObject(const std::string & oldName, const std::string & newName);
|
||||
|
||||
void renameDocument(const std::string &oldName, const std::string &newName);
|
||||
|
||||
App::Document *getDocument() const;
|
||||
|
||||
protected:
|
||||
|
||||
const App::DocumentObject *getDocumentObject(const App::Document *doc, const std::string &name) const;
|
||||
|
||||
const App::DocumentObject * owner;
|
||||
mutable int propertyIndex;
|
||||
String documentName;
|
||||
bool documentNameSet;
|
||||
String documentObjectName;
|
||||
bool documentObjectNameSet;
|
||||
std::string propertyName;
|
||||
|
||||
std::vector<Component> components;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for expressions.
|
||||
*
|
||||
*/
|
||||
|
||||
class SpreadsheetExport Expression : public Base::BaseClass {
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
|
||||
Expression(const App::DocumentObject * _owner);
|
||||
|
||||
virtual ~Expression();
|
||||
|
||||
virtual bool isTouched() const { return false; }
|
||||
|
||||
virtual Expression * eval() const = 0;
|
||||
|
||||
virtual std::string toString() const = 0;
|
||||
|
||||
static Expression * parse(const App::DocumentObject * owner, const std::string& buffer);
|
||||
|
||||
virtual Expression * copy() const = 0;
|
||||
|
||||
virtual int priority() const { return 0; }
|
||||
|
||||
virtual void getDeps(std::set<Path> &props) const { }
|
||||
|
||||
virtual Expression * simplify() const = 0;
|
||||
|
||||
virtual void visit(ExpressionVisitor & v) { v.visit(this); }
|
||||
|
||||
class Exception : public Base::Exception {
|
||||
public:
|
||||
Exception(const char *sMessage) : Base::Exception(sMessage) { }
|
||||
};
|
||||
|
||||
const App::DocumentObject * getOwner() const { return owner; }
|
||||
|
||||
protected:
|
||||
const App::DocumentObject * owner; /**< The document object used to access unqualified variables (i.e local scope) */
|
||||
};
|
||||
|
||||
/**
|
||||
* Part of an expressions that contains a unit.
|
||||
*
|
||||
*/
|
||||
|
||||
class SpreadsheetExport UnitExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
UnitExpression(const App::DocumentObject *_owner = 0, const Base::Quantity & _quantity = Base::Quantity(), const std::string & _unitStr = std::string());
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
virtual Expression * copy() const;
|
||||
|
||||
virtual int priority() const { return 10; }
|
||||
|
||||
void setUnit(const Base::Quantity &_quantity);
|
||||
|
||||
double getValue() const { return quantity.getValue(); }
|
||||
|
||||
const Base::Unit & getUnit() const { return quantity.getUnit(); }
|
||||
|
||||
const Base::Quantity & getQuantity() const { return quantity; }
|
||||
|
||||
const std::string getUnitString() const { return unitStr; }
|
||||
|
||||
double getScaler() const { return quantity.getValue(); }
|
||||
|
||||
protected:
|
||||
Base::Quantity quantity;
|
||||
std::string unitStr; /**< The unit string from the original parsed string */
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a number with an optional unit
|
||||
*/
|
||||
|
||||
class SpreadsheetExport NumberExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
NumberExpression(const App::DocumentObject *_owner = 0, const Base::Quantity & quantity = Base::Quantity());
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual Expression * copy() const;
|
||||
|
||||
virtual int priority() const { return 10; }
|
||||
|
||||
void negate();
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
class SpreadsheetExport ConstantExpression : public NumberExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
ConstantExpression(const App::DocumentObject *_owner = 0, std::string _name = "", const Base::Quantity &_quantity = Base::Quantity());
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
virtual Expression * copy() const;
|
||||
|
||||
virtual int priority() const { return 10; }
|
||||
|
||||
std::string getName() const { return name; }
|
||||
|
||||
protected:
|
||||
std::string name; /**< Constant's name */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class implementing an infix expression.
|
||||
*
|
||||
*/
|
||||
|
||||
class SpreadsheetExport OperatorExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
enum Operator {
|
||||
NONE,
|
||||
ADD,
|
||||
SUB,
|
||||
MUL,
|
||||
DIV,
|
||||
POW,
|
||||
EQ,
|
||||
NEQ,
|
||||
LT,
|
||||
GT,
|
||||
LTE,
|
||||
GTE,
|
||||
UNIT
|
||||
};
|
||||
OperatorExpression(const App::DocumentObject *_owner = 0, Expression * _left = 0, Operator _op = NONE, Expression * _right = 0);
|
||||
|
||||
virtual ~OperatorExpression();
|
||||
|
||||
virtual bool isTouched() const;
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
virtual Expression * copy() const;
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
virtual void getDeps(std::set<Path> &props) const;
|
||||
|
||||
virtual void visit(ExpressionVisitor & v);
|
||||
|
||||
protected:
|
||||
Operator op; /**< Operator working on left and right */
|
||||
Expression * left; /**< Left operand */
|
||||
Expression * right; /**< Right operand */
|
||||
};
|
||||
|
||||
class SpreadsheetExport RangeExpression : public 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 0; }
|
||||
|
||||
virtual void getDeps(std::set<Path> &props) const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
Range getRange() const { return range; }
|
||||
|
||||
protected:
|
||||
Range range;
|
||||
};
|
||||
|
||||
class SpreadsheetExport ConditionalExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
ConditionalExpression(const App::DocumentObject *_owner = 0, Expression * _condition = 0,Expression * _trueExpr = 0, Expression * _falseExpr = 0);
|
||||
|
||||
virtual ~ConditionalExpression();
|
||||
|
||||
virtual bool isTouched() const;
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
virtual Expression * copy() const;
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
virtual void getDeps(std::set<Path> &props) const;
|
||||
|
||||
virtual void visit(ExpressionVisitor & v);
|
||||
|
||||
protected:
|
||||
|
||||
Expression * condition; /**< Condition */
|
||||
Expression * trueExpr; /**< Expression if abs(condition) is > 0.5 */
|
||||
Expression * falseExpr; /**< Expression if abs(condition) is < 0.5 */
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing various functions, e.g sin, cos, etc.
|
||||
*
|
||||
*/
|
||||
|
||||
class SpreadsheetExport FunctionExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
enum Function {
|
||||
NONE,
|
||||
|
||||
// Normal functions taking one or two arguments
|
||||
ACOS,
|
||||
ASIN,
|
||||
ATAN,
|
||||
ABS,
|
||||
EXP,
|
||||
LOG,
|
||||
LOG10,
|
||||
SIN,
|
||||
SINH,
|
||||
TAN,
|
||||
TANH,
|
||||
SQRT,
|
||||
COS,
|
||||
COSH,
|
||||
ATAN2,
|
||||
MOD,
|
||||
POW,
|
||||
|
||||
// Aggregates
|
||||
SUM,
|
||||
AVERAGE,
|
||||
STDDEV,
|
||||
COUNT,
|
||||
MIN,
|
||||
MAX
|
||||
};
|
||||
|
||||
FunctionExpression(const App::DocumentObject *_owner = 0, Function _f = NONE, std::vector<Expression *> _args = std::vector<Expression*>());
|
||||
|
||||
virtual ~FunctionExpression();
|
||||
|
||||
virtual bool isTouched() const;
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
virtual Expression * copy() const;
|
||||
|
||||
virtual int priority() const { return 10; }
|
||||
|
||||
virtual void getDeps(std::set<Path> &props) const;
|
||||
|
||||
virtual void visit(ExpressionVisitor & v);
|
||||
|
||||
protected:
|
||||
Function f; /**< Function to execute */
|
||||
std::vector<Expression *> args; /** Arguments to function*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a reference to a property. If the name is unqualified,
|
||||
* the owner of the expression is searched. If it is qualified, the document
|
||||
* that contains the owning document object is searched for other document
|
||||
* objects to search. Both labels and internal document names are searched.
|
||||
*
|
||||
*/
|
||||
|
||||
class SpreadsheetExport VariableExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
VariableExpression(const App::DocumentObject *_owner = 0, Path _var = Path());
|
||||
|
||||
~VariableExpression();
|
||||
|
||||
virtual bool isTouched() const;
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString() const { return var.toString(); }
|
||||
|
||||
virtual Expression * copy() const;
|
||||
|
||||
virtual int priority() const { return 10; }
|
||||
|
||||
virtual void getDeps(std::set<Path> &props) const;
|
||||
|
||||
std::string name() const { return var.getPropertyName(); }
|
||||
|
||||
Path getPath() const { return var; }
|
||||
|
||||
void setName(const std::string & name) { assert(0); }
|
||||
|
||||
void resolve();
|
||||
|
||||
void renameDocumentObject(const std::string & oldName, const std::string & newName);
|
||||
|
||||
void renameDocument(const std::string &oldName, const std::string &newName);
|
||||
|
||||
protected:
|
||||
|
||||
const App::Property *getProperty() const;
|
||||
|
||||
Path var; /**< Variable name */
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a string. Used to signal either a genuine string or
|
||||
* a failed evaluation of an expression.
|
||||
*/
|
||||
|
||||
class SpreadsheetExport StringExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
StringExpression(const App::DocumentObject *_owner = 0, const std::string & _text = std::string());
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString() const;
|
||||
|
||||
virtual std::string getText() const { return text; }
|
||||
|
||||
virtual Expression * copy() const;
|
||||
|
||||
protected:
|
||||
|
||||
std::string text; /**< Text string */
|
||||
};
|
||||
|
||||
namespace ExpressionParser {
|
||||
SpreadsheetExport Expression * parse(const App::DocumentObject *owner, const char *buffer);
|
||||
SpreadsheetExport UnitExpression * parseUnit(const App::DocumentObject *owner, const char *buffer);
|
||||
SpreadsheetExport Path parsePath(const App::DocumentObject *owner, const char* buffer);
|
||||
}
|
||||
|
||||
}
|
||||
#endif // EXPRESSION_H
|
||||
267
src/Mod/Spreadsheet/App/ExpressionParser.l
Normal file
2207
src/Mod/Spreadsheet/App/ExpressionParser.tab.c
Normal file
184
src/Mod/Spreadsheet/App/ExpressionParser.y
Normal file
@@ -0,0 +1,184 @@
|
||||
/* 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 */
|
||||
|
||||
%{
|
||||
|
||||
class semantic_type {
|
||||
public:
|
||||
struct {
|
||||
Quantity scaler;
|
||||
std::string unitStr;
|
||||
} quantity;
|
||||
Expression * expr;
|
||||
Path path;
|
||||
std::deque<Path::Component> components;
|
||||
int ivalue;
|
||||
double fvalue;
|
||||
struct {
|
||||
std::string name;
|
||||
double fvalue;
|
||||
} constant;
|
||||
std::vector<Expression*> arguments;
|
||||
std::string string;
|
||||
FunctionExpression::Function func;
|
||||
Path::String string_or_identifier;
|
||||
semantic_type() {}
|
||||
};
|
||||
|
||||
#define YYSTYPE 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 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> NUM
|
||||
%type <constant> CONSTANT
|
||||
%type <expr> num
|
||||
%type <expr> range
|
||||
%type <path> identifier
|
||||
%type <components> path
|
||||
%type <func> FUNC
|
||||
%type <string_or_identifier> document
|
||||
%type <string_or_identifier> object
|
||||
%left NUM
|
||||
%left INTEGER
|
||||
%left CONSTANT
|
||||
%left '-' '+'
|
||||
%left '*' '/'
|
||||
%left '?' ':' EQ NEQ LT GT GTE LTE
|
||||
%left NEG /* negation--unary minus */
|
||||
%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); }
|
||||
| exp '+' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::ADD, $3); }
|
||||
| exp '-' 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); }
|
||||
| MINUSSIGN exp %prec NEG { $$ = new OperatorExpression(DocumentObject,
|
||||
new NumberExpression(DocumentObject, -1.0),
|
||||
OperatorExpression::MUL, $2); }
|
||||
| exp '^' exp %prec NUM { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, $3); }
|
||||
| '(' exp ')' { $$ = $2; }
|
||||
| FUNC args ')' { $$ = new FunctionExpression(DocumentObject, $1, $2); }
|
||||
| cond '?' exp ':' exp { $$ = new ConditionalExpression(DocumentObject, $1, $3, $5); }
|
||||
;
|
||||
|
||||
num: NUM { $$ = new NumberExpression(DocumentObject, $1); }
|
||||
| INTEGER { $$ = new NumberExpression(DocumentObject, (double)$1); }
|
||||
| CONSTANT { $$ = new ConstantExpression(DocumentObject, $1.name, $1.fvalue); }
|
||||
| NUM unit_exp %prec EXPONENT { $$ = new OperatorExpression(DocumentObject, new NumberExpression(DocumentObject, $1), OperatorExpression::UNIT, $2); }
|
||||
| INTEGER unit_exp { $$ = new OperatorExpression(DocumentObject, new NumberExpression(DocumentObject, (double)$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 ); }
|
||||
| unit_exp '/' unit_exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); }
|
||||
| unit_exp '*' unit_exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MUL, $3); }
|
||||
| unit_exp '^' NUM %prec EXPONENT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, new NumberExpression(DocumentObject, $3)); }
|
||||
| unit_exp '^' '-' NUM %prec EXPONENT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, new NumberExpression(DocumentObject, -$4)); }
|
||||
| unit_exp '^' INTEGER %prec EXPONENT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, new NumberExpression(DocumentObject, (double)$3)); }
|
||||
| unit_exp '^' MINUSSIGN INTEGER %prec EXPONENT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, new NumberExpression(DocumentObject, -(double)$4)); }
|
||||
| '(' unit_exp ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
identifier: path { /* Path to property within document object */
|
||||
$$ = Path(DocumentObject);
|
||||
$$.addComponents($1);
|
||||
}
|
||||
| object '.' path { /* Path to property within document object */
|
||||
$$ = Path(DocumentObject);
|
||||
$$.setDocumentObjectName($1, true);
|
||||
$$.addComponents($3);
|
||||
}
|
||||
| document '#' path { /* Path to property from an external document, within a named document object */
|
||||
$$ = Path(DocumentObject);
|
||||
$$.setDocumentName($1, true);
|
||||
$$.addComponents($3);
|
||||
}
|
||||
| document '#' object '.' path { /* Path to property from an external document, within a named document object */
|
||||
$$ = Path(DocumentObject);
|
||||
$$.setDocumentName($1, true);
|
||||
$$.setDocumentObjectName($3, true);
|
||||
$$.addComponents($5);
|
||||
}
|
||||
;
|
||||
|
||||
path: IDENTIFIER { $$.push_front(Path::Component::SimpleComponent($1)); }
|
||||
| CELLADDRESS { $$.push_front(Path::Component::SimpleComponent($1)); }
|
||||
| IDENTIFIER '[' INTEGER ']' { $$.push_front(Path::Component::ArrayComponent($1, $3)); }
|
||||
| IDENTIFIER '[' INTEGER ']' '.' path { $6.push_front(Path::Component::ArrayComponent($1, $3)); $$ = $6; }
|
||||
| IDENTIFIER '[' STRING ']' { $$.push_front(Path::Component::MapComponent($1, Path::String($3, true))); }
|
||||
| IDENTIFIER '[' IDENTIFIER ']' { $$.push_front(Path::Component::MapComponent($1, $3)); }
|
||||
| IDENTIFIER '[' STRING ']' '.' path { $6.push_front(Path::Component::MapComponent($1, Path::String($3, true))); $$ = $6; }
|
||||
| IDENTIFIER '[' IDENTIFIER ']' '.' path { $6.push_front(Path::Component::MapComponent($1, $3)); $$ = $6; }
|
||||
| IDENTIFIER '.' path { $3.push_front(Path::Component::SimpleComponent($1)); $$ = $3; }
|
||||
;
|
||||
|
||||
document: STRING { $$ = Path::String($1, true); }
|
||||
| IDENTIFIER { $$ = Path::String($1); }
|
||||
;
|
||||
|
||||
object: STRING { $$ = Path::String($1, true); }
|
||||
| CELLADDRESS { $$ = Path::String($1, true); }
|
||||
;
|
||||
|
||||
%%
|
||||
24
src/Mod/Spreadsheet/App/PreCompiled.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 *
|
||||
* *
|
||||
* 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"
|
||||
59
src/Mod/Spreadsheet/App/PreCompiled.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 *
|
||||
* *
|
||||
* 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 __PRECOMPILED__
|
||||
#define __PRECOMPILED__
|
||||
|
||||
#include <FCConfig.h>
|
||||
|
||||
// Exporting of App classes
|
||||
#ifdef FC_OS_WIN32
|
||||
# define SpreadsheetExport __declspec(dllexport)
|
||||
#else // for Linux
|
||||
# define SpreadsheetExport
|
||||
#endif
|
||||
|
||||
#ifdef _PreComp_
|
||||
/// here get the warnings of to long specifieres disabled (needed for VC6)
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( disable : 4251 )
|
||||
# pragma warning( disable : 4503 )
|
||||
# pragma warning( disable : 4786 ) // specifier longer then 255 chars
|
||||
#endif
|
||||
|
||||
// standard
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <bitset>
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#endif // _PreComp_
|
||||
#endif
|
||||
|
||||
157
src/Mod/Spreadsheet/App/PropertyColumnWidths.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/***************************************************************************
|
||||
* 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"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include "PropertyColumnWidths.h"
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Reader.h>
|
||||
#include "Utils.h"
|
||||
#include <PropertyColumnWidthsPy.h>
|
||||
|
||||
using namespace App;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
const int PropertyColumnWidths::defaultWidth = 100;
|
||||
const int PropertyColumnWidths::defaultHeaderWidth = 50;
|
||||
|
||||
TYPESYSTEM_SOURCE(Spreadsheet::PropertyColumnWidths , App::Property);
|
||||
|
||||
PropertyColumnWidths::PropertyColumnWidths()
|
||||
{
|
||||
}
|
||||
|
||||
PropertyColumnWidths::PropertyColumnWidths(const PropertyColumnWidths &other)
|
||||
{
|
||||
std::map<int, int>::const_iterator i = other.begin();
|
||||
|
||||
while (i != other.end()) {
|
||||
insert(*i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
App::Property *PropertyColumnWidths::Copy() const
|
||||
{
|
||||
PropertyColumnWidths * prop = new PropertyColumnWidths(*this);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
void PropertyColumnWidths::Paste(const App::Property &from)
|
||||
{
|
||||
aboutToSetValue();
|
||||
const PropertyColumnWidths * frompcw = static_cast<const PropertyColumnWidths*>(&from);
|
||||
|
||||
std::map<int, int>::const_iterator i;
|
||||
|
||||
/* Mark all as dirty first */
|
||||
i = begin();
|
||||
while (i != end()) {
|
||||
dirty.insert(i->first);
|
||||
++i;
|
||||
}
|
||||
|
||||
/* Clear old map */
|
||||
clear();
|
||||
|
||||
/* Copy new map from from */
|
||||
i = frompcw->begin();
|
||||
while (i != frompcw->end()) {
|
||||
insert(*i);
|
||||
dirty.insert(i->first);
|
||||
++i;
|
||||
}
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the width (in pixels) of column \a col to \a width.
|
||||
*
|
||||
* @param col Column to set
|
||||
* @param width Width in pixels
|
||||
*
|
||||
*/
|
||||
|
||||
void PropertyColumnWidths::setValue(int col, int width)
|
||||
{
|
||||
if (width >= 0) {
|
||||
aboutToSetValue();
|
||||
operator[](col) = width;
|
||||
dirty.insert(col);
|
||||
hasSetValue();
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyColumnWidths::Save(Base::Writer &writer) const
|
||||
{
|
||||
// Save column information
|
||||
writer.Stream() << writer.ind() << "<ColumnInfo Count=\"" << size() << "\">" << std::endl;
|
||||
writer.incInd(); // indention for 'ColumnInfo'
|
||||
std::map<int, int>::const_iterator coli = begin();
|
||||
while (coli != end()) {
|
||||
writer.Stream() << writer.ind() << "<Column name=\"" << columnName(coli->first) << "\" width=\"" << coli->second << "\" />" << std::endl;
|
||||
++coli;
|
||||
}
|
||||
writer.decInd(); // indention for 'ColumnInfo'
|
||||
writer.Stream() << writer.ind() << "</ColumnInfo>" << std::endl;
|
||||
}
|
||||
|
||||
void PropertyColumnWidths::Restore(Base::XMLReader &reader)
|
||||
{
|
||||
int Cnt;
|
||||
|
||||
// Column info
|
||||
reader.readElement("ColumnInfo");
|
||||
Cnt = reader.hasAttribute("Count") ? reader.getAttributeAsInteger("Count") : 0;
|
||||
for (int i = 0; i < Cnt; i++) {
|
||||
reader.readElement("Column");
|
||||
const char* name = reader.hasAttribute("name") ? reader.getAttribute("name") : 0;
|
||||
const char * width = reader.hasAttribute("width") ? reader.getAttribute("width") : 0;
|
||||
|
||||
try {
|
||||
if (name && width) {
|
||||
int col = decodeColumn(name);
|
||||
int colWidth = atoi(width);
|
||||
|
||||
setValue(col, colWidth);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
// Something is wrong, skip this column
|
||||
}
|
||||
|
||||
}
|
||||
reader.readEndElement("ColumnInfo");
|
||||
}
|
||||
|
||||
PyObject *PropertyColumnWidths::getPyObject()
|
||||
{
|
||||
if (PythonObject.is(Py::_None())){
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new PropertyColumnWidthsPy(this),true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
78
src/Mod/Spreadsheet/App/PropertyColumnWidths.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/***************************************************************************
|
||||
* 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 PROPERTYCOLUMNWIDTHS_H
|
||||
#define PROPERTYCOLUMNWIDTHS_H
|
||||
|
||||
#include <map>
|
||||
#include <App/Property.h>
|
||||
#include <CXX/Objects.hxx>
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
class SpreadsheetExport PropertyColumnWidths : public App::Property, std::map<int, int>
|
||||
{
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
PropertyColumnWidths();
|
||||
|
||||
PropertyColumnWidths(const PropertyColumnWidths & other);
|
||||
|
||||
void setValue() { }
|
||||
|
||||
void setValue(int col, int width);
|
||||
|
||||
std::map<int, int> getValues() const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
int getValue(int column) const { return find(column) != end() ? at(column) : defaultWidth; }
|
||||
|
||||
virtual Property *Copy(void) const;
|
||||
|
||||
virtual void Paste(const Property &from);
|
||||
|
||||
virtual void Save (Base::Writer & writer) const;
|
||||
|
||||
virtual void Restore(Base::XMLReader & reader);
|
||||
|
||||
bool isDirty() const { return dirty.size() > 0; }
|
||||
|
||||
void clearDirty() { dirty.clear(); }
|
||||
|
||||
const std::set<int> & getDirty() const { return dirty; }
|
||||
|
||||
PyObject *getPyObject(void);
|
||||
|
||||
static const int defaultWidth;
|
||||
static const int defaultHeaderWidth;
|
||||
|
||||
private:
|
||||
|
||||
std::set<int> dirty;
|
||||
|
||||
Py::Object PythonObject;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PROPERTYCOLUMNWIDTHS_H
|
||||
19
src/Mod/Spreadsheet/App/PropertyColumnWidthsPy.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="PersistencePy"
|
||||
Name="PropertyColumnWidthsPy"
|
||||
Twin="PropertyColumnWidths"
|
||||
TwinPointer="PropertyColumnWidths"
|
||||
Include="Mod/Spreadsheet/App/PropertyColumnWidths.h"
|
||||
Namespace="Spreadsheet"
|
||||
FatherInclude="Base/PersistencePy.h"
|
||||
FatherNamespace="Base"
|
||||
Constructor="true">
|
||||
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Eivind Kvedalen" EMail="eivind@kvedalen.name" />
|
||||
<UserDocu>Internal spreadsheet object</UserDocu>
|
||||
</Documentation>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
150
src/Mod/Spreadsheet/App/PropertyRowHeights.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
/***************************************************************************
|
||||
* 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"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include "PropertyRowHeights.h"
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Reader.h>
|
||||
#include "Utils.h"
|
||||
#include <PropertyRowHeightsPy.h>
|
||||
|
||||
using namespace App;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
const int PropertyRowHeights::defaultHeight = 20;
|
||||
|
||||
TYPESYSTEM_SOURCE(Spreadsheet::PropertyRowHeights , App::Property);
|
||||
|
||||
PropertyRowHeights::PropertyRowHeights()
|
||||
{
|
||||
}
|
||||
|
||||
PropertyRowHeights::PropertyRowHeights(const PropertyRowHeights &other)
|
||||
{
|
||||
}
|
||||
|
||||
Property *PropertyRowHeights::Copy() const
|
||||
{
|
||||
PropertyRowHeights * prop = new PropertyRowHeights(*this);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
void PropertyRowHeights::Paste(const Property &from)
|
||||
{
|
||||
aboutToSetValue();
|
||||
const PropertyRowHeights * fromprh = static_cast<const PropertyRowHeights*>(&from);
|
||||
|
||||
std::map<int, int>::const_iterator i;
|
||||
|
||||
/* Mark all as dirty first */
|
||||
i = begin();
|
||||
while (i != end()) {
|
||||
dirty.insert(i->first);
|
||||
++i;
|
||||
}
|
||||
|
||||
/* Clear old map */
|
||||
clear();
|
||||
|
||||
/* Copy new map from from */
|
||||
i = fromprh->begin();
|
||||
while (i != fromprh->end()) {
|
||||
insert(*i);
|
||||
dirty.insert(i->first);
|
||||
++i;
|
||||
}
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
void PropertyRowHeights::Save(Base::Writer &writer) const
|
||||
{
|
||||
// Save row information
|
||||
writer.Stream() << writer.ind() << "<RowInfo Count=\"" << size() << "\">" << std::endl;
|
||||
writer.incInd(); // indention for 'RowInfo'
|
||||
|
||||
std::map<int, int>::const_iterator ri = begin();
|
||||
while (ri != end()) {
|
||||
writer.Stream() << writer.ind() << "<Row name=\"" << rowName(ri->first) << "\" height=\"" << ri->second << "\" />" << std::endl;
|
||||
++ri;
|
||||
}
|
||||
writer.decInd(); // indention for 'RowInfo'
|
||||
writer.Stream() << writer.ind() << "</RowInfo>" << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set height of row given by \a row to \a height in pixels.
|
||||
*
|
||||
* @param row Address of row
|
||||
* @param height Height in pixels
|
||||
*
|
||||
*/
|
||||
|
||||
void PropertyRowHeights::setValue(int row, int height)
|
||||
{
|
||||
if (height >= 0) {
|
||||
aboutToSetValue();
|
||||
operator[](row) = height;
|
||||
dirty.insert(row);
|
||||
hasSetValue();
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyRowHeights::Restore(Base::XMLReader &reader)
|
||||
{
|
||||
int Cnt;
|
||||
|
||||
// Row info
|
||||
reader.readElement("RowInfo");
|
||||
Cnt = reader.hasAttribute("Count") ? reader.getAttributeAsInteger("Count") : 0;
|
||||
for (int i = 0; i < Cnt; i++) {
|
||||
reader.readElement("Row");
|
||||
const char* name = reader.hasAttribute("name") ? reader.getAttribute("name") : 0;
|
||||
const char * height = reader.hasAttribute("height") ? reader.getAttribute("height") : 0;
|
||||
|
||||
try {
|
||||
if (name && height) {
|
||||
int row = decodeRow(name);
|
||||
int rowHeight = atoi(height);
|
||||
|
||||
setValue(row, rowHeight);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
// Something is wrong, skip this row
|
||||
}
|
||||
}
|
||||
reader.readEndElement("RowInfo");
|
||||
}
|
||||
|
||||
PyObject *PropertyRowHeights::getPyObject()
|
||||
{
|
||||
if (PythonObject.is(Py::_None())){
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new PropertyRowHeightsPy(this),true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
77
src/Mod/Spreadsheet/App/PropertyRowHeights.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/***************************************************************************
|
||||
* 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 PROPERTYROWHEIGHTS_H
|
||||
#define PROPERTYROWHEIGHTS_H
|
||||
|
||||
#include <map>
|
||||
#include <App/Property.h>
|
||||
#include <CXX/Objects.hxx>
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
class SpreadsheetExport PropertyRowHeights : public App::Property, std::map<int, int>
|
||||
{
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
PropertyRowHeights();
|
||||
|
||||
PropertyRowHeights(const PropertyRowHeights & other);
|
||||
|
||||
void setValue() { }
|
||||
|
||||
void setValue(int row, int height);
|
||||
|
||||
int getValue(int row) const { return find(row) != end() ? at(row) : 20; }
|
||||
|
||||
std::map<int, int> getValues() const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual App::Property *Copy(void) const;
|
||||
|
||||
virtual void Paste(const App::Property &from);
|
||||
|
||||
virtual void Save (Base::Writer & writer) const;
|
||||
|
||||
virtual void Restore(Base::XMLReader & reader);
|
||||
|
||||
bool isDirty() const { return dirty.size() > 0; }
|
||||
|
||||
void clearDirty() { dirty.clear(); }
|
||||
|
||||
const std::set<int> & getDirty() const { return dirty; }
|
||||
|
||||
PyObject *getPyObject(void);
|
||||
|
||||
static const int defaultHeight;
|
||||
|
||||
private:
|
||||
|
||||
std::set<int> dirty;
|
||||
|
||||
Py::Object PythonObject;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PROPERTYROWHEIGHTS_H
|
||||
19
src/Mod/Spreadsheet/App/PropertyRowHeightsPy.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="PersistencePy"
|
||||
Name="PropertyRowHeightsPy"
|
||||
Twin="PropertyRowHeights"
|
||||
TwinPointer="PropertyRowHeights"
|
||||
Include="Mod/Spreadsheet/App/PropertyRowHeights.h"
|
||||
Namespace="Spreadsheet"
|
||||
FatherInclude="Base/PersistencePy.h"
|
||||
FatherNamespace="Base"
|
||||
Constructor="true">
|
||||
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Eivind Kvedalen" EMail="eivind@kvedalen.name" />
|
||||
<UserDocu>Internal spreadsheet object</UserDocu>
|
||||
</Documentation>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
1059
src/Mod/Spreadsheet/App/PropertySheet.cpp
Normal file
218
src/Mod/Spreadsheet/App/PropertySheet.h
Normal file
@@ -0,0 +1,218 @@
|
||||
/***************************************************************************
|
||||
* 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 PROPERTYSHEET_H
|
||||
#define PROPERTYSHEET_H
|
||||
|
||||
#include <map>
|
||||
#include <App/DocumentObserver.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/Property.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
#include "Cell.h"
|
||||
|
||||
namespace Spreadsheet
|
||||
{
|
||||
|
||||
class Sheet;
|
||||
class PropertySheet;
|
||||
class SheetObserver;
|
||||
|
||||
class PropertySheet : public App::Property {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
|
||||
PropertySheet(Sheet * _owner = 0);
|
||||
|
||||
PropertySheet(const PropertySheet & other);
|
||||
|
||||
~PropertySheet();
|
||||
|
||||
virtual Property *Copy(void) const;
|
||||
|
||||
virtual void Paste(const Property &from);
|
||||
|
||||
virtual void Save (Base::Writer & writer) const;
|
||||
|
||||
virtual void Restore(Base::XMLReader & reader);
|
||||
|
||||
Cell *createCell(CellAddress address);
|
||||
|
||||
void setValue() { }
|
||||
|
||||
void setContent(CellAddress address, const char * value);
|
||||
|
||||
void setAlignment(CellAddress address, int _alignment);
|
||||
|
||||
void setStyle(CellAddress address, const std::set<std::string> & _style);
|
||||
|
||||
void setForeground(CellAddress address, const App::Color &color);
|
||||
|
||||
void setBackground(CellAddress address, const App::Color &color);
|
||||
|
||||
void setDisplayUnit(CellAddress address, const std::string & unit);
|
||||
|
||||
void setAlias(CellAddress address, const std::string &alias);
|
||||
|
||||
void setComputedUnit(CellAddress address, const Base::Unit & unit);
|
||||
|
||||
void setSpans(CellAddress address, int rows, int columns);
|
||||
|
||||
void clear(CellAddress address);
|
||||
|
||||
void clear();
|
||||
|
||||
Cell * getValue(CellAddress key);
|
||||
|
||||
std::set<CellAddress> getUsedCells() const;
|
||||
|
||||
Sheet * sheet() const { return owner; }
|
||||
|
||||
const std::set<CellAddress> & getDirty() { return dirty; }
|
||||
|
||||
void setDirty(CellAddress address);
|
||||
|
||||
void clearDirty(CellAddress key) { dirty.erase(key); }
|
||||
|
||||
void clearDirty() { dirty.clear(); purgeTouched(); }
|
||||
|
||||
bool isDirty() const { return dirty.size() > 0; }
|
||||
|
||||
void moveCell(CellAddress currPos, CellAddress newPos);
|
||||
|
||||
void insertRows(int row, int count);
|
||||
|
||||
void removeRows(int row, int count);
|
||||
|
||||
void insertColumns(int col, int count);
|
||||
|
||||
void removeColumns(int col, int count);
|
||||
|
||||
unsigned int getMemSize (void);
|
||||
|
||||
bool mergeCells(CellAddress from, CellAddress to);
|
||||
|
||||
void splitCell(CellAddress address);
|
||||
|
||||
void getSpans(CellAddress address, int &rows, int &cols) const;
|
||||
|
||||
bool isMergedCell(CellAddress address) const;
|
||||
|
||||
bool isHidden(CellAddress address) const;
|
||||
|
||||
const std::set< CellAddress > & getDeps(const std::string & name) const;
|
||||
|
||||
const std::set<std::string> &getDeps(CellAddress pos) const;
|
||||
|
||||
const std::vector<App::DocumentObject*> & getDocDeps() const { return docDeps; }
|
||||
|
||||
class Signaller {
|
||||
public:
|
||||
Signaller(PropertySheet & sheet);
|
||||
~Signaller();
|
||||
private:
|
||||
PropertySheet & mSheet;
|
||||
};
|
||||
|
||||
void recomputeDependencies(CellAddress key);
|
||||
|
||||
PyObject *getPyObject(void);
|
||||
|
||||
void resolveAll();
|
||||
|
||||
void invalidateDependants(const App::DocumentObject *docObj);
|
||||
|
||||
void renamedDocumentObject(const App::DocumentObject *docObj);
|
||||
|
||||
void renamedDocument(const App::Document *doc);
|
||||
|
||||
private:
|
||||
|
||||
friend class Signaller;
|
||||
|
||||
friend class SheetObserver;
|
||||
|
||||
Cell *cellAt(CellAddress address);
|
||||
|
||||
Cell *nonNullCellAt(CellAddress address);
|
||||
|
||||
const Cell *cellAt(CellAddress address) const;
|
||||
|
||||
bool colSortFunc(const CellAddress &a, const CellAddress &b);
|
||||
|
||||
bool rowSortFunc(const CellAddress &a, const CellAddress &b);
|
||||
|
||||
friend class Cell;
|
||||
|
||||
std::map<CellAddress, Cell*> data;
|
||||
|
||||
std::set<CellAddress> dirty;
|
||||
|
||||
/* Merged cells; cell -> anchor cell */
|
||||
std::map<CellAddress, CellAddress> mergedCells;
|
||||
|
||||
Sheet * owner;
|
||||
|
||||
/*
|
||||
* Cell dependency tracking
|
||||
*/
|
||||
|
||||
void addDependencies(CellAddress key);
|
||||
|
||||
void removeDependencies(CellAddress key);
|
||||
|
||||
void recomputeDependants(const App::Property * prop);
|
||||
|
||||
void recomputeDependants(const App::DocumentObject * docObj);
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Properties this cell depends on */
|
||||
std::map<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;
|
||||
|
||||
/* DocumentObject this cell depends on */
|
||||
std::map<CellAddress, std::set< std::string > > cellToDocumentObjectMap;
|
||||
|
||||
/* Other document objects the sheet depends on */
|
||||
std::vector<App::DocumentObject*> docDeps;
|
||||
|
||||
/* Name of document objects, used for renaming */
|
||||
std::map<const App::DocumentObject*, std::string> documentObjectName;
|
||||
|
||||
/* Name of documents, used for renaming */
|
||||
std::map<const App::Document*, std::string> documentName;
|
||||
|
||||
int signalCounter;
|
||||
|
||||
Py::Object PythonObject;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // PROPERTYSHEET_H
|
||||
19
src/Mod/Spreadsheet/App/PropertySheetPy.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="PersistencePy"
|
||||
Name="PropertySheetPy"
|
||||
Twin="PropertySheet"
|
||||
TwinPointer="PropertySheet"
|
||||
Include="Mod/Spreadsheet/App/PropertySheet.h"
|
||||
Namespace="Spreadsheet"
|
||||
FatherInclude="Base/PersistencePy.h"
|
||||
FatherNamespace="Base"
|
||||
Constructor="true">
|
||||
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Eivind Kvedalen" EMail="eivind@kvedalen.name" />
|
||||
<UserDocu>Internal spreadsheet object</UserDocu>
|
||||
</Documentation>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
86
src/Mod/Spreadsheet/App/Range.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
* 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)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
89
src/Mod/Spreadsheet/App/Range.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/***************************************************************************
|
||||
* 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);
|
||||
|
||||
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 addressToString(CellAddress(row_begin, col_begin)); }
|
||||
|
||||
/** End of range as a string */
|
||||
inline std::string toCellString() const { return addressToString(CellAddress(row_end, col_end)); }
|
||||
|
||||
/** Current cell as a string */
|
||||
inline std::string address() const { return addressToString(CellAddress(row_curr, col_curr)); }
|
||||
|
||||
/** The raneg as a string */
|
||||
inline std::string rangeString() const {
|
||||
return addressToString(CellAddress(row_begin, col_begin)) + ":" + addressToString(CellAddress(row_end, col_end));
|
||||
}
|
||||
|
||||
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
|
||||
1087
src/Mod/Spreadsheet/App/Sheet.cpp
Normal file
281
src/Mod/Spreadsheet/App/Sheet.h
Normal file
@@ -0,0 +1,281 @@
|
||||
/***************************************************************************
|
||||
* 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_Spreadsheet_H
|
||||
#define Spreadsheet_Spreadsheet_H
|
||||
|
||||
#ifdef signals
|
||||
#undef signals
|
||||
#define signals signals
|
||||
#endif
|
||||
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/DocumentObserver.h>
|
||||
#include <App/PropertyFile.h>
|
||||
#include <App/PropertyUnits.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
#include <App/DynamicProperty.h>
|
||||
#include <App/Material.h>
|
||||
#include <Base/Unit.h>
|
||||
#include <map>
|
||||
#include "PropertySheet.h"
|
||||
#include "PropertyColumnWidths.h"
|
||||
#include "PropertyRowHeights.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace Spreadsheet
|
||||
{
|
||||
|
||||
class Sheet;
|
||||
class Cell;
|
||||
class Expression;
|
||||
class Range;
|
||||
class SheetObserver;
|
||||
|
||||
|
||||
class SpreadsheetExport Sheet : public App::DocumentObject
|
||||
{
|
||||
PROPERTY_HEADER(Sheet::Sheet);
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
Sheet();
|
||||
virtual ~Sheet();
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
virtual const char* getViewProviderName(void) const {
|
||||
return "SpreadsheetGui::ViewProviderSheet";
|
||||
}
|
||||
|
||||
bool importFromFile(const std::string & filename, char delimiter = '\t', char quoteChar = '\0', char escapeChar = '\\');
|
||||
|
||||
bool exportToFile(const std::string & filename, char delimiter = '\t', char quoteChar = '\0', char escapeChar = '\\') const;
|
||||
|
||||
bool mergeCells(const Range &range);
|
||||
|
||||
void splitCell(CellAddress address);
|
||||
|
||||
Cell * getCell(CellAddress address);
|
||||
|
||||
Cell *getNewCell(CellAddress address);
|
||||
|
||||
void setCell(const char *address, const char *value);
|
||||
|
||||
void setCell(CellAddress address, const char *value);
|
||||
|
||||
void clearAll();
|
||||
|
||||
void clear(CellAddress address, bool all = true);
|
||||
|
||||
void getSpans(CellAddress address, int & rows, int & cols) const;
|
||||
|
||||
bool isMergedCell(CellAddress address) const;
|
||||
|
||||
void setColumnWidth(int col, int width);
|
||||
|
||||
int getColumnWidth(int col) const;
|
||||
|
||||
void setRowHeight(int row, int height);
|
||||
|
||||
int getRowHeight(int row) const;
|
||||
|
||||
std::vector<std::string> getUsedCells() const;
|
||||
|
||||
void insertColumns(int col, int count);
|
||||
|
||||
void removeColumns(int col, int count);
|
||||
|
||||
void insertRows(int row, int count);
|
||||
|
||||
void removeRows(int row, int count);
|
||||
|
||||
void setContent(CellAddress address, const char * value);
|
||||
|
||||
void setAlignment(CellAddress address, int _alignment);
|
||||
|
||||
void setStyle(CellAddress address, const std::set<std::string> & _style);
|
||||
|
||||
void setForeground(CellAddress address, const App::Color &color);
|
||||
|
||||
void setBackground(CellAddress address, const App::Color &color);
|
||||
|
||||
void setDisplayUnit(CellAddress address, const std::string & unit);
|
||||
|
||||
void setComputedUnit(CellAddress address, const Base::Unit & unit);
|
||||
|
||||
void setAlias(CellAddress address, const std::string & alias);
|
||||
|
||||
void setSpans(CellAddress address, int rows, int columns);
|
||||
|
||||
std::set<std::string> dependsOn(CellAddress address) const;
|
||||
|
||||
void providesTo(CellAddress address, std::set<std::string> & result) const;
|
||||
|
||||
PyObject *getPyObject();
|
||||
|
||||
App::Property *getPropertyByName(const char *name) const;
|
||||
|
||||
const char* getPropertyName(const App::Property* prop) const;
|
||||
|
||||
virtual short mustExecute(void) const;
|
||||
|
||||
App::DocumentObjectExecReturn *execute(void);
|
||||
|
||||
void getCellAddress(const App::Property *prop, CellAddress &address);
|
||||
|
||||
std::map<int, int> getColumnWidths() const;
|
||||
|
||||
std::map<int, int> getRowHeights() const;
|
||||
|
||||
void setPosition(CellAddress address);
|
||||
|
||||
// Signals
|
||||
|
||||
boost::signal<void (Spreadsheet::CellAddress)> cellUpdated;
|
||||
|
||||
boost::signal<void (Spreadsheet::CellAddress)> cellSpanChanged;
|
||||
|
||||
boost::signal<void (int, int)> columnWidthChanged;
|
||||
|
||||
boost::signal<void (int, int)> rowHeightChanged;
|
||||
|
||||
boost::signal<void (CellAddress)> positionChanged;
|
||||
|
||||
|
||||
/** @name Access properties */
|
||||
//@{
|
||||
App::Property* addDynamicProperty(
|
||||
const char* type, const char* name=0,
|
||||
const char* group=0, const char* doc=0,
|
||||
short attr=0, bool ro=false, bool hidden=false) {
|
||||
return props.addDynamicProperty(type, name, group, doc, attr, ro, hidden);
|
||||
}
|
||||
virtual bool removeDynamicProperty(const char* name) {
|
||||
return props.removeDynamicProperty(name);
|
||||
}
|
||||
std::vector<std::string> getDynamicPropertyNames() const {
|
||||
return props.getDynamicPropertyNames();
|
||||
}
|
||||
App::Property *getDynamicPropertyByName(const char* name) const {
|
||||
return props.getDynamicPropertyByName(name);
|
||||
}
|
||||
virtual void addDynamicProperties(const App::PropertyContainer* cont) {
|
||||
return props.addDynamicProperties(cont);
|
||||
}
|
||||
/// get all properties of the class (including properties of the parent)
|
||||
virtual void getPropertyList(std::vector<App::Property*> &List) const {
|
||||
props.getPropertyList(List);
|
||||
}
|
||||
/// get all properties of the class (including parent)
|
||||
void getPropertyMap(std::map<std::string,App::Property*> &Map) const {
|
||||
props.getPropertyMap(Map);
|
||||
}
|
||||
|
||||
short getPropertyType(const App::Property *prop) const {
|
||||
props.getPropertyType(prop);
|
||||
}
|
||||
|
||||
/// get the name of a property
|
||||
virtual const char* getName(const App::Property* prop) const {
|
||||
return props.getPropertyName(prop);
|
||||
}
|
||||
//@}
|
||||
|
||||
void observeDocument(const std::string &docName);
|
||||
|
||||
protected:
|
||||
|
||||
void providesTo(CellAddress address, std::set<CellAddress> & result) const;
|
||||
|
||||
void onDocumentRestored();
|
||||
|
||||
void onRelabledDocument(const App::Document & document);
|
||||
|
||||
void onRenamedDocument(const App::Document & document);
|
||||
|
||||
void recomputeCell(CellAddress p);
|
||||
|
||||
App::Property *getProperty(CellAddress key) const;
|
||||
|
||||
App::Property *getProperty(const char * addr) const;
|
||||
|
||||
void updateProperty(CellAddress key);
|
||||
|
||||
App::Property *setStringProperty(CellAddress key, const std::string & value) ;
|
||||
|
||||
App::Property *setFloatProperty(CellAddress key, double value);
|
||||
|
||||
App::Property *setQuantityProperty(CellAddress key, double value, const Base::Unit &unit);
|
||||
|
||||
static std::string toAddress(CellAddress key);
|
||||
|
||||
void moveCell(CellAddress currPos, CellAddress newPos);
|
||||
|
||||
void renamedDocumentObject(const App::DocumentObject * docObj);
|
||||
|
||||
/* Properties for used cells */
|
||||
App::DynamicProperty props;
|
||||
|
||||
/* Mapping of properties to cell position */
|
||||
std::map<const App::Property*, CellAddress > propAddress;
|
||||
|
||||
/* Mapping of cell position to alias property */
|
||||
std::map<CellAddress, App::Property*> aliasProp;
|
||||
|
||||
/* Set of cells with errors */
|
||||
std::set<CellAddress> cellErrors;
|
||||
|
||||
/* Properties */
|
||||
|
||||
/* Cell data */
|
||||
PropertySheet cells;
|
||||
|
||||
/* Column widths */
|
||||
PropertyColumnWidths columnWidths;
|
||||
|
||||
/* Row heights */
|
||||
PropertyRowHeights rowHeights;
|
||||
|
||||
App::PropertyInteger currRow;
|
||||
App::PropertyInteger currColumn;
|
||||
|
||||
/* Dependencies to other documents */
|
||||
App::PropertyLinkList docDeps;
|
||||
|
||||
/* Document observers to track changes to external properties */
|
||||
typedef std::map<std::string, SheetObserver* > ObserverMap;
|
||||
ObserverMap observers;
|
||||
|
||||
boost::BOOST_SIGNALS_NAMESPACE::scoped_connection onRelabledDocumentConnection;
|
||||
boost::BOOST_SIGNALS_NAMESPACE::scoped_connection onRenamedDocumentConnection;
|
||||
|
||||
friend class SheetObserver;
|
||||
|
||||
friend class PropertySheet;
|
||||
};
|
||||
|
||||
} //namespace Spreadsheet
|
||||
|
||||
|
||||
#endif // Spreadsheet_Spreadsheet_H
|
||||
126
src/Mod/Spreadsheet/App/SheetObserver.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/***************************************************************************
|
||||
* 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 "SheetObserver.h"
|
||||
#include "PropertySheet.h"
|
||||
|
||||
using namespace Spreadsheet;
|
||||
using namespace App;
|
||||
|
||||
/**
|
||||
* The SheetObserver constructor.
|
||||
*
|
||||
* @param document The Document we are observing
|
||||
* @param _sheet The sheet owning this observer.
|
||||
*
|
||||
*/
|
||||
|
||||
SheetObserver::SheetObserver(App::Document * document, PropertySheet *_sheet)
|
||||
: DocumentObserver(document)
|
||||
, sheet(_sheet)
|
||||
, refCount(1)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Unimplemented.
|
||||
*
|
||||
*/
|
||||
|
||||
void SheetObserver::slotCreatedDocument(const App::Document &Doc)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Unimplemented.
|
||||
*
|
||||
*/
|
||||
|
||||
void SheetObserver::slotDeletedDocument(const App::Document &Doc)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate cells that depend on this document object.
|
||||
*
|
||||
*/
|
||||
|
||||
void SheetObserver::slotCreatedObject(const DocumentObject &Obj)
|
||||
{
|
||||
sheet->invalidateDependants(&Obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate cells that depend on this document object.
|
||||
*
|
||||
*/
|
||||
|
||||
void SheetObserver::slotDeletedObject(const DocumentObject &Obj)
|
||||
{
|
||||
sheet->invalidateDependants(&Obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the sheets recomputeDependants when a change to a Property occurs.
|
||||
*
|
||||
*/
|
||||
|
||||
void SheetObserver::slotChangedObject(const DocumentObject &Obj, const Property &Prop)
|
||||
{
|
||||
const char * name = Obj.getPropertyName(&Prop);
|
||||
assert(name != 0);
|
||||
|
||||
if (&Prop == &Obj.Label)
|
||||
sheet->renamedDocumentObject(&Obj);
|
||||
else {
|
||||
|
||||
if (isUpdating.find(name) != isUpdating.end())
|
||||
return;
|
||||
|
||||
isUpdating.insert(name);
|
||||
sheet->recomputeDependants(&Prop);
|
||||
isUpdating.erase(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase reference count.
|
||||
*
|
||||
*/
|
||||
|
||||
void SheetObserver::ref()
|
||||
{
|
||||
refCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrease reference count.
|
||||
*
|
||||
*/
|
||||
|
||||
bool SheetObserver::unref()
|
||||
{
|
||||
refCount--;
|
||||
return refCount;
|
||||
}
|
||||
|
||||
52
src/Mod/Spreadsheet/App/SheetObserver.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/***************************************************************************
|
||||
* 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 SHEETOBSERVER_H
|
||||
#define SHEETOBSERVER_H
|
||||
|
||||
#include <App/DocumentObserver.h>
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
class PropertySheet;
|
||||
|
||||
class SheetObserver : public App::DocumentObserver {
|
||||
public:
|
||||
SheetObserver(App::Document* document, PropertySheet *_sheet);
|
||||
~SheetObserver() { }
|
||||
virtual void slotCreatedDocument(const App::Document& Doc);
|
||||
virtual void slotDeletedDocument(const App::Document& Doc);
|
||||
virtual void slotCreatedObject(const App::DocumentObject& Obj);
|
||||
virtual void slotDeletedObject(const App::DocumentObject& Obj);
|
||||
virtual void slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop);
|
||||
void ref();
|
||||
bool unref();
|
||||
App::Document* getDocument() const { return App::DocumentObserver::getDocument(); }
|
||||
private:
|
||||
std::set<std::string> isUpdating;
|
||||
int refCount;
|
||||
PropertySheet * sheet;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SHEETOBSERVER_H
|
||||
164
src/Mod/Spreadsheet/App/SheetPy.xml
Normal file
@@ -0,0 +1,164 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="DocumentObjectPy"
|
||||
Name="SheetPy"
|
||||
Twin="Sheet"
|
||||
TwinPointer="Sheet"
|
||||
Include="Mod/Spreadsheet/App/Sheet.h"
|
||||
Namespace="Spreadsheet"
|
||||
FatherInclude="App/DocumentObjectPy.h"
|
||||
FatherNamespace="App"
|
||||
Constructor="true">
|
||||
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Eivind Kvedalen" EMail="eivind@kvedalen.name" />
|
||||
<UserDocu>With this object you can manipulate spreadsheets</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="set">
|
||||
<Documentation>
|
||||
<UserDocu>Set data into a cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="get">
|
||||
<Documentation>
|
||||
<UserDocu>Get evaluated cell contents</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getContents">
|
||||
<Documentation>
|
||||
<UserDocu>Get cell contents</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="clear">
|
||||
<Documentation>
|
||||
<UserDocu>Clear a cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="clearAll">
|
||||
<Documentation>
|
||||
<UserDocu>Clear all cells in the spreadsheet</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="importFile">
|
||||
<Documentation>
|
||||
<UserDocu>Import file into spreadsheet</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="exportFile">
|
||||
<Documentation>
|
||||
<UserDocu>Export file from spreadsheet</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="mergeCells">
|
||||
<Documentation>
|
||||
<UserDocu>Merge given cell area into one cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="splitCell">
|
||||
<Documentation>
|
||||
<UserDocu>Split a perviously merged cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="insertColumns">
|
||||
<Documentation>
|
||||
<UserDocu>Insert a given number of columns into the spreadsheet.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removeColumns">
|
||||
<Documentation>
|
||||
<UserDocu>Remove a given number of columns from the spreadsheet.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="insertRows">
|
||||
<Documentation>
|
||||
<UserDocu>Insert a given number of rows into the spreadsheet.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removeRows">
|
||||
<Documentation>
|
||||
<UserDocu>Remove a given number of rows from the spreadsheet.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setAlignment">
|
||||
<Documentation>
|
||||
<UserDocu>Set alignment of the cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getAlignment">
|
||||
<Documentation>
|
||||
<UserDocu>Get alignment of the cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setStyle">
|
||||
<Documentation>
|
||||
<UserDocu>Set style of the cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getStyle">
|
||||
<Documentation>
|
||||
<UserDocu>Get style of the cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setDisplayUnit">
|
||||
<Documentation>
|
||||
<UserDocu>Set display unit for cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setAlias">
|
||||
<Documentation>
|
||||
<UserDocu>Set alias for cell address</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getDisplayUnit">
|
||||
<Documentation>
|
||||
<UserDocu>Get display unit for cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setForeground">
|
||||
<Documentation>
|
||||
<UserDocu>Set foreground color of the cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getForeground">
|
||||
<Documentation>
|
||||
<UserDocu>Get foreground color of the cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setBackground">
|
||||
<Documentation>
|
||||
<UserDocu>Set background color of the cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getBackground">
|
||||
<Documentation>
|
||||
<UserDocu>Get background color of the cell</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setColumnWidth">
|
||||
<Documentation>
|
||||
<UserDocu>Set given spreadsheet column to given width</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getColumnWidth">
|
||||
<Documentation>
|
||||
<UserDocu>Get given spreadsheet column width</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setRowHeight">
|
||||
<Documentation>
|
||||
<UserDocu>Set given spreadsheet row to given height</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getRowHeight">
|
||||
<Documentation>
|
||||
<UserDocu>Get given spreadsheet row height</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setPosition">
|
||||
<Documentation>
|
||||
<UserDocu>Set focused cell for attached view(s).</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
892
src/Mod/Spreadsheet/App/SheetPyImp.cpp
Normal file
@@ -0,0 +1,892 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Eivind Kvedalen (eivind@kvedalen.name) 2015 *
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2010 *
|
||||
* *
|
||||
* 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 <boost/tokenizer.hpp>
|
||||
#include <Base/Exception.h>
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
#include "Utils.h"
|
||||
#include "Range.h"
|
||||
|
||||
// inclusion of the generated files (generated out of SheetPy.xml)
|
||||
#include "SheetPy.h"
|
||||
#include "SheetPy.cpp"
|
||||
|
||||
using namespace Spreadsheet;
|
||||
using namespace App;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string SheetPy::representation(void) const
|
||||
{
|
||||
return std::string("<Sheet object>");
|
||||
}
|
||||
|
||||
PyObject *SheetPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
{
|
||||
// create a new instance of SheetPy and the Twin object
|
||||
return new SheetPy(new Sheet());
|
||||
}
|
||||
|
||||
// constructor method
|
||||
int SheetPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// +++ methodes implementer ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
PyObject* SheetPy::set(PyObject *args)
|
||||
{
|
||||
char *address;
|
||||
char *contents;
|
||||
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ss:set", &address, &contents))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
Range rangeIter(address);
|
||||
do {
|
||||
getSheetPtr()->setCell(rangeIter.address().c_str(), contents);
|
||||
} while (rangeIter.next());
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::get(PyObject *args)
|
||||
{
|
||||
char *address;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:get", &address))
|
||||
return 0;
|
||||
|
||||
App::Property * prop = this->getSheetPtr()->getPropertyByName(address);
|
||||
|
||||
if (prop == 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "Invalid address or property.");
|
||||
return 0;
|
||||
}
|
||||
return prop->getPyObject();
|
||||
}
|
||||
|
||||
PyObject* SheetPy::getContents(PyObject *args)
|
||||
{
|
||||
char *strAddress;
|
||||
CellAddress address;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:getContents", &strAddress))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
address = stringToAddress(strAddress);
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string contents;
|
||||
const Cell * cell = this->getSheetPtr()->getCell(address);
|
||||
|
||||
if (cell)
|
||||
cell->getStringContent( contents );
|
||||
|
||||
return Py::new_reference_to( Py::String( contents ) );
|
||||
}
|
||||
|
||||
PyObject* SheetPy::clear(PyObject *args)
|
||||
{
|
||||
const char * strAddress;
|
||||
int all = 1;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|p:clear", &strAddress, &all))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
Range rangeIter(strAddress);
|
||||
do {
|
||||
this->getSheetPtr()->clear(*rangeIter, all);
|
||||
} while (rangeIter.next());
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::clearAll(PyObject *args)
|
||||
{
|
||||
this->getSheetPtr()->clearAll();
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::importFile(PyObject *args)
|
||||
{
|
||||
const char * filename;
|
||||
const char * delimiter = "\t";
|
||||
const char * quoteChar = "\"";
|
||||
const char * escapeChar = "\\";
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|sss:importFile", &filename, &delimiter, "eChar, &escapeChar))
|
||||
return 0;
|
||||
|
||||
if (getSheetPtr()->importFromFile(filename, delimiter[0], quoteChar[0], escapeChar[0]))
|
||||
return Py::new_reference_to( Py::Boolean(true) );
|
||||
else
|
||||
return Py::new_reference_to( Py::Boolean(false) );
|
||||
}
|
||||
|
||||
PyObject* SheetPy::exportFile(PyObject *args)
|
||||
{
|
||||
const char * filename;
|
||||
const char * delimiter = "\t";
|
||||
const char * quoteChar = "\"";
|
||||
const char * escapeChar = "\\";
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|sss:importFile", &filename, &delimiter, "eChar, &escapeChar))
|
||||
return 0;
|
||||
|
||||
if (getSheetPtr()->exportToFile(filename, delimiter[0], quoteChar[0], escapeChar[0]))
|
||||
return Py::new_reference_to( Py::Boolean(true) );
|
||||
else
|
||||
return Py::new_reference_to( Py::Boolean(false) );
|
||||
}
|
||||
|
||||
PyObject* SheetPy::mergeCells(PyObject *args)
|
||||
{
|
||||
const char * range;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:mergeCells", &range))
|
||||
return 0;
|
||||
|
||||
getSheetPtr()->mergeCells(Range(range));
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::splitCell(PyObject *args)
|
||||
{
|
||||
const char * strAddress;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:splitCell", &strAddress))
|
||||
return 0;
|
||||
|
||||
CellAddress address;
|
||||
try {
|
||||
address = stringToAddress(strAddress);
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
getSheetPtr()->splitCell(address);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::insertColumns(PyObject *args)
|
||||
{
|
||||
const char * column;
|
||||
int count;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "si:insertColumns", &column, &count))
|
||||
return 0;
|
||||
|
||||
getSheetPtr()->insertColumns(decodeColumn(column), count);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::removeColumns(PyObject *args)
|
||||
{
|
||||
const char * column;
|
||||
int count;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "si:removeColumns", &column, &count))
|
||||
return 0;
|
||||
|
||||
getSheetPtr()->removeColumns(decodeColumn(column), count);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::insertRows(PyObject *args)
|
||||
{
|
||||
const char * row;
|
||||
int count;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "si:insertRows", &row, &count))
|
||||
return 0;
|
||||
|
||||
getSheetPtr()->insertRows(decodeRow(std::string(row)), count);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::removeRows(PyObject *args)
|
||||
{
|
||||
const char * row;
|
||||
int count;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "si:removeRows", &row, &count))
|
||||
return 0;
|
||||
|
||||
getSheetPtr()->removeRows(decodeRow(std::string(row)), count);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::setStyle(PyObject *args)
|
||||
{
|
||||
const char * cell;
|
||||
PyObject * value;
|
||||
std::set<std::string> style;
|
||||
const char * options = "replace";
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sO|s:setStyle", &cell, &value, &options))
|
||||
return 0;
|
||||
|
||||
if (PySet_Check(value)) {
|
||||
PyObject * copy = PySet_New(value);
|
||||
|
||||
while (PySet_Size(copy) > 0) {
|
||||
PyObject * item = PySet_Pop(copy);
|
||||
|
||||
// check on the key:
|
||||
if (PyString_Check(item))
|
||||
style.insert(PyString_AsString(item));
|
||||
else {
|
||||
std::string error = std::string("type of the set need to be a string, not ") + item->ob_type->tp_name;
|
||||
PyErr_SetString(PyExc_TypeError, error.c_str());
|
||||
Py_DECREF(copy);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Py_DECREF(copy);
|
||||
}
|
||||
else if (PyString_Check(value)) {
|
||||
using namespace boost;
|
||||
|
||||
escaped_list_separator<char> e('\0', '|', '\0');
|
||||
std::string line = PyString_AsString(value);
|
||||
tokenizer<escaped_list_separator<char> > tok(line, e);
|
||||
|
||||
for(tokenizer<escaped_list_separator<char> >::iterator i = tok.begin(); i != tok.end();++i)
|
||||
style.insert(*i);
|
||||
}
|
||||
else {
|
||||
std::string error = std::string("style must be either set or string, not ") + value->ob_type->tp_name;
|
||||
PyErr_SetString(PyExc_TypeError, error.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(options, "replace") == 0) {
|
||||
Range rangeIter(cell);
|
||||
do {
|
||||
getSheetPtr()->setStyle(*rangeIter, style);
|
||||
} while (rangeIter.next());
|
||||
}
|
||||
else if (strcmp(options, "add") == 0) {
|
||||
Range rangeIter(cell);
|
||||
|
||||
do {
|
||||
std::set<std::string> oldStyle;
|
||||
const Cell * cell = getSheetPtr()->getCell(*rangeIter);
|
||||
|
||||
// Get old styles first
|
||||
if (cell)
|
||||
cell->getStyle(oldStyle);
|
||||
|
||||
for (std::set<std::string>::const_iterator it = oldStyle.begin(); it != oldStyle.end(); ++it)
|
||||
style.insert(*it);
|
||||
|
||||
// Set new style
|
||||
getSheetPtr()->setStyle(*rangeIter, style);
|
||||
} while (rangeIter.next());
|
||||
}
|
||||
else if (strcmp(options, "remove") == 0) {
|
||||
Range rangeIter(cell);
|
||||
|
||||
do {
|
||||
std::set<std::string> oldStyle;
|
||||
const Cell * cell = getSheetPtr()->getCell(*rangeIter);
|
||||
|
||||
// Get old styles first
|
||||
if (cell)
|
||||
cell->getStyle(oldStyle);
|
||||
|
||||
for (std::set<std::string>::const_iterator it = style.begin(); it != style.end(); ++it)
|
||||
oldStyle.erase(*it);
|
||||
|
||||
// Set new style
|
||||
getSheetPtr()->setStyle(*rangeIter, oldStyle);
|
||||
} while (rangeIter.next());
|
||||
}
|
||||
else if (strcmp(options, "invert") == 0) {
|
||||
Range rangeIter(cell);
|
||||
|
||||
do {
|
||||
std::set<std::string> oldStyle;
|
||||
std::set<std::string> newStyle;
|
||||
const Cell * cell = getSheetPtr()->getCell(*rangeIter);
|
||||
|
||||
// Get old styles first
|
||||
if (cell) {
|
||||
cell->getStyle(oldStyle);
|
||||
newStyle = oldStyle;
|
||||
}
|
||||
|
||||
for (std::set<std::string>::const_iterator i = style.begin(); i != style.end(); ++i) {
|
||||
if (oldStyle.find(*i) == oldStyle.end())
|
||||
// Not found in oldstyle; add it to newStyle
|
||||
newStyle.insert(*i);
|
||||
else
|
||||
// Found in oldStyle, remove it from newStyle
|
||||
newStyle.erase(*i);
|
||||
}
|
||||
|
||||
// Set new style
|
||||
getSheetPtr()->setStyle(*rangeIter, newStyle);
|
||||
} while (rangeIter.next());
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError, "Optional parameter must be either 'replace', 'add', 'remove', or 'invert'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::getStyle(PyObject *args)
|
||||
{
|
||||
const char * strAddress;
|
||||
CellAddress address;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:getStyle", &strAddress))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
address = stringToAddress(strAddress);
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::set<std::string> style;
|
||||
const Cell * cell = getSheetPtr()->getCell(address);
|
||||
|
||||
if (cell && cell->getStyle(style)) {
|
||||
PyObject * s = PySet_New(NULL);
|
||||
|
||||
for (std::set<std::string>::const_iterator i = style.begin(); i != style.end(); ++i)
|
||||
PySet_Add(s, PyString_FromString((*i).c_str()));
|
||||
|
||||
return s;
|
||||
}
|
||||
else {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::setDisplayUnit(PyObject *args)
|
||||
{
|
||||
int row, col;
|
||||
const char * cell;
|
||||
const char * value;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ss:setDisplayUnit", &cell, &value))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
Range rangeIter(cell);
|
||||
|
||||
do {
|
||||
getSheetPtr()->setDisplayUnit(*rangeIter, value);
|
||||
} while (rangeIter.next());
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::setAlias(PyObject *args)
|
||||
{
|
||||
CellAddress address;
|
||||
const char * strAddress;
|
||||
const char * value;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ss:setAlias", &strAddress, &value))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
address = stringToAddress(strAddress);
|
||||
getSheetPtr()->setAlias(address, value);
|
||||
Py_Return;
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::getDisplayUnit(PyObject *args)
|
||||
{
|
||||
const char * strAddress;
|
||||
CellAddress address;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:getDisplayUnit", &strAddress))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
address = stringToAddress(strAddress);
|
||||
|
||||
Spreadsheet::DisplayUnit unit;
|
||||
|
||||
const Cell * cell = getSheetPtr()->getCell(address);
|
||||
|
||||
if ( cell && cell->getDisplayUnit(unit) )
|
||||
return Py::new_reference_to( Py::String( unit.stringRep ) );
|
||||
else
|
||||
Py_Return;
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::setAlignment(PyObject *args)
|
||||
{
|
||||
const char * cell;
|
||||
PyObject * value;
|
||||
int alignment = 0;
|
||||
const char * options = "replace";
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sO|s:setAlignment", &cell, &value, &options))
|
||||
return 0;
|
||||
|
||||
if (PySet_Check(value)) {
|
||||
// Argument is a set of strings
|
||||
PyObject * copy = PySet_New(value);
|
||||
int n = PySet_Size(copy);
|
||||
|
||||
while (n-- > 0) {
|
||||
PyObject * item = PySet_Pop(copy);
|
||||
|
||||
if (PyString_Check(item))
|
||||
alignment = Cell::decodeAlignment(PyString_AsString(item), alignment);
|
||||
else {
|
||||
std::string error = std::string("type of the key need to be a string, not") + item->ob_type->tp_name;
|
||||
PyErr_SetString(PyExc_TypeError, error.c_str());
|
||||
Py_DECREF(copy);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(copy);
|
||||
}
|
||||
else if (PyString_Check(value)) {
|
||||
// Argument is a string, combination of alignments, separated by the pipe character
|
||||
using namespace boost;
|
||||
|
||||
escaped_list_separator<char> e('\0', '|', '\0');
|
||||
std::string line = PyString_AsString(value);
|
||||
tokenizer<escaped_list_separator<char> > tok(line, e);
|
||||
|
||||
for(tokenizer<escaped_list_separator<char> >::iterator i = tok.begin(); i != tok.end();++i)
|
||||
alignment = Cell::decodeAlignment(*i, alignment);
|
||||
}
|
||||
else {
|
||||
std::string error = std::string("style must be either set or string, not ") + value->ob_type->tp_name;
|
||||
PyErr_SetString(PyExc_TypeError, error.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set alignment depending on 'options' variable
|
||||
if (strcmp(options, "replace") == 0) {
|
||||
Range rangeIter(cell);
|
||||
|
||||
do {
|
||||
getSheetPtr()->setAlignment(*rangeIter, alignment);
|
||||
} while (rangeIter.next());
|
||||
}
|
||||
else if (strcmp(options, "keep") == 0) {
|
||||
Range rangeIter(cell);
|
||||
|
||||
do {
|
||||
int oldAlignment = 0;
|
||||
const Cell * cell = getSheetPtr()->getCell(*rangeIter);
|
||||
|
||||
if (cell)
|
||||
cell->getAlignment(oldAlignment);
|
||||
|
||||
if (alignment & Cell::ALIGNMENT_VERTICAL)
|
||||
oldAlignment &= ~Cell::ALIGNMENT_VERTICAL;
|
||||
if (alignment & Cell::ALIGNMENT_HORIZONTAL)
|
||||
oldAlignment &= ~Cell::ALIGNMENT_HORIZONTAL;
|
||||
|
||||
getSheetPtr()->setAlignment(*rangeIter, alignment | oldAlignment);
|
||||
} while (rangeIter.next());
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError, "Optional parameter must be either 'replace' or 'keep'");
|
||||
return 0;
|
||||
}
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* SheetPy::getAlignment(PyObject *args)
|
||||
{
|
||||
const char * strAddress;
|
||||
CellAddress address;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:getAlignment", &strAddress))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
address = stringToAddress(strAddress);
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int alignment;
|
||||
const Cell * cell = getSheetPtr()->getCell(address);
|
||||
if (cell && cell->getAlignment(alignment)) {
|
||||
PyObject * s = PySet_New(NULL);
|
||||
|
||||
if (alignment & Cell::ALIGNMENT_LEFT)
|
||||
PySet_Add(s, PyString_FromString("left"));
|
||||
if (alignment & Cell::ALIGNMENT_HCENTER)
|
||||
PySet_Add(s, PyString_FromString("center"));
|
||||
if (alignment & Cell::ALIGNMENT_RIGHT)
|
||||
PySet_Add(s, PyString_FromString("right"));
|
||||
if (alignment & Cell::ALIGNMENT_TOP)
|
||||
PySet_Add(s, PyString_FromString("top"));
|
||||
if (alignment & Cell::ALIGNMENT_VCENTER)
|
||||
PySet_Add(s, PyString_FromString("vcenter"));
|
||||
if (alignment & Cell::ALIGNMENT_BOTTOM)
|
||||
PySet_Add(s, PyString_FromString("bottom"));
|
||||
|
||||
return s;
|
||||
}
|
||||
else {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
|
||||
static float decodeFloat(const PyObject * obj)
|
||||
{
|
||||
if (PyFloat_Check(obj))
|
||||
return PyFloat_AsDouble((PyObject *)obj);
|
||||
else if (PyInt_Check(obj))
|
||||
return PyInt_AsLong((PyObject *)obj);
|
||||
throw Base::TypeError("Float or integer expected");
|
||||
}
|
||||
|
||||
static void decodeColor(PyObject * value, Color & c)
|
||||
{
|
||||
if (PyTuple_Check(value)) {
|
||||
if (PyTuple_Size(value) < 3 || PyTuple_Size(value) > 4)
|
||||
throw Base::TypeError("Tuple must be either of 3 or 4 floats/ints.");
|
||||
|
||||
c.r = decodeFloat(PyTuple_GetItem(value, 0));
|
||||
c.g = decodeFloat(PyTuple_GetItem(value, 1));
|
||||
c.b = decodeFloat(PyTuple_GetItem(value, 2));
|
||||
if (PyTuple_Size(value) == 4) {
|
||||
c.a = decodeFloat(PyTuple_GetItem(value, 3));
|
||||
return;
|
||||
}
|
||||
else
|
||||
c.a = 1.0;
|
||||
}
|
||||
else
|
||||
throw Base::TypeError("Tuple required.");
|
||||
}
|
||||
|
||||
PyObject* SheetPy::setForeground(PyObject *args)
|
||||
{
|
||||
try {
|
||||
const char * range;
|
||||
PyObject * value;
|
||||
Color c;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sO:setForeground", &range, &value))
|
||||
return 0;
|
||||
|
||||
decodeColor(value, c);
|
||||
|
||||
Range rangeIter(range);
|
||||
do {
|
||||
getSheetPtr()->setForeground(*rangeIter, c);
|
||||
} while (rangeIter.next());
|
||||
Py_Return;
|
||||
}
|
||||
catch (const Base::TypeError & e) {
|
||||
PyErr_SetString(PyExc_TypeError, e.what());
|
||||
return 0;
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::getForeground(PyObject *args)
|
||||
{
|
||||
const char * strAddress;
|
||||
CellAddress address;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:getForeground", &strAddress))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
address = stringToAddress(strAddress);
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
Color c;
|
||||
const Cell * cell = getSheetPtr()->getCell(address);
|
||||
if (cell && cell->getForeground(c)) {
|
||||
PyObject * t = PyTuple_New(4);
|
||||
|
||||
PyTuple_SetItem(t, 0, Py::new_reference_to( Py::Float(c.r) ));
|
||||
PyTuple_SetItem(t, 1, Py::new_reference_to( Py::Float(c.g) ));
|
||||
PyTuple_SetItem(t, 2, Py::new_reference_to( Py::Float(c.b) ));
|
||||
PyTuple_SetItem(t, 3, Py::new_reference_to( Py::Float(c.a) ));
|
||||
|
||||
return t;
|
||||
}
|
||||
else {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::setBackground(PyObject *args)
|
||||
{
|
||||
try {
|
||||
const char * strAddress;
|
||||
PyObject * value;
|
||||
Color c;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sO:setBackground", &strAddress, &value))
|
||||
return 0;
|
||||
|
||||
decodeColor(value, c);
|
||||
Range rangeIter(strAddress);
|
||||
|
||||
do {
|
||||
getSheetPtr()->setBackground(*rangeIter, c);
|
||||
} while (rangeIter.next());
|
||||
Py_Return;
|
||||
}
|
||||
catch (const Base::TypeError & e) {
|
||||
PyErr_SetString(PyExc_TypeError, e.what());
|
||||
return 0;
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::getBackground(PyObject *args)
|
||||
{
|
||||
const char * strAddress;
|
||||
CellAddress address;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:setStyle", &strAddress))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
address = stringToAddress(strAddress);
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
Color c;
|
||||
const Cell * cell = getSheetPtr()->getCell(address);
|
||||
if (cell && cell->getBackground(c)) {
|
||||
PyObject * t = PyTuple_New(4);
|
||||
|
||||
PyTuple_SetItem(t, 0, Py::new_reference_to( Py::Float(c.r) ));
|
||||
PyTuple_SetItem(t, 1, Py::new_reference_to( Py::Float(c.g) ));
|
||||
PyTuple_SetItem(t, 2, Py::new_reference_to( Py::Float(c.b) ));
|
||||
PyTuple_SetItem(t, 3, Py::new_reference_to( Py::Float(c.a) ));
|
||||
|
||||
return t;
|
||||
}
|
||||
else {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::setPosition(PyObject *args)
|
||||
{
|
||||
const char * strAddress;
|
||||
CellAddress address;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:setPosition", &strAddress))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
address = stringToAddress(strAddress);
|
||||
getSheetPtr()->setPosition(address);
|
||||
Py_Return;
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::setColumnWidth(PyObject *args)
|
||||
{
|
||||
const char * columnStr;
|
||||
int width;
|
||||
CellAddress address;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "si:setColumnWidth", &columnStr, &width))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
std::string cellAddr = std::string(columnStr) + "1";
|
||||
|
||||
address = stringToAddress(cellAddr.c_str());
|
||||
getSheetPtr()->setColumnWidth(address.col(), width);
|
||||
Py_Return;
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::getColumnWidth(PyObject *args)
|
||||
{
|
||||
const char * columnStr;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:getColumnWidth", &columnStr))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
CellAddress address(std::string(columnStr) + "1");
|
||||
|
||||
return Py::new_reference_to( Py::Int( getSheetPtr()->getColumnWidth(address.col()) ) );
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::setRowHeight(PyObject *args)
|
||||
{
|
||||
const char * rowStr;
|
||||
int height;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "si:setRowHeight", &rowStr, &height))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
CellAddress address("A" + std::string(rowStr));
|
||||
|
||||
getSheetPtr()->setRowHeight(address.row(), height);
|
||||
Py_Return;
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SheetPy::getRowHeight(PyObject *args)
|
||||
{
|
||||
const char * rowStr;
|
||||
int row, col;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:getRowHeight", &rowStr))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
CellAddress address("A" + std::string(rowStr));
|
||||
|
||||
return Py::new_reference_to( Py::Int( getSheetPtr()->getRowHeight(address.row()) ) );
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// +++ custom attributes implementer ++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
PyObject *SheetPy::getCustomAttributes(const char* attr) const
|
||||
{
|
||||
App::Property * prop = this->getSheetPtr()->getPropertyByName(attr);
|
||||
|
||||
if (prop == 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "Invalid address or property.");
|
||||
return 0;
|
||||
}
|
||||
return prop->getPyObject();
|
||||
}
|
||||
|
||||
int SheetPy::setCustomAttributes(const char* attr, PyObject* obj)
|
||||
{
|
||||
// Parse attr; if it looks like a cell address specifier, it probably is...
|
||||
char *contents;
|
||||
|
||||
if (!PyArg_ParseTuple(obj, "s:setCustomAttributes", &contents))
|
||||
return 0;
|
||||
|
||||
try {
|
||||
CellAddress address(attr);
|
||||
|
||||
getSheetPtr()->setCell(address, contents);
|
||||
return 0;
|
||||
}
|
||||
catch (const Base::Exception & e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
344
src/Mod/Spreadsheet/App/Utils.cpp
Normal file
@@ -0,0 +1,344 @@
|
||||
/***************************************************************************
|
||||
* 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"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include "Utils.h"
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <boost/regex.hpp>
|
||||
#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.
|
||||
*
|
||||
* @param col Column given as a 0-based column position.
|
||||
*
|
||||
* @returns String with column position, with "A" being the first column, "B" being the second and so on.
|
||||
*
|
||||
*/
|
||||
|
||||
std::string Spreadsheet::columnName(int col)
|
||||
{
|
||||
std::stringstream s;
|
||||
|
||||
if (col < 26)
|
||||
s << ((char)('A' + col));
|
||||
else
|
||||
s << ((char)('A' + (col - 26) / 26 )) << ((char)('A' + (col - 26) % 26));
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode \a row as a string.
|
||||
*
|
||||
* @param row Row given as a 0-based row position.
|
||||
*
|
||||
* @returns String with row position, with "1" being the first row.
|
||||
*
|
||||
*/
|
||||
|
||||
std::string Spreadsheet::rowName(int row)
|
||||
{
|
||||
std::stringstream s;
|
||||
|
||||
s << (row + 1);
|
||||
|
||||
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)
|
||||
{
|
||||
char * end;
|
||||
int i = strtol(rowstr.c_str(), &end, 10);
|
||||
|
||||
if (i <0 || i >= CellAddress::MAX_ROWS || *end)
|
||||
throw Base::Exception("Invalid row specification.");
|
||||
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = 0;
|
||||
|
||||
if (colstr.length() == 1) {
|
||||
if ((colstr[0] >= 'A' && colstr[0] <= 'Z'))
|
||||
col = colstr[0] - 'A';
|
||||
else
|
||||
col = colstr[0] - 'a';
|
||||
}
|
||||
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 if ((*i >= 'a' && *i <= 'z'))
|
||||
v = *i - 'a';
|
||||
else
|
||||
throw Base::Exception("Invalid column specification");
|
||||
|
||||
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)
|
||||
{
|
||||
int i = 0;
|
||||
static const boost::regex e("\\${0,1}([A-Za-z]+)\\${0,1}([0-9]+)");
|
||||
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.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert given \a row and \a col into a string address.
|
||||
*
|
||||
* @param row Row address.
|
||||
* @param col Column address.
|
||||
*
|
||||
* @returns Address given as a string.
|
||||
*/
|
||||
|
||||
std::string Spreadsheet::addressToString(const CellAddress &address)
|
||||
{
|
||||
std::stringstream s;
|
||||
|
||||
if (address.col() < 26)
|
||||
s << (char)('A' + address.col());
|
||||
else {
|
||||
int col = address.col() - 26;
|
||||
|
||||
s << (char)('A' + (col / 26));
|
||||
s << (char)('A' + (col % 26));
|
||||
}
|
||||
|
||||
s << (address.row() + 1);
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
void Spreadsheet::createRectangles(std::set<std::pair<int, int> > & cells, std::map<std::pair<int, int>, std::pair<int, int> > & rectangles)
|
||||
{
|
||||
while (cells.size() != 0) {
|
||||
int row, col;
|
||||
int orgRow;
|
||||
int rows = 1;
|
||||
int cols = 1;
|
||||
|
||||
orgRow = row = (*cells.begin()).first;
|
||||
col = (*cells.begin()).second;
|
||||
|
||||
// Expand right first
|
||||
while (cells.find(std::make_pair(row, col + cols)) != cells.end())
|
||||
++cols;
|
||||
|
||||
// Expand left
|
||||
while (cells.find(std::make_pair(row, col + cols)) != cells.end()) {
|
||||
col--;
|
||||
++cols;
|
||||
}
|
||||
|
||||
// Try to expand cell up (the complete row above from [col,col + cols> needs to be in the cells variable)
|
||||
bool ok = true;
|
||||
while (ok) {
|
||||
for (int i = col; i < col + cols; ++i) {
|
||||
if ( cells.find(std::make_pair(row - 1, i)) == cells.end()) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
// Complete row
|
||||
row--;
|
||||
rows++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Try to expand down (the complete row below from [col,col + cols> needs to be in the cells variable)
|
||||
ok = true;
|
||||
while (ok) {
|
||||
for (int i = col; i < col + cols; ++i) {
|
||||
if ( cells.find(std::make_pair(orgRow + 1, i)) == cells.end()) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
// Complete row
|
||||
orgRow++;
|
||||
rows++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Remove entries from cell set for this rectangle
|
||||
for (int r = row; r < row + rows; ++r)
|
||||
for (int c = col; c < col + cols; ++c)
|
||||
cells.erase(std::make_pair(r, c));
|
||||
|
||||
// Insert into output variable
|
||||
rectangles[std::make_pair(row, col)] = std::make_pair(rows, cols);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Spreadsheet::quote(const std::string &input)
|
||||
{
|
||||
std::stringstream output;
|
||||
|
||||
std::string::const_iterator cur = input.begin();
|
||||
std::string::const_iterator end = input.end();
|
||||
|
||||
output << "<<";
|
||||
while (cur != end) {
|
||||
switch (*cur) {
|
||||
case '\t':
|
||||
output << "\\t";
|
||||
break;
|
||||
case '\n':
|
||||
output << "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
output << "\\r";
|
||||
break;
|
||||
case '\\':
|
||||
output << "\\\\";
|
||||
break;
|
||||
case '\'':
|
||||
output << "\\'";
|
||||
break;
|
||||
case '"':
|
||||
output << "\\\"";
|
||||
break;
|
||||
case '>':
|
||||
output << "\\>";
|
||||
break;
|
||||
default:
|
||||
output << *cur;
|
||||
}
|
||||
++cur;
|
||||
}
|
||||
output << ">>";
|
||||
|
||||
return output.str();
|
||||
}
|
||||
|
||||
std::string Spreadsheet::unquote(const std::string & input)
|
||||
{
|
||||
assert(input.size() >= 4);
|
||||
|
||||
std::string output;
|
||||
std::string::const_iterator cur = input.begin() + 2;
|
||||
std::string::const_iterator end = input.end() - 2;
|
||||
|
||||
output.reserve(input.size());
|
||||
|
||||
bool escaped = false;
|
||||
while (cur != end) {
|
||||
if (escaped) {
|
||||
switch (*cur) {
|
||||
case 't':
|
||||
output += '\t';
|
||||
break;
|
||||
case 'n':
|
||||
output += '\n';
|
||||
break;
|
||||
case 'r':
|
||||
output += '\r';
|
||||
break;
|
||||
case '\\':
|
||||
output += '\\';
|
||||
break;
|
||||
case '\'':
|
||||
output += '\'';
|
||||
break;
|
||||
case '"':
|
||||
output += '"';
|
||||
break;
|
||||
}
|
||||
escaped = false;
|
||||
}
|
||||
else {
|
||||
if (*cur == '\\')
|
||||
escaped = true;
|
||||
else
|
||||
output += *cur;
|
||||
}
|
||||
++cur;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
92
src/Mod/Spreadsheet/App/Utils.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/***************************************************************************
|
||||
* 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 UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <Base/BaseClass.h>
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
SpreadsheetExport std::string addressToString(const CellAddress & address);
|
||||
|
||||
struct CellAddress {
|
||||
CellAddress(unsigned int _value) : value(_value) { }
|
||||
|
||||
CellAddress(int row = -1, int col = -1) : value(((row & 0xffff) << 16) | (col & 0xffff)) { }
|
||||
|
||||
CellAddress(const char * address) {
|
||||
*this = stringToAddress(address);
|
||||
}
|
||||
|
||||
CellAddress(const std::string & address) {
|
||||
*this = stringToAddress(address.c_str());
|
||||
}
|
||||
|
||||
inline int row() const { return (value >> 16) & 0xffff; }
|
||||
|
||||
inline int col() const { return value & 0xffff; }
|
||||
|
||||
inline bool operator<(const CellAddress & other) const { return value < other.value; }
|
||||
|
||||
inline bool operator==(const CellAddress & other) const { return value == other.value; }
|
||||
|
||||
inline bool operator!=(const CellAddress & other) const { return value != other.value; }
|
||||
|
||||
inline bool isValid() { return (row() >=0 && row() < MAX_ROWS && col() >= 0 && col() < MAX_COLUMNS); }
|
||||
|
||||
// Static members
|
||||
|
||||
static const int MAX_ROWS;
|
||||
|
||||
static const int MAX_COLUMNS;
|
||||
|
||||
protected:
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
template<typename T> T * freecad_dynamic_cast(Base::BaseClass * t)
|
||||
{
|
||||
if (t && t->isDerivedFrom(T::getClassTypeId()))
|
||||
return static_cast<T*>(t);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // UTILS_H
|
||||
21
src/Mod/Spreadsheet/App/create_regexps.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
# DerivedGeneralCategory.txt used below can be downloaded from
|
||||
# http://www.unicode.org/Public/UNIDATA/extracted/DerivedGeneralCategory.txt
|
||||
|
||||
exec 2>/dev/null
|
||||
|
||||
export PATH=../../../../build/src/Mod/Spreadsheet/App:$PATH
|
||||
|
||||
for l in Cc Cf Cn Co Cs Ll Lm Lo Lt Lu Mc Me Mn Nd Nl No Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So Zl Zp Zs ; do
|
||||
grep "; $l" DerivedGeneralCategory.txt > $l.txt
|
||||
genregexps $l $l.txt
|
||||
done
|
||||
|
||||
genregexps L Ll.txt Lm.txt Lo.txt Lt.txt Lu.txt
|
||||
genregexps C Cc.txt Cf.txt Cn.txt Co.txt Cs.txt
|
||||
genregexps M Mc.txt Me.txt Mn.txt
|
||||
genregexps N Nd.txt Nl.txt No.txt
|
||||
genregexps P Pc.txt Pd.txt Pe.txt Pf.txt Pi.txt Po.txt Ps.txt
|
||||
genregexps S Sc.txt Sk.txt Sm.txt So.txt
|
||||
genregexps Z Zl.txt Zp.txt Zs.txt
|
||||
232
src/Mod/Spreadsheet/App/genregexps.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
int genUtf8(int c, unsigned char * b)
|
||||
{
|
||||
if (c<0x80) { *b++=c, *b++ = '\0'; return 1; }
|
||||
else if (c<0x800) { *b++=192+c/64, *b++=128+c%64, *b++ = '\0'; return 2; }
|
||||
else if (c-0xd800u < 0x800) goto error;
|
||||
else if (c<0x10000) { *b++=224+c/4096, *b++=128+c/64%64, *b++=128+c%64, *b++ = '\0'; return 3; }
|
||||
else if (c<0x110000) { *b++=240+c/262144, *b++=128+c/4096%64, *b++=128+c/64%64, *b++=128+c%64, *b++ = '\0'; return 4; }
|
||||
else goto error;
|
||||
error:
|
||||
// printf("Error! %x\n", c);
|
||||
// exit(1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
typedef std::basic_string<unsigned char> String;
|
||||
typedef std::vector<String > StringList;
|
||||
|
||||
StringList list;
|
||||
|
||||
unsigned char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
static String escape(unsigned char c)
|
||||
{
|
||||
switch (c) {
|
||||
case '*':
|
||||
case '+':
|
||||
case '-':
|
||||
case '(':
|
||||
case ')':
|
||||
case '\\':
|
||||
case '.':
|
||||
case '[':
|
||||
case ']':
|
||||
case '?':
|
||||
case '{':
|
||||
case '}':
|
||||
case '#':
|
||||
case '^':
|
||||
case '|':
|
||||
case ':':
|
||||
case '$':
|
||||
case '/':
|
||||
case '\'':
|
||||
case '"':
|
||||
return String((const unsigned char*)"\\") + c;
|
||||
default:
|
||||
return String((const unsigned char*)"") + c;
|
||||
}
|
||||
}
|
||||
|
||||
static String encode(unsigned char c)
|
||||
{
|
||||
if (c <= 32 || c > 126)
|
||||
return String((const unsigned char*)"\\x") + hex[c >> 4] + hex[c & 0xf];
|
||||
else {
|
||||
return String((const unsigned char*)"") + c;
|
||||
}
|
||||
}
|
||||
|
||||
static String encodeString(String c)
|
||||
{
|
||||
int i;
|
||||
String result;
|
||||
|
||||
for (i = 0; i < c.size(); ++i)
|
||||
result += encode(c[i]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static String encodeRange(String r)
|
||||
{
|
||||
String result;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < r.size(); ++i) {
|
||||
int n = 0;
|
||||
|
||||
for (j = i; j < r.size() && r[i] + n == r[j]; ++j, ++n);
|
||||
|
||||
if (n > 1) {
|
||||
result += escape(r[i]);
|
||||
result += (const unsigned char*)"-";
|
||||
result += escape(r[j - 1]);
|
||||
i = j - 1;
|
||||
}
|
||||
else
|
||||
result += escape(r[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static String commonPrefix(int indent, StringList::const_iterator S, StringList::const_iterator E, int k)
|
||||
{
|
||||
StringList::const_iterator i = S;
|
||||
String leafs;
|
||||
String branches;
|
||||
int nBranches = 0;
|
||||
bool first = true;
|
||||
|
||||
if (S->size() <= k)
|
||||
return String((const unsigned char*)"");
|
||||
|
||||
while (i != E) {
|
||||
StringList::const_iterator start = i;
|
||||
StringList::const_iterator end = i;
|
||||
int n = 0;
|
||||
|
||||
if (i->size() == k + 1) {
|
||||
leafs += i->at(k);
|
||||
++i;
|
||||
}
|
||||
else {
|
||||
/* Common path */
|
||||
while (end != E &&
|
||||
end->size() >= start->size() &&
|
||||
end->at(k) == start->at(k)) {
|
||||
++n;
|
||||
++end;
|
||||
}
|
||||
|
||||
//if (leafs.size() > 0)
|
||||
if (!first)
|
||||
branches += (const unsigned char*)"|";
|
||||
branches += escape(start->at(k)) + commonPrefix(indent + 1, start, end, k + 1);
|
||||
|
||||
first = false;
|
||||
nBranches++;
|
||||
i = end;
|
||||
}
|
||||
}
|
||||
|
||||
if (leafs.size() > 1)
|
||||
leafs = (const unsigned char*)"[" + encodeRange(leafs) + (const unsigned char*)"]";
|
||||
|
||||
if (nBranches == 0)
|
||||
return leafs;
|
||||
else {
|
||||
if (leafs.size() > 0)
|
||||
leafs += (const unsigned char*)"|";
|
||||
return (const unsigned char*)"(" + leafs + branches + (const unsigned char*)")";
|
||||
}
|
||||
}
|
||||
|
||||
static void readFile(FILE * f)
|
||||
{
|
||||
while (!feof(f)) {
|
||||
char line[2048];
|
||||
int start;
|
||||
int end;
|
||||
char cat[128];
|
||||
unsigned char out[8];
|
||||
int i;
|
||||
|
||||
if (fgets(line, sizeof(line), f) == NULL)
|
||||
break;
|
||||
|
||||
if (sscanf(line, "%4X..%4X ; %s", &start, &end, cat) == 3) {
|
||||
for (i = start; i <= end; ++i) {
|
||||
int n = genUtf8(i, out);
|
||||
|
||||
if (n > 0) {
|
||||
list.push_back(String(out, n));
|
||||
fprintf(stderr, "%6X %d %s\n", i, n, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sscanf(line, "%X ; %s", &start, cat) == 2) {
|
||||
int n = genUtf8(start, out);
|
||||
|
||||
if (n > 0) {
|
||||
list.push_back(String(out, n));
|
||||
fprintf(stderr, "%6X %d %s\n", start, n, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static String subdivide(String prefix, StringList::const_iterator S, StringList::const_iterator E, StringList & result)
|
||||
{
|
||||
String regexp = commonPrefix(0, S, E, 0);
|
||||
|
||||
regexp = encodeString(regexp);
|
||||
if (regexp.size() < 2000) {
|
||||
return regexp;
|
||||
}
|
||||
else {
|
||||
int n = E - S;
|
||||
StringList::const_iterator M = S + n / 2;
|
||||
|
||||
result.push_back( prefix + (const unsigned char*)"1\t" + subdivide(prefix + (const unsigned char*)"1", S, M, result) + (const unsigned char*)"\n");
|
||||
result.push_back( prefix + (const unsigned char*)"2\t" + subdivide(prefix + (const unsigned char*)"2", M, E, result) + (const unsigned char*)"\n");
|
||||
|
||||
return (const unsigned char*)"({" + prefix + (const unsigned char*)"1}|" +
|
||||
(const unsigned char*)"{" + prefix + (const unsigned char*)"2})";
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
FILE * f = fopen(argv[i], "r");
|
||||
|
||||
if (f == NULL) {
|
||||
perror("fopen");
|
||||
return 1;
|
||||
}
|
||||
|
||||
readFile(f);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
sort(list.begin(), list.end());
|
||||
StringList result;
|
||||
|
||||
String regexp = subdivide((const unsigned char*)argv[1], list.begin(), list.end(), result);
|
||||
|
||||
for (StringList::const_iterator i = result.begin(); i != result.end(); ++i)
|
||||
printf("%s", i->c_str());
|
||||
|
||||
printf("%s\t%s\n", argv[1], regexp.c_str());
|
||||
|
||||
}
|
||||
7305
src/Mod/Spreadsheet/App/lex.ExpressionParser.c
Normal file
@@ -1,19 +1,9 @@
|
||||
PYSIDE_WRAP_RC(Spreadsheet_QRC_SRCS Resources/Spreadsheet.qrc)
|
||||
|
||||
SET(Spreadsheet_SRCS
|
||||
Init.py
|
||||
InitGui.py
|
||||
Spreadsheet.py
|
||||
)
|
||||
SOURCE_GROUP("" FILES ${Spreadsheet_SRCS})
|
||||
|
||||
SET(all_files ${Spreadsheet_SRCS})
|
||||
|
||||
ADD_CUSTOM_TARGET(Spreadsheet ALL
|
||||
SOURCES ${all_files} ${Spreadsheet_QRC_SRCS}
|
||||
)
|
||||
|
||||
fc_copy_sources(Spreadsheet "${CMAKE_BINARY_DIR}/Mod/Spreadsheet" ${all_files})
|
||||
add_subdirectory(App)
|
||||
if(BUILD_GUI)
|
||||
add_subdirectory(Gui)
|
||||
endif(BUILD_GUI)
|
||||
|
||||
fc_target_copy_resource(Spreadsheet
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
@@ -21,6 +11,9 @@ fc_target_copy_resource(Spreadsheet
|
||||
Spreadsheet_rc.py)
|
||||
|
||||
INSTALL(
|
||||
FILES ${Spreadsheet_SRCS} ${Spreadsheet_QRC_SRCS}
|
||||
DESTINATION Mod/Spreadsheet
|
||||
FILES
|
||||
Init.py
|
||||
InitGui.py
|
||||
DESTINATION
|
||||
Mod/Spreadsheet
|
||||
)
|
||||
|
||||
64
src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program 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. *
|
||||
* for detail see the LICENCE text file. *
|
||||
* Jrgen Riegel 2002 *
|
||||
* Eivind Kvedalen 2015 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <Python.h>
|
||||
#endif
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Language/Translator.h>
|
||||
#include "Workbench.h"
|
||||
#include "ViewProviderSpreadsheet.h"
|
||||
#include "SpreadsheetView.h"
|
||||
#include "qrc_Spreadsheet.cxx"
|
||||
|
||||
// use a different name to CreateCommand()
|
||||
void CreateSpreadsheetCommands(void);
|
||||
|
||||
void loadSpreadsheetResource()
|
||||
{
|
||||
// add resources and reloads the translators
|
||||
Q_INIT_RESOURCE(Spreadsheet);
|
||||
Gui::Translator::instance()->refresh();
|
||||
}
|
||||
|
||||
/* registration table */
|
||||
extern struct PyMethodDef SpreadsheetGui_Import_methods[];
|
||||
|
||||
|
||||
/* Python entry */
|
||||
extern "C" {
|
||||
void SpreadsheetGuiExport initSpreadsheetGui()
|
||||
{
|
||||
if (!Gui::Application::Instance) {
|
||||
PyErr_SetString(PyExc_ImportError, "Cannot load Gui module in console application.");
|
||||
return;
|
||||
}
|
||||
|
||||
(void) Py_InitModule("SpreadsheetGui", SpreadsheetGui_Import_methods); /* mod name, table ptr */
|
||||
Base::Console().Log("Loading GUI of Spreadsheet module... done\n");
|
||||
|
||||
// instantiating the commands
|
||||
CreateSpreadsheetCommands();
|
||||
|
||||
SpreadsheetGui::ViewProviderSheet::init();
|
||||
SpreadsheetGui::Workbench::init();
|
||||
// SpreadsheetGui::SheetView::init();
|
||||
|
||||
// add resources and reloads the translators
|
||||
loadSpreadsheetResource();
|
||||
}
|
||||
|
||||
} // extern "C" {
|
||||
71
src/Mod/Spreadsheet/Gui/AppSpreadsheetGuiPy.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2015 Eivind Kvedalen (eivind@kvedalen.name) *
|
||||
* Copyright (c) 2006 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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"
|
||||
#ifndef _PreComp_
|
||||
# include <QIcon>
|
||||
# include <QImage>
|
||||
# include <QFileInfo>
|
||||
#endif
|
||||
|
||||
#include "SpreadsheetView.h"
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/FileInfo.h>
|
||||
#include <App/Application.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
/* module functions */
|
||||
static PyObject *
|
||||
open(PyObject *self, PyObject *args)
|
||||
{
|
||||
const char* Name;
|
||||
const char* DocName=0;
|
||||
if (!PyArg_ParseTuple(args, "s|s",&Name,&DocName))
|
||||
return NULL;
|
||||
|
||||
PY_TRY {
|
||||
Base::FileInfo file(Name);
|
||||
App::Document *pcDoc = App::GetApplication().newDocument(DocName ? DocName : QT_TR_NOOP("Unnamed"));
|
||||
Sheet *pcSheet = (Sheet *)pcDoc->addObject("Spreadsheet::Sheet", file.fileNamePure().c_str());
|
||||
|
||||
pcSheet->importFromFile(Name, '\t', '"', '\\');
|
||||
pcSheet->execute();
|
||||
} PY_CATCH;
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
/* registration table */
|
||||
struct PyMethodDef SpreadsheetGui_Import_methods[] = {
|
||||
{"open" ,open , 1}, /* method name, C func ptr, always-tuple */
|
||||
{NULL, NULL} /* end of table marker */
|
||||
};
|
||||
91
src/Mod/Spreadsheet/Gui/CMakeLists.txt
Normal file
@@ -0,0 +1,91 @@
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${COIN3D_INCLUDE_DIR}
|
||||
${QT_INCLUDE_DIR}
|
||||
${ZLIB_INCLUDE_DIR}
|
||||
${SOQT_INCLUDE_DIR}
|
||||
${PYTHON_INCLUDE_PATH}
|
||||
${XERCESC_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(SpreadsheetGui_LIBS
|
||||
Spreadsheet
|
||||
FreeCADGui
|
||||
)
|
||||
|
||||
set(SpreadsheetGui_MOC_HDRS
|
||||
SpreadsheetView.h
|
||||
SheetModel.h
|
||||
SheetTableView.h
|
||||
SpreadsheetDelegate.h
|
||||
Workbench.h
|
||||
PropertiesDialog.h
|
||||
qtcolorpicker.h
|
||||
)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/moc_qtcolorpicker-internal.cpp
|
||||
COMMAND ${QT_MOC_EXECUTABLE} -o ${CMAKE_CURRENT_BINARY_DIR}/moc_qtcolorpicker-internal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/qtcolorpicker.cpp
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/qtcolorpicker.cpp)
|
||||
|
||||
set_property(SOURCE qtcolorpicker.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/moc_qtcolorpicker-internal.cpp)
|
||||
|
||||
fc_wrap_cpp(SpreadsheetGui_MOC_SRCS ${SpreadsheetGui_MOC_HDRS})
|
||||
SOURCE_GROUP("Moc" FILES ${SpreadsheetGui_MOC_SRCS})
|
||||
|
||||
|
||||
SET(SpreadsheetGui_RES_SRCS
|
||||
Resources/Spreadsheet.qrc
|
||||
)
|
||||
|
||||
#fc_add_resources(SpreadsheetGui_QRC_SRCS ${SpreadsheetGui_RES_SRCS})
|
||||
qt4_add_resources(SpreadsheetGui_QRC_SRCS ${SpreadsheetGui_RES_SRCS})
|
||||
|
||||
set(SpreadsheetGui_UIC_SRCS
|
||||
Sheet.ui
|
||||
PropertiesDialog.ui
|
||||
)
|
||||
|
||||
qt4_wrap_ui(SpreadsheetGui_UIC_HDRS ${SpreadsheetGui_UIC_SRCS})
|
||||
|
||||
SET(SpreadsheetGui_SRCS
|
||||
# ${SpreadsheetGui_MOC_SRCS}
|
||||
# ${SpreadsheetGui_QRC_SRCS}
|
||||
AppSpreadsheetGui.cpp
|
||||
AppSpreadsheetGuiPy.cpp
|
||||
Command.cpp
|
||||
ViewProviderSpreadsheet.cpp
|
||||
ViewProviderSpreadsheet.h
|
||||
Resources/Spreadsheet.qrc
|
||||
SpreadsheetView.cpp
|
||||
SpreadsheetView.h
|
||||
SpreadsheetDelegate.h
|
||||
SpreadsheetDelegate.cpp
|
||||
SheetTableView.cpp
|
||||
SheetTableView.h
|
||||
SheetModel.h
|
||||
SheetModel.cpp
|
||||
PreCompiled.cpp
|
||||
PreCompiled.h
|
||||
Workbench.cpp
|
||||
Workbench.h
|
||||
qtcolorpicker.h
|
||||
qtcolorpicker.cpp
|
||||
PropertiesDialog.h
|
||||
PropertiesDialog.cpp
|
||||
${SpreadsheetGui_UIC_HDRS}
|
||||
)
|
||||
|
||||
add_library(SpreadsheetGui SHARED ${SpreadsheetGui_SRCS})
|
||||
target_link_libraries(SpreadsheetGui ${SpreadsheetGui_LIBS})
|
||||
|
||||
fc_target_copy_resource(SpreadsheetGui
|
||||
${CMAKE_SOURCE_DIR}/src/Mod/Spreadsheet
|
||||
${CMAKE_BINARY_DIR}/Mod/Spreadsheet
|
||||
InitGui.py)
|
||||
|
||||
SET_BIN_DIR(SpreadsheetGui SpreadsheetGui /Mod/Spreadsheet)
|
||||
SET_PYTHON_PREFIX_SUFFIX(SpreadsheetGui)
|
||||
|
||||
INSTALL(TARGETS SpreadsheetGui DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
812
src/Mod/Spreadsheet/Gui/Command.cpp
Normal file
@@ -0,0 +1,812 @@
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program 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. *
|
||||
* for detail see the LICENCE text file. *
|
||||
* Jürgen Riegel 2002 *
|
||||
* Eivind Kvedalen 2015 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <QAction>
|
||||
# include <QFileDialog>
|
||||
# include <QImage>
|
||||
# include <QImageReader>
|
||||
# include <QMessageBox>
|
||||
# include <QTextStream>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <App/Document.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
# include <Gui/FileDialog.h>
|
||||
|
||||
#include "SpreadsheetView.h"
|
||||
#include "../App/Sheet.h"
|
||||
#include "../App/Range.h"
|
||||
#include "ViewProviderSpreadsheet.h"
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetMergeCells);
|
||||
|
||||
CmdSpreadsheetMergeCells::CmdSpreadsheetMergeCells()
|
||||
: Command("Spreadsheet_MergeCells")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Merge cells");
|
||||
sToolTipText = QT_TR_NOOP("Merge selected cells in spreadsheet");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetMergeCells";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetMergeCells::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
|
||||
// Execute mergeCells commands
|
||||
if (ranges.size() > 0) {
|
||||
Gui::Command::openCommand("Merge cells");
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
for (; i != ranges.end(); ++i)
|
||||
if (i->size() > 1)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.mergeCells('%s')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.setPosition('%s')", sheet->getNameInDocument(),
|
||||
ranges[0].address().c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetMergeCells::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetSplitCell);
|
||||
|
||||
CmdSpreadsheetSplitCell::CmdSpreadsheetSplitCell()
|
||||
: Command("Spreadsheet_SplitCell")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Split cell");
|
||||
sToolTipText = QT_TR_NOOP("Split previously merged cells in spreadsheet");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetSplitCell";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetSplitCell::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
QModelIndex current = sheetView->currentIndex();
|
||||
|
||||
if (current.isValid()) {
|
||||
std::string address = addressToString(CellAddress(current.row(), current.column()));
|
||||
Gui::Command::openCommand("Split cell");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.splitCell('%s')", sheet->getNameInDocument(),
|
||||
address.c_str());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetSplitCell::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
QModelIndex current = sheetView->currentIndex();
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
|
||||
if (current.isValid())
|
||||
return sheet->isMergedCell(CellAddress(current.row(), current.column()));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetImport);
|
||||
|
||||
CmdSpreadsheetImport::CmdSpreadsheetImport()
|
||||
: Command("Spreadsheet_Import")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Import spreadsheet");
|
||||
sToolTipText = QT_TR_NOOP("Import CSV file into spreadsheet");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetImport";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetImport::activated(int iMsg)
|
||||
{
|
||||
QString selectedFilter;
|
||||
QString formatList = QObject::tr("All (*)");
|
||||
QString fileName = Gui::FileDialog::getOpenFileName(Gui::getMainWindow(),
|
||||
QObject::tr("Import file"),
|
||||
QString(),
|
||||
formatList,
|
||||
&selectedFilter);
|
||||
if (!fileName.isEmpty()) {
|
||||
std::string FeatName = getUniqueObjectName("Spreadsheet");
|
||||
Sheet * sheet = freecad_dynamic_cast<Sheet>(App::GetApplication().getActiveDocument()->addObject("Spreadsheet::Sheet", FeatName.c_str()));
|
||||
|
||||
sheet->importFromFile(fileName.toStdString(), '\t', '"', '\\');
|
||||
sheet->execute();
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetImport::isActive()
|
||||
{
|
||||
return getActiveGuiDocument() ? true : false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetExport);
|
||||
|
||||
CmdSpreadsheetExport::CmdSpreadsheetExport()
|
||||
: Command("Spreadsheet_Export")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Export spreadsheet");
|
||||
sToolTipText = QT_TR_NOOP("Export spreadsheet to CSV file");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetExport";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetExport::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
QString selectedFilter;
|
||||
QString formatList = QObject::tr("All (*)");
|
||||
QString fileName = Gui::FileDialog::getSaveFileName(Gui::getMainWindow(),
|
||||
QObject::tr("Export file"),
|
||||
QString(),
|
||||
formatList,
|
||||
&selectedFilter);
|
||||
if (!fileName.isEmpty())
|
||||
sheet->exportToFile(fileName.toStdString(), '\t', '"', '\\');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetExport::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetAlignLeft);
|
||||
|
||||
CmdSpreadsheetAlignLeft::CmdSpreadsheetAlignLeft()
|
||||
: Command("Spreadsheet_AlignLeft")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Align left");
|
||||
sToolTipText = QT_TR_NOOP("Left-align contents of selected cells");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetAlignLeft";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetAlignLeft::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
|
||||
if (ranges.size() > 0) {
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Left-align cell");
|
||||
for (; i != ranges.end(); ++i)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setAlignment('%s', 'left', 'keep')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetAlignLeft::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetAlignCenter);
|
||||
|
||||
CmdSpreadsheetAlignCenter::CmdSpreadsheetAlignCenter()
|
||||
: Command("Spreadsheet_AlignCenter")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Align center");
|
||||
sToolTipText = QT_TR_NOOP("Center-align contents of selected cells");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetAlignCenter";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetAlignCenter::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
|
||||
if (ranges.size() > 0) {
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Center cell");
|
||||
for (; i != ranges.end(); ++i)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setAlignment('%s', 'center', 'keep')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetAlignCenter::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetAlignRight);
|
||||
|
||||
CmdSpreadsheetAlignRight::CmdSpreadsheetAlignRight()
|
||||
: Command("Spreadsheet_AlignRight")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Align right");
|
||||
sToolTipText = QT_TR_NOOP("Right-align contents of selected cells");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetAlignRight";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetAlignRight::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
|
||||
if (ranges.size() > 0) {
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Right-align cell");
|
||||
for (; i != ranges.end(); ++i)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setAlignment('%s', 'right', 'keep')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetAlignRight::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetAlignTop);
|
||||
|
||||
CmdSpreadsheetAlignTop::CmdSpreadsheetAlignTop()
|
||||
: Command("Spreadsheet_AlignTop")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Align top");
|
||||
sToolTipText = QT_TR_NOOP("Top-align contents of selected cells");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetAlignTop";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetAlignTop::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
|
||||
if (ranges.size() > 0) {
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Top-align cell");
|
||||
for (; i != ranges.end(); ++i)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setAlignment('%s', 'top', 'keep')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetAlignTop::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetAlignBottom);
|
||||
|
||||
CmdSpreadsheetAlignBottom::CmdSpreadsheetAlignBottom()
|
||||
: Command("Spreadsheet_AlignBottom")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Align bottom");
|
||||
sToolTipText = QT_TR_NOOP("Bottom-align contents of selected cells");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetAlignBottom";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetAlignBottom::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
|
||||
if (ranges.size() > 0) {
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Bottom-align cell");
|
||||
for (; i != ranges.end(); ++i)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setAlignment('%s', 'bottom', 'keep')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetAlignBottom::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetAlignVCenter);
|
||||
|
||||
CmdSpreadsheetAlignVCenter::CmdSpreadsheetAlignVCenter()
|
||||
: Command("Spreadsheet_AlignVCenter")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Vertically center-align");
|
||||
sToolTipText = QT_TR_NOOP("Center-align contents vertically of selected cells");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetAlignVCenter";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetAlignVCenter::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
|
||||
if (ranges.size() > 0) {
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Vertically center cells");
|
||||
for (; i != ranges.end(); ++i)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setAlignment('%s', 'vcenter', 'keep')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetAlignVCenter::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetStyleBold);
|
||||
|
||||
CmdSpreadsheetStyleBold::CmdSpreadsheetStyleBold()
|
||||
: Command("Spreadsheet_StyleBold")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Bold text");
|
||||
sToolTipText = QT_TR_NOOP("Set bold text in selected cells");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetStyleBold";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetStyleBold::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
QModelIndexList selection = sheetView->selectedIndexes();
|
||||
|
||||
if (selection.size() > 0) {
|
||||
bool allBold = true;
|
||||
|
||||
for (QModelIndexList::const_iterator it = selection.begin(); it != selection.end(); ++it) {
|
||||
std::set<std::string> style;
|
||||
|
||||
sheet->getCell(CellAddress((*it).row(), (*it).column()))->getStyle(style);
|
||||
if (style.find("bold") == style.end()) {
|
||||
allBold = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Set bold text");
|
||||
for (; i != ranges.end(); ++i) {
|
||||
if (!allBold)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setStyle('%s', 'bold', 'add')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
else
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setStyle('%s', 'bold', 'remove')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetStyleBold::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetStyleItalic);
|
||||
|
||||
CmdSpreadsheetStyleItalic::CmdSpreadsheetStyleItalic()
|
||||
: Command("Spreadsheet_StyleItalic")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Italic text");
|
||||
sToolTipText = QT_TR_NOOP("Set italic text in selected cells");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetStyleItalic";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetStyleItalic::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
QModelIndexList selection = sheetView->selectedIndexes();
|
||||
|
||||
if (selection.size() > 0) {
|
||||
bool allItalic = true;
|
||||
|
||||
for (QModelIndexList::const_iterator it = selection.begin(); it != selection.end(); ++it) {
|
||||
std::set<std::string> style;
|
||||
|
||||
sheet->getCell(CellAddress((*it).row(), (*it).column()))->getStyle(style);
|
||||
if (style.find("italic") == style.end()) {
|
||||
allItalic = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Set italic text");
|
||||
for (; i != ranges.end(); ++i) {
|
||||
if (!allItalic)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setStyle('%s', 'italic', 'add')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
else
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setStyle('%s', 'italic', 'remove')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetStyleItalic::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdSpreadsheetStyleUnderline);
|
||||
|
||||
CmdSpreadsheetStyleUnderline::CmdSpreadsheetStyleUnderline()
|
||||
: Command("Spreadsheet_StyleUnderline")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Underline text");
|
||||
sToolTipText = QT_TR_NOOP("Set underline text in selected cells");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "SpreadsheetStyleUnderline";
|
||||
}
|
||||
|
||||
void CmdSpreadsheetStyleUnderline::activated(int iMsg)
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
QModelIndexList selection = sheetView->selectedIndexes();
|
||||
|
||||
if (selection.size() > 0) {
|
||||
bool allUnderline = true;
|
||||
|
||||
for (QModelIndexList::const_iterator it = selection.begin(); it != selection.end(); ++it) {
|
||||
std::set<std::string> style;
|
||||
|
||||
sheet->getCell(CellAddress((*it).row(), (*it).column()))->getStyle(style);
|
||||
if (style.find("underline") == style.end()) {
|
||||
allUnderline = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Set underline text");
|
||||
for (; i != ranges.end(); ++i) {
|
||||
if (!allUnderline)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setStyle('%s', 'underline', 'add')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
else
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setStyle('%s', 'underline', 'remove')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str());
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSpreadsheetStyleUnderline::isActive()
|
||||
{
|
||||
if (getActiveGuiDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
if (activeWindow && freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
DEF_STD_CMD_A(CmdCreateSpreadsheet);
|
||||
|
||||
CmdCreateSpreadsheet::CmdCreateSpreadsheet()
|
||||
:Command("Spreadsheet_CreateSheet")
|
||||
{
|
||||
sAppModule = "Spreadsheet";
|
||||
sGroup = QT_TR_NOOP("Spreadsheet");
|
||||
sMenuText = QT_TR_NOOP("Create spreadsheet");
|
||||
sToolTipText = QT_TR_NOOP("Create a new spreadsheet");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Spreadsheet";
|
||||
}
|
||||
|
||||
void CmdCreateSpreadsheet::activated(int iMsg)
|
||||
{
|
||||
std::string FeatName = getUniqueObjectName("Spreadsheet");
|
||||
|
||||
openCommand("Create Spreadsheet");
|
||||
doCommand(Doc,"App.activeDocument().addObject('Spreadsheet::Sheet','%s\')",FeatName.c_str());
|
||||
commitCommand();
|
||||
}
|
||||
|
||||
bool CmdCreateSpreadsheet::isActive()
|
||||
{
|
||||
return App::GetApplication().getActiveDocument();
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
void CreateSpreadsheetCommands(void)
|
||||
{
|
||||
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
|
||||
|
||||
rcCmdMgr.addCommand(new CmdCreateSpreadsheet());
|
||||
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetMergeCells());
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetSplitCell());
|
||||
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetImport());
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetExport());
|
||||
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetAlignLeft());
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetAlignCenter());
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetAlignRight());
|
||||
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetAlignTop());
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetAlignVCenter());
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetAlignBottom());
|
||||
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetStyleBold());
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetStyleItalic());
|
||||
rcCmdMgr.addCommand(new CmdSpreadsheetStyleUnderline());
|
||||
}
|
||||
|
||||
24
src/Mod/Spreadsheet/Gui/PreCompiled.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 *
|
||||
* *
|
||||
* 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"
|
||||
79
src/Mod/Spreadsheet/Gui/PreCompiled.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 *
|
||||
* *
|
||||
* 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 __PRECOMPILED_GUI__
|
||||
#define __PRECOMPILED_GUI__
|
||||
|
||||
#include <FCConfig.h>
|
||||
|
||||
// Importing of App classes
|
||||
#ifdef FC_OS_WIN32
|
||||
# define SpreadsheetExport __declspec(dllimport)
|
||||
# define SpreadsheetGuiExport __declspec(dllexport)
|
||||
#else // for Linux
|
||||
# define SpreadsheetExport
|
||||
# define SpreadsheetGuiExport
|
||||
#endif
|
||||
|
||||
|
||||
// here get the warnings of too long specifiers disabled (needed for VC6)
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( disable : 4251 )
|
||||
# pragma warning( disable : 4503 )
|
||||
# pragma warning( disable : 4786 ) // specifier longer then 255 chars
|
||||
#endif
|
||||
|
||||
#ifdef _PreComp_
|
||||
|
||||
// Python
|
||||
#include <Python.h>
|
||||
|
||||
// standard
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
// STL
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <stack>
|
||||
#include <queue>
|
||||
#include <bitset>
|
||||
|
||||
#ifdef FC_OS_WIN32
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
// Qt Toolkit
|
||||
#ifndef __Qt4All__
|
||||
# include <Gui/Qt4All.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif //_PreComp_
|
||||
|
||||
#endif // __PRECOMPILED_GUI__
|
||||
297
src/Mod/Spreadsheet/Gui/PropertiesDialog.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
/***************************************************************************
|
||||
* 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 "PropertiesDialog.h"
|
||||
#include <Base/Tools.h>
|
||||
#include <Mod/Spreadsheet/App/Expression.h>
|
||||
#include <Mod/Spreadsheet/App/Range.h>
|
||||
#include <Gui/Command.h>
|
||||
#include "ui_PropertiesDialog.h"
|
||||
|
||||
using namespace Spreadsheet;
|
||||
using namespace SpreadsheetGui;
|
||||
|
||||
PropertiesDialog::PropertiesDialog(Sheet *_sheet, const std::vector<Range> &_ranges, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
sheet(_sheet),
|
||||
ranges(_ranges),
|
||||
ui(new Ui::PropertiesDialog),
|
||||
alignment(0),
|
||||
displayUnitOk(true),
|
||||
aliasOk(true)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->foregroundColor->setStandardColors();
|
||||
ui->backgroundColor->setStandardColors();
|
||||
|
||||
assert(ranges.size() > 0);
|
||||
Range range = ranges[0];
|
||||
|
||||
sheet->getNewCell(*range)->getForeground(foregroundColor);
|
||||
sheet->getCell(*range)->getBackground(backgroundColor);
|
||||
sheet->getCell(*range)->getAlignment(alignment);
|
||||
sheet->getCell(*range)->getStyle(style);
|
||||
sheet->getCell(*range)->getDisplayUnit(displayUnit);
|
||||
sheet->getCell(*range)->getAlias(alias);
|
||||
|
||||
orgForegroundColor = foregroundColor;
|
||||
orgBackgroundColor = backgroundColor;
|
||||
orgAlignment = alignment;
|
||||
orgStyle = style;
|
||||
orgDisplayUnit = displayUnit;
|
||||
orgAlias = alias;
|
||||
|
||||
ui->foregroundColor->setCurrentColor(QColor::fromRgbF(foregroundColor.r,
|
||||
foregroundColor.g,
|
||||
foregroundColor.b,
|
||||
foregroundColor.a));
|
||||
ui->backgroundColor->setCurrentColor(QColor::fromRgbF(backgroundColor.r,
|
||||
backgroundColor.g,
|
||||
backgroundColor.b,
|
||||
backgroundColor.a));
|
||||
|
||||
if (alignment & Cell::ALIGNMENT_LEFT)
|
||||
ui->alignLeft->setChecked(true);
|
||||
else if (alignment & Cell::ALIGNMENT_HCENTER)
|
||||
ui->alignHCenter->setChecked(true);
|
||||
else if (alignment & Cell::ALIGNMENT_RIGHT)
|
||||
ui->alignRight->setChecked(true);
|
||||
|
||||
if (alignment & Cell::ALIGNMENT_TOP)
|
||||
ui->alignTop->setChecked(true);
|
||||
else if (alignment & Cell::ALIGNMENT_VCENTER)
|
||||
ui->alignVCenter->setChecked(true);
|
||||
else if (alignment & Cell::ALIGNMENT_BOTTOM)
|
||||
ui->alignBottom->setChecked(true);
|
||||
|
||||
if (style.find("bold") != style.end())
|
||||
ui->styleBold->setChecked(true);
|
||||
if (style.find("italic") != style.end())
|
||||
ui->styleItalic->setChecked(true);
|
||||
if (style.find("underline") != style.end())
|
||||
ui->styleUnderline->setChecked(true);
|
||||
|
||||
ui->displayUnit->setText(QString::fromStdString(displayUnit.stringRep));
|
||||
|
||||
ui->alias->setText(QString::fromStdString(alias));
|
||||
|
||||
// Colors
|
||||
connect(ui->foregroundColor, SIGNAL(colorChanged(QColor)), this, SLOT(foregroundColorChanged(QColor)));
|
||||
connect(ui->backgroundColor, SIGNAL(colorChanged(QColor)), this, SLOT(backgroundColorChanged(QColor)));
|
||||
|
||||
// Alignment
|
||||
connect(ui->alignLeft, SIGNAL(clicked()), this, SLOT(alignmentChanged()));
|
||||
connect(ui->alignRight, SIGNAL(clicked()), this, SLOT(alignmentChanged()));
|
||||
connect(ui->alignHCenter, SIGNAL(clicked()), this, SLOT(alignmentChanged()));
|
||||
connect(ui->alignTop, SIGNAL(clicked()), this, SLOT(alignmentChanged()));
|
||||
connect(ui->alignVCenter, SIGNAL(clicked()), this, SLOT(alignmentChanged()));
|
||||
connect(ui->alignBottom, SIGNAL(clicked()), this, SLOT(alignmentChanged()));
|
||||
|
||||
// Style
|
||||
connect(ui->styleBold, SIGNAL(clicked()), this, SLOT(styleChanged()));
|
||||
connect(ui->styleItalic, SIGNAL(clicked()), this, SLOT(styleChanged()));
|
||||
connect(ui->styleUnderline, SIGNAL(clicked()), this, SLOT(styleChanged()));
|
||||
|
||||
// Display unit
|
||||
connect(ui->displayUnit, SIGNAL(textEdited(QString)), this, SLOT(displayUnitChanged(QString)));
|
||||
|
||||
// Alias is only allowed for a single cell
|
||||
ui->tabWidget->widget(4)->setEnabled(_ranges.size() == 1 && _ranges[0].size() == 1);
|
||||
|
||||
// Alias
|
||||
connect(ui->alias, SIGNAL(textEdited(QString)), this, SLOT(aliasChanged(QString)));
|
||||
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(displayUnitOk && aliasOk);
|
||||
}
|
||||
|
||||
void PropertiesDialog::foregroundColorChanged(const QColor & color)
|
||||
{
|
||||
foregroundColor = App::Color(color.redF(), color.greenF(), color.blueF(), color.alphaF());
|
||||
}
|
||||
|
||||
void PropertiesDialog::backgroundColorChanged(const QColor & color)
|
||||
{
|
||||
backgroundColor = App::Color(color.redF(), color.greenF(), color.blueF(), color.alphaF());
|
||||
}
|
||||
|
||||
void PropertiesDialog::alignmentChanged()
|
||||
{
|
||||
if (sender() == ui->alignLeft)
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_HORIZONTAL) | Cell::ALIGNMENT_LEFT;
|
||||
else if (sender() == ui->alignHCenter)
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_HORIZONTAL) | Cell::ALIGNMENT_HCENTER;
|
||||
else if (sender() == ui->alignRight)
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_HORIZONTAL) | Cell::ALIGNMENT_RIGHT;
|
||||
else if (sender() == ui->alignTop)
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_VERTICAL) | Cell::ALIGNMENT_TOP;
|
||||
else if (sender() == ui->alignVCenter)
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_VERTICAL) | Cell::ALIGNMENT_VCENTER;
|
||||
else if (sender() == ui->alignBottom)
|
||||
alignment = (alignment & ~Cell::ALIGNMENT_VERTICAL) | Cell::ALIGNMENT_BOTTOM;
|
||||
}
|
||||
|
||||
void PropertiesDialog::styleChanged()
|
||||
{
|
||||
if (sender() == ui->styleBold) {
|
||||
if (ui->styleBold->isChecked())
|
||||
style.insert("bold");
|
||||
else
|
||||
style.erase("bold");
|
||||
}
|
||||
else if (sender() == ui->styleItalic) {
|
||||
if (ui->styleItalic->isChecked())
|
||||
style.insert("italic");
|
||||
else
|
||||
style.erase("italic");
|
||||
}
|
||||
else if (sender() == ui->styleUnderline) {
|
||||
if (ui->styleUnderline->isChecked())
|
||||
style.insert("underline");
|
||||
else
|
||||
style.erase("underline");
|
||||
}
|
||||
}
|
||||
|
||||
void PropertiesDialog::displayUnitChanged(const QString & text)
|
||||
{
|
||||
if (text == "") {
|
||||
displayUnit = DisplayUnit();
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
QPalette palette = ui->displayUnit->palette();
|
||||
try {
|
||||
std::auto_ptr<UnitExpression> e(ExpressionParser::parseUnit(sheet, text.toUtf8().constData()));
|
||||
|
||||
displayUnit = DisplayUnit(text.toUtf8().constData(), e->getUnit(), e->getScaler());
|
||||
palette.setColor(QPalette::Text, Qt::black);
|
||||
displayUnitOk = true;
|
||||
}
|
||||
catch (...) {
|
||||
displayUnit = DisplayUnit();
|
||||
palette.setColor(QPalette::Text, text.size() == 0 ? Qt::black : Qt::red);
|
||||
displayUnitOk = false;
|
||||
}
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(displayUnitOk && aliasOk);
|
||||
ui->displayUnit->setPalette(palette);
|
||||
}
|
||||
|
||||
void PropertiesDialog::aliasChanged(const QString & text)
|
||||
{
|
||||
QPalette palette = ui->alias->palette();
|
||||
|
||||
if (text.indexOf(QRegExp("^[A-Za-z][_A-Za-z0-9]*$")) >= 0) {
|
||||
try {
|
||||
CellAddress address(text.toUtf8().constData());
|
||||
|
||||
palette.setColor(QPalette::Text, Qt::red);
|
||||
aliasOk = false;
|
||||
alias = "";
|
||||
}
|
||||
catch (...) {
|
||||
aliasOk = true;
|
||||
palette.setColor(QPalette::Text, Qt::black);
|
||||
alias = text.toStdString();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (text == "") {
|
||||
aliasOk = true;
|
||||
palette.setColor(QPalette::Text, Qt::black);
|
||||
}
|
||||
else {
|
||||
aliasOk = false;
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
palette.setColor(QPalette::Text, Qt::red);
|
||||
}
|
||||
alias = "";
|
||||
}
|
||||
|
||||
ui->alias->setPalette(palette);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(displayUnitOk && aliasOk);
|
||||
}
|
||||
|
||||
PropertiesDialog::~PropertiesDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void PropertiesDialog::apply()
|
||||
{
|
||||
if (ranges.size() > 0) {
|
||||
Gui::Command::openCommand("Set cell properties");
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
bool changes = false;
|
||||
|
||||
for (; i != ranges.end(); ++i) {
|
||||
if (orgAlignment != alignment) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setAlignment('%s', '%s')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str(), Cell::encodeAlignment(alignment).c_str());
|
||||
changes = true;
|
||||
}
|
||||
if (orgStyle != style) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setStyle('%s', '%s')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str(), Cell::encodeStyle(style).c_str());
|
||||
changes = true;
|
||||
}
|
||||
if (orgForegroundColor != foregroundColor) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setForeground('%s', (%f,%f,%f,%f))", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str(),
|
||||
foregroundColor.r,
|
||||
foregroundColor.g,
|
||||
foregroundColor.b,
|
||||
foregroundColor.a);
|
||||
changes = true;
|
||||
}
|
||||
if (orgBackgroundColor != backgroundColor) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setBackground('%s', (%f,%f,%f,%f))", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str(),
|
||||
backgroundColor.r,
|
||||
backgroundColor.g,
|
||||
backgroundColor.b,
|
||||
backgroundColor.a);
|
||||
changes = true;
|
||||
}
|
||||
if (orgDisplayUnit != displayUnit) {
|
||||
std::string escapedstr = Base::Tools::escapedUnicodeFromUtf8(displayUnit.stringRep.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setDisplayUnit('%s', '%s')", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str(), escapedstr.c_str());
|
||||
changes = true;
|
||||
}
|
||||
if (ranges.size() == 1 && ranges[0].size() == 1 && orgAlias != alias) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setAlias('%s', '%s')", sheet->getNameInDocument(),
|
||||
i->address().c_str(), alias.c_str());
|
||||
changes = true;
|
||||
}
|
||||
}
|
||||
if (changes) {
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
else
|
||||
Gui::Command::abortCommand();
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_PropertiesDialog.cpp"
|
||||
77
src/Mod/Spreadsheet/Gui/PropertiesDialog.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/***************************************************************************
|
||||
* 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 PROPERTIESDIALOG_H
|
||||
#define PROPERTIESDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "PreCompiled.h"
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
|
||||
namespace Ui {
|
||||
class PropertiesDialog;
|
||||
}
|
||||
|
||||
namespace SpreadsheetGui {
|
||||
|
||||
class PropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PropertiesDialog(Spreadsheet::Sheet *_sheet, const std::vector<Spreadsheet::Range> & _ranges, QWidget *parent = 0);
|
||||
~PropertiesDialog();
|
||||
|
||||
void apply();
|
||||
|
||||
private Q_SLOTS:
|
||||
void foregroundColorChanged(const QColor &color);
|
||||
void backgroundColorChanged(const QColor &color);
|
||||
void alignmentChanged();
|
||||
void styleChanged();
|
||||
void displayUnitChanged(const QString &text);
|
||||
void aliasChanged(const QString &text);
|
||||
private:
|
||||
Spreadsheet::Sheet * sheet;
|
||||
std::vector<Spreadsheet::Range> ranges;
|
||||
Ui::PropertiesDialog *ui;
|
||||
App::Color foregroundColor;
|
||||
App::Color backgroundColor;
|
||||
int alignment;
|
||||
std::set<std::string> style;
|
||||
Spreadsheet::DisplayUnit displayUnit;
|
||||
std::string alias;
|
||||
|
||||
App::Color orgForegroundColor;
|
||||
App::Color orgBackgroundColor;
|
||||
int orgAlignment;
|
||||
std::set<std::string> orgStyle;
|
||||
Spreadsheet::DisplayUnit orgDisplayUnit;
|
||||
std::string orgAlias;
|
||||
|
||||
bool displayUnitOk;
|
||||
bool aliasOk;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PROPERTIESDIALOG_H
|
||||
345
src/Mod/Spreadsheet/Gui/PropertiesDialog.ui
Normal file
@@ -0,0 +1,345 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PropertiesDialog</class>
|
||||
<widget class="QDialog" name="PropertiesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>426</width>
|
||||
<height>249</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Cell properties</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>&Color</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Text</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>240</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QtColorPicker" name="foregroundColor" native="true"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Background</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QtColorPicker" name="backgroundColor" native="true"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>&Alignment</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Horizontal</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="alignLeft">
|
||||
<property name="text">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="alignHCenter">
|
||||
<property name="text">
|
||||
<string>Center</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="alignRight">
|
||||
<property name="text">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Vertical</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="alignTop">
|
||||
<property name="text">
|
||||
<string>Top</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="alignVCenter">
|
||||
<property name="text">
|
||||
<string>Center</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="alignBottom">
|
||||
<property name="text">
|
||||
<string>Bottom</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>&Style</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="styleBold">
|
||||
<property name="text">
|
||||
<string>Bold</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="styleItalic">
|
||||
<property name="text">
|
||||
<string>Italic</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="styleUnderline">
|
||||
<property name="text">
|
||||
<string>Underline</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>&Display unit</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="displayUnit"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>123</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Unit string</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_5">
|
||||
<attribute name="title">
|
||||
<string>A&lias</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="alias"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Alias for this cell</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QtColorPicker</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>qtcolorpicker.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>PropertiesDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>PropertiesDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
19
src/Mod/Spreadsheet/Gui/Resources/Spreadsheet.qrc
Normal file
@@ -0,0 +1,19 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>icons/Spreadsheet.svg</file>
|
||||
<file>icons/SpreadsheetController.svg</file>
|
||||
<file>icons/SpreadsheetImport.svg</file>
|
||||
<file>icons/SpreadsheetExport.svg</file>
|
||||
<file>icons/SpreadsheetSplitCell.svg</file>
|
||||
<file>icons/SpreadsheetMergeCells.svg</file>
|
||||
<file>icons/SpreadsheetAlignRight.svg</file>
|
||||
<file>icons/SpreadsheetAlignLeft.svg</file>
|
||||
<file>icons/SpreadsheetAlignCenter.svg</file>
|
||||
<file>icons/SpreadsheetAlignVCenter.svg</file>
|
||||
<file>icons/SpreadsheetAlignTop.svg</file>
|
||||
<file>icons/SpreadsheetAlignBottom.svg</file>
|
||||
<file>icons/SpreadsheetStyleUnderline.svg</file>
|
||||
<file>icons/SpreadsheetStyleItalic.svg</file>
|
||||
<file>icons/SpreadsheetStyleBold.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="SpreadsheetAlignTop.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3692"
|
||||
cx="45.883327"
|
||||
cy="28.869568"
|
||||
fx="45.883327"
|
||||
fy="28.869568"
|
||||
r="19.467436"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3703"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="135.38333"
|
||||
cy="97.369568"
|
||||
fx="135.38333"
|
||||
fy="97.369568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3705"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="148.88333"
|
||||
cy="81.869568"
|
||||
fx="148.88333"
|
||||
fy="81.869568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="10.658514"
|
||||
inkscape:cy="35.257738"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="876"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#030000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="rect3068"
|
||||
width="65.090912"
|
||||
height="64.36364"
|
||||
x="-0.90909213"
|
||||
y="-0.36363849" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.49824524;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 7.3625277,29.636364 47.0931263,0"
|
||||
id="path3790"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.98300838;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 7.6478315,40.793448 31.7952445,0"
|
||||
id="path3794"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.49824524;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 6.635255,52.181818 47.093126,0"
|
||||
id="path3790-40"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
@@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="SpreadsheetAlignCenter.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3692"
|
||||
cx="45.883327"
|
||||
cy="28.869568"
|
||||
fx="45.883327"
|
||||
fy="28.869568"
|
||||
r="19.467436"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3703"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="135.38333"
|
||||
cy="97.369568"
|
||||
fx="135.38333"
|
||||
fy="97.369568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3705"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="148.88333"
|
||||
cy="81.869568"
|
||||
fx="148.88333"
|
||||
fy="81.869568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="10.658514"
|
||||
inkscape:cy="35.257738"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="876"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#030000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="rect3068"
|
||||
width="65.090912"
|
||||
height="64.36364"
|
||||
x="-0.90909213"
|
||||
y="-0.36363849" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.49824524;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 8.2716186,20.545455 47.0931264,0"
|
||||
id="path3790"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.98300838;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 15.647832,32.429811 31.795245,0"
|
||||
id="path3794"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.94518471;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 4.7572062,44.483064 54.1219518,0"
|
||||
id="path3796"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.25173235;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 11.077051,8.9090905 41.118626,0"
|
||||
id="path3790-8"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.20950508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 15.997228,56 31.278271,0"
|
||||
id="path3790-4"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
149
src/Mod/Spreadsheet/Gui/Resources/icons/SpreadsheetAlignLeft.svg
Normal file
@@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="SpreadsheetAlignLeft.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3692"
|
||||
cx="45.883327"
|
||||
cy="28.869568"
|
||||
fx="45.883327"
|
||||
fy="28.869568"
|
||||
r="19.467436"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3703"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="135.38333"
|
||||
cy="97.369568"
|
||||
fx="135.38333"
|
||||
fy="97.369568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3705"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="148.88333"
|
||||
cy="81.869568"
|
||||
fx="148.88333"
|
||||
fy="81.869568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="10.658514"
|
||||
inkscape:cy="35.257738"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="876"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#030000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="rect3068"
|
||||
width="65.090912"
|
||||
height="64.36364"
|
||||
x="-0.90909249"
|
||||
y="-0.18182078" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.95484757;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 4,20.545455 54.38739,0"
|
||||
id="path3790"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.55215096;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 4,32.429811 43.4453,0"
|
||||
id="path3794"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.57292891;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 4,44.483064 44.390244,0"
|
||||
id="path3796"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.97173762;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 4.1936752,9.454545 40.4175278,0"
|
||||
id="path3790-8"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.85852957;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 3.8181816,56 55.588692,56"
|
||||
id="path3790-4"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
@@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="SpreadsheetAlignRight.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3692"
|
||||
cx="45.883327"
|
||||
cy="28.869568"
|
||||
fx="45.883327"
|
||||
fy="28.869568"
|
||||
r="19.467436"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3703"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="135.38333"
|
||||
cy="97.369568"
|
||||
fx="135.38333"
|
||||
fy="97.369568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3705"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="148.88333"
|
||||
cy="81.869568"
|
||||
fx="148.88333"
|
||||
fy="81.869568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="10.658514"
|
||||
inkscape:cy="35.257738"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="876"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#030000;stroke-width:3.59999989999999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="rect3068"
|
||||
width="65.090912"
|
||||
height="64.36364"
|
||||
x="0.18181819"
|
||||
y="0" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.88404441;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 16.124723,20.545455 43.511641,0"
|
||||
id="path3790"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.83060455;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 8.5672727,32.429811 50.5236363,0"
|
||||
id="path3794"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.69230366;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 20.693459,44.483064 38.942905,0"
|
||||
id="path3796"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.20847988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 11.896315,8.9090905 47.558231,0"
|
||||
id="path3790-8"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.4652288;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 17.700111,56 41.754435,0"
|
||||
id="path3790-4"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
139
src/Mod/Spreadsheet/Gui/Resources/icons/SpreadsheetAlignTop.svg
Normal file
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="SpreadsheetAlignTop.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3692"
|
||||
cx="45.883327"
|
||||
cy="28.869568"
|
||||
fx="45.883327"
|
||||
fy="28.869568"
|
||||
r="19.467436"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3703"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="135.38333"
|
||||
cy="97.369568"
|
||||
fx="135.38333"
|
||||
fy="97.369568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3705"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="148.88333"
|
||||
cy="81.869568"
|
||||
fx="148.88333"
|
||||
fy="81.869568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="10.658514"
|
||||
inkscape:cy="35.257738"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="876"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#030000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="rect3068"
|
||||
width="65.090912"
|
||||
height="64.36364"
|
||||
x="-0.90909213"
|
||||
y="-0.36363849" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.49824524;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 7.1807095,10.909091 47.0931265,0"
|
||||
id="path3790"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.98300838;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 7.4660133,22.247993 31.7952447,0"
|
||||
id="path3794"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.49824524;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 7.1807095,33.272727 47.0931265,0"
|
||||
id="path3790-40"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="SpreadsheetAlignVCenter.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3692"
|
||||
cx="45.883327"
|
||||
cy="28.869568"
|
||||
fx="45.883327"
|
||||
fy="28.869568"
|
||||
r="19.467436"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3703"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="135.38333"
|
||||
cy="97.369568"
|
||||
fx="135.38333"
|
||||
fy="97.369568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3705"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="148.88333"
|
||||
cy="81.869568"
|
||||
fx="148.88333"
|
||||
fy="81.869568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="10.658514"
|
||||
inkscape:cy="35.257738"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="876"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#030000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="rect3068"
|
||||
width="65.090912"
|
||||
height="64.36364"
|
||||
x="-0.90909213"
|
||||
y="-0.36363849" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.49824524;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 8.2716186,20.545455 47.0931264,0"
|
||||
id="path3790"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.98300838;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 9.2841951,32.066175 31.7952449,0"
|
||||
id="path3794"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.49824524;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 7.5443459,43.454545 47.0931261,0"
|
||||
id="path3790-40"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
654
src/Mod/Spreadsheet/Gui/Resources/icons/SpreadsheetExport.svg
Normal file
|
After Width: | Height: | Size: 31 KiB |
554
src/Mod/Spreadsheet/Gui/Resources/icons/SpreadsheetImport.svg
Normal file
|
After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="Spreadsheet.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3692"
|
||||
cx="45.883327"
|
||||
cy="28.869568"
|
||||
fx="45.883327"
|
||||
fy="28.869568"
|
||||
r="19.467436"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3703"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="135.38333"
|
||||
cy="97.369568"
|
||||
fx="135.38333"
|
||||
fy="97.369568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3705"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="148.88333"
|
||||
cy="81.869568"
|
||||
fx="148.88333"
|
||||
fy="81.869568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11"
|
||||
inkscape:cx="43.689905"
|
||||
inkscape:cy="36.551269"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="876"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002-9"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 4.9090909,25.338902 60,25.338902"
|
||||
id="path3794"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 4.5454546,41.392155 55.6363634,0"
|
||||
id="path3796"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.47719836px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 23.727274,42.363636 c 0,14.181818 0,14.181818 0,14.181818"
|
||||
id="path4679"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.47719836px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 41.818182,41.636364 c 0,14.181817 0,14.181817 0,14.181817"
|
||||
id="path4679-2"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.47719836px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 23.272727,9.818182 c 0,14.181818 0,14.181818 0,14.181818"
|
||||
id="path4679-3"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.47719836px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 41.636364,9.8181824 c 0,14.1818166 0,14.1818166 0,14.1818166"
|
||||
id="path4679-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 19.678277,29.014962 -6.587368,3.803219 37.090909,0 -6.664684,-3.847857"
|
||||
id="path5239"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 19.678277,37.606563 -6.587368,-3.803219 37.090909,0 -6.664684,3.847857"
|
||||
id="path5239-5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
192
src/Mod/Spreadsheet/Gui/Resources/icons/SpreadsheetSplitCell.svg
Normal file
|
After Width: | Height: | Size: 10 KiB |
136
src/Mod/Spreadsheet/Gui/Resources/icons/SpreadsheetStyleBold.svg
Normal file
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="SpreadsheetStyleBold.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3692"
|
||||
cx="45.883327"
|
||||
cy="28.869568"
|
||||
fx="45.883327"
|
||||
fy="28.869568"
|
||||
r="19.467436"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3703"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="135.38333"
|
||||
cy="97.369568"
|
||||
fx="135.38333"
|
||||
fy="97.369568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3705"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="148.88333"
|
||||
cy="81.869568"
|
||||
fx="148.88333"
|
||||
fy="81.869568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="10.658514"
|
||||
inkscape:cy="35.257738"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="876"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#030000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="rect3068"
|
||||
width="65.090912"
|
||||
height="64.36364"
|
||||
x="-0.90909249"
|
||||
y="-0.18182078" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="16.363634"
|
||||
y="45.999996"
|
||||
id="text4123"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4125"
|
||||
x="16.363634"
|
||||
y="45.999996"
|
||||
style="font-weight:bold">B</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="SpreadsheetStyleBold.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3692"
|
||||
cx="45.883327"
|
||||
cy="28.869568"
|
||||
fx="45.883327"
|
||||
fy="28.869568"
|
||||
r="19.467436"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3703"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="135.38333"
|
||||
cy="97.369568"
|
||||
fx="135.38333"
|
||||
fy="97.369568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3705"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="148.88333"
|
||||
cy="81.869568"
|
||||
fx="148.88333"
|
||||
fy="81.869568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="10.658514"
|
||||
inkscape:cy="35.257738"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="876"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#030000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="rect3068"
|
||||
width="65.090912"
|
||||
height="64.36364"
|
||||
x="-0.90909249"
|
||||
y="-0.18182078" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="23.81818"
|
||||
y="46.545452"
|
||||
id="text4123"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4125"
|
||||
x="23.81818"
|
||||
y="46.545452"
|
||||
style="font-style:italic;font-weight:normal">i</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="SpreadsheetStyleUnderline.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3692"
|
||||
cx="45.883327"
|
||||
cy="28.869568"
|
||||
fx="45.883327"
|
||||
fy="28.869568"
|
||||
r="19.467436"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3703"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="135.38333"
|
||||
cy="97.369568"
|
||||
fx="135.38333"
|
||||
fy="97.369568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3705"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="148.88333"
|
||||
cy="81.869568"
|
||||
fx="148.88333"
|
||||
fy="81.869568"
|
||||
r="19.467436"
|
||||
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="10.658514"
|
||||
inkscape:cy="35.257738"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="876"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#030000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="rect3068"
|
||||
width="65.090912"
|
||||
height="64.36364"
|
||||
x="-0.90909249"
|
||||
y="-0.18182078" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3002"
|
||||
width="56.18182"
|
||||
height="46.545456"
|
||||
x="4"
|
||||
y="9.272728" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="16.727272"
|
||||
y="42.909088"
|
||||
id="text4123"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4125"
|
||||
x="16.727272"
|
||||
y="42.909088"
|
||||
style="font-style:normal;font-weight:normal">U</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.11890268px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 20.363637,48.181818 22.795883,0"
|
||||
id="path4186"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
56
src/Mod/Spreadsheet/Gui/Sheet.ui
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Sheet</class>
|
||||
<widget class="QWidget" name="Sheet">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>727</width>
|
||||
<height>596</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>&Contents</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>cellContent</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="cellContent">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SpreadsheetGui::SheetTableView" name="cells"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>SpreadsheetGui::SheetTableView</class>
|
||||
<extends>QTableView</extends>
|
||||
<header>SheetTableView.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>cells</tabstop>
|
||||
<tabstop>cellContent</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
435
src/Mod/Spreadsheet/Gui/SheetModel.cpp
Normal file
@@ -0,0 +1,435 @@
|
||||
/***************************************************************************
|
||||
* 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"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <QtCore>
|
||||
# include <QApplication>
|
||||
# include <QMessageBox>
|
||||
#endif
|
||||
|
||||
#include "SheetModel.h"
|
||||
#include <Mod/Spreadsheet/App/Expression.h>
|
||||
#include <Mod/Spreadsheet/App/Utils.h>
|
||||
#include "../App/Sheet.h"
|
||||
#include <Gui/Command.h>
|
||||
#include <strstream>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
using namespace App;
|
||||
|
||||
SheetModel::SheetModel(Sheet *_sheet, QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
, sheet(_sheet)
|
||||
{
|
||||
cellUpdatedConnection = sheet->cellUpdated.connect(bind(&SheetModel::cellUpdated, this, _1));
|
||||
}
|
||||
|
||||
SheetModel::~SheetModel()
|
||||
{
|
||||
cellUpdatedConnection.disconnect();
|
||||
}
|
||||
|
||||
int SheetModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 16384;
|
||||
}
|
||||
|
||||
int SheetModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 26 * 26 + 26;
|
||||
}
|
||||
|
||||
static void appendUnit(int l, bool isNumerator, std::string unit, std::vector<std::string> & v)
|
||||
{
|
||||
if (l == 0)
|
||||
return;
|
||||
if ((l < 0) ^ isNumerator ) {
|
||||
std::ostringstream s;
|
||||
|
||||
s << unit;
|
||||
if (abs(l) > 1)
|
||||
s << "^" << abs(l);
|
||||
|
||||
v.push_back(s.str());
|
||||
}
|
||||
}
|
||||
|
||||
static std::string getUnitString(const Base::Unit & unit)
|
||||
{
|
||||
std::vector<std::string> numerator;
|
||||
std::vector<std::string> denominator;
|
||||
const Base::UnitSignature & sig = unit.getSignature();
|
||||
|
||||
// Nominator
|
||||
appendUnit(sig.Length, true, "mm", numerator);
|
||||
appendUnit(sig.Mass, true, "kg", numerator);
|
||||
appendUnit(sig.Time, true, "s", numerator);
|
||||
appendUnit(sig.ElectricCurrent, true, "A", numerator);
|
||||
appendUnit(sig.ThermodynamicTemperature, true, "K", numerator);
|
||||
appendUnit(sig.AmountOfSubstance, true, "mol", numerator);
|
||||
appendUnit(sig.LuminoseIntensity, true, "cd", numerator);
|
||||
appendUnit(sig.Angle, true, "deg", numerator);
|
||||
|
||||
// Denominator
|
||||
appendUnit(sig.Length, false, "mm", denominator);
|
||||
appendUnit(sig.Mass, false, "kg", denominator);
|
||||
appendUnit(sig.Time, false, "s", denominator);
|
||||
appendUnit(sig.ElectricCurrent, false, "A", denominator);
|
||||
appendUnit(sig.ThermodynamicTemperature, false, "K", denominator);
|
||||
appendUnit(sig.AmountOfSubstance, false, "mol", denominator);
|
||||
appendUnit(sig.LuminoseIntensity, false, "cd", denominator);
|
||||
appendUnit(sig.Angle, false, "deg", denominator);
|
||||
|
||||
std::string unitStr;
|
||||
|
||||
if (numerator.size() > 0) {
|
||||
for (int i = 0; i < numerator.size(); ++i) {
|
||||
if (i > 0)
|
||||
unitStr += "*";
|
||||
unitStr += numerator[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (denominator.size() > 0) {
|
||||
if (numerator.size() == 0)
|
||||
unitStr = "1";
|
||||
unitStr += "/";
|
||||
|
||||
if (denominator.size() > 1)
|
||||
unitStr += "(";
|
||||
for (int i = 0; i < denominator.size(); ++i) {
|
||||
if (i > 0)
|
||||
unitStr += "*";
|
||||
unitStr += denominator[i];
|
||||
}
|
||||
if (denominator.size() > 1)
|
||||
unitStr += ")";
|
||||
}
|
||||
|
||||
return unitStr;
|
||||
}
|
||||
|
||||
QVariant SheetModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
static const Cell * emptyCell = new Cell(CellAddress(0, 0), 0);
|
||||
int row = index.row();
|
||||
int col = index.column();
|
||||
const Cell * cell = sheet->getCell(CellAddress(row, col));
|
||||
|
||||
if (cell == 0)
|
||||
cell = emptyCell;
|
||||
|
||||
//#define DEBUG_DEPS
|
||||
#ifdef DEBUG_DEPS
|
||||
if (role == Qt::ToolTipRole) {
|
||||
QString v;
|
||||
|
||||
std::set<std::string> deps = sheet->dependsOn(row, col);
|
||||
std::set<std::string> provides;
|
||||
|
||||
sheet->providesTo(row, col, provides);
|
||||
|
||||
if (deps.size() > 0) {
|
||||
v += QString::fromUtf8("Depends on:");
|
||||
for (std::set<std::string>::const_iterator i = deps.begin(); i != deps.end(); ++i)
|
||||
v += QString::fromUtf8("\n\t") + QString::fromStdString(*i);
|
||||
v += QString::fromUtf8("\n");
|
||||
}
|
||||
if (provides.size() > 0) {
|
||||
v += QString::fromUtf8("Used by:");
|
||||
for (std::set<std::string>::const_iterator i = provides.begin(); i != provides.end(); ++i)
|
||||
v += QString::fromUtf8("\n\t") + QString::fromStdString(*i);
|
||||
v += QString::fromUtf8("\n");
|
||||
}
|
||||
return QVariant(v);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cell->hasException()) {
|
||||
switch (role) {
|
||||
case Qt::ToolTipRole:
|
||||
return QVariant::fromValue(QString::fromStdString(cell->getException()));
|
||||
case Qt::DisplayRole:
|
||||
#ifdef DEBUG_DEPS
|
||||
return QVariant::fromValue(QString::fromUtf8("#ERR: %1").arg(QString::fromStdString(cell->getException())));
|
||||
#else
|
||||
return QVariant::fromValue(QString::fromUtf8("#ERR"));
|
||||
#endif
|
||||
case Qt::TextAlignmentRole:
|
||||
return QVariant(Qt::AlignVCenter | Qt::AlignLeft);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get edit value by querying the sheet
|
||||
if (role == Qt::EditRole || role == Qt::StatusTipRole) {
|
||||
std::string str;
|
||||
|
||||
if (cell->getStringContent(str))
|
||||
return QVariant(QString::fromUtf8(str.c_str()));
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// Get display value as computed property
|
||||
std::string address = addressToString(CellAddress(row, col));
|
||||
Property * prop = sheet->getPropertyByName(address.c_str());
|
||||
|
||||
if (prop == 0)
|
||||
return QVariant();
|
||||
|
||||
Color color;
|
||||
if (role == Qt::TextColorRole || role == Qt::ForegroundRole) {
|
||||
if (cell->getForeground(color))
|
||||
return QVariant::fromValue(QColor(255.0 * color.r, 255.0 * color.g, 255.0 * color.b, 255.0 * color.a));
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (role == Qt::BackgroundRole) {
|
||||
if (cell->getBackground(color))
|
||||
return QVariant::fromValue(QColor(255.0 * color.r, 255.0 * color.g, 255.0 * color.b, 255.0 * color.a));
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
int qtAlignment = 0;
|
||||
|
||||
int alignment;
|
||||
cell->getAlignment(alignment);
|
||||
|
||||
if (alignment & Cell::ALIGNMENT_LEFT)
|
||||
qtAlignment |= Qt::AlignLeft;
|
||||
if (alignment & Cell::ALIGNMENT_HCENTER)
|
||||
qtAlignment |= Qt::AlignHCenter;
|
||||
if (alignment & Cell::ALIGNMENT_RIGHT)
|
||||
qtAlignment |= Qt::AlignRight;
|
||||
if (alignment & Cell::ALIGNMENT_TOP)
|
||||
qtAlignment |= Qt::AlignTop;
|
||||
if (alignment & Cell::ALIGNMENT_VCENTER)
|
||||
qtAlignment |= Qt::AlignVCenter;
|
||||
if (alignment & Cell::ALIGNMENT_BOTTOM)
|
||||
qtAlignment |= Qt::AlignBottom;
|
||||
|
||||
std::set<std::string> style;
|
||||
if (role == Qt::FontRole && cell->getStyle(style)) {
|
||||
QFont f;
|
||||
|
||||
for (std::set<std::string>::const_iterator i = style.begin(); i != style.end(); ++i) {
|
||||
if (*i == "bold")
|
||||
f.setBold(true);
|
||||
else if (*i == "italic")
|
||||
f.setItalic(true);
|
||||
else if (*i == "underline")
|
||||
f.setUnderline(true);
|
||||
}
|
||||
|
||||
return QVariant::fromValue(f);
|
||||
}
|
||||
|
||||
if (prop->isDerivedFrom(App::PropertyString::getClassTypeId())) {
|
||||
/* String */
|
||||
const App::PropertyString * stringProp = static_cast<const App::PropertyString*>(prop);
|
||||
|
||||
switch (role) {
|
||||
case Qt::TextColorRole:
|
||||
return QVariant::fromValue(QColor(Qt::black));
|
||||
case Qt::DisplayRole:
|
||||
return QVariant(QString::fromUtf8(stringProp->getValue()));
|
||||
case Qt::TextAlignmentRole: {
|
||||
if (alignment & Cell::ALIGNMENT_HIMPLIED) {
|
||||
qtAlignment &= ~(Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight);
|
||||
qtAlignment |= Qt::AlignLeft;
|
||||
}
|
||||
if (alignment & Cell::ALIGNMENT_VIMPLIED) {
|
||||
qtAlignment &= ~(Qt::AlignTop | Qt::AlignVCenter | Qt::AlignBottom);
|
||||
qtAlignment |= Qt::AlignVCenter;
|
||||
}
|
||||
return QVariant::fromValue(qtAlignment);
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
else if (prop->isDerivedFrom(App::PropertyQuantity::getClassTypeId())) {
|
||||
/* Number */
|
||||
const App::PropertyQuantity * floatProp = static_cast<const App::PropertyQuantity*>(prop);
|
||||
|
||||
switch (role) {
|
||||
case Qt::TextColorRole:
|
||||
if (floatProp->getValue() < 0)
|
||||
return QVariant::fromValue(QColor(Qt::red));
|
||||
else
|
||||
return QVariant::fromValue(QColor(Qt::blue));
|
||||
case Qt::TextAlignmentRole: {
|
||||
if (alignment & Cell::ALIGNMENT_HIMPLIED) {
|
||||
qtAlignment &= ~(Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight);
|
||||
qtAlignment |= Qt::AlignRight;
|
||||
}
|
||||
if (alignment & Cell::ALIGNMENT_VIMPLIED) {
|
||||
qtAlignment &= ~(Qt::AlignTop | Qt::AlignVCenter | Qt::AlignBottom);
|
||||
qtAlignment |= Qt::AlignVCenter;
|
||||
}
|
||||
return QVariant::fromValue(qtAlignment);
|
||||
}
|
||||
case Qt::DisplayRole: {
|
||||
QString v;
|
||||
const Base::Unit & computedUnit = floatProp->getUnit();
|
||||
DisplayUnit displayUnit;
|
||||
|
||||
if (cell->getDisplayUnit(displayUnit)) {
|
||||
if (computedUnit.isEmpty() || computedUnit == displayUnit.unit)
|
||||
v = QString::number(floatProp->getValue() / displayUnit.scaler) + QString::fromStdString(" " + displayUnit.stringRep);
|
||||
else
|
||||
v = QString::fromUtf8("ERR: unit");
|
||||
}
|
||||
else {
|
||||
if (!computedUnit.isEmpty())
|
||||
v = QString::number(floatProp->getValue()) + QString::fromStdString(" " + getUnitString(computedUnit));
|
||||
else
|
||||
v = QString::number(floatProp->getValue());
|
||||
}
|
||||
|
||||
return QVariant(v);
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
else if (prop->isDerivedFrom(App::PropertyFloat::getClassTypeId())) {
|
||||
/* Number */
|
||||
const App::PropertyFloat * floatProp = static_cast<const App::PropertyFloat*>(prop);
|
||||
|
||||
switch (role) {
|
||||
case Qt::TextColorRole:
|
||||
if (floatProp->getValue() < 0)
|
||||
return QVariant::fromValue(QColor(Qt::red));
|
||||
else
|
||||
return QVariant::fromValue(QColor(Qt::blue));
|
||||
case Qt::TextAlignmentRole: {
|
||||
if (alignment & Cell::ALIGNMENT_HIMPLIED) {
|
||||
qtAlignment &= ~(Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight);
|
||||
qtAlignment |= Qt::AlignRight;
|
||||
}
|
||||
if (alignment & Cell::ALIGNMENT_VIMPLIED) {
|
||||
qtAlignment &= ~(Qt::AlignTop | Qt::AlignVCenter | Qt::AlignBottom);
|
||||
qtAlignment |= Qt::AlignVCenter;
|
||||
}
|
||||
return QVariant::fromValue(qtAlignment);
|
||||
}
|
||||
case Qt::DisplayRole: {
|
||||
QString v;
|
||||
DisplayUnit displayUnit;
|
||||
|
||||
if (cell->getDisplayUnit(displayUnit))
|
||||
v = QString::number(floatProp->getValue() / displayUnit.scaler) + QString::fromStdString(" " + displayUnit.stringRep);
|
||||
else
|
||||
v = QString::number(floatProp->getValue());
|
||||
return QVariant(v);
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariant SheetModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role == Qt::SizeHintRole) {
|
||||
if (orientation == Qt::Horizontal)
|
||||
return QVariant(QSize(sheet->getColumnWidth(section), PropertyRowHeights::defaultHeight));
|
||||
else
|
||||
return QVariant(QSize(PropertyColumnWidths::defaultHeaderWidth, sheet->getRowHeight(section)));
|
||||
}
|
||||
if (role == Qt::DisplayRole) {
|
||||
if (orientation == Qt::Horizontal) {
|
||||
static QString labels = QString::fromUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
if (section < 26) {
|
||||
return QVariant(labels[section]);
|
||||
}
|
||||
else {
|
||||
section -= 26;
|
||||
return QVariant(QString(labels[section / 26]) + QString(labels[section % 26]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
return QString::number(section + 1);
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool SheetModel::setData(const QModelIndex & index, const QVariant & value, int role)
|
||||
{
|
||||
if (role == Qt::DisplayRole) {
|
||||
// Nothing to do, it will get updated by the sheet in the application logic
|
||||
}
|
||||
else if (role == Qt::EditRole) {
|
||||
CellAddress address(index.row(), index.column());
|
||||
|
||||
try {
|
||||
std::string strAddress = addressToString(address);
|
||||
std::string next_address = addressToString(CellAddress(address.row() + 1, address.col()));
|
||||
QString str = value.toString();
|
||||
std::string content;
|
||||
Cell * cell = sheet->getCell(address);
|
||||
|
||||
if (cell)
|
||||
cell->getStringContent(content);
|
||||
|
||||
if ( content != str.toStdString()) {
|
||||
str.replace(QString::fromUtf8("'"), QString::fromUtf8("\\'"));
|
||||
Gui::Command::openCommand("Edit cell");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.set('%s', '%s')", sheet->getNameInDocument(),
|
||||
strAddress.c_str(), str.toUtf8().constData());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setPosition('%s')", sheet->getNameInDocument(),
|
||||
next_address.c_str());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
QMessageBox::critical(qApp->activeWindow(), QObject::tr("Cell contents"), QString::fromUtf8(e.what()));
|
||||
Gui::Command::abortCommand();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::ItemFlags SheetModel::flags(const QModelIndex & /*index*/) const
|
||||
{
|
||||
return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
|
||||
}
|
||||
|
||||
void SheetModel::cellUpdated(CellAddress address)
|
||||
{
|
||||
QModelIndex i = index(address.row(), address.col());
|
||||
|
||||
dataChanged(i, i);
|
||||
}
|
||||
|
||||
#include "moc_SheetModel.cpp"
|
||||
60
src/Mod/Spreadsheet/Gui/SheetModel.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/***************************************************************************
|
||||
* 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 SHEETMODEL_H
|
||||
#define SHEETMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <boost/signals/connection.hpp>
|
||||
#include <Mod/Spreadsheet/App/Utils.h>
|
||||
|
||||
namespace Spreadsheet {
|
||||
class Sheet;
|
||||
}
|
||||
|
||||
namespace SpreadsheetGui {
|
||||
|
||||
class SheetModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SheetModel(Spreadsheet::Sheet * _sheet, QObject *parent = 0);
|
||||
~SheetModel();
|
||||
|
||||
SheetModel(QObject *parent);
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const ;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
Qt::ItemFlags flags(const QModelIndex &) const;
|
||||
|
||||
private:
|
||||
void cellUpdated(Spreadsheet::CellAddress address);
|
||||
|
||||
boost::BOOST_SIGNALS_NAMESPACE::scoped_connection cellUpdatedConnection;
|
||||
Spreadsheet::Sheet * sheet;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SHEETMODEL_H
|
||||
299
src/Mod/Spreadsheet/Gui/SheetTableView.cpp
Normal file
@@ -0,0 +1,299 @@
|
||||
/***************************************************************************
|
||||
* 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"
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include "SheetTableView.h"
|
||||
#include <QKeyEvent>
|
||||
#include <QAction>
|
||||
#include <Gui/Command.h>
|
||||
#include "PropertiesDialog.h"
|
||||
#include "../App/Utils.h"
|
||||
#include "../App/Range.h"
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
void SheetViewHeader::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
QHeaderView::mouseReleaseEvent(event);
|
||||
resizeFinished();
|
||||
}
|
||||
|
||||
SheetTableView::SheetTableView(QWidget *parent)
|
||||
: QTableView(parent)
|
||||
{
|
||||
QAction * insertRows = new QAction(tr("Insert rows"), this);
|
||||
QAction * removeRows = new QAction(tr("Remove rows"), this);
|
||||
QAction * insertColumns = new QAction(tr("Insert columns"), this);
|
||||
QAction * removeColumns = new QAction(tr("Remove columns"), this);
|
||||
|
||||
setHorizontalHeader(new SheetViewHeader(Qt::Horizontal));
|
||||
setVerticalHeader(new SheetViewHeader(Qt::Vertical));
|
||||
|
||||
horizontalHeader()->addAction(insertColumns);
|
||||
horizontalHeader()->addAction(removeColumns);
|
||||
horizontalHeader()->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
|
||||
verticalHeader()->addAction(insertRows);
|
||||
verticalHeader()->addAction(removeRows);
|
||||
verticalHeader()->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
|
||||
connect(insertRows, SIGNAL(triggered()), this, SLOT(insertRows()));
|
||||
connect(insertColumns, SIGNAL(triggered()), this, SLOT(insertColumns()));
|
||||
connect(removeRows, SIGNAL(triggered()), this, SLOT(removeRows()));
|
||||
connect(removeColumns, SIGNAL(triggered()), this, SLOT(removeColumns()));
|
||||
|
||||
QAction * cellProperties = new QAction(tr("Properties..."), this);
|
||||
setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
addAction(cellProperties);
|
||||
|
||||
connect(cellProperties, SIGNAL(triggered()), this, SLOT(cellProperties()));
|
||||
}
|
||||
|
||||
void SheetTableView::cellProperties()
|
||||
{
|
||||
std::auto_ptr<PropertiesDialog> dialog(new PropertiesDialog(sheet, selectedRanges(), this));
|
||||
|
||||
if (dialog->exec() == QDialog::Accepted) {
|
||||
dialog->apply();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Range> SheetTableView::selectedRanges() const
|
||||
{
|
||||
QModelIndexList list = selectionModel()->selectedIndexes();
|
||||
std::vector<Range> result;
|
||||
|
||||
// Insert selected cells into set. This variable should ideally be a hash_set
|
||||
// but that is not part of standard stl.
|
||||
std::set<std::pair<int, int> > cells;
|
||||
for (QModelIndexList::const_iterator it = list.begin(); it != list.end(); ++it)
|
||||
cells.insert(std::make_pair<int,int>((*it).row(), (*it).column()));
|
||||
|
||||
// Create rectangular cells from the unordered collection of selected cells
|
||||
std::map<std::pair<int, int>, std::pair<int, int> > rectangles;
|
||||
createRectangles(cells, rectangles);
|
||||
|
||||
std::map<std::pair<int, int>, std::pair<int, int> >::const_iterator i = rectangles.begin();
|
||||
for (; i != rectangles.end(); ++i) {
|
||||
std::pair<int, int> ul = (*i).first;
|
||||
std::pair<int, int> size = (*i).second;
|
||||
|
||||
result.push_back(Range(ul.first, ul.second,
|
||||
ul.first + size.first - 1, ul.second + size.second - 1));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SheetTableView::insertRows()
|
||||
{
|
||||
assert(sheet != 0);
|
||||
|
||||
QModelIndexList rows = selectionModel()->selectedRows();
|
||||
std::vector<int> sortedRows;
|
||||
|
||||
/* Make sure rows are sorted in ascending order */
|
||||
for (QModelIndexList::const_iterator it = rows.begin(); it != rows.end(); ++it)
|
||||
sortedRows.push_back(it->row());
|
||||
std::sort(sortedRows.begin(), sortedRows.end());
|
||||
|
||||
/* Insert rows */
|
||||
Gui::Command::openCommand("Insert rows");
|
||||
std::vector<int>::const_reverse_iterator it = sortedRows.rbegin();
|
||||
while (it != sortedRows.rend()) {
|
||||
int prev = *it;
|
||||
int count = 1;
|
||||
|
||||
/* Collect neighbouring rows into one chunk */
|
||||
++it;
|
||||
while (it != sortedRows.rend()) {
|
||||
if (*it == prev - 1) {
|
||||
prev = *it;
|
||||
++count;
|
||||
++it;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.insertRows('%s', %d)", sheet->getNameInDocument(),
|
||||
rowName(prev).c_str(), count);
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
|
||||
void SheetTableView::removeRows()
|
||||
{
|
||||
assert(sheet != 0);
|
||||
|
||||
QModelIndexList rows = selectionModel()->selectedRows();
|
||||
std::vector<int> sortedRows;
|
||||
int extra = 0;
|
||||
|
||||
/* Make sure rows are sorted in descending order */
|
||||
for (QModelIndexList::const_iterator it = rows.begin(); it != rows.end(); ++it)
|
||||
sortedRows.push_back(it->row());
|
||||
std::sort(sortedRows.begin(), sortedRows.end(), std::greater<int>());
|
||||
|
||||
/* Remove rows */
|
||||
Gui::Command::openCommand("Remove rows");
|
||||
for (std::vector<int>::const_iterator it = sortedRows.begin(); it != sortedRows.end(); ++it) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.removeRows('%s', %d)", sheet->getNameInDocument(),
|
||||
rowName(*it).c_str(), 1);
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
|
||||
void SheetTableView::insertColumns()
|
||||
{
|
||||
assert(sheet != 0);
|
||||
|
||||
QModelIndexList cols = selectionModel()->selectedColumns();
|
||||
std::vector<int> sortedColumns;
|
||||
|
||||
/* Make sure rows are sorted in ascending order */
|
||||
for (QModelIndexList::const_iterator it = cols.begin(); it != cols.end(); ++it)
|
||||
sortedColumns.push_back(it->column());
|
||||
std::sort(sortedColumns.begin(), sortedColumns.end());
|
||||
|
||||
/* Insert columns */
|
||||
Gui::Command::openCommand("Insert columns");
|
||||
std::vector<int>::const_reverse_iterator it = sortedColumns.rbegin();
|
||||
while (it != sortedColumns.rend()) {
|
||||
int prev = *it;
|
||||
int count = 1;
|
||||
|
||||
/* Collect neighbouring columns into one chunk */
|
||||
++it;
|
||||
while (it != sortedColumns.rend()) {
|
||||
if (*it == prev - 1) {
|
||||
prev = *it;
|
||||
++count;
|
||||
++it;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.insertColumns('%s', %d)", sheet->getNameInDocument(),
|
||||
columnName(prev).c_str(), count);
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
|
||||
void SheetTableView::removeColumns()
|
||||
{
|
||||
assert(sheet != 0);
|
||||
|
||||
QModelIndexList cols = selectionModel()->selectedColumns();
|
||||
std::vector<int> sortedColumns;
|
||||
|
||||
/* Make sure rows are sorted in descending order */
|
||||
for (QModelIndexList::const_iterator it = cols.begin(); it != cols.end(); ++it)
|
||||
sortedColumns.push_back(it->column());
|
||||
std::sort(sortedColumns.begin(), sortedColumns.end(), std::greater<int>());
|
||||
|
||||
/* Remove columns */
|
||||
Gui::Command::openCommand("Remove rows");
|
||||
for (std::vector<int>::const_iterator it = sortedColumns.begin(); it != sortedColumns.end(); ++it)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.removeColumns('%s', %d)", sheet->getNameInDocument(),
|
||||
columnName(*it).c_str(), 1);
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
|
||||
SheetTableView::~SheetTableView()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SheetTableView::updateCellSpan(Spreadsheet::CellAddress address)
|
||||
{
|
||||
int rows, cols;
|
||||
|
||||
sheet->getSpans(address, rows, cols);
|
||||
|
||||
if (rows != rowSpan(address.row(), address.col()) || cols != columnSpan(address.row(), address.col()))
|
||||
setSpan(address.row(), address.col(), rows, cols);
|
||||
}
|
||||
|
||||
void SheetTableView::setSheet(Sheet * _sheet)
|
||||
{
|
||||
sheet = _sheet;
|
||||
cellSpanChangedConnection = sheet->cellSpanChanged.connect(bind(&SheetTableView::updateCellSpan, this, _1));
|
||||
|
||||
// Update row and column spans
|
||||
std::vector<std::string> usedCells = sheet->getUsedCells();
|
||||
|
||||
for (std::vector<std::string>::const_iterator i = usedCells.begin(); i != usedCells.end(); ++i) {
|
||||
CellAddress address(*i);
|
||||
|
||||
if (sheet->isMergedCell(address))
|
||||
updateCellSpan(address);
|
||||
}
|
||||
|
||||
// Update column widths and row height
|
||||
std::map<int, int> columWidths = sheet->getColumnWidths();
|
||||
for (std::map<int, int>::const_iterator i = columWidths.begin(); i != columWidths.end(); ++i) {
|
||||
int newSize = i->second;
|
||||
|
||||
if (newSize > 0 && horizontalHeader()->sectionSize(i->first) != newSize)
|
||||
setColumnWidth(i->first, newSize);
|
||||
}
|
||||
|
||||
std::map<int, int> rowHeights = sheet->getRowHeights();
|
||||
for (std::map<int, int>::const_iterator i = rowHeights.begin(); i != rowHeights.end(); ++i) {
|
||||
int newSize = i->second;
|
||||
|
||||
if (newSize > 0 && verticalHeader()->sectionSize(i->first) != newSize)
|
||||
setRowHeight(i->first, newSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SheetTableView::commitData ( QWidget * editor )
|
||||
{
|
||||
QTableView::commitData(editor);
|
||||
}
|
||||
|
||||
bool SheetTableView::edit ( const QModelIndex & index, EditTrigger trigger, QEvent * event )
|
||||
{
|
||||
if (trigger & (QAbstractItemView::DoubleClicked | QAbstractItemView::AnyKeyPressed | QAbstractItemView::EditKeyPressed) )
|
||||
currentEditIndex = index;
|
||||
return QTableView::edit(index, trigger, event);
|
||||
}
|
||||
|
||||
void SheetTableView::edit ( const QModelIndex & index )
|
||||
{
|
||||
currentEditIndex = index;
|
||||
QTableView::edit(index);
|
||||
}
|
||||
|
||||
#include "moc_SheetTableView.cpp"
|
||||
76
src/Mod/Spreadsheet/Gui/SheetTableView.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/***************************************************************************
|
||||
* 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 SHEETTABLEVIEW_H
|
||||
#define SHEETTABLEVIEW_H
|
||||
|
||||
#include <QTableView>
|
||||
#include <QHeaderView>
|
||||
#include <boost/signals/connection.hpp>
|
||||
#include "PreCompiled.h"
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
#include <Mod/Spreadsheet/App/Utils.h>
|
||||
|
||||
namespace SpreadsheetGui {
|
||||
|
||||
class SheetViewHeader : public QHeaderView {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SheetViewHeader(Qt::Orientation o) : QHeaderView(o) {
|
||||
setClickable(true);
|
||||
}
|
||||
Q_SIGNALS:
|
||||
void resizeFinished();
|
||||
protected:
|
||||
void mouseReleaseEvent(QMouseEvent * event);
|
||||
};
|
||||
|
||||
class SheetTableView : public QTableView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SheetTableView(QWidget *parent = 0);
|
||||
~SheetTableView();
|
||||
|
||||
void edit(const QModelIndex &index);
|
||||
void setSheet(Spreadsheet::Sheet *_sheet);
|
||||
std::vector<Spreadsheet::Range> selectedRanges() const;
|
||||
protected Q_SLOTS:
|
||||
void commitData(QWidget *editor);
|
||||
void updateCellSpan(Spreadsheet::CellAddress address);
|
||||
void insertRows();
|
||||
void removeRows();
|
||||
void insertColumns();
|
||||
void removeColumns();
|
||||
void cellProperties();
|
||||
protected:
|
||||
bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event);
|
||||
|
||||
QModelIndex currentEditIndex;
|
||||
Spreadsheet::Sheet * sheet;
|
||||
|
||||
boost::BOOST_SIGNALS_NAMESPACE::scoped_connection cellSpanChangedConnection;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SHEETTABLEVIEW_H
|
||||
79
src/Mod/Spreadsheet/Gui/SpreadsheetDelegate.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2015 Eivind Kvedalen (eivind@kvedalen.name) *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This file is based on the Qt spreadsheet example code. *
|
||||
* *
|
||||
* 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.1 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 "SpreadsheetDelegate.h"
|
||||
#include <QItemDelegate>
|
||||
#include <QLineEdit>
|
||||
|
||||
using namespace SpreadsheetGui;
|
||||
|
||||
SpreadsheetDelegate::SpreadsheetDelegate(QWidget *parent) :
|
||||
QItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QWidget *SpreadsheetDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QLineEdit *editor = new QLineEdit(parent);
|
||||
|
||||
connect(editor, SIGNAL(returnPressed()), this, SLOT(commitAndCloseEditor()));
|
||||
return editor;
|
||||
}
|
||||
|
||||
void SpreadsheetDelegate::commitAndCloseEditor()
|
||||
{
|
||||
QLineEdit *editor = qobject_cast<QLineEdit *>(sender());
|
||||
emit commitData(editor);
|
||||
emit closeEditor(editor);
|
||||
}
|
||||
|
||||
void SpreadsheetDelegate::setEditorData(QWidget *editor,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
|
||||
if (edit) {
|
||||
edit->setText(index.model()->data(index, Qt::EditRole).toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SpreadsheetDelegate::setModelData(QWidget *editor,
|
||||
QAbstractItemModel *model, const QModelIndex &index) const
|
||||
{
|
||||
QLineEdit *edit = qobject_cast<QLineEdit *>(editor);
|
||||
if (edit) {
|
||||
model->setData(index, edit->text());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QSize SpreadsheetDelegate::sizeHint( const QStyleOptionViewItem & option, const QModelIndex & index ) const
|
||||
{
|
||||
return QSize();
|
||||
}
|
||||
|
||||
#include "moc_SpreadsheetDelegate.cpp"
|
||||
|
||||
51
src/Mod/Spreadsheet/Gui/SpreadsheetDelegate.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2015 Eivind Kvedalen (eivind@kvedalen.name) *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This file is based on the Qt spreadsheet example code. *
|
||||
* *
|
||||
* 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.1 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 SPREADSHEETDELEGATE_H
|
||||
#define SPREADSHEETDELEGATE_H
|
||||
|
||||
#include <QItemDelegate>
|
||||
|
||||
namespace SpreadsheetGui {
|
||||
|
||||
class SpreadsheetDelegate : public QItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SpreadsheetDelegate(QWidget *parent = 0);
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
|
||||
const QModelIndex &index) const;
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const;
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const;
|
||||
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
private Q_SLOTS:
|
||||
void commitAndCloseEditor();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SPREADSHEETDELEGATE_H
|
||||
327
src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp
Normal file
@@ -0,0 +1,327 @@
|
||||
/***************************************************************************
|
||||
* 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"
|
||||
#ifndef _PreComp_
|
||||
# include <QAction>
|
||||
# include <QApplication>
|
||||
# include <QMenu>
|
||||
# include <QMouseEvent>
|
||||
# include <QSlider>
|
||||
# include <QStatusBar>
|
||||
# include <QToolBar>
|
||||
# include <QTableWidgetItem>
|
||||
# include <QMessageBox>
|
||||
# include <QPalette>
|
||||
# include <cmath>
|
||||
#endif
|
||||
|
||||
#include "SpreadsheetView.h"
|
||||
#include "SpreadsheetDelegate.h"
|
||||
#include <Mod/Spreadsheet/App/Expression.h>
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
#include <Mod/Spreadsheet/App/Range.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <boost/bind.hpp>
|
||||
#include <Mod/Spreadsheet/App/Utils.h>
|
||||
#include "qtcolorpicker.h"
|
||||
|
||||
#include "ui_Sheet.h"
|
||||
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
using namespace Gui;
|
||||
|
||||
/* TRANSLATOR SpreadsheetGui::SheetView */
|
||||
|
||||
TYPESYSTEM_SOURCE_ABSTRACT(SpreadsheetGui::SheetView, Gui::MDIView);
|
||||
|
||||
SheetView::SheetView(Gui::Document *pcDocument, App::DocumentObject *docObj, QWidget *parent)
|
||||
: MDIView(pcDocument, parent)
|
||||
, sheet(static_cast<Sheet*>(docObj))
|
||||
{
|
||||
// Set up ui
|
||||
|
||||
model = new SheetModel(static_cast<Sheet*>(docObj));
|
||||
|
||||
ui = new Ui::Sheet();
|
||||
QWidget * w = new QWidget(this);
|
||||
ui->setupUi(w);
|
||||
setCentralWidget(w);
|
||||
|
||||
delegate = new SpreadsheetDelegate();
|
||||
ui->cells->setModel(model);
|
||||
ui->cells->setItemDelegate(delegate);
|
||||
ui->cells->setSheet(sheet);
|
||||
|
||||
// Connect signals
|
||||
connect(ui->cells->selectionModel(), SIGNAL( currentChanged( QModelIndex, QModelIndex ) ),
|
||||
this, SLOT( currentChanged( QModelIndex, QModelIndex ) ) );
|
||||
|
||||
connect(ui->cells->horizontalHeader(), SIGNAL(resizeFinished()),
|
||||
this, SLOT(columnResizeFinished()));
|
||||
connect(ui->cells->horizontalHeader(), SIGNAL(sectionResized ( int, int, int ) ),
|
||||
this, SLOT(columnResized(int, int, int)));
|
||||
|
||||
connect(ui->cells->verticalHeader(), SIGNAL(resizeFinished()),
|
||||
this, SLOT(rowResizeFinished()));
|
||||
connect(ui->cells->verticalHeader(), SIGNAL(sectionResized ( int, int, int ) ),
|
||||
this, SLOT(rowResized(int, int, int)));
|
||||
|
||||
connect(ui->cellContent, SIGNAL(returnPressed()), this, SLOT( editingFinished() ));
|
||||
|
||||
columnWidthChangedConnection = sheet->columnWidthChanged.connect(bind(&SheetView::resizeColumn, this, _1, _2));
|
||||
rowHeightChangedConnection = sheet->rowHeightChanged.connect(bind(&SheetView::resizeRow, this, _1, _2));
|
||||
positionChangedConnection = sheet->positionChanged.connect(bind(&SheetView::setPosition, this, _1));
|
||||
|
||||
QPalette palette = ui->cells->palette();
|
||||
palette.setColor(QPalette::Base, QColor(255, 255, 255));
|
||||
palette.setColor(QPalette::Text, QColor(0, 0, 0));
|
||||
ui->cells->setPalette(palette);
|
||||
|
||||
QList<QtColorPicker*> bgList = Gui::getMainWindow()->findChildren<QtColorPicker*>(QString::fromAscii("Spreadsheet_BackgroundColor"));
|
||||
if (bgList.size() > 0)
|
||||
bgList[0]->setCurrentColor(palette.color(QPalette::Base));
|
||||
|
||||
QList<QtColorPicker*> fgList = Gui::getMainWindow()->findChildren<QtColorPicker*>(QString::fromAscii("Spreadsheet_ForegroundColor"));
|
||||
if (fgList.size() > 0)
|
||||
fgList[0]->setCurrentColor(palette.color(QPalette::Text));
|
||||
}
|
||||
|
||||
SheetView::~SheetView()
|
||||
{
|
||||
Application::Instance->detachView(this);
|
||||
//delete delegate;
|
||||
}
|
||||
|
||||
bool SheetView::onMsg(const char *pMsg, const char **ppReturn)
|
||||
{
|
||||
if(strcmp("Undo",pMsg) == 0 ) {
|
||||
getGuiDocument()->undo(1);
|
||||
App::Document* doc = getAppDocument();
|
||||
if (doc)
|
||||
doc->recomputeFeature(sheet);
|
||||
return true;
|
||||
}
|
||||
else if(strcmp("Redo",pMsg) == 0 ) {
|
||||
getGuiDocument()->redo(1);
|
||||
App::Document* doc = getAppDocument();
|
||||
if (doc)
|
||||
doc->recomputeFeature(sheet);
|
||||
return true;
|
||||
}
|
||||
else if (strcmp("Save",pMsg) == 0) {
|
||||
getGuiDocument()->save();
|
||||
return true;
|
||||
}
|
||||
else if (strcmp("SaveAs",pMsg) == 0) {
|
||||
getGuiDocument()->saveAs();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SheetView::onHasMsg(const char *pMsg) const
|
||||
{
|
||||
if (strcmp("Undo",pMsg) == 0) {
|
||||
App::Document* doc = getAppDocument();
|
||||
return doc && doc->getAvailableUndos() > 0;
|
||||
}
|
||||
else if (strcmp("Redo",pMsg) == 0) {
|
||||
App::Document* doc = getAppDocument();
|
||||
return doc && doc->getAvailableRedos() > 0;
|
||||
}
|
||||
else if (strcmp("Save",pMsg) == 0)
|
||||
return true;
|
||||
else if (strcmp("SaveAs",pMsg) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void SheetView::setCurrentCell(QString str)
|
||||
{
|
||||
updateContentLine();
|
||||
}
|
||||
|
||||
void SheetView::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Delete) {
|
||||
if (event->modifiers() == 0) {
|
||||
//model()->setData(currentIndex(), QVariant(), Qt::EditRole);
|
||||
}
|
||||
else if (event->modifiers() == Qt::ControlModifier) {
|
||||
//model()->setData(currentIndex(), QVariant(), Qt::EditRole);
|
||||
}
|
||||
}
|
||||
else
|
||||
Gui::MDIView::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void SheetView::updateContentLine()
|
||||
{
|
||||
QModelIndex i = ui->cells->currentIndex();
|
||||
|
||||
if (i.isValid()) {
|
||||
std::string str;
|
||||
Cell * cell = sheet->getCell(CellAddress(i.row(), i.column()));
|
||||
|
||||
if (cell)
|
||||
cell->getStringContent(str);
|
||||
ui->cellContent->setText(QString::fromUtf8(str.c_str()));
|
||||
ui->cellContent->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void SheetView::columnResizeFinished()
|
||||
{
|
||||
if (newColumnSizes.size() == 0)
|
||||
return;
|
||||
|
||||
blockSignals(true);
|
||||
Gui::Command::openCommand("Resize column");
|
||||
|
||||
QMap<int, int>::const_iterator i = newColumnSizes.begin();
|
||||
while (i != newColumnSizes.end()) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setColumnWidth('%s', %d)", sheet->getNameInDocument(),
|
||||
columnName(i.key()).c_str(), i.value());
|
||||
++i;
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
blockSignals(false);
|
||||
newColumnSizes.clear();
|
||||
}
|
||||
|
||||
void SheetView::rowResizeFinished()
|
||||
{
|
||||
if (newRowSizes.size() == 0)
|
||||
return;
|
||||
|
||||
blockSignals(true);
|
||||
Gui::Command::openCommand("Resize row");
|
||||
|
||||
QMap<int, int>::const_iterator i = newRowSizes.begin();
|
||||
while (i != newRowSizes.end()) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setRowHeight('%s', %d)", sheet->getNameInDocument(),
|
||||
rowName(i.key()).c_str(), i.value());
|
||||
++i;
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
blockSignals(false);
|
||||
newRowSizes.clear();
|
||||
}
|
||||
|
||||
void SheetView::columnResized(int col, int oldSize, int newSize)
|
||||
{
|
||||
newColumnSizes[col] = newSize;
|
||||
}
|
||||
|
||||
void SheetView::rowResized(int row, int oldSize, int newSize)
|
||||
{
|
||||
newRowSizes[row] = newSize;
|
||||
}
|
||||
|
||||
void SheetView::resizeColumn(int col, int newSize)
|
||||
{
|
||||
if (ui->cells->horizontalHeader()->sectionSize(col) != newSize)
|
||||
ui->cells->setColumnWidth(col, newSize);
|
||||
}
|
||||
|
||||
void SheetView::setPosition(CellAddress address)
|
||||
{
|
||||
QModelIndex curr = ui->cells->currentIndex();
|
||||
QModelIndex i = ui->cells->model()->index(address.row(), address.col());
|
||||
|
||||
if (i.isValid() && (curr.row() != address.row() || curr.column() != address.col())) {
|
||||
ui->cells->clearSelection();
|
||||
ui->cells->setCurrentIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
void SheetView::resizeRow(int col, int newSize)
|
||||
{
|
||||
if (ui->cells->verticalHeader()->sectionSize(col) != newSize)
|
||||
ui->cells->setRowHeight(col, newSize);
|
||||
}
|
||||
|
||||
void SheetView::editingFinished()
|
||||
{
|
||||
QModelIndex i = ui->cells->currentIndex();
|
||||
|
||||
// Update data in cell
|
||||
ui->cells->model()->setData(i, QVariant(ui->cellContent->text()), Qt::EditRole);
|
||||
}
|
||||
|
||||
void SheetView::currentChanged ( const QModelIndex & current, const QModelIndex & previous )
|
||||
{
|
||||
updateContentLine();
|
||||
sheet->setPosition(CellAddress(current.row(), current.column()));
|
||||
}
|
||||
|
||||
void SheetView::updateCell(const App::Property *prop)
|
||||
{
|
||||
try {
|
||||
CellAddress address;
|
||||
|
||||
sheet->getCellAddress(prop, address);
|
||||
updateContentLine();
|
||||
}
|
||||
catch (...) {
|
||||
// Property is not a cell
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Range> SheetView::selectedRanges() const
|
||||
{
|
||||
return ui->cells->selectedRanges();
|
||||
}
|
||||
|
||||
QModelIndexList SheetView::selectedIndexes() const
|
||||
{
|
||||
return ui->cells->selectionModel()->selectedIndexes();
|
||||
}
|
||||
|
||||
QModelIndex SheetView::currentIndex() const
|
||||
{
|
||||
return ui->cells->currentIndex();
|
||||
}
|
||||
|
||||
PyObject *SheetView::getPyObject()
|
||||
{
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
void SheetView::deleteSelf()
|
||||
{
|
||||
Gui::MDIView::deleteSelf();
|
||||
}
|
||||
|
||||
#include "moc_SpreadsheetView.cpp"
|
||||
111
src/Mod/Spreadsheet/Gui/SpreadsheetView.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/***************************************************************************
|
||||
* 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 SpreadsheetView_H
|
||||
#define SpreadsheetView_H
|
||||
|
||||
#include <Gui/MDIView.h>
|
||||
#include <QHeaderView>
|
||||
#include "SheetModel.h"
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
|
||||
class QSlider;
|
||||
class QAction;
|
||||
class QActionGroup;
|
||||
class QPopupMenu;
|
||||
class QToolBar;
|
||||
|
||||
namespace App {
|
||||
class DocumentObject;
|
||||
class Property;
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
class Sheet;
|
||||
}
|
||||
|
||||
class QTableWidgetItem;
|
||||
|
||||
namespace SpreadsheetGui
|
||||
{
|
||||
|
||||
class SpreadsheetDelegate;
|
||||
|
||||
class SpreadsheetGuiExport SheetView : public Gui::MDIView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
SheetView(Gui::Document* pcDocument, App::DocumentObject* docObj, QWidget* parent);
|
||||
~SheetView();
|
||||
|
||||
const char *getName(void) const {return "SheetView";}
|
||||
|
||||
bool onMsg(const char* pMsg,const char** ppReturn);
|
||||
bool onHasMsg(const char* pMsg) const;
|
||||
|
||||
void updateCell(const App::Property * prop);
|
||||
|
||||
Spreadsheet::Sheet * getSheet() { return sheet; }
|
||||
|
||||
std::vector<Spreadsheet::Range> selectedRanges() const;
|
||||
|
||||
QModelIndexList selectedIndexes() const;
|
||||
|
||||
QModelIndex currentIndex() const;
|
||||
|
||||
PyObject *getPyObject(void);
|
||||
|
||||
virtual void deleteSelf();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void editingFinished();
|
||||
void currentChanged( const QModelIndex & current, const QModelIndex & previous );
|
||||
void columnResized(int col, int oldSize, int newSize);
|
||||
void rowResized(int row, int oldSize, int newSize);
|
||||
void columnResizeFinished();
|
||||
void rowResizeFinished();
|
||||
protected:
|
||||
void setPosition(Spreadsheet::CellAddress address);
|
||||
void updateContentLine();
|
||||
void setCurrentCell(QString str);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void resizeColumn(int col, int newSize);
|
||||
void resizeRow(int col, int newSize);
|
||||
|
||||
Ui::Sheet * ui;
|
||||
Spreadsheet::Sheet * sheet;
|
||||
SpreadsheetDelegate * delegate;
|
||||
SheetModel * model;
|
||||
boost::BOOST_SIGNALS_NAMESPACE::scoped_connection columnWidthChangedConnection;
|
||||
boost::BOOST_SIGNALS_NAMESPACE::scoped_connection rowHeightChangedConnection;
|
||||
boost::BOOST_SIGNALS_NAMESPACE::scoped_connection positionChangedConnection;
|
||||
|
||||
QMap<int, int> newColumnSizes;
|
||||
QMap<int, int> newRowSizes;
|
||||
};
|
||||
|
||||
} // namespace SpreadsheetModGui
|
||||
|
||||
#endif // SpreadsheetView_H
|
||||
193
src/Mod/Spreadsheet/Gui/ViewProviderSpreadsheet.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2011 Jrgen Riegel (juergen.riegel@web.de) *
|
||||
* Copyright (c) 2015 Eivind Kvedalen (eivind@kvedalen.name) *
|
||||
* *
|
||||
* 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"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <QFile>
|
||||
# include <QFileInfo>
|
||||
# include <QImage>
|
||||
# include <QString>
|
||||
# include <QMenu>
|
||||
#endif
|
||||
|
||||
#include "ViewProviderSpreadsheet.h"
|
||||
#include "SpreadsheetView.h"
|
||||
|
||||
#include <Mod/Spreadsheet/App/Sheet.h>
|
||||
#include <App/Document.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Base/FileInfo.h>
|
||||
#include <Base/Stream.h>
|
||||
#include <Base/Console.h>
|
||||
#include <sstream>
|
||||
|
||||
using namespace Gui;
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
|
||||
PROPERTY_SOURCE(SpreadsheetGui::ViewProviderSheet, Gui::ViewProviderDocumentObject)
|
||||
|
||||
ViewProviderSheet::ViewProviderSheet()
|
||||
: Gui::ViewProviderDocumentObject()
|
||||
{
|
||||
}
|
||||
|
||||
ViewProviderSheet::~ViewProviderSheet()
|
||||
{
|
||||
if (!view.isNull()) {
|
||||
Gui::getMainWindow()->removeWindow(view);
|
||||
// delete view;
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderSheet::setDisplayMode(const char* ModeName)
|
||||
{
|
||||
ViewProviderDocumentObject::setDisplayMode(ModeName);
|
||||
}
|
||||
|
||||
std::vector<std::string> ViewProviderSheet::getDisplayModes(void) const
|
||||
{
|
||||
std::vector<std::string> StrList;
|
||||
StrList.push_back("Spreadsheet");
|
||||
return StrList;
|
||||
}
|
||||
|
||||
QIcon ViewProviderSheet::getIcon() const
|
||||
{
|
||||
static const char * const Points_Feature_xpm[] = {
|
||||
"16 16 3 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #FFFFFF",
|
||||
" ",
|
||||
" ",
|
||||
"................",
|
||||
".++++.++++.++++.",
|
||||
".++++.++++.++++.",
|
||||
"................",
|
||||
".++++.++++.++++.",
|
||||
".++++.++++.++++.",
|
||||
"................",
|
||||
".++++.++++.++++.",
|
||||
".++++.++++.++++.",
|
||||
"................",
|
||||
".++++.++++.++++.",
|
||||
".++++.++++.++++.",
|
||||
"................",
|
||||
" "};
|
||||
QPixmap px(Points_Feature_xpm);
|
||||
return px;
|
||||
}
|
||||
|
||||
bool ViewProviderSheet::setEdit(int ModNum)
|
||||
{
|
||||
if (ModNum == ViewProvider::Default) {
|
||||
if (!this->view) {
|
||||
showSpreadsheetView();
|
||||
view->viewAll();
|
||||
}
|
||||
Gui::getMainWindow()->setActiveWindow(this->view);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ViewProviderSheet::doubleClicked()
|
||||
{
|
||||
if (!this->view) {
|
||||
showSpreadsheetView();
|
||||
view->viewAll();
|
||||
}
|
||||
Gui::getMainWindow()->setActiveWindow(this->view);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewProviderSheet::setupContextMenu(QMenu * menu, QObject *receiver, const char *member)
|
||||
{
|
||||
QAction* act;
|
||||
act = menu->addAction(QObject::tr("Show spreadsheet"), receiver, member);
|
||||
act->setData(QVariant((int)ViewProvider::Default));
|
||||
}
|
||||
|
||||
Sheet *ViewProviderSheet::getSpreadsheetObject() const
|
||||
{
|
||||
return freecad_dynamic_cast<Sheet>(pcObject);
|
||||
}
|
||||
|
||||
bool ViewProviderSheet::onDelete(const std::vector<std::string> &)
|
||||
{
|
||||
// If view is closed, delete the object
|
||||
if (view.isNull())
|
||||
return true;
|
||||
|
||||
// View is not closed, delete cell contents instead if it is active
|
||||
if (Gui::Application::Instance->activeDocument()) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
QModelIndexList selection = sheetView->selectedIndexes();
|
||||
|
||||
if (selection.size() > 0) {
|
||||
Gui::Command::openCommand("Clear cell(s)");
|
||||
for (QModelIndexList::const_iterator it = selection.begin(); it != selection.end(); ++it) {
|
||||
std::string address = Spreadsheet::addressToString(CellAddress((*it).row(), (*it).column()));
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.clear('%s')", sheet->getNameInDocument(),
|
||||
address.c_str());
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SheetView *ViewProviderSheet::showSpreadsheetView()
|
||||
{
|
||||
if (!view){
|
||||
Gui::Document* doc = Gui::Application::Instance->getDocument
|
||||
(this->pcObject->getDocument());
|
||||
view = new SheetView(doc, this->pcObject, Gui::getMainWindow());
|
||||
view->setWindowIcon(Gui::BitmapFactory().pixmap(":icons/Spreadsheet.svg"));
|
||||
view->setWindowTitle(QString::fromUtf8(pcObject->Label.getValue()) + QString::fromAscii("[*]"));
|
||||
Gui::getMainWindow()->addWindow(view);
|
||||
startEditing();
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
void ViewProviderSheet::updateData(const App::Property* prop)
|
||||
{
|
||||
if (view)
|
||||
view->updateCell(prop);
|
||||
}
|
||||
78
src/Mod/Spreadsheet/Gui/ViewProviderSpreadsheet.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2011 Jrgen Riegel (juergen.riegel@web.de) *
|
||||
* Copyright (c) 2015 Eivind Kvedalen (eivind@kvedalen.name) *
|
||||
* *
|
||||
* 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_ViewProviderImagePlane_H
|
||||
#define SPREADSHEET_ViewProviderImagePlane_H
|
||||
|
||||
#include <Gui/ViewProviderDocumentObject.h>
|
||||
#include <QPointer>
|
||||
|
||||
namespace Spreadsheet {
|
||||
class Sheet;
|
||||
}
|
||||
|
||||
namespace SpreadsheetGui
|
||||
{
|
||||
|
||||
class SheetView;
|
||||
|
||||
class SpreadsheetGuiExport ViewProviderSheet : public Gui::ViewProviderDocumentObject
|
||||
{
|
||||
PROPERTY_HEADER(SpreadsheetGui::ViewProviderSheet);
|
||||
|
||||
public:
|
||||
/// constructor.
|
||||
ViewProviderSheet();
|
||||
|
||||
/// destructor.
|
||||
~ViewProviderSheet();
|
||||
|
||||
void setDisplayMode(const char* ModeName);
|
||||
virtual bool useNewSelectionModel(void) const {return false;}
|
||||
std::vector<std::string> getDisplayModes() const;
|
||||
|
||||
virtual bool doubleClicked(void);
|
||||
void setupContextMenu(QMenu* menu, QObject* receiver, const char* member);
|
||||
|
||||
Spreadsheet::Sheet* getSpreadsheetObject() const;
|
||||
|
||||
virtual bool onDelete(const std::vector<std::string> &);
|
||||
|
||||
QIcon getIcon() const;
|
||||
|
||||
virtual bool setEdit(int ModNum);
|
||||
|
||||
virtual bool isShow(void) const { return true; }
|
||||
|
||||
protected:
|
||||
SheetView* showSpreadsheetView();
|
||||
void updateData(const App::Property *prop);
|
||||
private:
|
||||
QPointer<SheetView> view;
|
||||
};
|
||||
|
||||
} //namespace Spreadsheet
|
||||
|
||||
|
||||
#endif // SPREADSHEET_ViewProviderSpreadsheet_H
|
||||
240
src/Mod/Spreadsheet/Gui/Workbench.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2005 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* Copyright (c) 2015 Eivind Kvedalen (eivind@kvedalen.name) *
|
||||
* *
|
||||
* 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"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <qobject.h>
|
||||
#endif
|
||||
|
||||
#include "Workbench.h"
|
||||
#include <Gui/ToolBarManager.h>
|
||||
#include <Gui/MenuManager.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <QToolBar>
|
||||
#include "qtcolorpicker.h"
|
||||
#include "Mod/Spreadsheet/App/Sheet.h"
|
||||
#include "Mod/Spreadsheet/App/Range.h"
|
||||
#include "Mod/Spreadsheet/Gui/SpreadsheetView.h"
|
||||
|
||||
using namespace SpreadsheetGui;
|
||||
using namespace Spreadsheet;
|
||||
|
||||
#if 0 // needed for Qt's lupdate utility
|
||||
qApp->translate("Workbench", "Spreadsheet");
|
||||
#endif
|
||||
|
||||
/// @namespace ImageGui @class Workbench
|
||||
TYPESYSTEM_SOURCE(SpreadsheetGui::Workbench, Gui::StdWorkbench)
|
||||
|
||||
Workbench::Workbench()
|
||||
: Gui::StdWorkbench()
|
||||
, initialized(false)
|
||||
, workbenchHelper(new WorkbenchHelper)
|
||||
{
|
||||
}
|
||||
|
||||
Workbench::~Workbench()
|
||||
{
|
||||
}
|
||||
|
||||
void Workbench::activated()
|
||||
{
|
||||
if (!initialized) {
|
||||
QList<QToolBar*> bars = Gui::getMainWindow()->findChildren<QToolBar*>(QString::fromAscii("Spreadsheet"));
|
||||
|
||||
if (bars.size() == 1) {
|
||||
QToolBar * bar = bars[0];
|
||||
QtColorPicker * foregroundColor;
|
||||
QtColorPicker * backgroundColor;
|
||||
QPalette palette = Gui::getMainWindow()->palette();
|
||||
|
||||
QList<QtColorPicker*> fgList = Gui::getMainWindow()->findChildren<QtColorPicker*>(QString::fromAscii("Spreadsheet_ForegroundColor"));
|
||||
if (fgList.size() > 0)
|
||||
foregroundColor = fgList[0];
|
||||
else {
|
||||
foregroundColor = new QtColorPicker();
|
||||
foregroundColor->setObjectName(QString::fromAscii("Spreadsheet_ForegroundColor"));
|
||||
foregroundColor->setStandardColors();
|
||||
foregroundColor->setCurrentColor(palette.color(QPalette::Foreground));
|
||||
QObject::connect(foregroundColor, SIGNAL(colorSet(QColor)), workbenchHelper.get(), SLOT(setForegroundColor(QColor)));
|
||||
}
|
||||
bar->addWidget(foregroundColor);
|
||||
|
||||
QList<QtColorPicker*> bgList = Gui::getMainWindow()->findChildren<QtColorPicker*>(QString::fromAscii("Spreadsheet_BackgroundColor"));
|
||||
if (bgList.size() > 0)
|
||||
backgroundColor = bgList[0];
|
||||
else {
|
||||
backgroundColor = new QtColorPicker();
|
||||
backgroundColor->setObjectName(QString::fromAscii("Spreadsheet_BackgroundColor"));
|
||||
backgroundColor->setStandardColors();
|
||||
backgroundColor->setCurrentColor(palette.color(QPalette::Base));
|
||||
QObject::connect(backgroundColor, SIGNAL(colorSet(QColor)), workbenchHelper.get(), SLOT(setBackgroundColor(QColor)));
|
||||
}
|
||||
bar->addWidget(backgroundColor);
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorkbenchHelper::setForegroundColor(const QColor & color)
|
||||
{
|
||||
Gui::Document * doc = Gui::Application::Instance->activeDocument();
|
||||
|
||||
if (doc) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
|
||||
// Execute mergeCells commands
|
||||
if (ranges.size() > 0) {
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Set foreground color");
|
||||
for (; i != ranges.end(); ++i)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setForeground('%s', (%f,%f,%f))", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str(), color.redF(), color.greenF(), color.blueF());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorkbenchHelper::setBackgroundColor(const QColor & color)
|
||||
{
|
||||
Gui::Document * doc = Gui::Application::Instance->activeDocument();
|
||||
|
||||
if (doc) {
|
||||
Gui::MDIView* activeWindow = Gui::getMainWindow()->activeWindow();
|
||||
SpreadsheetGui::SheetView * sheetView = freecad_dynamic_cast<SpreadsheetGui::SheetView>(activeWindow);
|
||||
|
||||
if (sheetView) {
|
||||
Sheet * sheet = sheetView->getSheet();
|
||||
std::vector<Range> ranges = sheetView->selectedRanges();
|
||||
|
||||
// Execute mergeCells commands
|
||||
if (ranges.size() > 0) {
|
||||
std::vector<Range>::const_iterator i = ranges.begin();
|
||||
|
||||
Gui::Command::openCommand("Set background color");
|
||||
for (; i != ranges.end(); ++i)
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setBackground('%s', (%f,%f,%f))", sheet->getNameInDocument(),
|
||||
i->rangeString().c_str(), color.redF(), color.greenF(), color.blueF());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gui::MenuItem *Workbench::setupMenuBar() const
|
||||
{
|
||||
Gui::MenuItem* root = StdWorkbench::setupMenuBar();
|
||||
Gui::MenuItem* item = root->findItem("&Windows");
|
||||
|
||||
Gui::MenuItem* spreadsheet = new Gui::MenuItem;
|
||||
root->insertItem(item, spreadsheet);
|
||||
|
||||
// utilities
|
||||
Gui::MenuItem* alignments = new Gui::MenuItem;
|
||||
alignments->setCommand("&Alignment");
|
||||
*alignments
|
||||
<< "Spreadsheet_AlignLeft"
|
||||
<< "Spreadsheet_AlignCenter"
|
||||
<< "Spreadsheet_AlignRight"
|
||||
<< "Spreadsheet_AlignTop"
|
||||
<< "Spreadsheet_AlignVCenter"
|
||||
<< "Spreadsheet_AlignBottom"
|
||||
;
|
||||
|
||||
Gui::MenuItem* styles = new Gui::MenuItem;
|
||||
styles->setCommand("&Styles");
|
||||
*styles
|
||||
<< "Spreadsheet_StyleBold"
|
||||
<< "Spreadsheet_StyleItalic"
|
||||
<< "Spreadsheet_StyleUnderline"
|
||||
;
|
||||
|
||||
spreadsheet->setCommand("&Spreadsheet");
|
||||
*spreadsheet << "Spreadsheet_CreateSheet"
|
||||
<< "Separator"
|
||||
<< "Spreadsheet_Import"
|
||||
<< "Spreadsheet_Export"
|
||||
<< "Separator"
|
||||
<< "Spreadsheet_MergeCells"
|
||||
<< "Spreadsheet_SplitCell"
|
||||
<< "Separator"
|
||||
<< alignments
|
||||
<< styles
|
||||
;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
{
|
||||
Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
|
||||
Gui::ToolBarItem* part = new Gui::ToolBarItem(root);
|
||||
part->setCommand("Spreadsheet");
|
||||
*part << "Spreadsheet_CreateSheet"
|
||||
<< "Separator"
|
||||
<< "Spreadsheet_Import"
|
||||
<< "Spreadsheet_Export"
|
||||
<< "Separator"
|
||||
<< "Spreadsheet_MergeCells"
|
||||
<< "Spreadsheet_SplitCell"
|
||||
<< "Separator"
|
||||
<< "Spreadsheet_AlignLeft"
|
||||
<< "Spreadsheet_AlignCenter"
|
||||
<< "Spreadsheet_AlignRight"
|
||||
<< "Spreadsheet_AlignTop"
|
||||
<< "Spreadsheet_AlignVCenter"
|
||||
<< "Spreadsheet_AlignBottom"
|
||||
<< "Separator"
|
||||
<< "Spreadsheet_StyleBold"
|
||||
<< "Spreadsheet_StyleItalic"
|
||||
<< "Spreadsheet_StyleUnderline"
|
||||
<< "Separator"
|
||||
;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
Gui::ToolBarItem* Workbench::setupCommandBars() const
|
||||
{
|
||||
Gui::ToolBarItem* root = new Gui::ToolBarItem;
|
||||
Gui::ToolBarItem* ss = new Gui::ToolBarItem(root);
|
||||
ss->setCommand("Spreadsheet");
|
||||
*ss << "Spreadsheet_Open";
|
||||
return root;
|
||||
}
|
||||
|
||||
#include "moc_Workbench.cpp"
|
||||
68
src/Mod/Spreadsheet/Gui/Workbench.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2005 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* Copyright (c) 2015 Eivind Kvedalen (eivind@kvedalen.name) *
|
||||
* *
|
||||
* 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_WORKBENCH_H
|
||||
#define SPREADSHEET_WORKBENCH_H
|
||||
|
||||
#include <Gui/Workbench.h>
|
||||
|
||||
class QtColorPicker;
|
||||
|
||||
namespace SpreadsheetGui {
|
||||
|
||||
/**
|
||||
* @author Eivind Kvedalen
|
||||
*/
|
||||
|
||||
class SpreadsheetGuiExport WorkbenchHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
protected Q_SLOTS:
|
||||
void setForegroundColor(const QColor &color);
|
||||
void setBackgroundColor(const QColor &color);
|
||||
};
|
||||
|
||||
class SpreadsheetGuiExport Workbench : public Gui::StdWorkbench
|
||||
{
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
Workbench();
|
||||
virtual ~Workbench();
|
||||
void activated();
|
||||
|
||||
private:
|
||||
bool initialized;
|
||||
std::auto_ptr<WorkbenchHelper> workbenchHelper;
|
||||
|
||||
protected:
|
||||
Gui::MenuItem *setupMenuBar() const;
|
||||
Gui::ToolBarItem* setupToolBars() const;
|
||||
Gui::ToolBarItem* setupCommandBars() const;
|
||||
};
|
||||
|
||||
} // namespace SpreadsheetModGui
|
||||
|
||||
|
||||
#endif // SPREADSHEET_WORKBENCH_H
|
||||
1156
src/Mod/Spreadsheet/Gui/qtcolorpicker.cpp
Normal file
122
src/Mod/Spreadsheet/Gui/qtcolorpicker.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of a Qt Solutions component.
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Solutions Commercial License Agreement provided
|
||||
** with the Software or, alternatively, in accordance with the terms
|
||||
** contained in a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain
|
||||
** additional rights. These rights are described in the Nokia Qt LGPL
|
||||
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
|
||||
** package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Please note Third Party Software included with Qt Solutions may impose
|
||||
** additional restrictions and it is the user's responsibility to ensure
|
||||
** that they have met the licensing requirements of the GPL, LGPL, or Qt
|
||||
** Solutions Commercial license and the relevant license of the Third
|
||||
** Party Software they are using.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at qt-sales@nokia.com.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTCOLORPICKER_H
|
||||
#define QTCOLORPICKER_H
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtCore/QString>
|
||||
#include <QtGui/QColor>
|
||||
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtGui/QFocusEvent>
|
||||
|
||||
#if defined(Q_WS_WIN)
|
||||
# if !defined(QT_QTCOLORPICKER_EXPORT) && !defined(QT_QTCOLORPICKER_IMPORT)
|
||||
# define QT_QTCOLORPICKER_EXPORT
|
||||
# elif defined(QT_QTCOLORPICKER_IMPORT)
|
||||
# if defined(QT_QTCOLORPICKER_EXPORT)
|
||||
# undef QT_QTCOLORPICKER_EXPORT
|
||||
# endif
|
||||
# define QT_QTCOLORPICKER_EXPORT __declspec(dllimport)
|
||||
# elif defined(QT_QTCOLORPICKER_EXPORT)
|
||||
# undef QT_QTCOLORPICKER_EXPORT
|
||||
# define QT_QTCOLORPICKER_EXPORT __declspec(dllexport)
|
||||
# endif
|
||||
#else
|
||||
# define QT_QTCOLORPICKER_EXPORT
|
||||
#endif
|
||||
|
||||
class ColorPickerPopup;
|
||||
|
||||
class QT_QTCOLORPICKER_EXPORT QtColorPicker : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(bool colorDialog READ colorDialogEnabled WRITE setColorDialogEnabled)
|
||||
|
||||
public:
|
||||
QtColorPicker(QWidget *parent = 0,
|
||||
int columns = -1, bool enableColorDialog = true);
|
||||
|
||||
~QtColorPicker();
|
||||
|
||||
void insertColor(const QColor &color, const QString &text = QString::null, int index = -1);
|
||||
|
||||
QColor currentColor() const;
|
||||
|
||||
QColor color(int index) const;
|
||||
|
||||
void setColorDialogEnabled(bool enabled);
|
||||
bool colorDialogEnabled() const;
|
||||
|
||||
void setStandardColors();
|
||||
|
||||
static QColor getColor(const QPoint &pos, bool allowCustomColors = true);
|
||||
|
||||
public Q_SLOTS:
|
||||
void setCurrentColor(const QColor &col);
|
||||
|
||||
Q_SIGNALS:
|
||||
void colorChanged(const QColor &);
|
||||
void colorSet(const QColor &);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
private Q_SLOTS:
|
||||
void buttonPressed(bool toggled);
|
||||
void popupClosed();
|
||||
|
||||
private:
|
||||
ColorPickerPopup *popup;
|
||||
QColor col;
|
||||
bool withColorDialog;
|
||||
bool dirty;
|
||||
bool firstInserted;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,26 +1,41 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2013 - Yorik van Havre <yorik@uncreated.net> *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
#* as published by the Free Software Foundation; either version 2 of *
|
||||
#* the License, or (at your option) any later version. *
|
||||
#* for detail see the LICENCE text file. *
|
||||
#* *
|
||||
#* 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 Library General Public License for more details. *
|
||||
#* *
|
||||
#* You should have received a copy of the GNU Library General Public *
|
||||
#* License along with this program; if not, write to the Free Software *
|
||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
# Supported file types
|
||||
FreeCAD.addImportType("Spreadsheet (*.csv)","Spreadsheet")
|
||||
FreeCAD.addExportType("Spreadsheet (*.csv)","Spreadsheet")
|
||||
|
||||
# FreeCAD init script of the Spreadsheet module
|
||||
# (c) 2001 Juergen Riegel
|
||||
|
||||
#***************************************************************************
|
||||
#* (c) Juergen Riegel (juergen.riegel@web.de) 2002 *
|
||||
#* Copyright (c) 2013 - Yorik van Havre <yorik@uncreated.net> *
|
||||
#* Copyright (c) 2013 Eivind Kvedalen (eivind@kvedalen.name) *
|
||||
#* *
|
||||
#* This file is part of the FreeCAD CAx development system. *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
#* as published by the Free Software Foundation; either version 2 of *
|
||||
#* the License, or (at your option) any later version. *
|
||||
#* for detail see the LICENCE text file. *
|
||||
#* *
|
||||
#* FreeCAD 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 Lesser General Public License for more details. *
|
||||
#* *
|
||||
#* You should have received a copy of the GNU Library General Public *
|
||||
#* License along with FreeCAD; if not, write to the Free Software *
|
||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
#* USA *
|
||||
#* *
|
||||
#* Juergen Riegel 2002 *
|
||||
#***************************************************************************/
|
||||
|
||||
|
||||
|
||||
# Get the Parameter Group of this module
|
||||
ParGrp = App.ParamGet("System parameter:Modules").GetGroup("Spreadsheet")
|
||||
|
||||
# Set the needed information
|
||||
ParGrp.SetString("HelpIndex", "Spreadsheet/Help/index.html")
|
||||
ParGrp.SetString("WorkBenchName", "Spreadsheet")
|
||||
ParGrp.SetString("WorkBenchModule", "SpreadsheetWorkbench.py")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,76 +1,74 @@
|
||||
# Spreadsheet gui init module
|
||||
# (c) 2003 Juergen Riegel
|
||||
#
|
||||
# Gathering all the information to start FreeCAD
|
||||
# This is the second one of three init scripts, the third one
|
||||
# runs when the gui is up
|
||||
|
||||
#***************************************************************************
|
||||
#* (c) Juergen Riegel (juergen.riegel@web.de) 2002 *
|
||||
#* Copyright (c) 2013 Eivind Kvedalen (eivind@kvedalen.name) *
|
||||
#* *
|
||||
#* Copyright (c) 2013 - Yorik van Havre <yorik@uncreated.net> *
|
||||
#* This file is part of the FreeCAD CAx development system. *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
#* it under the terms of the GNU General Public License (GPL) *
|
||||
#* as published by the Free Software Foundation; either version 2 of *
|
||||
#* the License, or (at your option) any later version. *
|
||||
#* for detail see the LICENCE text file. *
|
||||
#* *
|
||||
#* This program is distributed in the hope that it will be useful, *
|
||||
#* FreeCAD 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 program; if not, write to the Free Software *
|
||||
#* License along with FreeCAD; if not, write to the Free Software *
|
||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
class SpreadsheetWorkbench(Workbench):
|
||||
"Spreadsheet workbench object"
|
||||
Icon = """
|
||||
/* XPM */
|
||||
static char * Spreadsheet_xpm[] = {
|
||||
"16 16 5 1",
|
||||
" c None",
|
||||
". c #151614",
|
||||
"+ c #575956",
|
||||
"@ c #969895",
|
||||
"# c #F7F9F6",
|
||||
" ",
|
||||
" ",
|
||||
" ...............",
|
||||
".@##@+########@.",
|
||||
".+@@+.@@@@@@@@+.",
|
||||
"..+++.+++++++++.",
|
||||
".@##@+########@.",
|
||||
".+@@+.@@@@@@@@+.",
|
||||
"..+++.+++++++++.",
|
||||
".@##@+########@.",
|
||||
".+@@+.@@@@@@@@+.",
|
||||
"..+++.+++++++++.",
|
||||
".@##@+########@.",
|
||||
"..+++.+++++++++.",
|
||||
" ",
|
||||
" "};"""
|
||||
|
||||
MenuText = "Spreadsheet"
|
||||
ToolTip = "Spreadsheet workbench"
|
||||
|
||||
def Initialize(self):
|
||||
def QT_TRANSLATE_NOOP(scope, text): return text
|
||||
import Spreadsheet,Spreadsheet_rc
|
||||
from DraftTools import translate
|
||||
commands = ["Spreadsheet_Create","Spreadsheet_Controller","Spreadsheet_PropertyController"]
|
||||
self.appendToolbar(QT_TRANSLATE_NOOP("Workbench","Spreadsheet tools"),commands)
|
||||
self.appendMenu(str(translate("Spreadsheet","&Spreadsheet")),commands)
|
||||
FreeCADGui.addIconPath(":/icons")
|
||||
FreeCADGui.addLanguagePath(":/translations")
|
||||
Log ('Loading Spreadsheet module... done\n')
|
||||
|
||||
def Activated(self):
|
||||
Msg("Spreadsheet workbench activated\n")
|
||||
|
||||
def Deactivated(self):
|
||||
Msg("Spreadsheet workbench deactivated\n")
|
||||
|
||||
def GetClassName(self):
|
||||
return "Gui::PythonWorkbench"
|
||||
|
||||
FreeCADGui.addWorkbench(SpreadsheetWorkbench)
|
||||
#* Juergen Riegel 2002 *
|
||||
#***************************************************************************/
|
||||
|
||||
|
||||
class SpreadsheetWorkbench ( Workbench ):
|
||||
"Spreadsheet workbench object"
|
||||
Icon = """
|
||||
/* XPM */
|
||||
static char * Spreadsheet_xpm[] = {
|
||||
"16 16 5 1",
|
||||
" c None",
|
||||
". c #151614",
|
||||
"+ c #575956",
|
||||
"@ c #969895",
|
||||
"# c #F7F9F6",
|
||||
" ",
|
||||
" ",
|
||||
" ...............",
|
||||
".@##@+########@.",
|
||||
".+@@+.@@@@@@@@+.",
|
||||
"..+++.+++++++++.",
|
||||
".@##@+########@.",
|
||||
".+@@+.@@@@@@@@+.",
|
||||
"..+++.+++++++++.",
|
||||
".@##@+########@.",
|
||||
".+@@+.@@@@@@@@+.",
|
||||
"..+++.+++++++++.",
|
||||
".@##@+########@.",
|
||||
"..+++.+++++++++.",
|
||||
" ",
|
||||
" "};"""
|
||||
MenuText = "Spreadsheet"
|
||||
ToolTip = "Spreadsheet workbench"
|
||||
|
||||
def Initialize(self):
|
||||
# load the module
|
||||
import SpreadsheetGui
|
||||
|
||||
def GetClassName(self):
|
||||
return "SpreadsheetGui::Workbench"
|
||||
|
||||
Gui.addWorkbench(SpreadsheetWorkbench())
|
||||
|
||||
# Append the open handler
|
||||
FreeCAD.EndingAdd("Spreadsheet formats (*.csv)","SpreadsheetGui")
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>icons/Spreadsheet.svg</file>
|
||||
<file>icons/SpreadsheetController.svg</file>
|
||||
<file>icons/SpreadsheetPropertyController.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
3
src/Mod/Spreadsheet/spreadsheet.dox
Normal file
@@ -0,0 +1,3 @@
|
||||
/** \defgroup IMAGE Image
|
||||
* \ingroup WORKBENCHES */
|
||||
|
||||