Revert "Merge pull request #4626 from pavltom/GUI_TreeView_Item_Ordering"

This reverts commit c62239d0ba, reversing
changes made to bef1df4d40.

See forums discussion: https://forum.freecadweb.org/viewtopic.php?p=549120
This commit is contained in:
Chris Hennes
2021-11-24 09:03:35 -06:00
parent 643460e941
commit c9a74d40d2
16 changed files with 22 additions and 826 deletions

View File

@@ -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";}
};

View File

@@ -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;

View File

@@ -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"

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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:

View File

@@ -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 );

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -13,7 +13,6 @@ SET(Test_SRCS
unittestgui.py
testmakeWireString.py
TestPythonSyntax.py
TreeView.py
)
SOURCE_GROUP("" FILES ${Test_SRCS})

View File

@@ -77,5 +77,4 @@ Gui.addWorkbench(TestWorkbench())
FreeCAD.__unit_test__ += [ "Workbench",
"Menu",
"Menu.MenuDeleteCases",
"Menu.MenuCreateCases",
"TreeView"]
"Menu.MenuCreateCases" ]

View File

@@ -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