Gui: Selection API changes
Mostly about API changes to SelectionSingleton. Also include related changes to SelectionObject, SelectionChange, and SelectionView. Please check out the summary of changes [here](https://git.io/fjimC)
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,7 @@
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
#include <boost/signals2.hpp>
|
||||
#include <CXX/Objects.hxx>
|
||||
|
||||
@@ -68,20 +69,102 @@ public:
|
||||
RmvSelection,
|
||||
SetSelection,
|
||||
ClrSelection,
|
||||
SetPreselect,
|
||||
RmvPreselect
|
||||
SetPreselect, // to signal observer the preselect has changed
|
||||
RmvPreselect,
|
||||
SetPreselectSignal, // to request 3D view to change preselect
|
||||
PickedListChanged,
|
||||
ShowSelection, // to show a selection
|
||||
HideSelection, // to hide a selection
|
||||
RmvPreselectSignal, // to request 3D view to remove preselect
|
||||
MovePreselect, // to signal observer the mouse movement when preselect
|
||||
};
|
||||
SelectionChanges()
|
||||
: Type(ClrSelection)
|
||||
, pDocName(0)
|
||||
, pObjectName(0)
|
||||
, pSubName(0)
|
||||
, pTypeName(0)
|
||||
, x(0),y(0),z(0)
|
||||
|
||||
SelectionChanges(MsgType type = ClrSelection,
|
||||
const char *docName=0, const char *objName=0,
|
||||
const char *subName=0, const char *typeName=0,
|
||||
float x=0, float y=0, float z=0, int subtype=0)
|
||||
: Type(type),SubType(subtype)
|
||||
, x(x),y(y),z(z)
|
||||
{
|
||||
if(docName) DocName=docName;
|
||||
pDocName = DocName.c_str();
|
||||
if(objName) ObjName = objName;
|
||||
pObjectName = ObjName.c_str();
|
||||
if(subName) SubName = subName;
|
||||
pSubName = SubName.c_str();
|
||||
if(typeName) TypeName = typeName;
|
||||
pTypeName = TypeName.c_str();
|
||||
}
|
||||
|
||||
SelectionChanges(MsgType type,
|
||||
const std::string &docName,
|
||||
const std::string &objName,
|
||||
const std::string &subName,
|
||||
const std::string &typeName = std::string(),
|
||||
float x=0,float y=0,float z=0, int subtype=0)
|
||||
: Type(type), SubType(subtype)
|
||||
, x(x),y(y),z(z)
|
||||
, DocName(docName)
|
||||
, ObjName(objName)
|
||||
, SubName(subName)
|
||||
, TypeName(typeName)
|
||||
{
|
||||
pDocName = DocName.c_str();
|
||||
pObjectName = ObjName.c_str();
|
||||
pSubName = SubName.c_str();
|
||||
pTypeName = TypeName.c_str();
|
||||
}
|
||||
|
||||
SelectionChanges(const SelectionChanges &other) {
|
||||
*this = other;
|
||||
}
|
||||
|
||||
SelectionChanges &operator=(const SelectionChanges &other) {
|
||||
Type = other.Type;
|
||||
SubType = other.SubType;
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
z = other.z;
|
||||
DocName = other.DocName;
|
||||
ObjName = other.ObjName;
|
||||
SubName = other.SubName;
|
||||
TypeName = other.TypeName;
|
||||
pDocName = DocName.c_str();
|
||||
pObjectName = ObjName.c_str();
|
||||
pSubName = SubName.c_str();
|
||||
pTypeName = TypeName.c_str();
|
||||
pOriginalMsg = other.pOriginalMsg;
|
||||
pSubObject = other.pSubObject;
|
||||
pParentObject = other.pParentObject;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SelectionChanges(SelectionChanges &&other) {
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
SelectionChanges &operator=(SelectionChanges &&other) {
|
||||
Type = other.Type;
|
||||
SubType = other.SubType;
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
z = other.z;
|
||||
DocName = std::move(other.DocName);
|
||||
ObjName = std::move(other.ObjName);
|
||||
SubName = std::move(other.SubName);
|
||||
TypeName = std::move(other.TypeName);
|
||||
pDocName = DocName.c_str();
|
||||
pObjectName = ObjName.c_str();
|
||||
pSubName = SubName.c_str();
|
||||
pTypeName = TypeName.c_str();
|
||||
pOriginalMsg = other.pOriginalMsg;
|
||||
pSubObject = other.pSubObject;
|
||||
pParentObject = other.pParentObject;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MsgType Type;
|
||||
int SubType;
|
||||
|
||||
const char* pDocName;
|
||||
const char* pObjectName;
|
||||
@@ -90,6 +173,22 @@ public:
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
|
||||
// For more robust selection notification (e.g. in case user make selection
|
||||
// change inside selection notification handler), the notification message
|
||||
// shall make a copy of all the strings here.
|
||||
std::string DocName;
|
||||
std::string ObjName;
|
||||
std::string SubName;
|
||||
std::string TypeName;
|
||||
|
||||
// Resolved sub object in case resolve!=0, otherwise this is null
|
||||
App::DocumentObject *pSubObject = 0;
|
||||
// Resolved parent object in case resolve!=0, otherwise this is null
|
||||
App::DocumentObject *pParentObject = 0;
|
||||
|
||||
// Original selection message in case resolve!=0
|
||||
const SelectionChanges *pOriginalMsg = 0;
|
||||
};
|
||||
|
||||
} //namespace Gui
|
||||
@@ -118,6 +217,7 @@ template class GuiExport Base::Subject<const Gui::SelectionChanges&>;
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
class ViewProviderDocumentObject;
|
||||
|
||||
/**
|
||||
* The SelectionObserver class simplifies the step to write classes that listen
|
||||
@@ -130,10 +230,12 @@ class GuiExport SelectionObserver
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
SelectionObserver();
|
||||
SelectionObserver(bool attach = true, int resolve = 1);
|
||||
SelectionObserver(const Gui::ViewProviderDocumentObject *vp, bool attach=true, int resolve=1);
|
||||
virtual ~SelectionObserver();
|
||||
bool blockConnection(bool block);
|
||||
bool isConnectionBlocked() const;
|
||||
bool isConnectionAttached() const;
|
||||
|
||||
/** Attaches to the selection. */
|
||||
void attachSelection();
|
||||
@@ -147,6 +249,9 @@ private:
|
||||
private:
|
||||
typedef boost::signals2::connection Connection;
|
||||
Connection connectSelection;
|
||||
std::string filterDocName;
|
||||
std::string filterObjName;
|
||||
int resolve;
|
||||
bool blockSelection;
|
||||
};
|
||||
|
||||
@@ -162,10 +267,10 @@ class GuiExport SelectionObserverPython : public SelectionObserver
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
SelectionObserverPython(const Py::Object& obj);
|
||||
SelectionObserverPython(const Py::Object& obj, int resolve=1);
|
||||
virtual ~SelectionObserverPython();
|
||||
|
||||
static void addObserver(const Py::Object& obj);
|
||||
static void addObserver(const Py::Object& obj, int resolve=1);
|
||||
static void removeObserver(const Py::Object& obj);
|
||||
|
||||
private:
|
||||
@@ -176,9 +281,26 @@ private:
|
||||
void clearSelection(const SelectionChanges&);
|
||||
void setPreselection(const SelectionChanges&);
|
||||
void removePreselection(const SelectionChanges&);
|
||||
void pickedListChanged();
|
||||
|
||||
private:
|
||||
Py::Object inst;
|
||||
|
||||
#define FC_PY_SEL_OBSERVER \
|
||||
FC_PY_ELEMENT(onSelectionChanged) \
|
||||
FC_PY_ELEMENT(addSelection) \
|
||||
FC_PY_ELEMENT(removeSelection) \
|
||||
FC_PY_ELEMENT(setSelection) \
|
||||
FC_PY_ELEMENT(clearSelection) \
|
||||
FC_PY_ELEMENT(setPreselection) \
|
||||
FC_PY_ELEMENT(removePreselection) \
|
||||
FC_PY_ELEMENT(pickedListChanged)
|
||||
|
||||
#undef FC_PY_ELEMENT
|
||||
#define FC_PY_ELEMENT(_name) Py::Object py_##_name;
|
||||
|
||||
FC_PY_SEL_OBSERVER
|
||||
|
||||
static std::vector<SelectionObserverPython*> _instances;
|
||||
};
|
||||
|
||||
@@ -201,6 +323,18 @@ public:
|
||||
std::string notAllowedReason;
|
||||
};
|
||||
|
||||
/** SelectionGateFilterExternal
|
||||
* The selection gate disallows any external object
|
||||
*/
|
||||
class GuiExport SelectionGateFilterExternal: public SelectionGate
|
||||
{
|
||||
public:
|
||||
SelectionGateFilterExternal(const char *docName, const char *objName=0);
|
||||
virtual bool allow(App::Document*,App::DocumentObject*, const char*) override;
|
||||
private:
|
||||
std::string DocName;
|
||||
std::string ObjName;
|
||||
};
|
||||
|
||||
/** The Selection class
|
||||
* The selection singleton keeps track of the selection state of
|
||||
@@ -220,70 +354,6 @@ public:
|
||||
class GuiExport SelectionSingleton : public Base::Subject<const SelectionChanges&>
|
||||
{
|
||||
public:
|
||||
/// Add to selection
|
||||
bool addSelection(const char* pDocName, const char* pObjectName=0, const char* pSubName=0, float x=0, float y=0, float z=0);
|
||||
/// Add to selection with several sub-elements
|
||||
bool addSelection(const char* pDocName, const char* pObjectName, const std::vector<std::string>& pSubNames);
|
||||
/// Add to selection
|
||||
bool addSelection(const SelectionObject&);
|
||||
/// Remove from selection (for internal use)
|
||||
void rmvSelection(const char* pDocName, const char* pObjectName=0, const char* pSubName=0);
|
||||
/// Set the selection for a document
|
||||
void setSelection(const char* pDocName, const std::vector<App::DocumentObject*>&);
|
||||
/// Clear the selection of document \a pDocName. If the document name is not given the selection of the active document is cleared.
|
||||
void clearSelection(const char* pDocName=0);
|
||||
/// Clear the selection of all documents
|
||||
void clearCompleteSelection();
|
||||
/// Check if selected
|
||||
bool isSelected(const char* pDocName, const char* pObjectName=0, const char* pSubName=0) const;
|
||||
/// Check if selected
|
||||
bool isSelected(App::DocumentObject*, const char* pSubName=0) const;
|
||||
|
||||
/// set the preselected object (mostly by the 3D view)
|
||||
bool setPreselect(const char* pDocName, const char* pObjectName, const char* pSubName, float x=0, float y=0, float z=0);
|
||||
/// remove the present preselection
|
||||
void rmvPreselect();
|
||||
/// sets different coords for the preselection
|
||||
void setPreselectCoord(float x, float y, float z);
|
||||
/// returns the present preselection
|
||||
const SelectionChanges& getPreselection(void) const;
|
||||
/// add a SelectionGate to control what is selectable
|
||||
void addSelectionGate(Gui::SelectionGate *gate);
|
||||
/// remove the active SelectionGate
|
||||
void rmvSelectionGate(void);
|
||||
|
||||
|
||||
/** Returns the number of selected objects with a special object type
|
||||
* It's the convenient way to check if the right objects are selected to
|
||||
* perform an operation (GuiCommand). The check also detects base types.
|
||||
* E.g. "Part" also fits on "PartImport" or "PartTransform types.
|
||||
* If no document name is given the active document is assumed.
|
||||
*/
|
||||
unsigned int countObjectsOfType(const Base::Type& typeId, const char* pDocName=0) const;
|
||||
|
||||
/**
|
||||
* Does basically the same as the method above unless that it accepts a string literal as first argument.
|
||||
* \a typeName must be a registered type, otherwise 0 is returned.
|
||||
*/
|
||||
unsigned int countObjectsOfType(const char* typeName, const char* pDocName=0) const;
|
||||
|
||||
/** Returns a vector of objects of type \a TypeName selected for the given document name \a pDocName.
|
||||
* If no document name is specified the objects from the active document are regarded.
|
||||
* If no objects of this document are selected an empty vector is returned.
|
||||
* @note The vector reflects the sequence of selection.
|
||||
*/
|
||||
std::vector<App::DocumentObject*> getObjectsOfType(const Base::Type& typeId, const char* pDocName=0) const;
|
||||
|
||||
/**
|
||||
* Does basically the same as the method above unless that it accepts a string literal as first argument.
|
||||
* \a typeName must be a registered type otherwise an empty array is returned.
|
||||
*/
|
||||
std::vector<App::DocumentObject*> getObjectsOfType(const char* typeName, const char* pDocName=0) const;
|
||||
/**
|
||||
* A convenience template-based method that returns an array with the correct types already.
|
||||
*/
|
||||
template<typename T> inline std::vector<T*> getObjectsOfType(const char* pDocName=0) const;
|
||||
|
||||
struct SelObj {
|
||||
const char* DocName;
|
||||
const char* FeatName;
|
||||
@@ -291,24 +361,139 @@ public:
|
||||
const char* TypeName;
|
||||
App::Document* pDoc;
|
||||
App::DocumentObject* pObject;
|
||||
App::DocumentObject* pResolvedObject;
|
||||
float x,y,z;
|
||||
};
|
||||
|
||||
/// Add to selection
|
||||
bool addSelection(const char* pDocName, const char* pObjectName=0, const char* pSubName=0,
|
||||
float x=0, float y=0, float z=0, const std::vector<SelObj> *pickedList = 0, bool clearPreSelect=true);
|
||||
bool addSelection2(const char* pDocName, const char* pObjectName=0, const char* pSubName=0,
|
||||
float x=0, float y=0, float z=0, const std::vector<SelObj> *pickedList = 0)
|
||||
{
|
||||
return addSelection(pDocName,pObjectName,pSubName,x,y,z,pickedList,false);
|
||||
}
|
||||
|
||||
/// Add to selection
|
||||
bool addSelection(const SelectionObject&, bool clearPreSelect=true);
|
||||
/// Add to selection with several sub-elements
|
||||
bool addSelections(const char* pDocName, const char* pObjectName, const std::vector<std::string>& pSubNames);
|
||||
/// Update a selection
|
||||
bool updateSelection(bool show, const char* pDocName, const char* pObjectName=0, const char* pSubName=0);
|
||||
/// Remove from selection (for internal use)
|
||||
void rmvSelection(const char* pDocName, const char* pObjectName=0, const char* pSubName=0,
|
||||
const std::vector<SelObj> *pickedList = 0);
|
||||
/// Set the selection for a document
|
||||
void setSelection(const char* pDocName, const std::vector<App::DocumentObject*>&);
|
||||
/// Clear the selection of document \a pDocName. If the document name is not given the selection of the active document is cleared.
|
||||
void clearSelection(const char* pDocName=0, bool clearPreSelect=true);
|
||||
/// Clear the selection of all documents
|
||||
void clearCompleteSelection(bool clearPreSelect=true);
|
||||
/// Check if selected
|
||||
bool isSelected(const char* pDocName, const char* pObjectName=0,
|
||||
const char* pSubName=0, int resolve=1) const;
|
||||
/// Check if selected
|
||||
bool isSelected(App::DocumentObject*, const char* pSubName=0, int resolve=1) const;
|
||||
|
||||
const char *getSelectedElement(App::DocumentObject*, const char* pSubName) const;
|
||||
|
||||
/// set the preselected object (mostly by the 3D view)
|
||||
int setPreselect(const char* pDocName, const char* pObjectName,
|
||||
const char* pSubName, float x=0, float y=0, float z=0, int signal=0);
|
||||
/// remove the present preselection
|
||||
void rmvPreselect(bool signal=false);
|
||||
/// sets different coords for the preselection
|
||||
void setPreselectCoord(float x, float y, float z);
|
||||
/// returns the present preselection
|
||||
const SelectionChanges& getPreselection(void) const;
|
||||
/// add a SelectionGate to control what is selectable
|
||||
void addSelectionGate(Gui::SelectionGate *gate, int resolve = 1);
|
||||
/// remove the active SelectionGate
|
||||
void rmvSelectionGate(void);
|
||||
|
||||
int disableCommandLog();
|
||||
int enableCommandLog(bool silent=false);
|
||||
|
||||
/** Returns the number of selected objects with a special object type
|
||||
* It's the convenient way to check if the right objects are selected to
|
||||
* perform an operation (GuiCommand). The check also detects base types.
|
||||
* E.g. "Part" also fits on "PartImport" or "PartTransform types.
|
||||
* If no document name is given the active document is assumed.
|
||||
*
|
||||
* Set 'resolve' to true to resolve any sub object inside selection SubName
|
||||
* field
|
||||
*/
|
||||
unsigned int countObjectsOfType(const Base::Type& typeId=App::DocumentObject::getClassTypeId(),
|
||||
const char* pDocName=0, int resolve=1) const;
|
||||
|
||||
/**
|
||||
* Does basically the same as the method above unless that it accepts a string literal as first argument.
|
||||
* \a typeName must be a registered type, otherwise 0 is returned.
|
||||
*/
|
||||
unsigned int countObjectsOfType(const char* typeName,
|
||||
const char* pDocName=0, int resolve=1) const;
|
||||
|
||||
/** Returns a vector of objects of type \a TypeName selected for the given document name \a pDocName.
|
||||
* If no document name is specified the objects from the active document are regarded.
|
||||
* If no objects of this document are selected an empty vector is returned.
|
||||
* @note The vector reflects the sequence of selection.
|
||||
*/
|
||||
std::vector<App::DocumentObject*> getObjectsOfType(const Base::Type& typeId,
|
||||
const char* pDocName=0, int resolve=1) const;
|
||||
|
||||
/**
|
||||
* Does basically the same as the method above unless that it accepts a string literal as first argument.
|
||||
* \a typeName must be a registered type otherwise an empty array is returned.
|
||||
*/
|
||||
std::vector<App::DocumentObject*> getObjectsOfType(const char* typeName,
|
||||
const char* pDocName=0, int resolve=1) const;
|
||||
/**
|
||||
* A convenience template-based method that returns an array with the correct types already.
|
||||
*/
|
||||
template<typename T> inline std::vector<T*> getObjectsOfType(
|
||||
const char* pDocName=0, int resolve=1) const;
|
||||
|
||||
/** Set selection object visibility
|
||||
*
|
||||
* @param visible: 1: make visible, 0: make invisible, -1: toggle visibility
|
||||
*/
|
||||
void setVisible(int visible);
|
||||
|
||||
/// signal on new object
|
||||
boost::signals2::signal<void (const SelectionChanges& msg)> signalSelectionChanged;
|
||||
|
||||
/// signal on selection change with resolved object
|
||||
boost::signals2::signal<void (const SelectionChanges& msg)> signalSelectionChanged2;
|
||||
/// signal on selection change with resolved object and sub element map
|
||||
boost::signals2::signal<void (const SelectionChanges& msg)> signalSelectionChanged3;
|
||||
|
||||
/** Returns a vector of selection objects
|
||||
* If no document name is given the objects of the active are returned.
|
||||
* If nothing for this Document is selected an empty vector is returned.
|
||||
* The vector reflects the sequence of selection.
|
||||
*
|
||||
* @param pDocName: document name. If no document name is given the objects
|
||||
* of the active are returned. If nothing for this Document is selected an
|
||||
* empty vector is returned. If document name is "*", then all document is
|
||||
* considered.
|
||||
* @param resolve: whether to resolve the subname reference of the selection
|
||||
* @param single: if set to true, then it will return an empty vector if
|
||||
* there is more than one selections.
|
||||
*
|
||||
* @return The returned vector reflects the sequence of selection.
|
||||
*/
|
||||
std::vector<SelObj> getSelection(const char* pDocName=0) const;
|
||||
std::vector<SelObj> getSelection(const char* pDocName=0, int resolve=1, bool single=false) const;
|
||||
/** Returns a vector of selection objects
|
||||
* If no document name is given the objects of the active are returned.
|
||||
* If nothing for this document is selected an empty vector is returned.
|
||||
* The vector reflects the sequence of selection.
|
||||
*
|
||||
* @param pDocName: document name. If no document name is given the objects
|
||||
* of the active are returned. If nothing for this Document is selected an
|
||||
* empty vector is returned. If document name is "*", then all document is
|
||||
* considered.
|
||||
* @param typeId: specify the type of object to be returned.
|
||||
* @param resolve: whether to resolve the subname reference of the selection
|
||||
* @param single: if set to true, then it will return an empty vector if
|
||||
* there is more than one selections.
|
||||
*
|
||||
* @return The returned vector reflects the sequence of selection.
|
||||
*/
|
||||
std::vector<Gui::SelectionObject> getSelectionEx(const char* pDocName=0,Base::Type typeId=App::DocumentObject::getClassTypeId()) const;
|
||||
std::vector<Gui::SelectionObject> getSelectionEx(const char* pDocName=0,Base::Type typeId=App::DocumentObject::getClassTypeId(),int resolve=1, bool single=false) const;
|
||||
|
||||
/**
|
||||
* @brief getAsPropertyLinkSubList fills PropertyLinkSubList with current selection.
|
||||
@@ -318,15 +503,29 @@ public:
|
||||
int getAsPropertyLinkSubList(App::PropertyLinkSubList &prop) const;
|
||||
|
||||
/** Returns a vector of all selection objects of all documents. */
|
||||
std::vector<SelObj> getCompleteSelection() const;
|
||||
std::vector<SelObj> getCompleteSelection(int resolve=1) const;
|
||||
bool hasSelection() const;
|
||||
bool hasSelection(const char* doc) const;
|
||||
bool hasSelection(const char* doc, bool resolve=true) const;
|
||||
bool hasSubSelection(const char *doc=0) const;
|
||||
bool hasPreselection() const;
|
||||
|
||||
/// Size of selected entities for all documents
|
||||
unsigned int size(void) const {
|
||||
return static_cast<unsigned int>(_SelList.size());
|
||||
}
|
||||
|
||||
int selStackBackSize() const {return _SelStackBack.size();}
|
||||
int selStackForwardSize() const {return _SelStackForward.size();}
|
||||
std::vector<Gui::SelectionObject> selStackGet(const char* pDocName=0,int resolve=1,int index=0) const;
|
||||
void selStackGoBack(int count=1);
|
||||
void selStackGoForward(int count=1);
|
||||
void selStackPush(bool clearForward=true, bool overwrite=false);
|
||||
|
||||
bool needPickedList() const;
|
||||
void enablePickedList(bool);
|
||||
bool hasPickedList() const;
|
||||
std::vector<SelectionSingleton::SelObj> getPickedList(const char* pDocName) const;
|
||||
std::vector<Gui::SelectionObject> getPickedListEx(const char* pDocName=0,Base::Type typeId=App::DocumentObject::getClassTypeId()) const;
|
||||
static SelectionSingleton& instance(void);
|
||||
static void destruct (void);
|
||||
friend class SelectionFilter;
|
||||
@@ -336,12 +535,13 @@ public:
|
||||
|
||||
protected:
|
||||
static PyObject *sAddSelection (PyObject *self,PyObject *args);
|
||||
static PyObject *sUpdateSelection (PyObject *self,PyObject *args);
|
||||
static PyObject *sRemoveSelection (PyObject *self,PyObject *args);
|
||||
static PyObject *sClearSelection (PyObject *self,PyObject *args);
|
||||
static PyObject *sIsSelected (PyObject *self,PyObject *args);
|
||||
static PyObject *sCountObjectsOfType (PyObject *self,PyObject *args);
|
||||
static PyObject *sGetSelection (PyObject *self,PyObject *args);
|
||||
static PyObject *sSetPreselection (PyObject *self,PyObject *args);
|
||||
static PyObject *sSetPreselection (PyObject *self,PyObject *args,PyObject *kwd);
|
||||
static PyObject *sGetPreselection (PyObject *self,PyObject *args);
|
||||
static PyObject *sRemPreselection (PyObject *self,PyObject *args);
|
||||
static PyObject *sGetCompleteSelection(PyObject *self,PyObject *args);
|
||||
@@ -351,6 +551,14 @@ protected:
|
||||
static PyObject *sRemSelObserver (PyObject *self,PyObject *args);
|
||||
static PyObject *sAddSelectionGate (PyObject *self,PyObject *args);
|
||||
static PyObject *sRemoveSelectionGate (PyObject *self,PyObject *args);
|
||||
static PyObject *sGetPickedList (PyObject *self,PyObject *args);
|
||||
static PyObject *sEnablePickedList (PyObject *self,PyObject *args);
|
||||
static PyObject *sPreselect (PyObject *self,PyObject *args);
|
||||
static PyObject *sSetVisible (PyObject *self,PyObject *args);
|
||||
static PyObject *sPushSelStack (PyObject *self,PyObject *args);
|
||||
static PyObject *sHasSelection (PyObject *self,PyObject *args);
|
||||
static PyObject *sHasSubSelection (PyObject *self,PyObject *args);
|
||||
static PyObject *sGetSelectionFromStack(PyObject *self,PyObject *args);
|
||||
|
||||
protected:
|
||||
/// Construction
|
||||
@@ -364,8 +572,16 @@ protected:
|
||||
/// helper to retrieve document by name
|
||||
App::Document* getDocument(const char* pDocName=0) const;
|
||||
|
||||
void slotSelectionChanged(const SelectionChanges& msg);
|
||||
|
||||
SelectionChanges CurrentPreselection;
|
||||
|
||||
std::deque<SelectionChanges> NotificationQueue;
|
||||
bool Notifying = false;
|
||||
|
||||
void notify(SelectionChanges &&Chng);
|
||||
void notify(const SelectionChanges &Chng) { notify(SelectionChanges(Chng)); }
|
||||
|
||||
struct _SelObj {
|
||||
std::string DocName;
|
||||
std::string FeatName;
|
||||
@@ -374,8 +590,29 @@ protected:
|
||||
App::Document* pDoc;
|
||||
App::DocumentObject* pObject;
|
||||
float x,y,z;
|
||||
bool logged = false;
|
||||
|
||||
std::pair<std::string,std::string> elementName;
|
||||
App::DocumentObject* pResolvedObject = 0;
|
||||
|
||||
void log(bool remove=false, bool clearPreselect=true);
|
||||
};
|
||||
std::list<_SelObj> _SelList;
|
||||
mutable std::list<_SelObj> _SelList;
|
||||
|
||||
mutable std::list<_SelObj> _PickedList;
|
||||
bool _needPickedList;
|
||||
|
||||
typedef std::set<std::array<std::string,3> > SelStackItem;
|
||||
std::deque<SelStackItem> _SelStackBack;
|
||||
std::deque<SelStackItem> _SelStackForward;
|
||||
|
||||
int checkSelection(const char *pDocName, const char *pObjectName,
|
||||
const char *pSubName,int resolve, _SelObj &sel, const std::list<_SelObj> *selList=0) const;
|
||||
|
||||
std::vector<Gui::SelectionObject> getObjectList(const char* pDocName,Base::Type typeId, std::list<_SelObj> &objs, int resolve, bool single=false) const;
|
||||
|
||||
static App::DocumentObject *getObjectOfType(_SelObj &sel, Base::Type type,
|
||||
int resolve, const char **subelement=0);
|
||||
|
||||
static SelectionSingleton* _pcSingleton;
|
||||
|
||||
@@ -385,16 +622,20 @@ protected:
|
||||
float hx,hy,hz;
|
||||
|
||||
Gui::SelectionGate *ActiveGate;
|
||||
int gateResolve;
|
||||
|
||||
int logDisabled = 0;
|
||||
bool logHasSelection = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* A convenience template-based method that returns an array with the correct types already.
|
||||
*/
|
||||
template<typename T>
|
||||
inline std::vector<T*> SelectionSingleton::getObjectsOfType(const char* pDocName) const
|
||||
inline std::vector<T*> SelectionSingleton::getObjectsOfType(const char* pDocName, int resolve) const
|
||||
{
|
||||
std::vector<T*> type;
|
||||
std::vector<App::DocumentObject*> obj = this->getObjectsOfType(T::getClassTypeId(), pDocName);
|
||||
std::vector<App::DocumentObject*> obj = this->getObjectsOfType(T::getClassTypeId(), pDocName, resolve);
|
||||
type.reserve(obj.size());
|
||||
for (std::vector<App::DocumentObject*>::iterator it = obj.begin(); it != obj.end(); ++it)
|
||||
type.push_back(static_cast<T*>(*it));
|
||||
@@ -407,6 +648,18 @@ inline SelectionSingleton& Selection(void)
|
||||
return SelectionSingleton::instance();
|
||||
}
|
||||
|
||||
class GuiExport SelectionLogDisabler {
|
||||
public:
|
||||
SelectionLogDisabler(bool silent=false) :silent(silent) {
|
||||
Selection().disableCommandLog();
|
||||
}
|
||||
~SelectionLogDisabler() {
|
||||
Selection().enableCommandLog(silent);
|
||||
}
|
||||
private:
|
||||
bool silent;
|
||||
};
|
||||
|
||||
} //namespace Gui
|
||||
|
||||
#endif // GUI_SELECTION_H
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "SelectionObject.h"
|
||||
#include "Selection.h"
|
||||
#include "Application.h"
|
||||
#include "Command.h"
|
||||
#include <Gui/SelectionObjectPy.h>
|
||||
|
||||
using namespace Gui;
|
||||
@@ -94,22 +95,12 @@ bool SelectionObject::isObjectTypeOf(const Base::Type& typeId) const
|
||||
|
||||
std::string SelectionObject::getAsPropertyLinkSubString(void)const
|
||||
{
|
||||
std::string buf;
|
||||
buf += "(App.";
|
||||
buf += "ActiveDocument";//getObject()->getDocument()->getName();
|
||||
buf += ".";
|
||||
buf += getObject()->getNameInDocument();
|
||||
buf += ",[";
|
||||
for(std::vector<std::string>::const_iterator it = SubNames.begin();it!=SubNames.end();++it){
|
||||
buf += "\"";
|
||||
buf += *it;
|
||||
buf += "\"";
|
||||
if(it != --SubNames.end())
|
||||
buf += ",";
|
||||
}
|
||||
buf += "])";
|
||||
|
||||
return buf;
|
||||
std::ostringstream str;
|
||||
str << "(" << Gui::Command::getObjectCmd(getObject()) << ",[";
|
||||
for(std::vector<std::string>::const_iterator it = SubNames.begin();it!=SubNames.end();++it)
|
||||
str << "'" << *it << "',";
|
||||
str << "])";
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject* SelectionObject::getPyObject()
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
/*! Constructs a SelectionObject from the SelectionChanges structure.
|
||||
*/
|
||||
SelectionObject(const SelectionChanges& msg);
|
||||
SelectionObject(App::DocumentObject*);
|
||||
explicit SelectionObject(App::DocumentObject*);
|
||||
virtual ~SelectionObject();
|
||||
/**
|
||||
* The default implementation returns an instance of @ref SelectionObjectPy.
|
||||
@@ -89,6 +89,9 @@ protected:
|
||||
std::string TypeName;
|
||||
std::vector<Base::Vector3d> SelPoses;
|
||||
|
||||
private:
|
||||
/// to make sure no duplicates of subnames
|
||||
std::set<std::string> _SubNameSet;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -110,7 +110,14 @@ Py::Object SelectionObjectPy::getObject(void) const
|
||||
|
||||
Py::Tuple SelectionObjectPy::getSubObjects(void) const
|
||||
{
|
||||
std::vector<PyObject *> objs = getSelectionObjectPtr()->getObject()->getPySubObjects(getSelectionObjectPtr()->getSubNames());
|
||||
std::vector<PyObject *> objs;
|
||||
|
||||
for(const auto &subname : getSelectionObjectPtr()->getSubNames()) {
|
||||
PyObject *pyObj=0;
|
||||
Base::Matrix4D mat;
|
||||
getSelectionObjectPtr()->getObject()->getSubObject(subname.c_str(),&pyObj,&mat);
|
||||
if(pyObj) objs.push_back(pyObj);
|
||||
}
|
||||
|
||||
Py::Tuple temp(objs.size());
|
||||
Py::sequence_index_type index = 0;
|
||||
|
||||
@@ -29,11 +29,13 @@
|
||||
# include <QLineEdit>
|
||||
# include <QTextStream>
|
||||
# include <QToolButton>
|
||||
#include <QCheckBox>
|
||||
# include <QMenu>
|
||||
# include <QLabel>
|
||||
#endif
|
||||
|
||||
/// Here the FreeCAD includes sorted by Base,App,Gui......
|
||||
#include <Base/Console.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/GeoFeature.h>
|
||||
#include "SelectionView.h"
|
||||
@@ -43,7 +45,7 @@
|
||||
#include "ViewProvider.h"
|
||||
#include "BitmapFactory.h"
|
||||
|
||||
|
||||
FC_LOG_LEVEL_INIT("Selection",true,true,true)
|
||||
|
||||
using namespace Gui;
|
||||
using namespace Gui::DockWnd;
|
||||
@@ -53,6 +55,7 @@ using namespace Gui::DockWnd;
|
||||
|
||||
SelectionView::SelectionView(Gui::Document* pcDocument, QWidget *parent)
|
||||
: DockWindow(pcDocument,parent)
|
||||
, SelectionObserver(false,0)
|
||||
{
|
||||
setWindowTitle(tr("Selection View"));
|
||||
|
||||
@@ -85,27 +88,45 @@ SelectionView::SelectionView(Gui::Document* pcDocument, QWidget *parent)
|
||||
selectionView = new QListWidget(this);
|
||||
selectionView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
vLayout->addWidget( selectionView );
|
||||
|
||||
enablePickList = new QCheckBox(this);
|
||||
enablePickList->setText(tr("Picked object list"));
|
||||
vLayout->addWidget(enablePickList);
|
||||
pickList = new QListWidget(this);
|
||||
pickList->setVisible(false);
|
||||
vLayout->addWidget(pickList);
|
||||
|
||||
#if QT_VERSION >= 0x040200
|
||||
selectionView->setMouseTracking(true); // needed for itemEntered() to work
|
||||
pickList->setMouseTracking(true);
|
||||
#endif
|
||||
|
||||
resize(200, 200);
|
||||
|
||||
connect(clearButton, SIGNAL(clicked()), searchBox, SLOT(clear()));
|
||||
connect(searchBox, SIGNAL(textChanged(QString)), this, SLOT(search(QString)));
|
||||
connect(searchBox, SIGNAL(editingFinished()), this, SLOT(validateSearch()));
|
||||
connect(selectionView, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(select(QListWidgetItem*)));
|
||||
connect(selectionView, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(toggleSelect(QListWidgetItem*)));
|
||||
connect(selectionView, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(preselect(QListWidgetItem*)));
|
||||
connect(pickList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(toggleSelect(QListWidgetItem*)));
|
||||
connect(pickList, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(preselect(QListWidgetItem*)));
|
||||
connect(selectionView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onItemContextMenu(QPoint)));
|
||||
connect(enablePickList, SIGNAL(stateChanged(int)), this, SLOT(onEnablePickList()));
|
||||
|
||||
Gui::Selection().Attach(this);
|
||||
}
|
||||
|
||||
SelectionView::~SelectionView()
|
||||
{
|
||||
Gui::Selection().Detach(this);
|
||||
}
|
||||
|
||||
void SelectionView::leaveEvent(QEvent *)
|
||||
{
|
||||
Selection().rmvPreselect();
|
||||
}
|
||||
|
||||
/// @cond DOXERR
|
||||
void SelectionView::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
|
||||
Gui::SelectionSingleton::MessageType Reason)
|
||||
void SelectionView::onSelectionChanged(const SelectionChanges &Reason)
|
||||
{
|
||||
Q_UNUSED(rCaller);
|
||||
QString selObject;
|
||||
QTextStream str(&selObject);
|
||||
if (Reason.Type == SelectionChanges::AddSelection) {
|
||||
@@ -116,16 +137,17 @@ void SelectionView::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
|
||||
|
||||
// insert the selection as item
|
||||
str << Reason.pDocName;
|
||||
str << ".";
|
||||
str << "#";
|
||||
str << Reason.pObjectName;
|
||||
App::Document* doc = App::GetApplication().getDocument(Reason.pDocName);
|
||||
App::DocumentObject* obj = doc->getObject(Reason.pObjectName);
|
||||
if (Reason.pSubName[0] != 0 ) {
|
||||
str << ".";
|
||||
str << Reason.pSubName;
|
||||
list << QString::fromLatin1(Reason.pSubName);
|
||||
auto subObj = obj->getSubObject(Reason.pSubName);
|
||||
if(subObj)
|
||||
obj = subObj;
|
||||
}
|
||||
|
||||
App::Document* doc = App::GetApplication().getDocument(Reason.pDocName);
|
||||
App::DocumentObject* obj = doc->getObject(Reason.pObjectName);
|
||||
str << " (";
|
||||
str << QString::fromUtf8(obj->Label.getValue());
|
||||
str << ")";
|
||||
@@ -134,26 +156,31 @@ void SelectionView::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
|
||||
item->setData(Qt::UserRole, list);
|
||||
}
|
||||
else if (Reason.Type == SelectionChanges::ClrSelection) {
|
||||
// remove all items
|
||||
selectionView->clear();
|
||||
if(!Reason.pDocName[0]) {
|
||||
// remove all items
|
||||
selectionView->clear();
|
||||
}else{
|
||||
// build name
|
||||
str << Reason.pDocName;
|
||||
str << "#";
|
||||
// remove all items
|
||||
for(auto item : selectionView->findItems(selObject,Qt::MatchStartsWith))
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
else if (Reason.Type == SelectionChanges::RmvSelection) {
|
||||
// build name
|
||||
str << Reason.pDocName;
|
||||
str << ".";
|
||||
str << "#";
|
||||
str << Reason.pObjectName;
|
||||
if (Reason.pSubName[0] != 0) {
|
||||
str << ".";
|
||||
str << Reason.pSubName;
|
||||
}
|
||||
App::Document* doc = App::GetApplication().getDocument(Reason.pDocName);
|
||||
App::DocumentObject* obj = doc->getObject(Reason.pObjectName);
|
||||
str << " (";
|
||||
str << QString::fromUtf8(obj->Label.getValue());
|
||||
str << ")";
|
||||
|
||||
// remove all items
|
||||
QList<QListWidgetItem *> l = selectionView->findItems(selObject,Qt::MatchExactly);
|
||||
QList<QListWidgetItem *> l = selectionView->findItems(selObject,Qt::MatchStartsWith);
|
||||
if (l.size() == 1)
|
||||
delete l[0];
|
||||
|
||||
@@ -161,7 +188,7 @@ void SelectionView::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
|
||||
else if (Reason.Type == SelectionChanges::SetSelection) {
|
||||
// remove all items
|
||||
selectionView->clear();
|
||||
std::vector<SelectionSingleton::SelObj> objs = Gui::Selection().getSelection(Reason.pDocName);
|
||||
std::vector<SelectionSingleton::SelObj> objs = Gui::Selection().getSelection(Reason.pDocName,0);
|
||||
for (std::vector<SelectionSingleton::SelObj>::iterator it = objs.begin(); it != objs.end(); ++it) {
|
||||
// save as user data
|
||||
QStringList list;
|
||||
@@ -170,16 +197,17 @@ void SelectionView::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
|
||||
|
||||
// build name
|
||||
str << it->DocName;
|
||||
str << ".";
|
||||
str << "#";
|
||||
str << it->FeatName;
|
||||
App::Document* doc = App::GetApplication().getDocument(it->DocName);
|
||||
App::DocumentObject* obj = doc->getObject(it->FeatName);
|
||||
if (it->SubName && it->SubName[0] != '\0') {
|
||||
str << ".";
|
||||
str << it->SubName;
|
||||
list << QString::fromLatin1(it->SubName);
|
||||
auto subObj = obj->getSubObject(Reason.pSubName);
|
||||
if(subObj)
|
||||
obj = subObj;
|
||||
}
|
||||
|
||||
App::Document* doc = App::GetApplication().getDocument(it->DocName);
|
||||
App::DocumentObject* obj = doc->getObject(it->FeatName);
|
||||
str << " (";
|
||||
str << QString::fromUtf8(obj->Label.getValue());
|
||||
str << ")";
|
||||
@@ -189,6 +217,43 @@ void SelectionView::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
|
||||
selObject.clear();
|
||||
}
|
||||
}
|
||||
else if (Reason.Type == SelectionChanges::PickedListChanged) {
|
||||
bool picking = Selection().needPickedList();
|
||||
enablePickList->setChecked(picking);
|
||||
pickList->setVisible(picking);
|
||||
pickList->clear();
|
||||
if(picking) {
|
||||
const auto &sels = Selection().getPickedList(Reason.pDocName);
|
||||
for(const auto &sel : sels) {
|
||||
App::Document* doc = App::GetApplication().getDocument(sel.DocName);
|
||||
if(!doc) continue;
|
||||
App::DocumentObject* obj = doc->getObject(sel.FeatName);
|
||||
if(!obj) continue;
|
||||
|
||||
QString selObject;
|
||||
QTextStream str(&selObject);
|
||||
str << sel.DocName;
|
||||
str << "#";
|
||||
str << sel.FeatName;
|
||||
if (sel.SubName[0] != 0 ) {
|
||||
str << ".";
|
||||
str << sel.SubName;
|
||||
auto subObj = obj->getSubObject(sel.SubName);
|
||||
if(subObj)
|
||||
obj = subObj;
|
||||
}
|
||||
str << " (";
|
||||
str << QString::fromUtf8(obj->Label.getValue());
|
||||
str << ")";
|
||||
|
||||
this->x = sel.x;
|
||||
this->y = sel.y;
|
||||
this->z = sel.z;
|
||||
|
||||
new QListWidgetItem(selObject, pickList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
countLabel->setText(QString::number(selectionView->count()));
|
||||
}
|
||||
@@ -213,8 +278,8 @@ void SelectionView::search(const QString& text)
|
||||
list << QString::fromLatin1(doc->getName());
|
||||
list << QString::fromLatin1((*it)->getNameInDocument());
|
||||
// build name
|
||||
str << doc->getName();
|
||||
str << ".";
|
||||
str << QString::fromUtf8(doc->Label.getValue());
|
||||
str << "#";
|
||||
str << (*it)->getNameInDocument();
|
||||
str << " (";
|
||||
str << label;
|
||||
@@ -235,9 +300,7 @@ void SelectionView::validateSearch(void)
|
||||
if (doc) {
|
||||
Gui::Selection().clearSelection();
|
||||
for (std::vector<App::DocumentObject*>::iterator it = searchList.begin(); it != searchList.end(); ++it) {
|
||||
if (!Gui::Selection().hasSelection((*it)->getNameInDocument())) {
|
||||
Gui::Selection().addSelection(doc->getName(),(*it)->getNameInDocument(),0);
|
||||
}
|
||||
Gui::Selection().addSelection(doc->getName(),(*it)->getNameInDocument(),0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,11 +316,15 @@ void SelectionView::select(QListWidgetItem* item)
|
||||
if (elements.size() < 2)
|
||||
return;
|
||||
|
||||
//Gui::Selection().clearSelection();
|
||||
Gui::Command::runCommand(Gui::Command::Gui,"Gui.Selection.clearSelection()");
|
||||
//Gui::Selection().addSelection(elements[0].toLatin1(),elements[1].toLatin1(),0);
|
||||
QString cmd = QString::fromLatin1("Gui.Selection.addSelection(App.getDocument(\"%1\").getObject(\"%2\"))").arg(elements[0], elements[1]);
|
||||
Gui::Command::runCommand(Gui::Command::Gui,cmd.toLatin1());
|
||||
try {
|
||||
//Gui::Selection().clearSelection();
|
||||
Gui::Command::runCommand(Gui::Command::Gui,"Gui.Selection.clearSelection()");
|
||||
//Gui::Selection().addSelection(elements[0].toLatin1(),elements[1].toLatin1(),0);
|
||||
QString cmd = QString::fromLatin1("Gui.Selection.addSelection(App.getDocument(\"%1\").getObject(\"%2\"))").arg(elements[0],elements[1]);
|
||||
Gui::Command::runCommand(Gui::Command::Gui,cmd.toLatin1());
|
||||
}catch(Base::Exception &e) {
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionView::deselect(void)
|
||||
@@ -270,20 +337,99 @@ void SelectionView::deselect(void)
|
||||
return;
|
||||
|
||||
//Gui::Selection().rmvSelection(elements[0].toLatin1(),elements[1].toLatin1(),0);
|
||||
QString cmd = QString::fromLatin1("Gui.Selection.removeSelection(App.getDocument(\"%1\").getObject(\"%2\"))").arg(elements[0], elements[1]);
|
||||
Gui::Command::runCommand(Gui::Command::Gui,cmd.toLatin1());
|
||||
QString cmd = QString::fromLatin1("Gui.Selection.removeSelection(App.getDocument(\"%1\").getObject(\"%2\"))").arg(elements[0],elements[1]);
|
||||
try {
|
||||
Gui::Command::runCommand(Gui::Command::Gui,cmd.toLatin1());
|
||||
}catch(Base::Exception &e) {
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionView::toggleSelect(QListWidgetItem* item)
|
||||
{
|
||||
if (!item) return;
|
||||
std::string name = item->text().toLatin1().constData();
|
||||
char *docname = &name.at(0);
|
||||
char *objname = std::strchr(docname,'#');
|
||||
if(!objname) return;
|
||||
*objname++ = 0;
|
||||
char *subname = std::strchr(objname,'.');
|
||||
if(subname) {
|
||||
*subname++ = 0;
|
||||
char *end = std::strchr(subname,' ');
|
||||
if(end) *end = 0;
|
||||
}else {
|
||||
char *end = std::strchr(objname,' ');
|
||||
if(end) *end = 0;
|
||||
}
|
||||
QString cmd;
|
||||
if(Gui::Selection().isSelected(docname,objname,subname))
|
||||
cmd = QString::fromLatin1("Gui.Selection.removeSelection("
|
||||
"App.getDocument('%1').getObject('%2'),'%3')")
|
||||
.arg(QString::fromLatin1(docname))
|
||||
.arg(QString::fromLatin1(objname))
|
||||
.arg(QString::fromLatin1(subname));
|
||||
else
|
||||
cmd = QString::fromLatin1("Gui.Selection.addSelection("
|
||||
"App.getDocument('%1').getObject('%2'),'%3',%4,%5,%6)")
|
||||
.arg(QString::fromLatin1(docname))
|
||||
.arg(QString::fromLatin1(objname))
|
||||
.arg(QString::fromLatin1(subname))
|
||||
.arg(x).arg(y).arg(z);
|
||||
try {
|
||||
Gui::Command::runCommand(Gui::Command::Gui,cmd.toLatin1());
|
||||
}catch(Base::Exception &e) {
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionView::preselect(QListWidgetItem* item)
|
||||
{
|
||||
if (!item) return;
|
||||
std::string name = item->text().toLatin1().constData();
|
||||
char *docname = &name.at(0);
|
||||
char *objname = std::strchr(docname,'#');
|
||||
if(!objname) return;
|
||||
*objname++ = 0;
|
||||
char *subname = std::strchr(objname,'.');
|
||||
if(subname) {
|
||||
*subname++ = 0;
|
||||
char *end = std::strchr(subname,' ');
|
||||
if(end) *end = 0;
|
||||
}else {
|
||||
char *end = std::strchr(objname,' ');
|
||||
if(end) *end = 0;
|
||||
}
|
||||
QString cmd = QString::fromLatin1("Gui.Selection.setPreselection("
|
||||
"App.getDocument('%1').getObject('%2'),'%3',tp=2)")
|
||||
.arg(QString::fromLatin1(docname))
|
||||
.arg(QString::fromLatin1(objname))
|
||||
.arg(QString::fromLatin1(subname));
|
||||
try {
|
||||
Gui::Command::runCommand(Gui::Command::Gui,cmd.toLatin1());
|
||||
}catch(Base::Exception &e) {
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionView::zoom(void)
|
||||
{
|
||||
select();
|
||||
Gui::Command::runCommand(Gui::Command::Gui,"Gui.SendMsgToActiveView(\"ViewSelection\")");
|
||||
try {
|
||||
Gui::Command::runCommand(Gui::Command::Gui,"Gui.SendMsgToActiveView(\"ViewSelection\")");
|
||||
}catch(Base::Exception &e) {
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionView::treeSelect(void)
|
||||
{
|
||||
select();
|
||||
Gui::Command::runCommand(Gui::Command::Gui,"Gui.runCommand(\"Std_TreeSelection\")");
|
||||
try {
|
||||
Gui::Command::runCommand(Gui::Command::Gui,"Gui.runCommand(\"Std_TreeSelection\")");
|
||||
}catch(Base::Exception &e) {
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionView::touch(void)
|
||||
@@ -294,8 +440,12 @@ void SelectionView::touch(void)
|
||||
QStringList elements = item->data(Qt::UserRole).toStringList();
|
||||
if (elements.size() < 2)
|
||||
return;
|
||||
QString cmd = QString::fromLatin1("App.getDocument(\"%1\").getObject(\"%2\").touch()").arg(elements[0], elements[1]);
|
||||
Gui::Command::runCommand(Gui::Command::Doc,cmd.toLatin1());
|
||||
QString cmd = QString::fromLatin1("App.getDocument(\"%1\").getObject(\"%2\").touch()").arg(elements[0],elements[1]);
|
||||
try {
|
||||
Gui::Command::runCommand(Gui::Command::Doc,cmd.toLatin1());
|
||||
}catch(Base::Exception &e) {
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionView::toPython(void)
|
||||
@@ -455,6 +605,26 @@ bool SelectionView::onMsg(const char* /*pMsg*/,const char** /*ppReturn*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void SelectionView::hideEvent(QHideEvent *ev) {
|
||||
FC_TRACE(this << " detaching selection observer");
|
||||
this->detachSelection();
|
||||
DockWindow::hideEvent(ev);
|
||||
}
|
||||
|
||||
void SelectionView::showEvent(QShowEvent *ev) {
|
||||
FC_TRACE(this << " attaching selection observer");
|
||||
this->attachSelection();
|
||||
enablePickList->setChecked(Selection().needPickedList());
|
||||
Gui::DockWindow::showEvent(ev);
|
||||
}
|
||||
|
||||
void SelectionView::onEnablePickList() {
|
||||
bool enabled = enablePickList->isChecked();
|
||||
Selection().enablePickedList(enabled);
|
||||
pickList->setVisible(enabled);
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
|
||||
#include "moc_SelectionView.cpp"
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "Selection.h"
|
||||
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
class QCheckBox;
|
||||
class QLabel;
|
||||
|
||||
namespace App {
|
||||
@@ -42,7 +44,7 @@ namespace DockWnd {
|
||||
/** A test class. A more elaborate class description.
|
||||
*/
|
||||
class SelectionView : public Gui::DockWindow,
|
||||
public Gui::SelectionSingleton::ObserverType
|
||||
public Gui::SelectionObserver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -60,9 +62,9 @@ public:
|
||||
virtual ~SelectionView();
|
||||
|
||||
/// Observer message from the Selection
|
||||
virtual void OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
|
||||
Gui::SelectionSingleton::MessageType Reason);
|
||||
virtual void onSelectionChanged(const SelectionChanges& msg);
|
||||
|
||||
virtual void leaveEvent(QEvent*) override;
|
||||
|
||||
bool onMsg(const char* pMsg,const char** ppReturn);
|
||||
|
||||
@@ -74,6 +76,9 @@ public:
|
||||
QListWidget* selectionView;
|
||||
QLabel* countLabel;
|
||||
|
||||
QCheckBox *enablePickList;
|
||||
QListWidget *pickList;
|
||||
|
||||
public Q_SLOTS:
|
||||
/// get called when text is entered in the search box
|
||||
void search(const QString& text);
|
||||
@@ -89,11 +94,21 @@ public Q_SLOTS:
|
||||
void toPython(void);
|
||||
void touch(void);
|
||||
void showPart(void);
|
||||
void onEnablePickList();
|
||||
void toggleSelect(QListWidgetItem* item=0);
|
||||
void preselect(QListWidgetItem* item=0);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *) override;
|
||||
void hideEvent(QHideEvent *) override;
|
||||
|
||||
private:
|
||||
QString getModule(const char* type) const;
|
||||
QString getProperty(App::DocumentObject* obj) const;
|
||||
bool supportPart(App::DocumentObject* obj, const QString& part) const;
|
||||
|
||||
private:
|
||||
float x,y,z;
|
||||
std::vector<App::DocumentObject*> searchList;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user