878 lines
25 KiB
C++
878 lines
25 KiB
C++
/***************************************************************************
|
|
* 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:exportFile", &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)
|
|
{
|
|
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::getCellFromAlias(PyObject *args)
|
|
{
|
|
const char * alias;
|
|
|
|
if (!PyArg_ParseTuple(args, "s:getAlias", &alias))
|
|
return 0;
|
|
|
|
try {
|
|
std::string address = getSheetPtr()->getAddressFromAlias(alias);
|
|
|
|
if (address.size() > 0)
|
|
return Py::new_reference_to( Py::String( address ) );
|
|
else {
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
}
|
|
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::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;
|
|
|
|
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)
|
|
return 0;
|
|
return prop->getPyObject();
|
|
}
|
|
|
|
int SheetPy::setCustomAttributes(const char* attr, PyObject* obj)
|
|
{
|
|
return 0;
|
|
}
|