finfodlg.cpp

Go to the documentation of this file.
00001 // $Id: finfodlg.cpp 1765 2007-01-31 11:43:52Z luke $
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 // Implementation of the FileInfo class - copied from AboutDlg
00099 
00100 /*
00101 */
00102 
00103 #include "camtypes.h"
00104 
00105 DECLARE_SOURCE("$Revision: 1765 $");
00106 
00107 #include "camelot.h"
00108 //#include "dlgtypes.h"  - in camtypes.h [AUTOMATICALLY REMOVED]
00109 #include "finfodlg.h" 
00110 
00111 //#include "mario.h"                // for string resource
00112 //#include "peter.h"                // for string resources
00113 //#include "reshlpid.h"         // for help resources
00114 //#include "peterdlg.h"         // for dialogue resources
00115 
00116 //#include "document.h"             // for reading and setting document attributes - in camtypes.h [AUTOMATICALLY REMOVED]
00117 #include "localenv.h"           // for locale string settings
00118 //#include "node.h"             // for tree scanning calls - in camtypes.h [AUTOMATICALLY REMOVED]
00119 //#include "spread.h"               // for Spread - in camtypes.h [AUTOMATICALLY REMOVED]
00120 #include "page.h"               // for Page
00121 //#include "group.h"                // for NodeGroup - in camtypes.h [AUTOMATICALLY REMOVED]
00122 #include "nodebmp.h"            // for NodeBitmap
00123 #include "bitmpinf.h"           // for BitmapInfo
00124 //#include "app.h"              // for GetApplication - in camtypes.h [AUTOMATICALLY REMOVED]
00125 //#include "convert.h"          // for StringToBytes and BytesToString  - in camtypes.h [AUTOMATICALLY REMOVED]
00126 #include "nodetxts.h"           // for TextStory node.
00127 #include "fontlist.h"           // for the document font list
00128 #include "progress.h"
00129 //#include "barsdlgs.h"         // for the document info file bar controls
00130 #include "fontman.h"
00131 #include "bubbleid.h"
00132 //#include "customlist.h"
00133 //#include "richard.h"
00134 
00135 //#include "will2.h"
00136 //#include "opdesc.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00137 #include "ophist.h"
00138 
00139 // Required for the document font combo box handling
00140 #include "fontman.h"
00141 #include "fontdrop.h"
00142 #include "fontbase.h"
00143 
00144 #include "nodeliveeffect.h"
00145 
00146 CC_IMPLEMENT_DYNCREATE(FileInfo, DialogOp)   
00147 CC_IMPLEMENT_DYNCREATE(RefItem, ListItem)
00148 
00149 #define new CAM_DEBUG_NEW
00150 
00151 
00152 const CDlgMode FileInfo::Mode = MODELESS;   // The dialog is modal (for the moment.)  
00153 const UINT32 FileInfo::IDD = _R(IDD_FINFODLG);
00154 FileInfo * FileInfo::CurrentDialog = NULL;            
00155 
00156 DocumentFontDropDown    *FileInfo::NameDropDown = NULL;     // Font name drop-down list which shows document fonts
00157 
00158 // Timing constants
00159 #define DURATION_FASTJOB 500        // Half a second
00160 #define DURATION_SLOWJOB 10*1000    // Ten seconds
00161 
00162 
00163 /*******************************************************************************************
00164 
00165 >   FileInfo::FileInfo(): DialogOp(FileInfo::IDD, FileInfo::Mode) 
00166 
00167 
00168     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00169     Created:    23/08/94
00170     Inputs:     -
00171     Outputs:    -
00172     Returns:    -
00173     Purpose:    FileInfo constructor
00174     Errors:     -
00175     SeeAlso:    -
00176 
00177 *******************************************************************************************/
00178 FileInfo::FileInfo(): DialogOp(FileInfo::IDD, FileInfo::Mode) 
00179 {
00180 }       
00181 
00182 
00183 
00184 /*******************************************************************************************
00185 
00186 >   FileInfo::~FileInfo()
00187 
00188     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00189     Created:    22/09/94
00190     Inputs:     -
00191     Outputs:    -
00192     Returns:    -
00193     Purpose:    FileInfo destructor - deallocate the BitmapList space
00194     Errors:     -
00195     SeeAlso:    -
00196 
00197 *******************************************************************************************/
00198 FileInfo::~FileInfo() 
00199 {
00200     BitmapList.DeleteAll();
00201 
00202     CurrentDialog = NULL;
00203 
00204     // Jim, 5/8/96
00205     // Delete a Drop Down list if it's been created (via a static, of all things!)
00206     // This removes a memory leak. (And should have been here all the time.)
00207     if (NameDropDown != NULL)
00208     {
00209         delete NameDropDown;
00210         NameDropDown = NULL;
00211     }
00212 } 
00213 
00214 
00215 
00216 /*******************************************************************************************
00217 
00218 >   MsgResult FileInfo::Message(Msg* Message);
00219 
00220     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00221     Created:    23/08/94
00222     Inputs:     -
00223     Outputs:    -
00224     Returns:    -
00225     Purpose:    Handles all the File info dialog's messages 
00226     Errors:     -
00227     SeeAlso:    -
00228 
00229 *******************************************************************************************/
00230 MsgResult FileInfo::Message(Msg* Message)
00231 {
00232     if (IS_OUR_DIALOG_MSG(Message))
00233     {
00234         DialogMsg* Msg = (DialogMsg*)Message;
00235         
00236         if (Msg->DlgMsg == DIM_CREATE)
00237         {
00238             OnDimCreate();
00239         }
00240 
00241         if ((Msg->DlgMsg == DIM_COMMIT) || (Msg->DlgMsg == DIM_SOFT_COMMIT))
00242         {
00243             Document*   WorkDoc = Document::GetSelected();
00244             if (WorkDoc != NULL)
00245             {
00246                 String_256 NewComment = GetStringGadgetValue(_R(IDC_FILEINFO_COMMENT), NULL, -1);
00247                 String_256 OldComment = WorkDoc->GetComment();
00248                 if (NewComment != OldComment)
00249                 {
00250                     WorkDoc->SetComment(&NewComment);   
00251                     WorkDoc->SetModified(TRUE);
00252                 }
00253             }
00254         }
00255 
00256         if ((Msg->DlgMsg == DIM_COMMIT) || (Msg->DlgMsg == DIM_CANCEL))
00257         {
00258             Close(); // Close and destroy the dialog 
00259             End();
00260             return (DLG_EAT_IF_HUNGRY(Msg));     
00261         }
00262 
00263         if (Msg->DlgMsg == DIM_TIMER)
00264         {
00265             SetDocInfo(FALSE, timerSlowJob.Elapsed(DURATION_SLOWJOB, TRUE));                // Don't update comment field
00266         }
00267     }
00268 
00269     if (MESSAGE_IS_A(Message, DocChangingMsg))
00270     {
00271         DocChangingMsg* DocMsg = (DocChangingMsg*) Message;
00272         if (DocMsg->State == DocChangingMsg::SELCHANGED)
00273         {
00274             if (DocMsg->pOldDoc != NULL)
00275             {
00276                 String_256 NewComment = GetStringGadgetValue(_R(IDC_FILEINFO_COMMENT), NULL, -1);
00277                 String_256 OldComment = DocMsg->pOldDoc->GetComment();
00278                 if (NewComment != OldComment)
00279                 {
00280                     DocMsg->pOldDoc->SetComment(&NewComment);   
00281                     DocMsg->pOldDoc->SetModified(TRUE);
00282                 }
00283             }
00284             SetDocInfo(TRUE,TRUE);
00285         }
00286     }
00287 
00288 //  return OK;  
00289     return DialogOp::Message(Message);
00290 }  
00291 
00292 
00293 
00294 /*******************************************************************************************
00295 
00296 >   BOOL FileInfo::OnDimCreate()
00297 
00298     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00299     Created:    01/02/2005
00300     Inputs:     -
00301     Outputs:    -
00302     Returns:    -
00303     Purpose:    Initialises the contents of the File Info dialog when it is first created
00304     Errors:     -
00305     SeeAlso:    -
00306 
00307 *******************************************************************************************/
00308 BOOL FileInfo::OnDimCreate()
00309 {
00310     // Setup callback timer
00311     this->SetTimer(42, DURATION_FASTJOB);               // Ten seconds between updates
00312     timerSlowJob.Sample();
00313 
00314     
00315     // Setting up the external resources list control.
00316     if (!m_lstctrlExternalResInfo.Init(WindowID, _R(IDC_FINFO_REFSLIST)))
00317         return FALSE;
00318         
00319     m_lstctrlExternalResInfo.AddColumn(_T("Status"), 14);
00320     m_lstctrlExternalResInfo.AddColumn(_T("Item"), 180);
00321     m_lstctrlExternalResInfo.AddColumn(_T("Details"), 760);
00322 
00323     // Setup list columns
00324     // Why do we do this here when we have to use a custom AddItem function (AddRefsItem)
00325     // to populate the list?
00326 /*  CCustomList* pListGadget = CCustomList::GetGadget(GetReadWriteWindowID(), _R(IDC_FINFO_REFSLIST));
00327     ERROR2IF(pListGadget==NULL, FALSE, "No refs list gadget");
00328 //  pListGadget->ShowColumnHeaders("", "Item", "Details");
00329     pListGadget->SetColumnWidth(0, 14);     // Status indicators
00330     pListGadget->SetColumnWidth(1, 80);     // Item name
00331     pListGadget->SetColumnWidth(2, 760);    // Details
00332 */
00333     SetDocInfo(TRUE, TRUE);
00334 
00335     return TRUE;
00336 }
00337 
00338             
00339 
00340 /*******************************************************************************************
00341 
00342 >   OpState FileInfo::GetState(String_256*, OpDescriptor*)
00343 
00344     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00345     Created:    23/08/94
00346     Inputs:     -
00347     Outputs:    -
00348     Returns:    -
00349     Purpose:    Returns the OpState of the file info dialogue operation
00350     Errors:     -
00351     SeeAlso:    -
00352 
00353 *******************************************************************************************/
00354 OpState FileInfo::GetState(String_256*, OpDescriptor*)
00355 {
00356     return OpState(FALSE, (Document::GetSelected() == NULL));
00357 }
00358 
00359          
00360 
00361 /*******************************************************************************************
00362 
00363 >   BOOL FileInfo::Init()
00364 
00365     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00366     Created:    23/08/94
00367     Inputs:     -
00368     Outputs:    -
00369     Returns:    FALSE if it fails (due to lack of memory)
00370     Purpose:    Creates an OpDescriptor for a file info dialog
00371     Errors:     -
00372     SeeAlso:    -
00373 
00374 *******************************************************************************************/
00375 BOOL FileInfo::Init()
00376 {  
00377     return RegisterOpDescriptor(
00378                                 0,                              // Tool ID
00379                                 _R(IDS_FILE_INFO),                  // String resouirce ID
00380                                 CC_RUNTIME_CLASS(FileInfo),     // Runtime class
00381                                 OPTOKEN_FINFODLG,               // Token string
00382                                 FileInfo::GetState,             // GetState function
00383                                 0,                              // Help ID
00384                                 _R(IDBBL_FILEINFO),                 // Bubble ID
00385                                 _R(IDD_BARCONTROLSTORE),            // Resource ID
00386                                 _R(IDC_FILEINFO),                   // Control ID
00387                                 SYSTEMBAR_FILE,                 // Bar ID
00388                                 TRUE,                           // Recieve system messages
00389                                 FALSE,                          // Smart duplicate operation
00390                                 TRUE,                           // Clean operation
00391                                 0,                              // No vertical counterpart
00392                                 _R(IDS_FILEINFO_ONE),               // String for one copy only
00393                                 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags
00394                                 );
00395 }   
00396  
00397 
00398          
00399 /*******************************************************************************************
00400 
00401 >   void FileInfo::Do(OpDescriptor*)
00402 
00403     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00404     Created:    23/08/94 
00405     Inputs:     -
00406     Outputs:    -
00407     Returns:    -
00408     Purpose:    Creates and shows a file info dialog
00409     Errors:     -
00410     SeeAlso:    -
00411 
00412 *******************************************************************************************/
00413 void FileInfo::Do(OpDescriptor*)
00414 {
00415     Create();
00416     Open();
00417     CurrentDialog = this;
00418 }
00419 
00420 /*******************************************************************************************
00421 
00422 >   void FileInfo::Refresh()
00423 
00424     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
00425     Created:    10/05/95 
00426     Inputs:     -
00427     Outputs:    -
00428     Returns:    -
00429     Purpose:    Can be called by anyone to force an update  Errors:     -
00430     SeeAlso:    -
00431 
00432 *******************************************************************************************/
00433 void FileInfo::Refresh()
00434 {
00435     if (CurrentDialog)
00436         CurrentDialog->SetDocInfo(TRUE,TRUE);
00437 
00438 }
00439 
00440 
00441 /*******************************************************************************************
00442 
00443 >   BOOL FileInfo::UpdateFontList(Document* WorkDoc)                  
00444 
00445     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00446     Created:    13/11/95
00447     Inputs:     WorkDoc     pointer to the document we are working on, NULL if no document
00448     Outputs:    -
00449     Returns:    True if completed ok, False otherwise.
00450     Purpose:    Updates the font name list with the current list of fonts in the selected
00451                 document. If no fonts are present then shows this by using a blank list and
00452                 putting a suitable message in the top item. If the specified document is
00453                 null then will just show a blank list with a dashed and greyed top item.
00454     Errors:     -
00455     SeeAlso:    SetDocInfo; FontDropDown; DocumentFontDropDown;
00456 
00457 *******************************************************************************************/
00458 
00459 BOOL FileInfo::UpdateFontList(Document* WorkDoc)
00460 {
00461 //  CCustomList* pListGadget = CCustomList::GetGadget(GetReadWriteWindowID(), _R(IDC_FINFO_REFSLIST));
00462 //  ERROR2IF(pListGadget == NULL, FALSE, "No list gadget?!");
00463 
00464     List ItemList;
00465 
00466     // Build the font list for the specified document
00467     // This will NOT be alphabetical
00468     FontListItem* FontItem = NULL;
00469     if (WorkDoc)
00470     {
00471         FontList DocFonts;
00472         DocFonts.Build(WorkDoc);
00473         FontItem = DocFonts.GetFirstItem();
00474 
00475         // fill up the list
00476         while (FontItem != NULL)
00477         {
00478             // get the name
00479             UINT32 idBitmap = 0;
00480             String_64 strName = FontItem->GetFontName();
00481             String_256 strDetails;
00482             
00483             WORD Handle = FONTMANAGER->GetFontHandle(&strName);
00484 
00485             // check the style
00486             INT32 Style = FontItem->GetFontStyle();
00487             if (Style & 1)
00488                 strName += _T(" -Bold");
00489             if (Style & 2)
00490                 strName += _T(" -Italic");
00491             
00492             if (Handle > 0)
00493             {
00494                 if (FONTMANAGER->IsFontReplaced(Handle))
00495                     strDetails = String(_R(IDS_FINFO_FONTNOTINSTALLED));
00496             }
00497             FontClass Type = FontItem->GetFontClass();
00498             switch(Type)
00499             {
00500                 case FC_TRUETYPE:
00501                     idBitmap = _R(IDB_TTF_SYMBOL);
00502                     break;
00503 
00504                 case FC_ATM:
00505                     idBitmap = _R(IDB_ATM_SYMBOL);
00506                     break;
00507 
00508                 default:
00509                     idBitmap = 0;
00510                     break;
00511             }
00512 
00513             AddToSortedList(ItemList, idBitmap, strName, strDetails);
00514             
00515             FontItem = DocFonts.GetNextItem(FontItem);
00516 
00517             ContinueSlowJob();
00518         }
00519     }
00520 
00521     // Put the sorted items in the list gadget
00522     RefItem* pRefItem = (RefItem*)ItemList.GetHead();
00523     while (pRefItem)
00524     {
00525         // Add the font in the list to the list box
00526 //      pListGadget->AddRefsItem(pRefItem->idBitmap, pRefItem->strItemName, pRefItem->strDetails);
00527         CFileInfoList::CListRow oNewRow = m_lstctrlExternalResInfo.AddRow();
00528         oNewRow.SetBitmap(pRefItem->idBitmap);
00529         oNewRow.SetText(1, pRefItem->strItemName);
00530         oNewRow.SetText(2, pRefItem->strDetails);
00531         
00532 
00533         pRefItem = (RefItem*)ItemList.GetNext(pRefItem);
00534     }
00535 
00536     ItemList.DeleteAll();
00537 
00538     return TRUE;
00539 }
00540 
00541 
00542 /*******************************************************************************************
00543 
00544 >   BOOL FileInfo::UpdateEffectsList(Document*  pWorkDoc)
00545 
00546     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00547     Created:    31/01/2005
00548     Inputs:     WorkDoc     pointer to the document we are working on, NULL if no document
00549     Outputs:    -
00550     Returns:    True if completed ok, False otherwise.
00551     Purpose:    Updates the effects list showing referred and missing effects
00552     Errors:     -
00553     SeeAlso:    SetDocInfo; FontDropDown; DocumentFontDropDown;
00554 
00555 *******************************************************************************************/
00556 
00557 BOOL FileInfo::UpdateEffectsList(Document* pWorkDoc)
00558 {
00559     // Make a list of all unique effects used in the doc
00560     // Add each list item to the listbox, marking it if the referred effect can not
00561     // be found in the installed effect list
00562 
00563 //  CCustomList* pListGadget = CCustomList::GetGadget(GetReadWriteWindowID(), _R(IDC_FINFO_REFSLIST));
00564 //  ERROR2IF(pListGadget == NULL, FALSE, "No list gadget?!");
00565 
00566     if (pWorkDoc == NULL)   // Don't try to fill in anything when the window is shaded
00567     {
00568         return TRUE;
00569     }
00570 
00571     List ItemList;
00572 
00573 PORTNOTE("other", "Disabled bitmap effects")
00574 #ifndef EXCLUDE_FROM_XARALX
00575     ListRange* pEffectList = pWorkDoc->GetEffectsList(500000);  // Arbitrary large number
00576     if (pEffectList)
00577     {
00578         // Now add listed items to the ListBox
00579         INT32 index = 0;
00580         Node* pNode = pEffectList->FindFirst();
00581         while (pNode)
00582         {
00583             ENSURE(pNode->IsBitmapEffect(), "How can this node not be a BitmapEffect?");
00584 
00585             if (pNode->IsBitmapEffect())
00586             {
00587                 NodeBitmapEffect* pEffect = (NodeBitmapEffect*)pNode;
00588 
00589                 String_64 strEffectName = pEffect->GetDisplayName();
00590                 String_256 strDetails;
00591                 UINT32 idBitmap = 0;
00592 
00593                 if (pEffect->IsLockedEffect())
00594                 {
00595                     // Destructive/locked effects have their own bitmap stored in them
00596                     // So we don't need to test whether their handler is installed on this machine
00597                     String_64 strFoundDisplayName;
00598                     BOOL bFound = XPEHost::GetEffectDetails(pEffect->GetPostProcessorID(), &strFoundDisplayName);
00599                     if (bFound)
00600                     {
00601                         strDetails = String(_R(IDS_FINFO_EFFECTOK));
00602                         idBitmap = _R(IDB_FINFO_OKEFFECT);
00603                     }
00604                     else
00605                     {
00606                         strDetails = String(_R(IDS_FINFO_LOCKEDEFFECT));
00607                         idBitmap = _R(IDB_FINFO_LOCKEDEFFECT);
00608                     }
00609                 }
00610                 else
00611                 {
00612                     // Live effects need to regenerate their bitmaps so we must
00613                     // test whether the handler is present and warn the user if not
00614                     String_64 strFoundDisplayName;
00615                     BOOL bFound = XPEHost::GetEffectDetails(pEffect->GetPostProcessorID(), &strFoundDisplayName);
00616                     if (bFound)
00617                     {
00618                         strDetails = String(_R(IDS_FINFO_EFFECTOK));
00619                         idBitmap = _R(IDB_FINFO_OKEFFECT);
00620                     }
00621                     else
00622                     {
00623                         strDetails = String(_R(IDS_FINFO_NOTFOUND));
00624                         strDetails += String(" [");
00625                         strDetails += pEffect->GetPostProcessorID();
00626                         strDetails += String("]");
00627                         idBitmap = _R(IDB_FINFO_MISSINGEFFECT);
00628                     }
00629                 }
00630                 AddToSortedList(ItemList, idBitmap, strEffectName, strDetails);
00631 
00632                 ContinueSlowJob();
00633             }
00634 
00635             pNode = pEffectList->FindNext(pNode);
00636         }
00637 
00638         delete pEffectList;
00639         pEffectList = NULL;
00640     }
00641 #endif
00642     // Put the sorted items in the list gadget
00643     RefItem* pRefItem = (RefItem*)ItemList.GetHead();
00644     while (pRefItem)
00645     {
00646         // Add the font in the list to the list box
00647 //      pListGadget->AddRefsItem(pRefItem->idBitmap, pRefItem->strItemName, pRefItem->strDetails);
00648         CFileInfoList::CListRow oNewRow = m_lstctrlExternalResInfo.AddRow();
00649         oNewRow.SetBitmap(pRefItem->idBitmap);
00650         oNewRow.SetText(1, pRefItem->strItemName);
00651         oNewRow.SetText(2, pRefItem->strDetails);
00652 
00653         pRefItem = (RefItem*)ItemList.GetNext(pRefItem);
00654     }
00655 
00656     ItemList.DeleteAll();
00657 
00658     return TRUE;
00659 }
00660 
00661 
00662 /*******************************************************************************************
00663 
00664 >   BOOL FileInfo::SetDocInfo(BOOL UpdateComment, BOOL UpdateFonts)
00665 
00666     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00667     Created:    25/08/94
00668     Inputs:     UpdateComment - TRUE if the comment field should be updated.  Normally
00669                 FALSE for fast updates (otherwise the comment field looses newly entered
00670                 text).
00671                 UpdateFonts - TRUE if we want to update the font list avoid if possible 
00672                 as this causes a rebuild of the font list and much flicker..
00673     Outputs:    -
00674     Returns:    -
00675     Purpose:    Sets the values in the fields of the document information dialogue.
00676     Errors:     -
00677     SeeAlso:    -
00678 
00679 *******************************************************************************************/
00680 BOOL FileInfo::SetDocInfo(BOOL UpdateComment, BOOL UpdateFonts)
00681 {
00682     Document*   WorkDoc = Document::GetSelected();
00683 
00684     if (UpdateFonts)
00685     {
00686         BeginSlowJob();
00687         GadgetRedraw(_R(IDC_FINFO_REFSLIST), FALSE);    // Disable redraw while updating
00688 
00689 //      INT32 iSelectedItem = pListGadget->GetSelectedItemIndex();
00690 //      INT32 iScrollPos = pListGadget->GetScrollPos(SB_VERT);
00691         
00692         m_lstctrlExternalResInfo.Clear();
00693 
00694         // Work out all the document based fonts again and recreate the drop down list
00695         CFileInfoList::CListRow oNewRow = m_lstctrlExternalResInfo.AddRow();
00696         oNewRow.SetText(1, String(_R(IDS_FINFO_FONTREFS_NAMEHEADER)));
00697         oNewRow.SetText(2, String(_R(IDS_FINFO_FONTREFS_DETAILSHEADER)));
00698         
00699         UpdateFontList(WorkDoc);
00700 
00701         // Show effects usage
00702 //      pListGadget->AddRefsItem(0, String(_R(IDS_FINFO_EFFECTREFS_NAMEHEADER)), String(_R(IDS_FINFO_EFFECTREFS_DETAILSHEADER)));
00703         oNewRow = m_lstctrlExternalResInfo.AddRow();
00704         oNewRow.SetText(1, String(_R(IDS_FINFO_EFFECTREFS_NAMEHEADER)));
00705         oNewRow.SetText(2, String(_R(IDS_FINFO_EFFECTREFS_DETAILSHEADER)));
00706         
00707         UpdateEffectsList(WorkDoc);
00708 
00709 //      pListGadget->SetSelectedItemIndex(iSelectedItem);
00710 //      pListGadget->SetScrollPos(SB_VERT, iScrollPos, FALSE);
00711 
00712         GadgetRedraw(_R(IDC_FINFO_REFSLIST), TRUE);     // Enable redraw while updating
00713         InvalidateGadget(_R(IDC_FINFO_REFSLIST));       // Force redraw now that we're done
00714         EndSlowJob();
00715     }
00716 
00717     // If there is no selected document then we want to set the fields to be blank 
00718     if (WorkDoc == NULL)
00719     {
00720         String_8    DashString(_R(IDS_K_FINFODLG_DASH));
00721         String_8    NullString = _T("");
00722         UpdateStringGadgetValue(_R(IDC_FILEINFO_UNDOSIZE),      &DashString);
00723         UpdateStringGadgetValue(_R(IDC_FILEINFO_UNDOSTEPS),     &DashString);
00724 //      UpdateStringGadgetValue(_R(IDC_FILEINFO_SPREADS),           &DashString);
00725 //      UpdateStringGadgetValue(_R(IDC_FILEINFO_PAGES),         &DashString);
00726         UpdateStringGadgetValue(_R(IDC_FILEINFO_NUMOBJECTS),        &DashString);
00727         UpdateStringGadgetValue(_R(IDC_FILEINFO_NUMSELOBJECTS), &DashString);
00728         UpdateStringGadgetValue(_R(IDC_FILEINFO_LOCATION),      &DashString);
00729         UpdateStringGadgetValue(_R(IDC_FILEINFO_FILENAME),      &DashString);
00730         UpdateStringGadgetValue(_R(IDC_FILEINFO_FILESIZE),      &DashString);
00731         UpdateStringGadgetValue(_R(IDC_FILEINFO_NUMBITMAPS),        &DashString);
00732         UpdateStringGadgetValue(_R(IDC_FILEINFO_BITMAPSIZE),        &DashString);
00733         UpdateStringGadgetValue(_R(IDC_FILEINFO_FRACTALS),      &DashString);
00734         UpdateStringGadgetValue(_R(IDC_FILEINFO_FRACTALSIZE),       &DashString);
00735         UpdateStringGadgetValue(_R(IDC_FILEINFO_CREATIONDATE),  &DashString);
00736         UpdateStringGadgetValue(_R(IDC_FILEINFO_LASTSAVEDATE),  &DashString);
00737         UpdateStringGadgetValue(_R(IDC_FILEINFO_COMMENT),           &NullString);
00738         return TRUE;
00739     }
00740 
00741     // Declare the general strings we use throughout
00742     String_256  String;
00743     String_256  String2;
00744 
00745     // Keep a list of the bitmaps that we have found in our scan so that we do not
00746     // count the same bitmap twice
00747     BitmapList.DeleteAll();
00748 
00749     // --
00750     // -- Display the undo and redo steps for the document
00751     // --
00752 
00753     // Now calculate the size of the undo buffer and if any records have been discarded
00754     Convert::BytesToString(&String, WorkDoc->GetOpHistory().GetSize());
00755     if (WorkDoc->GetOpHistory().IsReduced())
00756     {
00757         String2.MakeMsg(_R(IDS_FILEINFO_REDUCED));
00758         String += String2;
00759     }
00760     UpdateStringGadgetValue(_R(IDC_FILEINFO_UNDOSIZE), &String);
00761 
00762     // Now calculate the number of undo and redo steps
00763     UINT32  UndoSteps = WorkDoc->GetOpHistory().GetNumUndoSteps();
00764     UINT32  RedoSteps = WorkDoc->GetOpHistory().GetNumRedoSteps();
00765     String = "";
00766     if (UndoSteps != 0)
00767     {
00768         String.MakeMsg(_R(IDS_FILEINFO_UNDOSTEPS), UndoSteps);
00769         if (UndoSteps == 1)
00770             String2.MakeMsg(_R(IDS_FILEINFO_STEP));
00771         else
00772             String2.MakeMsg(_R(IDS_FILEINFO_STEPS));
00773         String += String2;
00774     }
00775     if (RedoSteps != 0)
00776     {
00777         String_256  String3;
00778         String2.MakeMsg(_R(IDS_FILEINFO_REDOSTEPS), RedoSteps); 
00779         if (String.CompareTo(_T("")) != 0)
00780             String += String_64(_R(IDS_K_FINFODLG_SEPERATOR));
00781         if (RedoSteps == 1)
00782             String3.MakeMsg(_R(IDS_FILEINFO_STEP));
00783         else
00784             String3.MakeMsg(_R(IDS_FILEINFO_STEPS));
00785         String += String2;
00786         String += String3;
00787     }
00788     if (String.CompareTo(_T("")) == 0)
00789     {
00790         String.MakeMsg(_R(IDS_FILEINFO_NOSTEPS)); 
00791         UpdateStringGadgetValue(_R(IDC_FILEINFO_UNDOSTEPS), &String);
00792     }
00793     else
00794     {
00795         UpdateStringGadgetValue(_R(IDC_FILEINFO_UNDOSTEPS), &String);
00796     }
00797 
00798     // --
00799     // -- Display the comment field for the current document
00800     // --
00801 
00802     // Update the comment field if we should
00803     if (UpdateComment)
00804     {
00805         String = WorkDoc->GetComment();
00806         UpdateStringGadgetValue(_R(IDC_FILEINFO_COMMENT), &String);
00807     }
00808 
00809     // Now scan the document for the various object counts
00810     BitmapInfo  BitInfo;
00811     Node*   CurrentNode = StartTreeScan(WorkDoc);
00812     UINT32  Spreads = 0;                          
00813     UINT32  Pages = 0;
00814     UINT32  Bitmaps = 0; 
00815     UINT32  BitmapSize = 0;
00816     UINT32  Objects = 0;
00817     UINT32  SelObjects = 0;
00818     UINT32  Groups = 0;
00819     UINT32  Size = 0;
00820     BOOL    DontGetNext = TRUE;
00821 
00822     while (CurrentNode != NULL)
00823     {
00824         Size += CurrentNode->GetNodeSize();
00825         DontGetNext = TRUE;
00826 
00827         if (CurrentNode->IsAnObject())
00828         {           
00829             // If it's a renderable object then count it.
00830             Objects ++;
00831 
00832             // This is silly as there is already a function to do this (SelRange::Count)
00833             // and using this method we won't be counting selected inside items.
00834             //if (CurrentNode->IsSelected())
00835             //{
00836             //  SelObjects++;
00837             //}
00838 
00839             if (CurrentNode->IS_KIND_OF(NodeGroup) || IS_A(CurrentNode,TextStory))
00840             {   // Count objects inside groups, moulds and blends as one object
00841                 // as these are renderable and would otherwise be included in the count.
00842                 // Need to do the same with TextStories as these contain the renderable
00843                 // text lines and text characters ...
00844                 // Don't want to count objects inside groups (or blends) so sidestep
00845                 Size += CurrentNode->GetSubtreeSize();
00846                 CurrentNode = SkipSubtreeScan(CurrentNode);
00847                 DontGetNext = FALSE;
00848                 // Increment our group count if this is a real group rather than a blend
00849                 // or a mould or a text story. 
00850                 if (IS_A(CurrentNode,NodeGroup))
00851                     Groups++;
00852             }
00853             else
00854             {
00858                 //Objects ++;
00859                 
00860                 if (IS_A(CurrentNode,NodeBitmap))
00861                 {   // We've found a bitmap, so we need to see whether it is in our list of
00862                     // previously found bitmaps.  If we have found it before then we can
00863                     // ignore it.  Otherwise, we add it to the list and add its size to our
00864                     // size count.
00865                     Bitmaps ++;
00866                     NodeListItem* CurrentBitmapNode = (NodeListItem*)BitmapList.GetHead();
00867                     BOOL Found = FALSE;
00868 
00869                     while (CurrentBitmapNode != NULL)
00870                     {
00871                         if ((((NodeBitmap*)CurrentBitmapNode->pNode)->GetBitmap()->ActualBitmap) == 
00872                                                 (((NodeBitmap*)CurrentNode)->GetBitmap()->ActualBitmap))
00873                         {
00874                             Found = TRUE;
00875                         }
00876                         CurrentBitmapNode = (NodeListItem*)BitmapList.GetNext(CurrentBitmapNode);
00877                     }
00878                     if (!Found)
00879                     {
00880                         ((NodeBitmap*)CurrentNode)->GetBitmap()->ActualBitmap->GetInfo(&BitInfo);
00881                         BitmapSize += BitInfo.MemoryUsed;
00882                         CurrentBitmapNode = new NodeListItem(CurrentNode);
00883                         BitmapList.AddHead(CurrentBitmapNode);
00884                     }
00885                 }
00886             }
00887         }
00888         else
00889         {   // Increment specific non-renderable object counts.
00890             if (IS_A(CurrentNode,Spread))
00891             {
00892                 Spreads ++;
00893             }
00894             else
00895             {
00896                 if (IS_A(CurrentNode,Page))
00897                 {
00898                     Pages ++;
00899                 }
00900             }
00901         }
00902         if ((CurrentNode != NULL) && DontGetNext)
00903         {
00904             CurrentNode = GetNextTreeNode(CurrentNode);
00905         }                                                                
00906     }
00907 
00908     // Now work out the number of objects that are currently selected
00909     // Find the application and hence the selection range
00910     Application* pApplication = GetApplication();
00911     if (pApplication)
00912     {
00913         // First, check if there is a selection present. ClipRect should be empty if not.
00914         SelRange* pSelection = pApplication->FindSelection();
00915         // If there is a selection then count it
00916         if (pSelection)
00917         {
00918             SelObjects = pSelection->Count();
00919         }
00920     }
00921 
00922     // --
00923     // -- Display number of pages and number of spreads in the document
00924     // --
00925 
00926 // No longer required as only one spread in version 1.0
00927 //  String._MakeMsg("#1%lu", Spreads);
00928 //  UpdateStringGadgetValue(_R(IDC_FILEINFO_SPREADS), &String);
00929 //  String._MakeMsg("#1%lu", Pages);
00930 //  UpdateStringGadgetValue(_R(IDC_FILEINFO_PAGES), &String);
00931 
00932     // --
00933     // -- Display number of objects and number of selected objects
00934     // --
00935 
00936     // Show some of the information that we found
00937     String._MakeMsg(_T("#1%lu"), Objects);
00938     UpdateStringGadgetValue(_R(IDC_FILEINFO_NUMOBJECTS), &String);
00939     String._MakeMsg(_T("#1%lu"), SelObjects);
00940     UpdateStringGadgetValue(_R(IDC_FILEINFO_NUMSELOBJECTS), &String);
00941 
00942     // --
00943     // -- Display count and size of fractals in the document
00944     // --
00945 
00946     // Show the current number of fractals and bitmaps in this document 
00947     // First the fractals.
00948     Application * Camelot = GetApplication();   
00949     EnumFractalData FracData;
00950     if (Camelot)
00951     {
00952         GlobalFractalList * FracList = Camelot->GetGlobalFractalList();
00953         if (FracList)
00954             FracList->GetDocumentFractalData(WorkDoc,&FracData);
00955     }
00956     String._MakeMsg(_T("#1%lu"), FracData.Count);
00957     UpdateStringGadgetValue(_R(IDC_FILEINFO_FRACTALS), &String);
00958     Convert::BytesToString(&String, FracData.Size);
00959     UpdateStringGadgetValue(_R(IDC_FILEINFO_FRACTALSIZE), &String);
00960 
00961     // --
00962     // -- Display count and size of bitmaps in the document
00963     // --
00964 
00965     INT32 BitmapsCount = 0;
00966     INT32 BitmapsSize = 0;
00967     if (Camelot)
00968     {
00969         GlobalBitmapList * BmpList = Camelot->GetGlobalBitmapList();
00970         if (BmpList)
00971         {
00972             BitmapsCount = BmpList->GetDocumentBitmapCount(WorkDoc);
00973             BitmapsSize = BmpList->GetDocumentBitmapSize(WorkDoc);
00974         }
00975     }
00976     //String._MakeMsg("#1%lu", Bitmaps);
00977     String._MakeMsg(_T("#1%lu"), BitmapsCount);
00978     UpdateStringGadgetValue(_R(IDC_FILEINFO_NUMBITMAPS), &String);
00979     //BytesToString(&String, BitmapSize);
00980     Convert::BytesToString(&String, BitmapsSize);
00981     UpdateStringGadgetValue(_R(IDC_FILEINFO_BITMAPSIZE), &String);
00982 
00983     // Now show our final size 
00984     // Add in the number of bitmaps that we found as these will be saved with the
00985     // document. Don't include fractals as these are regenerated on loading. 
00986     // Current thinking seems to be that we should show the fractals as well as this
00987     // field is now memory used.
00988     Size += BitmapsSize;
00989     Size += FracData.Size;
00990     Convert::BytesToString(&String, Size);
00991     UpdateStringGadgetValue(_R(IDC_FILEINFO_FILESIZE), &String);
00992 
00993     // --
00994     // -- Display Location and Filename of document
00995     // --
00996 
00997     // Show the current pathname for the document
00998     // The number give sthe size that we have to fit the pathname into.
00999     String.Empty();
01000     //String = WorkDoc->GetPathName(45);
01001     String = WorkDoc->GetLocation(41);
01002     if ( String.IsEmpty() )
01003     {
01004         // No pathname yet, so put in a nice message
01005         String.MakeMsg(_R(IDS_FILEINFO_UNSAVED));
01006     }
01007     UpdateStringGadgetValue(_R(IDC_FILEINFO_LOCATION), &String);
01008 
01009     // Now show the current filename
01010     String.Empty();
01011     String = WorkDoc->GetTitle();
01012     UpdateStringGadgetValue(_R(IDC_FILEINFO_FILENAME), &String);
01013 
01014     // --
01015     // -- Display Creation and Save times for the document
01016     // --
01017 
01018     // Now do the creation and save times
01019     time_t  TimeData;
01020     TimeData = WorkDoc->GetCreationTime();
01021             
01022     String = asctime(localtime(&TimeData));
01023     
01024 //  LocalEnvironment::SystemTimeToString(&String, &TimeData);
01025 //  LocalEnvironment::SystemDateToString(&String2, &TimeData);
01026 //  String += _T("  ");
01027 //  String += String2;
01028     UpdateStringGadgetValue(_R(IDC_FILEINFO_CREATIONDATE), &String);
01029 
01030     TimeData = WorkDoc->GetLastSaveTime();
01031     if (TimeData != 0)
01032     {
01033 //      LocalEnvironment::SystemTimeToString(&String, &TimeData);
01034 //      LocalEnvironment::SystemDateToString(&String2, &TimeData);
01035 //      String += _T("  ");
01036 //      String += String2;
01037         String = asctime(localtime(&TimeData));
01038         
01039         UpdateStringGadgetValue(_R(IDC_FILEINFO_LASTSAVEDATE), &String);
01040     }
01041     else
01042     {
01043         String.MakeMsg(_R(IDS_FILEINFO_UNSAVED));
01044         UpdateStringGadgetValue(_R(IDC_FILEINFO_LASTSAVEDATE), &String);
01045     }
01046 
01047 #ifdef STANDALONE
01048     EnableGadget(_R(IDC_FILEINFO_COMMENT),FALSE);
01049 #endif
01050 
01051     return TRUE;
01052 }
01053                     
01054 
01055 /*******************************************************************************************
01056 >   Node* StartTreeScan(Document* pDoc);    
01057     
01058     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01059     Created:    31th August 1994
01060     Inputs:     Pointer to the document to scan.
01061     Returns:    Pointer to the first node.
01062     Purpose:    To scan a tree "not depth first".  Instead of skipping to the bottom of
01063                 the tree and scanning back up I want to scan to the bottom and skip
01064                 back up.  Initialises the scan of the document.
01065     See also:   GetNextTreeNode
01066 *******************************************************************************************/
01067 Node* StartTreeScan(Document* pDoc)
01068 {
01069     if (pDoc == NULL)          
01070     {
01071         ENSURE(FALSE,"NULL document pointer passed to StartTreeScan");
01072         return NULL;
01073     }
01074     return pDoc->GetFirstNode();
01075 }   
01076                              
01077 
01078                                         
01079 /*******************************************************************************************
01080 >   Node* GetNextTreeNode(Node* Current);   
01081     
01082     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01083     Created:    31th August 1994
01084     Inputs:     The current node. 
01085     Returns:    Pointer to the next node.
01086     Purpose:    To scan a tree "not depth first".  Instead of skipping to the bottom of
01087                 the tree and scanning back up I want to scan to the bottom and skip
01088                 back up.  Gets the node after the current one.  Returns NULL if no more
01089     See also:   StartTreeScan, SkipSubTreeScan
01090 *******************************************************************************************/
01091 Node* GetNextTreeNode(Node* Current)
01092 {
01093     if (Current == NULL)
01094     {
01095         ENSURE(FALSE,"NULL node pointer passed to GetNextTreeNode");
01096         return NULL;
01097     }
01098     // first try going down one level
01099     if (Current->FindFirstChild() != NULL)
01100     {
01101         return Current->FindFirstChild();
01102     }
01103     // now try going right one
01104     if (Current->FindNext() != NULL)
01105     {
01106         return Current->FindNext();
01107     }
01108     // if we get this far we need to go up and to the right.
01109     Node* Temp = Current->FindParent();;
01110     while (Temp != NULL)
01111     {
01112         if (Temp->FindNext() != NULL)
01113         {
01114             return Temp->FindNext();
01115         }
01116         Temp = Temp->FindParent();
01117     }
01118     // no more nodes left in the document
01119     return NULL;
01120 }   
01121 
01122 
01123 
01124 /*******************************************************************************************
01125 >   Node* SkipSubtreeScan(Node* Current);   
01126     
01127     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
01128     Created:    31th August 1994
01129     Inputs:     The current node. 
01130     Returns:    Pointer to the next node.
01131     Purpose:    To skip the scan of the children of the current node.  The node returned
01132                 is either a sibling or a parent of the current node.  Can return NULL.
01133     See also:   GetNextTreeNode
01134 *******************************************************************************************/
01135 Node* SkipSubtreeScan(Node* Current)
01136 {
01137     if (Current == NULL)
01138     {
01139         ENSURE(FALSE,"NULL node pointer passed to SkipSubTreeScan");
01140         return NULL;
01141     }
01142     if (Current->FindNext() != NULL)
01143     {
01144         return Current->FindNext();
01145     }
01146 
01147     // now we need to go up and to the right.
01148     Node* Temp = Current->FindParent();
01149     while (Temp != NULL)
01150     {
01151         if (Temp->FindNext() != NULL)
01152         {
01153             return Temp->FindNext();
01154         }
01155         Temp = Temp->FindParent();
01156     }
01157     return NULL;
01158 }   
01159 
01160 
01161 
01162 
01163 
01164 
01165 /*******************************************************************************************
01166 
01167 >   BOOL FileInfo::AddToSortedList(List& ItemList, UINT32 idBitmap, String_64& strItemName, String_256& strDetails)
01168 
01169     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01170     Created:    01/01/2005
01171     Inputs:     List
01172                 Bitmap ID
01173                 Item name
01174                 Item details
01175     Outputs:    -
01176     Returns:    -
01177     Purpose:    Create a new item in the list, insertion sorted alphabetically by item name
01178     Errors:     -
01179     SeeAlso:    -
01180 
01181 *******************************************************************************************/
01182 
01183 BOOL FileInfo::AddToSortedList(List& ItemList, UINT32 idBitmap, String_64& strItemName, String_256& strDetails)
01184 {
01185     RefItem* pNewItem = new RefItem(idBitmap, strItemName, strDetails);
01186     if (pNewItem == NULL)
01187     {
01188         ERROR3("AddRefsItem couldn't create Item");
01189         return FALSE;
01190     }
01191 
01192     // Add the item into the list, in a sorted fashion...
01193     RefItem *pTheItem = (RefItem*)ItemList.GetHead();
01194 
01195     if (pTheItem == NULL)
01196     {
01197         ItemList.AddTail(pNewItem);
01198         return TRUE;
01199     }
01200     
01201     if (pTheItem->strItemName > strItemName)
01202     {
01203         ItemList.InsertBefore(pTheItem, pNewItem);
01204         return TRUE;
01205     }
01206 
01207     while (pTheItem != NULL)
01208     {
01209         RefItem* pTheNextItem = (RefItem*)ItemList.GetNext(pTheItem);
01210 
01211         if (pTheNextItem == NULL)
01212         {
01213             ItemList.InsertAfter(pTheItem, pNewItem);
01214             return TRUE;
01215         }
01216 
01217         if (pTheNextItem->strItemName > strItemName)
01218         {
01219             ItemList.InsertBefore(pTheNextItem, pNewItem);
01220             return TRUE;
01221         }
01222 
01223         // Try the next item
01224         pTheItem = pTheNextItem;
01225     }
01226 
01227     // Should never get here!
01228     ERROR3("Why are we here?");
01229     return FALSE;
01230 }
01231 
01232 
01233 
01234 
01235 

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