cmxtree.cpp

Go to the documentation of this file.
00001 // $Id: cmxtree.cpp 1688 2006-08-10 12:05:20Z gerry $
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 "cmxtree.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 <ios.h>
00114 #include "bubbleid.h"
00115 
00116 //#include "filtrres.h"
00117 
00118 #include "rifffile.h"
00119 #include "cdrfiltr.h"
00120 #include "cmxform.h"
00121 
00122 //#include "cxftree.h"
00123 //#include "cxfile.h"
00124 //#include "cxftfile.h"
00125 //#include "cxftags.h"
00126 //#include "camfiltr.h"
00127 
00128 // new tree control stuff
00129 #include "clipint.h"
00130 #include "keypress.h"
00131 #include "vkextra.h"
00132 #include "insertnd.h"
00133 
00134 #if DEBUG_TREE
00135 
00136 CC_IMPLEMENT_DYNCREATE(CMXTreeDlg, DialogOp)
00137 //CC_IMPLEMENT_DYNAMIC(CMXTreeDlgRecordHandler,CMXFileRecordHandler)
00138 
00139 CC_IMPLEMENT_MEMDUMP(CMXTreeDlgRecordHandler, CC_CLASS_MEMDUMP)
00140 //CC_IMPLEMENT_MEMDUMP( CMXFileRecordHandler, CC_CLASS_MEMDUMP )
00141 CC_IMPLEMENT_MEMDUMP( CMXFileRecord, CC_CLASS_MEMDUMP )
00142 
00143 CC_IMPLEMENT_MEMDUMP( CMXNodeInfo, CC_CLASS_MEMDUMP )
00144 CC_IMPLEMENT_MEMDUMP( CMXNode, CC_CLASS_MEMDUMP )
00145 
00146 CC_IMPLEMENT_MEMDUMP(CMXNodeTypeStatistics,ListItem)
00147 CC_IMPLEMENT_MEMDUMP(CMXNodeTypeStatisticsList,List)
00148 
00149 // This will get Camelot to display the filename and linenumber of any memory allocations
00150 // that are not released at program exit
00151 #define new CAM_DEBUG_NEW
00152 
00153 CMXTreeDlg* CMXTreeDlg::pCurrentCMXTreeDlg = NULL;
00154 
00155 /********************************************************************************************
00156 
00157 >   CMXTreeDlg::CMXTreeDlg()
00158 
00159     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00160     Created:    7/11/97
00161     Purpose:    Create a debug tree dialog operation. Sets up the string used to hold
00162                 node details.
00163 
00164 ********************************************************************************************/
00165 
00166 CMXTreeDlg::CMXTreeDlg(): DialogOp(CMXTreeDlg::IDD, MODELESS) 
00167 {      
00168     pRoot           = NULL;
00169     pContextNode    = NULL;
00170     EndOfFile       = FALSE;
00171     AddNextAsChild  = FALSE;
00172     Level           = 0;
00173     TreeInfo        = NULL;
00174     MaxIndex        = 0;
00175 
00176     EditStr = new StringBase;
00177     if (!EditStr || !EditStr->Alloc(0x100000)) return;
00178 
00179     CMXTreeDlg::pCurrentCMXTreeDlg = this;
00180 
00181     m_pRIFF = NULL;
00182     m_pHandler = NULL;
00183 }     
00184 
00185 
00186 /********************************************************************************************
00187 
00188 >   CMXTreeDlg::~CMXTreeDlg()
00189 
00190     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00191     Created:    7/11/97
00192     Purpose:    Cleans up a debug tree dialog operation.
00193 
00194 ********************************************************************************************/
00195 
00196 CMXTreeDlg::~CMXTreeDlg()     
00197 {
00198     Delete(pRoot);
00199     DeleteTreeInfo();
00200 
00201     // Deallocate the node details string.
00202     delete EditStr;         
00203 
00204     CMXTreeDlg::pCurrentCMXTreeDlg = NULL;
00205 
00206     if (m_pRIFF != NULL)
00207         delete m_pRIFF;
00208 
00209     if (m_pHandler != NULL)
00210         delete m_pHandler;
00211 }
00212 
00213 
00214 
00215 /********************************************************************************************
00216 
00217 >   void CMXTreeDlg::Do(OpDescriptor*)
00218 
00219     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00220     Created:    7/11/97
00221     Inputs:     Ignored
00222     Purpose:    The 'Do' function for the debug tree dialog. Just creates and opens the
00223                 dialog.
00224 
00225 ********************************************************************************************/
00226 
00227 void CMXTreeDlg::Do(OpDescriptor*)      // "Do" function        
00228 {  
00229     Create();
00230     Open();
00231 }
00232 
00233 
00234 
00235 /********************************************************************************************
00236 
00237 >   BOOL CMXTreeDlg::Init()
00238 
00239     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00240     Created:    7/11/97
00241     Returns:    TRUE if intialised ok;
00242                 FALSE if not.
00243     Purpose:    Initialise the preferences, and register the OpDescriptor for this dialog.
00244 
00245 ********************************************************************************************/
00246 
00247 BOOL CMXTreeDlg::Init()                     
00248 {
00249     // Register our OpDescriptor
00250     return (RegisterOpDescriptor(
00251                                  0,
00252                                  _R(IDS_CMXTREEDLG), 
00253                                  CC_RUNTIME_CLASS(CMXTreeDlg),
00254                                  OPTOKEN_CMXTREEDLG,
00255                                  CMXTreeDlg::GetState,
00256                                  0, /* help ID */
00257                                  _R(IDBBL_DEBUGTREEDLG),
00258                                  0  /* bitmap ID */));
00259 }
00260 
00261 /********************************************************************************************
00262 
00263 >   BOOL CMXTreeDlg::Create()
00264 
00265     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00266     Created:    7/11/97
00267     Returns:    TRUE if setup ok;
00268                 FALSE if not.
00269     Purpose:    Create and setup the debug tree dialog.
00270 
00271 ********************************************************************************************/
00272 
00273 BOOL CMXTreeDlg::Create()
00274 {    
00275     if (DialogOp::Create())
00276     {
00277         EnableGadget(_R(IDC_DEBUGTREE_EXPAND),  TRUE);
00278         EnableGadget(_R(IDC_DEBUGTREE_DUMP),    FALSE);
00279         EnableGadget(_R(IDC_DEBUGTREE_HIDDEN),  FALSE);
00280         EnableGadget(_R(IDC_DEBUGTREE_SELNONLY),FALSE);
00281         EnableGadget(_R(IDC_DEBUGTREE_REFRESH), FALSE);
00282 
00283         InitialiseNewTreeControl();
00284     }     
00285 
00286     return TRUE; 
00287 }
00288 
00289 
00290 
00291 /********************************************************************************************
00292 
00293 >   OpState CMXTreeDlg::GetState(String_256*, OpDescriptor*)
00294 
00295     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00296     Created:    7/11/97
00297     Purpose:    The usual.
00298 
00299 ********************************************************************************************/
00300 
00301 OpState CMXTreeDlg::GetState(String_256*, OpDescriptor*)
00302 {  
00303     OpState OpSt;
00304     return(OpSt);
00305 }   
00306 /********************************************************************************************
00307 
00308 >   void CMXTreeDlg::ShowFile(char* pFile)
00309 
00310     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00311     Created:    7/11/97
00312     Input:      pFile = ptr to file name
00313     Purpose:    Set up the initial debug tree display
00314     SeeAlso:    CMXTreeDlg::GetTree
00315 
00316 ********************************************************************************************/
00317 
00318 void CMXTreeDlg::ShowFile(char* pFile)
00319 {
00320     String_256 s = pFile;
00321     SetFileName(s);
00322 
00323     CreateTree();
00324     DisplayTree(FALSE);
00325 }  
00326 
00327 
00328 void CMXTreeDlg::DeInit()
00329 {
00330     HWND hwndTree = ::GetDlgItem(WindowID, _R(IDC_DEBUGTREE_TREE));
00331     TreeView_DeleteAllItems(hwndTree);
00332 
00333     Delete(pRoot);
00334     pRoot = NULL;
00335 } 
00336 
00337 
00338 void CMXTreeDlg::Delete(CMXNode* pNode)
00339 {
00340     if (pNode == NULL)
00341         return;
00342 
00343     Delete(pNode->GetChild());
00344     Delete(pNode->GetNext());
00345 
00346     delete pNode;
00347 }
00348 
00349 void CMXTreeDlg::SetFileName(String_256& ThisFileName)
00350 {
00351     FileName = ThisFileName;
00352 }
00353 
00354 
00355 void CMXTreeDlg::CreateTree()
00356 {
00357     // Init vars before reading the file
00358     AddNextAsChild = FALSE;
00359     Level = 0;
00360     Delete(pRoot);
00361     pRoot = NULL;
00362     pContextNode = NULL;
00363     
00364     String_256 NameOfType;
00365 
00366     ListOfNodeTypeStats.DeleteAll();
00367 
00368     PathName* pPath = new PathName(FileName);
00369 
00370     if (pPath != NULL && pPath->IsValid())
00371     {
00372         CCDiskFile* pFile = new CCDiskFile(*pPath,ios::in | ios::binary);
00373 
00374         if (pFile != NULL)
00375         {
00376             EndOfFile = FALSE;
00377 
00378             //CCFile* pCMXile = NULL;
00379             /*char Buf[1024];
00380             pFile->read(Buf, 1024);
00381             // reset to the begining
00382             pFile->seek(0); */
00383 
00384             // sort out the RIFF file
00385             m_pRIFF = new RIFFFile();
00386 
00387             FOURCC FormType = m_pRIFF->Init(pFile);
00388             BOOL FileOk = TRUE;         
00389             switch (FormType)
00390             {
00391                 case cmxRIFFFORMTYPE_CMX:
00392                     NameOfType = "CMX";
00393                     break;
00394                 case cmxRIFFFORMTYPE_CDR5:
00395                     NameOfType = "CDR5";
00396                     break;
00397                 case cmxRIFFFORMTYPE_CDT5:
00398                     NameOfType = "CDRT5";
00399                     break;
00400                 case cmxRIFFFORMTYPE_CDR6:
00401                     NameOfType = "CDR6";
00402                     break;
00403                 case cmxRIFFFORMTYPE_CDT6:
00404                     NameOfType = "CDT6";
00405                     break;
00406 
00407                 default:
00408                     FileOk=FALSE;
00409                     break;
00410             }
00411 
00412             if (FileOk)
00413             {
00414                 ParseFile(pFile);
00415             }
00416 
00417             delete pFile;
00418         }
00419     }
00420 
00421     if (pPath != NULL)
00422         delete pPath;
00423 
00424     ListOfNodeTypeStats.Dump(this);
00425     ListOfNodeTypeStats.DeleteAll();
00426 
00427     AddOneItem(NULL, (TCHAR *)FileName, TVI_LAST, m_idxPage, NULL);
00428     AddOneItem(NULL, (TCHAR*)NameOfType,TVI_LAST, m_idxPage, NULL);
00429     AddItemsToNewTreeControl(NULL, pRoot);
00430 }
00431 
00432 
00433 BOOL CMXTreeDlg::ParseFile(CCFile * pFile)
00434 {
00435     ERROR2IF(pFile == NULL || m_pRIFF == NULL,FALSE,"Bad params");
00436 
00437     m_pHandler = new CMXTreeDlgRecordHandler(this, pFile);
00438     
00439     if (m_pHandler == NULL)
00440         return FALSE;
00441 
00442     // loop through looking at top level lists, and dispatch them to various handlers
00443     BOOL finished = FALSE;
00444     // store the level we're working on
00445     UINT32 StartLevel = m_pRIFF->GetObjLevel();
00446 
00447     // get the next object in the file
00448     if (!m_pRIFF->NextObject())
00449         finished = TRUE;
00450 
00451     RIFFObjectType  ObjectType      = m_pRIFF->GetObjType();
00452     FOURCC          ChunkType       = m_pRIFF->GetObjChunkType();
00453     UINT32          Size            = m_pRIFF->GetObjSize();
00454     UINT32          Level           = m_pRIFF->GetObjLevel();
00455     INT32           RecordNumber    = 0;
00456 
00457     while (ObjectType != RIFFOBJECTTYPE_FILEEND && !finished)
00458     {
00459         CMXFileRecord* pCMXFileRecord = new CMXFileRecord(ObjectType, ChunkType, Size, Level);
00460         
00461         RecordNumber ++;    
00462 
00463         if (pCMXFileRecord != NULL)
00464         {
00465             pCMXFileRecord->SetRecordNumber(RecordNumber);
00466             m_pHandler->HandleRecord(pCMXFileRecord);
00467         }
00468         else
00469             finished = TRUE;
00470     
00471         // get the next object in the file
00472         if (!m_pRIFF->NextObject())
00473             finished = TRUE;
00474 
00475         ObjectType  = m_pRIFF->GetObjType();
00476         ChunkType   = m_pRIFF->GetObjChunkType();
00477         Size        = m_pRIFF->GetObjSize();
00478         Level       = m_pRIFF->GetObjLevel();
00479     }
00480 
00481     return TRUE;
00482 }
00483 
00484 
00485 //------------------------------------------------------------------
00486 //------------------------------------------------------------------
00487 
00488 void CMXTreeDlg::AddNode(CMXNode* pNode)
00489 {
00490     if (pNode == NULL)
00491         return;
00492 
00493     ListOfNodeTypeStats.Update(pNode);
00494 
00495     if (pRoot == NULL)
00496     {
00497         pRoot = pNode;
00498         return;
00499     }
00500 
00501     if (pContextNode == NULL)
00502         pContextNode = pRoot;
00503 
00504     if (pContextNode != NULL)
00505     {
00506         INT32 NewLevel = pNode->GetObjectLevel();
00507         if (NewLevel > Level)
00508         {
00509             AddNextAsChild = TRUE;
00510             Level++;
00511         }
00512         else if (NewLevel < Level)
00513         {
00514             AddNextAsChild = FALSE;
00515             Level--;
00516         }
00517 
00518         /* switch (pNode->GetObjectType())
00519         {
00520             case RIFFOBJECTTYPE_LISTEND:
00521             // case TAG_UP:
00522                 AddNextAsChild = FALSE;
00523                 Level--;
00524                 break;
00525 
00526             case RIFFOBJECTTYPE_LISTSTART:
00527             //case TAG_DOWN:
00528                 AddNextAsChild = TRUE;
00529                 Level++;
00530                 break;
00531         } */
00532 
00533         if (pContextNode != NULL)
00534         {
00535             if (AddNextAsChild)
00536             {
00537                 CMXNode* pChildNode = pContextNode->GetChild();
00538                 if (pChildNode != NULL)
00539                 {
00540                     TRACEUSER( "Neville from Markn code", _T("Take cover - context node has already got children"));
00541 
00542                     while (pChildNode->GetNext() != NULL)
00543                         pChildNode = pChildNode->GetNext();
00544 
00545                     pChildNode->SetNext(pNode);
00546                     pNode->SetPrevious(pChildNode);
00547                     pNode->SetParent(pChildNode->GetParent());
00548                 }
00549                 else
00550                 {
00551                     pContextNode->SetChild(pNode);
00552                     pNode->SetParent(pContextNode);
00553                 }
00554 
00555                 AddNextAsChild = FALSE;
00556                 pContextNode = pNode;
00557             }
00558             else
00559             {
00560                 pContextNode->SetNext(pNode);
00561                 pNode->SetPrevious(pContextNode);
00562                 pNode->SetParent(pContextNode->GetParent());
00563 
00564                 //if (pNode->GetTag() == TAG_UP)
00565                 //  pContextNode = pNode->GetParent();
00566                 //else
00567                     pContextNode = pNode;
00568             }
00569         }
00570     }
00571 }
00572 
00573 /********************************************************************************************
00574 
00575 >   CMXFileRecordHandler* CCFile::FindHandler(UINT32 Tag)
00576 
00577     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00578     Created:    7/11/97
00579     Inputs:     Tag = the tag value of a record
00580     Returns:    -
00581     Purpose:    Finds the record handler that's been registered to handle a record with the given tag value
00582     SeeAlso:    ReadNextRecord()
00583     Scope:      -
00584 
00585 ********************************************************************************************/
00586 
00587 CMXTreeDlgRecordHandler* CMXTreeDlg::FindHandler(FOURCC ChunkType)
00588 {
00589 /*  List* pRecordHandlerList = BaseCamelotFilter::GetRecordHandlers();
00590 
00591     ERROR3IF(pRecordHandlerList == NULL,"pRecordHandlerList is NULL");
00592 
00593     if (pRecordHandlerList != NULL)
00594     {
00595         CMXFileRecordHandler* pHandler = (CMXFileRecordHandler*) pRecordHandlerList->GetHead();
00596         while (pHandler != NULL)
00597         {
00598             if (pHandler->IsTagInList(Tag))
00599                 return pHandler;
00600 
00601             pHandler = (CMXFileRecordHandler*) pRecordHandlerList->GetNext(pHandler);
00602         }
00603     }
00604 */
00605 
00606     // return the default handler
00607     return m_pHandler;
00608 }
00609 
00610 void CMXTreeDlg::GetTagText(CMXNode* pNode,String_256& Str)
00611 {
00612     if (pNode != NULL)
00613         GetTagText(pNode->GetChunkType(),Str);
00614 }
00615 
00616 void CMXTreeDlg::GetTagText(FOURCC ChunkType, String_256& Str)
00617 {
00618     CMXTreeDlgRecordHandler* pHandler = FindHandler(ChunkType);
00619 
00620     if (pHandler != NULL)
00621         pHandler->GetTagText(ChunkType, Str);
00622 }
00623 
00624 INT32 CMXTreeDlg::AddDisplayNode(CMXNode* pNode,INT32 Index,INT32 Depth,BOOL ExpandAll)
00625 {
00626     while (pNode != NULL)
00627     {
00628         if (ExpandAll)
00629             pNode->SetShowChildren(TRUE);
00630 
00631         // Set up the info record for this node.
00632         CMXNodeInfo* pInfo = new CMXNodeInfo;
00633         
00634         if (pInfo != NULL)
00635             pInfo->pNode = pNode;
00636         else
00637             return Index;
00638 
00639         // Create the indentation string, based of the depth value
00640         char indent[256];
00641         indent[0] = 0;
00642         for (INT32 i=0;i<Depth;i++)
00643             camStrcat(indent,"       ");
00644 
00645         if (pNode->HasChildren())
00646         {
00647             if (pNode->ShowChildren())
00648                 camStrcat(indent,"-");
00649             else
00650                 camStrcat(indent,"+");
00651         }
00652 
00653         // Get the textual desc of the tag
00654         String_256 TagText;
00655         GetTagText(pNode,TagText);
00656 
00657         // Construct the string for the node
00658         String_256 ListBoxText = indent;
00659         ListBoxText += TagText;
00660 
00661         // Add the item to the list
00662         SetStringGadgetValue(_R(IDC_DEBUGTREE_LIST), &ListBoxText, FALSE, Index); 
00663 
00664         // Store the debug info for this item
00665         if (TreeInfo != NULL)
00666             TreeInfo->AddDebugInfo(Index, pInfo);
00667 
00668         MaxIndex = Index;
00669         Index++;
00670 
00671         if (pNode->ShowChildren())
00672             Index = AddDisplayNode(pNode->GetChild(),Index,Depth+1,ExpandAll);
00673 
00674 //      dont recurse the next value, stick it in a while loop you prat
00675 //      Index = AddDisplayNode(pNode->GetNext(),Index,Depth);
00676 
00677         pNode = pNode->GetNext();
00678 
00679     }
00680 
00681     return Index;
00682 }
00683 
00684 void CMXTreeDlg::DeleteTreeInfo()
00685 {
00686     if (TreeInfo != NULL)
00687     {
00688         for (INT32 i=0;i<=MaxIndex;i++)
00689         {
00690             CMXNodeInfo *pNodeInfo = GetInfo(i);
00691 
00692             TreeInfo->AddDebugInfo(i, NULL);
00693 
00694             if (pNodeInfo != NULL)
00695                 delete pNodeInfo;
00696         }
00697 
00698         delete TreeInfo;
00699     }
00700 
00701     TreeInfo = NULL;
00702     MaxIndex = 0;
00703 }
00704 
00705 
00706 void CMXTreeDlg::DisplayTree(BOOL ExpandAll)
00707 {
00708     // Get handle of list box
00709     HWND hListBox = ::GetDlgItem(WindowID, _R(IDC_DEBUGTREE_LIST));
00710     ENSURE(hListBox != NULL, "Can't find list box in debug tree dialog!");
00711 
00712     DeleteTreeInfo();
00713 
00714     TreeInfo = new DebugTreeInfo(hListBox);
00715 
00716     DeleteAllValues(_R(IDC_DEBUGTREE_LIST));
00717     SetStringGadgetValue(_R(IDC_DEBUGTREE_LIST), &FileName, FALSE, 0); 
00718     AddDisplayNode(pRoot,1,0,ExpandAll);
00719 }
00720 
00721 /********************************************************************************************
00722 
00723 >   void CMXTreeDlg::ShowNodeDebugInfo(INT32 ListIndex)
00724 
00725     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00726     Created:    7/11/97
00727     Inputs:     ListIndex - the list item to display information on.
00728     Purpose:    Display the debug information for the given node in the debug tree dialog's
00729                 scrolly window.
00730 
00731 ********************************************************************************************/
00732 
00733 void CMXTreeDlg::ShowNodeDebugInfo(INT32 ListIndex)
00734 {  
00735     if (ListIndex < 1)
00736     {
00737         String_256 Str = "";
00738         SetStringGadgetValue(_R(IDC_DEBUGTREE_DETAILS), &Str); 
00739         return;
00740     }
00741 
00742     // Get the Node
00743     CMXNode *pNode = GetInfo(ListIndex)->pNode;
00744 
00745     if (pNode != NULL)
00746     {
00747         ShowNodeDebugInfoForNode(pNode);
00748     }
00749 }  
00750 
00751 void CMXTreeDlg::ShowNodeDebugInfoForNode(CMXNode *pNode)
00752 {  
00753     if (pNode != NULL)
00754     {
00755         (*EditStr).Empty();
00756 
00757         pNode->ResetReadPos();
00758 
00759         CMXTreeDlgRecordHandler* pHandler = FindHandler(pNode->GetChunkType());
00760         if (pHandler != NULL)
00761             pHandler->GetRecordDescriptionText(pNode->GetCMXFileRecord(),EditStr);
00762         else
00763         {
00764             TCHAR s[256];
00765             FOURCC ChunkType = pNode->GetChunkType();
00766             canSprintf(s,_T("Default handler (%d)\r\n"), ChunkType);
00767             (*EditStr) += s;
00768         }
00769 
00770         // Copy this string into the edit control.
00771         SetStringGadgetValue(_R(IDC_DEBUGTREE_DETAILS), EditStr); 
00772     }
00773 }  
00774 
00775 CMXNodeInfo *CMXTreeDlg::GetInfo(INT32 Index)
00776 {
00777     ERROR2IF(TreeInfo==NULL,NULL,"TreeInfo is NULL");
00778     return (CMXNodeInfo *) TreeInfo->GetDebugInfo(Index);
00779 }
00780 
00781 /********************************************************************************************
00782 
00783 >   MsgResult CMXTreeDlg::Message( Msg* Message)                               
00784 
00785     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00786     Created:    7/11/97
00787     Inputs:     Msg - the message to handle.
00788     Returns:    -
00789     Purpose:    Handles messages for this dialog.
00790 
00791 ********************************************************************************************/
00792 
00793 MsgResult CMXTreeDlg::Message( Msg* Message)
00794 {
00795 
00796     if (IS_OUR_DIALOG_MSG(Message))
00797     {
00798         DialogMsg* Msg = (DialogMsg*) Message;
00799         if ((Msg->DlgMsg == DIM_COMMIT || Msg->DlgMsg == DIM_CANCEL)) 
00800         {
00801             DeInit();
00802             Close(); // Hide the dialog   
00803             End();
00804         }          
00805         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_EXPAND))
00806              && (Msg->DlgMsg == DIM_LFT_BN_CLICKED))
00807         {   
00808             // Expand the tree  
00809             DisplayTree(TRUE); 
00810             ExpandNewTree();
00811         }    
00812 /*
00813         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_DUMP))
00814              && (Msg->DlgMsg == DIM_LFT_BN_CLICKED))
00815         {   
00816             // Dump the tree
00817             DumpTree();
00818 
00819         }    
00820         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_HIDDEN))
00821              && (Msg->DlgMsg == DIM_LFT_BN_CLICKED))
00822         {   
00823             // Update the 'show hidden nodes' flag
00824             BOOL Valid;
00825             INT32 Value = GetLongGadgetValue(_R(IDC_DEBUGTREE_HIDDEN), 0, 1, 0, &Valid);
00826 
00827             if (Valid)
00828                 ShowHiddenNodes = (Value == 1);
00829 
00830             // Update the tree display according to this value.
00831             ShowHidden(ShowHiddenNodes);
00832         }    
00833         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_SELNONLY))
00834              && (Msg->DlgMsg == DIM_LFT_BN_CLICKED))
00835         {   
00836             // Update the 'show selection' flag
00837             BOOL Valid;
00838             INT32 Value = GetLongGadgetValue(_R(IDC_DEBUGTREE_SELNONLY), 0, 1, 0, &Valid);
00839 
00840             if (Valid)
00841                 SelectionOnly = (Value == 1);
00842 
00843             // Update the tree display according to this value.
00844             ShowHidden(!SelectionOnly);
00845         }    
00846         */
00847         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_LIST)) && 
00848                  (Msg->DlgMsg == DIM_SELECTION_CHANGED_COMMIT))
00849         {
00850             WORD Index; 
00851             GetValueIndex(_R(IDC_DEBUGTREE_LIST), &Index);
00852             if (Index > 0)
00853             {
00854                 CMXNode *pNode = GetInfo(Index)->pNode;
00855                 if (pNode != NULL)
00856                 {
00857                     pNode->SetShowChildren(!pNode->ShowChildren());
00858                     DisplayTree(FALSE);
00859                     SetSelectedValueIndex(_R(IDC_DEBUGTREE_LIST), Index);
00860                 }
00861             }
00862         } 
00863         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_LIST)) && (Msg->DlgMsg == DIM_SELECTION_CHANGED)) 
00864         {
00865             WORD Index; 
00866             GetValueIndex(_R(IDC_DEBUGTREE_LIST), &Index);
00867             ShowNodeDebugInfo(Index);
00868         }  
00869         else if ((Msg->GadgetID == _R(IDC_DEBUGTREE_TREE)) && (Msg->DlgMsg == DIM_SELECTION_CHANGED))
00870         {
00871             NM_TREEVIEW *pTV = (NM_TREEVIEW *)Msg->DlgMsgParam;
00872             
00873             if(pTV != NULL)
00874             {
00875                 // Get the newly selected TV_ITEM
00876                 TV_ITEM Item = pTV->itemNew;
00877                 {
00878                     // Get the node out of the item
00879                     CMXNode *pNode = (CMXNode *)Item.lParam;
00880                     ShowNodeDebugInfoForNode(pNode);
00881                 }
00882             }
00883         } 
00884 
00885         return (DLG_EAT_IF_HUNGRY(Msg)); 
00886     }
00887     return OK; 
00888 }
00889 
00890 
00891 
00892 //------------------------------------------------------------------
00893 
00894 CMXTreeDlgRecordHandler::CMXTreeDlgRecordHandler(CMXTreeDlg * pThisDlg,CCFile* pThisCMXile)
00895 {
00896     ERROR3IF(pThisDlg    == NULL,"Null pThisDlg");
00897     ERROR3IF(pThisCMXile == NULL,"Null pThisCMXile");
00898 
00899     pCMXDlg = pThisDlg;
00900     pCMXile = pThisCMXile;
00901 }
00902 
00903 //------------------------------------------------------------------
00904 
00905 BOOL CMXTreeDlgRecordHandler::HandleRecord(CMXFileRecord* pRecord)
00906 {
00907     ERROR2IF(pRecord == NULL,FALSE,"NULL record given!");
00908     ERROR2IF(pCMXDlg == NULL,FALSE,"NULL pCMXDlg!");
00909     ERROR2IF(pCMXile == NULL,FALSE,"NULL pCMXile!");
00910 
00911     CMXNode* pNode = new CMXNode(pRecord);
00912 
00913     pCMXDlg->AddNode(pNode);
00914 
00915 /*  switch (pRecord->GetTag())
00916     {
00917         case TAG_STARTCOMPRESSION:
00918             // Ask the compression system to be turned on
00919             pCMXile->SetCompression(TRUE);
00920             break;
00921         case TAG_ENDCOMPRESSION:
00922             // Ask the compression system to be turned off
00923             pCMXile->SetCompression(FALSE);
00924             break;
00925 
00926         case TAG_ENDOFFILE:
00927             pCMXDlg->SetEndOfFile(TRUE);
00928             break;
00929     } */
00930 
00931     return TRUE;
00932 }
00933 
00934 void CMXTreeDlgRecordHandler::GetTagText(FOURCC ChunkType, String_256& Str)
00935 {
00936     // Convert the ChunkType from the DWORD into a description;
00937     TCHAR c = ' ';
00938     
00939     c = (TCHAR)((ChunkType) & 0xFF);
00940     Str += c;
00941     c = (TCHAR)((ChunkType >> 8) & 0xFF);
00942     Str += c;
00943     c = (TCHAR)((ChunkType >> 16) & 0xFF);
00944     Str += c;
00945     c = (TCHAR)((ChunkType >> 24) & 0xFF);
00946     Str += c;
00947 }
00948 
00949 /********************************************************************************************
00950 
00951 >   virtual void CMXTreeDlgRecordHandler::GetRecordDescriptionText(CMXFileRecord* pCMXFileRecord,StringBase* pStr)
00952 
00953     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Markn code
00954     Created:    7/11/97
00955     Inputs:     pRecord = ptr to a record
00956                 pStr = ptr to string to update
00957     Returns:    -
00958     Purpose:    This is the base class record description generator.
00959                 Adds the Tag & Size items to the string, so derived classes should call the base class version
00960                 first.
00961     Errors:     -
00962     SeeAlso:    -
00963 
00964 ********************************************************************************************/
00965 
00966 void CMXTreeDlgRecordHandler::GetRecordDescriptionText(CMXFileRecord* pRecord,StringBase* pStr)
00967 {
00968     if (pStr == NULL || pRecord == NULL)
00969         return;
00970 
00971     String_256 TagText;
00972     GetTagText(pRecord->GetChunkType(),TagText);
00973     TCHAR* pTagText = TagText;
00974 
00975     RIFFObjectType ObjType = pRecord->GetObjectType();
00976     String_256 ObjText;
00977     TCHAR* pObjText = ObjText;
00978     switch (ObjType)
00979     {
00980         case RIFFOBJECTTYPE_NONE:
00981             ObjText = _T("None");
00982             break;
00983         case RIFFOBJECTTYPE_CHUNK:
00984             ObjText = _T("Chunk");
00985             break;
00986         case RIFFOBJECTTYPE_LISTSTART:
00987             ObjText = _T("List start");
00988             break;
00989         case RIFFOBJECTTYPE_LISTEND:
00990             ObjText = _T("List end");
00991             break;
00992         case RIFFOBJECTTYPE_FILEEND:
00993             ObjText = _T("List end");
00994             break;
00995     }
00996 
00997     TCHAR s[256];
00998     camSprintf(s,_T("Record Number = %d\r\nRIFF type = %s\r\nTag = %s\r\nSize = %d\r\n\r\n"),pRecord->GetRecordNumber(),pObjText,pTagText,pRecord->GetChunkSize());
00999 
01000     (*pStr) += s;
01001 }
01002 
01003 //------------------------------------------------------------------
01004 //------------------------------------------------------------------
01005 
01006 CMXNode::CMXNode(CMXFileRecord* pThisRecord)
01007 {
01008     pRecord     = NULL;
01009     pNext       = NULL;
01010     pPrevious   = NULL;
01011     pParent     = NULL;
01012     pChild      = NULL;
01013 
01014     DoShowChildren = FALSE;
01015 
01016     if (pThisRecord != NULL)
01017         pRecord = pThisRecord; //->GetCopy();
01018 }
01019 
01020 CMXNode::~CMXNode()
01021 {
01022     if (pRecord != NULL)
01023         delete pRecord;
01024 }
01025 
01026 RIFFObjectType  CMXNode::GetObjectType()
01027 {
01028     if (pRecord != NULL)
01029         return pRecord->GetObjectType();
01030 
01031     return RIFFOBJECTTYPE_NONE;
01032 }
01033 
01034 FOURCC  CMXNode::GetChunkType()
01035 {
01036     if (pRecord != NULL)
01037         return pRecord->GetChunkType();
01038 
01039     return cmxRIFFFORMTYPE_CMX;
01040 }
01041 
01042 UINT32  CMXNode::GetChunkSize()
01043 {
01044     if (pRecord != NULL)
01045         return pRecord->GetChunkSize();
01046 
01047     return UINT32(-1);
01048 }
01049 
01050 UINT32  CMXNode::GetObjectLevel()
01051 {
01052     if (pRecord != NULL)
01053         return pRecord->GetObjectLevel();
01054 
01055     return UINT32(-1);
01056 }
01057 
01058 void CMXNode::ResetReadPos()
01059 {
01060 //  if (pRecord != NULL)
01061 //      pRecord->ResetReadPos();
01062 }
01063 
01064 
01065 //---------------------------------------------------------------------------------------------------
01066 //---------------------------------------------------------------------------------------------------
01067 //---------------------------------------------------------------------------------------------------
01068 
01069 void CMXNodeTypeStatisticsList::Update(CMXNode* pNode)
01070 {
01071     CMXNodeTypeStatistics* pItem = FindNodeType(pNode->GetObjectType());
01072 
01073     if (pItem == NULL)
01074     {
01075         pItem = new CMXNodeTypeStatistics(pNode->GetObjectType());
01076         if (pItem != NULL)
01077             Add(pItem);
01078     }
01079 
01080     if (pItem != NULL)
01081     {
01082         pItem->IncNumOccurances();
01083         pItem->AddToTotalSize(pNode->GetChunkSize());
01084     }
01085 }
01086 
01087 void CMXNodeTypeStatisticsList::Dump(CMXTreeDlg* pDlg)
01088 {
01089     TRACE( _T("\nRecord stats:\n\n"));
01090 
01091     CMXNodeTypeStatistics* pItem = GetHead();
01092 
01093     String_256 Str;
01094 
01095     while (pItem != NULL)
01096     {
01097         pDlg->GetTagText(pItem->GetChunkType(), Str);
01098 
01099         INT32 o = pItem->GetNumOccurances();
01100         INT32 s = pItem->GetTotalSize();
01101 
01102         TRACE( _T("%s\t%d\t%d\t%d\n"),(TCHAR*)Str,o,s,(o*8)+s);
01103 
01104         pItem = GetNext(pItem);
01105     }
01106 }
01107 
01108 
01109 CMXNodeTypeStatistics* CMXNodeTypeStatisticsList::FindNodeType(FOURCC ChunkType)
01110 {
01111     CMXNodeTypeStatistics* pItem = GetHead();
01112     while (pItem != NULL)
01113     {
01114         if (pItem->GetChunkType() == ChunkType)
01115             return pItem;
01116 
01117         pItem = GetNext(pItem);
01118     }
01119 
01120     return NULL;
01121 }
01122 
01123 
01124 void CMXNodeTypeStatisticsList::Add(CMXNodeTypeStatistics* pNodeType)
01125 {
01126     AddTail(pNodeType);
01127 }
01128 
01129 CMXNodeTypeStatistics* CMXNodeTypeStatisticsList::GetHead()
01130 {
01131     return (CMXNodeTypeStatistics*)List::GetHead();
01132 }
01133 
01134 CMXNodeTypeStatistics* CMXNodeTypeStatisticsList::GetNext(CMXNodeTypeStatistics* pItem)
01135 {
01136     return (CMXNodeTypeStatistics*)List::GetNext(pItem);
01137 }
01138 
01139 
01140 /********************************************************************************************
01141 
01142 New TreeView Control stuff by Richard - 14/3/97
01143 
01144 ********************************************************************************************/
01145 
01146 
01147 /********************************************************************************************
01148 
01149 >   HTREEITEM CMXTreeDlg::AddOneItem(HTREEITEM hParent, TCHAR *pText, HTREEITEM hInsAfter,
01150                                                                      INT32 iImage, CMXNode *pNode)
01151 
01152     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01153     Created:    15/02/97
01154     Purpose:    This function fills out the TV_ITEM and TV_INSERTSTRUCT structures 
01155                 and adds the item to the tree view control.
01156 
01157 ********************************************************************************************/
01158 
01159 HTREEITEM CMXTreeDlg::AddOneItem(HTREEITEM hParent, TCHAR *pText, HTREEITEM hInsAfter, INT32 iImage, CMXNode *pNode)
01160 {
01161     HWND hwndTree = ::GetDlgItem(WindowID, _R(IDC_DEBUGTREE_TREE));
01162 
01163     HTREEITEM hItem;
01164     TV_ITEM tvI;
01165     TV_INSERTSTRUCT tvIns;
01166 
01167     // The pszText, iImage, and iSelectedImage members are filled out.
01168     tvI.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
01169     tvI.pszText = pText;
01170     tvI.cchTextMax = camStrlen(pText);
01171     tvI.iImage = iImage;
01172     tvI.iSelectedImage = iImage;
01173     tvI.lParam = (LPARAM)pNode;
01174 
01175     tvIns.item = tvI;
01176     tvIns.hInsertAfter = hInsAfter;
01177     tvIns.hParent = hParent;
01178 
01179     // Insert the item into the tree.
01180     hItem = TreeView_InsertItem(hwndTree, &tvIns);
01181 
01182     return (hItem);
01183 }
01184 
01185 
01186 /********************************************************************************************
01187 
01188 >   INT32 CMXTreeDlg::GetImageForNode(CMXNode *pNode)
01189 
01190     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01191     Created:    15/02/97
01192     Purpose:    Return an imagelist item (icon) for the given node.
01193 
01194 ********************************************************************************************/
01195 
01196 INT32 CMXTreeDlg::GetImageForNode(CMXNode *pNode)
01197 {
01198     INT32 iImage = m_idxGeneralTag;
01199 
01200     if (pNode != NULL)
01201     {
01202 
01203         RIFFObjectType Type = pNode->GetObjectType();
01204         switch(Type)
01205         {
01206             case RIFFOBJECTTYPE_LISTEND:
01207                 iImage = m_idxUp;
01208                 break;
01209 
01210             case RIFFOBJECTTYPE_LISTSTART:
01211                 iImage = m_idxDown;
01212                 break;
01213 
01214             case RIFFOBJECTTYPE_FILEEND:
01215                 iImage = m_idxCompression;
01216                 break;
01217 
01218             case RIFFOBJECTTYPE_CHUNK:
01219                 iImage = m_idxGroup;
01220                 /*
01221                 iImage = m_idxPage;
01222                 iImage = m_idxDefineColour;
01223                 iImage = m_idxDefineBitmap;
01224                 iImage = m_idxGroup;
01225                 iImage = m_idxShape;
01226                 iImage = m_idxAttribute; */
01227                 break;
01228         }
01229     }
01230 
01231     return iImage;
01232 }
01233 
01234 /********************************************************************************************
01235 
01236 >   HTREEITEM CMXTreeDlg::AddItemsToNewTreeControl(HTREEITEM hParentItem, CMXNode *pNode)
01237 
01238     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01239     Created:    15/02/97
01240     Purpose:    Recursively add new items to the tree control from given root node
01241 
01242 ********************************************************************************************/
01243 
01244 HTREEITEM CMXTreeDlg::AddItemsToNewTreeControl(HTREEITEM hParentItem, CMXNode *pNode)
01245 {
01246     if(pNode == NULL)
01247         return 0;
01248 
01249     String_256 NodeText; //(((TCHAR*)(pNode->GetRuntimeClass()->m_lpszClassName)));
01250 
01251     GetTagText(pNode, NodeText);
01252     INT32 iImage = GetImageForNode(pNode);
01253 
01254     HTREEITEM hThisItem = AddOneItem(hParentItem, (TCHAR *)NodeText, hParentItem, iImage, pNode);
01255 
01256     // Check to see if this node has any children
01257     CMXNode *pChild = pNode->GetChild();
01258 
01259     if(pChild != NULL)
01260     {
01261         // Add to the tree control
01262         AddItemsToNewTreeControl(hThisItem, pChild);
01263     }
01264   
01265     // Add the next nodes in
01266     CMXNode *pNext = pNode->GetNext();
01267     
01268     if(pNext != NULL)
01269     {
01270         // Add to the tree control
01271         AddItemsToNewTreeControl(hParentItem, pNext);
01272     }
01273 
01274     return hThisItem;
01275 }
01276 
01277 
01278 /********************************************************************************************
01279 
01280 >   INT32 CMXTreeDlg::AddBitmapResourceToImageList(HIMAGELIST hList, UINT32 ResID)
01281 
01282     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01283     Created:    15/02/97
01284     Purpose:    Obtain the bitmap from the resources and add it to the imagelist.
01285                 We use the old Magenta Mask trick for optimum viewtasticness...
01286 
01287 ********************************************************************************************/
01288 
01289 INT32 CMXTreeDlg::AddBitmapResourceToImageList(HIMAGELIST hList, UINT32 ResID)
01290 {
01291     HINSTANCE hMain = AfxGetResourceHandle();
01292     HBITMAP hBmp = ::LoadBitmap(hMain, MAKEINTRESOURCE(ResID));
01293     INT32 index = ImageList_AddMasked(hList, hBmp, RGB(255,0,255));
01294     return index;
01295 }
01296 
01297 /********************************************************************************************
01298 
01299 >   BOOL CMXTreeDlg::InitialiseNewTreeControl(void)
01300 
01301     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01302     Created:    15/02/97
01303     Purpose:    Sets up the ImageList for the tree control
01304 
01305 ********************************************************************************************/
01306 
01307 BOOL CMXTreeDlg::InitialiseNewTreeControl(void)
01308 {
01309     HWND hwndTree = ::GetDlgItem(WindowID, _R(IDC_DEBUGTREE_TREE));
01310 
01311     INT32 BitmapWidth = 16;
01312     INT32 BitmapHeight = 16;
01313 
01314     // Need to create an image list
01315     hNewTreeControlImageList = ImageList_Create(BitmapWidth, BitmapHeight, ILC_MASK, 0, 0);
01316 
01317     // Load the bitmaps and add them to the image list.
01318     m_idxGeneralTag = AddBitmapResourceToImageList(hNewTreeControlImageList, _R(IDB_CXFTREE_GENERALTAG));
01319     m_idxDefineBitmap = AddBitmapResourceToImageList(hNewTreeControlImageList, _R(IDB_CXFTREE_DEFINEBITMAP));
01320     m_idxDefineColour = AddBitmapResourceToImageList(hNewTreeControlImageList, _R(IDB_CXFTREE_DEFINECOLOUR));
01321     m_idxCompression = AddBitmapResourceToImageList(hNewTreeControlImageList, _R(IDB_CXFTREE_COMPRESSION));
01322     m_idxDown = AddBitmapResourceToImageList(hNewTreeControlImageList, _R(IDB_CXFTREE_DOWN));
01323     m_idxUp = AddBitmapResourceToImageList(hNewTreeControlImageList, _R(IDB_CXFTREE_UP));
01324     m_idxGroup = AddBitmapResourceToImageList(hNewTreeControlImageList, _R(IDB_CXFTREE_GROUP));
01325     m_idxPage = AddBitmapResourceToImageList(hNewTreeControlImageList, _R(IDB_DEBUGTREE_RENDERABLEPAPER));
01326     m_idxAttribute = AddBitmapResourceToImageList(hNewTreeControlImageList, _R(IDB_DEBUGTREE_ATTRIBUTE));
01327     m_idxShape = AddBitmapResourceToImageList(hNewTreeControlImageList, _R(IDB_DEBUGTREE_RENDERABLEINK));
01328 
01329     // Associate the image list with the tree view control.
01330     TreeView_SetImageList(hwndTree, hNewTreeControlImageList, m_idxGeneralTag);
01331 
01332     // Check list actually contains bitmaps
01333     INT32 Count = ImageList_GetImageCount(hNewTreeControlImageList);
01334 
01335     return(Count > 0);
01336 }
01337 
01338 
01339 /********************************************************************************************
01340 
01341 >   BOOL CMXTreeDlg::GetInfoFromHTREEITEM(HTREEITEM hItem, CMXNode **ppNode, INT32 *pChildren)
01342 
01343     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01344     Created:    15/02/97
01345     Purpose:    Obtains the Node pointer and children flag for the given HTREEITEM.
01346 
01347 ********************************************************************************************/
01348 
01349 BOOL CMXTreeDlg::GetInfoFromHTREEITEM(HTREEITEM hItem, CMXNode **ppNode, INT32 *pChildren)
01350 {
01351     HWND hwndTree = ::GetDlgItem(WindowID, _R(IDC_DEBUGTREE_TREE));
01352 
01353     TV_ITEM Item;
01354     Item.hItem = hItem;
01355     Item.mask = TVIF_PARAM | TVIF_CHILDREN | TVIF_STATE;
01356 
01357     if(TreeView_GetItem(hwndTree, &Item))
01358     {
01359         *ppNode = (CMXNode *)Item.lParam;
01360         *pChildren = Item.cChildren;
01361         return TRUE;
01362     }
01363 
01364     return FALSE;
01365 }
01366 
01367 
01368 /********************************************************************************************
01369 
01370 >   void CMXTreeDlg::ExpandNewTree()
01371 
01372     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
01373     Created:    14/02/97
01374     Purpose:    Expands the tree display so that the whole tree is displayed in the control.
01375 
01376 ********************************************************************************************/
01377 
01378 void CMXTreeDlg::ExpandNewTree()
01379 {
01380     HTREEITEM hItem = 0;
01381     HWND hwndTree = ::GetDlgItem(WindowID, _R(IDC_DEBUGTREE_TREE));
01382     hItem = TreeView_GetRoot(hwndTree);
01383 
01384     HTREEITEM hSelectedItem = TreeView_GetSelection(hwndTree);
01385 
01386     // Loop through the items in the tree control, dumping each one to the trace output
01387     while(hItem != 0)
01388     {
01389         TreeView_Expand(hwndTree, hItem, TVE_EXPAND);   
01390 
01391         // Get the next item
01392         hItem = TreeView_GetNextItem(hwndTree, hItem, TVGN_NEXTVISIBLE);
01393     }
01394 
01395     TreeView_SelectItem(hwndTree, hSelectedItem);
01396 } 
01397 
01398 #endif //DEBUG_TREE
01399 
01400 
01401 

Generated on Sat Nov 10 03:44:47 2007 for Camelot by  doxygen 1.4.4