Commit 55379524 authored by Bob Obara's avatar Bob Obara

ENH: Improving Model and Mesh Entity Selection in Qt

1. If there is only one entity that matches the selection critera it is now
automatically selected
2. If the selection criteria is that there is only one item to be selected then
if a new item is selected, the previous one is becomes unselected
3. If there are model entities initially selected the model item will attempt to be
set to the pre-selected entities.
4. qtModelEntityItem::associateEntities now pre-validates the list of model entities
being associated by on the following criteria:

a. Filter the list based on the model item's definition to remove inappropriate entities
b. Based on the number of valid entities compare that to the model item's definition size
requirements
parent dfba4872
......@@ -48,7 +48,7 @@ bool ModelEntityItem::isValid() const
{
return true;
}
// Do we have atleats the number of required values present?
// Do we have at least the number of required values present?
if (this->numberOfValues() < this->numberOfRequiredValues())
{
return false;
......
......@@ -152,6 +152,7 @@ void qtModelEntityItemCombo::init()
tmpGrp.setMembershipMask(itemDef->membershipMask());
int row = 1;
QStandardItem* item = nullptr;
if (modelManager)
{
for (smtk::model::UUIDWithEntity it = modelManager->topology().begin();
......@@ -172,7 +173,7 @@ void qtModelEntityItemCombo::init()
(showNonActiveModel && entref.isModel() &&
(entref.owningSession().entity() == activeModel.owningSession().entity()))))
{
QStandardItem* item = new QStandardItem;
item = new QStandardItem;
std::string entName = entref.name();
item->setText(entName.c_str());
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
......@@ -187,7 +188,6 @@ void qtModelEntityItemCombo::init()
}
itemModel->sort(0);
}
connect(this->model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this,
SLOT(itemCheckChanged(const QModelIndex&, const QModelIndex&)));
......@@ -198,6 +198,14 @@ void qtModelEntityItemCombo::init()
// this->view()->setSelectionMode(QAbstractItemView::ExtendedSelection);
this->updateText();
this->hidePopup();
// If there is only 1 model entity that matches the criteria then lets select it by default
// Note that the combobox always has 1 entry even if there are no model entities that match the
// requirements - hence why the count needs to be 2 and not 1
if (this->count() == 2)
{
item->setCheckState(Qt::Checked);
}
}
void qtModelEntityItemCombo::showPopup()
......@@ -241,6 +249,7 @@ void qtModelEntityItemCombo::itemCheckChanged(const QModelIndex& topLeft, const
return;
}
ModelEntityItemPtr modelEntityItem = this->m_ModelEntityItem->modelEntityItem();
auto def = modelEntityItem->definition();
QString entid = item->data(Qt::UserRole).toString();
if (!entid.isEmpty())
{
......@@ -248,12 +257,36 @@ void qtModelEntityItemCombo::itemCheckChanged(const QModelIndex& topLeft, const
modelEntityItem->attribute()->system()->refModelManager(), entid.toStdString());
if (item->checkState() == Qt::Checked)
{
// see if we can add it to the model item
// see if we can add it to the model item (base on size or if we are dealing with a simple item
// (one that is not existenible and has only 1 required value). If that is the case
// then unslect the previous item and select the new one
if (!this->m_ModelEntityItem->add(selentityref))
{
this->blockSignals(true);
item->setCheckState(Qt::Unchecked);
this->blockSignals(false);
if ((def->numberOfRequiredValues() == 1) && (!def->isExtensible()))
{
// We need tp turn off the item that was originally checked
for (int row = 1; row < this->count(); row++)
{
if (itemModel->item(row)->checkState() == Qt::Checked)
{
if (itemModel->item(row) != item)
{
itemModel->item(row)->setCheckState(Qt::Unchecked);
QString oldEntid = itemModel->item(row)->data(Qt::UserRole).toString();
smtk::model::EntityRef previousRef(
modelEntityItem->attribute()->system()->refModelManager(),
oldEntid.toStdString());
this->m_ModelEntityItem->remove(previousRef);
}
}
}
}
else
{
item->setCheckState(Qt::Unchecked);
this->blockSignals(false);
}
}
}
else
......@@ -284,6 +317,7 @@ void qtMeshItemCombo::init()
QStandardItemModel* itemModel = qobject_cast<QStandardItemModel*>(this->model());
QStandardItem* item = nullptr;
if (modelManager)
{
// find out all associated collections, or use all collections if none associated
......@@ -315,7 +349,7 @@ void qtMeshItemCombo::init()
{
if ((*cit)->isValid())
{
QStandardItem* item = new QStandardItem;
item = new QStandardItem;
std::string meshName = (*cit)->name();
item->setText(meshName.c_str());
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
......@@ -355,6 +389,14 @@ void qtMeshItemCombo::init()
// this->view()->setSelectionMode(QAbstractItemView::ExtendedSelection);
this->updateText();
this->hidePopup();
// If there is only 1 mesh entity that matches the criteria then lets select it by default
// Note that the combobox always has 1 entry even if there are no mesh entities that match the
// requirements - hence why the count needs to be 2 and not 1
if (this->count() == 2)
{
item->setCheckState(Qt::Checked);
}
}
void qtMeshItemCombo::showPopup()
......@@ -402,6 +444,7 @@ void qtMeshItemCombo::itemCheckChanged(const QModelIndex& topLeft, const QModelI
return;
}
MeshItemPtr meshItem = this->m_MeshItem->meshItem();
auto def = smtk::dynamic_pointer_cast<const MeshItemDefinition>(meshItem->definition());
smtk::common::UUID collectionid(strcollectionid.toStdString());
smtk::mesh::CollectionPtr selcollection =
meshItem->attribute()->system()->refModelManager()->meshes()->collection(collectionid);
......@@ -410,11 +453,40 @@ void qtMeshItemCombo::itemCheckChanged(const QModelIndex& topLeft, const QModelI
smtk::mesh::MeshSet allmeshes = selcollection->meshes();
if (item->checkState() == Qt::Checked)
{
// see if we can add it to the mesh item (base on size or if we are dealing with a simple item
// (one that is not existenible and has only 1 required value). If that is the case
// then unslect the previous item and select the new one
if (!this->m_MeshItem->add(allmeshes))
{
this->blockSignals(true);
item->setCheckState(Qt::Unchecked);
this->blockSignals(false);
if ((def->numberOfRequiredValues() == 1) && (!def->isExtensible()))
{
// We need tp turn off the item that was originally checked
for (int row = 1; row < this->count(); row++)
{
if (itemModel->item(row)->checkState() == Qt::Checked)
{
if (itemModel->item(row) != item)
{
itemModel->item(row)->setCheckState(Qt::Unchecked);
QString oldCollectionId = itemModel->item(row)->data(Qt::UserRole).toString();
auto oldCollection =
meshItem->attribute()->system()->refModelManager()->meshes()->collection(
oldCollectionId.toStdString());
if (selcollection && selcollection->isValid())
{
smtk::mesh::MeshSet oldMeshes = selcollection->meshes();
this->m_MeshItem->remove(oldMeshes);
}
}
}
}
}
else
{
item->setCheckState(Qt::Unchecked);
this->blockSignals(false);
}
}
}
else
......
......@@ -74,6 +74,16 @@ qtModelEntityItem::qtModelEntityItem(smtk::attribute::ItemPtr dataObj, QWidget*
std::cerr << "register selection source " << this->m_selectionSourceName
<< "failed. Already existed!" << std::endl;
}
// If there is a selection manager then lets see if we can set the checkbox widget to
// match the current selection state
if (qtActiveObjects::instance().smtkSelectionManager())
{
smtk::model::EntityRefs selEntities;
qtActiveObjects::instance().smtkSelectionManager()->getSelectedEntitiesAsEntityRefs(
selEntities);
this->associateEntities(selEntities, false);
}
}
qtModelEntityItem::~qtModelEntityItem()
......@@ -371,12 +381,35 @@ void qtModelEntityItem::associateEntities(
{
return;
}
auto def = modEntityItem->definition();
smtk::model::EntityRefs ents;
// First lets filter out any entities that are not valid w/r to the item's
// definition
for (auto it = selEntityRefs.begin(); it != selEntityRefs.end(); ++it)
{
if (def->isValueValid(*it))
{
ents.insert(*it);
}
}
// OK - so we now have a list of valid elements - next we need to see if there is a restriction as to the
// number of entities that can be assigned to the item
auto numEnts = ents.size();
if ((numEnts == 0) || ((!def->isExtensible() || ((def->maxNumberOfValues() != 0) &&
(numEnts > def->maxNumberOfValues()))) &&
(numEnts > def->numberOfRequiredValues())))
{
std::cerr << "Not Setting ModelEntityItem, numEnts = " << numEnts
<< " Def isExtensible = " << def->isExtensible()
<< " Num Vals = " << def->numberOfRequiredValues() << std::endl;
return;
}
if (resetExisting)
modEntityItem->reset();
std::size_t idx = 0;
for (smtk::model::EntityRefs::const_iterator it = selEntityRefs.begin();
it != selEntityRefs.end(); ++it)
for (smtk::model::EntityRefs::const_iterator it = ents.begin(); it != ents.end(); ++it)
{
bool success = false;
if (idx < modEntityItem->numberOfValues())
......
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