bfxopun.cpp

Go to the documentation of this file.
00001 // $Id: bfxopun.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 // 
00099 
00100 #include "camtypes.h"
00101 
00102 // temp bodge, must be here to avoid Rect problems
00103 #include "makebmp.h"        // MakeBitmapFilter;
00104 
00105 #include "bfxopun.h"        // useful Bfx plug-in related undoable operations
00106 #include "bfxop.h"          // useful Bfx plug-in related operations
00107 //#include "plugres.h"      // _R(IDS_PLUGIN_FAMILY)
00108 
00109 #include "plugmngr.h"       // main plug-in manager
00110 #include "bfxitem.h"        // useful Bfx plug-in related items
00111 //#include "app.h"          // GetApplication() - in camtypes.h [AUTOMATICALLY REMOVED]
00112 
00113 //#include "bitmap.h"           // KernelBitmap - in camtypes.h [AUTOMATICALLY REMOVED]
00114 
00115 //#include "simon.h"            // _R(IDS_NO_DOC) _R(IDS_NO_OBJECTS_SELECTED)
00116 //#include "nodebmp.h"      // NodeBitmap
00117 //#include "fillattr.h"     // AttrFillGeometry
00118 
00119 // Place any IMPLEMENT type statements here
00120 CC_IMPLEMENT_DYNCREATE(BfxPlugInUndoOp, PlugInUndoOp);
00121 
00122 // We want better memory tracking
00123 #define new CAM_DEBUG_NEW
00124 
00125 /********************************************************************************************
00126 
00127 >   BfxPlugInUndoOp::BfxPlugInUndoOp()
00128 
00129     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00130     Created:    6/3/97
00131     Inputs:
00132     Outputs:
00133     Returns:
00134     Purpose:    Constructor for BfxPlugInUndoOp operation. It is undoable.
00135                 It is derived off PlugInUndoOp which is derived off
00136                 SelOperation as we are working off the selection.
00137     Errors:     None
00138 
00139 ********************************************************************************************/
00140 
00141 BfxPlugInUndoOp::BfxPlugInUndoOp()
00142 {
00143 }
00144 
00145 /********************************************************************************************
00146 
00147 >   static BOOL BfxPlugInUndoOp::Init()
00148 
00149     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00150     Created:    6/3/97
00151     Returns:    TRUE if the Op was started ok
00152     Purpose:    Creates all the opDescriptors that call this operation.
00153 
00154 ********************************************************************************************/
00155 
00156 BOOL BfxPlugInUndoOp::Init()
00157 {
00158     BOOL ok = TRUE;
00159     // Set up some standard operations
00160     //ok = ok && RegisterOpToken(OPTOKEN_Bfx_UNDO_PLUGINS, _R(IDS_Bfx_PLUGINS),
00161     //                         CC_RUNTIME_CLASS(BfxPlugInUndoOp), BfxPlugInUndoOp::GetState);
00162     //ok = ok && RegisterOpToken(OPTOKEN_Bfx_UNDO_APPLYLAST, _R(IDS_Bfx_APPLYLAST),
00163     //                         CC_RUNTIME_CLASS(BfxPlugInUndoOp), BfxPlugInUndoOp::GetState);
00164 
00165     return ok;
00166 }
00167 
00168 /********************************************************************************************
00169 
00170 >   static BOOL BfxPlugInUndoOp::CheckBitmapWithPlugIn(const String_256& OpName,
00171                                                        KernelBitmap * pBitmap,
00172                                                        BOOL IncludeUniqueName = TRUE,
00173                                                        BOOL IncludeUndoAbleSig = FALSE)
00174 
00175     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00176     Created:    6/3/97
00177     Inputs:     OpName              - the name of the OpToken being requested.
00178                 pBitmap             - the bitmap being checked.
00179                 IncludeUniqueName   - Set to True (Default) if want the
00180                         unique name of the plug-in added to the OpToken
00181                 IncludeUndoAbleSig  - Set to True is want the unique undoable
00182                         sig added to the OpToken. (Default = FALSE.)
00183     Returns:    True if the item is ok with the plug-in, False otherwise
00184     Purpose:    To ask the plug-in which matches the OpName whether the
00185                 bitmap is ok.
00186                 Assumes only working on Bfx plug-ins. Not that this should
00187                 make much difference at present.
00188     SeeAlso:    PLugInOp::CheckBitmapWithPlugIn;
00189 
00190 ********************************************************************************************/
00191 
00192 BOOL BfxPlugInUndoOp::CheckBitmapWithPlugIn(const String_256& OpName, KernelBitmap * pBitmap,
00193                                             BOOL IncludeUniqueName, BOOL IncludeUndoAbleSig)
00194 {
00195     // If no bitmap then always return False
00196     if (pBitmap == NULL)
00197         return FALSE;
00198 
00199     // Search the plug-ins list for the specified plug-in and check
00200     // that this colour depth is ok with it
00201     INT32 ColourDepth = pBitmap->GetBPP();
00202     BOOL GreyScale = pBitmap->IsGreyscale();
00203     PlugInManager* pManager = GetApplication()->GetPlugInManager();
00204     if (pManager)
00205     {
00206         PlugInItem * pPlugIn = pManager->GetFirstPlugIn();
00207         String_32 OpToken;
00208         // Add the unique undo signature
00209         String_32 UndoSig(TEXT(PLUGIN_UNDO_SIG));
00210         while (pPlugIn)
00211         {
00212             // If we are to include the unique name in the test then do so
00213             if (IncludeUniqueName)
00214                 OpToken = pPlugIn->GetUniqueID();
00215             else
00216                 OpToken.Empty();
00217             if (IncludeUndoAbleSig)
00218                 OpToken += UndoSig;
00219             OpToken += pPlugIn->GetPlugInName();
00220             if (OpName == OpToken)
00221             {
00222                 // Ask the plug-in item whether it likes this colour depth
00223                 // Returns True if likes it, False otherwise, so we must negate this to
00224                 // set the greyed state.
00225                 return pPlugIn->IsBitmapModeOk(ColourDepth, GreyScale);
00226             }
00227             
00228             pPlugIn = pManager->GetNextPlugIn(pPlugIn);
00229         }
00230     }
00231 
00232     // Cannot find plug-in so return False
00233     return FALSE;
00234 }
00235 
00236 /********************************************************************************************
00237 
00238 >   OpState BfxPlugInUndoOp::GetState(String_256* pUIDescription, OpDescriptor* pOpDesc)
00239 
00240     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00241     Created:    6/3/97
00242     Inputs:     pOpDesc         - the OpDescriptor for the operation 
00243     Outputs:    pUIDescription  - if the Operation is enabled Then return the name of the operation to 
00244                                  be undone Else return the reason why it is disabled
00245     Returns:    OpState the state of the operation
00246     Purpose:    To provide greying and ticking functionality for the
00247                 operation.
00248     Errors:     -
00249     SeeAlso:    OpConvertToBitmap::GetState;
00250 
00251 ********************************************************************************************/
00252 
00253 OpState BfxPlugInUndoOp::GetState(String_256* pUIDescription, OpDescriptor* pOpDesc)
00254 {
00255     OpState OpSt;
00256     String_256 DisableReason;
00257 
00258     // Ensure that a document exists
00259     if (Document::GetSelected() == NULL)
00260     {
00261         // There is no selected document
00262         OpSt.Greyed = TRUE;
00263 
00264         // Load reason why operation is disabled
00265         DisableReason = String_256(_R(IDS_NO_DOC));
00266         if (pUIDescription)
00267             *pUIDescription = DisableReason;         
00268         return OpSt;                                 
00269     }
00270 
00271     // See if there is a bitmap in the current selection
00272     KernelBitmap *pBitmap = NULL;
00273     BOOL FoundBitmap = FALSE;
00274 
00275     SelRange *pSelRange = GetApplication()->FindSelection();
00276     if (pSelRange)
00277     {
00278         // Look for bitmap nodes and bitmap fills
00279         AttrFillGeometry* pFillAttr;
00280         FoundBitmap = pSelRange->FindBitmap(&pBitmap, NULL, NULL, &pFillAttr);
00281     }
00282 
00283     if (!FoundBitmap)
00284     {
00285         OpSt.Greyed = TRUE; 
00286         // Load reason why operation is disabled
00287         DisableReason = String_256(_R(IDS_NO_OBJECTS_SELECTED));
00288         if (pUIDescription)
00289             *pUIDescription = DisableReason;            
00290     }
00291     else
00292     {
00293         if (pBitmap)
00294         {
00295             // We are always available at present if there is a bitmap
00296             OpSt.Greyed = FALSE;
00297 
00298 /*          // If we have a valid bitmap then checks that it is of the correct type
00299             INT32 ColourDepth = pBitmap->GetBPP();
00300 
00301             // Only allow bitmaps of 24bpp or of 8bpp greyscale
00302             if (ColourDepth == 24 || (ColourDepth == 8 && pBitmap->IsGreyscale()))
00303             {
00304                 // Check the bitmap depth with the plug-in itself
00305                 // Returns True if likes it, False otherwise, so we must negate this to
00306                 // set the greyed state.
00307                 OpSt.Greyed = !CheckBitmapWithPlugIn(pOpDesc->Token, pBitmap, TRUE, TRUE);
00308             }
00309             else
00310                 OpSt.Greyed = TRUE;
00311 */
00312         }
00313     }
00314     
00315     return OpSt;   
00316 }
00317 
00318 /********************************************************************************************
00319 
00320 >   void BfxPlugInUndoOp::Do(OpDescriptor*)
00321 
00322     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00323     Created:    6/3/97
00324     Inputs:     pOpDesc     the OpDescriptor of the item to invoke
00325     Outputs:    None
00326     Returns:    None
00327     Purpose:    Invokes the plug-in specified by the OpDescriptor.
00328     Errors:     if no OpDescriptor is supplied
00329     SeeAlso:    OpConvertToBitmap::Do;
00330 
00331 ********************************************************************************************/
00332 
00333 void BfxPlugInUndoOp::Do(OpDescriptor* pOpDesc)
00334 {
00335     // Store away a copy of the OpDescriptor for later use
00336     m_pOpDesc = pOpDesc;
00337 
00338     // Search the plug-ins list for the specified plug-in and invoke it
00339     PlugInManager* pManager = GetApplication()->GetPlugInManager();
00340     if (pManager == NULL)
00341     {
00342         ERROR3("Called BfxPlugInUndoOp with no PlugInManager");
00343         End();
00344         return; 
00345     }
00346 
00347     SelRange *pSelRange = GetApplication()->FindSelection();
00348     if (pSelRange == NULL)
00349     {
00350         ERROR3("Called BfxPlugInUndoOp with no selection range!");
00351         End();
00352         return; 
00353     }
00354 
00355     KernelBitmap *      pBitmap = NULL;
00356     KernelBitmapRef *   pFoundBitmapRef = NULL;
00357     NodeBitmap *        pFoundNode = NULL;
00358     AttrFillGeometry *  pFoundFillAttribute = NULL;
00359     BOOL FoundBitmap = pSelRange->FindBitmap(&pBitmap, &pFoundBitmapRef, &pFoundNode, &pFoundFillAttribute);
00360     if (!FoundBitmap || pBitmap == NULL || pFoundBitmapRef == NULL)
00361     {
00362         ERROR3("Called BfxPlugInUndoOp with no selected bitmap in the range!");
00363         End();
00364         return; 
00365     }
00366 
00367     // We need to invalidate the region
00368     Range Sel(*pSelRange);
00369     if (!DoInvalidateNodesRegions(Sel, TRUE))
00370     {
00371         End();
00372         return; 
00373     } 
00374 
00375     PlugInItem * pPlugIn = pManager->GetFirstPlugIn();
00376     PlugInItem * pPlugInToApply = NULL;
00377     BOOL Found = FALSE;
00378     String_32 OpToken;
00379     // Add the unique undo signature
00380     String_32 UndoSig(TEXT(PLUGIN_UNDO_SIG));
00381     while (pPlugIn && !Found)
00382     {
00383         OpToken = pPlugIn->GetUniqueID();
00384         OpToken += UndoSig;
00385         OpToken += pPlugIn->GetPlugInName();
00386         if (pOpDesc->Token == OpToken)
00387         {
00388             // Note the plug-in for later use
00389             pPlugInToApply = pPlugIn;
00390             Found = TRUE;
00391             break;
00392         }
00393 
00394         pPlugIn = pManager->GetNextPlugIn(pPlugIn);
00395     }
00396 
00397     if (!DoStartSelOp(FALSE,FALSE))  // Try to record the selection state , don't render the blobs though 
00398     {
00399         FailAndExecute(); 
00400         End();
00401         return; 
00402     }
00403          
00404     // We have searched high and low for the plug-in to apply.
00405     // We should have found it by now and so can get on to actually using it
00406     Document * pDocument = Document::GetSelected();
00407     // If we haven't found one or there is no selected document then get out now
00408     if (pPlugInToApply == NULL || pDocument == NULL)
00409     {
00410         FailAndExecute();
00411         End();
00412         return; 
00413     }
00414 
00415     // We have found the desired plug-in so use it to do its stuff
00416     KernelBitmap* pBitmapCreated = NULL;
00417 
00418     BOOL AppliedOk = TRUE;
00419     AppliedOk = pPlugInToApply->Apply(pBitmap, pDocument, &pBitmapCreated);
00420 
00421     // the brightness and resize plugins are causing access violations when we simply press ok
00422     // within their dialog boxes.  This is caused through pBitmapCreated having been deleted.
00423     // i'm not exactly sure where the problem is occuring, but the following code fixes the problem.
00424     // the following code also guards against this sort of thing in general ....
00425     
00426     // lets just check the actual bitmap that has been returned.  If this is NULL, or 0xdddddddd
00427     // then we cannot allow the op to continue ....
00428 
00429     if (AppliedOk)
00430     {   // verify that please ....
00431         if (!pBitmapCreated)
00432         {
00433             AppliedOk = FALSE;
00434         }
00435         else
00436         {
00437             if (pBitmapCreated->HasBeenDeleted ())
00438             {
00439                 AppliedOk = FALSE;      // although everything appeared to work, the bitmap has been deleted
00440                                         // => abort the op
00441             }
00442         }
00443     }
00444 
00445     if (!AppliedOk)
00446     {
00447         FailAndExecute(); 
00448         End();
00449         return; 
00450     }
00451 
00452 #if 0
00453     // Use the special Bitmap filter as a temp bodge to stick the new bitmap in the tree   
00454     MakeBitmapFilter* pBitmapFilter = new MakeBitmapFilter();
00455     if (pBitmapFilter == NULL)
00456     {
00457         FailAndExecute();
00458         End();
00459         return; 
00460     }
00461     
00462     if (!pBitmapFilter->InsertBitmapIntoDocument(this, pBitmapCreated, pDocument))
00463     {
00464         delete pBitmapFilter;
00465         FailAndExecute();
00466         End();
00467         return; 
00468     }
00469 
00470     delete pBitmapFilter;
00471 
00472 #else           
00473     // Create an action to Undo the resizing operation
00474     ActionApplyPlugInToBitmap *APR;
00475 
00476     ActionCode ApplyPlugInAction = ActionApplyPlugInToBitmap::Init( this,
00477                                                                     &UndoActions,
00478                                                                     sizeof(ActionApplyPlugInToBitmap),
00479                                                                     pDocument,
00480                                                                     pBitmap,
00481                                                                     pFoundBitmapRef,
00482                                                                     pFoundNode,
00483                                                                     pFoundFillAttribute,
00484                                                                     (Action**)(&APR)
00485                                                                     );
00486 
00487     // If the init happened ok then go and do the first operation
00488     if (ApplyPlugInAction != AC_FAIL) 
00489     {
00490         // Apply the initial 'Do' operation - switch the node or fill to use the
00491         // new bitmap that the plug-in has generated.
00492         if (pFoundNode != NULL)
00493         {
00494             // Its a node bitmap so change its bitmap reference to be the new one
00495             pFoundBitmapRef->Attach(pBitmapCreated, pDocument);
00496 
00497             // Say that the bitmap has changed
00498             //DoInvalidateNodeRegion((NodeRenderableInk*)pFoundNode, TRUE);
00499         }
00500         else if (pFoundFillAttribute != NULL)
00501         {
00502             // Its a bitmap fill so change its bitmap reference to be the new one
00503             pFoundBitmapRef->Attach(pBitmapCreated, pDocument);
00504         }
00505         else
00506         {
00507             ERROR3("Called ActionApplyPlugInToBitmap::Execute with no node or fill selected!");
00508             FailAndExecute();
00509             End();
00510             return; 
00511         }
00512     }
00513     else
00514     {
00515         FailAndExecute();
00516         End();
00517         return;
00518     }
00519 #endif
00520 
00521     // Make sure that the new selection is up to date
00522     pSelRange = GetApplication()->FindSelection();
00523     if (pSelRange == NULL || !DoInvalidateNodesRegions(*pSelRange, TRUE))
00524     {
00525         // We need to invalidate the region
00526         FailAndExecute();
00527         End();
00528         return; 
00529     } 
00530 
00531     End(); 
00532     return;
00533 }
00534 

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