Skip to content

Commit

Permalink
Merge pull request FreeCAD#19019 from hyarion/refactor/countObjectsOf…
Browse files Browse the repository at this point in the history
…Type

Refactor countObjectsOfType in selection and document
  • Loading branch information
chennes authored Jan 14, 2025
2 parents 70423b7 + ef27cc7 commit 115cd05
Show file tree
Hide file tree
Showing 31 changed files with 194 additions and 222 deletions.
15 changes: 8 additions & 7 deletions src/App/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4397,14 +4397,15 @@ Document::findObjects(const Base::Type& typeId, const char* objname, const char*

int Document::countObjectsOfType(const Base::Type& typeId) const
{
int ct = 0;
for (const auto& it : d->objectMap) {
if (it.second->getTypeId().isDerivedFrom(typeId)) {
ct++;
}
}
return std::count_if(d->objectMap.begin(), d->objectMap.end(), [&](const auto& it) {
return it.second->getTypeId().isDerivedFrom(typeId);
});
}

return ct;
int Document::countObjectsOfType(const char* typeName) const
{
Base::Type type = Base::Type::fromName(typeName);
return type.isBad() ? 0 : countObjectsOfType(type);
}

PyObject* Document::getPyObject()
Expand Down
13 changes: 12 additions & 1 deletion src/App/Document.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,9 @@ class AppExport Document: public App::PropertyContainer
/// Returns an array with the correct types already.
template<typename T>
inline std::vector<T*> getObjectsOfType() const;
int countObjectsOfType(const Base::Type& typeId) const;
template<typename T>
inline int countObjectsOfType() const;
int countObjectsOfType(const char* typeName) const;
/// get the number of objects in the document
int countObjects() const;
//@}
Expand Down Expand Up @@ -590,6 +592,7 @@ class AppExport Document: public App::PropertyContainer
std::vector<App::DocumentObject*> readObjects(Base::XMLReader& reader);
void writeObjects(const std::vector<App::DocumentObject*>&, Base::Writer& writer) const;
bool saveToFile(const char* filename) const;
int countObjectsOfType(const Base::Type& typeId) const;

void onBeforeChange(const Property* prop) override;
void onChanged(const Property* prop) override;
Expand Down Expand Up @@ -651,6 +654,14 @@ inline std::vector<T*> Document::getObjectsOfType() const
return type;
}

template<typename T>
inline int Document::countObjectsOfType() const
{
static_assert(std::is_base_of<App::DocumentObject, T>::value,
"T must be derived from App::DocumentObject");
return this->countObjectsOfType(T::getClassTypeId());
}


} // namespace App

Expand Down
2 changes: 1 addition & 1 deletion src/Gui/CommandDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,7 @@ bool StdCmdAlignment::isActive()
{
if (ManualAlignment::hasInstance())
return false;
return Gui::Selection().countObjectsOfType(App::GeoFeature::getClassTypeId()) == 2;
return Gui::Selection().countObjectsOfType<App::GeoFeature>() == 2;
}

//===========================================================================
Expand Down
10 changes: 3 additions & 7 deletions src/Gui/Selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,20 +526,16 @@ std::vector<App::DocumentObject*> SelectionSingleton::getObjectsOfType(const cha

unsigned int SelectionSingleton::countObjectsOfType(const Base::Type& typeId, const char* pDocName, ResolveMode resolve) const
{
unsigned int iNbr=0;
App::Document *pcDoc = nullptr;
if(!pDocName || strcmp(pDocName,"*") != 0) {
pcDoc = getDocument(pDocName);
if (!pcDoc)
return 0;
}

for (auto &sel : _SelList) {
if((!pcDoc||pcDoc==sel.pDoc) && getObjectOfType(sel, typeId, resolve))
iNbr++;
}

return iNbr;
return std::count_if(_SelList.begin(), _SelList.end(), [&](auto& sel) {
return (!pcDoc || pcDoc == sel.pDoc) && getObjectOfType(sel, typeId, resolve);
});
}

unsigned int SelectionSingleton::countObjectsOfType(const char* typeName, const char* pDocName, ResolveMode resolve) const
Expand Down
18 changes: 16 additions & 2 deletions src/Gui/Selection.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,11 @@ class GuiExport SelectionSingleton : public Base::Subject<const SelectionChanges
* If no document name is given the active document is assumed.
*
* Set 'resolve' to true to resolve any sub object inside selection SubName
* field
* field.
*
* The typename T must be based on App::DocumentObject.
*/
unsigned int countObjectsOfType(const Base::Type& typeId=App::DocumentObject::getClassTypeId(),
template<typename T> inline unsigned int countObjectsOfType(
const char* pDocName=nullptr, ResolveMode resolve = ResolveMode::OldStyleElement) const;

/**
Expand Down Expand Up @@ -708,6 +710,9 @@ class GuiExport SelectionSingleton : public Base::Subject<const SelectionChanges
static App::DocumentObject *getObjectOfType(_SelObj &sel, Base::Type type,
ResolveMode resolve, const char **subelement=nullptr);

unsigned int countObjectsOfType(const Base::Type& typeId=App::DocumentObject::getClassTypeId(),
const char* pDocName=nullptr, ResolveMode resolve = ResolveMode::OldStyleElement) const;

static SelectionSingleton* _pcSingleton;

std::string DocName;
Expand All @@ -724,6 +729,15 @@ class GuiExport SelectionSingleton : public Base::Subject<const SelectionChanges
SelectionStyle selectionStyle;
};

/**
* A convenience template-based method that returns the number of objects of the given type.
*/
template<typename T>
inline unsigned int SelectionSingleton::countObjectsOfType(const char* pDocName, ResolveMode resolve) const {
static_assert(std::is_base_of<App::DocumentObject, T>::value, "Template parameter T must be derived from App::DocumentObject");
return this->countObjectsOfType(T::getClassTypeId(), pDocName, resolve);
}

/**
* A convenience template-based method that returns an array with the correct types already.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/Gui/Workbench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
<< StdViews << "Separator"
<< "Std_ViewDockUndockFullscreen";

if (Gui::Selection().countObjectsOfType(App::DocumentObject::getClassTypeId()) > 0) {
if (Gui::Selection().countObjectsOfType<App::DocumentObject>() > 0) {
*item << "Separator" << "Std_ToggleVisibility"
<< "Std_ToggleSelectability" << "Std_TreeSelection"
<< "Std_RandomColor" << "Std_ToggleTransparency" << "Separator" << "Std_Delete"
Expand All @@ -603,7 +603,7 @@ void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
}
else if (strcmp(recipient,"Tree") == 0)
{
if (Gui::Selection().countObjectsOfType(App::DocumentObject::getClassTypeId()) > 0) {
if (Gui::Selection().countObjectsOfType<App::DocumentObject>() > 0) {
*item << "Std_ToggleFreeze" << "Separator"
<< "Std_Placement" << "Std_ToggleVisibility" << "Std_ShowSelection" << "Std_HideSelection"
<< "Std_ToggleSelectability" << "Std_TreeSelectAllInstances" << "Separator"
Expand Down
6 changes: 3 additions & 3 deletions src/Mod/Drawing/Gui/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ CmdDrawingOpenBrowserView::CmdDrawingOpenBrowserView()
void CmdDrawingOpenBrowserView::activated(int iMsg)
{
Q_UNUSED(iMsg);
unsigned int n = getSelection().countObjectsOfType(Drawing::FeaturePage::getClassTypeId());
unsigned int n = getSelection().countObjectsOfType<Drawing::FeaturePage>();
if (n != 1) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Wrong selection"),
Expand Down Expand Up @@ -691,7 +691,7 @@ CmdDrawingExportPage::CmdDrawingExportPage()
void CmdDrawingExportPage::activated(int iMsg)
{
Q_UNUSED(iMsg);
unsigned int n = getSelection().countObjectsOfType(Drawing::FeaturePage::getClassTypeId());
unsigned int n = getSelection().countObjectsOfType<Drawing::FeaturePage>();
if (n != 1) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Wrong selection"),
Expand Down Expand Up @@ -757,7 +757,7 @@ void CmdDrawingProjectShape::activated(int iMsg)

bool CmdDrawingProjectShape::isActive(void)
{
int ct = Gui::Selection().countObjectsOfType(Part::Feature::getClassTypeId());
int ct = Gui::Selection().countObjectsOfType<Part::Feature>();
return (ct > 0 && !Gui::Control().activeDialog());
}

Expand Down
Loading

0 comments on commit 115cd05

Please sign in to comment.