dbugtree.cpp

Go to the documentation of this file.
00001 // $Id: dbugtree.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 // The Camelot debug tree dialog.
00100 
00101 
00102 #include "camtypes.h"
00103 
00104 #include "dbugtree.h"
00105 //#include "node.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00107 //#include "simon.h"
00108 #include "oildbug.h"
00109 #include "nodedoc.h"
00110 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "ccobject.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "nodetext.h"
00113 #include "userattr.h"
00114 #include "ngsentry.h"
00115 
00116 #include "clipint.h"
00117 #include "keypress.h"
00118 #include "vkextra.h"
00119 
00120 #include "insertnd.h"
00121 #include "bubbleid.h"
00122 
00123 #if DEBUG_TREE
00124 
00125 CC_IMPLEMENT_DYNCREATE(DebugTreeDlg, DialogOp)   
00126 
00127 BOOL DebugTreeDlg::s_bShowHiddenNodes = TRUE;
00128 BOOL DebugTreeDlg::s_bSelectionOnly = FALSE;
00129 BOOL DebugTreeDlg::s_bExpandClicked = FALSE;
00130 
00131 /********************************************************************************************
00132 
00133 >   DebugTreeDlg::DebugTreeDlg()
00134 
00135     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00136     Created:    01/06/94
00137     Purpose:    Create a debug tree dialog operation. Sets up the string used to hold
00138                 node details.
00139 
00140 ********************************************************************************************/
00141 
00142 DebugTreeDlg::DebugTreeDlg()
00143   : DialogOp(DebugTreeDlg::IDD(), MODELESS)
00144 {      
00145     m_pstrDetails = new StringBase;
00146     if (!m_pstrDetails || !m_pstrDetails->Alloc(4096)) return;  // 4K is plenty for any node's details
00147     s_bExpandClicked = FALSE;
00148 }     
00149 
00150 
00151 /********************************************************************************************
00152 
00153 >   DebugTreeDlg::~DebugTreeDlg()
00154 
00155     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00156     Created:    01/06/94
00157     Purpose:    Cleans up a debug tree dialog operation.
00158 
00159 ********************************************************************************************/
00160 
00161 DebugTreeDlg::~DebugTreeDlg()     
00162 {
00163     // Deallocate the node details string.
00164     delete m_pstrDetails;         
00165 }
00166 
00167 
00168 
00169 /********************************************************************************************
00170 
00171 >   MsgResult DebugTreeDlg::Message( Msg* Message)                               
00172 
00173     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00174     Created:    01/06/94
00175     Inputs:     Msg - the message to handle.
00176     Returns:    -
00177     Purpose:    Handles messages for this dialog.
00178 
00179 ********************************************************************************************/
00180 
00181 MsgResult DebugTreeDlg::Message( Msg* Message)
00182 {
00183 
00184     if (IS_OUR_DIALOG_MSG(Message))
00185     {
00186         DialogMsg* Msg = (DialogMsg*) Message;
00187 
00188         if ((Msg->DlgMsg == DIM_COMMIT || Msg->DlgMsg == DIM_CANCEL)) 
00189         {
00190             DeInit();
00191             Close(); // Hide the dialog   
00192             End(); 
00193         }          
00194         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_EXPAND))
00195              && (Msg->DlgMsg == DIM_LFT_BN_CLICKED))
00196         {   
00197             // Expand the tree  
00198             // Used by refresh
00199             s_bExpandClicked = TRUE;
00200             ExpandNewTree();
00201         }    
00202         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_DUMP))
00203              && (Msg->DlgMsg == DIM_LFT_BN_CLICKED))
00204         {   
00205             // Dump the tree
00206             DumpTreeTree();
00207         }    
00208         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_REFRESH))
00209              && (Msg->DlgMsg == DIM_LFT_BN_CLICKED))
00210         {   
00211             // Refresh the tree
00212             Refresh(); 
00213         }    
00214         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_HIDDEN))
00215              && (Msg->DlgMsg == DIM_LFT_BN_CLICKED))
00216         {
00217             // Update the 'show hidden nodes' flag
00218             BOOL Valid;
00219             INT32 Value = GetLongGadgetValue(_R(IDC_DEBUGTREE_HIDDEN), 0, 1, 0, &Valid);
00220 
00221             if (Valid)
00222                 s_bShowHiddenNodes = (Value == 1);
00223 
00224             // Refresh the new tree control
00225             RefreshNewTree();
00226         }
00227         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_SELNONLY))
00228              && (Msg->DlgMsg == DIM_LFT_BN_CLICKED))
00229         {   
00230             // Update the 'show selection' flag
00231             BOOL Valid;
00232             INT32 Value = GetLongGadgetValue(_R(IDC_DEBUGTREE_SELNONLY), 0, 1, 0, &Valid);
00233 
00234             if (Valid)
00235                 s_bSelectionOnly = (Value == 1);
00236 
00237             // Refresh the new tree control
00238             RefreshNewTree();
00239         }    
00240         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_TREE)) && (Msg->DlgMsg == DIM_SELECTION_CHANGED))
00241         {
00242             // Get the node out of the item
00243             CTreeItemID hItem = GetTreeGadgetFirstSelectedItem(_R(IDC_DEBUGTREE_TREE));
00244             if (hItem.IsOk())
00245             {
00246                 CCObject* pNode = GetTreeGadgetItemData(_R(IDC_DEBUGTREE_TREE), hItem);
00247                 if (pNode)
00248                     ShowNodeDebugInfoForNode((Node*)pNode);
00249             }
00250         }
00251 
00252         return (DLG_EAT_IF_HUNGRY(Msg)); 
00253     }
00254     return OK; 
00255 }
00256 
00257 
00258 
00259 /********************************************************************************************
00260 
00261 >   void DebugTreeDlg::Do(OpDescriptor*)
00262 
00263     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00264     Created:    08/06/94
00265     Inputs:     Ignored
00266     Purpose:    The 'Do' function for the debug tree dialog. Just creates and opens the
00267                 dialog.
00268 
00269 ********************************************************************************************/
00270 
00271 void DebugTreeDlg::Do(OpDescriptor*)        // "Do" function        
00272 {  
00273     Create();
00274     Open();
00275 }
00276 
00277 
00278 
00279 /********************************************************************************************
00280 
00281 >   BOOL DebugTreeDlg::Init()
00282 
00283     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00284     Created:    08/06/94
00285     Returns:    TRUE if intialised ok;
00286                 FALSE if not.
00287     Purpose:    Initialise the preferences, and register the OpDescriptor for this dialog.
00288 
00289 ********************************************************************************************/
00290 
00291 BOOL DebugTreeDlg::Init()                     
00292 {
00293     // Register our preferences
00294     Camelot.DeclareSection(_T("DebugFlags"), 2);
00295     Camelot.DeclarePref(_T("DebugFlags"), _T("ShowHiddenNodes"),    &s_bShowHiddenNodes);
00296     Camelot.DeclarePref(_T("DebugFlags"), _T("SelectionOnly"),      &s_bSelectionOnly);
00297 
00298     // Register our OpDescriptor
00299     return (RegisterOpDescriptor(
00300                                  0,
00301                                  _R(IDS_DEBUGTREEDLG), 
00302                                  CC_RUNTIME_CLASS(DebugTreeDlg),
00303                                  OPTOKEN_DEBUGTREEDLG,
00304                                  DebugTreeDlg::GetState,
00305                                  0, /* help ID */
00306                                  _R(IDBBL_DEBUGTREEDLG),
00307                                  0  /* bitmap ID */));
00308 }
00309 
00310 
00311 /********************************************************************************************
00312 
00313 >   BOOL DebugTreeDlg::Create()
00314 
00315     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00316     Created:    08/06/94
00317     Returns:    TRUE if setup ok;
00318                 FALSE if not.
00319     Purpose:    Create and setup the debug tree dialog.
00320 
00321 ********************************************************************************************/
00322 
00323 BOOL DebugTreeDlg::Create()
00324 {    
00325     if (DialogOp::Create())
00326     {
00327         Initialise();  
00328     }     
00329     return TRUE; 
00330 }
00331 
00332 
00333 
00334 /********************************************************************************************
00335 
00336 >   OpState DebugTreeDlg::GetState(String_256*, OpDescriptor*)
00337 
00338     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00339     Created:    08/06/94
00340     Purpose:    The usual.
00341 
00342 ********************************************************************************************/
00343 
00344 OpState DebugTreeDlg::GetState(String_256*, OpDescriptor*)
00345 {  
00346     OpState OpSt;
00347     return(OpSt);
00348 }   
00349 
00350 /********************************************************************************************
00351 
00352 >   INT32 DebugTreeDlg::GetTreeDepth(Node *pNode)
00353 
00354     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00355     Created:    01/06/94
00356     Inputs:     pNode - the node to find out the depth of.
00357     Returns:    Depth of the node in range 0...n
00358     Purpose:    Find out the depth of a node in the document tree; the document node at the
00359                 top of the tree has a depth of 0, its children are at depth 1, and so on.
00360 
00361 ********************************************************************************************/
00362 
00363 INT32 DebugTreeDlg::GetTreeDepth(Node *pNode)
00364 {
00365     INT32 Depth = 0;
00366 
00367     do
00368     {
00369         pNode = pNode->FindParent();
00370         Depth++;
00371     } while (pNode != NULL);
00372 
00373     return Depth - 1;
00374 }
00375 
00376 /********************************************************************************************
00377 
00378 >   void DebugTreeDlg::ShowNodeDebugInfo(INT32 ListIndex)
00379 
00380     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00381     Created:    07/06/94
00382     Inputs:     ListIndex - the list item to display information on.
00383     Purpose:    Display the debug information for the given node in the debug tree dialog's
00384                 scrolly window.
00385 
00386 ********************************************************************************************/
00387 
00388 void DebugTreeDlg::ShowNodeDebugInfoForNode(Node *pNode)
00389 {  
00390     // Get the Node's class name.
00391     String_256 NodeDesc = String_256( (TCHAR *)( pNode->GetRuntimeClass()->GetClassName() ) ); 
00392 
00393     // Fill in the string.
00394     m_pstrDetails->Empty();
00395     *m_pstrDetails += NodeDesc;
00396     TCHAR NodeAddress[64];
00397     camSnprintf( NodeAddress, 64, _T(" Data at 0x%p (%lu bytes)\n\n"), pNode, pNode->GetNodeSize() );
00398     *m_pstrDetails += NodeAddress;
00399     pNode->GetDebugDetails(m_pstrDetails);
00400 
00401     // Copy this string into the edit control.
00402     SetStringGadgetValue(_R(IDC_DEBUGTREE_DETAILS), *m_pstrDetails); 
00403 }  
00404 
00405 /********************************************************************************************
00406 
00407 >   void DebugTreeDlg::Refresh()
00408 
00409     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00410     Created:    14/02/97
00411     Purpose:    Refreshes the tree.
00412 
00413 ********************************************************************************************/
00414 
00415 void DebugTreeDlg::Refresh()
00416 {
00417     // Vape the old tree
00418     DeleteAllValues(_R(IDC_DEBUGTREE_TREE));
00419 
00420     // Create a new tree
00421     GetTree();
00422 
00423     // Select the first item in the tree and display its debug info.
00424     CTreeItemID hItem = GetTreeGadgetRootItem(_R(IDC_DEBUGTREE_TREE));
00425     SelectTreeGadgetItem(_R(IDC_DEBUGTREE_TREE), hItem);
00426     CCObject* pNode = GetTreeGadgetItemData(_R(IDC_DEBUGTREE_TREE), hItem);
00427     if (pNode && pNode->IsKindOf(CC_RUNTIME_CLASS(Node) ))
00428         ShowNodeDebugInfoForNode((Node*)pNode);
00429 
00430     // Expand the tree ?
00431     if (s_bExpandClicked)
00432         ExpandNewTree();
00433 } 
00434 
00435 
00436 // The depth in the tree of selected nodes.
00437 const INT32 SelectionDepth = 4;
00438 
00439 
00440 /********************************************************************************************
00441 >   static void DebugTreeDlg::TweeDump(BaseDocument *DocToDump = NULL)
00442 
00443     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00444     Created:    29/11/94
00445     Inputs:     DocToDump - the document that should be dumped out.
00446                 If NULL then the selected document is dumped.
00447     Purpose:    Writes a textual description of the tree to the debug output.
00448     SeeAlso:    DebugTreeDlg::DumpTree
00449 ********************************************************************************************/
00450 
00451 void DebugTreeDlg::TweeDump(BaseDocument* DocToDump)
00452 {
00453     TCHAR               StrBuff[256];
00454     String_256          Details;
00455 
00456     if (DocToDump == NULL)
00457         DocToDump = Document::GetSelected();
00458     if (DocToDump==NULL)
00459     {
00460         DebugTreeInfo::OutputDebug( _T("TweeDump: No Selected Document!\n") );
00461         return;
00462     }
00463     else
00464     {
00465         camSnprintf( StrBuff, 256, _T("Tweedump: Document %p\n"), DocToDump);
00466         DebugTreeInfo::OutputDebug((TCHAR*) StrBuff);
00467     }
00468 
00469     Node* pNode = DocToDump->GetFirstNode();
00470     INT32 depth = 0;
00471     INT32 i;
00472     while (pNode)
00473     {
00474         // Fill in the details string for this node...
00475         Details.Empty();
00476         for(i=0; i<depth; i++)
00477         {
00478             camSnprintf( StrBuff, 256, _T("  ") );
00479             Details += StrBuff;
00480         }
00481         camSnprintf( StrBuff, 256, _T("%p  "), pNode);
00482         Details += StrBuff;
00483         camSnprintf( StrBuff, 256, _T("%c%c%c  "),  
00484                                         (pNode->IsRenderable() ? 'R':'-'),
00485                                         (pNode->IsSelected() ? 'S':'-'),
00486                                         (pNode->IsParentOfSelected() ? 'P':'-')
00487                 );
00488         Details += StrBuff;
00489         Details += String_256((TCHAR*)(pNode->GetRuntimeClass()->GetClassName())); 
00490         camSnprintf( StrBuff, 256, _T("\n"), pNode);
00491         Details += StrBuff;
00492         DebugTreeInfo::OutputDebug((TCHAR*)Details);
00493 
00494         // Find any children we may have and show them...
00495         if (pNode->FindFirstChild())
00496         {
00497             depth+=1;
00498             pNode = pNode->FindFirstChild();
00499         }
00500         else
00501         {
00502             // Now find the next subtree...
00503             while ( pNode && pNode->FindNext()==NULL)
00504             {
00505                 pNode = pNode->FindParent();
00506                 depth-=1;
00507             }
00508             if (pNode)
00509                 pNode = pNode->FindNext();
00510         }
00511     }
00512 
00513     DebugTreeInfo::OutputDebug( _T("\n") );
00514 }
00515 
00516 
00517 /********************************************************************************************
00518 >   static void DebugTreeDlg::DumpSubTree(Node* pSubTree, INT32 FromParent=0, INT32 MaxDepth=9999)
00519 
00520     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> (tweaked version of Phil's amusingly named 'TweeDump')
00521     Created:    7/2/96
00522     Inputs:     pSubTree   - pointer to subtree to dump
00523                 FromParent - levels to ascend before dumping sub tree
00524                 MaxDepth   - depth to which to descend
00525 ********************************************************************************************/
00526 
00527 void DebugTreeDlg::DumpSubTree(Node* pSubTree, INT32 FromParent, INT32 MaxDepth)
00528 {
00529     if (FromParent<0)
00530     {
00531         DebugTreeInfo::OutputDebug( _T("DebugTreeDlg::DumpSubTree() - FromParent<0!\n") );
00532         return;
00533     }
00534     if (MaxDepth<0)
00535     {
00536         DebugTreeInfo::OutputDebug( _T("DebugTreeDlg::DumpSubTree() - MaxDepth<0!\n") );
00537         return;
00538     }
00539 
00540     Node* pStartNode = pSubTree;
00541     while (FromParent--!=0 && pStartNode!=NULL)
00542         pStartNode = pStartNode->FindParent();
00543 
00544     if (pStartNode==NULL)
00545     {
00546         DebugTreeInfo::OutputDebug( _T("DebugTreeDlg::DumpSubTree() - pSubTree==NULL!\n") );
00547         return;
00548     }
00549 
00550     TCHAR               StrBuff[256];
00551     camSnprintf( StrBuff, 256, _T("DebugTreeDlg::DumpSubTree() - pStartNode = %p\n"), pStartNode );
00552     DebugTreeInfo::OutputDebug((TCHAR*)StrBuff);
00553 
00554     INT32        depth = 0;
00555     String_256 Details;
00556     Node* pNode = pStartNode;
00557     while (pNode && depth>=0)
00558     {
00559         // Fill in the details string for this node...
00560         camSnprintf( StrBuff, 256, _T("  ") );
00561         Details.Empty();
00562         for(INT32 i=0; i<depth; i++)
00563             Details += StrBuff;
00564         camSnprintf( StrBuff, 256, _T("%p  "), pNode);
00565         Details += StrBuff;
00566         camSnprintf( StrBuff, 256, _T("%c%c%c  "),
00567                                     (pNode->IsRenderable()       ? 'R':'-'),
00568                                     (pNode->IsSelected()         ? 'S':'-'),
00569                                     (pNode->IsParentOfSelected() ? 'P':'-') );
00570         Details += StrBuff;
00571         Details += String_256((TCHAR*)(pNode->GetRuntimeClass()->GetClassName()));
00572         if (IS_A(pNode,TextChar))
00573         {
00574             Details += String_8( _T(" '") );
00575             TCHAR ptch[2] =  { (TCHAR)(((TextChar*)pNode)->GetUnicodeValue()), '\0' };
00576             Details += String_8((TCHAR*)ptch);
00577             Details += String_8( _T("'") );
00578         }
00579         Details += String_8( _T("\n") );
00580         DebugTreeInfo::OutputDebug((TCHAR*)Details);
00581 
00582         // Find any children we may have and show them...
00583         if (pNode->FindFirstChild() && depth<MaxDepth)
00584         {
00585             depth += 1;
00586             pNode  = pNode->FindFirstChild();
00587         }
00588         else
00589         {
00590             // Now find the next subtree...
00591             while ( pNode && pNode->FindNext()==NULL)
00592             {
00593                 pNode = pNode->FindParent();
00594                 depth-=1;
00595             }
00596             if (pNode==pStartNode)
00597                 pNode = NULL;   // end
00598             if (pNode)
00599                 pNode = pNode->FindNext();
00600         }
00601     }
00602 
00603     DebugTreeInfo::OutputDebug( _T("\n") );
00604 }
00605 
00606 
00607 /********************************************************************************************
00608 
00609 >   BOOL DebugTreeDlg::ShouldBeHidden(Node *pNode)
00610 
00611     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00612     Created:    08/06/94
00613     Inputs:     pNode - the node to check.
00614     Returns:    TRUE if the Node should be hidden; 
00615                 FALSE if it should be displayed.
00616     Purpose:    Determine whether or not a given node should be displayed or not,
00617                 according to the current preferences.
00618     SeeAlso:    DebugTreeDlg::ShowHidden
00619 
00620 ********************************************************************************************/
00621 
00622 BOOL DebugTreeDlg::ShouldBeHidden(Node *pNode)
00623 {
00624     if (!s_bShowHiddenNodes && pNode->IsKindOf(CC_RUNTIME_CLASS(NodeHidden)))
00625         // This is a hidden node and the user does not want hidden nodes.
00626         return TRUE;
00627 
00628     if (s_bSelectionOnly && 
00629         (GetTreeDepth(pNode) == SelectionDepth) &&
00630         !pNode->IsSelected())
00631     {
00632         // This is an unselected node and the user only wants to see the selection
00633         return TRUE;
00634     }
00635 
00636     // Otherwise, we want to see this node
00637     return FALSE;
00638 }
00639 
00640 
00641 /********************************************************************************************
00642 
00643 >   BOOL DebugTreeDlg::IsChildOfHiddenNode(Node *pNode)
00644 
00645     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00646     Created:    08/06/94
00647     Inputs:     pNode - the node to check.
00648     Returns:    TRUE if the node is the child of a hidden node;
00649                 FALSE if not.
00650     Purpose:    Determine if a given node is 'hidden' (in the Camelot sense), i.e. it is the 
00651                 child of a hidden node.
00652 
00653 ********************************************************************************************/
00654 
00655 BOOL DebugTreeDlg::IsChildOfHiddenNode(Node *pNode)
00656 {
00657     if (pNode->FindParent() != NULL)
00658         // Can't be the child of a hidden node
00659         return FALSE;
00660 
00661     // It's either a Hidden node's child, or a Document node...
00662     return (!pNode->IsKindOf(CC_RUNTIME_CLASS(NodeDocument)));
00663 }
00664 
00665 
00666 /********************************************************************************************
00667 
00668 >   BOOL DebugTreeDlg::HasChildren(Node *pNode)
00669 
00670     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00671     Created:    08/06/94
00672     Inputs:     pNode - the node to check.
00673     Returns:    TRUE if the node has displayable children;
00674                 FALSE if not.
00675     Purpose:    Determine if a node has any children that can be displayed in the tree
00676                 (irrespective of user preferences).  Any node that has a normal child
00677                 can be displayed, unless it is the child of a Hidden node.
00678                 Hidden nodes also have displayable children, via their 'HiddenNd' field.
00679     SeeAlso:    DebugTreeDlg::IsChildOfHiddenNode
00680 
00681 ********************************************************************************************/
00682 
00683 BOOL DebugTreeDlg::HasChildren(Node *pNode)
00684 {
00685     if (pNode->FindFirstChild() != NULL)
00686     {
00687         // It has children, but we only display them if this node is not hanging
00688         // off a NodeHidden.
00689         return (IsChildOfHiddenNode(pNode) == FALSE);
00690     }
00691 
00692     if (pNode->IsKindOf(CC_RUNTIME_CLASS(NodeHidden)))
00693         // NodeHiddens have a pseudo-child
00694         return TRUE;
00695 
00696     // Otherwise, no children
00697     return FALSE;
00698 }
00699 
00700 /********************************************************************************************
00701 
00702 >   void DebugTreeDlg::GetTree()
00703 
00704     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00705     Created:    01/06/94
00706     Purpose:    Initialises the tree display to contain the top level of the tree.
00707     SeeAlso:    DebugTreeDlg::AddNodesChildren
00708 
00709 ********************************************************************************************/
00710 
00711 void DebugTreeDlg::GetTree()  
00712 {
00713     // Add the main document node.
00714     Node *pNodeDoc = Document::GetSelected()->GetFirstNode()->FindNext();
00715 
00716     if (KeyPress::IsKeyPressed(CAMKEY(C)))
00717         pNodeDoc = InternalClipboard::Instance()->GetFirstNode()->FindNext();
00718 
00719     ENSURE(pNodeDoc->IsKindOf(CC_RUNTIME_CLASS(NodeDocument)),
00720            "Bad document node in tree");
00721 
00722     AddItemToNewTreeControl( CTreeItemID(), CTreeItemID(), pNodeDoc );
00723 } 
00724 
00725 
00726 /********************************************************************************************
00727 
00728 >   void DebugTreeDlg::Initialise()
00729 
00730     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00731     Created:    01/06/94
00732     Purpose:    Set up the initial debug tree display
00733     SeeAlso:    DebugTreeDlg::GetTree
00734 
00735 ********************************************************************************************/
00736 
00737 void DebugTreeDlg::Initialise()
00738 {
00739     // Got to do this before adding items to the new tree control
00740     InitialiseNewTreeControl();
00741 
00742     GetTree();
00743 
00744     // Select the first item in the tree and display its debug info.
00745     CTreeItemID hItem = GetTreeGadgetRootItem(_R(IDC_DEBUGTREE_TREE));
00746     SelectTreeGadgetItem(_R(IDC_DEBUGTREE_TREE), hItem);
00747     CCObject* pNode = GetTreeGadgetItemData(_R(IDC_DEBUGTREE_TREE), hItem);
00748     if (pNode && pNode->IsKindOf(CC_RUNTIME_CLASS(Node) ))
00749         ShowNodeDebugInfoForNode((Node*)pNode);
00750 
00751     // Set the check boxes according to preferences
00752     if (s_bShowHiddenNodes)
00753         SetLongGadgetValue(_R(IDC_DEBUGTREE_HIDDEN), 1);
00754     else
00755         SetLongGadgetValue(_R(IDC_DEBUGTREE_HIDDEN), 0);
00756 
00757     if (s_bSelectionOnly)
00758         SetLongGadgetValue(_R(IDC_DEBUGTREE_SELNONLY), 1);
00759     else
00760         SetLongGadgetValue(_R(IDC_DEBUGTREE_SELNONLY), 0);
00761 }  
00762 
00763 
00764 BOOL DebugTreeDlg::IsAHiddenNode(Node *pNode)
00765 {
00766     return (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeHidden));
00767 }
00768 
00769 
00770 void DebugTreeDlg::DeInit()
00771 {
00772     DeleteAllValues(_R(IDC_DEBUGTREE_TREE));
00773 } 
00774 
00775 
00776 
00777 
00778 /********************************************************************************************
00779 
00780 >   CTreeItemID DebugTreeDlg::AddOneItem(CTreeItemID hParent,
00781                                          const StringBase& str,
00782                                          CTreeItemID hInsAfter,
00783                                          INT32 iImage,
00784                                          Node *pNode)
00785 
00786     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00787     Created:    15/02/97
00788     Purpose:    This function fills out the TV_ITEM and TV_INSERTSTRUCT structures 
00789                 and adds the item to the tree view control.
00790 
00791 ********************************************************************************************/
00792 
00793 CTreeItemID DebugTreeDlg::AddOneItem(CTreeItemID hParent,
00794                                      const StringBase& str,
00795                                      CTreeItemID hInsAfter,
00796                                      INT32 iImage,
00797                                      Node* pNode)
00798 {
00799     return SetTreeGadgetItem(_R(IDC_DEBUGTREE_TREE), hParent, str, hInsAfter, iImage, pNode);
00800 }
00801 
00802 
00803 /********************************************************************************************
00804 
00805 >   INT32 DebugTreeDlg::GetImageForNode(Node *pNode)
00806 
00807     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00808     Created:    15/02/97
00809     Purpose:    Ah well... This should really be up to the nodes themselves... This has
00810                 been left as an exercise to the reader...
00811 
00812 ********************************************************************************************/
00813 
00814 INT32 DebugTreeDlg::GetImageForNode(Node *pNode)
00815 {
00816     INT32 iImage = m_idxNode;
00817 
00818     if (pNode->IS_KIND_OF(AttrUser))
00819         iImage = m_idxUserAttr;
00820     else if (pNode->IsKindOf(CC_RUNTIME_CLASS(NodeHidden)))
00821         iImage = m_idxHiddenNode;
00822     else if (pNode->IsKindOf(CC_RUNTIME_CLASS(NodeAttribute)))
00823         iImage = m_idxAttribute;
00824     else if (pNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)))
00825         iImage = m_idxRenderableInk;
00826     else if (pNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderablePaper)))
00827         iImage = m_idxRenderablePaper;
00828     else if (pNode->IsKindOf(CC_RUNTIME_CLASS(InsertionNode)))
00829         iImage = m_idxInsertionNode;
00830     else if (pNode->IS_KIND_OF(NodeSetSentinel))
00831         iImage = m_idxSentinelNode;
00832     else if (pNode->IS_KIND_OF(NodeSetProperty))
00833         iImage = m_idxSetProperty;
00834 
00835     return iImage;
00836 }
00837 
00838 /********************************************************************************************
00839 
00840 >   CTreeItemID DebugTreeDlg::AddItemToNewTreeControl(CTreeItemID hParentItem, CTreeItemID hInsAfterItem, Node *pNode, BOOL bAddChildren = TRUE)
00841 
00842     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00843     Created:    15/02/97
00844     Purpose:    Recursively add new items to the tree control from given root node
00845 
00846 ********************************************************************************************/
00847 
00848 CTreeItemID DebugTreeDlg::AddItemToNewTreeControl(CTreeItemID hParentItem, CTreeItemID hInsAfterItem, Node *pNode, BOOL bAddChildren)
00849 {
00850     String_256 strNodeText( (TCHAR*)( pNode->GetRuntimeClass()->GetClassName() ) );
00851     INT32 iImage = GetImageForNode(pNode);
00852 
00853     CTreeItemID hThisItem = AddOneItem(hParentItem, strNodeText, hInsAfterItem, iImage, pNode);
00854 
00855     if (bAddChildren && HasChildren(pNode))
00856     {
00857         // Check to see if this node has any children
00858         Node *pChild;
00859         CTreeItemID hInsContext;
00860 
00861         // Get the first node
00862         if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeHidden))
00863         {
00864             pChild = ((NodeHidden*) pNode)->HiddenNd;
00865 
00866             // Add to the tree control but don't add children
00867             hInsContext = AddItemToNewTreeControl(hThisItem, hInsContext, pChild, FALSE);
00868         }
00869         else
00870         {
00871             pChild = pNode->FindFirstChild();
00872 
00873             while (pChild != NULL)
00874             {
00875                 // Don't show certain kinds of nodes if the user doesn't want them
00876                 if (!ShouldBeHidden(pChild))
00877                 {
00878                     // Add to the tree control
00879                     hInsContext = AddItemToNewTreeControl(hThisItem, hInsContext, pChild);
00880                 }
00881 
00882                 pChild = pChild->FindNext();
00883             }
00884         }
00885     }
00886 
00887     return hThisItem;
00888 }
00889 
00890 
00891 /********************************************************************************************
00892 
00893 >   BOOL DebugTreeDlg::InitialiseNewTreeControl(void)
00894 
00895     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00896     Created:    15/02/97
00897     Purpose:    Sets up the ImageList for the tree control
00898 
00899 ********************************************************************************************/
00900 
00901 BOOL DebugTreeDlg::InitialiseNewTreeControl(void)
00902 {
00903     // Load the bitmaps and add them to the image list.
00904     CGadgetImageList NewImageList(16, 16);
00905     m_idxNode               = NewImageList.Add(_R(IDB_DEBUGTREE_NODE));
00906     m_idxAttribute          = NewImageList.Add(_R(IDB_DEBUGTREE_ATTRIBUTE));
00907     m_idxRenderableInk      = NewImageList.Add(_R(IDB_DEBUGTREE_RENDERABLE));
00908     m_idxRenderablePaper    = NewImageList.Add(_R(IDB_DEBUGTREE_PAPER));
00909     m_idxInsertionNode      = NewImageList.Add(_R(IDB_DEBUGTREE_INSERT));
00910     m_idxHiddenNode         = NewImageList.Add(_R(IDB_DEBUGTREE_HIDDEN));
00911     m_idxSentinelNode       = NewImageList.Add(_R(IDB_DEBUGTREE_SENTINEL));
00912     m_idxUserAttr           = NewImageList.Add(_R(IDB_DEBUGTREE_USER));
00913     m_idxSetProperty        = NewImageList.Add(_R(IDB_DEBUGTREE_PROPERTY));
00914 
00915     SetGadgetBitmaps(_R(IDC_DEBUGTREE_TREE), NewImageList);
00916 
00917 PORTNOTE("other", "Removed use of GetGadgetImageCount")
00918 //  INT32 Count = GetGadgetImageCount(_R(IDC_DEBUGTREE_TREE));
00919 //
00920 //  return (Count>0);
00921     return TRUE;
00922 }
00923 
00924 /********************************************************************************************
00925 
00926 >   void DebugTreeDlg::DumpTreeTree()
00927 
00928     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00929     Created:    15/02/97
00930     Purpose:    This does the equivalent of Tim's DumpTree function - dumps the tree view
00931                 to the TRACE output - except it does it for the tree control view. Tree
00932                 controls were definitely not designed with this in mind...
00933 
00934 ********************************************************************************************/
00935 
00936 void DebugTreeDlg::DumpTreeTree()
00937 {
00938 PORTNOTETRACE("other", "Removed body of DumpTreeTree because it does nothing!");
00939 /*
00940     CTreeItemID         hItem;
00941     Node*               pNode = NULL;
00942     RECT                RootRect;
00943     BOOL                RootRectOK = FALSE;
00944     INT32               Children = 0;
00945     INT32               Indent = 0;
00946     String_256          ItemText;
00947     
00948     hItem = GetTreeGadgetRootItem(_R(IDC_DEBUGTREE_TREE));
00949     BOOL ok = GetInfoFromTreeItemId((hItem, &pNode, &Children, &Indent);
00950 
00951     // Loop through the items in the tree control, dumping each one to the trace output
00952     while(ok && hItem != NULL)
00953     {
00954         ItemText = TEXT("");
00955 
00956         // Suss the indentation level
00957         // This might need altering if bad indentation levels result - depends on your
00958         // desktop's font size...
00959         INT32 i = 0;
00960         for (i=0; i < Indent; i++)
00961         {
00962             ItemText += TEXT("  ");
00963         }
00964     
00965         // Add '+' to show children
00966         if (Children > 0)
00967             ItemText += TEXT("+ ");
00968         else
00969             ItemText += TEXT("  ");
00970             
00971         // Display the node name
00972         ItemText += (((TCHAR*)(pNode->GetRuntimeClass()->m_lpszClassName)));
00973 
00974         // Display the node address in brackets after the name...
00975         TCHAR AddrStr[32];
00976         _stprintf(AddrStr, " (%p)\n", pNode);
00977         ItemText += AddrStr;
00978 
00979         // Dump Item to debug output (this is a bit OILy...oops!)
00980 //      TreeInfo->OutputDebugLine((TCHAR *) ItemText);
00981 
00982         // Get the next item
00983         hItem = GetTreeGadgetNextVisItem(_R(IDC_DEBUGTREE_TREE), hItem);
00984         ok = GetInfoFromTreeItem(hItem, &pNode, &Children, &Indent);
00985     }
00986 */
00987 } 
00988 
00989 /********************************************************************************************
00990 
00991 >   BOOL DebugTreeDlg::GetInfoFromTreeItem(CNativeTreeItem hItem, Node **ppNode, INT32 *pChildren)
00992 
00993     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00994     Created:    15/02/97
00995     Purpose:    Obtains the Node pointer and children flag for the given CNativeTreeItem.
00996 
00997 ********************************************************************************************/
00998 
00999 BOOL DebugTreeDlg::GetInfoFromTreeItem(CTreeItemID hItem, Node** ppNode, size_t* pChildren)
01000 {
01001     CCObject* pNode = GetTreeGadgetItemData(_R(IDC_DEBUGTREE_TREE), hItem);
01002     ERROR3IF(!pNode->IsKindOf(CC_RUNTIME_CLASS(Node)), "DebugTreeDlg found a non-node tree item");
01003     if (!pNode->IsKindOf(CC_RUNTIME_CLASS(Node)))
01004         return FALSE;
01005 
01006     *ppNode     = (Node*)pNode;
01007     *pChildren  = GetTreeGadgetChildrenCount(_R(IDC_DEBUGTREE_TREE), hItem, FALSE);
01008 
01009     return TRUE;
01010 }
01011 
01012 
01013 /********************************************************************************************
01014 
01015 >   void DebugTreeDlg::ExpandNewTree()
01016 
01017     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01018     Created:    14/02/97
01019     Purpose:    Expands the tree display so that the whole tree is displayed in the control.
01020 
01021 ********************************************************************************************/
01022 
01023 void DebugTreeDlg::ExpandNewTree()
01024 {
01025     CTreeItemID     hItem = GetTreeGadgetRootItem(_R(IDC_DEBUGTREE_TREE));
01026     CTreeItemID     hSelectedItem = GetTreeGadgetFirstSelectedItem(_R(IDC_DEBUGTREE_TREE));
01027 
01028     // Loop through the items in the tree control
01029     while (hItem.IsOk())
01030     {
01031         TreeGadgetExpandItem(_R(IDC_DEBUGTREE_TREE), hItem);
01032         CTreeItemID hChild = GetTreeGadgetFirstChildItem(_R(IDC_DEBUGTREE_TREE), hItem);
01033         if (hChild.IsOk())
01034             hItem = hChild;
01035 
01036         // Get the next item
01037         hItem = GetTreeGadgetNextVisItem(_R(IDC_DEBUGTREE_TREE), hItem);
01038     }
01039 
01040     SelectTreeGadgetItem(_R(IDC_DEBUGTREE_TREE), hSelectedItem, TRUE );
01041 } 
01042 
01043 
01044 
01045 /********************************************************************************************
01046 
01047 >   void DebugTreeDlg::RefreshNewTree()
01048 
01049     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01050     Created:    14/02/97
01051     Purpose:    Kills and recreates the newtree... Bit nasty this...
01052 
01053 ********************************************************************************************/
01054 
01055 void DebugTreeDlg::RefreshNewTree()
01056 {
01057     // Vape the new tree
01058     DeleteAllValues(_R(IDC_DEBUGTREE_TREE));
01059 
01060     // Add the main document node.
01061     Node* pNodeDoc = Document::GetSelected()->GetFirstNode()->FindNext();
01062 
01063     if (KeyPress::IsKeyPressed(CAMKEY(C)))
01064         pNodeDoc = InternalClipboard::Instance()->GetFirstNode()->FindNext();
01065 
01066     ENSURE(pNodeDoc->IsKindOf(CC_RUNTIME_CLASS(NodeDocument)),
01067            "Bad document node in tree");
01068 
01069     AddItemToNewTreeControl( CTreeItemID(), CTreeItemID(), pNodeDoc );
01070 
01071     // Expand the tree ?
01072     if (s_bExpandClicked)
01073         ExpandNewTree(); 
01074 }
01075 
01076 #endif //DEBUG_TREE
01077 
01078 

Generated on Sat Nov 10 03:45:00 2007 for Camelot by  doxygen 1.4.4