Make information if tree item is expanded/collapsed persistent
This commit is contained in:
parent
7e7dc80a7f
commit
a233388328
|
@ -38,6 +38,15 @@ namespace App
|
|||
class Document;
|
||||
class DocumentObjectPy;
|
||||
|
||||
enum ObjectStatus {
|
||||
Touch = 0,
|
||||
Error = 1,
|
||||
New = 2,
|
||||
Recompute = 3,
|
||||
Restore = 4,
|
||||
Expand = 16
|
||||
};
|
||||
|
||||
/** Return object for feature execution
|
||||
*/
|
||||
class AppExport DocumentObjectExecReturn
|
||||
|
@ -105,9 +114,11 @@ public:
|
|||
virtual App::DocumentObjectExecReturn *recompute(void);
|
||||
/// return the status bits
|
||||
unsigned long getStatus() const {return StatusBits.to_ulong();}
|
||||
bool testStatus(ObjectStatus pos) const {return StatusBits.test((size_t)pos);}
|
||||
void setStatus(ObjectStatus pos, bool on) {StatusBits.set((size_t)pos, on);}
|
||||
//@}
|
||||
|
||||
/// returns a list of objects this object is pointing to by Links
|
||||
/// returns a list of objects this object is pointing to by Links
|
||||
std::vector<App::DocumentObject*> getOutList(void) const;
|
||||
/// get all objects link to this object
|
||||
std::vector<App::DocumentObject*> getInList(void) const;
|
||||
|
@ -129,7 +140,7 @@ public:
|
|||
|
||||
/** Called in case of loosing a link
|
||||
* Get called by the document when a object got deleted a link property of this
|
||||
* object ist pointing to. The standard behaivour of the DocumentObject implementation
|
||||
* object ist pointing to. The standard behaviour of the DocumentObject implementation
|
||||
* is to reset the links to nothing. You may overide this method to implement
|
||||
*additional or different behavior.
|
||||
*/
|
||||
|
@ -160,14 +171,15 @@ protected:
|
|||
* The first 8 bits are used for the base system the rest can be used in
|
||||
* descendent classes to to mark special stati on the objects.
|
||||
* The bits and their meaning are listed below:
|
||||
* 0 - object is marked as 'touched'
|
||||
* 1 - object is marked as 'erroneous'
|
||||
* 2 - object is marked as 'new'
|
||||
* 3 - object is marked as 'recompute', i.e. the object gets recomputed now
|
||||
* 4 - object is marked as 'restoring', i.e. the object gets loaded at the moment
|
||||
* 5 - reserved
|
||||
* 6 - reserved
|
||||
* 7 - reserved
|
||||
* 0 - object is marked as 'touched'
|
||||
* 1 - object is marked as 'erroneous'
|
||||
* 2 - object is marked as 'new'
|
||||
* 3 - object is marked as 'recompute', i.e. the object gets recomputed now
|
||||
* 4 - object is marked as 'restoring', i.e. the object gets loaded at the moment
|
||||
* 5 - reserved
|
||||
* 6 - reserved
|
||||
* 7 - reserved
|
||||
* 16 - object is marked as 'expanded' in the tree view
|
||||
*/
|
||||
std::bitset<32> StatusBits;
|
||||
|
||||
|
|
|
@ -695,9 +695,20 @@ void Document::RestoreDocFile(Base::Reader &reader)
|
|||
for (i=0 ;i<Cnt ;i++) {
|
||||
xmlReader.readElement("ViewProvider");
|
||||
std::string name = xmlReader.getAttribute("name");
|
||||
bool expanded = false;
|
||||
if (xmlReader.hasAttribute("expanded")) {
|
||||
const char* attr = xmlReader.getAttribute("expanded");
|
||||
if (strcmp(attr,"1") == 0) {
|
||||
expanded = true;
|
||||
}
|
||||
}
|
||||
ViewProvider* pObj = getViewProviderByName(name.c_str());
|
||||
if (pObj) // check if this feature has been registered
|
||||
pObj->Restore(xmlReader);
|
||||
if (expanded) {
|
||||
Gui::ViewProviderDocumentObject* vp = static_cast<Gui::ViewProviderDocumentObject*>(pObj);
|
||||
this->signalExpandObject(*vp, Gui::Expand);
|
||||
}
|
||||
xmlReader.readEndElement("ViewProvider");
|
||||
}
|
||||
xmlReader.readEndElement("ViewProviderData");
|
||||
|
@ -784,7 +795,9 @@ void Document::SaveDocFile (Base::Writer &writer) const
|
|||
const App::DocumentObject* doc = it->first;
|
||||
ViewProvider* obj = it->second;
|
||||
writer.Stream() << writer.ind() << "<ViewProvider name=\""
|
||||
<< doc->getNameInDocument() << "\">" << std::endl;
|
||||
<< doc->getNameInDocument() << "\" "
|
||||
<< "expanded=\"" << (doc->testStatus(App::Expand) ? 1:0)
|
||||
<< "\">" << std::endl;
|
||||
obj->Save(writer);
|
||||
writer.Stream() << writer.ind() << "</ViewProvider>" << std::endl;
|
||||
}
|
||||
|
|
|
@ -112,6 +112,10 @@ TreeWidget::TreeWidget(QWidget* parent)
|
|||
this, SLOT(onTestStatus()));
|
||||
connect(this, SIGNAL(itemEntered(QTreeWidgetItem*, int)),
|
||||
this, SLOT(onItemEntered(QTreeWidgetItem*)));
|
||||
connect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)),
|
||||
this, SLOT(onItemCollapsed(QTreeWidgetItem*)));
|
||||
connect(this, SIGNAL(itemExpanded(QTreeWidgetItem*)),
|
||||
this, SLOT(onItemExpanded(QTreeWidgetItem*)));
|
||||
connect(this, SIGNAL(itemSelectionChanged()),
|
||||
this, SLOT(onItemSelectionChanged()));
|
||||
|
||||
|
@ -572,12 +576,30 @@ void TreeWidget::onTestStatus(void)
|
|||
void TreeWidget::onItemEntered(QTreeWidgetItem * item)
|
||||
{
|
||||
// object item selected
|
||||
if ( item && item->type() == TreeWidget::ObjectType ) {
|
||||
if (item && item->type() == TreeWidget::ObjectType) {
|
||||
DocumentObjectItem* obj = static_cast<DocumentObjectItem*>(item);
|
||||
obj->displayStatusInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void TreeWidget::onItemCollapsed(QTreeWidgetItem * item)
|
||||
{
|
||||
// object item collapsed
|
||||
if (item && item->type() == TreeWidget::ObjectType) {
|
||||
DocumentObjectItem* obj = static_cast<DocumentObjectItem*>(item);
|
||||
obj->setExpandedStatus(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TreeWidget::onItemExpanded(QTreeWidgetItem * item)
|
||||
{
|
||||
// object item expanded
|
||||
if (item && item->type() == TreeWidget::ObjectType) {
|
||||
DocumentObjectItem* obj = static_cast<DocumentObjectItem*>(item);
|
||||
obj->setExpandedStatus(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TreeWidget::scrollItemToTop(Gui::Document* doc)
|
||||
{
|
||||
std::map<const Gui::Document*,DocumentItem*>::iterator it;
|
||||
|
@ -810,52 +832,52 @@ void DocumentItem::slotChangeObject(const Gui::ViewProviderDocumentObject& view)
|
|||
std::string objectName = obj->getNameInDocument();
|
||||
std::map<std::string, DocumentObjectItem*>::iterator it = ObjectMap.find(objectName);
|
||||
if (it != ObjectMap.end()) {
|
||||
// use new grouping style
|
||||
std::set<QTreeWidgetItem*> children;
|
||||
std::vector<App::DocumentObject*> group = view.claimChildren();
|
||||
for (std::vector<App::DocumentObject*>::iterator jt = group.begin(); jt != group.end(); ++jt) {
|
||||
if(*jt){
|
||||
const char* internalName = (*jt)->getNameInDocument();
|
||||
if (internalName) {
|
||||
std::map<std::string, DocumentObjectItem*>::iterator kt = ObjectMap.find(internalName);
|
||||
if (kt != ObjectMap.end()) {
|
||||
children.insert(kt->second);
|
||||
QTreeWidgetItem* parent = kt->second->parent();
|
||||
if (parent && parent != it->second) {
|
||||
if (it->second != kt->second) {
|
||||
int index = parent->indexOfChild(kt->second);
|
||||
parent->takeChild(index);
|
||||
it->second->addChild(kt->second);
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Object references to itself.\n");
|
||||
}
|
||||
// use new grouping style
|
||||
std::set<QTreeWidgetItem*> children;
|
||||
std::vector<App::DocumentObject*> group = view.claimChildren();
|
||||
for (std::vector<App::DocumentObject*>::iterator jt = group.begin(); jt != group.end(); ++jt) {
|
||||
if (*jt) {
|
||||
const char* internalName = (*jt)->getNameInDocument();
|
||||
if (internalName) {
|
||||
std::map<std::string, DocumentObjectItem*>::iterator kt = ObjectMap.find(internalName);
|
||||
if (kt != ObjectMap.end()) {
|
||||
children.insert(kt->second);
|
||||
QTreeWidgetItem* parent = kt->second->parent();
|
||||
if (parent && parent != it->second) {
|
||||
if (it->second != kt->second) {
|
||||
int index = parent->indexOfChild(kt->second);
|
||||
parent->takeChild(index);
|
||||
it->second->addChild(kt->second);
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Object references to itself.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Cannot reparent unknown object.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Group references unknown object.\n");
|
||||
Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Cannot reparent unknown object.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
// move all children which are not part of the group anymore to this item
|
||||
int count = it->second->childCount();
|
||||
for (int i=0; i < count; i++) {
|
||||
QTreeWidgetItem* child = it->second->child(i);
|
||||
if (children.find(child) == children.end()) {
|
||||
it->second->takeChild(i);
|
||||
this->addChild(child);
|
||||
else {
|
||||
Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Group references unknown object.\n");
|
||||
}
|
||||
}
|
||||
this->treeWidget()->expandItem(it->second);
|
||||
}
|
||||
// move all children which are not part of the group anymore to this item
|
||||
int count = it->second->childCount();
|
||||
for (int i=0; i < count; i++) {
|
||||
QTreeWidgetItem* child = it->second->child(i);
|
||||
if (children.find(child) == children.end()) {
|
||||
it->second->takeChild(i);
|
||||
this->addChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
// set the text label
|
||||
std::string displayName = obj->Label.getValue();
|
||||
it->second->setText(0, QString::fromUtf8(displayName.c_str()));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Cannot change unknown object.\n");
|
||||
}
|
||||
}
|
||||
|
@ -1226,6 +1248,12 @@ void DocumentObjectItem::displayStatusInfo()
|
|||
|
||||
}
|
||||
|
||||
void DocumentObjectItem::setExpandedStatus(bool on)
|
||||
{
|
||||
App::DocumentObject* Obj = viewObject->getObject();
|
||||
Obj->setStatus(App::Expand, on);
|
||||
}
|
||||
|
||||
void DocumentObjectItem::setData (int column, int role, const QVariant & value)
|
||||
{
|
||||
QTreeWidgetItem::setData(column, role, value);
|
||||
|
|
|
@ -96,6 +96,8 @@ protected Q_SLOTS:
|
|||
private Q_SLOTS:
|
||||
void onItemSelectionChanged(void);
|
||||
void onItemEntered(QTreeWidgetItem * item);
|
||||
void onItemCollapsed(QTreeWidgetItem * item);
|
||||
void onItemExpanded(QTreeWidgetItem * item);
|
||||
void onTestStatus(void);
|
||||
|
||||
private:
|
||||
|
@ -176,6 +178,7 @@ public:
|
|||
Gui::ViewProviderDocumentObject* object() const;
|
||||
void testStatus();
|
||||
void displayStatusInfo();
|
||||
void setExpandedStatus(bool);
|
||||
void setData(int column, int role, const QVariant & value);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -58,7 +58,6 @@ ViewProviderDocumentObject::ViewProviderDocumentObject()
|
|||
sPixmap = "Feature";
|
||||
}
|
||||
|
||||
|
||||
ViewProviderDocumentObject::~ViewProviderDocumentObject()
|
||||
{
|
||||
// Make sure that the property class does not destruct our string list
|
||||
|
@ -139,12 +138,12 @@ void ViewProviderDocumentObject::attach(App::DocumentObject *pcObj)
|
|||
// Retrieve the supported display modes of the view provider
|
||||
aDisplayModesArray = this->getDisplayModes();
|
||||
|
||||
if( aDisplayModesArray.empty() )
|
||||
if (aDisplayModesArray.empty())
|
||||
aDisplayModesArray.push_back("");
|
||||
|
||||
// We must collect the const char* of the strings and give it to PropertyEnumeration,
|
||||
// but we are still responsible for them, i.e. the property class must not delete the literals.
|
||||
for ( std::vector<std::string>::iterator it = aDisplayModesArray.begin(); it != aDisplayModesArray.end(); ++it ) {
|
||||
for (std::vector<std::string>::iterator it = aDisplayModesArray.begin(); it != aDisplayModesArray.end(); ++it) {
|
||||
aDisplayEnumsArray.push_back( it->c_str() );
|
||||
}
|
||||
aDisplayEnumsArray.push_back(0); // null termination
|
||||
|
|
Loading…
Reference in New Issue
Block a user