Commit f3d211a5 authored by David Thompson's avatar David Thompson Committed by Kitware Robot

Merge topic 'fix-phrase-move' into release

225fe3c3 Fix reordering of descriptive phrases.
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Bob Obara's avatarBob Obara <bob.obara@kitware.com>
Merge-request: !1586
parents d9bf63b9 225fe3c3
Pipeline #139169 running with stage
## SMTK View System Changes
+ Changes to component names did not always result in
reordering of phrases in the resource tree-view.
+ Reordering of phrases could result in a crash due
to improper offsets passed to Qt's item model.
......@@ -348,6 +348,12 @@ void PhraseModel::handleModified(Operation::Ptr op, Operation::Result res, Compo
if (modified.find(phr->relatedComponent()) != modified.end())
{
this->trigger(phr, PhraseModelEvent::PHRASE_MODIFIED, idx, idx, std::vector<int>());
// Now check whether the modification requires a reorder
auto pp = phr->parent();
smtk::view::DescriptivePhrases sorted(pp->subphrases().begin(), pp->subphrases().end());
std::sort(sorted.begin(), sorted.end(), DescriptivePhrase::compareByTypeThenTitle);
std::vector<int> pidx(idx.begin(), idx.begin() + idx.size() - 1);
this->updateChildren(pp, sorted, pidx);
}
return 0;
});
......@@ -548,18 +554,18 @@ void PhraseModel::updateChildren(
}
std::vector<int> moveRange(3);
moveRange[0] = static_cast<int>(oi - orig.begin());
moveRange[1] = static_cast<int>(bi == orig.end() ? orig.size() : bi - orig.begin());
moveRange[2] = static_cast<int>(mv - next.begin());
moveRange[1] = static_cast<int>(bi == orig.end() ? orig.size() : bi - orig.begin()) - 1;
moveRange[2] = static_cast<int>((mv - next.begin()) + (moveRange[1] - moveRange[0]) + 1);
this->trigger(src, PhraseModelEvent::ABOUT_TO_MOVE, idx, idx, moveRange);
// Copy batch to destination (which must be *after* source)
orig.insert(
orig.begin() + moveRange[2], orig.begin() + moveRange[0], orig.begin() + moveRange[1]);
orig.insert(orig.begin() + moveRange[2], orig.begin() + moveRange[0],
orig.begin() + moveRange[1] + 1);
// Erase batch in its original location (we cannot use iterators in orig
// as they may have been invalidated by insertion).
orig.erase(orig.begin() + moveRange[0], orig.begin() + moveRange[1]);
orig.erase(orig.begin() + moveRange[0], orig.begin() + moveRange[1] + 1);
this->trigger(src, PhraseModelEvent::MOVE_FINISHED, idx, idx, moveRange);
// Update iterator to continue search for relocated entries.
oi = orig.begin() + moveRange[1];
oi = orig.begin() + moveRange[0];
}
}
}
......
......@@ -29,6 +29,7 @@
#include "smtk/model/SessionRef.h"
#include "smtk/model/operators/EntityGroupOperation.h"
#include "smtk/model/operators/SetProperty.h"
#include "smtk/common/testing/cxx/helpers.h"
#include "smtk/model/testing/cxx/helpers.h"
......@@ -161,11 +162,11 @@ int unitComponentPhraseModel(int argc, char* argv[])
smtkTest(phraseModel->root()->subphrases().size() == reducedSize,
"Expected the same number of phrases as earlier.");
// IV. Test updates due to an operation.
// IV. Test updates due to operations.
// Grab the faces as reported to us:
smtk::resource::ComponentArray faces;
smtk::model::EntityPtr fmod;
smtk::model::EntityPtr fmod; // model owning the faces
phraseModel->root()->visitChildren(
[&faces, &fmod](DescriptivePhrasePtr p, const std::vector<int>&) {
auto comp = p->relatedComponent();
......@@ -176,32 +177,106 @@ int unitComponentPhraseModel(int argc, char* argv[])
});
smtkTest(!fmod || !faces.empty(), "Cannot test grouping without groupees.");
// Add a filter so groups will be listed at the top level:
// Configure the phrase model to show groups as well as faces at the top level:
filters.insert(
std::make_pair(std::string("smtk::session::polygon::Resource"), std::string("group")));
phraseModel->setComponentFilters(filters);
auto sizeBeforeAdd = phraseModel->root()->subphrases().size();
// Create a new group
auto op = operMgr->create<smtk::model::EntityGroupOperation>();
auto pm = op->parameters();
pm->findString("Operation")->setValue("Create");
pm->findString("group name")->setValue("everything");
pm->findVoid("Face")->setIsEnabled(true);
// pm->findModelEntity("cell to add")->setObjectValues(faces.begin(), faces.end());
pm->associations()->appendObjectValue(fmod);
auto res = op->operate();
std::cout << "add group success "
<< (res->findInt("outcome")->value(0) ==
static_cast<int>(smtk::operation::Operation::Outcome::SUCCEEDED)
? "T"
: "F")
<< "\n";
(void)res;
auto sizeAfterAdd = phraseModel->root()->subphrases().size();
std::cout << "---\n";
phraseModel->root()->visitChildren(printer);
smtkTest(
sizeAfterAdd == sizeBeforeAdd + 1, "Adding a group should increase number of phrases by 1.");
{
// IV.a. Test that creation inserts phrases properly.
// Add a filter so groups will be listed at the top level:
// Create a new group
auto sizeBeforeAdd = phraseModel->root()->subphrases().size();
auto op = operMgr->create<smtk::model::EntityGroupOperation>();
auto pm = op->parameters();
pm->findString("Operation")->setValue("Create");
pm->findString("group name")->setValue("everything");
pm->findVoid("Face")->setIsEnabled(true);
// pm->findModelEntity("cell to add")->setObjectValues(faces.begin(), faces.end());
pm->associations()->appendObjectValue(fmod);
auto res = op->operate();
bool ok = (res->findInt("outcome")->value(0) ==
static_cast<int>(smtk::operation::Operation::Outcome::SUCCEEDED));
std::cout << "add group success " << (ok ? "T" : "F") << "\n";
auto sizeAfterAdd = phraseModel->root()->subphrases().size();
std::cout << "---\n";
phraseModel->root()->visitChildren(printer);
smtkTest(sizeAfterAdd == sizeBeforeAdd + 1,
"Adding a group should increase number of phrases by 1.");
}
{
// IV.b. Test that modification reorders phrases properly.
// Change entity names in non-alphabetical ways.
// (i) Move from middle to end of list:
auto op = operMgr->create<smtk::model::SetProperty>();
auto pm = op->parameters();
auto value = pm->findString("string value");
pm->associate(faces[0]);
pm->findString("name")->setValue("name");
value->appendValue("zzz");
auto res = op->operate();
bool ok = (res->findInt("outcome")->value(0) ==
static_cast<int>(smtk::operation::Operation::Outcome::SUCCEEDED));
std::cout << "set property success " << (ok ? "T" : "F") << "\n";
std::cout << "---\n";
phraseModel->root()->visitChildren(printer);
smtkTest(phraseModel->root()->subphrases().back()->title() == "zzz",
"Did not move renamed face to end.");
// (ii) Make a change that requires no move, but which
// could cause a move if sorting alphabetically rather
// than by component type and *then* name.
pm->disassociate(faces[0]);
pm->associate(faces[1]);
value->setValue("aaa");
res = op->operate();
ok = (res->findInt("outcome")->value(0) ==
static_cast<int>(smtk::operation::Operation::Outcome::SUCCEEDED));
std::cout << "set property success " << (ok ? "T" : "F") << "\n";
std::cout << "---\n";
phraseModel->root()->visitChildren(printer);
smtkTest(phraseModel->root()->subphrases()[5]->title() == "aaa", "Improper phrase title \""
<< phraseModel->root()->subphrases()[5]->title() << "\".");
// (iii) Move something from the middle to the beginning
// of the list.
pm->disassociate(faces[1]);
auto gp = fmod->modelResource()->findEntitiesByProperty("name", "epic")[0].entityRecord();
pm->associate(gp);
res = op->operate();
ok = (res->findInt("outcome")->value(0) ==
static_cast<int>(smtk::operation::Operation::Outcome::SUCCEEDED));
std::cout << "set property success " << (ok ? "T" : "F") << "\n";
std::cout << "---\n";
phraseModel->root()->visitChildren(printer);
smtkTest(phraseModel->root()->subphrases().front()->title() == "aaa",
"Did not move renamed group to beginning.");
// (iv) Move something from the beginning to the middle
value->setValue("epic");
res = op->operate();
ok = (res->findInt("outcome")->value(0) ==
static_cast<int>(smtk::operation::Operation::Outcome::SUCCEEDED));
std::cout << "set property success " << (ok ? "T" : "F") << "\n";
std::cout << "---\n";
phraseModel->root()->visitChildren(printer);
smtkTest(phraseModel->root()->subphrases().front()->title() != "epic",
"Did not move renamed group to middle.");
smtkTest(phraseModel->root()->subphrases()[2]->title() == "epic",
"Did not move renamed group to middle.");
// (v) Move something from the end to the middle
pm->disassociate(gp);
pm->associate(faces[0]);
res = op->operate();
ok = (res->findInt("outcome")->value(0) ==
static_cast<int>(smtk::operation::Operation::Outcome::SUCCEEDED));
std::cout << "set property success " << (ok ? "T" : "F") << "\n";
std::cout << "---\n";
phraseModel->root()->visitChildren(printer);
smtkTest(phraseModel->root()->subphrases()[6]->title() == "epic",
"Did not move renamed group to middle.");
}
// Don't leak
free(dataArgs[1]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment