Merge pull request #21902 from tetektoza/fix/21380_allow_group_to_be_in_active_obj

Core: Allow users to add groups to active objects
This commit is contained in:
Benjamin Nauck
2025-06-23 00:45:24 +02:00
committed by GitHub
6 changed files with 75 additions and 3 deletions

View File

@@ -70,3 +70,9 @@ class GroupExtension(DocumentObjectExtension):
@param recursive if true check also if the obj is child of some sub group (default is false).
"""
...
def allowObject(self, obj: Any) -> bool:
"""
Returns true if obj is allowed in the group extension.
"""
...

View File

@@ -318,3 +318,30 @@ int GroupExtensionPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*
{
return 0;
}
// def allowObject(self, obj: Any) -> bool:
PyObject* GroupExtensionPy::allowObject(PyObject* args)
{
PyObject* object;
if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) {
return nullptr;
}
auto* docObj = static_cast<DocumentObjectPy*>(object);
if (!docObj->getDocumentObjectPtr()
|| !docObj->getDocumentObjectPtr()->isAttachedToDocument()) {
PyErr_SetString(Base::PyExc_FC_GeneralError, "Cannot check an invalid object");
return nullptr;
}
if (docObj->getDocumentObjectPtr()->getDocument()
!= getGroupExtensionPtr()->getExtendedObject()->getDocument()) {
PyErr_SetString(Base::PyExc_FC_GeneralError,
"Cannot check an object from another document from this group");
return nullptr;
}
GroupExtension* grp = getGroupExtensionPtr();
bool allowed = grp->allowObject(docObj->getDocumentObjectPtr());
return PyBool_FromLong(allowed ? 1 : 0);
}

View File

@@ -197,3 +197,15 @@ void ActiveObjectList::objectDeleted(const ViewProviderDocumentObject &vp)
}
}
}
App::DocumentObject* ActiveObjectList::getObjectWithExtension(const Base::Type extensionTypeId) const
{
for (const auto& pair : _ObjectMap) {
App::DocumentObject* obj = getObject(pair.second, true);
if (obj && obj->hasExtension(extensionTypeId)) {
return obj;
}
}
return nullptr;
}

View File

@@ -27,6 +27,7 @@
#include <map>
#include <string>
#include <Base/Type.h>
#include <Gui/TreeItemMode.h>
#include <FCGlobal.h>
@@ -67,6 +68,8 @@ namespace Gui
void objectDeleted(const ViewProviderDocumentObject& viewProviderIn);
bool hasObject(App::DocumentObject *obj, const char *, const char *subname=nullptr) const;
App::DocumentObject* getObjectWithExtension(Base::Type extensionTypeId) const;
private:
struct ObjectInfo;
void setHighlight(const ObjectInfo &info, Gui::HighlightMode mode, bool enable);

View File

@@ -32,6 +32,7 @@
#include "ActiveObjectList.h"
#include "Application.h"
#include "Document.h"
#include "MDIView.h"
#include "ViewProviderDocumentObject.h"
#include "Selection.h"
@@ -121,9 +122,27 @@ void StdCmdGroup::activated(int iMsg)
std::string GroupName;
GroupName = getUniqueObjectName("Group");
QString label = QApplication::translate("Std_Group", "Group");
doCommand(Doc,"App.activeDocument().Tip = App.activeDocument().addObject('App::DocumentObjectGroup','%s')",GroupName.c_str());
doCommand(Doc,"App.activeDocument().%s.Label = '%s'", GroupName.c_str(),
label.toUtf8().data());
// create a group
doCommand(Doc,"group = App.activeDocument().addObject('App::DocumentObjectGroup','%s')",GroupName.c_str());
doCommand(Doc,"group.Label = '%s'", label.toUtf8().data());
doCommand(Doc,"App.activeDocument().Tip = group");
// try to add the group to any active object that supports grouping (has GroupExtension)
if (auto* activeDoc = Gui::Application::Instance->activeDocument()) {
if (auto* activeView = activeDoc->getActiveView()) {
// find the first active object with GroupExtension
if (auto* activeObj = activeView->getActiveObjectWithExtension(
App::GroupExtension::getExtensionClassTypeId())) {
doCommand(Doc,
"active_obj = App.activeDocument().getObject('%s')\n"
"if active_obj and active_obj.allowObject(group):\n"
" active_obj.Group += [group]",
activeObj->getNameInDocument());
}
}
} // if we have no active object, group will be added to root doc
commitCommand();
Gui::Document* gui = Application::Instance->activeDocument();

View File

@@ -147,6 +147,11 @@ public:
return ActiveObjects.hasObject(o,n,subname);
}
App::DocumentObject* getActiveObjectWithExtension(const Base::Type extensionTypeId) const
{
return ActiveObjects.getObjectWithExtension(extensionTypeId);
}
/*!
* \brief containsViewProvider
* Checks if the given view provider is part of this view. The default implementation