bmplist.cpp

Go to the documentation of this file.
00001 // $Id: bmplist.cpp 1488 2006-07-20 15:31:34Z phil $
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 // Kernel level parts of bitmap lists
00100 
00101 /*
00102 */
00103 
00104 #include "camtypes.h"
00105 //#include "bmplist.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 //#include "bitmap.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00107 #include "bitmpinf.h"
00108 //#include "list.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00110 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 //#include "will.h"
00113 //#include "native.h"           // The new designed native filter, used for v2
00114 //#include "nativeps.h"     // The old style EPS native filter, used in v1.1
00115 
00116 #include "clipint.h"
00117 #include "nodebmp.h"
00118 #include "progress.h"
00119 
00120 #include "toollist.h"
00121 #include "objchge.h"
00122 #include "csrstack.h"
00123 
00124 //#include "clipint.h"
00125 #include "ophist.h"
00126 
00127 //#include "will2.h"
00128 
00129 #include "bmpcomp.h"
00130 
00131 //#include "nodecach.h"     // for CacheCompound specific tests in cleaning up GlobalList
00132 
00133 CC_IMPLEMENT_MEMDUMP( GlobalBitmapList, List )
00134 //CC_IMPLEMENT_MEMDUMP( GreyscaleBitmapList, List )
00135 
00136 CC_IMPLEMENT_DYNAMIC(BitmapListChangedMsg, Msg)
00137 #if !defined(EXCLUDE_FROM_RALPH)
00138 CC_IMPLEMENT_DYNCREATE(OpDeleteBitmap,Operation);
00139 #endif
00140 
00141 // Declare smart memory handling in Debug builds
00142 #define new CAM_DEBUG_NEW
00143 
00144 // Preference for the maximum size of the greyscale bitmap list
00145 //INT32 GreyscaleBitmapList::m_lMaxSize = 2 * 1024 * 1024;      // 2MB default max size
00146 
00147 
00148 /**********************************************************************************************
00149 
00150 >   GlobalBitmapList::GlobalBitmapList()
00151 
00152     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00153     Created:    14/12/94
00154     Inputs:     -
00155     Outputs:    -
00156     Returns:    -
00157     Purpose:    GlobalBitmapList constructor
00158 
00159 **********************************************************************************************/
00160 
00161 GlobalBitmapList::GlobalBitmapList()
00162 {
00163 }
00164 
00165 /**********************************************************************************************
00166 
00167 >   GlobalBitmapList::~GlobalBitmapList()
00168 
00169     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00170     Created:    14/12/94
00171     Inputs:     -
00172     Outputs:    -
00173     Returns:    -
00174     Purpose:    GlobalBitmapList destructor
00175 
00176 **********************************************************************************************/
00177 
00178 GlobalBitmapList::~GlobalBitmapList()
00179 {
00180 }
00181 
00182 /**********************************************************************************************
00183 
00184 >   BOOL GlobalBitmapList::Init()
00185 
00186     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00187     Created:    6/2/95
00188     Returns:    FALSE if failed.
00189     Purpose:    Initialise the GlobalBitmapList
00190 
00191 **********************************************************************************************/
00192 
00193 BOOL GlobalBitmapList::Init()
00194 {
00195 //  GreyscaleBitmapList::Init();
00196 
00197 #if !defined(EXCLUDE_FROM_RALPH)
00198     return OpDeleteBitmap::Init();
00199 #else
00200     return TRUE;
00201 #endif
00202 }
00203 
00204 /**********************************************************************************************
00205 
00206 >   BOOL GlobalBitmapList::DeInit()
00207 
00208     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00209     Created:    6/2/95
00210     Returns:    FALSE if failed.
00211     Purpose:    DeInitialise the GlobalBitmapList
00212 
00213 **********************************************************************************************/
00214 
00215 BOOL GlobalBitmapList::DeInit()
00216 {
00217     // First deinit the global bitmap list
00218     GlobalBitmapList* pBmpList = GetApplication()->GetGlobalBitmapList();
00219 
00220     ListItem* pItem = pBmpList->GetHead();
00221 
00222     while (pItem != NULL)
00223     {
00224         ListItem* pNext = pBmpList->GetNext(pItem);
00225 
00226         OILBitmap* pBitmap = (OILBitmap*)pItem;
00227 
00228         ERROR3IF(pBitmap->IsTemp(), "Warning.  Found temp bitmap in global bitmap list");
00229 
00230         if (pBitmap == OILBitmap::Default)
00231         {
00232             // Don't delete the default bitmap, just remove it from the list
00233             pBitmap->RemoveFromGlobalList();
00234         }
00235         else
00236         {
00237             delete pBitmap;     // This will remove it from the list before deleting it
00238         }
00239 
00240         pItem = pNext;
00241     }
00242 
00243     // Now deinit the greyscale bitmap list
00244 //  GreyscaleBitmapList::DeInit();
00245 
00246     return TRUE;
00247 }
00248 
00249 /**********************************************************************************************
00250 
00251 >   BOOL GlobalBitmapList::AddItem(OILBitmap *Item)
00252 
00253     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00254     Created:    14/12/94
00255     Returns:    TRUE
00256     Purpose:    Adds an item to the tail of the GlobalBitmaplist
00257 
00258 **********************************************************************************************/
00259 
00260 BOOL GlobalBitmapList::AddItem(OILBitmap *Item)
00261 {
00262     ERROR3IF(Item == NULL, "Trying to add NULL item to Global Bitmap List");
00263     
00264     if (Item == NULL)
00265         return FALSE;
00266 
00267     // Is this Bitmap already in the list ?
00268     LISTPOS pos = FindPosition((ListItem*)Item);
00269 
00270     if (pos == NOT_IN_LIST || pos == EMPTY_LIST)
00271     {
00272         // It's not in the list yet, so add it on the end
00273         AddTail((ListItem*)Item);
00274         return TRUE;
00275     }
00276     else
00277     {
00278         // It's already in the list, so just return
00279         return FALSE;
00280     }
00281 }
00282 
00283 /**********************************************************************************************
00284 
00285 >   ListItem* GlobalBitmapList::GetFirstBitmapName(String_256* BitmapName)
00286 
00287     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00288     Created:    14/12/94
00289     Returns:    The bitmap found at the head of the List, or NULL if none found.
00290     Purpose:    Find the names of the bitmaps in the list
00291 
00292 **********************************************************************************************/
00293 
00294 ListItem* GlobalBitmapList::GetFirstBitmapName(String_256* BitmapName)
00295 {
00296     ListItem* First = GetHead();
00297     
00298     while (First != NULL)
00299     {
00300         if (!((OILBitmap*)First)->HasBeenDeleted())
00301         {
00302             *BitmapName = ((OILBitmap*)First)->GetName();
00303             return First;
00304         }
00305 
00306         First = GetNext(First);
00307     }
00308 
00309     return NULL;
00310 }
00311 
00312 /**********************************************************************************************
00313 
00314 >   ListItem* GlobalBitmapList::GetNextBitmapName(ListItem* Prev, String_256* BitmapName)
00315 
00316     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00317     Created:    14/12/94
00318     Returns:    The next bitmap in the List, or NULL if none found.
00319     Purpose:    Find the names of the bitmaps in the list
00320 
00321 **********************************************************************************************/
00322 
00323 ListItem* GlobalBitmapList::GetNextBitmapName(ListItem* Prev, String_256* BitmapName)
00324 {
00325     ListItem* Next = GetNext(Prev);
00326     
00327     while (Next != NULL)
00328     {
00329         if (!((OILBitmap*)Next)->HasBeenDeleted())
00330         {
00331             *BitmapName = ((OILBitmap*)Next)->GetName();
00332             return Next;
00333         }
00334 
00335         Next = GetNext(Next);
00336     }
00337 
00338     return NULL;
00339 }
00340 
00341 /**********************************************************************************************
00342 
00343 >   OILBitmap* GlobalBitmapList::GetBitmapFromName(String_256* BitmapName)
00344 
00345     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00346     Created:    14/12/94
00347     Returns:    Ptr to Bitmap of the name given, or NULL if not found.
00348     Purpose:    Finds a bitmap with a particular name.
00349 
00350 **********************************************************************************************/
00351 
00352 OILBitmap* GlobalBitmapList::GetBitmapFromName(String_256* BitmapName)
00353 {
00354     ListItem* pItem = GetHead();
00355     
00356     while (pItem != NULL)
00357     {
00358         OILBitmap* pBmp = (OILBitmap*)pItem;
00359         
00360         if (!pBmp->HasBeenDeleted())
00361         {
00362             if (*BitmapName == pBmp->GetName())
00363                 return pBmp;
00364         }
00365 
00366         pItem = GetNext(pItem);
00367     }
00368 
00369     return NULL;
00370 }
00371 
00372 /**********************************************************************************************
00373 
00374 >   void GlobalBitmapList::MakeNameUnique(String_256* BitmapName)
00375 
00376     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00377     Created:    14/12/94
00378     Purpose:    Ensures a bitmap name is unique.
00379 
00380 **********************************************************************************************/
00381 
00382 void GlobalBitmapList::MakeNameUnique(String_256* BitmapName)
00383 {
00384     ListItem* Bitmap = GetHead();
00385 
00386     INT32 Number = 1;
00387     String_256 Name = *BitmapName;
00388 
00389     while (Bitmap != NULL)
00390     {
00391         if ( Name == ((OILBitmap*)Bitmap)->GetName() )
00392         {
00393             // This name already exists, so lets make it unique
00394             String_256  Str;
00395             camSnprintf( Str, 256, TEXT("%d"), Number++ );
00396             Name = (*BitmapName);
00397             Name += Str;
00398 
00399             Bitmap = GetHead(); // Start at the beginning again
00400         }
00401         else
00402         {
00403             Bitmap = GetNext(Bitmap);
00404         }
00405     }   
00406 
00407     *BitmapName = Name;
00408 }
00409 
00410 
00411 /**********************************************************************************************
00412 
00413 >   OILBitmap* GlobalBitmapList::FindDuplicateBitmap(OILBitmap* pBitmap)
00414 
00415     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00416     Created:    14/8/96
00417     Purpose:    Looks to see if an identical bitmap is already in the bitmap list
00418 
00419 **********************************************************************************************/
00420 
00421 OILBitmap* GlobalBitmapList::FindDuplicateBitmap(OILBitmap* pOILBitmap)
00422 {
00423     ListItem* pItem = GetHead();
00424 
00425     while (pItem != NULL)
00426     {
00427         OILBitmap* pBmp = (OILBitmap*)pItem;
00428 
00429         ERROR3IF(pBmp == pOILBitmap, "Why is this bitmap already in the list ?");
00430 
00431         if (pBmp != pOILBitmap &&
00432             *pBmp == *pOILBitmap)
00433         {
00434             return pBmp;
00435         }
00436 
00437         pItem = GetNext(pItem);
00438     }
00439 
00440     return NULL;
00441 }
00442 
00443 
00444 /**********************************************************************************************
00445 
00446 >   INT32 GlobalBitmapList::GetDocumentBitmapCount(Document* pDoc)
00447 
00448     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00449     Created:    14/8/96
00450     Purpose:    Find how many bitmaps are being used by this document
00451 
00452 **********************************************************************************************/
00453 
00454 INT32 GlobalBitmapList::GetDocumentBitmapCount(Document* pDoc)
00455 {
00456     INT32 Count = 0;
00457     INT32 DefaultIsUsed = FALSE;
00458 
00459     if (pDoc != NULL)
00460     {
00461         // Now get the actual bitmap list
00462         BitmapList* Bitmaps = pDoc->GetBitmapList();
00463 
00464         if (Bitmaps)
00465         {
00466             // Go through all the bitmaps in the list 
00467             ListItem *Ptr = Bitmaps->GetHead();
00468             while (Ptr != NULL)
00469             {
00470                 KernelBitmap* Bmp = (KernelBitmap*)Ptr;
00471 
00472                 if (Bmp->IsDefaultBitmap() && !DefaultIsUsed)
00473                 {
00474                     if (Bmp->IsUsedInDocument(pDoc))
00475                         DefaultIsUsed = TRUE;
00476                 }
00477                 else if (Bmp->IsUsedInDocument(pDoc))
00478                 {
00479                     Count++;
00480                 }
00481                 
00482                 Ptr = Bitmaps->GetNext(Ptr);
00483             }
00484         }
00485     }
00486 
00487     if (DefaultIsUsed) Count++;
00488 
00489     return Count;
00490 }
00491 
00492 /**********************************************************************************************
00493 
00494 >   INT32 GlobalBitmapList::GetDocumentBitmapSize(Document* pDoc)
00495 
00496     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00497     Created:    14/8/96
00498     Purpose:    Find the total size of the bitmaps being used by this document
00499 
00500 **********************************************************************************************/
00501 
00502 INT32 GlobalBitmapList::GetDocumentBitmapSize(Document* pDoc)
00503 {
00504     INT32 Mem = 0;
00505     INT32 DefaultIsUsed = FALSE;
00506 
00507     if (pDoc != NULL)
00508     {
00509         // Now get the actual bitmap list
00510         BitmapList* Bitmaps = pDoc->GetBitmapList();
00511 
00512         if (Bitmaps)
00513         {
00514             // Go through all the bitmaps in the list 
00515             ListItem *Ptr = Bitmaps->GetHead();
00516             while (Ptr != NULL)
00517             {
00518                 KernelBitmap* Bmp = (KernelBitmap*)Ptr;
00519 
00520                 if (Bmp->IsDefaultBitmap() && !DefaultIsUsed)
00521                 {
00522                     if (Bmp->IsUsedInDocument(pDoc))
00523                         DefaultIsUsed = TRUE;
00524                 }
00525                 else if (Bmp->IsUsedInDocument(pDoc))
00526                 {
00527                     Mem += Bmp->ActualBitmap->GetBitmapSize();
00528                 }
00529                 
00530                 Ptr = Bitmaps->GetNext(Ptr);
00531             }
00532         }
00533     }
00534 
00535     if (DefaultIsUsed) 
00536     {
00537         Mem += OILBitmap::Default->GetBitmapSize();
00538     }
00539 
00540     return Mem;
00541 }
00542 
00543 /**********************************************************************************************
00544 
00545 >   BOOL GlobalBitmapList::IsUsedInDocument(Document * pDoc, OILBitmap* pOILBmp)
00546 
00547     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00548     Created:    12/8/97
00549     Inputs:     pDoc    Document to check bitmap list of
00550                 pOILBmp the OIL bitmap to find in the list
00551     Returns:    True if the bitmap is found, False otherwise
00552     Purpose:    Checks if the specified OIL bitmap is in the bitmap list of the specified
00553                 document.
00554     SeeAlso:    DeleteAllUnusedBitmaps;
00555 
00556 **********************************************************************************************/
00557 
00558 BOOL GlobalBitmapList::IsUsedInDocument(Document * pDoc, OILBitmap* pOILBmp)
00559 {
00560     ERROR2IF(pDoc == NULL || pOILBmp == NULL,FALSE,"GlobalBitmapList::IsUsedInDocument Bad params!");
00561     
00562     // Get the bitmap list for the specified document
00563     BitmapList* pBitmaps = pDoc->GetBitmapList();
00564     if (pBitmaps)
00565     {
00566         ListItem* pKBmp = pBitmaps->GetHead();
00567 
00568         while (pKBmp)
00569         {
00570             KernelBitmap* pBmp = (KernelBitmap*)pKBmp;
00571 
00572             if (pBmp->ActualBitmap == pOILBmp)
00573             {
00574                 // Found a copy of the bitmap and so return TRUE
00575                 return TRUE;
00576             }
00577 
00578 PORTNOTETRACE("other","GlobalBitmapList::IsUsedInDocument - skip XPE master bit");
00579 #ifndef EXCLUDE_FROM_XARALX
00580             // Check whether this bitmap is an XPE master
00581             if (pBmp->ActualBitmap)
00582             {
00583                 OILBitmap* pMaster = NULL;
00584                 IXMLDOMDocumentPtr pInfo = NULL;
00585                 pBmp->ActualBitmap->GetXPEInfo(pMaster, pInfo);
00586                 if (pMaster == pOILBmp)
00587                     return TRUE;
00588             }
00589 #endif
00590 
00591             pKBmp = pBitmaps->GetNext(pKBmp);
00592         }
00593     }
00594 
00595     // Bitmap not found and so return FALSE
00596     return FALSE;
00597 }
00598 
00599 /**********************************************************************************************
00600 
00601 >   void GlobalBitmapList::DeleteAllUnusedBitmaps()
00602 
00603     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00604     Created:    14/8/96
00605     Purpose:    Called when a document is deleted, to delete all the unused bitmaps
00606 
00607 **********************************************************************************************/
00608 
00609 void GlobalBitmapList::DeleteAllUnusedBitmaps()
00610 {
00611     InternalClipboard::AttrsHaveChanged();
00612     // As we now have two clipboards, we need to sort out both
00613     InternalClipboard::Swap(); // Swap to alternative clipboard
00614     InternalClipboard::AttrsHaveChanged();
00615     InternalClipboard::Swap(); // Swap back to orignal clipboard
00616 
00617     ListItem* pItem = GetHead();
00618     
00619     while (pItem != NULL)
00620     {
00621         OILBitmap* pOILBmp = (OILBitmap*)pItem;
00622 
00623         ERROR3IF(pOILBmp->IsAFractal(), "There's a fractal in the global list !  How'd that happen ?");
00624 
00625         BOOL IsUsed = FALSE;
00626 
00627         if (pOILBmp == OILBitmap::Default)
00628         {
00629             IsUsed = TRUE;
00630         }
00631         // DY 16/3/2000, we don't want to delete bitmaps that are used by brushes when the
00632         // document they are in is deleted. 
00633         if (pOILBmp->IsUsedByBrush())
00634         {
00635             IsUsed = TRUE;
00636         }
00637         else
00638         {
00639             // Go though all the documents
00640             Document* pDoc = (Document*)GetApplication()->Documents.GetHead();
00641             while (pDoc != NULL)
00642             {
00643                 if (IsUsedInDocument(pDoc, pOILBmp))
00644                 {
00645                     IsUsed = TRUE;
00646                     break;
00647                 }
00648 
00649                 // Move onto the next document
00650                 pDoc = (Document*)GetApplication()->Documents.GetNext(pDoc);
00651             }
00652 
00653 #if !defined(EXCLUDE_FROM_RALPH)
00654             // Now check the ClipBoard to see if the Bitmap is in there
00655             if (!IsUsed && IsBitmapOnClipBoard(pOILBmp))
00656             {
00657                 IsUsed = TRUE;
00658                 //break;
00659             }
00660             
00661             // Should do this but will ERROR2 on exit as the clipboard has no doc components
00662             // Should be ok as we now clear out the bitmap lists when the clipboard is cleared
00663             /*if (!IsUsed)
00664             {
00665                 Document * pClipDoc = InternalClipboard::Instance();
00666                 if (pClipDoc && IsUsedInDocument(pClipDoc, pOILBmp))
00667                 {
00668                     IsUsed = TRUE;
00669                 }
00670             } */
00671 
00672             // As we now have two clipboards, we need to check both
00673             // Now check the ClipBoard to see if the Bitmap is in there
00674             if (!IsUsed)
00675             {
00676                 InternalClipboard::Swap(); // Swap to alternative clipboard
00677                 if (IsBitmapOnClipBoard(pOILBmp))
00678                 {
00679                     IsUsed = TRUE;
00680                     // break;
00681                 }
00682                 InternalClipboard::Swap(); // Swap back to orignal clipboard
00683             }
00684 
00685             // Should do this but will ERROR2 on exit as the clipboard has no doc components
00686             // Should be ok as we now clear out the bitmap lists when the clipboard is cleared
00687             /*if (!IsUsed)
00688             {
00689                 Document * pClipDoc = InternalClipboard::Other();
00690                 if (pClipDoc && IsUsedInDocument(pClipDoc, pOILBmp))
00691     .           {
00692                     IsUsed = TRUE;
00693                 }
00694             } */
00695 #endif
00696 
00697         }
00698 
00699         // Get next item before we delete this item
00700         pItem = GetNext(pItem);
00701 
00702         if (!IsUsed)
00703         {
00704             delete pOILBmp; // Delete if not used
00705             pOILBmp = NULL;
00706         }
00707     }
00708 }
00709 
00710 /**********************************************************************************************
00711 
00712 >   BOOL GlobalBitmapList::IsBitmapOnClipBoard(OILBitmap* pOILBmp)
00713 
00714     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00715     Created:    14/8/96
00716     Purpose:    Check to see if a bitmap is used on the clipboard
00717 
00718 **********************************************************************************************/
00719 
00720 BOOL GlobalBitmapList::IsBitmapOnClipBoard(OILBitmap* pOILBmp)
00721 {
00722 #if !defined(EXCLUDE_FROM_RALPH)
00723 
00724     // Clear out any Cached attrs on the Clipboard
00725     Node* Subtree = (Node*) InternalClipboard::GetInsertionLayer();
00726     if (!Subtree) return FALSE;
00727 
00728     Range ClipRange(Subtree->FindFirstChild(),
00729                     Subtree->FindLastChild(),
00730                     RangeControl(TRUE,TRUE,TRUE,TRUE));
00731 
00732     // Go though all the nodes on the clipboard
00733     Node* Current = ClipRange.FindFirst();
00734     while (Current != NULL)
00735     {
00736         // And search right down each subtree
00737         Node* pNodeToCheck = Current->FindFirstDepthFirst();
00738     
00739         while (pNodeToCheck != NULL)
00740         {
00741             // See if this node uses the bitmap
00742             INT32 Count = 0;
00743 
00744             // Does this node have any bitmaps in it ?
00745             KernelBitmap* pKernelBmp = pNodeToCheck->EnumerateBitmaps(Count++);
00746 
00747             while (pKernelBmp != NULL)
00748             {
00749                 // Found a bitmap reference, but ... is it the one we want ?
00750                 if (pKernelBmp->GetActualBitmap() == pOILBmp)
00751                 {
00752                     return TRUE;
00753                 }
00754                 
00755                 // Check whether this bitmap is an XPE master
00756                 if (pKernelBmp->GetActualBitmap())
00757                 {
00758 PORTNOTE("other","Removed IXMLDOMDocumentPtr usage")
00759 #ifndef EXCLUDE_FROM_XARALX
00760                     OILBitmap* pMaster = NULL;
00761                     IXMLDOMDocumentPtr pInfo = NULL;
00762                     pKernelBmp->GetActualBitmap()->GetXPEInfo(pMaster, pInfo);
00763                     if (pMaster == pOILBmp)
00764                         return TRUE;
00765 #endif
00766                 }
00767 
00768                 pKernelBmp = pNodeToCheck->EnumerateBitmaps(Count++);               
00769             }
00770             
00771             pNodeToCheck = pNodeToCheck->FindNextDepthFirst(Current);
00772         }
00773 
00774         Current = ClipRange.FindNext(Current);
00775     }
00776 
00777 #endif
00778 
00779     return FALSE;
00780 }
00781 
00782 /**********************************************************************************************
00783 
00784 >   GreyscaleBitmapList* GlobalBitmapList::GetGreyscaleBitmapList()
00785 
00786     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00787     Created:    14/8/96
00788     Purpose:    Get a pointer to the greyscale bitmap list
00789 
00790 **********************************************************************************************/
00791 
00792 //GreyscaleBitmapList* GlobalBitmapList::GetGreyscaleBitmapList()
00793 //{
00794 //  return &GreyscaleBitmaps;
00795 //}
00796 
00797 
00798 #ifdef _DEBUG
00799 
00800 void GlobalBitmapList::DumpGlobalBitmapListToTrace()
00801 {
00802     TRACEALL( _T("\nDumping Global bitmap list ...\n\n") );
00803 
00804     INT32 TotalSize = 0;
00805     INT32 Count = 0;
00806     
00807     ListItem* pItem = GetHead();
00808     
00809     while (pItem != NULL)
00810     {
00811         OILBitmap* pBmp = (OILBitmap*)pItem;
00812 
00813         if (pBmp->HasBeenDeleted())
00814         {
00815             TRACEALL( _T("OILBitmap @ %x, (Deleted)\n"), pBmp);
00816         }
00817         else
00818         {
00819             TRACEALL( _T("OILBitmap @ %x, '%s', Size=%d bytes"), pBmp, (TCHAR*)pBmp->GetName(), pBmp->GetBitmapSize());
00820 
00821             if (pBmp->IsGreyscale())
00822                 TRACEALL( _T(", (Greyscale)") );
00823 
00824             TRACEALL( _T("\n") );
00825         
00826             TotalSize += pBmp->GetBitmapSize();
00827         }
00828 
00829         Count++;
00830 
00831         pItem = GetNext(pItem);
00832     }
00833 
00834     TRACEALL( _T("\n") );
00835     TRACEALL( _T("Total bitmaps = %d\n"), Count );
00836     TRACEALL( _T("Total size    = %d bytes\n\n"), TotalSize );
00837 }
00838 
00839 #endif
00840 
00841 
00842 
00843 #if 0
00844 /**********************************************************************************************
00845 
00846 >   GreyscaleBitmapList::GreyscaleBitmapList()
00847 
00848     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00849     Created:    14/12/94
00850     Inputs:     -
00851     Outputs:    -
00852     Returns:    -
00853     Purpose:    GreyscaleBitmapList constructor
00854 
00855 **********************************************************************************************/
00856 
00857 GreyscaleBitmapList::GreyscaleBitmapList()
00858 {
00859     m_CurrentSize = 0;
00860 }
00861 
00862 /**********************************************************************************************
00863 
00864 >   GreyscaleBitmapList::~GreyscaleBitmapList()
00865 
00866     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00867     Created:    14/12/94
00868     Inputs:     -
00869     Outputs:    -
00870     Returns:    -
00871     Purpose:    GreyscaleBitmapList destructor
00872 
00873 **********************************************************************************************/
00874 
00875 GreyscaleBitmapList::~GreyscaleBitmapList()
00876 {
00877 }
00878 
00879 /**********************************************************************************************
00880 
00881 >   BOOL GreyscaleBitmapList::Init()
00882 
00883     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00884     Created:    6/2/95
00885     Returns:    FALSE if failed.
00886     Purpose:    Initialise the GreyscaleBitmapList
00887 
00888 **********************************************************************************************/
00889 
00890 BOOL GreyscaleBitmapList::Init()
00891 {
00892     if (Camelot.DeclareSection("Screen", 1))
00893     {
00894         Camelot.DeclarePref( NULL, "MaxGreyscaleCacheSize", (UINT32*)&m_lMaxSize);
00895     }
00896 
00897     GreyscaleBitmapList* pGreyList = 
00898             GetApplication()->GetGlobalBitmapList()->GetGreyscaleBitmapList();
00899 
00900     pGreyList->SetMaxGreyscaleSize(m_lMaxSize);
00901 
00902     return TRUE;
00903 }
00904 
00905 /**********************************************************************************************
00906 
00907 >   BOOL GreyscaleBitmapList::DeInit()
00908 
00909     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00910     Created:    6/2/95
00911     Returns:    FALSE if failed.
00912     Purpose:    DeInitialise the GreyscaleBitmapList
00913 
00914 **********************************************************************************************/
00915 
00916 BOOL GreyscaleBitmapList::DeInit()
00917 {
00918     GreyscaleBitmapList* pGreyList = 
00919             GetApplication()->GetGlobalBitmapList()->GetGreyscaleBitmapList();
00920 
00921     ListItem* pItem = pGreyList->GetHead();
00922 
00923     while (pItem != NULL)
00924     {
00925         ListItem* pNext = pGreyList->GetNext(pItem);
00926 
00927         OILBitmap* pBitmap = (OILBitmap*)pItem;
00928         delete pBitmap;     // This will remove it from the list before deleting it
00929 
00930         pItem = pNext;
00931     }
00932 
00933     return TRUE;
00934 }
00935 
00936 /**********************************************************************************************
00937 
00938 >   BOOL GreyscaleBitmapList::AddItem(OILBitmap *Item)
00939 
00940     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00941     Created:    14/12/94
00942     Returns:    TRUE
00943     Purpose:    Adds an item to the tail of the GreyscaleBitmaplist
00944 
00945 **********************************************************************************************/
00946 
00947 BOOL GreyscaleBitmapList::AddItem(OILBitmap *Item)
00948 {
00949     ERROR3IF(Item == NULL, "Trying to add NULL item to Greyscale Bitmap List");
00950     if (Item == NULL)
00951         return FALSE;
00952 
00953     ERROR2IF(!Item->IsGreyscale(), FALSE, "Trying to add a non-grey bitmap to Greyscale Bitmap List");
00954 
00955     // Is this Bitmap already in the list ?
00956     LISTPOS pos = FindPosition((ListItem*)Item);
00957 
00958     if (pos == NOT_IN_LIST || pos == EMPTY_LIST)
00959     {
00960         // It's not in the list yet, so add it on the end
00961         AddTail((ListItem*)Item);
00962 
00963         TRACEUSER( "Will", _T("Added new Greyscale bitmap to list\n") );
00964 
00965         // Check we haven't gone over the maximum size for the list
00966         CheckSizeIsOk();
00967 
00968         return TRUE;
00969     }
00970     else
00971     {
00972         // It's already in the list, so just return
00973         return FALSE;
00974     }
00975 }
00976 
00977 /**********************************************************************************************
00978 
00979 >   ListItem* GreyscaleBitmapList::RemoveItem(ListItem* Item)
00980 
00981     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00982     Created:    18/03/2004
00983     Returns:    TRUE
00984     Purpose:    Adds an item to the tail of the GreyscaleBitmaplist
00985 
00986 **********************************************************************************************/
00987 
00988 ListItem* GreyscaleBitmapList::RemoveItem(ListItem* Item)
00989 {
00990     m_CurrentSize -= ((OILBitmap*)Item)->GetBitmapSize();
00991     return List::RemoveItem(Item);
00992 }
00993 
00994 void GreyscaleBitmapList::AddHead(ListItem* Item)
00995 {
00996     List::AddHead(Item);
00997     m_CurrentSize += ((OILBitmap*)Item)->GetBitmapSize();
00998 }
00999 
01000 void GreyscaleBitmapList::AddTail(ListItem* Item)
01001 {
01002     List::AddTail(Item);
01003     m_CurrentSize += ((OILBitmap*)Item)->GetBitmapSize();
01004 }
01005 
01006 ListItem* GreyscaleBitmapList::RemoveHead()
01007 {
01008     ListItem* pItem = List::RemoveHead();
01009 
01010     if (pItem)
01011         m_CurrentSize -= ((OILBitmap*)pItem)->GetBitmapSize();
01012 
01013     return pItem;
01014 }
01015 
01016 ListItem* GreyscaleBitmapList::RemoveTail()
01017 {
01018     ListItem* pItem = List::RemoveTail();
01019 
01020     if (pItem)
01021         m_CurrentSize -= ((OILBitmap*)pItem)->GetBitmapSize();
01022 
01023     return pItem;
01024 }
01025 
01026 LISTPOS GreyscaleBitmapList::InsertBefore(LISTPOS here, ListItem* item)
01027 {
01028     ERROR3("Not implemented");
01029     return 0;
01030 }
01031 
01032 ListItem* GreyscaleBitmapList::InsertBefore(ListItem* here, ListItem* item)
01033 {
01034     ERROR3("Not implemented");
01035     return NULL;
01036 }
01037 
01038 LISTPOS GreyscaleBitmapList::InsertAfter(LISTPOS here, ListItem* item)
01039 {
01040     ERROR3("Not implemented");
01041     return 0;
01042 }
01043 
01044 ListItem* GreyscaleBitmapList::InsertAfter(ListItem* here, ListItem* item)
01045 {
01046     ERROR3("Not implemented");
01047     return NULL;
01048 }
01049 
01050 /**********************************************************************************************
01051 
01052 >   INT32 GreyscaleBitmapList::GetCurrentGreyscaleSize()
01053 
01054     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01055     Created:    14/8/96
01056     Purpose:    Gets the current total size of the list
01057 
01058 **********************************************************************************************/
01059 
01060 INT32 GreyscaleBitmapList::GetCurrentGreyscaleSize()
01061 {   
01062 /*  INT32 CurrentSize = 0;
01063 
01064     OILBitmap* pItem = (OILBitmap*)GetHead();
01065 
01066     while (pItem)
01067     {
01068         INT32 ItemSize = pItem->GetBitmapSize();
01069         CurrentSize += ItemSize;
01070 
01071         pItem = (OILBitmap*)GetNext(pItem);
01072     }
01073 
01074     return CurrentSize;
01075 */
01076     return m_CurrentSize;
01077 }
01078 
01079 /**********************************************************************************************
01080 
01081 >   void GreyscaleBitmapList::SetMaxGreyscaleSize(INT32 NewMaxSize)
01082 
01083     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01084     Created:    14/8/96
01085     Purpose:    Sets the maximum size that the list can grow to
01086 
01087 **********************************************************************************************/
01088 
01089 void GreyscaleBitmapList::SetMaxGreyscaleSize(INT32 NewMaxSize)
01090 {
01091     if (NewMaxSize < 0)
01092         NewMaxSize = 0;
01093 
01094     if (NewMaxSize > 16*1024*1024)      // 16MB should be plenty for a few years
01095         NewMaxSize = 16*1024*1024;
01096 
01097     m_lMaxSize = NewMaxSize;
01098 
01099     TRACEUSER( "Will", _T("Setting MaxGreyscaleSize to %d bytes\n"), m_lMaxSize );
01100 
01101     // And check the list is not bigger than the new size
01102     CheckSizeIsOk();
01103 }
01104 
01105 /**********************************************************************************************
01106 
01107 >   INT32 GreyscaleBitmapList::GetMaxGreyscaleSize()
01108 
01109     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01110     Created:    14/8/96
01111     Purpose:    Gets the current maximum size that the list can grow to
01112 
01113 **********************************************************************************************/
01114 
01115 INT32 GreyscaleBitmapList::GetMaxGreyscaleSize()
01116 {
01117     return m_lMaxSize;
01118 }
01119 
01120 /**********************************************************************************************
01121 
01122 >   void GreyscaleBitmapList::CheckSizeIsOk()
01123 
01124     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01125     Created:    14/8/96
01126     Purpose:    Ensures the list is smaller than the max list size, and throws away
01127                 bitmaps from the start of the list if not
01128 
01129 **********************************************************************************************/
01130 
01131 void GreyscaleBitmapList::CheckSizeIsOk()
01132 {
01133     INT32 CurrentSize = GetCurrentGreyscaleSize();
01134     INT32 MaxSize = GetMaxGreyscaleSize();
01135 
01136     TRACEUSER( "Will", _T("CheckSizeIsOk, current size is %d bytes, max is %d bytes\n"), CurrentSize, MaxSize );
01137 
01138     if (CurrentSize > MaxSize)
01139     {
01140         // How many bytes do we need to remove ?
01141         INT32 SizeToRemove = CurrentSize - MaxSize;
01142         INT32 SizeRemoved = 0;
01143 
01144         TRACEUSER( "Will", _T("Trying to remove %d bytes from greyscale list\n"), SizeToRemove );
01145 
01146         OILBitmap* pItem = (OILBitmap*)GetHead();
01147         if (pItem == NULL)
01148             return;
01149 
01150         while (pItem && (SizeRemoved < SizeToRemove))
01151         {
01152             OILBitmap* pNextItem = (OILBitmap*)GetNext(pItem);
01153 
01154             INT32 ItemSize = pItem->GetBitmapSize();
01155 
01156             // Remove it from this list
01157             RemoveItem(pItem);
01158 
01159             // and delete it
01160             delete pItem;
01161             
01162             SizeRemoved += ItemSize;
01163             pItem = pNextItem;
01164         }
01165 
01166         TRACEUSER( "Will", _T("New size is %d bytes\n"), CurrentSize - SizeRemoved );
01167         ERROR3IF(SizeRemoved < SizeToRemove, "Couldn't free enough memory in Greyscale list");
01168     }
01169 }
01170 
01171 
01172 
01173 #ifdef _DEBUG
01174 
01175 void GreyscaleBitmapList::DumpGreyscaleBitmapListToTrace()
01176 {
01177     TRACEALL( _T("\nDumping Greyscale bitmap list ...\n\n") );
01178 
01179     INT32 TotalSize = 0;
01180     INT32 Count = 0;
01181     
01182     ListItem* pItem = GetHead();
01183     
01184     while (pItem != NULL)
01185     {
01186         OILBitmap* pBmp = (OILBitmap*)pItem;
01187 
01188         TRACEALL( _T("Grey bitmap @ %x, '%s', Size=%d bytes\n"), pBmp, (TCHAR*)pBmp->GetName(), pBmp->GetBitmapSize());
01189     
01190         TotalSize += pBmp->GetBitmapSize();
01191         Count++;
01192 
01193         pItem = GetNext(pItem);
01194     }
01195 
01196     TRACEALL( _T("\n"));
01197     TRACEALL( _T("Total bitmaps = %d\n"), Count);
01198     TRACEALL( _T("Total size    = %d bytes\n"), TotalSize);
01199     TRACEALL( _T("Max size      = %d bytes\n\n"), GetMaxGreyscaleSize());
01200 }
01201 
01202 #endif
01203 
01204 #endif // 0
01205 
01206 
01207 
01208 
01209 #if !defined(EXCLUDE_FROM_RALPH)
01210 
01211 //-----------------------------------------------------------------------------------------------
01212 // OpDeleteBitmap - Delete all references to a bitmap, and remove it from memory
01213 
01214 /********************************************************************************************
01215 
01216 >   BOOL OpDeleteBitmap::Init()
01217 
01218     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01219     Created:    16/2/95
01220     Returns:    TRUE if the operation could be successfully initialised 
01221                 FALSE if no more memory could be allocated 
01222     Purpose:    OpDeleteBitmap initialiser method
01223     Errors:     ERROR will be called if there was insufficient memory to allocate the 
01224                 operation.
01225     SeeAlso:    -
01226 
01227 ********************************************************************************************/
01228 
01229 BOOL OpDeleteBitmap::Init()
01230 {
01231     return (RegisterOpDescriptor(
01232                                 0,
01233                                 0,
01234                                 CC_RUNTIME_CLASS(OpDeleteBitmap),
01235                                 OPTOKEN_DELETEBITMAP,
01236                                 OpDeleteBitmap::GetState,
01237                                 0,  /* help ID */
01238                                 0,
01239                                 0   /* bitmap ID */));
01240 }               
01241     
01242 /********************************************************************************************
01243 
01244 >   OpState OpDeleteBitmap::GetState(String_256*, OpDescriptor*)
01245 
01246     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01247     Created:    16/2/95
01248     Returns:    The state of the OpDeleteBitmap operation
01249     Purpose:    For finding the OpDeleteBitmap's state. 
01250     Errors:     -
01251     SeeAlso:    -
01252 
01253 ********************************************************************************************/
01254 
01255 OpState OpDeleteBitmap::GetState(String_256* UIDescription, OpDescriptor*)
01256 {
01257     OpState OpSt;
01258     return(OpSt);
01259 }
01260 
01261 /********************************************************************************************
01262 
01263 >   void OpDeleteBitmap::DoDelete(OILBitmap* BmpToDelete)
01264 
01265     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01266     Created:    16/2/95
01267     Inputs:     pOpParam: Param1 contains a pointer to the OILBitmap to delete.
01268     Purpose:    Frees the memory used by a bitmap
01269     Errors:     -
01270     SeeAlso:    -
01271 
01272 ********************************************************************************************/
01273 
01274 void OpDeleteBitmap::DoDelete(OILBitmap* pBmpToDelete)
01275 {
01276     // Declared up 'ere, 'cus of the goto thingy
01277     Document* Doc;
01278     OILBitmap* poBmp = NULL;
01279 
01280     // Set the busy cursor . . .
01281     String_64 StatusText =  String_64(_R(IDS_K_BMPLIST_DELBMPOPEN));
01282     StatusText +=   pBmpToDelete->GetName();
01283     StatusText +=   String_64(_R(IDS_K_BMPLIST_DELBMPCLOSE));
01284 
01285     BeginSlowJob(-1, FALSE, &StatusText);
01286 
01287     // Remember the current document
01288     Document* pCurrent  = Document::GetCurrent();
01289 
01290     ObjChangeFlags cFlags;
01291     cFlags.TransformNode = TRUE;    // The node is going to be changed to point at a
01292                                     // different bitmap, which is a Bit like transforming
01293                                     // it I suppose ?
01294 
01295     cFlags.Attribute = TRUE;        // Needed to make Blends re-calc themselves
01296 
01297     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL);
01298 
01299     // Don't do anything if the bitmap is NULL, or if it's the default bitmap
01300     if (pBmpToDelete == NULL || pBmpToDelete == OILBitmap::Default)
01301         goto EndOperation;
01302 
01303     ERROR3IF(pBmpToDelete->HasBeenDeleted(), "This bitmap has been deleted already !");
01304 
01305     // -------------------------------------------------------------
01306     // If this bitmap is an XPE master bitmap then we must unlink
01307     poBmp = (OILBitmap*) GetApplication()->GetGlobalBitmapList()->GetHead();
01308     while (poBmp)
01309     {
01310         if (poBmp->m_pMasterBitmap == pBmpToDelete)
01311         {
01312             poBmp->RebuildXPEBitmap();      // Ensure that we have a generated bitmap
01313             poBmp->DestroyXPEInfo();        // Unlink this bitmap from the master being deleted
01314         }
01315 
01316         poBmp = (OILBitmap*) GetApplication()->GetGlobalBitmapList()->GetNext(poBmp);
01317     }
01318 
01319     // -------------------------------------------------------------
01320     // Go though all the documents
01321     Doc = (Document*)GetApplication()->Documents.GetHead();
01322     while (Doc != NULL)
01323     {
01324         // Set the document to be current, because the bitmap system needs this
01325         // so it knows which bitmap list to look at.
01326         Doc->SetCurrent();
01327 
01328         // First we look at the doc component bitmap list to see if the bitmap
01329         // we deleted is in there somewhere
01330         BOOL BitmapIsInList = FALSE;
01331 
01332         BitmapList* pBitmaps = Doc->GetBitmapList();
01333         if (pBitmaps != NULL)
01334         {
01335             KernelBitmap* pBitmap = (KernelBitmap*)pBitmaps->GetHead();
01336             while (pBitmap)
01337             {
01338                 if (pBitmap->GetActualBitmap() == pBmpToDelete)
01339                 {
01340                     // We've found the bitmap, so flag thaat we need to 
01341                     // scan the tree
01342                     BitmapIsInList = TRUE;
01343                     break;
01344                 }
01345 
01346                 pBitmap = (KernelBitmap*)pBitmaps->GetNext(pBitmap);
01347             }
01348         }
01349 
01350         if (BitmapIsInList)
01351         {
01352             // If the bitmap was found in the list somewhere, then we need to scan
01353             // though the document tree, and make sure we redraw any nodes that
01354             // use the bitmap
01355 
01356             BOOL DocModified = FALSE;
01357 
01358             // Scan the document's tree for bitmap references
01359             Node* pNode = Node::DocFindFirstDepthFirst(Doc);
01360             while (pNode != NULL)
01361             {
01362                 // Ignore hidden nodes
01363                 if (!pNode->IsNodeHidden())
01364                 {
01365                     INT32 Count = 0;
01366 
01367                     // Does this node have any bitmaps in it ?
01368                     KernelBitmap* pBitmap = pNode->EnumerateBitmaps(Count++);
01369 
01370                     while (pBitmap != NULL)
01371                     {
01372                         // Found a bitmap reference, but ... is it the one that we deleted ?
01373                         if (pBitmap->GetActualBitmap() == pBmpToDelete)
01374                         {
01375                             // pBmpToDelete is being deleted, so we MUST reset any bitmapref
01376                             // that references it to the default (otherwise we still reference the
01377                             // deleted bitmap) ....
01378                             if (IS_A (pNode, NodeBitmap))
01379                             {
01380                                 // i'm only willing to do this for NodeBitmaps!  Not sure about
01381                                 // any other type of node that overides the EnumerateBitmaps function
01382                                 // (they look scary).
01383                                 NodeBitmap* pBitmap = (NodeBitmap*) pNode;
01384                                 pBitmap->GetBitmapRef ()->SetBitmap (pBitmaps->FindDefaultBitmap());
01385                             }
01386                             
01387                             // Make sure the node is redrawn
01388                             ForceRedrawOfNode(Doc, pNode, &ObjChange);
01389                             DocModified = TRUE;
01390                         }
01391                         
01392                         pBitmap = pNode->EnumerateBitmaps(Count++);             
01393                     }
01394                 }
01395 
01396                 // Move onto the next node in the tree
01397                 pNode = pNode->DocFindNextDepthFirst(); 
01398             }
01399 
01400             if (DocModified)
01401             {
01402                 // Flag that the document has changed
01403                 Doc->SetModified(TRUE);
01404             }
01405         }
01406 
01407         // Move onto the next document
01408         Doc = (Document*)GetApplication()->Documents.GetNext(Doc);
01409     }
01410 
01411     // Now delete the bitmap data
01412     pBmpToDelete->DeleteData();
01413 
01414     // and make sure all the bitmap list are updated ...
01415     // (this needs to be done after the bitmap data is deleted)
01416     Doc = (Document*)GetApplication()->Documents.GetHead();
01417     while (Doc != NULL)
01418     {
01419         BROADCAST_TO_ALL(BitmapListChangedMsg(Doc->GetBitmapList())); 
01420         Doc = (Document*)GetApplication()->Documents.GetNext(Doc);
01421     }
01422 
01423     // Restore the current document
01424     if (pCurrent)
01425         pCurrent->SetCurrent();
01426 
01427 EndOperation:
01428     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,NULL);
01429     UpdateAllChangedNodes(&ObjChange);
01430 
01431     EndSlowJob();
01432     End();
01433 }
01434 
01435 /********************************************************************************************
01436 
01437 >   void OpDeleteBitmap::ForceRedrawOfNode(Document* Doc, Node* pNodeToRedraw, 
01438                                        ObjChangeParam* pObjChange)
01439 
01440     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01441     Created:    27/6/95
01442     Inputs:     -
01443     Purpose:    -
01444     Errors:     -
01445     SeeAlso:    -
01446 
01447 ********************************************************************************************/
01448 
01449 void OpDeleteBitmap::ForceRedrawOfNode(Document* Doc, Node* pNodeToRedraw, 
01450                                        ObjChangeParam* pObjChange)
01451 {
01452 
01453     /*BOOL Allowed =*/ pNodeToRedraw->AllowOp(pObjChange);
01454     // Ignore the Allowed state, do it regardless ...
01455 
01456     // Force a redraw on the object and it's parent.
01457     Node* pParent = pNodeToRedraw;
01458     Spread* pSpread = pNodeToRedraw->FindParentSpread();
01459 
01460     while (pSpread != NULL && pParent != NULL)
01461     {
01462         Node* pPrevParent = pParent->FindParent();
01463 
01464         if (pPrevParent && pPrevParent->IsLayer())
01465         {
01466             DocRect Bounds = 
01467                 ((NodeRenderableBounded*)pParent)->GetBoundingRect();
01468             Doc->ForceRedraw(pSpread, Bounds, FALSE, pParent);
01469         }
01470 
01471         pParent = pPrevParent;
01472     }
01473 }
01474 
01475 #endif

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