Spreadsheet changes

Various changes to support in-place editing, and more.
This commit is contained in:
Zheng, Lei
2019-07-12 13:25:50 +08:00
committed by wmayer
parent a460fdc8b6
commit 11321bb996
17 changed files with 334 additions and 180 deletions

View File

@@ -27,8 +27,10 @@
# include <QApplication>
# include <QLocale>
# include <QMessageBox>
# include <QTextDocument>
#endif
#include <App/Document.h>
#include <Gui/Application.h>
#include "SheetModel.h"
#include <Mod/Spreadsheet/App/Utils.h>
@@ -177,7 +179,7 @@ QVariant SheetModel::data(const QModelIndex &index, int role) const
return QVariant(v);
}
#else
if (role == Qt::ToolTipRole) {
if (!cell->hasException() && role == Qt::ToolTipRole) {
std::string alias;
if (cell->getAlias(alias))
return QVariant(Base::Tools::fromStdString(alias));
@@ -186,14 +188,26 @@ QVariant SheetModel::data(const QModelIndex &index, int role) const
if (cell->hasException()) {
switch (role) {
case Qt::ToolTipRole:
return QVariant::fromValue(Base::Tools::fromStdString(cell->getException()));
case Qt::DisplayRole:
case Qt::ToolTipRole: {
#if QT_VERSION >= 0x050000
QString txt(Base::Tools::fromStdString(cell->getException()).toHtmlEscaped());
#else
QString txt(Qt::escape(Base::Tools::fromStdString(cell->getException())));
#endif
return QVariant(QString::fromLatin1("<pre>%1</pre>").arg(txt));
}
case Qt::DisplayRole: {
#ifdef DEBUG_DEPS
return QVariant::fromValue(QString::fromUtf8("#ERR: %1").arg(Tools::fromStdString(cell->getException())));
#else
std::string str;
if(cell->getStringContent(str))
return QVariant::fromValue(QString::fromUtf8(str.c_str()));
return QVariant::fromValue(QString::fromUtf8("#ERR"));
#endif
}
case Qt::TextColorRole:
return QVariant::fromValue(QColor(255.0, 0, 0));
case Qt::TextAlignmentRole:
return QVariant(Qt::AlignVCenter | Qt::AlignLeft);
default:
@@ -215,9 +229,6 @@ QVariant SheetModel::data(const QModelIndex &index, int role) const
std::string address = CellAddress(row, col).toString();
Property * prop = sheet->getPropertyByName(address.c_str());
if (prop == 0)
return QVariant();
if (role == Qt::BackgroundRole) {
Color color;
@@ -267,7 +278,24 @@ QVariant SheetModel::data(const QModelIndex &index, int role) const
return QVariant::fromValue(f);
}
if (prop->isDerivedFrom(App::PropertyString::getClassTypeId())) {
if (!prop) {
switch (role) {
case Qt::TextColorRole: {
return QColor(0, 0, 255.0);
}
case Qt::TextAlignmentRole: {
qtAlignment = Qt::AlignHCenter | Qt::AlignVCenter;
return QVariant::fromValue(qtAlignment);
}
case Qt::DisplayRole:
if(cell->getExpression())
return QVariant(QLatin1String("#PENDING"));
else
return QVariant();
default:
return QVariant();
}
} else if (prop->isDerivedFrom(App::PropertyString::getClassTypeId())) {
/* String */
const App::PropertyString * stringProp = static_cast<const App::PropertyString*>(prop);
@@ -338,7 +366,7 @@ QVariant SheetModel::data(const QModelIndex &index, int role) const
v = number + Base::Tools::fromStdString(" " + displayUnit.stringRep);
}
else {
v = QString::fromUtf8("ERR: unit");
v = QString::fromUtf8("#ERR: unit");
}
}
else {
@@ -356,9 +384,15 @@ QVariant SheetModel::data(const QModelIndex &index, int role) const
return QVariant();
}
}
else if (prop->isDerivedFrom(App::PropertyFloat::getClassTypeId())) {
else if (prop->isDerivedFrom(App::PropertyFloat::getClassTypeId())
|| prop->isDerivedFrom(App::PropertyInteger::getClassTypeId()))
{
/* Number */
const App::PropertyFloat * floatProp = static_cast<const App::PropertyFloat*>(prop);
double d;
if(prop->isDerivedFrom(App::PropertyFloat::getClassTypeId()))
d = static_cast<const App::PropertyFloat*>(prop)->getValue();
else
d = static_cast<const App::PropertyInteger*>(prop)->getValue();
switch (role) {
case Qt::TextColorRole: {
@@ -367,7 +401,7 @@ QVariant SheetModel::data(const QModelIndex &index, int role) const
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 {
if (floatProp->getValue() < 0)
if (d < 0)
return QVariant::fromValue(QColor(negativeFgColor));
else
return QVariant::fromValue(QColor(positiveFgColor));
@@ -390,13 +424,13 @@ QVariant SheetModel::data(const QModelIndex &index, int role) const
// Display locale specific decimal separator (#0003875,#0003876)
if (cell->getDisplayUnit(displayUnit)) {
QString number = QLocale::system().toString(floatProp->getValue() / displayUnit.scaler,'f',Base::UnitsApi::getDecimals());
//QString number = QString::number(floatProp->getValue() / displayUnit.scaler);
QString number = QLocale::system().toString(d / displayUnit.scaler,'f',Base::UnitsApi::getDecimals());
//QString number = QString::number(d / displayUnit.scaler);
v = number + Base::Tools::fromStdString(" " + displayUnit.stringRep);
}
else {
v = QLocale::system().toString(floatProp->getValue(),'f',Base::UnitsApi::getDecimals());
//v = QString::number(floatProp->getValue());
v = QLocale::system().toString(d,'f',Base::UnitsApi::getDecimals());
//v = QString::number(d);
}
return QVariant(v);
}
@@ -404,6 +438,50 @@ QVariant SheetModel::data(const QModelIndex &index, int role) const
return QVariant();
}
}
else if (prop->isDerivedFrom(App::PropertyPythonObject::getClassTypeId())) {
auto pyProp = static_cast<const App::PropertyPythonObject*>(prop);
switch (role) {
case Qt::TextColorRole: {
Color color;
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(QColor(textFgColor));
}
case Qt::TextAlignmentRole: {
if (alignment & Cell::ALIGNMENT_HIMPLIED) {
qtAlignment &= ~(Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight);
qtAlignment |= Qt::AlignHCenter;
}
if (alignment & Cell::ALIGNMENT_VIMPLIED) {
qtAlignment &= ~(Qt::AlignTop | Qt::AlignVCenter | Qt::AlignBottom);
qtAlignment |= Qt::AlignVCenter;
}
return QVariant::fromValue(qtAlignment);
}
case Qt::DisplayRole: {
Base::PyGILStateLocker lock;
std::string value;
try {
value = pyProp->getValue().as_string();
} catch (Py::Exception &) {
Base::PyException e;
value = "#ERR: ";
value += e.what();
} catch (Base::Exception &e) {
value = "#ERR: ";
value += e.what();
} catch (...) {
value = "#ERR: unknown exception";
}
return QVariant(QString::fromUtf8(value.c_str()));
}
default:
return QVariant();
}
}
return QVariant();
}
@@ -443,26 +521,27 @@ bool SheetModel::setData(const QModelIndex & index, const QVariant & value, int
CellAddress address(index.row(), index.column());
try {
std::string strAddress = address.toString();
QString str = value.toString();
std::string content;
Cell * cell = sheet->getCell(address);
if (cell)
cell->getStringContent(content);
if ( content != Base::Tools::toStdString(str)) {
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::commitCommand();
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
}
Gui::Command::openCommand("Edit cell");
// Because of possible complication of recursively escaped
// characters, let's take a shortcut and bypass the command
// interface for now.
#if 0
std::string strAddress = address.toString();
str.replace(QString::fromUtf8("\\"), QString::fromUtf8("\\\\"));
str.replace(QString::fromUtf8("'"), QString::fromUtf8("\\'"));
FCMD_OBJ_CMD(sheet,"set('" << strAddress << "','" <<
str.toUtf8().constData() << "')");
#else
sheet->setContent(address, str.toUtf8().constData());
#endif
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()));
e.ReportException();
Gui::Command::abortCommand();
return false;
}
}
return true;