Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGQNodeTreeView_qt.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 #include "OSGQNodeTreeView_qt.h"
00040 #include "OSGQWidgetFunctions.h"
00041 
00042 #include <OSGNode.h>
00043 #include <OSGNodeCore.h>
00044 #include <OSGSimpleAttachments.h>
00045 
00046 OSG_USING_NAMESPACE
00047 
00048 #ifdef __sgi
00049 #pragma set woff 1174
00050 #endif
00051 
00052 namespace
00053 {
00054     static Char8 cvsid_cpp[] = "@(#)$Id: OSGQNodeTreeView_qt.cpp,v 1.1 2003/05/07 14:03:40 neumannc Exp $";
00055     static Char8 cvsid_hpp[] = OSGQNODETREEVIEW_HEADER_CVSID;
00056 //    static Char8 cvsid_inl[] = OSGQNODETREEVIEW_INLINE_CVSID;
00057 }
00058 
00059 #ifdef __sgi
00060 #pragma reset woff 1174
00061 #endif
00062 
00063 //
00064 // QHeaderItem
00065 //
00066 
00067 QHeaderItem::QHeaderItem(QFCItem *parent, const QString &strText)
00068     : Inherited(parent, strText)
00069 {
00070 }
00071 
00072 QHeaderItem::~QHeaderItem(void)
00073 {
00074 }
00075 
00076 QHeaderItem *
00077 QHeaderItem::dcast(QListViewItem *pItem)
00078 {
00079     return dynamic_cast<QHeaderItem *>(pItem);
00080 }
00081 
00082 //
00083 // QSceneGraphItem
00084 //
00085 
00086 QSceneGraphItem::QSceneGraphItem(QListView *parent)
00087     : Inherited(parent)
00088 {
00089 }
00090 
00091 QSceneGraphItem::QSceneGraphItem(QListViewItem *parent)
00092     : Inherited(parent)
00093 {
00094 }
00095 
00096 QSceneGraphItem::~QSceneGraphItem(void)
00097 {
00098 }
00099 
00100 QSceneGraphItem *
00101 QSceneGraphItem::dcast(QListViewItem *pItem)
00102 {
00103     return dynamic_cast<QSceneGraphItem *>(pItem);
00104 }
00105 
00106 void
00107 QSceneGraphItem::setOpen(bool bOpen)
00108 {
00109     if(bOpen)
00110         expand();
00111     else
00112         collapse();
00113 
00114     Inherited::setOpen(bOpen);
00115 }
00116 
00117 UInt32
00118 QSceneGraphItem::getAspect(void)
00119 {
00120     if(!this->listView())
00121         return 0;
00122 
00123     QNodeTreeView *pView = QNodeTreeView::dcast(this->listView());
00124 
00125     if(!pView)
00126         return 0;
00127 
00128     return pView->getAspect();
00129 }
00130 
00131 //
00132 // QFCItem
00133 //
00134 
00135 QFCItem::QFCItem(QListView *parent, const FieldContainerPtr &pFC)
00136     : Inherited(parent),
00137       _pFC     (pFC   )
00138 {
00139     if(getFC() != NullFC)
00140     {
00141         setText(0, QString(getFC()->getType().getCName()));
00142 
00143         if(getName(AttachmentContainerPtr::dcast(getFC())))
00144             setText(1, 
00145                     QString(getName(AttachmentContainerPtr::dcast(getFC()))));
00146         else
00147             setText(1, QString("unnamed")       );
00148     }
00149 }
00150 
00151 QFCItem::QFCItem(QListViewItem *parent, const FieldContainerPtr &pFC)
00152     : Inherited(parent),
00153       _pFC     (pFC   )
00154 {
00155     if(getFC() != NullFC)
00156     {
00157         setText(0, QString(getFC()->getType().getCName()));
00158 
00159         if(getName(AttachmentContainerPtr::dcast(getFC())))
00160             setText(1, 
00161                     QString(getName(AttachmentContainerPtr::dcast(getFC()))));
00162         else
00163             setText(1, QString("unnamed")       );
00164     }
00165 }
00166 
00167 QFCItem::~QFCItem(void)
00168 {
00169 }
00170 
00171 QFCItem *
00172 QFCItem::dcast(QListViewItem *pItem)
00173 {
00174     return dynamic_cast<QFCItem *>(pItem);
00175 }
00176 
00177 FieldContainerPtr
00178 QFCItem::getFC(void) const
00179 {
00180     return _pFC;
00181 }
00182 
00183 void
00184 QFCItem::setup(void)
00185 {
00186     FieldContainer *pFCAsp = getFC().getAspectCPtr(getAspect());
00187 
00188     if(!pFCAsp)
00189         return;
00190 
00191     UInt32 uiNumFields = pFCAsp->getType().getNumFieldDescs();
00192     
00193     for(UInt32  fieldId = 1; fieldId <= uiNumFields; ++fieldId)
00194     {
00195         FieldDescription *pDesc     = 
00196             pFCAsp->getType().getFieldDescription     (fieldId);
00197         Field            *pField    = pFCAsp->getField(fieldId);
00198         
00199         if(isSFFieldContainerPtr(pField))
00200         {
00201             if(stringcmp(pDesc->getCName(), "parent" ) == 0)
00202                 continue;
00203 
00204             SFFieldContainerPtr *pSFFCPtr = 
00205                 reinterpret_cast<SFFieldContainerPtr *>(pField);
00206 
00207             if(pSFFCPtr->getValue() != NullFC)
00208             {
00209                 setExpandable(this);
00210                 break;
00211             }
00212         }
00213         else if(isMFFieldContainerPtr(pField))
00214         {
00215             MFFieldContainerPtr *pMFFCPtr =
00216                 reinterpret_cast<MFFieldContainerPtr *>(pField);
00217 
00218             if(stringcmp(pDesc->getCName(), "parents") == 0)
00219             {
00220                 if(pMFFCPtr->size() > 1)
00221                 {
00222                     setExpandable(this);
00223                     break;
00224                 }
00225             }
00226             else
00227             {
00228                 if(pMFFCPtr->size() > 0)
00229                 {
00230                     setExpandable(this);
00231                     break;
00232                 }
00233             }
00234         }
00235     }
00236 
00237     Inherited::setup();
00238 }
00239 
00240 void
00241 QFCItem::expand(void)
00242 {
00243     if(childCount() != 0)
00244         return;
00245 
00246     FieldContainer *pFCAsp = getFC().getAspectCPtr(getAspect());
00247 
00248     if(!pFCAsp)
00249         return;
00250 
00251     FieldContainerType &fcType      = pFCAsp->getType();
00252     UInt32              uiNumFields = fcType.getNumFieldDescs();
00253 
00254     for(UInt32 fieldId = 1; fieldId <= uiNumFields; ++fieldId)
00255     {
00256         FieldDescription *pFieldDesc = fcType.getFieldDescription(fieldId);
00257         Field            *pField     = pFCAsp->getField          (fieldId);
00258         
00259         //add Items for all referenced containers (except parents)
00260         if(isSFFieldContainerPtr(pField))
00261         {
00262             if(stringcmp(pFieldDesc->getCName(), "parent" ) == 0)
00263                 continue;
00264 
00265             addRefedContainer(
00266                 reinterpret_cast<SFFieldContainerPtr *>(pField));
00267         }
00268         else if(isMFFieldContainerPtr(pField))
00269         {
00270             if(stringcmp(pFieldDesc->getCName(), "parents") == 0)
00271             {
00272                 addParents(
00273                     reinterpret_cast<MFFieldContainerPtr *>(pField));
00274             }
00275             else
00276             {
00277                 addRefedContainer(
00278                     reinterpret_cast<MFFieldContainerPtr *>(pField), 
00279                     pFieldDesc   );
00280             }
00281         }
00282 
00283         //add attachments
00284         if(stringcmp(pFieldDesc->getCName(), "attachments") == 0)
00285         {
00286             addAttachments(dynamic_cast<SFAttachmentMap *>(pField));
00287         }
00288     }
00289 
00290     PNOTICE << endLog;
00291 }
00292 
00293 void
00294 QFCItem::collapse(void)
00295 {
00296 }
00297 
00298 void
00299 QFCItem::addRefedContainer(SFFieldContainerPtr *pSFFCPtr)
00300 {
00301     if(!pSFFCPtr || (pSFFCPtr->getValue() == NullFC))
00302         return;
00303 
00304     if(pSFFCPtr->getValue()->getType().isNode())
00305     {
00306         new QNodeItem(this, NodePtr::dcast(pSFFCPtr->getValue()));
00307     }
00308     else if(pSFFCPtr->getValue()->getType().isNodeCore())
00309     {
00310         new QNodeCoreItem(this, NodeCorePtr::dcast(pSFFCPtr->getValue()));
00311     }
00312     else
00313     {
00314         new QFCItem(this, pSFFCPtr->getValue());
00315     }
00316 }
00317 
00318 void
00319 QFCItem::addRefedContainer(MFFieldContainerPtr *pMFFCPtr, 
00320                            FieldDescription    *pFieldDesc)
00321 {
00322     if(!pMFFCPtr || !pFieldDesc)
00323         return;
00324 
00325     MFFieldContainerPtr::reverse_iterator mfIter = pMFFCPtr->rbegin();
00326     MFFieldContainerPtr::reverse_iterator mfEnd  = pMFFCPtr->rend();
00327 
00328     QHeaderItem *pHeaderItem;
00329 
00330     if(mfIter != mfEnd)
00331         pHeaderItem = new QHeaderItem(this, pFieldDesc->getCName());
00332 
00333     for(; mfIter != mfEnd; ++mfIter)
00334     {
00335         if((*mfIter)->getType().isNode())
00336         {
00337             new QNodeItem(pHeaderItem, NodePtr::dcast(*mfIter));
00338         }
00339         else if((*mfIter)->getType().isNodeCore())
00340         {
00341             new QNodeCoreItem(pHeaderItem, NodeCorePtr::dcast(*mfIter));
00342         }
00343         else
00344         {
00345             new QFCItem(pHeaderItem, *mfIter);
00346         }
00347     }
00348 }
00349 
00350 void
00351 QFCItem::addAttachments(SFAttachmentMap *pSFAttMap)
00352 {
00353     AttachmentMap::reverse_iterator mapIter = pSFAttMap->getValue().rbegin();
00354     AttachmentMap::reverse_iterator mapEnd  = pSFAttMap->getValue().rend();
00355 
00356     if(mapIter == mapEnd)
00357         return;
00358         
00359     QHeaderItem *pHeaderItem = new QHeaderItem(this, "attachments");
00360 
00361     for(; mapIter != mapEnd; ++mapIter)
00362     {
00363         new QFCItem(pHeaderItem, (*mapIter).second);
00364     }
00365 }
00366 
00367 void
00368 QFCItem::addParents(MFFieldContainerPtr *pMFFCPtr)
00369 {
00370     if(!pMFFCPtr)
00371         return;
00372 
00373     MFFieldContainerPtr::reverse_iterator mfIter = pMFFCPtr->rbegin();
00374     MFFieldContainerPtr::reverse_iterator mfEnd  = pMFFCPtr->rend();
00375 
00376     if((mfIter == mfEnd) || (pMFFCPtr->size() <= 1))
00377         return;
00378 
00379     QHeaderItem *pHeaderItem = new QHeaderItem(this, "parents");  
00380 
00381     for( ; mfIter != mfEnd; ++mfIter)
00382     {
00383         if(*mfIter == getFC())
00384             continue;
00385         
00386         if((*mfIter)->getType().isNode())
00387         {
00388             new QNodeItem(pHeaderItem, NodePtr::dcast(*mfIter));
00389         }
00390         else if((*mfIter)->getType().isNodeCore())
00391         {
00392             new QNodeCoreItem(pHeaderItem, NodeCorePtr::dcast(*mfIter));
00393         }
00394         else
00395         {
00396             new QFCItem(pHeaderItem, *mfIter);
00397         }
00398     }   
00399 }    
00400      
00401 //
00402 // QNodeItem
00403 //
00404 
00405 QNodeItem::QNodeItem(QListView *parent, const NodePtr &pNode)
00406     : Inherited(parent, pNode)
00407 {
00408 }
00409 
00410 QNodeItem::QNodeItem(QListViewItem *parent, const NodePtr &pNode)
00411     : Inherited(parent, pNode)
00412 {
00413 }
00414 
00415 QNodeItem::~QNodeItem(void)
00416 {
00417 }
00418 
00419 QNodeItem *
00420 QNodeItem::dcast(QListViewItem *pItem)
00421 {
00422     return dynamic_cast<QNodeItem *>(pItem);
00423 }
00424 
00425 //
00426 // QNodeCoreItem
00427 //
00428 
00429 QNodeCoreItem::QNodeCoreItem(      QListView   *parent, 
00430                              const NodeCorePtr &pNodeCore)
00431     : Inherited (parent, pNodeCore)
00432 {
00433     if(pNodeCore != NullFC)
00434     {
00435         setText(0, QString(pNodeCore->getType().getCName()) + 
00436                    QString(" NodeCore")                      );
00437 
00438         if(getName(pNodeCore))
00439             setText(1, QString(getName(pNodeCore)));
00440         else
00441             setText(1, QString("unnamed")         );
00442     }
00443 }
00444 
00445 QNodeCoreItem::QNodeCoreItem(      QListViewItem *parent, 
00446                              const NodeCorePtr   &pNodeCore)
00447     : Inherited (parent, pNodeCore)
00448 {
00449     if(pNodeCore != NullFC)
00450     {
00451         setText(0, QString(pNodeCore->getType().getCName()) + 
00452                    QString(" NodeCore")                      );
00453 
00454         if(getName(pNodeCore))
00455             setText(1, QString(getName(pNodeCore)));
00456         else
00457             setText(1, QString("unnamed")         );
00458     }
00459 }
00460 
00461 QNodeCoreItem::~QNodeCoreItem(void)
00462 {
00463 }
00464 
00465 QNodeCoreItem *
00466 QNodeCoreItem::dcast(QListViewItem *pItem)
00467 {
00468     return dynamic_cast<QNodeCoreItem *>(pItem);
00469 }
00470 
00471 //
00472 // QNodeTreeView
00473 //
00474 
00475 QNodeTreeView::QNodeTreeView(QWidget *parent, const char *name)
00476     : Inherited      (parent, name                     ),
00477       _pRoot         (NullFC                           ),
00478       _uiAspect      (Thread::getCurrent()->getAspect())
00479 {
00480     setRootIsDecorated    (true              );
00481     setAllColumnsShowFocus(true              );
00482     setSorting            (-1                );
00483     addColumn             (QString("FC Type"));
00484     addColumn             (QString("FC Name"));
00485 }
00486 
00487 QNodeTreeView::~QNodeTreeView(void)
00488 {
00489 }
00490 
00491 QNodeTreeView *
00492 QNodeTreeView::dcast(QListView *pView)
00493 {
00494     return dynamic_cast<QNodeTreeView *>(pView);
00495 }
00496 
00497 FieldContainerPtr
00498 QNodeTreeView::getRoot(void)
00499 {
00500     return _pRoot;
00501 }
00502 
00503 const FieldContainerPtr
00504 QNodeTreeView::getRoot(void) const
00505 {
00506     return _pRoot;
00507 }
00508 
00509 UInt32
00510 QNodeTreeView::getAspect(void) const
00511 {
00512     return _uiAspect;
00513 }
00514 
00515 FieldContainerPtr
00516 QNodeTreeView::getSelectedFC(void) const
00517 {
00518     if(!selectedItem())
00519         return NullFC;
00520 
00521     QSceneGraphItem *pSGItem = dynamic_cast<QSceneGraphItem *>(selectedItem());
00522 
00523     if(pSGItem)
00524         return pSGItem->getFC();
00525     else
00526         return NullFC;
00527 }
00528 
00529 QFCItem *
00530 QNodeTreeView::rereadTree(void)
00531 {
00532     removeChildren(firstChild());
00533     
00534     delete firstChild();
00535 
00536     return new QFCItem(this, _pRoot);
00537 }
00538 
00539 void
00540 QNodeTreeView::setRoot(const FieldContainerPtr &pRoot)
00541 {
00542     if(_pRoot != pRoot)
00543     {
00544         _pRoot = pRoot;
00545 
00546         QFCItem *pRootItem = rereadTree();
00547  
00548         setSelected(pRootItem, true);
00549     }
00550 }
00551 
00552 void
00553 QNodeTreeView::setAspect(UInt32 uiAspect)
00554 {
00555     _uiAspect = uiAspect;
00556 
00557     QFCItem *pRootItem = rereadTree();
00558 
00559     setSelected(pRootItem, true);
00560 }
00561 
00562 void
00563 QNodeTreeView::setSelectedFC(const FieldContainerPtr &pFC)
00564 {
00565     doSelectFC(pFC);
00566 }
00567 
00568 void
00569 QNodeTreeView::removeChildren(QListViewItem *pItem)
00570 {
00571     if(!pItem)
00572         return;
00573     
00574     for(QListViewItem *pChild = pItem->firstChild(); pChild; 
00575         pChild = pItem->firstChild())
00576     {
00577         delete pChild;
00578     }
00579 }
00580 
00581 void
00582 QNodeTreeView::doSelectFC(const FieldContainerPtr &pFC)
00583 {
00584     if(pFC == getSelectedFC())
00585         return;
00586 
00587     BranchType         branch;
00588     QListViewItem     *pSelectedItem = this->selectedItem ();
00589 
00590     if(getBranch(pFC, branch))
00591     {
00592         expandBranch(branch);
00593     }
00594     else
00595     {
00596         QListViewItem *pItem = findItemInChildren(pFC, pSelectedItem);
00597 
00598         if(pItem)
00599         {
00600             this->setSelected      (pItem, true);
00601             this->ensureItemVisible(pItem      );
00602         }
00603     }
00604 }
00605 
00606 bool
00607 QNodeTreeView::getBranch(const FieldContainerPtr &pFromFC, BranchType &branch)
00608 {
00609     branch.clear();
00610 
00611     if(pFromFC == NullFC)
00612         return false;
00613 
00614     return getBranchRecursion(pFromFC, branch);
00615 }
00616 
00617 bool
00618 QNodeTreeView::getBranchRecursion(const FieldContainerPtr &pFromFC, 
00619                                         BranchType        &branch  )
00620 {
00621     if(pFromFC == NullFC)
00622     {
00623         return false;
00624     }
00625     else if(pFromFC == getRoot())
00626     {
00627         return true;
00628     }
00629     else
00630     {
00631         branch.push_front(pFromFC);
00632 
00633         Field *pParentsField = getParentsField(pFromFC, getAspect());
00634 
00635         if(!pParentsField)
00636         {
00637             return false;
00638         }
00639 
00640         if(pParentsField->getCardinality() == FieldType::SINGLE_FIELD)
00641         {
00642             SFFieldContainerPtr *pSFParent =
00643                 reinterpret_cast<SFFieldContainerPtr *>(pParentsField);
00644             
00645             if(getBranchRecursion(pSFParent->getValue(), branch))
00646             {
00647                 return true;
00648             }
00649             else
00650             {
00651                 branch.pop_front();
00652 
00653                 return false;
00654             }
00655         }
00656         else
00657         {
00658             MFFieldContainerPtr *pMFParent =
00659                 reinterpret_cast<MFFieldContainerPtr *>(pParentsField);
00660             
00661             MFFieldContainerPtr::iterator mfIter = pMFParent->begin();
00662             MFFieldContainerPtr::iterator mfEnd  = pMFParent->end();
00663 
00664             for(; mfIter != mfEnd; ++mfIter)
00665             {
00666                 if(getBranchRecursion(*mfIter, branch))
00667                 {
00668                     return true;
00669                 }
00670                 else
00671                 {
00672                     branch.pop_front();
00673                 }
00674             }
00675         }
00676     }
00677 
00678     return false;
00679 }
00680 
00681 void
00682 QNodeTreeView::expandBranch(const BranchType &branch)
00683 {
00684     BranchTypeConstIt  bIter = branch.begin();
00685     BranchTypeConstIt  bEnd  = branch.end  ();
00686 
00687     QListViewItem     *pPrevItem = NULL;
00688     QListViewItem     *pCurrItem = this->firstChild();
00689 
00690     for(; bIter != bEnd; ++bIter)
00691     {
00692         pPrevItem = pCurrItem;
00693         pCurrItem = findItemInChildren(*bIter, pCurrItem);
00694 
00695         if(!pCurrItem)
00696         {
00697             SWARNING << "QNodeTreeView::expandBranch(): FAILED. " 
00698                      << "Expanding as far as possible. "
00699                      << endLog;
00700 
00701             break;
00702         }
00703     }
00704 
00705     if(pCurrItem)
00706     {
00707         this->setSelected      (pCurrItem, true);
00708         this->ensureItemVisible(pCurrItem      );
00709     }
00710     else if(pPrevItem)
00711     {
00712         this->setSelected      (pPrevItem, true);
00713         this->ensureItemVisible(pPrevItem      );
00714     }
00715 }
00716 
00717 QListViewItem *
00718 QNodeTreeView::findItemInChildren(const FieldContainerPtr &pFC, 
00719                                         QListViewItem     *pParentItem)
00720 {
00721     if(!pParentItem || (pFC == NullFC))
00722         return NULL;
00723 
00724     QSceneGraphItem *pParentSGItem = QSceneGraphItem::dcast(pParentItem);
00725 
00726     if(pParentSGItem)
00727         pParentSGItem->expand(); // make sure children are created
00728 
00729     for(QListViewItem *pChild = pParentItem->firstChild(); 
00730         pChild;        pChild = pChild->nextSibling()     )
00731     {
00732         QSceneGraphItem *pSGItem = QSceneGraphItem::dcast(pChild);
00733         QHeaderItem     *pHItem  = QHeaderItem::dcast    (pChild);
00734 
00735         if(pSGItem && pSGItem->getFC() == pFC)
00736             return pSGItem;
00737 
00738         if(pHItem && (pHItem->childCount() > 0))
00739         {
00740             for(QListViewItem *pHChild = pHItem->firstChild();
00741                 pHChild;       pHChild = pHChild->nextSibling())
00742             {
00743                 QSceneGraphItem *pHSGItem = QSceneGraphItem::dcast(pHChild);
00744 
00745                 if(pHSGItem && (pHSGItem->getFC() == pFC))
00746                     return pHSGItem;
00747             }
00748         }
00749     }
00750 
00751     return NULL;
00752 }
00753 
00754             
00755 
00756 
00757 #include "OSGQNodeTreeView_qt_moc.cpp"

Generated on Thu Aug 25 04:08:59 2005 for OpenSG by  doxygen 1.4.3