diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index 139f76569a..5b1b0e2e9c 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -61,7 +61,8 @@ enum ObjectStatus { ObjImporting = 13, // Mark the object as importing NoTouch = 14, // no touch on any property change GeoExcluded = 15, // mark as a member but not claimed by GeoFeatureGroup - Expand = 16, + Expand = 16, // indicate the object's tree item expansion status + NoAutoExpand = 17, // disable tree item auto expand on selection for this object }; /** Return object for feature execution diff --git a/src/App/Origin.cpp b/src/App/Origin.cpp index 04cd559e2b..25b79d2ab3 100644 --- a/src/App/Origin.cpp +++ b/src/App/Origin.cpp @@ -51,6 +51,8 @@ const char* Origin::PlaneRoles[3] = {"XY_Plane", "XZ_Plane", "YZ_Plane"}; Origin::Origin(void) { ADD_PROPERTY_TYPE ( OriginFeatures, (0), 0, App::Prop_Hidden, "Axis and baseplanes controlled by the origin" ); + + setStatus(App::NoAutoExpand,true); } diff --git a/src/Gui/Tree.cpp b/src/Gui/Tree.cpp index 3178ece610..9aa9ebfa99 100644 --- a/src/Gui/Tree.cpp +++ b/src/Gui/Tree.cpp @@ -2405,7 +2405,7 @@ void TreeWidget::onUpdateStatus(void) currentDocItem = 0; for(auto &v : DocumentMap) { v.second->setSelected(false); - v.second->selectItems(false); + v.second->selectItems(); } this->blockConnection(false); } @@ -2533,7 +2533,7 @@ void TreeWidget::scrollItemToTop() auto it = tree->DocumentMap.find(doc); if (it != tree->DocumentMap.end()) { bool lock = tree->blockConnection(true); - it->second->selectItems(true); + it->second->selectItems(DocumentItem::SR_FORCE_EXPAND); tree->blockConnection(lock); } } else { @@ -2545,7 +2545,7 @@ void TreeWidget::scrollItemToTop() auto doc = docItem->document()->getDocument(); if(Gui::Selection().hasSelection(doc->getName())) { tree->currentDocItem = docItem; - docItem->selectItems(true); + docItem->selectItems(DocumentItem::SR_FORCE_EXPAND); tree->currentDocItem = 0; break; } @@ -2765,7 +2765,7 @@ void TreeWidget::onSelectTimer() { for(auto &v : DocumentMap) { v.second->setSelected(false); currentDocItem = v.second; - v.second->selectItems(syncSelect); + v.second->selectItems(syncSelect?DocumentItem::SR_EXPAND:DocumentItem::SR_SELECT); currentDocItem = 0; } }else{ @@ -4162,13 +4162,16 @@ DocumentObjectItem *DocumentItem::findItem( return res; } -void DocumentItem::selectItems(bool sync) { +void DocumentItem::selectItems(SelectionReason reason) { const auto &sels = Selection().getSelection(pDocument->getDocument()->getName(),false); + + bool sync = reason==SR_SELECT?false:true; + for(const auto &sel : sels) findItemByObject(sync,sel.pObject,sel.SubName,true); - DocumentObjectItem *first = 0; - DocumentObjectItem *last = 0; + DocumentObjectItem *newSelect = 0; + DocumentObjectItem *oldSelect = 0; FOREACH_ITEM_ALL(item) if(item->selected == 1) { @@ -4178,26 +4181,36 @@ void DocumentItem::selectItems(bool sync) { item->mySubs.clear(); item->setSelected(false); }else if(item->selected) { - if(item->selected == 2) { - // This means newly selected - if(!first) - first = item; - if(sync) - showItem(item,false,true); + if(sync) { + if(item->selected==2 && showItem(item,false,reason==SR_FORCE_EXPAND)) { + // This means newly selected and can auto expand + if(!newSelect) + newSelect = item; + } + if(!newSelect && !oldSelect && !item->isHidden()) { + bool visible = true; + for(auto parent=item->parent();parent;parent=parent->parent()) { + if(!parent->isExpanded() || parent->isHidden()) { + visible = false; + break; + } + } + if(visible) + oldSelect = item; + } } item->selected = 1; item->setSelected(true); - last = item; } END_FOREACH_ITEM; if(sync) { - if(!first) - first = last; + if(!newSelect) + newSelect = oldSelect; else - getTree()->syncView(first->object()); - if(first) - getTree()->scrollToItem(first); + getTree()->syncView(newSelect->object()); + if(newSelect) + getTree()->scrollToItem(newSelect); } } @@ -4273,12 +4286,19 @@ bool DocumentItem::showItem(DocumentObjectItem *item, bool select, bool force) { item->setHidden(false); } - if(parent->type()==TreeWidget::ObjectType && - !showItem(static_cast(parent),false)) - return false; + if(parent->type()==TreeWidget::ObjectType) { + if(!showItem(static_cast(parent),false)) + return false; + auto pitem = static_cast(parent); + if(force || !pitem->object()->getObject()->testStatus(App::NoAutoExpand)) + parent->setExpanded(true); + else if(!select) + return false; + }else + parent->setExpanded(true); - parent->setExpanded(true); - if(select) item->setSelected(true); + if(select) + item->setSelected(true); return true; } diff --git a/src/Gui/Tree.h b/src/Gui/Tree.h index 7066f2de86..d4fdeb3cd5 100644 --- a/src/Gui/Tree.h +++ b/src/Gui/Tree.h @@ -272,7 +272,14 @@ public: void updateSelection(QTreeWidgetItem *, bool unselect=false); void updateSelection(); void updateItemSelection(DocumentObjectItem *); - void selectItems(bool sync); + + enum SelectionReason { + SR_SELECT, // only select, no expansion + SR_EXPAND, // select and expand but respect ObjectStatus::NoAutoExpand + SR_FORCE_EXPAND, // select and force expansion + }; + void selectItems(SelectionReason reason=SR_SELECT); + void testStatus(void); void setData(int column, int role, const QVariant & value) override; void populateItem(DocumentObjectItem *item, bool refresh=false, bool delayUpdate=true);