Skip to content

Commit

Permalink
App: fix Expression _moveCells()
Browse files Browse the repository at this point in the history
The problem is caused by not refreshing ObjectIdentifier internal cache
after change.
  • Loading branch information
realthunder authored and wwmayer committed Dec 31, 2019
1 parent 6562946 commit d5a4996
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 15 deletions.
10 changes: 6 additions & 4 deletions src/App/Expression.cpp
Expand Up @@ -2716,7 +2716,8 @@ void VariableExpression::_moveCells(const CellAddress &address,
if(var.hasDocumentObjectName(true))
return;

auto &comp = var.getPropertyComponent(0);
int idx = 0;
const auto &comp = var.getPropertyComponent(0,&idx);
CellAddress addr = stringToAddress(comp.getName().c_str(),true);
if(!addr.isValid())
return;
Expand All @@ -2727,15 +2728,16 @@ void VariableExpression::_moveCells(const CellAddress &address,
v.aboutToChange();
addr.setRow(thisRow + rowCount);
addr.setCol(thisCol + colCount);
comp = ObjectIdentifier::SimpleComponent(addr.toString());
var.setComponent(idx,ObjectIdentifier::SimpleComponent(addr.toString()));
}
}

void VariableExpression::_offsetCells(int rowOffset, int colOffset, ExpressionVisitor &v) {
if(var.hasDocumentObjectName(true))
return;

auto &comp = var.getPropertyComponent(0);
int idx = 0;
const auto &comp = var.getPropertyComponent(0,&idx);
CellAddress addr = stringToAddress(comp.getName().c_str(),true);
if(!addr.isValid() || (addr.isAbsoluteCol() && addr.isAbsoluteRow()))
return;
Expand All @@ -2745,7 +2747,7 @@ void VariableExpression::_offsetCells(int rowOffset, int colOffset, ExpressionVi
addr.setCol(addr.col()+colOffset);
if(!addr.isAbsoluteRow())
addr.setRow(addr.row()+rowOffset);
comp = ObjectIdentifier::SimpleComponent(addr.toString());
var.setComponent(idx,ObjectIdentifier::SimpleComponent(addr.toString()));
}

void VariableExpression::setPath(const ObjectIdentifier &path)
Expand Down
29 changes: 20 additions & 9 deletions src/App/ObjectIdentifier.cpp
Expand Up @@ -185,25 +185,36 @@ std::string App::ObjectIdentifier::getPropertyName() const

/**
* @brief Get Component at given index \a i.
* @param i Index to get
* @param i: Index to get
* @param idx: optional return of adjusted component index
* @return A component.
*/

const App::ObjectIdentifier::Component &App::ObjectIdentifier::getPropertyComponent(int i) const
const App::ObjectIdentifier::Component &App::ObjectIdentifier::getPropertyComponent(int i, int *idx) const
{
ResolveResults result(*this);

assert(result.propertyIndex + i >=0 && static_cast<std::size_t>(result.propertyIndex) + i < components.size());
i += result.propertyIndex;
if (i < 0 || i >= static_cast<int>(components.size()))
FC_THROWM(Base::ValueError, "Invalid property component index");

return components[result.propertyIndex + i];
if (idx)
*idx = i;

return components[i];
}

App::ObjectIdentifier::Component &App::ObjectIdentifier::getPropertyComponent(int i)
void App::ObjectIdentifier::setComponent(int idx, Component &&comp)
{
ResolveResults result(*this);
assert(result.propertyIndex + i >=0 &&
static_cast<std::size_t>(result.propertyIndex) + i < components.size());
return components[result.propertyIndex + i];
if (idx < 0 || idx >= static_cast<int>(components.size()))
FC_THROWM(Base::ValueError, "Invalid component index");
components[idx] = std::move(comp);
_cache.clear();
}

void App::ObjectIdentifier::setComponent(int idx, const Component &comp)
{
setComponent(idx, Component(comp));
}

std::vector<ObjectIdentifier::Component> ObjectIdentifier::getPropertyComponents() const {
Expand Down
5 changes: 3 additions & 2 deletions src/App/ObjectIdentifier.h
Expand Up @@ -292,9 +292,10 @@ class AppExport ObjectIdentifier {
template<typename C>
void addComponents(const C &cs) { components.insert(components.end(), cs.begin(), cs.end()); }

const Component & getPropertyComponent(int i) const;
const Component & getPropertyComponent(int i, int *idx=0) const;

Component & getPropertyComponent(int i);
void setComponent(int idx, Component &&comp);
void setComponent(int idx, const Component &comp);

std::vector<Component> getPropertyComponents() const;
const std::vector<Component> &getComponents() const { return components; }
Expand Down
3 changes: 3 additions & 0 deletions src/Mod/Spreadsheet/TestSpreadsheet.py
Expand Up @@ -664,6 +664,9 @@ def testInsertRows(self):
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
sheet.set('B1', '=B2')
sheet.set('B2', '124')
# Calling getContents() here activates ObjectIdentifier internal cache,
# which needs to be tested as well.
self.assertEqual(sheet.getContents("B1"),"=B2")
sheet.insertRows('2', 1)
self.assertEqual(sheet.getContents("B1"),"=B3")

Expand Down

0 comments on commit d5a4996

Please sign in to comment.