Gui: clean-up Selection API
Replace the int of the 'resolve' argument of several functions with a proper enum class. * This avoids the inconsistencies in client code where often true/false is passed when an int is expected * This avoids the use of magic numbers like 0, 1, 2 or the undocumented 3
This commit is contained in:
@@ -79,7 +79,7 @@ bool SelectionGateFilterExternal::allow(App::Document *doc ,App::DocumentObject
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SelectionObserver::SelectionObserver(bool attach, int resolve)
|
||||
SelectionObserver::SelectionObserver(bool attach, ResolveMode resolve)
|
||||
: resolve(resolve)
|
||||
, blockedSelection(false)
|
||||
{
|
||||
@@ -87,7 +87,7 @@ SelectionObserver::SelectionObserver(bool attach, int resolve)
|
||||
attachSelection();
|
||||
}
|
||||
|
||||
SelectionObserver::SelectionObserver(const ViewProviderDocumentObject *vp,bool attach, int resolve)
|
||||
SelectionObserver::SelectionObserver(const ViewProviderDocumentObject *vp, bool attach, ResolveMode resolve)
|
||||
: resolve(resolve)
|
||||
, blockedSelection(false)
|
||||
{
|
||||
@@ -125,9 +125,11 @@ bool SelectionObserver::isSelectionAttached() const
|
||||
void SelectionObserver::attachSelection()
|
||||
{
|
||||
if (!connectSelection.connected()) {
|
||||
auto &signal = resolve > 1 ? Selection().signalSelectionChanged3 :
|
||||
resolve ? Selection().signalSelectionChanged2 :
|
||||
Selection().signalSelectionChanged ;
|
||||
bool newStyle = (resolve >= ResolveMode::NewStyleElement);
|
||||
bool oldStyle = (resolve == ResolveMode::OldStyleElement);
|
||||
auto &signal = newStyle ? Selection().signalSelectionChanged3 :
|
||||
oldStyle ? Selection().signalSelectionChanged2 :
|
||||
Selection().signalSelectionChanged ;
|
||||
connectSelection = signal.connect(boost::bind
|
||||
(&SelectionObserver::_onSelectionChanged, this, bp::_1));
|
||||
|
||||
@@ -166,8 +168,8 @@ void SelectionObserver::detachSelection()
|
||||
|
||||
std::vector<SelectionObserverPython*> SelectionObserverPython::_instances;
|
||||
|
||||
SelectionObserverPython::SelectionObserverPython(const Py::Object& obj, int resolve)
|
||||
: SelectionObserver(true,resolve),inst(obj)
|
||||
SelectionObserverPython::SelectionObserverPython(const Py::Object& obj, ResolveMode resolve)
|
||||
: SelectionObserver(true, resolve), inst(obj)
|
||||
{
|
||||
#undef FC_PY_ELEMENT
|
||||
#define FC_PY_ELEMENT(_name) FC_PY_GetCallable(obj.ptr(),#_name,py_##_name);
|
||||
@@ -178,9 +180,9 @@ SelectionObserverPython::~SelectionObserverPython()
|
||||
{
|
||||
}
|
||||
|
||||
void SelectionObserverPython::addObserver(const Py::Object& obj, int resolve)
|
||||
void SelectionObserverPython::addObserver(const Py::Object& obj, ResolveMode resolve)
|
||||
{
|
||||
_instances.push_back(new SelectionObserverPython(obj,resolve));
|
||||
_instances.push_back(new SelectionObserverPython(obj, resolve));
|
||||
}
|
||||
|
||||
void SelectionObserverPython::removeObserver(const Py::Object& obj)
|
||||
@@ -362,20 +364,20 @@ bool SelectionSingleton::hasPreselection() const {
|
||||
return !CurrentPreselection.Object.getObjectName().empty();
|
||||
}
|
||||
|
||||
std::vector<SelectionSingleton::SelObj> SelectionSingleton::getCompleteSelection(int resolve) const
|
||||
std::vector<SelectionSingleton::SelObj> SelectionSingleton::getCompleteSelection(ResolveMode resolve) const
|
||||
{
|
||||
return getSelection("*",resolve);
|
||||
return getSelection("*", resolve);
|
||||
}
|
||||
|
||||
std::vector<SelectionSingleton::SelObj> SelectionSingleton::getSelection(const char* pDocName,
|
||||
int resolve, bool single) const
|
||||
std::vector<SelectionSingleton::SelObj> SelectionSingleton::getSelection(const char* pDocName, ResolveMode resolve, bool single) const
|
||||
{
|
||||
std::vector<SelObj> temp;
|
||||
if(single) temp.reserve(1);
|
||||
if (single)
|
||||
temp.reserve(1);
|
||||
SelObj tempSelObj;
|
||||
|
||||
App::Document *pcDoc = nullptr;
|
||||
if(!pDocName || strcmp(pDocName,"*")!=0) {
|
||||
if(!pDocName || strcmp(pDocName,"*") != 0) {
|
||||
pcDoc = getDocument(pDocName);
|
||||
if (!pcDoc)
|
||||
return temp;
|
||||
@@ -384,17 +386,18 @@ std::vector<SelectionSingleton::SelObj> SelectionSingleton::getSelection(const c
|
||||
std::map<App::DocumentObject*,std::set<std::string> > objMap;
|
||||
|
||||
for(auto &sel : _SelList) {
|
||||
if(!sel.pDoc) continue;
|
||||
if (!sel.pDoc)
|
||||
continue;
|
||||
const char *subelement = nullptr;
|
||||
auto obj = getObjectOfType(sel,App::DocumentObject::getClassTypeId(),resolve,&subelement);
|
||||
if(!obj || (pcDoc && sel.pObject->getDocument()!=pcDoc))
|
||||
auto obj = getObjectOfType(sel, App::DocumentObject::getClassTypeId(), resolve, &subelement);
|
||||
if (!obj || (pcDoc && sel.pObject->getDocument() != pcDoc))
|
||||
continue;
|
||||
|
||||
// In case we are resolving objects, make sure no duplicates
|
||||
if(resolve && !objMap[obj].insert(std::string(subelement?subelement:"")).second)
|
||||
if (resolve != ResolveMode::NoResolve && !objMap[obj].insert(std::string(subelement ? subelement : "")).second)
|
||||
continue;
|
||||
|
||||
if(single && temp.size()) {
|
||||
if (single && temp.size()) {
|
||||
temp.clear();
|
||||
break;
|
||||
}
|
||||
@@ -416,18 +419,19 @@ std::vector<SelectionSingleton::SelObj> SelectionSingleton::getSelection(const c
|
||||
return temp;
|
||||
}
|
||||
|
||||
bool SelectionSingleton::hasSelection(const char* doc, bool resolve) const
|
||||
bool SelectionSingleton::hasSelection(const char* doc, ResolveMode resolve) const
|
||||
{
|
||||
App::Document *pcDoc = nullptr;
|
||||
if(!doc || strcmp(doc,"*")!=0) {
|
||||
if (!doc || strcmp(doc,"*") != 0) {
|
||||
pcDoc = getDocument(doc);
|
||||
if (!pcDoc)
|
||||
return false;
|
||||
}
|
||||
for(auto &sel : _SelList) {
|
||||
if(!sel.pDoc) continue;
|
||||
auto obj = getObjectOfType(sel,App::DocumentObject::getClassTypeId(),resolve);
|
||||
if(obj && (!pcDoc || sel.pObject->getDocument()==pcDoc)) {
|
||||
if (!sel.pDoc)
|
||||
continue;
|
||||
auto obj = getObjectOfType(sel, App::DocumentObject::getClassTypeId(), resolve);
|
||||
if (obj && (!pcDoc || sel.pObject->getDocument()==pcDoc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -463,7 +467,7 @@ std::vector<SelectionSingleton::SelObj> SelectionSingleton::getPickedList(const
|
||||
SelObj tempSelObj;
|
||||
|
||||
App::Document *pcDoc = nullptr;
|
||||
if(!pDocName || strcmp(pDocName,"*")!=0) {
|
||||
if(!pDocName || strcmp(pDocName,"*") != 0) {
|
||||
pcDoc = getDocument(pDocName);
|
||||
if (!pcDoc)
|
||||
return temp;
|
||||
@@ -488,20 +492,24 @@ std::vector<SelectionSingleton::SelObj> SelectionSingleton::getPickedList(const
|
||||
return temp;
|
||||
}
|
||||
|
||||
std::vector<SelectionObject> SelectionSingleton::getSelectionEx(
|
||||
const char* pDocName, Base::Type typeId, int resolve, bool single) const {
|
||||
return getObjectList(pDocName,typeId,_SelList,resolve,single);
|
||||
std::vector<SelectionObject> SelectionSingleton::getSelectionEx(const char* pDocName, Base::Type typeId,
|
||||
ResolveMode resolve, bool single) const
|
||||
{
|
||||
return getObjectList(pDocName, typeId, _SelList, resolve, single);
|
||||
}
|
||||
|
||||
std::vector<SelectionObject> SelectionSingleton::getPickedListEx(const char* pDocName, Base::Type typeId) const {
|
||||
return getObjectList(pDocName,typeId,_PickedList,false);
|
||||
std::vector<SelectionObject> SelectionSingleton::getPickedListEx(const char* pDocName, Base::Type typeId) const
|
||||
{
|
||||
return getObjectList(pDocName, typeId, _PickedList, ResolveMode::NoResolve);
|
||||
}
|
||||
|
||||
std::vector<SelectionObject> SelectionSingleton::getObjectList(const char* pDocName, Base::Type typeId,
|
||||
std::list<_SelObj> &objList, int resolve, bool single) const
|
||||
std::list<_SelObj> &objList,
|
||||
ResolveMode resolve, bool single) const
|
||||
{
|
||||
std::vector<SelectionObject> temp;
|
||||
if(single) temp.reserve(1);
|
||||
if (single)
|
||||
temp.reserve(1);
|
||||
std::map<App::DocumentObject*,size_t> SortMap;
|
||||
|
||||
// check the type
|
||||
@@ -509,30 +517,31 @@ std::vector<SelectionObject> SelectionSingleton::getObjectList(const char* pDocN
|
||||
return temp;
|
||||
|
||||
App::Document *pcDoc = nullptr;
|
||||
if(!pDocName || strcmp(pDocName,"*")!=0) {
|
||||
if (!pDocName || strcmp(pDocName,"*") != 0) {
|
||||
pcDoc = getDocument(pDocName);
|
||||
if (!pcDoc)
|
||||
return temp;
|
||||
}
|
||||
|
||||
for (auto &sel : objList) {
|
||||
if(!sel.pDoc) continue;
|
||||
if(!sel.pDoc)
|
||||
continue;
|
||||
const char *subelement = nullptr;
|
||||
auto obj = getObjectOfType(sel,typeId,resolve,&subelement);
|
||||
if(!obj || (pcDoc && sel.pObject->getDocument()!=pcDoc))
|
||||
if (!obj || (pcDoc && sel.pObject->getDocument() != pcDoc))
|
||||
continue;
|
||||
auto it = SortMap.find(obj);
|
||||
if(it!=SortMap.end()) {
|
||||
// only add sub-element
|
||||
if (subelement && *subelement) {
|
||||
if(resolve && !temp[it->second]._SubNameSet.insert(subelement).second)
|
||||
if (resolve != ResolveMode::NoResolve && !temp[it->second]._SubNameSet.insert(subelement).second)
|
||||
continue;
|
||||
temp[it->second].SubNames.push_back(subelement);
|
||||
temp[it->second].SelPoses.emplace_back(sel.x,sel.y,sel.z);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(single && temp.size()) {
|
||||
if (single && temp.size()) {
|
||||
temp.clear();
|
||||
break;
|
||||
}
|
||||
@@ -541,7 +550,7 @@ std::vector<SelectionObject> SelectionSingleton::getObjectList(const char* pDocN
|
||||
if (subelement && *subelement) {
|
||||
temp.back().SubNames.push_back(subelement);
|
||||
temp.back().SelPoses.emplace_back(sel.x,sel.y,sel.z);
|
||||
if(resolve)
|
||||
if (resolve != ResolveMode::NoResolve)
|
||||
temp.back()._SubNameSet.insert(subelement);
|
||||
}
|
||||
SortMap.insert(std::make_pair(obj,temp.size()-1));
|
||||
@@ -551,11 +560,13 @@ std::vector<SelectionObject> SelectionSingleton::getObjectList(const char* pDocN
|
||||
return temp;
|
||||
}
|
||||
|
||||
bool SelectionSingleton::needPickedList() const {
|
||||
bool SelectionSingleton::needPickedList() const
|
||||
{
|
||||
return _needPickedList;
|
||||
}
|
||||
|
||||
void SelectionSingleton::enablePickedList(bool enable) {
|
||||
void SelectionSingleton::enablePickedList(bool enable)
|
||||
{
|
||||
if(enable != _needPickedList) {
|
||||
_needPickedList = enable;
|
||||
_PickedList.clear();
|
||||
@@ -563,7 +574,8 @@ void SelectionSingleton::enablePickedList(bool enable) {
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionSingleton::notify(SelectionChanges &&Chng) {
|
||||
void SelectionSingleton::notify(SelectionChanges &&Chng)
|
||||
{
|
||||
if(Notifying) {
|
||||
NotificationQueue.push_back(std::move(Chng));
|
||||
return;
|
||||
@@ -575,10 +587,10 @@ void SelectionSingleton::notify(SelectionChanges &&Chng) {
|
||||
bool notify;
|
||||
switch(msg.Type) {
|
||||
case SelectionChanges::AddSelection:
|
||||
notify = isSelected(msg.pDocName,msg.pObjectName,msg.pSubName,0);
|
||||
notify = isSelected(msg.pDocName, msg.pObjectName, msg.pSubName, ResolveMode::NoResolve);
|
||||
break;
|
||||
case SelectionChanges::RmvSelection:
|
||||
notify = !isSelected(msg.pDocName,msg.pObjectName,msg.pSubName,0);
|
||||
notify = !isSelected(msg.pDocName, msg.pObjectName, msg.pSubName, ResolveMode::NoResolve);
|
||||
break;
|
||||
case SelectionChanges::SetPreselect:
|
||||
notify = CurrentPreselection.Type==SelectionChanges::SetPreselect
|
||||
@@ -604,23 +616,27 @@ void SelectionSingleton::notify(SelectionChanges &&Chng) {
|
||||
}
|
||||
}
|
||||
|
||||
bool SelectionSingleton::hasPickedList() const {
|
||||
bool SelectionSingleton::hasPickedList() const
|
||||
{
|
||||
return _PickedList.size();
|
||||
}
|
||||
|
||||
int SelectionSingleton::getAsPropertyLinkSubList(App::PropertyLinkSubList &prop) const
|
||||
{
|
||||
std::vector<Gui::SelectionObject> sel = this->getSelectionEx();
|
||||
std::vector<App::DocumentObject*> objs; objs.reserve(sel.size()*2);
|
||||
std::vector<App::DocumentObject*> objs; objs.reserve(sel.size() * 2);
|
||||
std::vector<std::string> subs; subs.reserve(sel.size()*2);
|
||||
for (std::size_t iobj = 0; iobj < sel.size(); iobj++) {
|
||||
Gui::SelectionObject &selitem = sel[iobj];
|
||||
App::DocumentObject* obj = selitem.getObject();
|
||||
const std::vector<std::string> &subnames = selitem.getSubNames();
|
||||
if (subnames.size() == 0){//whole object is selected
|
||||
|
||||
//whole object is selected
|
||||
if (subnames.size() == 0){
|
||||
objs.push_back(obj);
|
||||
subs.emplace_back();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
for (std::size_t isub = 0; isub < subnames.size(); isub++) {
|
||||
objs.push_back(obj);
|
||||
subs.push_back(subnames[isub]);
|
||||
@@ -632,35 +648,39 @@ int SelectionSingleton::getAsPropertyLinkSubList(App::PropertyLinkSubList &prop)
|
||||
return objs.size();
|
||||
}
|
||||
|
||||
App::DocumentObject *SelectionSingleton::getObjectOfType(_SelObj &sel,
|
||||
Base::Type typeId, int resolve, const char **subelement)
|
||||
App::DocumentObject *SelectionSingleton::getObjectOfType(_SelObj &sel, Base::Type typeId,
|
||||
ResolveMode resolve, const char **subelement)
|
||||
{
|
||||
auto obj = sel.pObject;
|
||||
if(!obj || !obj->getNameInDocument())
|
||||
return nullptr;
|
||||
const char *subname = sel.SubName.c_str();
|
||||
if(resolve) {
|
||||
if (resolve != ResolveMode::NoResolve) {
|
||||
obj = sel.pResolvedObject;
|
||||
if(resolve==2 && sel.elementName.first.size())
|
||||
if (resolve == ResolveMode::NewStyleElement && sel.elementName.first.size())
|
||||
subname = sel.elementName.first.c_str();
|
||||
else
|
||||
subname = sel.elementName.second.c_str();
|
||||
}
|
||||
if(!obj)
|
||||
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
if(!obj->isDerivedFrom(typeId) &&
|
||||
(resolve!=3 || !obj->getLinkedObject(true)->isDerivedFrom(typeId)))
|
||||
|
||||
if (!obj->isDerivedFrom(typeId) && (resolve != ResolveMode::FollowLink || !obj->getLinkedObject(true)->isDerivedFrom(typeId)))
|
||||
return nullptr;
|
||||
if(subelement) *subelement = subname;
|
||||
|
||||
if (subelement)
|
||||
*subelement = subname;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
vector<App::DocumentObject*> SelectionSingleton::getObjectsOfType(const Base::Type& typeId, const char* pDocName, int resolve) const
|
||||
vector<App::DocumentObject*> SelectionSingleton::getObjectsOfType(const Base::Type& typeId, const char* pDocName, ResolveMode resolve) const
|
||||
{
|
||||
std::vector<App::DocumentObject*> temp;
|
||||
|
||||
App::Document *pcDoc = nullptr;
|
||||
if(!pDocName || strcmp(pDocName,"*")!=0) {
|
||||
if (!pDocName || strcmp(pDocName,"*") != 0) {
|
||||
pcDoc = getDocument(pDocName);
|
||||
if (!pcDoc)
|
||||
return temp;
|
||||
@@ -669,7 +689,7 @@ vector<App::DocumentObject*> SelectionSingleton::getObjectsOfType(const Base::Ty
|
||||
std::set<App::DocumentObject*> objs;
|
||||
for(auto &sel : _SelList) {
|
||||
if(pcDoc && pcDoc!=sel.pDoc) continue;
|
||||
App::DocumentObject *pObject = getObjectOfType(sel,typeId,resolve);
|
||||
App::DocumentObject *pObject = getObjectOfType(sel, typeId, resolve);
|
||||
if (pObject) {
|
||||
auto ret = objs.insert(pObject);
|
||||
if(ret.second)
|
||||
@@ -680,7 +700,7 @@ vector<App::DocumentObject*> SelectionSingleton::getObjectsOfType(const Base::Ty
|
||||
return temp;
|
||||
}
|
||||
|
||||
std::vector<App::DocumentObject*> SelectionSingleton::getObjectsOfType(const char* typeName, const char* pDocName, int resolve) const
|
||||
std::vector<App::DocumentObject*> SelectionSingleton::getObjectsOfType(const char* typeName, const char* pDocName, ResolveMode resolve) const
|
||||
{
|
||||
Base::Type typeId = Base::Type::fromName(typeName);
|
||||
if (typeId == Base::Type::badType())
|
||||
@@ -688,25 +708,25 @@ std::vector<App::DocumentObject*> SelectionSingleton::getObjectsOfType(const cha
|
||||
return getObjectsOfType(typeId, pDocName, resolve);
|
||||
}
|
||||
|
||||
unsigned int SelectionSingleton::countObjectsOfType(const Base::Type& typeId, const char* pDocName, int resolve) const
|
||||
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) {
|
||||
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))
|
||||
if((!pcDoc||pcDoc==sel.pDoc) && getObjectOfType(sel, typeId, resolve))
|
||||
iNbr++;
|
||||
}
|
||||
|
||||
return iNbr;
|
||||
}
|
||||
|
||||
unsigned int SelectionSingleton::countObjectsOfType(const char* typeName, const char* pDocName, int resolve) const
|
||||
unsigned int SelectionSingleton::countObjectsOfType(const char* typeName, const char* pDocName, ResolveMode resolve) const
|
||||
{
|
||||
Base::Type typeId = Base::Type::fromName(typeName);
|
||||
if (typeId == Base::Type::badType())
|
||||
@@ -715,7 +735,8 @@ unsigned int SelectionSingleton::countObjectsOfType(const char* typeName, const
|
||||
}
|
||||
|
||||
|
||||
void SelectionSingleton::slotSelectionChanged(const SelectionChanges& msg) {
|
||||
void SelectionSingleton::slotSelectionChanged(const SelectionChanges& msg)
|
||||
{
|
||||
if(msg.Type == SelectionChanges::SetPreselectSignal ||
|
||||
msg.Type == SelectionChanges::ShowSelection ||
|
||||
msg.Type == SelectionChanges::HideSelection)
|
||||
@@ -723,13 +744,13 @@ void SelectionSingleton::slotSelectionChanged(const SelectionChanges& msg) {
|
||||
|
||||
if(msg.Object.getSubName().size()) {
|
||||
auto pParent = msg.Object.getObject();
|
||||
if(!pParent)
|
||||
if(!pParent)
|
||||
return;
|
||||
std::pair<std::string,std::string> elementName;
|
||||
auto &newElementName = elementName.first;
|
||||
auto &oldElementName = elementName.second;
|
||||
auto pObject = App::GeoFeature::resolveElement(pParent,msg.pSubName,elementName);
|
||||
if (!pObject)
|
||||
if (!pObject)
|
||||
return;
|
||||
SelectionChanges msg2(msg.Type,pObject->getDocument()->getName(),
|
||||
pObject->getNameInDocument(),
|
||||
@@ -797,18 +818,18 @@ int SelectionSingleton::setPreselect(const char* pDocName, const char* pObjectNa
|
||||
return 0;
|
||||
|
||||
const char *subelement = pSubName;
|
||||
if(gateResolve) {
|
||||
if (gateResolve != ResolveMode::NoResolve) {
|
||||
auto &newElementName = elementName.first;
|
||||
auto &oldElementName = elementName.second;
|
||||
pObject = App::GeoFeature::resolveElement(pObject,pSubName,elementName);
|
||||
if (!pObject)
|
||||
return 0;
|
||||
if(gateResolve > 1)
|
||||
subelement = newElementName.size()?newElementName.c_str():oldElementName.c_str();
|
||||
if (gateResolve > ResolveMode::OldStyleElement)
|
||||
subelement = newElementName.size() ? newElementName.c_str() : oldElementName.c_str();
|
||||
else
|
||||
subelement = oldElementName.c_str();
|
||||
}
|
||||
if (!ActiveGate->allow(pObject->getDocument(),pObject,subelement)) {
|
||||
if (!ActiveGate->allow(pObject->getDocument(), pObject, subelement)) {
|
||||
QString msg;
|
||||
if (ActiveGate->notAllowedReason.length() > 0){
|
||||
msg = QObject::tr(ActiveGate->notAllowedReason.c_str());
|
||||
@@ -894,7 +915,7 @@ void SelectionSingleton::setPreselectCoord( float x, float y, float z)
|
||||
static char buf[513];
|
||||
|
||||
// if nothing is in preselect ignore
|
||||
if(CurrentPreselection.Object.getObjectName().empty())
|
||||
if(CurrentPreselection.Object.getObjectName().empty())
|
||||
return;
|
||||
|
||||
CurrentPreselection.x = x;
|
||||
@@ -955,7 +976,7 @@ const SelectionChanges &SelectionSingleton::getPreselection(void) const
|
||||
}
|
||||
|
||||
// add a SelectionGate to control what is selectable
|
||||
void SelectionSingleton::addSelectionGate(Gui::SelectionGate *gate, int resolve)
|
||||
void SelectionSingleton::addSelectionGate(Gui::SelectionGate *gate, ResolveMode resolve)
|
||||
{
|
||||
if (ActiveGate)
|
||||
rmvSelectionGate();
|
||||
@@ -1059,8 +1080,8 @@ bool SelectionSingleton::addSelection(const char* pDocName, const char* pObjectN
|
||||
}
|
||||
|
||||
_SelObj temp;
|
||||
int ret = checkSelection(pDocName,pObjectName,pSubName,0,temp);
|
||||
if(ret!=0)
|
||||
int ret = checkSelection(pDocName, pObjectName, pSubName, ResolveMode::NoResolve, temp);
|
||||
if (ret!=0)
|
||||
return false;
|
||||
|
||||
temp.x = x;
|
||||
@@ -1206,15 +1227,15 @@ void SelectionSingleton::selStackGoForward(int count) {
|
||||
getMainWindow()->updateActions();
|
||||
}
|
||||
|
||||
std::vector<SelectionObject> SelectionSingleton::selStackGet(
|
||||
const char* pDocName, int resolve, int index) const
|
||||
std::vector<SelectionObject> SelectionSingleton::selStackGet(const char* pDocName, ResolveMode resolve, int index) const
|
||||
{
|
||||
const SelStackItem *item = nullptr;
|
||||
if(index>=0) {
|
||||
if(index>=(int)_SelStackBack.size())
|
||||
if (index >= 0) {
|
||||
if(index >= (int)_SelStackBack.size())
|
||||
return {};
|
||||
item = &_SelStackBack[_SelStackBack.size()-1-index];
|
||||
}else{
|
||||
}
|
||||
else {
|
||||
index = -index-1;
|
||||
if(index>=(int)_SelStackForward.size())
|
||||
return {};
|
||||
@@ -1227,7 +1248,7 @@ std::vector<SelectionObject> SelectionSingleton::selStackGet(
|
||||
if(checkSelection(sobjT.getDocumentName().c_str(),
|
||||
sobjT.getObjectName().c_str(),
|
||||
sobjT.getSubName().c_str(),
|
||||
0,
|
||||
ResolveMode::NoResolve,
|
||||
sel,
|
||||
&selList)==0)
|
||||
{
|
||||
@@ -1235,7 +1256,7 @@ std::vector<SelectionObject> SelectionSingleton::selStackGet(
|
||||
}
|
||||
}
|
||||
|
||||
return getObjectList(pDocName,App::DocumentObject::getClassTypeId(),selList,resolve);
|
||||
return getObjectList(pDocName,App::DocumentObject::getClassTypeId(), selList, resolve);
|
||||
}
|
||||
|
||||
bool SelectionSingleton::addSelections(const char* pDocName, const char* pObjectName, const std::vector<std::string>& pSubNames)
|
||||
@@ -1248,8 +1269,8 @@ bool SelectionSingleton::addSelections(const char* pDocName, const char* pObject
|
||||
bool update = false;
|
||||
for(std::vector<std::string>::const_iterator it = pSubNames.begin(); it != pSubNames.end(); ++it) {
|
||||
_SelObj temp;
|
||||
int ret = checkSelection(pDocName,pObjectName,it->c_str(),0,temp);
|
||||
if(ret!=0)
|
||||
int ret = checkSelection(pDocName, pObjectName, it->c_str(), ResolveMode::NoResolve, temp);
|
||||
if (ret!=0)
|
||||
continue;
|
||||
|
||||
temp.x = 0;
|
||||
@@ -1288,12 +1309,12 @@ bool SelectionSingleton::updateSelection(bool show, const char* pDocName,
|
||||
rmvPreselect();
|
||||
}
|
||||
auto pDoc = getDocument(pDocName);
|
||||
if(!pDoc)
|
||||
if(!pDoc)
|
||||
return false;
|
||||
auto pObject = pDoc->getObject(pObjectName);
|
||||
if(!pObject)
|
||||
if(!pObject)
|
||||
return false;
|
||||
if (!isSelected(pObject, pSubName,0))
|
||||
if (!isSelected(pObject, pSubName, ResolveMode::NoResolve))
|
||||
return false;
|
||||
|
||||
SelectionChanges Chng(show?SelectionChanges::ShowSelection:SelectionChanges::HideSelection,
|
||||
@@ -1306,7 +1327,7 @@ bool SelectionSingleton::updateSelection(bool show, const char* pDocName,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SelectionSingleton::addSelection(const SelectionObject& obj,bool clearPreselect)
|
||||
bool SelectionSingleton::addSelection(const SelectionObject& obj, bool clearPreselect)
|
||||
{
|
||||
const std::vector<std::string>& subNames = obj.getSubNames();
|
||||
const std::vector<Base::Vector3d> points = obj.getPickedPoints();
|
||||
@@ -1357,12 +1378,12 @@ void SelectionSingleton::rmvSelection(const char* pDocName, const char* pObjectN
|
||||
notify(SelectionChanges(SelectionChanges::PickedListChanged));
|
||||
}
|
||||
|
||||
if(!pDocName)
|
||||
if(!pDocName)
|
||||
return;
|
||||
|
||||
_SelObj temp;
|
||||
int ret = checkSelection(pDocName,pObjectName,pSubName,0,temp);
|
||||
if(ret<0)
|
||||
int ret = checkSelection(pDocName, pObjectName, pSubName, ResolveMode::NoResolve, temp);
|
||||
if (ret<0)
|
||||
return;
|
||||
|
||||
std::vector<SelectionChanges> changes;
|
||||
@@ -1518,8 +1539,8 @@ void SelectionSingleton::setSelection(const char* pDocName, const std::vector<Ap
|
||||
if(!obj || !obj->getNameInDocument())
|
||||
continue;
|
||||
_SelObj temp;
|
||||
int ret = checkSelection(pDocName,obj->getNameInDocument(),nullptr,0,temp);
|
||||
if(ret!=0)
|
||||
int ret = checkSelection(pDocName,obj->getNameInDocument(), nullptr, ResolveMode::NoResolve, temp);
|
||||
if (ret!=0)
|
||||
continue;
|
||||
touched = true;
|
||||
_SelList.push_back(temp);
|
||||
@@ -1527,7 +1548,7 @@ void SelectionSingleton::setSelection(const char* pDocName, const std::vector<Ap
|
||||
|
||||
if(touched) {
|
||||
_SelStackForward.clear();
|
||||
notify(SelectionChanges(SelectionChanges::SetSelection,pDocName));
|
||||
notify(SelectionChanges(SelectionChanges::SetSelection, pDocName));
|
||||
getMainWindow()->updateActions();
|
||||
}
|
||||
}
|
||||
@@ -1611,24 +1632,24 @@ void SelectionSingleton::clearCompleteSelection(bool clearPreSelect)
|
||||
getMainWindow()->updateActions();
|
||||
}
|
||||
|
||||
bool SelectionSingleton::isSelected(const char* pDocName,
|
||||
const char* pObjectName, const char* pSubName, int resolve) const
|
||||
bool SelectionSingleton::isSelected(const char* pDocName, const char* pObjectName,
|
||||
const char* pSubName, ResolveMode resolve) const
|
||||
{
|
||||
_SelObj sel;
|
||||
return checkSelection(pDocName,pObjectName,pSubName,resolve,sel,&_SelList)>0;
|
||||
return checkSelection(pDocName, pObjectName, pSubName, resolve, sel, &_SelList) > 0;
|
||||
}
|
||||
|
||||
bool SelectionSingleton::isSelected(App::DocumentObject* pObject, const char* pSubName, int resolve) const
|
||||
bool SelectionSingleton::isSelected(App::DocumentObject* pObject, const char* pSubName, ResolveMode resolve) const
|
||||
{
|
||||
if(!pObject || !pObject->getNameInDocument() || !pObject->getDocument())
|
||||
if (!pObject || !pObject->getNameInDocument() || !pObject->getDocument())
|
||||
return false;
|
||||
_SelObj sel;
|
||||
return checkSelection(pObject->getDocument()->getName(),
|
||||
pObject->getNameInDocument(),pSubName,resolve,sel,&_SelList)>0;
|
||||
pObject->getNameInDocument(), pSubName, resolve, sel, &_SelList) > 0;
|
||||
}
|
||||
|
||||
int SelectionSingleton::checkSelection(const char *pDocName, const char *pObjectName,
|
||||
const char *pSubName, int resolve, _SelObj &sel, const std::list<_SelObj> *selList) const
|
||||
int SelectionSingleton::checkSelection(const char *pDocName, const char *pObjectName, const char *pSubName,
|
||||
ResolveMode resolve, _SelObj &sel, const std::list<_SelObj> *selList) const
|
||||
{
|
||||
sel.pDoc = getDocument(pDocName);
|
||||
if(!sel.pDoc) {
|
||||
@@ -1648,11 +1669,11 @@ int SelectionSingleton::checkSelection(const char *pDocName, const char *pObject
|
||||
FC_ERR("Object not found");
|
||||
return -1;
|
||||
}
|
||||
if(sel.pObject->testStatus(App::ObjectStatus::Remove))
|
||||
if (sel.pObject->testStatus(App::ObjectStatus::Remove))
|
||||
return -1;
|
||||
if(pSubName)
|
||||
if (pSubName)
|
||||
sel.SubName = pSubName;
|
||||
if(!resolve)
|
||||
if (resolve == ResolveMode::NoResolve)
|
||||
TreeWidget::checkTopParent(sel.pObject,sel.SubName);
|
||||
pSubName = sel.SubName.size()?sel.SubName.c_str():nullptr;
|
||||
sel.FeatName = sel.pObject->getNameInDocument();
|
||||
@@ -1688,20 +1709,21 @@ int SelectionSingleton::checkSelection(const char *pDocName, const char *pObject
|
||||
if (s.DocName==pDocName && s.FeatName==sel.FeatName) {
|
||||
if(s.SubName==pSubName)
|
||||
return 1;
|
||||
if(resolve>1 && boost::starts_with(s.SubName,prefix))
|
||||
if (resolve > ResolveMode::OldStyleElement && boost::starts_with(s.SubName,prefix))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if(resolve==1) {
|
||||
if (resolve == ResolveMode::OldStyleElement) {
|
||||
for(auto &s : *selList) {
|
||||
if(s.pResolvedObject != sel.pResolvedObject)
|
||||
continue;
|
||||
if(!pSubName[0])
|
||||
return 1;
|
||||
if(s.elementName.first.size()) {
|
||||
if(s.elementName.first == sel.elementName.first)
|
||||
if (s.elementName.first.size()) {
|
||||
if (s.elementName.first == sel.elementName.first)
|
||||
return 1;
|
||||
}else if(s.SubName == sel.elementName.second)
|
||||
}
|
||||
else if(s.SubName == sel.elementName.second)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1710,7 +1732,7 @@ int SelectionSingleton::checkSelection(const char *pDocName, const char *pObject
|
||||
|
||||
const char *SelectionSingleton::getSelectedElement(App::DocumentObject *obj, const char* pSubName) const
|
||||
{
|
||||
if (!obj)
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
for(list<_SelObj>::const_iterator It = _SelList.begin();It != _SelList.end();++It) {
|
||||
@@ -1729,7 +1751,7 @@ const char *SelectionSingleton::getSelectedElement(App::DocumentObject *obj, con
|
||||
|
||||
void SelectionSingleton::slotDeletedObject(const App::DocumentObject& Obj)
|
||||
{
|
||||
if(!Obj.getNameInDocument())
|
||||
if(!Obj.getNameInDocument())
|
||||
return;
|
||||
|
||||
// For safety reason, don't bother checking
|
||||
@@ -1787,7 +1809,7 @@ SelectionSingleton::SelectionSingleton()
|
||||
hy = 0;
|
||||
hz = 0;
|
||||
ActiveGate = nullptr;
|
||||
gateResolve = 1;
|
||||
gateResolve = ResolveMode::OldStyleElement;
|
||||
App::GetApplication().signalDeletedObject.connect(boost::bind(&Gui::SelectionSingleton::slotDeletedObject, this, bp::_1));
|
||||
signalSelectionChanged.connect(boost::bind(&Gui::SelectionSingleton::slotSelectionChanged, this, bp::_1));
|
||||
}
|
||||
@@ -2171,19 +2193,41 @@ PyObject *SelectionSingleton::sClearSelection(PyObject * /*self*/, PyObject *arg
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
namespace {
|
||||
ResolveMode toEnum(int value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return ResolveMode::NoResolve;
|
||||
case 1:
|
||||
return ResolveMode::OldStyleElement;
|
||||
case 2:
|
||||
return ResolveMode::NewStyleElement;
|
||||
case 3:
|
||||
return ResolveMode::FollowLink;
|
||||
default:
|
||||
throw Base::ValueError("Wrong enum value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *SelectionSingleton::sIsSelected(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
PyObject *object;
|
||||
char* subname = nullptr;
|
||||
PyObject *resolve = Py_True;
|
||||
if (!PyArg_ParseTuple(args, "O!|sO!", &(App::DocumentObjectPy::Type), &object,
|
||||
&subname, &PyBool_Type, &resolve))
|
||||
int resolve = 1;
|
||||
if (!PyArg_ParseTuple(args, "O!|si", &(App::DocumentObjectPy::Type), &object, &subname, &resolve))
|
||||
return nullptr;
|
||||
|
||||
App::DocumentObjectPy* docObj = static_cast<App::DocumentObjectPy*>(object);
|
||||
bool ok = Selection().isSelected(docObj->getDocumentObjectPtr(), subname,PyObject_IsTrue(resolve));
|
||||
try {
|
||||
App::DocumentObjectPy* docObj = static_cast<App::DocumentObjectPy*>(object);
|
||||
bool ok = Selection().isSelected(docObj->getDocumentObjectPtr(), subname, toEnum(resolve));
|
||||
|
||||
return Py_BuildValue("O", (ok ? Py_True : Py_False));
|
||||
return Py_BuildValue("O", (ok ? Py_True : Py_False));
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
e.setPyException();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *SelectionSingleton::sCountObjectsOfType(PyObject * /*self*/, PyObject *args)
|
||||
@@ -2194,9 +2238,14 @@ PyObject *SelectionSingleton::sCountObjectsOfType(PyObject * /*self*/, PyObject
|
||||
if (!PyArg_ParseTuple(args, "s|si", &objecttype, &document,&resolve))
|
||||
return nullptr;
|
||||
|
||||
unsigned int count = Selection().countObjectsOfType(objecttype, document, resolve);
|
||||
|
||||
return PyLong_FromLong(count);
|
||||
try {
|
||||
unsigned int count = Selection().countObjectsOfType(objecttype, document, toEnum(resolve));
|
||||
return PyLong_FromLong(count);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
e.setPyException();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *SelectionSingleton::sGetSelection(PyObject * /*self*/, PyObject *args)
|
||||
@@ -2207,10 +2256,10 @@ PyObject *SelectionSingleton::sGetSelection(PyObject * /*self*/, PyObject *args)
|
||||
if (!PyArg_ParseTuple(args, "|siO!", &documentName, &resolve, &PyBool_Type, &single))
|
||||
return nullptr;
|
||||
|
||||
std::vector<SelectionSingleton::SelObj> sel;
|
||||
sel = Selection().getSelection(documentName,resolve,PyObject_IsTrue(single));
|
||||
|
||||
try {
|
||||
std::vector<SelectionSingleton::SelObj> sel;
|
||||
sel = Selection().getSelection(documentName, toEnum(resolve), PyObject_IsTrue(single));
|
||||
|
||||
std::set<App::DocumentObject*> noduplicates;
|
||||
std::vector<App::DocumentObject*> selectedObjects; // keep the order of selection
|
||||
Py::List list;
|
||||
@@ -2224,6 +2273,10 @@ PyObject *SelectionSingleton::sGetSelection(PyObject * /*self*/, PyObject *args)
|
||||
}
|
||||
return Py::new_reference_to(list);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
e.setPyException();
|
||||
return nullptr;
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2294,16 +2347,20 @@ PyObject *SelectionSingleton::sGetCompleteSelection(PyObject * /*self*/, PyObjec
|
||||
if (!PyArg_ParseTuple(args, "|i",&resolve))
|
||||
return nullptr;
|
||||
|
||||
std::vector<SelectionSingleton::SelObj> sel;
|
||||
sel = Selection().getCompleteSelection(resolve);
|
||||
|
||||
try {
|
||||
std::vector<SelectionSingleton::SelObj> sel;
|
||||
sel = Selection().getCompleteSelection(toEnum(resolve));
|
||||
|
||||
Py::List list;
|
||||
for (std::vector<SelectionSingleton::SelObj>::iterator it = sel.begin(); it != sel.end(); ++it) {
|
||||
list.append(Py::asObject(it->pObject->getPyObject()));
|
||||
}
|
||||
return Py::new_reference_to(list);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
e.setPyException();
|
||||
return nullptr;
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2317,17 +2374,21 @@ PyObject *SelectionSingleton::sGetSelectionEx(PyObject * /*self*/, PyObject *arg
|
||||
if (!PyArg_ParseTuple(args, "|siO!", &documentName, &resolve, &PyBool_Type, &single))
|
||||
return nullptr;
|
||||
|
||||
std::vector<SelectionObject> sel;
|
||||
sel = Selection().getSelectionEx(documentName,
|
||||
App::DocumentObject::getClassTypeId(),resolve,PyObject_IsTrue(single));
|
||||
|
||||
try {
|
||||
std::vector<SelectionObject> sel;
|
||||
sel = Selection().getSelectionEx(documentName,
|
||||
App::DocumentObject::getClassTypeId(), toEnum(resolve), PyObject_IsTrue(single));
|
||||
|
||||
Py::List list;
|
||||
for (std::vector<SelectionObject>::iterator it = sel.begin(); it != sel.end(); ++it) {
|
||||
list.append(Py::asObject(it->getPyObject()));
|
||||
}
|
||||
return Py::new_reference_to(list);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
e.setPyException();
|
||||
return nullptr;
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2396,7 +2457,7 @@ PyObject *SelectionSingleton::sAddSelObserver(PyObject * /*self*/, PyObject *arg
|
||||
return nullptr;
|
||||
|
||||
PY_TRY {
|
||||
SelectionObserverPython::addObserver(Py::Object(o),resolve);
|
||||
SelectionObserverPython::addObserver(Py::Object(o), toEnum(resolve));
|
||||
Py_Return;
|
||||
}
|
||||
PY_CATCH;
|
||||
@@ -2421,7 +2482,7 @@ PyObject *SelectionSingleton::sAddSelectionGate(PyObject * /*self*/, PyObject *a
|
||||
int resolve = 1;
|
||||
if (PyArg_ParseTuple(args, "s|i", &filter, &resolve)) {
|
||||
PY_TRY {
|
||||
Selection().addSelectionGate(new SelectionFilterGate(filter),resolve);
|
||||
Selection().addSelectionGate(new SelectionFilterGate(filter), toEnum(resolve));
|
||||
Py_Return;
|
||||
}
|
||||
PY_CATCH;
|
||||
@@ -2432,7 +2493,7 @@ PyObject *SelectionSingleton::sAddSelectionGate(PyObject * /*self*/, PyObject *a
|
||||
if (PyArg_ParseTuple(args, "O!|i",SelectionFilterPy::type_object(),&filterPy,resolve)) {
|
||||
PY_TRY {
|
||||
Selection().addSelectionGate(new SelectionFilterGatePython(
|
||||
static_cast<SelectionFilterPy*>(filterPy)),resolve);
|
||||
static_cast<SelectionFilterPy*>(filterPy)), toEnum(resolve));
|
||||
Py_Return;
|
||||
}
|
||||
PY_CATCH;
|
||||
@@ -2442,7 +2503,7 @@ PyObject *SelectionSingleton::sAddSelectionGate(PyObject * /*self*/, PyObject *a
|
||||
PyObject* gate;
|
||||
if (PyArg_ParseTuple(args, "O|i",&gate,&resolve)) {
|
||||
PY_TRY {
|
||||
Selection().addSelectionGate(new SelectionGatePython(Py::Object(gate, false)),resolve);
|
||||
Selection().addSelectionGate(new SelectionGatePython(Py::Object(gate, false)), toEnum(resolve));
|
||||
Py_Return;
|
||||
}
|
||||
PY_CATCH;
|
||||
@@ -2505,14 +2566,14 @@ PyObject *SelectionSingleton::sPushSelStack(PyObject * /*self*/, PyObject *args)
|
||||
PyObject *SelectionSingleton::sHasSelection(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
const char *doc = nullptr;
|
||||
PyObject *resolve = Py_False;
|
||||
if (!PyArg_ParseTuple(args, "|sO!", &doc, &PyBool_Type, &resolve))
|
||||
int resolve = 0;
|
||||
if (!PyArg_ParseTuple(args, "|sO!", &doc, &resolve))
|
||||
return nullptr;
|
||||
|
||||
PY_TRY {
|
||||
bool ret;
|
||||
if(doc || PyObject_IsTrue(resolve))
|
||||
ret = Selection().hasSelection(doc,PyObject_IsTrue(resolve));
|
||||
if (doc || resolve > 0)
|
||||
ret = Selection().hasSelection(doc, toEnum(resolve));
|
||||
else
|
||||
ret = Selection().hasSelection();
|
||||
|
||||
@@ -2545,7 +2606,7 @@ PyObject *SelectionSingleton::sGetSelectionFromStack(PyObject * /*self*/, PyObje
|
||||
|
||||
PY_TRY {
|
||||
Py::List list;
|
||||
for(auto &sel : Selection().selStackGet(documentName, resolve, index))
|
||||
for(auto &sel : Selection().selStackGet(documentName, toEnum(resolve), index))
|
||||
list.append(Py::asObject(sel.getPyObject()));
|
||||
return Py::new_reference_to(list);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user