diff --git a/src/App/PropertyExpressionEngine.cpp b/src/App/PropertyExpressionEngine.cpp index daef397fcd..31cacdf17a 100644 --- a/src/App/PropertyExpressionEngine.cpp +++ b/src/App/PropertyExpressionEngine.cpp @@ -147,17 +147,17 @@ void PropertyExpressionEngine::hasSetValue() void PropertyExpressionEngine::Paste(const Property &from) { - const PropertyExpressionEngine * fromee = static_cast(&from); + const PropertyExpressionEngine &fromee = dynamic_cast(from); AtomicPropertyChange signaller(*this); expressions.clear(); - for(auto &e : fromee->expressions) { + for(auto &e : fromee.expressions) { expressions[e.first] = ExpressionInfo( boost::shared_ptr(e.second.expression->copy())); expressionChanged(e.first); } - validator = fromee->validator; + validator = fromee.validator; signaller.tryInvoke(); } diff --git a/src/App/Transactions.cpp b/src/App/Transactions.cpp index 2467e2a4bd..d2511a6b5f 100644 --- a/src/App/Transactions.cpp +++ b/src/App/Transactions.cpp @@ -292,7 +292,7 @@ void TransactionObject::applyNew(Document & /*Doc*/, TransactionalObject * /*pcO { } -void TransactionObject::applyChn(Document & /*Doc*/, TransactionalObject *pcObj, bool Forward) +void TransactionObject::applyChn(Document & /*Doc*/, TransactionalObject *pcObj, bool /* Forward */) { if (status == New || status == Chn) { // Property change order is not preserved, as it is recursive in nature @@ -333,17 +333,29 @@ void TransactionObject::applyChn(Document & /*Doc*/, TransactionalObject *pcObj, prop->setStatusValue(data.property->getStatus()); } } - // Because we now allow undo/redo dynamic property adding/removing, - // we have to enforce property type checking before calling Copy/Paste. - if(data.propertyType != prop->getTypeId()) { - FC_WARN("Cannot " << (Forward?"redo":"undo") - << " change of property " << prop->getName() - << " because of type change: " - << data.propertyType.getName() - << " -> " << prop->getTypeId().getName()); - continue; - } - prop->Paste(*data.property); + + // Many properties do not bother implement Copy() and accepts + // derived types just fine in Paste(). So we do not enforce type + // matching here. But instead, strengthen type checking in all + // Paste() implementation. + // + // if(data.propertyType != prop->getTypeId()) { + // FC_WARN("Cannot " << (Forward?"redo":"undo") + // << " change of property " << prop->getName() + // << " because of type change: " + // << data.propertyType.getName() + // << " -> " << prop->getTypeId().getName()); + // continue; + // } + try { + prop->Paste(*data.property); + } catch (Base::Exception &e) { + e.ReportException(); + FC_ERR("exception while restoring " << prop->getFullName() << ": " << e.what()); + } catch (std::exception &e) { + FC_ERR("exception while restoring " << prop->getFullName() << ": " << e.what()); + } catch (...) + {} } } } diff --git a/src/Mod/Spreadsheet/App/PropertyColumnWidths.cpp b/src/Mod/Spreadsheet/App/PropertyColumnWidths.cpp index d3b9a9655b..79f300cccb 100644 --- a/src/Mod/Spreadsheet/App/PropertyColumnWidths.cpp +++ b/src/Mod/Spreadsheet/App/PropertyColumnWidths.cpp @@ -63,7 +63,7 @@ App::Property *PropertyColumnWidths::Copy() const void PropertyColumnWidths::Paste(const App::Property &from) { - setValues(static_cast(from).getValues()); + setValues(dynamic_cast(from).getValues()); } void PropertyColumnWidths::setValues(const std::map &values) { diff --git a/src/Mod/Spreadsheet/App/PropertyRowHeights.cpp b/src/Mod/Spreadsheet/App/PropertyRowHeights.cpp index 9a61fa2ab3..36cd85e72d 100644 --- a/src/Mod/Spreadsheet/App/PropertyRowHeights.cpp +++ b/src/Mod/Spreadsheet/App/PropertyRowHeights.cpp @@ -56,7 +56,7 @@ App::Property *PropertyRowHeights::Copy() const void PropertyRowHeights::Paste(const Property &from) { - setValues(static_cast(from).getValues()); + setValues(dynamic_cast(from).getValues()); } void PropertyRowHeights::setValues(const std::map &values) { diff --git a/src/Mod/Spreadsheet/App/PropertySheet.cpp b/src/Mod/Spreadsheet/App/PropertySheet.cpp index 4ae6d4d09d..28012a70f5 100644 --- a/src/Mod/Spreadsheet/App/PropertySheet.cpp +++ b/src/Mod/Spreadsheet/App/PropertySheet.cpp @@ -224,9 +224,9 @@ App::Property *PropertySheet::Copy(void) const void PropertySheet::Paste(const Property &from) { - AtomicPropertyChange signaller(*this); + const PropertySheet &froms = dynamic_cast(from); - const PropertySheet * froms = static_cast(&from); + AtomicPropertyChange signaller(*this); std::map::iterator icurr = data.begin(); @@ -236,8 +236,8 @@ void PropertySheet::Paste(const Property &from) ++icurr; } - std::map::const_iterator ifrom = froms->data.begin(); - while (ifrom != froms->data.end()) { + std::map::const_iterator ifrom = froms.data.begin(); + while (ifrom != froms.data.end()) { std::map::iterator i = data.find(ifrom->first); if (i != data.end()) { @@ -269,7 +269,7 @@ void PropertySheet::Paste(const Property &from) ++icurr; } - mergedCells = froms->mergedCells; + mergedCells = froms.mergedCells; signaller.tryInvoke(); } diff --git a/src/Mod/Spreadsheet/App/Sheet.cpp b/src/Mod/Spreadsheet/App/Sheet.cpp index 85c8e93a05..cc254ed9b2 100644 --- a/src/Mod/Spreadsheet/App/Sheet.cpp +++ b/src/Mod/Spreadsheet/App/Sheet.cpp @@ -1470,9 +1470,10 @@ Property *PropertySpreadsheetQuantity::Copy() const void PropertySpreadsheetQuantity::Paste(const Property &from) { + const auto &src = dynamic_cast(from); aboutToSetValue(); - _dValue = static_cast(&from)->_dValue; - _Unit = static_cast(&from)->_Unit; + _dValue = src._dValue; + _Unit = src._Unit; hasSetValue(); }