Scope the selection per document

This commit is contained in:
theo-vt
2026-02-22 11:37:16 -05:00
parent d59471b6bd
commit 3076ce66be
3 changed files with 469 additions and 335 deletions
File diff suppressed because it is too large Load Diff
+56 -51
View File
@@ -284,7 +284,6 @@ public:
* literal into QT_TR_NOOP() for translatability.
*/
std::string notAllowedReason;
ResolveMode resolveMode;
};
/** SelectionGateFilterExternal
@@ -383,7 +382,7 @@ public:
/// of the active document is cleared.
void clearSelection(const char* pDocName = nullptr, bool clearPreSelect = true);
/// Clear the selection of all documents
void clearCompleteSelection(bool clearPreSelect = true);
void clearCompleteSelection(const char* pDocName = nullptr, bool clearPreSelect = true);
/// Check if selected
bool isSelected(
const char* pDocName,
@@ -505,8 +504,9 @@ public:
/** Set selection object visibility
*
* @param visible: see VisibleState
* @param pDocName: name of the document that scopes the request, defaults to active document
*/
void setVisible(VisibleState visible);
void setVisible(VisibleState visible, const char* pDocName = nullptr);
bool isClarifySelectionActive();
void setClarifySelectionActive(bool active);
@@ -590,7 +590,7 @@ public:
std::vector<SelObj> getCompleteSelection(ResolveMode resolve = ResolveMode::OldStyleElement) const;
/// Check if there is any selection
bool hasSelection() const;
bool hasSelection(const char* pDocName = nullptr) const;
/** Check if there is any selection within a given document
*
@@ -604,7 +604,7 @@ public:
* If \c resolve is false, then the match is only done with the top
* level parent object.
*/
bool hasSelection(const char* doc, ResolveMode resolve = ResolveMode::OldStyleElement) const;
bool hasSelection(const char* doc, ResolveMode resolve) const;
/** Check if there is any sub-element selection
*
@@ -621,10 +621,7 @@ public:
bool hasPreselection() const;
/// Size of selected entities for all documents
unsigned int size() const
{
return static_cast<unsigned int>(_SelList.size());
}
unsigned int size(const char* pDocName = nullptr) const;
/** @name Selection stack functions
*
@@ -633,16 +630,10 @@ public:
*/
//@{
/// Return the current selection stack size
std::size_t selStackBackSize() const
{
return _SelStackBack.size();
}
std::size_t selStackBackSize(const char* pDocName = nullptr) const;
/// Return the current forward selection stack size
std::size_t selStackForwardSize() const
{
return _SelStackForward.size();
}
std::size_t selStackForwardSize(const char* pDocName = nullptr) const;
/** Obtain selected objects from stack
*
@@ -660,28 +651,31 @@ public:
/** Go back selection history
*
* @param count: optional number of steps to go back
* @param pDocName: the name of the document to index the context, defaults to active document
*
* This function pops the selection stack, and populate the current
* selection with the content of the last pop'd entry
*/
void selStackGoBack(int count = 1);
void selStackGoBack(int count = 1, const char* pDocName = nullptr);
/** Go forward selection history
*
* @param count: optional number of steps to go back
* @param pDocName: the name of the document to index the context, defaults to active document
*
* This function pops the selection stack, and populate the current
* selection with the content of the last pop'd entry
*/
void selStackGoForward(int count = 1);
void selStackGoForward(int count = 1, const char* pDocName = nullptr);
/** Save the current selection on to the stack
*
* @param clearForward: whether to clear forward selection stack
* @param overwrite: whether to overwrite the current top entry of the
* stack instead of pushing a new entry.
* @param pDocName: the name of the document to index the context, defaults to active document
*/
void selStackPush(bool clearForward = true, bool overwrite = false);
void selStackPush(bool clearForward = true, bool overwrite = false, const char* pDocName = nullptr);
//@}
/** @name Picked list functions
@@ -692,11 +686,11 @@ public:
*/
//@{
/// Check whether picked list is enabled
bool needPickedList() const;
bool needPickedList(const char* pDocName = nullptr) const;
/// Turn on or off picked list
void enablePickedList(bool);
void enablePickedList(bool, const char* pDocName = nullptr);
/// Check if there is any selection inside picked list
bool hasPickedList() const;
bool hasPickedList(const char* pDocName = nullptr) const;
/// Return select objects inside picked list
std::vector<SelectionSingleton::SelObj> getPickedList(const char* pDocName) const;
/// Return selected object inside picked list grouped by top level parents
@@ -718,9 +712,9 @@ public:
GreedySelection
};
/// Changes the style of selection between greedy and normal.
void setSelectionStyle(SelectionStyle selStyle);
void setSelectionStyle(SelectionStyle selStyle, const char* pDocName = nullptr);
/// Get the style of selection.
SelectionStyle getSelectionStyle();
SelectionStyle getSelectionStyle(const char* pDocName = nullptr);
//@}
static SelectionSingleton& instance();
@@ -766,24 +760,20 @@ protected:
/// Observer message from the App doc
void slotDeletedObject(const App::DocumentObject&);
void slotClosedDocument(const App::Document&);
/// helper to retrieve document by name
App::Document* getDocument(const char* pDocName = nullptr) 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
struct SelectionDescription
{
std::string DocName;
std::string FeatName;
@@ -802,34 +792,26 @@ protected:
void log(bool remove = false, bool clearPreselect = true);
std::string getSubString() const;
};
mutable std::list<_SelObj> _SelList;
mutable std::list<_SelObj> _PickedList;
bool _needPickedList {false};
using SelStackItem = std::set<App::SubObjectT>;
std::deque<SelStackItem> _SelStackBack;
std::deque<SelStackItem> _SelStackForward;
int checkSelection(
const char* pDocName,
const char* pObjectName,
const char* pSubName,
ResolveMode resolve,
_SelObj& sel,
const std::list<_SelObj>* selList = nullptr
SelectionDescription& sel,
const std::list<SelectionDescription>* selList = nullptr
) const;
std::vector<Gui::SelectionObject> getObjectList(
const char* pDocName,
Base::Type typeId,
std::list<_SelObj>& objs,
const std::list<SelectionDescription>& objs,
ResolveMode resolve,
bool single = false
) const;
static App::DocumentObject* getObjectOfType(
_SelObj& sel,
const SelectionDescription& sel,
Base::Type type,
ResolveMode resolve,
const char** subelement = nullptr
@@ -841,23 +823,46 @@ protected:
ResolveMode resolve = ResolveMode::OldStyleElement
) const;
using SelStackItem = std::set<App::SubObjectT>;
// Each document has a description context
struct SelectionContext
{
Gui::SelectionGate* gate {nullptr};
ResolveMode resolveMode {ResolveMode::OldStyleElement};
std::list<SelectionDescription> selList;
std::list<SelectionDescription> pickedList;
bool needPickedList {false};
std::deque<SelStackItem> selStackBack;
std::deque<SelStackItem> selStackForward;
SelectionStyle selectionStyle {SelectionStyle::NormalSelection};
};
// Returns a selection context or nullptr if the document is not found
SelectionContext* getSelectionContext(const char* pDocName);
const SelectionContext* getSelectionContext(const char* pDocName) const;
static SelectionSingleton* _pcSingleton;
// each document can have at most 1 selection gate active
std::map<App::Document*, Gui::SelectionGate*> docSelectionGate;
// Preselection helpers - it's a mess
std::map<App::Document*, SelectionContext> docSelectionContext;
// Preselection helpers, it's a mess, needs clarifying -theo-vt
std::string DocName;
std::string FeatName;
std::string SubName;
float hx, hy, hz;
float hx {0.0f}, hy {0.0f}, hz {0.0f};
SelectionChanges CurrentPreselection;
int logDisabled = 0;
bool logHasSelection = false;
bool clarifySelectionActive = false;
int logDisabled {0};
bool logHasSelection {false};
bool clarifySelectionActive {false};
SelectionStyle selectionStyle;
std::deque<SelectionChanges> NotificationQueue;
bool Notifying {false};
};
/**
+1 -1
View File
@@ -3722,7 +3722,7 @@ void TreeWidget::scrollItemToTop()
continue;
}
auto doc = docItem->document()->getDocument();
if (Gui::Selection().hasSelection(doc->getName())) {
if (Gui::Selection().hasSelection(doc->getName(), ResolveMode::OldStyleElement)) {
tree->currentDocItem = docItem;
docItem->selectItems(DocumentItem::SR_FORCE_EXPAND);
tree->currentDocItem = nullptr;