Revert "Merge pull request #4626 from pavltom/GUI_TreeView_Item_Ordering"
This reverts commitc62239d0ba, reversing changes made tobef1df4d40. See forums discussion: https://forum.freecadweb.org/viewtopic.php?p=549120
This commit is contained in:
@@ -3684,116 +3684,6 @@ void StdTreeDrag::activated(int)
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_GroupMoveUp
|
||||
//===========================================================================
|
||||
DEF_STD_CMD_A(StdGroupMoveUp)
|
||||
|
||||
StdGroupMoveUp::StdGroupMoveUp()
|
||||
: Command("Std_GroupMoveUp")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Move up in group");
|
||||
sToolTipText = QT_TR_NOOP("Move object one place higher in its group");
|
||||
sStatusTip = sToolTipText;
|
||||
sWhatsThis = "Std_GroupMoveUp";
|
||||
sPixmap = "button_up";
|
||||
sAccel = "Alt+Up";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdGroupMoveUp::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
TreeWidget *tree = TreeWidget::instance();
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<DocumentObjectItem *> selected;
|
||||
if (!tree->getSelectedSiblingObjectItems(selected)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DocumentObjectItem *previous;
|
||||
if (!tree->allowMoveUpInGroup(selected, &previous)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TreeWidget::moveSiblings(selected, previous, -1);
|
||||
}
|
||||
|
||||
bool StdGroupMoveUp::isActive(void)
|
||||
{
|
||||
TreeWidget *tree = TreeWidget::instance();
|
||||
if (!tree) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<DocumentObjectItem *> selected;
|
||||
if (!tree->getSelectedSiblingObjectItems(selected)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tree->allowMoveUpInGroup(selected);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_GroupMoveDown
|
||||
//===========================================================================
|
||||
DEF_STD_CMD_A(StdGroupMoveDown)
|
||||
|
||||
StdGroupMoveDown::StdGroupMoveDown()
|
||||
: Command("Std_GroupMoveDown")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Move down in group");
|
||||
sToolTipText = QT_TR_NOOP("Move object one place lower in its group");
|
||||
sStatusTip = sToolTipText;
|
||||
sWhatsThis = "Std_GroupMoveDown";
|
||||
sPixmap = "button_down";
|
||||
sAccel = "Alt+Down";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdGroupMoveDown::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
TreeWidget *tree = TreeWidget::instance();
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<DocumentObjectItem *> selected;
|
||||
if (!tree->getSelectedSiblingObjectItems(selected)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DocumentObjectItem *next ;
|
||||
if (!tree->allowMoveDownInGroup(selected, &next)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TreeWidget::moveSiblings(selected, next, +1);
|
||||
}
|
||||
|
||||
bool StdGroupMoveDown::isActive(void)
|
||||
{
|
||||
TreeWidget *tree = TreeWidget::instance();
|
||||
if (!tree) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<DocumentObjectItem *> selected;
|
||||
if (!tree->getSelectedSiblingObjectItems(selected)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tree->allowMoveDownInGroup(selected);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Std_TreeViewActions
|
||||
//===========================================================================
|
||||
@@ -3828,11 +3718,6 @@ public:
|
||||
|
||||
addCommand(new StdTreeDrag(),cmds.size());
|
||||
addCommand(new StdTreeSelection(),cmds.size());
|
||||
|
||||
addCommand();
|
||||
|
||||
addCommand(new StdGroupMoveUp());
|
||||
addCommand(new StdGroupMoveDown());
|
||||
};
|
||||
virtual const char* className() const {return "StdCmdTreeViewActions";}
|
||||
};
|
||||
|
||||
@@ -727,9 +727,6 @@ void Document::slotNewObject(const App::DocumentObject& Obj)
|
||||
activeView->getViewer()->addViewProvider(pcProvider);
|
||||
}
|
||||
|
||||
// If no tree rank was assigned, do it now, otherwise keep the current one
|
||||
pcProvider->TreeRank.setValue(pcProvider->TreeRank.getValue());
|
||||
|
||||
// adding to the tree
|
||||
signalNewObject(*pcProvider);
|
||||
pcProvider->pcDocument = this;
|
||||
@@ -1438,29 +1435,13 @@ void Document::RestoreDocFile(Base::Reader &reader)
|
||||
expanded = true;
|
||||
}
|
||||
}
|
||||
|
||||
int rank = 0;
|
||||
if (localreader->hasAttribute("rank")) {
|
||||
rank = localreader->getAttributeAsInteger("rank");
|
||||
}
|
||||
|
||||
ViewProvider* pObj = getViewProviderByName(name.c_str());
|
||||
if (pObj) // check if this feature has been registered
|
||||
pObj->Restore(*localreader);
|
||||
|
||||
ViewProviderDocumentObject *vpdo = dynamic_cast<ViewProviderDocumentObject *>(pObj);
|
||||
if (vpdo) {
|
||||
if (rank <= 0 ) {
|
||||
// For backward compatibility, use object ID as tree rank
|
||||
rank = vpdo->getObject()->getID();
|
||||
}
|
||||
vpdo->TreeRank.setValue(rank);
|
||||
|
||||
if (expanded) {
|
||||
this->signalExpandObject(*vpdo, TreeItemMode::ExpandItem, 0, 0);
|
||||
}
|
||||
if (pObj && expanded) {
|
||||
Gui::ViewProviderDocumentObject* vp = static_cast<Gui::ViewProviderDocumentObject*>(pObj);
|
||||
this->signalExpandObject(*vp, TreeItemMode::ExpandItem,0,0);
|
||||
}
|
||||
|
||||
localreader->readEndElement("ViewProvider");
|
||||
}
|
||||
localreader->readEndElement("ViewProviderData");
|
||||
@@ -1580,11 +1561,6 @@ void Document::SaveDocFile (Base::Writer &writer) const
|
||||
if (obj->hasExtensions())
|
||||
writer.Stream() << " Extensions=\"True\"";
|
||||
|
||||
ViewProviderDocumentObject *vpdo = dynamic_cast<ViewProviderDocumentObject *>(obj);
|
||||
if (vpdo && vpdo->TreeRank.getValue()) {
|
||||
writer.Stream() << " rank=\"" << vpdo->TreeRank.getValue() << "\"";
|
||||
}
|
||||
|
||||
writer.Stream() << ">" << std::endl;
|
||||
obj->Save(writer);
|
||||
writer.Stream() << writer.ind() << "</ViewProvider>" << std::endl;
|
||||
|
||||
378
src/Gui/Tree.cpp
378
src/Gui/Tree.cpp
@@ -340,18 +340,8 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the child items by their tree rank
|
||||
std::stable_sort(newChildren.begin(), newChildren.end(),
|
||||
[this](App::DocumentObject *a, App::DocumentObject *b) {
|
||||
ViewProviderDocumentObject *vpa = this->docItem->getViewProvider(a);
|
||||
ViewProviderDocumentObject *vpb = this->docItem->getViewProvider(b);
|
||||
return vpa->TreeRank.getValue() < vpb->TreeRank.getValue();
|
||||
});
|
||||
|
||||
// Mark updated in case the order of the children did change
|
||||
// We still need to check the order of the children
|
||||
updated = updated || children!=newChildren;
|
||||
|
||||
children.swap(newChildren);
|
||||
childSet.swap(newSet);
|
||||
|
||||
@@ -565,9 +555,6 @@ TreeWidget::TreeWidget(const char *name, QWidget* parent)
|
||||
this, SLOT(onItemSelectionChanged()));
|
||||
connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
|
||||
this, SLOT(onItemChanged(QTreeWidgetItem*, int)));
|
||||
connect(MainWindow::getInstance(), SIGNAL(tabifiedDockWidgetActivated(QDockWidget *)),
|
||||
this, SLOT(onTabifiedDockWidgetActivated(QDockWidget *)));
|
||||
|
||||
connect(this->preselectTimer, SIGNAL(timeout()),
|
||||
this, SLOT(onPreSelectTimer()));
|
||||
connect(this->selectTimer, SIGNAL(timeout()),
|
||||
@@ -1400,17 +1387,6 @@ void TreeWidget::keyPressEvent(QKeyEvent *event)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (event->modifiers() == Qt::AltModifier
|
||||
&& (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)) {
|
||||
// Consume the Alt+Up/Down keypresses. This is because if the "Move Up/Down in Group"
|
||||
// key shortcut is inactive, they are interpreted as ordinary up/down single selection
|
||||
// move, which results in confusing behavior on item group borders crossing
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QTreeWidget::keyPressEvent(event);
|
||||
}
|
||||
|
||||
@@ -2361,10 +2337,6 @@ void TreeWidget::slotChangedViewObject(const Gui::ViewProvider& vp, const App::P
|
||||
ChangedObjects.emplace(vpd.getObject(),0);
|
||||
_updateStatus();
|
||||
}
|
||||
else if (&prop == &vpd.TreeRank) {
|
||||
ReorderedObjects.insert(vpd.getObject());
|
||||
_updateStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2526,47 +2498,6 @@ void TreeWidget::onUpdateStatus(void)
|
||||
}
|
||||
ChangedObjects.clear();
|
||||
|
||||
// Sort parents of object items with adjusted order
|
||||
std::set<QTreeWidgetItem *> reorderParents;
|
||||
for (auto &obj : ReorderedObjects) {
|
||||
ViewProvider *vp = Application::Instance->getViewProvider(obj);
|
||||
if (!vp || !vp->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto docIt = DocumentMap.find(static_cast<ViewProviderDocumentObject *>(vp)->getDocument());
|
||||
if (docIt == DocumentMap.end() || !docIt->second) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DocumentItem *docItem = docIt->second;
|
||||
auto parentIt = docItem->_ParentMap.find(obj);
|
||||
if (parentIt != docItem->_ParentMap.end() && parentIt->second.size() > 0) {
|
||||
for (App::DocumentObject *parent : parentIt->second) {
|
||||
auto dataIt = docItem->ObjectMap.find(parent);
|
||||
if (dataIt == docItem->ObjectMap.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (DocumentObjectItem *parentItem : dataIt->second->items) {
|
||||
reorderParents.insert(parentItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
reorderParents.insert(docItem);
|
||||
}
|
||||
}
|
||||
ReorderedObjects.clear();
|
||||
|
||||
if (!reorderParents.empty()) {
|
||||
for (QTreeWidgetItem *parentItem : reorderParents) {
|
||||
sortObjectItems(parentItem, [](const DocumentObjectItem *a, const DocumentObjectItem *b)
|
||||
{ return a->object()->TreeRank.getValue() < b->object()->TreeRank.getValue(); });
|
||||
}
|
||||
reorderParents.clear();
|
||||
}
|
||||
|
||||
FC_LOG("update item status");
|
||||
TimingInit();
|
||||
for (auto pos = DocumentMap.begin();pos!=DocumentMap.end();++pos) {
|
||||
@@ -2655,7 +2586,6 @@ void TreeWidget::onUpdateStatus(void)
|
||||
errItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
if(errItem)
|
||||
scrollToItem(errItem);
|
||||
|
||||
@@ -2690,27 +2620,6 @@ void TreeWidget::onItemEntered(QTreeWidgetItem * item)
|
||||
Selection().rmvPreselect();
|
||||
}
|
||||
|
||||
void TreeWidget::onTabifiedDockWidgetActivated(QDockWidget *dockWidget) {
|
||||
|
||||
QWidget *parent = this->parentWidget();
|
||||
while (parent) {
|
||||
if (parent == dockWidget) {
|
||||
this->setFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
parent = parent->parentWidget();
|
||||
}
|
||||
}
|
||||
|
||||
void TreeWidget::focusInEvent(QFocusEvent *event) {
|
||||
|
||||
_LastSelectedTreeWidget = this;
|
||||
Application::Instance->updateActions(true);
|
||||
|
||||
QTreeWidget::focusInEvent(event);
|
||||
}
|
||||
|
||||
void TreeWidget::leaveEvent(QEvent *) {
|
||||
if(!updateBlocked && TreeParams::Instance()->PreSelection()) {
|
||||
preselectTimer->stop();
|
||||
@@ -3057,209 +2966,6 @@ void TreeWidget::onSelectionChanged(const SelectionChanges& msg)
|
||||
}
|
||||
}
|
||||
|
||||
bool TreeWidget::getSelectedSiblingObjectItems(std::vector<DocumentObjectItem *> &items) const
|
||||
{
|
||||
QList<QTreeWidgetItem *> selected = this->selectedItems();
|
||||
if (selected.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selected.first()->type() != TreeWidget::ObjectType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *parentItem = selected.first()->parent();
|
||||
for (int i = 1; i < selected.size(); ++i) {
|
||||
if (selected[i]->type() != TreeWidget::ObjectType || selected[i]->parent() != parentItem) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
items.resize(items.size() + selected.size(), 0);
|
||||
std::transform(selected.begin(), selected.end(), items.end() - selected.size(),
|
||||
[](QTreeWidgetItem *i) { return static_cast<DocumentObjectItem *>(i); });
|
||||
std::sort(items.begin(), items.end(),
|
||||
[parentItem](DocumentObjectItem *a, DocumentObjectItem *b)
|
||||
{ return parentItem->indexOfChild(a) < parentItem->indexOfChild(b); });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TreeWidget::allowMoveUpInGroup(const std::vector<DocumentObjectItem *> &items, DocumentObjectItem **preceding) const
|
||||
{
|
||||
if (!items.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DocumentObjectItem *previous = items.front()->getPreviousSibling();
|
||||
if (!previous) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preceding) {
|
||||
*preceding = previous;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *parent = items.front()->parent();
|
||||
if (parent->type() == ObjectType) {
|
||||
ViewProviderDocumentObject *docObj = static_cast<DocumentObjectItem *>(parent)->object();
|
||||
if (!docObj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (DocumentObjectItem *item : items) {
|
||||
if (!docObj->allowTreeOrderSwap(item->object()->getObject(), previous->object()->getObject())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TreeWidget::allowMoveDownInGroup(const std::vector<DocumentObjectItem *> &items, DocumentObjectItem **succeeding) const
|
||||
{
|
||||
if (!items.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DocumentObjectItem *next = items.back()->getNextSibling();
|
||||
if (!next) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (succeeding) {
|
||||
*succeeding = next;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *parent = items.back()->parent();
|
||||
if (parent->type() == ObjectType) {
|
||||
ViewProviderDocumentObject *docObj = static_cast<DocumentObjectItem *>(parent)->object();
|
||||
if (!docObj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (DocumentObjectItem *item : items) {
|
||||
if (!docObj->allowTreeOrderSwap(item->object()->getObject(), next->object()->getObject())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TreeWidget::moveSiblings(const std::vector<DocumentObjectItem *> &items, DocumentObjectItem *pivot, int direction)
|
||||
{
|
||||
// Some sanity checks + make sure pivot is not within the items to be moved
|
||||
if (!items.size() || !pivot || !direction || std::find(items.begin(), items.end(), pivot) != items.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *parent = pivot->parent();
|
||||
if (!parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Gui::Document *doc = pivot->object()->getDocument();
|
||||
if (!doc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int childCount = parent->childCount();
|
||||
std::vector<DocumentObjectItem *> groupItems(childCount, 0);
|
||||
std::vector<long> ranks(childCount);
|
||||
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
QTreeWidgetItem *treeItem = parent->child(i);
|
||||
if (treeItem->type() != ObjectType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
groupItems[i] = static_cast<DocumentObjectItem *>(treeItem);
|
||||
ranks[i] = static_cast<DocumentObjectItem *>(treeItem)->object()->TreeRank.getValue();
|
||||
}
|
||||
|
||||
int insertIndex = parent->indexOfChild(pivot) + (direction > 0);
|
||||
for (DocumentObjectItem *item : items) {
|
||||
std::vector<DocumentObjectItem *>::iterator it = std::find(groupItems.begin(), groupItems.end(), item);
|
||||
if (it == groupItems.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int index = it - groupItems.begin();
|
||||
groupItems.erase(it);
|
||||
|
||||
if (index < insertIndex) {
|
||||
--insertIndex;
|
||||
}
|
||||
groupItems.insert(groupItems.begin() + insertIndex, item);
|
||||
++insertIndex;
|
||||
}
|
||||
|
||||
doc->openCommand(QT_TRANSLATE_NOOP("Command", direction > 0 ? "Move down in group" : "Move down in group"));
|
||||
|
||||
int changes = 0;
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
App::PropertyInteger &rank = groupItems[i]->object()->TreeRank;
|
||||
if (rank.getValue() != ranks[i]) {
|
||||
rank.setValue(ranks[i]);
|
||||
++changes;
|
||||
}
|
||||
}
|
||||
|
||||
return changes > 0;
|
||||
}
|
||||
|
||||
bool TreeWidget::sortObjectItems(QTreeWidgetItem *node, DocumentObjectItemComparator comparator)
|
||||
{
|
||||
if (!node || !comparator || node->childCount() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lock = blockConnection(true);
|
||||
|
||||
std::vector<DocumentObjectItem *> sortedItems;
|
||||
sortedItems.reserve(node->childCount());
|
||||
|
||||
for (int i = 0; i < node->childCount(); ++i) {
|
||||
QTreeWidgetItem *treeItem = node->child(i);
|
||||
if (treeItem->type() == TreeWidget::ObjectType) {
|
||||
sortedItems.push_back(static_cast<DocumentObjectItem *>(treeItem));
|
||||
}
|
||||
}
|
||||
|
||||
std::stable_sort(sortedItems.begin(), sortedItems.end(), comparator);
|
||||
|
||||
int sortedIndex = 0;
|
||||
int swaps = 0;
|
||||
for (int i = 0; i < node->childCount(); ++i) {
|
||||
QTreeWidgetItem *treeItem = node->child(i);
|
||||
if (treeItem->type() != TreeWidget::ObjectType) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DocumentObjectItem *sortedItem = sortedItems[sortedIndex++];
|
||||
if (sortedItem == treeItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<bool> expansion;
|
||||
sortedItem->getExpandedSnapshot(expansion);
|
||||
|
||||
node->removeChild(sortedItem);
|
||||
node->insertChild(i, sortedItem);
|
||||
++swaps;
|
||||
|
||||
std::vector<bool>::const_iterator expFrom = expansion.cbegin();
|
||||
sortedItem->applyExpandedSnapshot(expansion, expFrom);
|
||||
}
|
||||
|
||||
blockConnection(lock);
|
||||
|
||||
return swaps > 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* TRANSLATOR Gui::TreePanel */
|
||||
@@ -3566,7 +3272,7 @@ bool DocumentItem::createNewItem(const Gui::ViewProviderDocumentObject& obj,
|
||||
parent = this;
|
||||
data->rootItem = item;
|
||||
if(index<0)
|
||||
index = findRootIndex(&obj);
|
||||
index = findRootIndex(obj.getObject());
|
||||
}
|
||||
if(index<0)
|
||||
parent->addChild(item);
|
||||
@@ -3865,7 +3571,7 @@ void DocumentItem::populateItem(DocumentObjectItem *item, bool refresh, bool del
|
||||
DocumentObjectItem* childItem = static_cast<DocumentObjectItem*>(ci);
|
||||
if(childItem->requiredAtRoot()) {
|
||||
item->removeChild(childItem);
|
||||
auto index = findRootIndex(childItem->object());
|
||||
auto index = findRootIndex(childItem->object()->getObject());
|
||||
if(index>=0)
|
||||
this->insertChild(index,childItem);
|
||||
else
|
||||
@@ -3886,13 +3592,13 @@ void DocumentItem::populateItem(DocumentObjectItem *item, bool refresh, bool del
|
||||
getTree()->_updateStatus();
|
||||
}
|
||||
|
||||
int DocumentItem::findRootIndex(const ViewProviderDocumentObject *childObj) const {
|
||||
if (!TreeParams::Instance()->KeepRootOrder() || !childObj || !childObj->getObject()
|
||||
|| !childObj->getObject()->getNameInDocument()) {
|
||||
int DocumentItem::findRootIndex(App::DocumentObject *childObj) {
|
||||
if(!TreeParams::Instance()->KeepRootOrder() || !childObj || !childObj->getNameInDocument())
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Use view provider's tree rank to find correct place at the root level.
|
||||
// object id is monotonically increasing, so use this as a hint to insert
|
||||
// object back so that we can have a stable order in root level.
|
||||
|
||||
int count = this->childCount();
|
||||
if(!count)
|
||||
return -1;
|
||||
@@ -3903,10 +3609,9 @@ int DocumentItem::findRootIndex(const ViewProviderDocumentObject *childObj) cons
|
||||
for(last=count-1;last>=0;--last) {
|
||||
auto citem = this->child(last);
|
||||
if(citem->type() == TreeWidget::ObjectType) {
|
||||
auto obj = static_cast<DocumentObjectItem *>(citem)->object();
|
||||
if (obj->TreeRank.getValue() <= childObj->TreeRank.getValue()) {
|
||||
return last + 1;
|
||||
}
|
||||
auto obj = static_cast<DocumentObjectItem*>(citem)->object()->getObject();
|
||||
if(obj->getID()<=childObj->getID())
|
||||
return last+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3915,10 +3620,9 @@ int DocumentItem::findRootIndex(const ViewProviderDocumentObject *childObj) cons
|
||||
for(first=0;first<count;++first) {
|
||||
auto citem = this->child(first);
|
||||
if(citem->type() == TreeWidget::ObjectType) {
|
||||
auto obj = static_cast<DocumentObjectItem*>(citem)->object();
|
||||
if (obj->TreeRank.getValue() > childObj->TreeRank.getValue()) {
|
||||
auto obj = static_cast<DocumentObjectItem*>(citem)->object()->getObject();
|
||||
if(obj->getID()>=childObj->getID())
|
||||
return first;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3934,8 +3638,8 @@ int DocumentItem::findRootIndex(const ViewProviderDocumentObject *childObj) cons
|
||||
auto citem = this->child(pos);
|
||||
if(citem->type() != TreeWidget::ObjectType)
|
||||
continue;
|
||||
auto obj = static_cast<DocumentObjectItem*>(citem)->object();
|
||||
if (obj->TreeRank.getValue() < childObj->TreeRank.getValue()) {
|
||||
auto obj = static_cast<DocumentObjectItem*>(citem)->object()->getObject();
|
||||
if(obj->getID()<childObj->getID()) {
|
||||
first = ++pos;
|
||||
count -= step+1;
|
||||
} else
|
||||
@@ -5266,40 +4970,6 @@ DocumentObjectItem *DocumentObjectItem::getParentItem() const{
|
||||
return static_cast<DocumentObjectItem*>(parent());
|
||||
}
|
||||
|
||||
DocumentObjectItem *DocumentObjectItem::getNextSibling() const
|
||||
{
|
||||
QTreeWidgetItem *parent = this->parent();
|
||||
if (parent) {
|
||||
int index = parent->indexOfChild(const_cast<DocumentObjectItem *>(this));
|
||||
if (index >= 0) {
|
||||
while (++index < parent->childCount()) {
|
||||
QTreeWidgetItem *sibling = parent->child(index);
|
||||
if (sibling->type() == TreeWidget::ObjectType) {
|
||||
return static_cast<DocumentObjectItem *>(sibling);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DocumentObjectItem *DocumentObjectItem::getPreviousSibling() const
|
||||
{
|
||||
QTreeWidgetItem *parent = this->parent();
|
||||
if (parent) {
|
||||
int index = parent->indexOfChild(const_cast<DocumentObjectItem *>(this));
|
||||
while (index > 0) {
|
||||
QTreeWidgetItem *sibling = parent->child(--index);
|
||||
if (sibling->type() == TreeWidget::ObjectType) {
|
||||
return static_cast<DocumentObjectItem *>(sibling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *DocumentObjectItem::getName() const {
|
||||
const char *name = object()->getObject()->getNameInDocument();
|
||||
return name?name:"";
|
||||
@@ -5426,22 +5096,4 @@ TreeWidget *DocumentObjectItem::getTree() const{
|
||||
return static_cast<TreeWidget*>(treeWidget());
|
||||
}
|
||||
|
||||
void DocumentObjectItem::getExpandedSnapshot(std::vector<bool> &snapshot) const
|
||||
{
|
||||
snapshot.push_back(isExpanded());
|
||||
|
||||
for (int i = 0; i < childCount(); ++i) {
|
||||
static_cast<const DocumentObjectItem *>(child(i))->getExpandedSnapshot(snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentObjectItem::applyExpandedSnapshot(const std::vector<bool> &snapshot, std::vector<bool>::const_iterator &from)
|
||||
{
|
||||
setExpanded(*from++);
|
||||
|
||||
for (int i = 0; i < childCount(); ++i) {
|
||||
static_cast<DocumentObjectItem *>(child(i))->applyExpandedSnapshot(snapshot, from);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_Tree.cpp"
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <QTreeWidget>
|
||||
#include <QElapsedTimer>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QDockWidget>
|
||||
|
||||
#include <Base/Parameter.h>
|
||||
#include <Base/Persistence.h>
|
||||
@@ -132,13 +131,6 @@ public:
|
||||
|
||||
void synchronizeSelectionCheckBoxes();
|
||||
|
||||
bool getSelectedSiblingObjectItems(std::vector<DocumentObjectItem *> &items) const;
|
||||
|
||||
bool allowMoveUpInGroup(const std::vector<DocumentObjectItem *> &items, DocumentObjectItem **preceding = 0) const;
|
||||
bool allowMoveDownInGroup(const std::vector<DocumentObjectItem *> &items, DocumentObjectItem **succeeding = 0) const;
|
||||
|
||||
static bool moveSiblings(const std::vector<DocumentObjectItem *> &items, DocumentObjectItem *pivot, int direction);
|
||||
|
||||
protected:
|
||||
/// Observer message from the Selection
|
||||
void onSelectionChanged(const SelectionChanges& msg) override;
|
||||
@@ -163,7 +155,6 @@ protected:
|
||||
protected:
|
||||
void showEvent(QShowEvent *) override;
|
||||
void hideEvent(QHideEvent *) override;
|
||||
void focusInEvent(QFocusEvent *event) override;
|
||||
void leaveEvent(QEvent *) override;
|
||||
void _updateStatus(bool delay=true);
|
||||
|
||||
@@ -192,7 +183,6 @@ private Q_SLOTS:
|
||||
void onItemEntered(QTreeWidgetItem * item);
|
||||
void onItemCollapsed(QTreeWidgetItem * item);
|
||||
void onItemExpanded(QTreeWidgetItem * item);
|
||||
void onTabifiedDockWidgetActivated(QDockWidget *dockWidget);
|
||||
void onUpdateStatus(void);
|
||||
|
||||
Q_SIGNALS:
|
||||
@@ -222,9 +212,6 @@ private:
|
||||
bool CheckForDependents();
|
||||
void addDependentToSelection(App::Document* doc, App::DocumentObject* docObject);
|
||||
|
||||
typedef bool (*DocumentObjectItemComparator)(const DocumentObjectItem *a, const DocumentObjectItem *b);
|
||||
bool sortObjectItems(QTreeWidgetItem *node, DocumentObjectItemComparator comparator);
|
||||
|
||||
private:
|
||||
QAction* createGroupAction;
|
||||
QAction* relabelObjectAction;
|
||||
@@ -263,8 +250,6 @@ private:
|
||||
|
||||
std::unordered_map<std::string,std::vector<long> > NewObjects;
|
||||
|
||||
std::set<App::DocumentObject *> ReorderedObjects;
|
||||
|
||||
static std::set<TreeWidget*> Instances;
|
||||
|
||||
std::string myName; // for debugging purpose
|
||||
@@ -356,7 +341,7 @@ protected:
|
||||
QTreeWidgetItem *parent=0, int index=-1,
|
||||
DocumentObjectDataPtr ptrs = DocumentObjectDataPtr());
|
||||
|
||||
int findRootIndex(const ViewProviderDocumentObject *childObj) const;
|
||||
int findRootIndex(App::DocumentObject *childObj);
|
||||
|
||||
DocumentObjectItem *findItemByObject(bool sync,
|
||||
App::DocumentObject *obj, const char *subname, bool select=false);
|
||||
@@ -456,14 +441,8 @@ public:
|
||||
int isParentGroup() const;
|
||||
|
||||
DocumentObjectItem *getParentItem() const;
|
||||
DocumentObjectItem *getNextSibling() const;
|
||||
DocumentObjectItem *getPreviousSibling() const;
|
||||
|
||||
TreeWidget *getTree() const;
|
||||
|
||||
void getExpandedSnapshot(std::vector<bool> &snapshot) const;
|
||||
void applyExpandedSnapshot(const std::vector<bool> &snapshot, std::vector<bool>::const_iterator &from);
|
||||
|
||||
private:
|
||||
void setCheckState(bool checked);
|
||||
|
||||
|
||||
@@ -66,8 +66,6 @@ FC_LOG_LEVEL_INIT("Gui",true,true)
|
||||
using namespace Gui;
|
||||
|
||||
|
||||
int ViewProviderDocumentObject::lastTreeRank = 0;
|
||||
|
||||
PROPERTY_SOURCE(Gui::ViewProviderDocumentObject, Gui::ViewProvider)
|
||||
|
||||
ViewProviderDocumentObject::ViewProviderDocumentObject()
|
||||
@@ -92,8 +90,6 @@ ViewProviderDocumentObject::ViewProviderDocumentObject()
|
||||
"Element: On top only if some sub-element of the object is selected");
|
||||
OnTopWhenSelected.setEnums(OnTopEnum);
|
||||
|
||||
ADD_PROPERTY_TYPE(TreeRank, (0), dogroup, App::PropertyType(App::Prop_Hidden|App::Prop_NoPersist), "Tree view item ordering key");
|
||||
|
||||
sPixmap = "Feature";
|
||||
}
|
||||
|
||||
@@ -226,14 +222,6 @@ void ViewProviderDocumentObject::onChanged(const App::Property* prop)
|
||||
? SoFCSelectionRoot::Box : SoFCSelectionRoot::Full;
|
||||
}
|
||||
}
|
||||
else if (prop == &TreeRank) {
|
||||
if (this->TreeRank.getValue() <= 0) {
|
||||
this->TreeRank.setValue(++ViewProviderDocumentObject::lastTreeRank);
|
||||
}
|
||||
else if (this->TreeRank.getValue() > ViewProviderDocumentObject::lastTreeRank) {
|
||||
ViewProviderDocumentObject::lastTreeRank = this->TreeRank.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
if (prop && !prop->testStatus(App::Property::NoModify)
|
||||
&& pcDocument
|
||||
@@ -690,15 +678,3 @@ std::string ViewProviderDocumentObject::getFullName() const {
|
||||
return pcObject->getFullName() + ".ViewObject";
|
||||
return std::string("?");
|
||||
}
|
||||
|
||||
bool ViewProviderDocumentObject::allowTreeOrderSwap(const App::DocumentObject *child1, const App::DocumentObject *child2) const
|
||||
{
|
||||
std::vector<ViewProviderExtension *> extensions = getExtensionsDerivedFromType<ViewProviderExtension>();
|
||||
for (ViewProviderExtension *ext : extensions) {
|
||||
if (!ext->extensionAllowTreeOrderSwap(child1, child2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -64,9 +64,6 @@ public:
|
||||
App::PropertyEnumeration OnTopWhenSelected;
|
||||
App::PropertyEnumeration SelectionStyle;
|
||||
|
||||
// Hidden properties
|
||||
App::PropertyInteger TreeRank;
|
||||
|
||||
virtual void attach(App::DocumentObject *pcObject);
|
||||
virtual void reattach(App::DocumentObject *);
|
||||
virtual void update(const App::Property*) override;
|
||||
@@ -158,8 +155,6 @@ public:
|
||||
void setShowable(bool enable);
|
||||
bool isShowable() const;
|
||||
|
||||
virtual bool allowTreeOrderSwap(const App::DocumentObject *child1, const App::DocumentObject *child2) const;
|
||||
|
||||
protected:
|
||||
/*! Get the active mdi view of the document this view provider is part of.
|
||||
@note The returned mdi view doesn't need to be a 3d view but can be e.g.
|
||||
@@ -212,8 +207,6 @@ protected:
|
||||
App::DocumentObject *pcObject;
|
||||
Gui::Document* pcDocument;
|
||||
|
||||
static int lastTreeRank;
|
||||
|
||||
private:
|
||||
bool _Showable = true;
|
||||
|
||||
|
||||
@@ -110,8 +110,6 @@ public:
|
||||
virtual bool extensionGetElementPicked(const SoPickedPoint *, std::string &) const {return false;}
|
||||
virtual bool extensionGetDetailPath(const char *, SoFullPath *, SoDetail *&) const {return false;}
|
||||
|
||||
virtual bool extensionAllowTreeOrderSwap(const App::DocumentObject *, const App::DocumentObject *) const { return true; }
|
||||
|
||||
private:
|
||||
bool m_ignoreOverlayIcon = false;
|
||||
//Gui::ViewProviderDocumentObject* m_viewBase = nullptr;
|
||||
|
||||
@@ -74,8 +74,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool allowTreeOrderSwap(const App::DocumentObject *, const App::DocumentObject *) const { return false; }
|
||||
|
||||
/// Returns default size. Use this if it is not possible to determine appropriate size by other means
|
||||
static double defaultSize();
|
||||
protected:
|
||||
|
||||
@@ -48,8 +48,6 @@ public:
|
||||
|
||||
void updateOriginSize();
|
||||
|
||||
virtual bool extensionAllowTreeOrderSwap(const App::DocumentObject *, const App::DocumentObject *) const override { return false; }
|
||||
|
||||
protected:
|
||||
void slotChangedObjectApp ( const App::DocumentObject& obj );
|
||||
void slotChangedObjectGui ( const Gui::ViewProviderDocumentObject& obj );
|
||||
|
||||
@@ -44,9 +44,6 @@ public:
|
||||
QIcon getIcon(void) const;
|
||||
void updateData(const App::Property*);
|
||||
bool onDelete(const std::vector<std::string> &);
|
||||
|
||||
virtual bool allowTreeOrderSwap(const App::DocumentObject *, const App::DocumentObject *) const { return false; }
|
||||
|
||||
};
|
||||
|
||||
/// ViewProvider for the MultiFuse feature
|
||||
|
||||
@@ -126,8 +126,6 @@ public:
|
||||
/// grouping handling
|
||||
std::vector<App::DocumentObject*> claimChildren(void)const;
|
||||
bool onDelete(const std::vector<std::string> &);
|
||||
|
||||
virtual bool allowTreeOrderSwap(const App::DocumentObject *, const App::DocumentObject *) const { return false; }
|
||||
};
|
||||
|
||||
class ViewProviderSweep : public ViewProviderPart
|
||||
@@ -143,8 +141,6 @@ public:
|
||||
/// grouping handling
|
||||
std::vector<App::DocumentObject*> claimChildren(void)const;
|
||||
bool onDelete(const std::vector<std::string> &);
|
||||
|
||||
virtual bool allowTreeOrderSwap(const App::DocumentObject *, const App::DocumentObject *) const { return false; }
|
||||
};
|
||||
|
||||
class ViewProviderOffset : public ViewProviderPart
|
||||
@@ -192,8 +188,6 @@ public:
|
||||
void setupContextMenu(QMenu*, QObject*, const char*);
|
||||
bool onDelete(const std::vector<std::string> &);
|
||||
|
||||
virtual bool allowTreeOrderSwap(const App::DocumentObject *, const App::DocumentObject *) const { return false; }
|
||||
|
||||
protected:
|
||||
virtual bool setEdit(int ModNum);
|
||||
virtual void unsetEdit(int ModNum);
|
||||
|
||||
@@ -44,9 +44,7 @@ public:
|
||||
|
||||
virtual bool onDelete(const std::vector<std::string> &);
|
||||
void highlightReferences(const bool on, bool auxiliary);
|
||||
|
||||
virtual bool allowTreeOrderSwap(const App::DocumentObject *, const App::DocumentObject *) const { return false; }
|
||||
|
||||
|
||||
protected:
|
||||
virtual bool setEdit(int ModNum);
|
||||
virtual void unsetEdit(int ModNum);
|
||||
|
||||
@@ -52,9 +52,7 @@ public:
|
||||
|
||||
virtual bool onDelete(const std::vector<std::string> &);
|
||||
void highlightReferences(Reference mode, bool on);
|
||||
|
||||
virtual bool allowTreeOrderSwap(const App::DocumentObject *, const App::DocumentObject *) const { return false; }
|
||||
|
||||
|
||||
protected:
|
||||
virtual QIcon getIcon(void) const;
|
||||
virtual bool setEdit(int ModNum);
|
||||
|
||||
@@ -13,7 +13,6 @@ SET(Test_SRCS
|
||||
unittestgui.py
|
||||
testmakeWireString.py
|
||||
TestPythonSyntax.py
|
||||
TreeView.py
|
||||
)
|
||||
SOURCE_GROUP("" FILES ${Test_SRCS})
|
||||
|
||||
|
||||
@@ -77,5 +77,4 @@ Gui.addWorkbench(TestWorkbench())
|
||||
FreeCAD.__unit_test__ += [ "Workbench",
|
||||
"Menu",
|
||||
"Menu.MenuDeleteCases",
|
||||
"Menu.MenuCreateCases",
|
||||
"TreeView"]
|
||||
"Menu.MenuCreateCases" ]
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
|
||||
# TreeView test module
|
||||
|
||||
import os
|
||||
import time
|
||||
import tempfile
|
||||
import unittest
|
||||
import FreeCAD
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
import FreeCADGui
|
||||
|
||||
|
||||
class TreeViewTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def getTreeWidget(self):
|
||||
mainWnd = FreeCADGui.getMainWindow()
|
||||
treeDock = mainWnd.findChild(QtGui.QDockWidget, "Tree View")
|
||||
if treeDock is None:
|
||||
treeDock = mainWnd.findChild(QtGui.QDockWidget, "Combo View")
|
||||
if not treeDock is None:
|
||||
tabWidget = treeDock.findChild(QtGui.QTabWidget, "combiTab")
|
||||
if not tabWidget is None:
|
||||
tabWidget.setCurrentIndex(0)
|
||||
self.assertTrue(not treeDock is None, "No Tree View docks available")
|
||||
|
||||
treeView = treeDock.findChild(QtGui.QTreeWidget)
|
||||
self.assertTrue(not treeView is None, "No Tree View widget found")
|
||||
|
||||
return treeView
|
||||
|
||||
def waitForTreeViewSync(self):
|
||||
start = time.time()
|
||||
while time.time() < start + 0.5:
|
||||
FreeCADGui.updateGui()
|
||||
|
||||
def selectDocItem(self, docItem):
|
||||
|
||||
treeView = self.getTreeWidget()
|
||||
|
||||
if docItem.TypeId == "App::Document":
|
||||
appNode = treeView.topLevelItem(0)
|
||||
self.assertTrue(not appNode is None, "No Application top level node")
|
||||
|
||||
docNode = next((appNode.child(i) for i in range(appNode.childCount())
|
||||
if appNode.child(i).text(0) == docItem.Label), None)
|
||||
self.assertTrue(not docNode is None, "No test Document node")
|
||||
treeView.setCurrentItem(docNode)
|
||||
else:
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection(docItem)
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
def trySwapOuterTreeViewItems(self, docItem, transposable):
|
||||
|
||||
self.selectDocItem(docItem)
|
||||
treeView = self.getTreeWidget()
|
||||
|
||||
selected = treeView.selectedItems()
|
||||
self.assertTrue(len(selected) == 1,
|
||||
"Unexpected count of selected items: " + str(len(selected)))
|
||||
selected = selected[0]
|
||||
|
||||
originalState = [ selected.child(i).text(0) for i in range(selected.childCount()) ]
|
||||
self.assertTrue(len(originalState) >= 1,
|
||||
"No children found in item " + selected.text(0))
|
||||
|
||||
targetState = originalState.copy()
|
||||
if transposable:
|
||||
targetState[0], targetState[-1] = targetState[-1], targetState[0]
|
||||
|
||||
treeView.setCurrentItem(selected.child(0))
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
# One move down attempt more to test boundary behaviour
|
||||
for i in range(len(originalState)):
|
||||
FreeCADGui.runCommand("Std_GroupMoveDown")
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
treeView.setCurrentItem(selected.child(len(originalState) - 2 if len(originalState) > 1 else 0))
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
# One move up attempt more to test boundary behaviour
|
||||
for i in range(len(originalState) - 1):
|
||||
FreeCADGui.runCommand("Std_GroupMoveUp")
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
finalState = [ selected.child(i).text(0) for i in range(selected.childCount()) ]
|
||||
self.assertTrue(targetState == finalState,
|
||||
"Unexpected final state: %s\nExpected: %s" % (finalState, targetState))
|
||||
|
||||
def getChildrenOf(self, docItem):
|
||||
|
||||
self.selectDocItem(docItem)
|
||||
treeView = self.getTreeWidget()
|
||||
|
||||
selected = treeView.selectedItems()
|
||||
self.assertTrue(len(selected) == 1,
|
||||
"Unexpected count of selected items: " + str(len(selected)))
|
||||
selected = selected[0]
|
||||
|
||||
return [ selected.child(i).text(0) for i in range(selected.childCount()) ]
|
||||
|
||||
|
||||
def testMoveTransposableItems(self):
|
||||
# Makes sense only if Gui is shown
|
||||
if not FreeCAD.GuiUp:
|
||||
return
|
||||
|
||||
FreeCAD.TestEnvironment = True
|
||||
|
||||
doc = FreeCAD.newDocument("TreeViewTest1")
|
||||
FreeCAD.setActiveDocument(doc.Name)
|
||||
|
||||
box = doc.addObject("Part::Box", "Box")
|
||||
cyl = doc.addObject("Part::Cylinder", "Cylinder")
|
||||
sph = doc.addObject("Part::Sphere", "Sphere")
|
||||
con = doc.addObject("Part::Cone", "Cone")
|
||||
doc.recompute()
|
||||
|
||||
self.trySwapOuterTreeViewItems(doc, True)
|
||||
|
||||
grp = doc.addObject("App::DocumentObjectGroup", "Group")
|
||||
grp.addObjects([ box, cyl, sph, con ])
|
||||
doc.recompute()
|
||||
|
||||
self.trySwapOuterTreeViewItems(grp, True)
|
||||
|
||||
del FreeCAD.TestEnvironment
|
||||
|
||||
|
||||
def testMoveUnmovableItems(self):
|
||||
# Makes sense only if Gui is shown
|
||||
if not FreeCAD.GuiUp:
|
||||
return
|
||||
|
||||
FreeCAD.TestEnvironment = True
|
||||
|
||||
doc = FreeCAD.newDocument("TreeViewTest2")
|
||||
FreeCAD.setActiveDocument(doc.Name)
|
||||
|
||||
sph = doc.addObject("Part::Sphere", "Sphere")
|
||||
con = doc.addObject("Part::Cone", "Cone")
|
||||
doc.recompute()
|
||||
|
||||
cut = doc.addObject("Part::Cut", "Cut")
|
||||
cut.Base = sph
|
||||
cut.Tool = con
|
||||
doc.recompute()
|
||||
|
||||
self.trySwapOuterTreeViewItems(cut, False)
|
||||
|
||||
bdy = doc.addObject("PartDesign::Body", "Body")
|
||||
box = doc.addObject("PartDesign::AdditiveBox", "Box")
|
||||
bdy.addObject(box)
|
||||
doc.recompute()
|
||||
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection(bdy)
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
treeView = self.getTreeWidget()
|
||||
treeView.selectedItems()[0].setExpanded(True)
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection(doc.Name, bdy.Name, box.Name + ".Face6")
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
cha = bdy.newObject("PartDesign::Chamfer", "Chamfer")
|
||||
cha.Base = (box, ["Face6"])
|
||||
doc.recompute()
|
||||
|
||||
cyl = doc.addObject("PartDesign::SubtractiveCylinder", "Cylinder")
|
||||
bdy.addObject(cyl)
|
||||
doc.recompute()
|
||||
|
||||
self.trySwapOuterTreeViewItems(bdy, False)
|
||||
|
||||
del FreeCAD.TestEnvironment
|
||||
|
||||
|
||||
def testItemOrderSaveAndRestore(self):
|
||||
# Makes sense only if Gui is shown
|
||||
if not FreeCAD.GuiUp:
|
||||
return
|
||||
|
||||
FreeCAD.TestEnvironment = True
|
||||
|
||||
doc = FreeCAD.newDocument("TreeViewTest3")
|
||||
FreeCAD.setActiveDocument(doc.Name)
|
||||
|
||||
grp = doc.addObject("App::DocumentObjectGroup", "Group")
|
||||
box = doc.addObject("Part::Box", "Box")
|
||||
cyl = doc.addObject("Part::Cylinder", "Cylinder")
|
||||
sph = doc.addObject("Part::Sphere", "Sphere")
|
||||
con = doc.addObject("Part::Cone", "Cone")
|
||||
doc.recompute()
|
||||
|
||||
origOrder = self.getChildrenOf(doc)
|
||||
self.assertTrue(origOrder == ["Group", "Box", "Cylinder", "Sphere", "Cone"])
|
||||
|
||||
origOrderFile = tempfile.gettempdir() + os.sep + "TreeViewTest3_1.fcstd"
|
||||
doc.saveAs(origOrderFile)
|
||||
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection(con)
|
||||
FreeCADGui.Selection.addSelection(cyl)
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
FreeCADGui.runCommand("Std_GroupMoveUp")
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection(grp)
|
||||
FreeCADGui.Selection.addSelection(box)
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
FreeCADGui.runCommand("Std_GroupMoveDown")
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
newOrder = self.getChildrenOf(doc)
|
||||
self.assertTrue(newOrder == ["Cylinder", "Cone", "Sphere", "Group", "Box"])
|
||||
|
||||
newOrderFile = tempfile.gettempdir() + os.sep + "TreeViewTest3_2.fcstd"
|
||||
doc.saveAs(newOrderFile)
|
||||
|
||||
FreeCAD.closeDocument(doc.Name)
|
||||
self.waitForTreeViewSync()
|
||||
|
||||
doc = FreeCAD.open(origOrderFile)
|
||||
order = self.getChildrenOf(doc)
|
||||
self.assertTrue(order == origOrder)
|
||||
|
||||
doc = FreeCAD.open(newOrderFile)
|
||||
order = self.getChildrenOf(doc)
|
||||
self.assertTrue(order == newOrder)
|
||||
|
||||
del FreeCAD.TestEnvironment
|
||||
Reference in New Issue
Block a user