opshadow.cpp

Go to the documentation of this file.
00001 // $Id: opshadow.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 // Implementation of the Shadow tool operations
00099 
00100 /*
00101 */
00102 
00103 
00104 #include "camtypes.h"
00105 #include "opshadow.h"   
00106 #include "nodecont.h"
00107 #include "nodebmp.h"
00108 #include "nbevcont.h"
00109 
00110 #ifdef BUILDSHADOWS
00111 
00112 // Code headers
00113 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00116 #include "nodeshad.h"
00117 #include "progress.h"
00118 #include "objchge.h"
00119 #include "nodetxts.h"
00120 //#include "list.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00121 #include "fillattr2.h"
00122 
00123 // Resource headers
00124 //#include "shadres.h"
00125 
00126 // for the apply attribute alias class
00127 //#include "simon.h"
00128 //#include "mario.h"
00129 
00130 #include "opbevel.h"
00131 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00132 
00133 #include "shadtool.h"
00134 #include "shadinfo.h"
00135 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00136 #include "nodeblnd.h"
00137 #include "nodebldr.h"
00138 #include "blobs.h"
00139 
00140 #include "slicehelper.h"
00141 #include "opliveeffects.h"
00142 #include "shadtool.h"
00143 
00144 #include "colormgr.h"
00145 //#include "jason.h"
00146 //#include "gerry.h"
00147 #include "ophist.h"
00148 
00149 DECLARE_SOURCE( "$Revision: 1282 $" );
00150 
00151 CC_IMPLEMENT_DYNCREATE(OpApplyShadow, SelOperation)
00152 CC_IMPLEMENT_DYNCREATE(OpChangeShadowType, SelOperation)
00153 CC_IMPLEMENT_DYNCREATE(OpRemoveShadow, SelOperation)
00154 CC_IMPLEMENT_DYNCREATE(ShadowPosition, OpParam)
00155 CC_IMPLEMENT_DYNCREATE(OpShadowPosition, SelOperation)
00156 CC_IMPLEMENT_DYNCREATE(ShadowPenumbra, OpParam)
00157 CC_IMPLEMENT_DYNCREATE(OpShadowPenumbra, SelOperation)
00158 CC_IMPLEMENT_DYNCREATE(OpShadowAngle, SelOperation)
00159 CC_IMPLEMENT_DYNCREATE(OpShadowHeightAndAngle, SelOperation)
00160 CC_IMPLEMENT_DYNCREATE(OpShadowHeight, SelOperation)
00161 CC_IMPLEMENT_DYNCREATE(OpGlowWidth, SelOperation)
00162 CC_IMPLEMENT_DYNCREATE(OpShadowScale, SelOperation)
00163 CC_IMPLEMENT_DYNCREATE(ChangePositionShadowAction, Action)
00164 CC_IMPLEMENT_DYNCREATE(ChangePenumbraSizeAction, Action)
00165 CC_IMPLEMENT_DYNCREATE(NodeShadowClick, OpParam)
00166 CC_IMPLEMENT_DYNCREATE(OpApplyAttribForShadows, OpApplyAttribToSelected)
00167 CC_IMPLEMENT_DYNCREATE(OpSaveShadowData, SelOperation)
00168 CC_IMPLEMENT_DYNCREATE(ChangeFloorShadowAngleAction, Action)
00169 CC_IMPLEMENT_DYNCREATE(ChangeFloorShadowHeightAction, Action)
00170 CC_IMPLEMENT_DYNCREATE(ChangeShadowTypeAction, Action)
00171 CC_IMPLEMENT_DYNCREATE(ChangeGlowWidthAction, Action)
00172 CC_IMPLEMENT_DYNCREATE(ChangeShadowScaleAction, Action)
00173 CC_IMPLEMENT_DYNCREATE(SaveShadowDataAction, Action)
00174 CC_IMPLEMENT_DYNCREATE(ShadowProfileOpParam, OpParam)
00175 CC_IMPLEMENT_DYNCREATE(OpChangeShadowProfile, SelOperation)
00176 CC_IMPLEMENT_DYNCREATE(ChangeProfileAction, Action)
00177 CC_IMPLEMENT_DYNCREATE(ShadowDarknessOpParam, OpParam)
00178 CC_IMPLEMENT_DYNCREATE(OpChangeShadowDarkness, SelOperation)
00179 CC_IMPLEMENT_DYNCREATE(ChangeShadowDarknessAction, Action)
00180 
00181 #define new CAM_DEBUG_NEW
00182 
00183 
00184 /********************************************************************************************
00185 
00186 >   BOOL OpApplyShadow::Declare()
00187 
00188     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00189     Created:    18/11/2004
00190     Returns:    TRUE if all went OK, False otherwise
00191     Purpose:    Adds the operation to the list of all known operations
00192 
00193 ********************************************************************************************/
00194 BOOL OpApplyShadow::Declare()
00195 {
00196     BOOL ok = TRUE;
00197 
00198     // Use an ParamOpDescriptor to allow OpApplyLiveEffect to receive extra information
00199     // about the menu item that invoked it...
00200     ParamOpDescriptor* pOD2 = new ParamOpDescriptor(OPTOKEN_APPLYSHADOW,
00201                                                         CC_RUNTIME_CLASS(OpApplyShadow),
00202                                                         OpApplyShadow::GetParamState);
00203     ok = ok && (pOD2!=NULL);
00204 
00205     return ok;
00206 }
00207 
00208 
00209 
00210 /********************************************************************************************
00211 >   OpApplyShadow::OpApplyShadow()
00212 
00213     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00214     Created:    18/11/2004
00215     Purpose:    Constructor.
00216 ********************************************************************************************/
00217 OpApplyShadow::OpApplyShadow()
00218 {
00219 }
00220 
00221 
00222 
00223 /********************************************************************************************
00224 >   OpApplyShadow::~OpApplyShadow()
00225 
00226     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00227     Created:    18/11/2004
00228     Purpose:    Destructor.
00229 ********************************************************************************************/
00230 OpApplyShadow::~OpApplyShadow()
00231 {
00232 }
00233 
00234 
00235 /********************************************************************************************
00236 >   virtual void OpApplyShadow::Do(OpDescriptor *pOpDesc)
00237 
00238     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00239     Created:    18/11/2004
00240     Inputs:     pOpDesc - OpDescriptor - unused
00241     Outputs:    -
00242     Returns:    -
00243     Purpose:    The do function.  Applys a shadow to the selection in the current document
00244 ********************************************************************************************/
00245 void OpApplyShadow::Do(OpDescriptor *pOpDesc)
00246 {
00247     ERROR2RAW("Don't call this!");
00248     End();
00249 }
00250 
00251 
00252 /********************************************************************************************
00253 >   void OpApplyShadow::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
00254 
00255     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00256     Created:    18/11/2004
00257     Inputs:     
00258     Outputs:    -
00259     Returns:    -
00260     Purpose:    Applys a shadow to the selected node after a mouse click
00261 ********************************************************************************************/
00262 
00263 void OpApplyShadow::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
00264 {
00265 //  BOOL ok = FALSE;
00266 
00267     NodeShadowParam* pNSParam = (NodeShadowParam*)pParam;
00268 
00269     INT32 InsertPos = pNSParam->StackPosition - 1;  // We want to find the surface below the current pos
00270                                                     // because we are going to insert above that surface
00271 
00272     // obtain the current selection.
00273     SelRange* pSelRange = GetApplication()->FindSelection();
00274 
00275     Range* pInitialRange = NULL;
00276 
00277     // render blobs off for tools which don't automatically redraw their blobs.
00278     Tool* pTool = Tool::GetCurrent();
00279     Spread* pSpread = Document::GetSelectedSpread();
00280     if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection())
00281         pTool->RenderToolBlobs(pSpread, NULL);
00282 
00283     // record the current selection state and if required, render off any selection blobs.
00284     if (!DoStartSelOp(FALSE, FALSE))
00285     {
00286         End();
00287         return;
00288     }
00289 
00290     // invalidate the region bounding the selection.
00291     if (!DoInvalidateNodesRegions(*pSelRange, TRUE, FALSE, FALSE, FALSE))
00292     {
00293         End();
00294         return;
00295     }
00296 
00297     // Force text subselection up to the whole parent text object
00298     pSelRange->MakePartialSelectionWhole(FALSE);
00299 
00300     // Get a list of the LiveEffects we will be working on
00301     if (InsertPos==-1)
00302     {
00303         // We are to apply the LiveEFfects to the selection
00304         pInitialRange = GetApplication()->FindSelection();
00305     }
00306     else
00307     {
00308         ENSURE(pNSParam->pPPStack, "Can't find EffectsStack");
00309         pInitialRange = pNSParam->pPPStack->GetLevelRange(&InsertPos);
00310     }
00311 
00312     // Check whether we can edit an existing effect or whether we have to apply a new one
00313     if (pInitialRange==NULL)
00314     {
00315         ERROR3("Failed to get surface range to apply shadow too");
00316         FailAndExecute();
00317         End();
00318         return;
00319     }
00320 
00321     // Need to add a new LiveEffects node to the selection
00322     // Decide whether we need to create a group or can apply to
00323     // each selected object individually
00324     ListRange* pPPRange = NULL;
00325     pPPRange = DoApplyShadow(this, pInitialRange, pNSParam);
00326 
00327     // We should now have a decent list of NodeShadowController nodes...
00328     if (pPPRange==NULL)
00329     {
00330         FailAndExecute();
00331         End();
00332         return;
00333     }
00334 
00335     // invalidate the (new) region bounding the selection.
00336     DoInvalidateNodesRegions(*pSelRange, TRUE, FALSE, FALSE);
00337 
00338     // render blobs back on if the current tool doesn't automatically redraw its blobs.
00339     if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection())
00340         pTool->RenderToolBlobs(pSpread, NULL);
00341 
00342     End();
00343 
00344     // Make sure the Shadow tool is current... (this func can be called from other tools)
00345     Tool* pShadowTool = Tool::FindTool(TOOLID_SOFTSHADOW);
00346     if (pShadowTool && !pShadowTool->IsCurrent())
00347     {
00348         ((SoftShadowTool*)pShadowTool)->SetShadowEditRange(pPPRange, STACKPOS_TOP, TRUE);   // We know this range is consistent because we just created it!
00349         pShadowTool->SetCurrent();
00350     }
00351 
00352     // We don't actually need this range...!
00353     delete pPPRange;
00354     pPPRange = NULL;
00355 
00356     BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::EFFECTSTACKCHANGED)); 
00357 
00358 }
00359 
00360 
00361 
00362 /********************************************************************************************
00363 >   static ListRange* OpApplyShadow::DoApplyShadow(UndoableOperation* pOp, Range* pRange, NodeShadowParam* pNSParam)
00364 
00365     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00366     Created:    18/11/2004
00367     Inputs:     
00368     Outputs:    -
00369     Returns:    -
00370     Purpose:    Applys a shadow to the specified range (range probably comes from a
00371                 PostProcessor stack)
00372 
00373 ********************************************************************************************/
00374 
00375 ListRange* OpApplyShadow::DoApplyShadow(UndoableOperation* pOp, Range* pRange, NodeShadowParam* pNSParam)
00376 {
00377     ERROR3IF(pOp==NULL, "DoApplyShadow not given an operation to work in");
00378     ERROR3IF(pRange==NULL, "DoApplyShadow not given a range to work on");
00379 
00380 //  BOOL ok = TRUE;
00381 
00382     ListRange* pNewRange = new ListRange();
00383     ENSURE(pNewRange, "DoApplyEffect can't create a ListRange");
00384     if (pNewRange==NULL)
00385         return NULL;
00386 
00387     Node* pNode = pRange->FindFirst();
00388 
00389     // For each node in the range
00390     // Create a new NodeShadowController and insert it into the tree
00391     while (pNode)
00392     {
00393         NodeShadowController* pShadControl = DoApplyShadow(pOp, pNode, pNSParam);
00394         if (pShadControl)
00395         {
00396             pNewRange->AddNode(pShadControl);
00397             
00398             // Make sure the attributes are optimised correctly
00399             BOOL ok = pOp->DoFactorOutCommonChildAttributes(pShadControl);
00400             if (!ok)
00401             {
00402                 delete pNewRange;
00403                 return NULL;
00404             }
00405         }
00406         else
00407         {
00408             delete pNewRange;
00409             return NULL;
00410         }
00411             
00412         pNode = pRange->FindNext(pNode);
00413     }
00414     
00415     return pNewRange;
00416 }
00417 
00418 
00419 
00420 
00421 /********************************************************************************************
00422 >   static NodeShadowController* OpApplyShadow::DoApplyShadow(UndoableOperation* pOp, Node* pNode, NodeShadowParam* pNSParam, BOOL bSetSelected = TRUE)
00423 
00424     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00425     Created:    18/11/2004
00426     Inputs:     
00427     Outputs:    -
00428     Returns:    -
00429     Purpose:    Applys a shadow to the specified range (range probably comes from a
00430                 PostProcessor stack)
00431 
00432 ********************************************************************************************/
00433 
00434 NodeShadowController* OpApplyShadow::DoApplyShadow(UndoableOperation* pOp, Node* pNode, NodeShadowParam* pNSParam, BOOL bSetSelected)
00435 {
00436     ERROR3IF(pOp==NULL, "DoApplyShadow not given an operation to work in");
00437     ERROR3IF(pNode==NULL, "DoApplyShadow not given a node to work on");
00438 
00439     BOOL ok = TRUE;
00440     NodeShadowController* pShadControl = NULL;
00441 
00442     ObjChangeFlags flgs(FALSE, FALSE, FALSE, FALSE);
00443     ObjChangeParam ocp(OBJCHANGE_STARTING, flgs, NULL, pOp, OBJCHANGE_CALLEDBYOP);
00444 
00445     if (pNode->AllowOp(&ocp))
00446     {
00447         ALLOC_WITH_FAIL(pShadControl, (new NodeShadowController()), pOp);
00448         if (pShadControl==NULL) goto ApplyShadowError;
00449         
00450         // Create a new NodeShadow, apply default attributes and insert it into the tree
00451         NodeShadow* pShadow = NULL; 
00452         ALLOC_WITH_FAIL(pShadow, (new NodeShadow()), pOp);
00453         if (pShadow==NULL) goto ApplyShadowError;
00454 
00455         ok = pOp->DoInsertNewNode(pShadControl, pNode, NEXT, FALSE, FALSE, FALSE, FALSE);
00456         if (!ok) goto ApplyShadowError;
00457 
00458         ok = pOp->DoInvalidateNodeRegion(pShadControl, TRUE, FALSE, FALSE, FALSE);  // Don't force recache - we've already handled that
00459         if (!ok) goto ApplyShadowError;
00460         
00461         // Insert a flat fill attribute onto the shadow node
00462         AttrFlatColourFill * pAttr = NULL;
00463         ALLOC_WITH_FAIL(pAttr, new AttrFlatColourFill(pShadow, FIRSTCHILD), pOp);
00464         if (pAttr==NULL) goto ApplyShadowError;
00465 
00466         DocColour ShadowCol;
00467 
00468         if (pNSParam->m_Type == SHADOWTYPE_GLOW)
00469             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
00470                                                 _R(IDS_REDNAME), &ShadowCol);
00471         else
00472             AttributeManager::FindDefaultColour(ColourManager::GetCurrentColourList(),
00473                                                 _R(IDS_BLACKNAME), &ShadowCol);
00474         pAttr->SetStartColour(&ShadowCol);
00475 
00476         // Run through the selected nodes moving them to be children of the shadow controller
00477         ok = pOp->DoMoveNode(pNode, pShadControl, LASTCHILD);
00478         if (!ok) goto ApplyShadowError;
00479 
00480         pNode->SetSelected(FALSE);      // Deselect node (deselect whole subtree)
00481         
00482         // insert the shadow node now
00483         ok = pOp->DoInsertNewNode(pShadow, pShadControl, FIRSTCHILD, FALSE, FALSE, FALSE, FALSE);
00484         if (!ok) goto ApplyShadowError;
00485 
00486         // Now that shadow controller is in the tree in the correct place...
00487         // Release cached data for our parents only! We want to retain child cached data where possible
00488         pShadControl->ReleaseCached(TRUE, FALSE);
00489 #ifdef NEW_SHADOW_RENDER
00490         // To make multiple stacked shadowing work properly
00491         pShadControl->ReleaseStackedShadows();
00492 
00493         // Tidy up effects of applying one shadow on top of another
00494         if (pNode->IsAShadowController())
00495         {
00496             // Ensure previously selected shadows are all deselected
00497             NodeShadowController* pPrevTopController = (NodeShadowController*) pNode;
00498 //          NodeShadow* pPrevTopShadow = pPrevTopController->GetShadow();
00499 
00500             // Copy effect attrs up because the prev top controller will no longer be rendered
00501             NodeAttribute* pAttr = NodeAttribute::FindFirstAppliedAttr(pPrevTopController);
00502             while (pAttr && pAttr->IsEffectAttribute())
00503             {
00504                 pOp->DoMoveNode(pAttr, pShadControl, LASTCHILD);
00505 
00506                 pAttr = NodeAttribute::FindFirstAppliedAttr(pPrevTopController);    // First again, because we just moved one!
00507             }
00508         }
00509 #endif
00510         
00511         if (bSetSelected)
00512             pShadControl->FindBottomShadowController()->GetInkNodeFromController()->SetSelected(TRUE);
00513 
00514         ok = pOp->DoInvalidateNodeRegion(pShadow, TRUE, FALSE, FALSE, FALSE);   // Don't force recache - we've already handled that
00515         if (!ok) goto ApplyShadowError;
00516         
00517         
00518         // factor out the child attributes
00519         ok = pOp->DoFactorOutCommonChildAttributes(pShadControl);
00520         if (!ok) goto ApplyShadowError;
00521         
00522         // set all the attributes
00523         pShadControl->SetPenumbraWidth(pNSParam->m_Blur);
00524         pShadControl->SetOffsetX(pNSParam->m_OffsetX);
00525         pShadControl->SetOffsetY(pNSParam->m_OffsetY);
00526         pShadControl->SetShadowType(pNSParam->m_Type);
00527         pShadControl->SetFloorShadowAngle(pNSParam->m_FloorShadowAngle);
00528         pShadControl->SetFloorShadowHeight((float)pNSParam->m_FloorShadowHeight);
00529         pShadControl->SetWallShadowScale((float)pNSParam->m_Scale);
00530         pShadControl->SetGlowWidth(pNSParam->m_GlowWidth);
00531         pShadControl->SetFeatherWidth(pNSParam->m_FeatherWidth);
00532         pShadow->SetBiasGain(pNSParam->m_Profile);
00533         pShadow->SetDarkness(pNSParam->m_dDarkness);
00534         
00535         // set up the shadow
00536         ((pShadControl)->GetShadow())->GenerateShadow();
00537         
00538         // TODO: Why?
00539         // reinitialise any blend which we may belong to.
00540         // this assumes that if we are directly blended, then our parent
00541         // must be a NodeBlend.
00542         if (pNode->IsAnObject())
00543         {
00544             NodeRenderableInk* pInk = (NodeRenderableInk*)pNode;
00545             Node* pTestBlend = pShadControl->FindParent();
00546             if (pTestBlend != NULL && pTestBlend->IsABlend())
00547                 ((NodeBlend*)pTestBlend)->ReinitialiseOnChildChanged(pOp, pInk, pShadControl);
00548         }
00549 
00550         // inform all parents
00551         // [Phil 26/08/2005: WHY??? Why not just let the normal UpdateChangedNodes call do this?]
00552         // [What a mess!]
00553         ObjChangeFlags flgs(FALSE, FALSE, FALSE, FALSE);
00554         flgs.RegenerateNode = TRUE;
00555         ObjChangeParam ocp2(OBJCHANGE_FINISHED, flgs, pShadControl, pOp, OBJCHANGE_CALLEDBYCHILD);
00556         
00557         Node *pParent = pShadControl->FindParent();
00558         
00559         while (pParent)
00560         {           
00561             pParent->OnChildChange(&ocp2);
00562             pParent = pParent->FindParent();
00563         }
00564 
00565         // TODO: Why?
00566         SliceHelper::AddNamesToController(pOp, pShadControl);
00567     }
00568             
00569     return pShadControl;
00570 
00571 ApplyShadowError:
00572     delete pShadControl;
00573     return NULL;
00574 }
00575 
00576 
00577 
00578 
00579 /********************************************************************************************
00580 
00581 >   OpState OpApplyShadow::GetState(String_256* Description, OpDescriptor*)
00582 
00583     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00584     Created:    18/11/2004
00585     Outputs:    -
00586     Returns:    Ungreyed, Unticked
00587     Purpose:    Find out the state of the new regular shape at the specific time
00588 
00589 ********************************************************************************************/
00590 OpState OpApplyShadow::GetState(String_256* Description, OpDescriptor*)
00591 {
00592     OpState Blobby;
00593 
00594     Blobby.Greyed = FALSE;
00595 
00596     return Blobby;
00597 }
00598 
00599 
00600 
00601 
00602 /********************************************************************************************
00603 
00604 >   static OpState OpApplyShadow::GetParamState(String_256* pstrDescription, OpDescriptor* pOpDesc, OpParam* pOpParam)
00605 
00606     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00607     Created:    07/09/2004
00608     Inputs:     
00609     Outputs:    
00610     Returns:    
00611     Purpose:    Return state of the specified LiveEffect (name in pstrDescription) being
00612                 applied to the selection (taking into account the current position in the
00613                 LiveEffect Stack.
00614     Errors:     
00615     See also:   
00616 
00617 ********************************************************************************************/
00618 OpState OpApplyShadow::GetParamState(String_256* pstrDescription, OpDescriptor* pOpDesc, OpParam* pOpParam)
00619 {
00620     // default is an unticked, *GREYED*, on-menu state.
00621     OpState OpSt;
00622     OpSt.Greyed = FALSE;
00623 
00624 //  OpSt.Greyed = (XPEHost::IsEditSessionRunning());
00625 
00626     return OpSt;
00627 }
00628 
00629 
00630 
00631 
00632 
00633 
00638 
00639 
00640 /********************************************************************************************
00641 
00642 >   BOOL OpChangeShadowType::Declare()
00643 
00644     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00645     Created:    18/11/2004
00646     Returns:    TRUE if all went OK, False otherwise
00647     Purpose:    Adds the operation to the list of all known operations
00648 
00649 ********************************************************************************************/
00650 BOOL OpChangeShadowType::Declare()
00651 {
00652     BOOL ok = TRUE;
00653 
00654     // Use an ParamOpDescriptor to allow OpApplyLiveEffect to receive extra information
00655     // about the menu item that invoked it...
00656     ParamOpDescriptor* pOD2 = new ParamOpDescriptor(OPTOKEN_CHANGESHADOWTYPE,
00657                                                         CC_RUNTIME_CLASS(OpChangeShadowType),
00658                                                         OpChangeShadowType::GetParamState);
00659     ok = ok && (pOD2!=NULL);
00660 
00661     return ok;
00662 }
00663 
00664 
00665 
00666 /********************************************************************************************
00667 >   OpChangeShadowType::OpChangeShadowType()
00668 
00669     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00670     Created:    18/11/2004
00671     Purpose:    Constructor.
00672 ********************************************************************************************/
00673 OpChangeShadowType::OpChangeShadowType()
00674 {
00675 }
00676 
00677 
00678 
00679 /********************************************************************************************
00680 >   OpChangeShadowType::~OpChangeShadowType()
00681 
00682     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00683     Created:    18/11/2004
00684     Purpose:    Destructor.
00685 ********************************************************************************************/
00686 OpChangeShadowType::~OpChangeShadowType()
00687 {
00688 }
00689 
00690 
00691 /********************************************************************************************
00692 >   virtual void OpChangeShadowType::Do(OpDescriptor *pOpDesc)
00693 
00694     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00695     Created:    18/11/2004
00696     Inputs:     pOpDesc - OpDescriptor - unused
00697     Outputs:    -
00698     Returns:    -
00699     Purpose:    The do function.  Applys a shadow to the selection in the current document
00700 ********************************************************************************************/
00701 void OpChangeShadowType::Do(OpDescriptor *pOpDesc)
00702 {
00703     ERROR2RAW("Don't call this!");
00704     End();
00705 }
00706 
00707 
00708 /********************************************************************************************
00709 >   void OpChangeShadowType::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
00710 
00711     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00712     Created:    18/11/2004
00713     Inputs:     
00714     Outputs:    -
00715     Returns:    -
00716     Purpose:    Applys a shadow to the selected node after a mouse click
00717 ********************************************************************************************/
00718 
00719 void OpChangeShadowType::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
00720 {
00721 //  BOOL ok = FALSE;
00722 
00723     NodeShadowParam* pNSParam = (NodeShadowParam*)pParam;
00724 
00725 //  INT32 InsertPos = pNSParam->StackPosition - 1;  // We want to find the surface below the current pos
00726                                                     // because we are going to insert above that surface
00727 
00728     // obtain the current selection.
00729     Range Sel(*(GetApplication()->FindSelection()));
00730     RangeControl rc = Sel.GetRangeControlFlags();
00731     rc.PromoteToParent = TRUE;
00732     Sel.Range::SetRangeControl(rc);
00733 
00734 //  Range* pInitialRange = NULL;
00735 
00736     // render blobs off for tools which don't automatically redraw their blobs.
00737     Tool* pTool = Tool::GetCurrent();
00738     Spread* pSpread = Document::GetSelectedSpread();
00739     if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection())
00740         pTool->RenderToolBlobs(pSpread, NULL);
00741 
00742     // record the current selection state and if required, render off any selection blobs.
00743     if (!DoStartSelOp(FALSE, FALSE))
00744     {
00745         End();
00746         return;
00747     }
00748 
00749     // invalidate the region bounding the selection.
00750     if (!DoInvalidateNodesRegions(Sel, TRUE, FALSE, FALSE, FALSE))
00751     {
00752         End();
00753         return;
00754     }
00755 
00756     // Force text subselection up to the whole parent text object
00757 //  SelRange::MakeTextSelectionWhole(FALSE);
00758 
00759     // Need to add a new LiveEffects node to the selection
00760     // Decide whether we need to create a group or can apply to
00761     // each selected object individually
00762     BOOL bOK = DoChangeShadowType(this, pNSParam);
00763 
00764     // We should now have a decent list of LiveEffect nodes...
00765     if (!bOK)
00766     {
00767         FailAndExecute();
00768         End();
00769         return;
00770     }
00771 
00772     // invalidate the (new) region bounding the selection.
00773     DoInvalidateNodesRegions(*(GetApplication()->FindSelection()), TRUE, FALSE, FALSE, FALSE); // Assume DoChangeShadowType has released caches where needed
00774 
00775     // render blobs back on if the current tool doesn't automatically redraw its blobs.
00776     if (pSpread != NULL && pTool != NULL && !pTool->AreToolBlobsRenderedOnSelection())
00777         pTool->RenderToolBlobs(pSpread, NULL);
00778 
00779     End();
00780 }
00781 
00782 
00783 
00784 /********************************************************************************************
00785 >   static BOOL OpChangeShadowType::DoChangeShadowType(UndoableOperation* pOp, Range* pRange, NodeShadowParam* pNSParam)
00786 
00787     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00788     Created:    18/11/2004
00789     Inputs:     
00790     Outputs:    -
00791     Returns:    -
00792     Purpose:    Change the type of the specified range of shadows...
00793 
00794 ********************************************************************************************/
00795 
00796 BOOL OpChangeShadowType::DoChangeShadowType(UndoableOperation* pOp, NodeShadowParam* pNSParam)
00797 {
00798     ERROR3IF(pOp==NULL, "DoChangeShadowType not given an operation to work in");
00799 
00800 //  BOOL ok = TRUE;
00801 
00802     ObjChangeFlags flgs(FALSE, FALSE, FALSE, FALSE);
00803     ObjChangeParam ocp(OBJCHANGE_STARTING, flgs, NULL, pOp, OBJCHANGE_CALLEDBYOP);
00804 
00805     ENSURE(pNSParam->pShadowTool, "Op not given pointer to shadow tool");
00806     Range* pShadowRange = pNSParam->pShadowTool->GetShadowEditRange();
00807     Node* pNode = pShadowRange->FindFirst();
00808     if (pNode==NULL)
00809     {
00810         ERROR3("Nothing was selected in OpChangeShadowType");
00811         return FALSE;
00812     }
00813 
00814     while (pNode)
00815     {
00816         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
00817         NodeShadowController* pController = (NodeShadowController*)pNode;
00818 
00819         if (pController->GetShadowType() != pNSParam->m_Type)
00820         {
00821 //          Node *pParent = pController->FindParent();
00822 
00823             pController->InvalidateBoundingRect();
00824 //          if (bRedraw)
00825             {
00826 //              pOp->DoInvalidateNodeRegion(pController, TRUE);
00827                 pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
00828                 pOp->DoInvalidateNodeRegion(pController, TRUE, FALSE, FALSE, FALSE);    // Don't force recache - we've already handled that
00829                 pOp->DoInvalidateRegion(pController->FindParentSpread(), pController->GetBlobBoundingRect());
00830             }
00831 
00832             ChangeShadowTypeAction* Action = NULL;
00833             ChangeShadowTypeAction::Init(pOp, pOp->GetUndoActionList(), pController, pNSParam->m_Type, &Action);
00834 //          m_OpName = _R(IDS_CHANGESHADOWTYPEOPNAME);
00835 
00836             pController->InvalidateBoundingRect();
00837 //          if (bRedraw)
00838             {
00839 //              pOp->DoInvalidateNodeRegion(pController, TRUE);
00840                 pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
00841                 pOp->DoInvalidateNodeRegion(pController, TRUE, FALSE, FALSE, FALSE);    // Don't force recache - we've already handled that
00842                 pOp->DoInvalidateRegion(pController->FindParentSpread(), pController->GetBlobBoundingRect());
00843             }
00844         }
00845 
00846         pNode = pShadowRange->FindNext(pNode);
00847     }
00848 
00849     return TRUE;
00850 }
00851 
00852 /********************************************************************************************
00853 
00854 >   OpState OpChangeShadowType::GetState(String_256* Description, OpDescriptor*)
00855 
00856     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00857     Created:    18/11/2004
00858     Outputs:    -
00859     Returns:    Ungreyed, Unticked
00860     Purpose:    Find out the state of the new regular shape at the specific time
00861 
00862 ********************************************************************************************/
00863 OpState OpChangeShadowType::GetState(String_256* Description, OpDescriptor*)
00864 {
00865     OpState Blobby;
00866 
00867     Blobby.Greyed = FALSE;
00868 
00869     return Blobby;
00870 }
00871 
00872 
00873 
00874 /********************************************************************************************
00875 
00876 >   static OpState OpChangeShadowType::GetParamState(String_256* pstrDescription, OpDescriptor* pOpDesc, OpParam* pOpParam)
00877 
00878     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00879     Created:    07/09/2004
00880     Inputs:     
00881     Outputs:    
00882     Returns:    
00883     Purpose:    Return state of the specified LiveEffect (name in pstrDescription) being
00884                 applied to the selection (taking into account the current position in the
00885                 LiveEffect Stack.
00886     Errors:     
00887     See also:   
00888 
00889 ********************************************************************************************/
00890 OpState OpChangeShadowType::GetParamState(String_256* pstrDescription, OpDescriptor* pOpDesc, OpParam* pOpParam)
00891 {
00892     // default is an unticked, *GREYED*, on-menu state.
00893     OpState OpSt;
00894     OpSt.Greyed = FALSE;
00895 
00896 //  OpSt.Greyed = (XPEHost::IsEditSessionRunning());
00897 
00898     return OpSt;
00899 }
00900 
00901 
00902 
00907 
00908 
00909 /********************************************************************************************
00910 >   OpRemoveShadow::OpRemoveShadow()
00911 
00912     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
00913     Created:    21/11/96
00914     Purpose:    Constructor.
00915 ********************************************************************************************/
00916 OpRemoveShadow::OpRemoveShadow()
00917 {
00918 }
00919 
00920 
00921 
00922 /********************************************************************************************
00923 >   OpRemoveShadow::~OpRemoveShadow()
00924 
00925     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
00926     Created:    21/11/96
00927     Purpose:    Destructor.
00928 ********************************************************************************************/
00929 OpRemoveShadow::~OpRemoveShadow()
00930 {
00931 }
00932 
00933 
00934 /********************************************************************************************
00935 >   virtual void OpRemoveShadow::DoWithParam(OpDescriptor *pOpDesc, OpParam* pParam)
00936     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
00937     Created:    21/11/96
00938     Inputs:     pOpDesc - OpDescriptor - unused
00939     Outputs:    -
00940     Returns:    -
00941     Purpose:    The do function.  Applys a shadow to the selection in the current document
00942 ********************************************************************************************/
00943 void OpRemoveShadow::DoWithParam(OpDescriptor *pOpDesc, OpParam* pParam)
00944 {
00945     // Start a slow job
00946     BeginSlowJob();
00947 
00948     // Get the selection 
00949     NodeShadowParam* pNSParam = (NodeShadowParam*)pParam;
00950 
00951     BOOL ok = TRUE;
00952     // Start the SelectionOp
00953     if (ok) ok = DoStartSelOp(TRUE);
00954 
00955     NodeBlend * pBlend = NULL;
00956     NodeBlender * pBlender = NULL;
00957     NodeRenderableInk * pRenderableNode = NULL;
00958 
00959     BOOL bBlendBefore = FALSE;
00960     BOOL bBlendAfter  = FALSE;
00961 
00962     ENSURE(pNSParam->pShadowTool, "Op not given pointer to shadow tool");
00963 
00964     // We need to copy the range because we are about to fiddle with the document
00965     // tree and that could cause the EditRange to be uncached
00966     ListRange* pShadowRange = new ListRange(pNSParam->pShadowTool->GetShadowEditRange());
00967     Node* pSCNode = pShadowRange->FindFirst();
00968     while (pSCNode)
00969     {
00970         if (pSCNode->IS_KIND_OF(NodeShadowController) && pSCNode->FindParent()!=NULL)
00971         {
00972             Node* pNode = pSCNode;
00973             NodeShadowController* pControl = (NodeShadowController*) pSCNode;
00974             
00975             // are we part of a blend ? if so, make a record of the blender object
00976             // and whether we're before or after it
00977             pBlender = (NodeBlender *)pNode->FindNext(CC_RUNTIME_CLASS(NodeBlender));
00978 
00979             bBlendBefore = FALSE;
00980             bBlendAfter = FALSE;
00981 
00982             if (pBlender)
00983             {
00984                 // we're before it !
00985                 bBlendBefore = TRUE;
00986 
00987                 pBlend = (NodeBlend *)pBlender->FindParent();
00988             }
00989             else
00990             {
00991                 // try the blend after
00992                 pBlender = (NodeBlender *)pNode->FindPrevious(CC_RUNTIME_CLASS(NodeBlender));
00993 
00994                 if (pBlender)
00995                 {
00996                     bBlendAfter = TRUE;
00997                     pBlend = (NodeBlend *)pBlender->FindParent();
00998                 }
00999             }
01000 
01001             
01002             // We now have a selected NodeShadowController node. Here's what we do:
01003             //      Invalidate the region
01004             //      Hide the NodeShadowController
01005             //      Move all other nodes next to the place the NodeShadowContrller node used to be (select them too)
01006 
01007             // localise all attributes
01008             if (ok) ok = DoLocaliseCommonAttributes((NodeShadowController *)pNode, TRUE);
01009 
01010             NodeHidden* pNodeHidden;
01011             NodeShadowController* pNodeShadCont = (NodeShadowController*)pNode;
01012 
01013             // Will the shadowconller node allow us to do the op to it?
01014             //ok = pNodeShadCont->AllowOp(&ObjChange);
01015             if (ok)
01016                 SliceHelper::RemoveNamesFromController(this, pNodeShadCont);
01017 
01018             // Invalidate the whole blend region
01019 //          if (ok) ok = DoInvalidateNodeRegion(pNodeShadCont,TRUE,FALSE);
01020             if (ok)
01021             {
01022                 pNodeShadCont->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
01023                 ok = DoInvalidateNodeRegion(pNodeShadCont, TRUE, FALSE, FALSE, FALSE);  // Don't force recache - we've already handled that
01024             }
01025 
01026             // move the children
01027             pNode = pNodeShadCont->FindFirstChild();
01028 
01029             while (pNode != NULL && ok)
01030             {
01031                 Node* pNext = pNode->FindNext();
01032 
01033                 if (pNode->IsAnObject() && !pNode->IS_KIND_OF(NodeShadow))
01034                     ok = DoMoveNode(pNode,pNodeShadCont,PREV);          // Move next to hidden node (where shadowcont node used to be)
01035                 // reselect the node
01036                 if (ok) pNode->SetSelected(TRUE);
01037                 pNode = pNext;
01038             }
01039 
01040 
01041             // Firstly, hide the nodeshadowcontroller, and deselect it
01042             if (ok) pNodeShadCont->SetSelected(FALSE);
01043 
01044             Node * pParent = pNodeShadCont->FindParent();
01045             
01046             if (ok) ok = DoHideNode(pNodeShadCont,TRUE,&pNodeHidden,FALSE);
01047 
01048             if (ok)
01049             {
01050                 // do blends
01051                 // do the blend inform - i.e. inform them that their objects have changed
01052                 if (bBlendBefore)
01053                 {
01054                     if (InitBlendAction::InitOnBlender(this, GetUndoActionList(), pBlender, TRUE, TRUE) != AC_OK)
01055                     {
01056                         ERROR2RAW("Couldn't Initialise blend action");
01057                     }
01058 
01059                     // reinit the node
01060                     pRenderableNode = (NodeRenderableInk *)pBlender->FindPrevious(CC_RUNTIME_CLASS(NodeRenderableInk)); 
01061                     
01062                     if (pRenderableNode)
01063                     {
01064                         pBlender->Reinit(pRenderableNode,   pBlender->GetNodeEnd(), FALSE);
01065                     }
01066                 }
01067                 else if (bBlendAfter)
01068                 {
01069                     if (InitBlendAction::InitOnBlender(this, GetUndoActionList(), pBlender, TRUE, TRUE) != AC_OK)
01070                     {
01071                         ERROR2RAW("Couldn't Initialise blend action");
01072                     }
01073 
01074                     // reinit the node
01075                     pRenderableNode = (NodeRenderableInk *)pBlender->FindNext(CC_RUNTIME_CLASS(NodeRenderableInk)); 
01076                     
01077                     if (pRenderableNode)
01078                     {
01079                         pBlender->Reinit(pBlender->GetNodeStart(), pRenderableNode, FALSE);
01080                     }
01081                 }
01082 
01083                 if (pBlender)
01084                 {
01085                     NodeBlend* ptrBlend = (NodeBlend*) pBlender->FindParent ();
01086 
01087                     ERROR3IF (!IS_A (ptrBlend, NodeBlend), "NodeBlend is not a NodeBlend!");
01088 
01089                     BOOL done = FALSE;
01090                     NodeBlender* ptrNode = ptrBlend->FindFirstBlender ();
01091 
01092                     while (!done)
01093                     {
01094                         if (ptrNode != pBlender)
01095                         {
01096                             if (ptrNode->GetNodeStart() == pControl)
01097                             {
01098                                 if (InitBlendAction::InitOnBlender(this, GetUndoActionList(), ptrNode, TRUE, TRUE) != AC_OK)
01099                                 {
01100                                     ERROR2RAW("Couldn't Initialise blend action");
01101                                 }
01102 
01103                                 // reinit the node
01104                                 //pRenderableNode = (NodeRenderableInk *)ptrNode->FindPrevious(CC_RUNTIME_CLASS(NodeRenderableInk)); 
01105                                 
01106                                 if (pRenderableNode)
01107                                 {
01108                                     ptrNode->Reinit(pRenderableNode, NULL, FALSE);
01109                                 }
01110                             }
01111                             if (ptrNode->GetNodeEnd() == pControl)
01112                             {
01113                                 if (InitBlendAction::InitOnBlender(this, GetUndoActionList(),  ptrNode, TRUE, TRUE) != AC_OK)
01114                                 {
01115                                     ERROR2RAW("Couldn't Initialise blend action");
01116                                 }
01117                                 
01118                                 // reinit the node
01119                                 //pRenderableNode = (NodeRenderableInk *)ptrNode->FindNext(CC_RUNTIME_CLASS(NodeRenderableInk)); 
01120 
01121                                 if (pRenderableNode)
01122                                 {
01123                                     ptrNode->Reinit(NULL, pRenderableNode, FALSE);
01124                                 }
01125                             }
01126                         }
01127 
01128                         ptrNode = ptrBlend->FindNextBlender (ptrNode);
01129 
01130                         if (!ptrNode)
01131                         {
01132                             done = TRUE;
01133                         }
01134                     }
01135                 }
01136             }
01137 
01138             // Karim 19/07/2000
01139             // the parent's bounds will have changed, so tell them so.
01140             if (pParent->IsBounded())       // paranoia code - this is always true.
01141                 ((NodeRenderableBounded*)pParent)->InvalidateBoundingRect();
01142 
01143             // tell all parents
01144             if (ok)
01145             {
01146                 ObjChangeFlags flgs(FALSE, FALSE, FALSE, FALSE);
01147                 flgs.DeleteNode = TRUE;
01148                 flgs.RegenerateNode = TRUE;
01149                 ObjChangeParam OP(OBJCHANGE_FINISHED, flgs, pNodeShadCont, this, OBJCHANGE_CALLEDBYCHILD);
01150 
01151                 while (pParent)
01152                 {
01153                     if (pParent->OnChildChange(&OP) != CC_OK)
01154                         break;
01155 
01156                     if (pParent->IS_KIND_OF(NodeBlend))
01157                     {
01158                         ((NodeBlend *)pParent)->Deinit();
01159                         ((NodeBlend *)pParent)->Reinit(FALSE);
01160                     }
01161 
01162                     pParent = pParent->FindParent();
01163                 }
01164             }
01165         }
01166         
01167         pSCNode = pShadowRange->FindNext(pSCNode);
01168     }
01169 
01170     if (pShadowRange)
01171     {
01172         delete pShadowRange;
01173         pShadowRange = NULL;
01174     }
01175 
01176     if (!ok)
01177         FailAndExecute();
01178 
01179     End();  
01180 }
01181 
01182 
01183 /********************************************************************************************
01184 
01185 >   BOOL OpRemoveShadow::Declare()
01186 
01187     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01188     Created:    21/11/96
01189     Returns:    TRUE if all went OK, False otherwise
01190     Purpose:    Adds the operation to the list of all known operations
01191 
01192 ********************************************************************************************/
01193 BOOL OpRemoveShadow::Declare()
01194 {
01195     return (RegisterOpDescriptor(
01196                                 0, 
01197                                 _R(IDS_REMOVESHADOWOP),
01198                                 CC_RUNTIME_CLASS(OpRemoveShadow), 
01199                                 OPTOKEN_REMOVESHADOW,
01200                                 OpRemoveShadow::GetState));
01201 
01202 }
01203 
01204 
01205 /********************************************************************************************
01206 
01207 >   OpState OpRemoveShadow::GetState(String_256* Description, OpDescriptor*)
01208 
01209     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01210     Created:    21/11/96
01211     Outputs:    -
01212     Returns:    Ungreyed, Unticked
01213     Purpose:    Find out the state of the new regular shape at the specific time
01214 
01215 ********************************************************************************************/
01216 OpState OpRemoveShadow::GetState(String_256* Description, OpDescriptor*)
01217 {
01218     OpState Blobby;
01219     
01220     return Blobby;
01221 }
01222 
01223 
01228 
01229 ShadowPosition::ShadowPosition()
01230 {
01231     X = 0;
01232     Y = 0;
01233     m_bUpdateX = 0;
01234     m_bUpdateY = 0;
01235     m_pTool = NULL;
01236 }
01237 
01238 /********************************************************************************************
01239 
01240 >   ShadowPosition::ShadowPosition(const INT32 x, const INT32 y)
01241 
01242     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01243     Created:    17/12/96
01244 
01245 ********************************************************************************************/
01246 
01247 ShadowPosition::ShadowPosition(const INT32 x, const INT32 y,
01248                                BOOL UpdateX, BOOL UpdateY, SoftShadowTool* pTool)
01249 {
01250     X = x;
01251     Y = y;
01252     m_bUpdateX = UpdateX;
01253     m_bUpdateY = UpdateY;
01254     m_pTool = pTool;
01255 }
01256 
01257 /********************************************************************************************
01258 
01259 >   ShadowPosition::~ShadowPosition()
01260 
01261     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01262     Created:    17/12/96
01263 
01264 ********************************************************************************************/
01265 
01266 ShadowPosition::~ShadowPosition()
01267 {
01268 }
01269 
01270 
01271 /********************************************************************************************
01272 
01273 >   OpShadowPosition::OpShadowPosition()
01274 
01275     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01276     Created:    16/12/96
01277     Outputs:    -
01278     Returns:    -
01279     Purpose:    constructor
01280 
01281 ********************************************************************************************/
01282 OpShadowPosition::OpShadowPosition()
01283 {
01284 }
01285 
01286 /********************************************************************************************
01287 
01288 >   OpShadowPosition::~OpShadowPosition()
01289 
01290     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01291     Created:    16/12/96
01292     Outputs:    -
01293     Returns:    -
01294     Purpose:    destructor
01295 
01296 ********************************************************************************************/
01297 OpShadowPosition::~OpShadowPosition()
01298 {
01299 }
01300 
01301 
01302 /********************************************************************************************
01303 
01304 >   BOOL OpShadowPosition::Declare()
01305 
01306     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01307     Created:    18/12/96
01308     Returns:    TRUE if all went OK, False otherwise
01309     Purpose:    Adds the operation to the list of all known operations
01310 
01311 ********************************************************************************************/
01312 
01313 BOOL OpShadowPosition::Declare()
01314 {
01315     return (RegisterOpDescriptor(
01316                                 0, 
01317                                 _R(IDS_POSITIONSHADOWOP),
01318                                 CC_RUNTIME_CLASS(OpShadowPosition), 
01319                                 OPTOKEN_SHADOWPOSITION,
01320                                 OpShadowPosition::GetState));
01321 }
01322 
01323 /********************************************************************************************
01324 
01325 >   OpShadowPosition::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
01326 
01327     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01328     Created:    16/12/96
01329     Outputs:    
01330     Returns:    
01331     Purpose:    
01332 
01333 ********************************************************************************************/
01334 void OpShadowPosition::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
01335 {
01336     // Start a slow job
01337     BeginSlowJob();
01338 
01339     ShadowPosition *MyShadowPosition = (ShadowPosition *)pParam;
01340     ERROR3IF(MyShadowPosition == NULL, "Parameter block pointer was NULL");
01341 
01342     if (MyShadowPosition == NULL)
01343     {
01344         End();
01345         return;
01346     }
01347 
01348     ENSURE(MyShadowPosition->m_pTool, "Op not given pointer to shadow tool");
01349     Range* pShadowRange = MyShadowPosition->m_pTool->GetShadowEditRange();
01350     Node* pNode = pShadowRange->FindFirst();
01351     if (pNode==NULL)
01352     {
01353         ERROR3("Nothing was selected in OpShadowPosition");
01354         FailAndExecute();
01355         End();
01356         return;
01357     }
01358     while (pNode)
01359     {
01360         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
01361         NodeShadowController* pController = (NodeShadowController*)pNode;
01362 
01363         ChangePositionShadowAction* pAction = NULL;
01364             
01365 //      DoInvalidateNodeRegion(pController->GetShadow(), TRUE);
01366         pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
01367         DoInvalidateNodeRegion(pController->GetShadow(), TRUE, FALSE, FALSE, FALSE);    // Don't force recache - we've already handled that
01368         
01369         // set the new penumbra
01370         ActionCode ac = ChangePositionShadowAction::Init(this,
01371                                                   &UndoActions,pController,
01372                                                   MyShadowPosition->X,
01373                                                   MyShadowPosition->Y,
01374                                                   MyShadowPosition->m_bUpdateX,
01375                                                   MyShadowPosition->m_bUpdateY,
01376                                                   &pAction
01377                                                  );
01378         if (ac==AC_FAIL)
01379         {
01380             FailAndExecute();
01381             End();
01382             return;
01383         }
01384         
01385 //      DoInvalidateNodeRegion(pController->GetShadow(), TRUE);
01386         pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
01387         DoInvalidateNodeRegion(pController->GetShadow(), TRUE, FALSE, FALSE, FALSE);    // Don't force recache - we've already handled that
01388 
01389         // do the object change on the node
01390         ObjChangeFlags flgs(FALSE, FALSE, FALSE, TRUE);
01391         ObjChangeParam OP(OBJCHANGE_FINISHED, flgs, pController, this, OBJCHANGE_CALLEDBYOP);
01392         flgs.RegenerateNode = TRUE;
01393         Node * pNodeParent = pController->FindParent();
01394 
01395         while (pNodeParent)
01396         {
01397             pNodeParent->OnChildChange(&OP);
01398 
01399             pNodeParent = pNodeParent->FindParent();
01400         }
01401 
01402         pNode = pShadowRange->FindNext(pNode);
01403     }
01404     
01405     End();  
01406 }
01407 
01408 
01409 /********************************************************************************************
01410 
01411 >   OpState OpShadowPosition::GetState(String_256* Description, OpDescriptor*)
01412 
01413     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01414     Created:    16/12/96
01415     Outputs:    -
01416     Returns:    Ungreyed, Unticked
01417     Purpose:    Find out the state of the new regular shape at the specific time
01418 
01419 ********************************************************************************************/
01420 OpState OpShadowPosition::GetState(String_256* Description, OpDescriptor*)
01421 {
01422     OpState Blobby;
01423     
01424     return Blobby;
01425 }
01426 
01427 
01433 
01434 
01435 ShadowPenumbra::ShadowPenumbra()
01436 {
01437     P = 0;
01438     m_pTool = NULL;
01439 }
01440 
01441 /********************************************************************************************
01442 
01443 >   ShadowPenumbra::~ShadowPenumbra()
01444 
01445     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01446     Created:    18/12/96
01447     Outputs:    -
01448     Returns:    -
01449     Purpose:    ShadowPenumbra destructor
01450 
01451 ********************************************************************************************/
01452 
01453 ShadowPenumbra::~ShadowPenumbra()
01454 {
01455 }
01456 
01457 /********************************************************************************************
01458 
01459 >   ShadowPenumbra::ShadowPenumbra(const INT32 p, SoftShadowTool* pTool)
01460 
01461     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01462     Created:    18/12/96
01463     Inputs:     p - new size of the penumbra
01464     Outputs:    -
01465     Returns:    -
01466     Purpose:    ShadowPenumbra constructor
01467 
01468 ********************************************************************************************/
01469 
01470 ShadowPenumbra::ShadowPenumbra(const INT32 p, SoftShadowTool* pTool)
01471 {
01472     P = p;
01473     m_pTool = pTool;
01474 }
01475 
01476 
01477 OpShadowPenumbra::OpShadowPenumbra()
01478 {
01479 }
01480 
01481 OpShadowPenumbra::~OpShadowPenumbra()
01482 {
01483 }
01484 
01485 /********************************************************************************************
01486 
01487 >   BOOL OpShadowPenumbra::Declare()
01488 
01489     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01490     Created:    19/12/96
01491     Returns:    TRUE if all went OK, False otherwise
01492     Purpose:    Adds the operation to the list of all known operations
01493 
01494 ********************************************************************************************/
01495 
01496 BOOL OpShadowPenumbra::Declare()
01497 {
01498     return (RegisterOpDescriptor(
01499                                 0, 
01500                                 _R(IDS_PENUMBRASHADOWOP),
01501                                 CC_RUNTIME_CLASS(OpShadowPenumbra), 
01502                                 OPTOKEN_SHADOWPENUMBRA,
01503                                 OpShadowPenumbra::GetState));
01504 }
01505 
01506 
01507 /********************************************************************************************
01508 
01509 >   OpState OpShadowEnumbra::GetState(String_256* Description, OpDescriptor*)
01510 
01511     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01512     Created:    18/12/96
01513     Outputs:    -
01514     Returns:    Ungreyed, Unticked
01515     Purpose:    Find out the state of the new regular shape at the specific time
01516 
01517 ********************************************************************************************/
01518 OpState OpShadowPenumbra::GetState(String_256* Description, OpDescriptor*)
01519 {
01520     OpState Blobby;
01521     
01522     return Blobby;
01523 }
01524 
01525 
01526 /********************************************************************************************
01527 x
01528 >   OpShadowPenumbra::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
01529 
01530     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01531     Created:    19/12/96
01532     Outputs:    
01533     Returns:    
01534     Purpose:    
01535 
01536 ********************************************************************************************/
01537 void OpShadowPenumbra::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
01538 {
01539     // Start a slow job
01540     BeginSlowJob();
01541 
01542     ShadowPenumbra *MyShadowPenumbra = (ShadowPenumbra *)pParam;
01543     ERROR3IF(MyShadowPenumbra == NULL, "Parameter block pointer was NULL");
01544 
01545     if (MyShadowPenumbra == NULL)
01546     {
01547         End();
01548         return;
01549     }
01550 
01551     // Get the selection
01552     ENSURE(MyShadowPenumbra->m_pTool, "Op not given pointer to shadow tool");
01553     Range* pShadowRange = MyShadowPenumbra->m_pTool->GetShadowEditRange();
01554     Node* pNode = pShadowRange->FindFirst();
01555     if (pNode==NULL)
01556     {
01557         ERROR3("Nothing was selected in OpShadowPenumbra");
01558         FailAndExecute();
01559         End();
01560         return;
01561     }
01562     while (pNode)
01563     {
01564         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
01565         NodeShadowController* pController = (NodeShadowController*)pNode;
01566 
01567         ChangePenumbraSizeAction* pAction = NULL;
01568         
01569         // Invalidate the region
01570 //      DoInvalidateNodeRegion(pController, TRUE);
01571         pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
01572         DoInvalidateNodeRegion(pController, TRUE, FALSE, FALSE, FALSE); // Don't force recache - we've already handled that
01573         
01574         ActionCode ac = ChangePenumbraSizeAction::Init(this,
01575                                                         &UndoActions,
01576                                                         pController,
01577                                                         MyShadowPenumbra->P,
01578                                                         &pAction
01579                                                         );
01580         if (ac==AC_FAIL)
01581         {
01582             FailAndExecute();
01583             End();
01584             return;
01585         }
01586         
01587 //      DoInvalidateNodeRegion(pController, TRUE);
01588         pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
01589         DoInvalidateNodeRegion(pController, TRUE, FALSE, FALSE, FALSE); // Don't force recache - we've already handled that
01590 
01591         // do the object change on the node
01592         ObjChangeFlags flgs(FALSE, FALSE, FALSE, TRUE);
01593         ObjChangeParam OP(OBJCHANGE_FINISHED, flgs, pController, this, OBJCHANGE_CALLEDBYOP);
01594 
01595         Node* pNodeParent = pController->FindParent();
01596 
01597         while (pNodeParent)
01598         {
01599             pNodeParent->OnChildChange(&OP);
01600 
01601             pNodeParent = pNodeParent->FindParent();
01602         }
01603 
01604         pNode = pShadowRange->FindNext(pNode);
01605     }
01606 
01607     End();  
01608 }
01609 
01610 
01611 
01612 //------------------------------------------------------------------------------------------------
01613 //------------------------------------------------------------------------------------------------
01614 //------------------------------------------------------------------------------------------------
01615 // The ChangePositionShadowAction class
01616 
01617 /********************************************************************************************
01618 
01619 >   ChangePositionShadowAction::ChangePositionShadowAction()
01620 
01621     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01622     Created:    07/01/97
01623     Inputs:     -
01624     Outputs:    -
01625     Returns:    -
01626     Purpose:    Constructor for the action
01627     Errors:     -
01628     SeeAlso:    -
01629 
01630 ********************************************************************************************/
01631 
01632 ChangePositionShadowAction::ChangePositionShadowAction()
01633 {
01634     m_pNodeShadowCont  = NULL;
01635     m_OldPositionX = 0;
01636     m_OldPositionY = 0;
01637     m_bUpdateX = 0;
01638     m_bUpdateY = 0;
01639 }
01640 
01641 
01642 /********************************************************************************************
01643 
01644 >   ActionCode ChangePositionShadowAction::Init(    Operation*  pOp,
01645                                                 ActionList* pActionList,
01646                                                 NodeShadowCont*     pThisNodeShadow,
01647                                                 ChangePositionShadowXAction**   ppNewAction);
01648 
01649     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01650     Created:    07/01/96
01651     Inputs:     pOp             = ptr to the operation to which this action belongs
01652                 pActionList     =  ptr to action list to which this action should be added
01653                 pThisNodeShadow = ptr to NodeShadow to change 
01654                 PosShadowX      = New position X to apply to pThisNodeShadow
01655     Outputs:    ppNewAction     = ptr to a ptr to an action, allowing the function to return
01656                                   a pointer to the created action
01657     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
01658     Purpose:    This is the function which creates an instance of this action. If there is no room 
01659                 in the undo buffer (which is determined by the base class Init function called within)
01660                 the function will either return AC_NO_RECORD which means the operation can continue, 
01661                 but no undo information needs to be stored, or AC_OK which means the operation should
01662                 continue AND record undo information. If the function returns AC_FAIL, there was not 
01663                 enough memory to record the undo information, and the user has decided not to continue
01664                 with the operation.
01665     Errors:     -
01666     SeeAlso:    Action::Init()
01667 
01668 ********************************************************************************************/
01669 
01670 
01671 
01672 ActionCode ChangePositionShadowAction::Init(Operation* pOp,
01673                                         ActionList* pActionList,
01674                                         NodeShadowController* pThisNodeShadow,
01675                                         MILLIPOINT NewOffsetX,
01676                                         MILLIPOINT NewOffsetY,
01677                                         BOOL UpdateX,
01678                                         BOOL UpdateY,
01679                                         ChangePositionShadowAction** ppNewAction,
01680                                         BOOL Reverse)
01681 {
01682     UINT32 ActSize = sizeof(ChangePositionShadowAction);
01683 
01684     ActionCode Ac = Action::Init(pOp,pActionList,ActSize,CC_RUNTIME_CLASS(ChangePositionShadowAction),(Action**)ppNewAction);
01685 
01686     MILLIPOINT OldOffsetX = pThisNodeShadow->GetOffsetX();
01687     MILLIPOINT OldOffsetY = pThisNodeShadow->GetOffsetY();
01688 
01689     if (Ac != AC_FAIL)
01690     {
01691         (*ppNewAction)->m_pNodeShadowCont  = pThisNodeShadow;
01692 
01693         // first thing we need to do is move my action to the start of the undo list
01694         // this is because we want to regen after all other actions have occurred
01695         // DMc
01696         /*
01697         if (Reverse)
01698         {
01699             pActionList->RemoveItem(*ppNewAction);
01700             pActionList->AddHead(*ppNewAction);
01701         }
01702         */
01703         
01704         if (UpdateX)
01705             pThisNodeShadow->SetOffsetX(NewOffsetX);
01706         else
01707             NewOffsetX = pThisNodeShadow->GetOffsetX();
01708 
01709         if (UpdateY)
01710             pThisNodeShadow->SetOffsetY(NewOffsetY);
01711         else
01712             NewOffsetY = pThisNodeShadow->GetOffsetY();
01713 
01714         // and set it in the history
01715         (*ppNewAction)->m_OldPositionX = OldOffsetX;
01716         (*ppNewAction)->m_OldPositionY = OldOffsetY;
01717         (*ppNewAction)->m_bUpdateX = UpdateX;
01718         (*ppNewAction)->m_bUpdateY = UpdateY;
01719 
01720         TRACEUSER( "DavidM", _T("Moving shadow by %d %d, %d %d\n"),
01721             NewOffsetX, NewOffsetY, OldOffsetX, OldOffsetY);
01722 
01723         pThisNodeShadow->SetWallShadowOffset(DocCoord(NewOffsetX, NewOffsetY), TRUE);
01724     }
01725 
01726     return Ac;
01727 }
01728 
01729 /********************************************************************************************
01730 
01731 >   ActionCode ChangePositionShadowAction::Execute();
01732 
01733     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01734     Created:    7/11/94
01735     Inputs:     -
01736     Outputs:    -
01737     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
01738     Purpose:    Executes the action.  This will reset the num blend steps in pThisNodeBlend to OldNumSteps,
01739                 after creating another action to record the current num steps of pThisNodeBlend
01740     Errors:     -
01741     SeeAlso:    Action::Init()
01742 
01743 ********************************************************************************************/
01744 
01745 ActionCode ChangePositionShadowAction::Execute()
01746 {
01747     ActionCode Act;
01748     ChangePositionShadowAction* pAction;
01749 
01750     Act = ChangePositionShadowAction::Init( pOperation, 
01751                                         pOppositeActLst,
01752                                         m_pNodeShadowCont,
01753                                         m_OldPositionX, m_OldPositionY,
01754                                         m_bUpdateX, m_bUpdateY,
01755                                         &pAction,
01756                                         TRUE);
01757 
01758     // and set the matrix
01759     if (Act != AC_FAIL)
01760     {
01761         (m_pNodeShadowCont)->SetOffsetX(m_OldPositionX);
01762         (m_pNodeShadowCont)->SetOffsetY(m_OldPositionY);
01763     }
01764 
01765     return Act;
01766 }
01767 
01768 ChangePositionShadowAction::~ChangePositionShadowAction()
01769 {
01770 }
01771 
01772 
01773 //------------------------------------------------------------------------------------------------
01774 //------------------------------------------------------------------------------------------------
01775 //------------------------------------------------------------------------------------------------
01776 // The ChangePenumbraSizeAction class
01777 
01778 /********************************************************************************************
01779 
01780 >   ChangePenumbraSizeAction::ChangePenumbraSizeAction()
01781 
01782     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01783     Created:    07/01/97
01784     Inputs:     -
01785     Outputs:    -
01786     Returns:    -
01787     Purpose:    Constructor for the action
01788     Errors:     -
01789     SeeAlso:    -
01790 
01791 ********************************************************************************************/
01792 
01793 ChangePenumbraSizeAction::ChangePenumbraSizeAction()
01794 {
01795     m_pNodeShadowCont  = NULL;
01796     m_OldPenumbraSize = 0;
01797 }
01798 
01799 
01800 /********************************************************************************************
01801 
01802 >   ActionCode ChangePenumbraSizeAction::Init(  Operation*  pOp,
01803                                                 ActionList* pActionList,
01804                                                 NodeShadow*     pThisNodeShadow,
01805                                                 MILLIPOINT  PenumbraSize,
01806                                                 ChangePositionShadowXAction**   ppNewAction);
01807 
01808     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01809     Created:    07/01/96
01810     Inputs:     pOp             = ptr to the operation to which this action belongs
01811                 pActionList     =  ptr to action list to which this action should be added
01812                 pThisNodeShadow = ptr to NodeShadow to change 
01813                 PenumbraSize    = New position X to apply to pThisNodeShadow
01814     Outputs:    ppNewAction     = ptr to a ptr to an action, allowing the function to return
01815                                   a pointer to the created action
01816     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
01817     Purpose:    This is the function which creates an instance of this action. If there is no room 
01818                 in the undo buffer (which is determined by the base class Init function called within)
01819                 the function will either return AC_NO_RECORD which means the operation can continue, 
01820                 but no undo information needs to be stored, or AC_OK which means the operation should
01821                 continue AND record undo information. If the function returns AC_FAIL, there was not 
01822                 enough memory to record the undo information, and the user has decided not to continue
01823                 with the operation.
01824     Errors:     -
01825     SeeAlso:    Action::Init()
01826 
01827 ********************************************************************************************/
01828 
01829 
01830 
01831 ActionCode ChangePenumbraSizeAction::Init(Operation* pOp,
01832                                         ActionList* pActionList,
01833                                         NodeShadowController* pThisNodeShadow,
01834                                         MILLIPOINT NewPenumbraSize,
01835                                         ChangePenumbraSizeAction** ppNewAction,
01836                                         BOOL bReverse,
01837                                         BOOL bCache)
01838 {
01839     UINT32 ActSize = sizeof(ChangePenumbraSizeAction);
01840 
01841     ActionCode Ac = Action::Init(pOp,pActionList,ActSize,CC_RUNTIME_CLASS(ChangePenumbraSizeAction),(Action**)ppNewAction);
01842 
01843     Document * pDoc = Document::GetCurrent();
01844 
01845     DocView * pView = DocView::GetCurrent();
01846 
01847     Spread * pSpread = NULL;
01848 
01849     if (Ac != AC_FAIL)
01850     {
01851         // reverse the action
01852         // DMc
01853         if (bReverse)
01854         {
01855             pActionList->RemoveItem(*ppNewAction);
01856             pActionList->AddHead(*ppNewAction);
01857             (*ppNewAction)->m_bCache = bCache;
01858         }
01859 
01860         pSpread = (Spread *)pThisNodeShadow->FindParent(CC_RUNTIME_CLASS(Spread));
01861 
01862         if (!pSpread)
01863             pSpread = Document::GetSelectedSpread();
01864 
01865         if (pDoc)
01866         {
01867             if (pSpread)
01868             {
01869                 pThisNodeShadow->ReleaseCached(TRUE, FALSE, TRUE, TRUE);        // Fix for 11304
01870                 pDoc->ForceRedraw(pSpread, pThisNodeShadow->GetBoundingRect(FALSE, FALSE), FALSE, pThisNodeShadow, FALSE);
01871             }
01872         }
01873         
01874         (*ppNewAction)->m_pNodeShadowCont  = pThisNodeShadow;
01875         (*ppNewAction)->m_OldPenumbraSize = pThisNodeShadow->GetPenumbraWidth();
01876 
01877         pThisNodeShadow->SetPenumbraWidth(NewPenumbraSize);
01878         // ((pThisNodeShadow)->GetShadow())->SetCurrentBlur(NewPenumbraSize);
01879 
01880         if (pView && bCache)
01881         {
01882             GetApplication()->AddNodeToRegenList(pThisNodeShadow);
01883         }
01884         else
01885         {           
01886             ((pThisNodeShadow)->GetShadow())->GenerateShadow();
01887         }
01888 
01889         if (pDoc)
01890         {
01891             if (pSpread)
01892             {
01893                 pThisNodeShadow->ReleaseCached(TRUE, FALSE, TRUE, TRUE);        // Fix for 11304
01894                 pDoc->ForceRedraw(pSpread, pThisNodeShadow->GetBoundingRect(FALSE, FALSE), FALSE, pThisNodeShadow, FALSE);
01895                 pDoc->ForceRedraw(pSpread, pThisNodeShadow->GetBoundingRect(TRUE, FALSE), FALSE, pThisNodeShadow, FALSE);
01896             }
01897         }
01898         
01899         (*ppNewAction)->m_LastRect = (*ppNewAction)->m_pNodeShadowCont->GetBoundingRect();
01900     }
01901 
01902     return Ac;
01903 }
01904 
01905 /********************************************************************************************
01906 
01907 >   ActionCode ChangePenumbraSizeAction::Execute();
01908 
01909     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01910     Created:    07/01/96
01911     Inputs:     -
01912     Outputs:    -
01913     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
01914     Purpose:    Executes the action.  This will reset the num blend steps in pThisNodeBlend to OldNumSteps,
01915                 after creating another action to record the current num steps of pThisNodeBlend
01916     Errors:     -
01917     SeeAlso:    Action::Init()
01918 
01919 ********************************************************************************************/
01920 
01921 ActionCode ChangePenumbraSizeAction::Execute()
01922 {
01923     ActionCode Act;
01924     ChangePenumbraSizeAction* pAction;
01925 
01926     // force a redraw of the region
01927     DocRect dr = m_LastRect;
01928 
01929     Act = ChangePenumbraSizeAction::Init(   pOperation, 
01930                                         pOppositeActLst,
01931                                         m_pNodeShadowCont,
01932                                         m_OldPenumbraSize,
01933                                         &pAction, TRUE, m_bCache
01934                                         );
01935 
01936     Spread * pSpread = NULL;
01937 
01938     if (Act != AC_FAIL)
01939     {
01940         Document * pDoc = Document::GetCurrent();
01941 
01942         pSpread = (Spread *)m_pNodeShadowCont->FindParent(CC_RUNTIME_CLASS(Spread));
01943 
01944         if (!pSpread)
01945             pSpread = Document::GetSelectedSpread();
01946         
01947         if (pDoc)
01948         {
01949             m_LastRect = m_pNodeShadowCont->GetBoundingRect();
01950 
01951             if (pSpread)
01952             {
01953                 pDoc->ForceRedraw(pSpread, 
01954                     m_LastRect, FALSE, m_pNodeShadowCont);
01955             }
01956         }
01957     }
01958     
01959     return Act;
01960 }
01961 
01962 ChangePenumbraSizeAction::~ChangePenumbraSizeAction()
01963 {
01964 }
01965 
01966 
01972 
01973 
01974 /********************************************************************************************
01975 >   NodeShadowClick::NodeShadowClick(Node *p)
01976 
01977     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
01978     Created:    13/01/97
01979     Purpose:    When a user click, used by SoftShadowTool::DoWithParam()
01980 ********************************************************************************************/
01981 
01982 NodeShadowClick::NodeShadowClick()
01983 {
01984     m_pNode = NULL;
01985     m_pTool = NULL;
01986 }
01987 
01988 NodeShadowClick::NodeShadowClick(Node *p, SoftShadowTool* pTool)
01989 {
01990     m_pNode = p;
01991     m_pTool = pTool;
01992 }
01993 
01994 NodeShadowClick::~NodeShadowClick()
01995 {
01996 }
01997 
02003 
02004 
02005 /********************************************************************************************
02006 
02007 >   BOOL OpApplyAttribForShadows::DoApplyFillAttributeToShadow(Node * CurrentNode, 
02008         NodeAttribute * Attrib, BOOL * AttribWasRequired = NULL)
02009 
02010 
02011     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02012     Created:    6/6/95
02013     Inputs:     -
02014     Returns:    TRUE if all ok.
02015     Purpose:    Same as DoApply only for shadow nodes
02016     Errors:     -
02017     SeeAlso:    -
02018 
02019 ********************************************************************************************/
02020 BOOL OpApplyAttribForShadows::DoApply(Node* CurrentNode, 
02021                             NodeAttribute* Attrib, 
02022                             BOOL Mutate, 
02023                             BOOL InvalidateRegion,
02024                             BOOL KeepExistingCols, /* = TRUE */
02025                             BOOL* AttribWasRequired    /* = NULL */
02026                             )
02027 {
02028     if (!CurrentNode->IsKindOf(CC_RUNTIME_CLASS(NodeShadowController)) ||
02029         (!Attrib->IsKindOf(CC_RUNTIME_CLASS(AttrFillGeometry)) &&
02030         !Attrib->IsKindOf(CC_RUNTIME_CLASS(AttrValueChange))))
02031     {
02032         return OpApplyAttrib::DoApply(CurrentNode, Attrib, Mutate, InvalidateRegion,
02033             KeepExistingCols, AttribWasRequired);
02034     }
02035     
02036     // do the apply for all nodes under me
02037     Node * pNode = CurrentNode->FindFirstChild();
02038 
02039     BOOL bOk = TRUE;
02040 
02041     while (pNode && bOk)
02042     {
02043         if (pNode->IsRenderable() && !pNode->IsAnAttribute())
02044         {
02045             if (!pNode->IsKindOf(CC_RUNTIME_CLASS(NodeShadow)))
02046             {
02047                 bOk = OpApplyAttrib::DoApply(pNode, Attrib, Mutate, InvalidateRegion,
02048                     KeepExistingCols, AttribWasRequired);
02049             }
02050         }
02051 
02052         pNode = pNode->FindNext();
02053     }
02054     
02055     return bOk;
02056 }
02057 
02058 
02059 /********************************************************************************************
02060 
02061 >   BOOL OpApplyAttribForShadows::DoApplyFillAttributeToShadow(Node * CurrentNode, 
02062         NodeAttribute * Attrib, BOOL * AttribWasRequired = NULL)
02063 
02064 
02065     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02066     Created:    6/6/95
02067     Inputs:     -
02068     Returns:    TRUE if all ok.
02069     Purpose:    Alias init function
02070     Errors:     -
02071     SeeAlso:    -
02072 
02073 ********************************************************************************************/
02074 BOOL OpApplyAttribForShadows::Init()
02075 {
02076     // Register the opdescriptors for the OpApplyAttribToSelected operation
02077     OpDescriptor* OpDesc = new OpDescriptor(
02078                                             0,
02079                                             _R(IDS_APPLYATTRIBOP),              
02080                                             CC_RUNTIME_CLASS(OpApplyAttribForShadows),
02081                                             OPTOKEN_SHADOWATTRIB,
02082                                             OpApplyAttribToSelected::GetState); 
02083 
02084     ERRORIF(!OpDesc, _R(IDE_NOMORE_MEMORY), FALSE);
02085     return(OpDesc != NULL);
02086 }
02087 
02088 //------------------------------------------------------------------------------------------------
02089 //------------------------------------------------------------------------------------------------
02090 //------------------------------------------------------------------------------------------------
02091 // The ChangeFloorShadowHeightAction class
02092 
02093 /********************************************************************************************
02094 
02095 >   ChangeFloorShadowHeightAction::ChangeFloorShadowHeightAction()
02096 
02097     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02098     Created:    07/01/97
02099     Inputs:     -
02100     Outputs:    -
02101     Returns:    -
02102     Purpose:    Constructor for the action
02103     Errors:     -
02104     SeeAlso:    -
02105 
02106 ********************************************************************************************/
02107 
02108 ChangeFloorShadowHeightAction::ChangeFloorShadowHeightAction()
02109 {
02110     m_pNodeShadowCont  = NULL;
02111     m_LastHeight = 0;
02112 }
02113 
02114 
02115 /********************************************************************************************
02116 
02117 >   ActionCode ChangeFloorShadowHeightAction::Init(     Operation*  pOp,
02118                                                 ActionList* pActionList,
02119                                                 NodeShadow*     pThisNodeShadow,
02120                                                 MILLIPOINT  PenumbraSize,
02121                                                 ChangePositionShadowXAction**   ppNewAction);
02122 
02123     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02124     Created:    07/01/96
02125     Inputs:     pOp             = ptr to the operation to which this action belongs
02126                 pActionList     =  ptr to action list to which this action should be added
02127                 pThisNodeShadow = ptr to NodeShadow to change 
02128                 PenumbraSize    = New position X to apply to pThisNodeShadow
02129     Outputs:    ppNewAction     = ptr to a ptr to an action, allowing the function to return
02130                                   a pointer to the created action
02131     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
02132     Purpose:    This is the function which creates an instance of this action. If there is no room 
02133                 in the undo buffer (which is determined by the base class Init function called within)
02134                 the function will either return AC_NO_RECORD which means the operation can continue, 
02135                 but no undo information needs to be stored, or AC_OK which means the operation should
02136                 continue AND record undo information. If the function returns AC_FAIL, there was not 
02137                 enough memory to record the undo information, and the user has decided not to continue
02138                 with the operation.
02139     Errors:     -
02140     SeeAlso:    Action::Init()
02141 
02142 ********************************************************************************************/
02143 
02144 
02145 
02146 ActionCode ChangeFloorShadowHeightAction::Init(Operation* pOp,
02147                                         ActionList* pActionList,
02148                                         NodeShadowController* pThisNodeShadow,
02149                                         double NewHeight,
02150                                         ChangeFloorShadowHeightAction** ppNewAction,
02151                                         BOOL bReverse,
02152                                         BOOL bCache)
02153 {
02154     UINT32 ActSize = sizeof(ChangeFloorShadowHeightAction);
02155 
02156     ActionCode Ac = Action::Init(pOp,pActionList,ActSize,
02157         CC_RUNTIME_CLASS(ChangeFloorShadowHeightAction),
02158         (Action**)ppNewAction);
02159 
02160     Document * pDoc = Document::GetCurrent();
02161 
02162     if (Ac != AC_FAIL)
02163     {
02164         // reverse the action
02165         // DMc
02166         if (bReverse)
02167         {
02168             pActionList->RemoveItem(*ppNewAction);
02169             pActionList->AddHead(*ppNewAction);
02170         }
02171         
02172         (*ppNewAction)->m_pNodeShadowCont  = pThisNodeShadow;
02173         (*ppNewAction)->m_LastHeight = pThisNodeShadow->GetFloorShadowHeight();
02174         (*ppNewAction)->m_bCache = bCache;
02175 
02176         pThisNodeShadow->SetFloorShadowHeight((float)NewHeight);
02177 
02178         if (pDoc)
02179         {
02180             pDoc->ForceRedraw(pThisNodeShadow->FindParentSpread(), pThisNodeShadow->GetBlobBoundingRect(), FALSE, pThisNodeShadow);
02181         }
02182 
02183         pThisNodeShadow->RegenerateNode(NULL, FALSE);
02184 
02185         if (pDoc)
02186         {
02187             pDoc->ForceRedraw(pThisNodeShadow->FindParentSpread(), pThisNodeShadow->GetBlobBoundingRect(), FALSE, pThisNodeShadow);
02188         }
02189         
02190         (*ppNewAction)->m_LastRect = (*ppNewAction)->m_pNodeShadowCont->GetBoundingRect();  
02191     }
02192 
02193     return Ac;
02194 }
02195 
02196 /********************************************************************************************
02197 
02198 >   ActionCode ChangeFloorShadowHeightAction::Execute();
02199 
02200     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02201     Created:    07/01/96
02202     Inputs:     -
02203     Outputs:    -
02204     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
02205     Purpose:    Executes the action.  This will reset the num blend steps in pThisNodeBlend to OldNumSteps,
02206                 after creating another action to record the current num steps of pThisNodeBlend
02207     Errors:     -
02208     SeeAlso:    Action::Init()
02209 
02210 ********************************************************************************************/
02211 
02212 ActionCode ChangeFloorShadowHeightAction::Execute()
02213 {
02214     ActionCode Act;
02215     ChangeFloorShadowHeightAction* pAction;
02216 
02217     // force a redraw of the region
02218     DocRect dr = m_LastRect;
02219 
02220     Act = ChangeFloorShadowHeightAction::Init(  pOperation, 
02221                                         pOppositeActLst,
02222                                         m_pNodeShadowCont,
02223                                         m_LastHeight,
02224                                         &pAction,
02225                                         TRUE,
02226                                         m_bCache);
02227 
02228     if (Act != AC_FAIL)
02229     {
02230         Document * pDoc = Document::GetCurrent();
02231         
02232         if (pDoc)
02233         {
02234             m_LastRect = m_pNodeShadowCont->GetShadow()->GetBoundingRect();
02235             pDoc->ForceRedraw(m_pNodeShadowCont->GetShadow()->FindParentSpread(), 
02236                 m_LastRect, FALSE, m_pNodeShadowCont);
02237         }
02238     }
02239     
02240     return Act;
02241 }
02242 
02243 ChangeFloorShadowHeightAction::~ChangeFloorShadowHeightAction()
02244 {
02245 }
02246 
02247 //------------------------------------------------------------------------------------------------
02248 //------------------------------------------------------------------------------------------------
02249 //------------------------------------------------------------------------------------------------
02250 // The ChangeFloorShadowAngleAction class
02251 
02252 /********************************************************************************************
02253 
02254 >   ChangeFloorShadowAngleAction::ChangeFloorShadowAngleAction()
02255 
02256     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02257     Created:    07/01/97
02258     Inputs:     -
02259     Outputs:    -
02260     Returns:    -
02261     Purpose:    Constructor for the action
02262     Errors:     -
02263     SeeAlso:    -
02264 
02265 ********************************************************************************************/
02266 
02267 ChangeFloorShadowAngleAction::ChangeFloorShadowAngleAction()
02268 {
02269     m_pNodeShadowCont  = NULL;
02270     m_LastAngle = 0;
02271 }
02272 
02273 
02274 /********************************************************************************************
02275 
02276 >   ActionCode ChangeFloorShadowAngleAction::Init(  Operation*  pOp,
02277                                                 ActionList* pActionList,
02278                                                 NodeShadow*     pThisNodeShadow,
02279                                                 MILLIPOINT  PenumbraSize,
02280                                                 ChangePositionShadowXAction**   ppNewAction);
02281 
02282     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02283     Created:    10/6/99
02284     Inputs:     pOp             = ptr to the operation to which this action belongs
02285                 pActionList     =  ptr to action list to which this action should be added
02286                 pThisNodeShadow = ptr to NodeShadow to change 
02287                 PenumbraSize    = New position X to apply to pThisNodeShadow
02288     Outputs:    ppNewAction     = ptr to a ptr to an action, allowing the function to return
02289                                   a pointer to the created action
02290     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
02291     Purpose:    This is the function which creates an instance of this action. If there is no room 
02292                 in the undo buffer (which is determined by the base class Init function called within)
02293                 the function will either return AC_NO_RECORD which means the operation can continue, 
02294                 but no undo information needs to be stored, or AC_OK which means the operation should
02295                 continue AND record undo information. If the function returns AC_FAIL, there was not 
02296                 enough memory to record the undo information, and the user has decided not to continue
02297                 with the operation.
02298     Errors:     -
02299     SeeAlso:    Action::Init()
02300 
02301 ********************************************************************************************/
02302 
02303 
02304 
02305 ActionCode ChangeFloorShadowAngleAction::Init(Operation* pOp,
02306                                         ActionList* pActionList,
02307                                         NodeShadowController* pThisNodeShadow,
02308                                         INT32 NewAngle,
02309                                         ChangeFloorShadowAngleAction** ppNewAction,
02310                                         BOOL bReverse, BOOL bCache)
02311 {
02312     UINT32 ActSize = sizeof(ChangeFloorShadowAngleAction);
02313 
02314     ActionCode Ac = Action::Init(pOp,pActionList,ActSize,
02315         CC_RUNTIME_CLASS(ChangeFloorShadowAngleAction),
02316         (Action**)ppNewAction);
02317 
02318 
02319     Document * pDoc = Document::GetCurrent();   
02320 
02321     DocRect dr;
02322 
02323     if (Ac != AC_FAIL)
02324     {
02325         // reverse the action
02326         // DMc
02327         if (bReverse)
02328         {
02329             pActionList->RemoveItem(*ppNewAction);
02330             pActionList->AddHead(*ppNewAction);
02331         }
02332         
02333         (*ppNewAction)->m_pNodeShadowCont  = pThisNodeShadow;
02334         (*ppNewAction)->m_LastAngle = (INT32)pThisNodeShadow->GetFloorShadowAngle();
02335         (*ppNewAction)->m_bCache = bCache;
02336 
02337         // set the values, invalidate and regenerate
02338         pThisNodeShadow->InvalidateBoundingRect();
02339 
02340         dr = pThisNodeShadow->GetBoundingRect();
02341         TRACEUSER( "DavidM", _T("Rect before %d %d %d %d\n"),
02342             dr.lo.x, dr.lo.y, dr.hi.x, dr.hi.y);
02343 
02344         pDoc->ForceRedraw(pThisNodeShadow->GetShadow()->FindParentSpread(), 
02345                 pThisNodeShadow->GetBoundingRect(), FALSE, pThisNodeShadow);
02346 
02347         pThisNodeShadow->SetFloorShadowAngle(NewAngle);
02348 
02349         pThisNodeShadow->RegenerateNode(NULL, bCache);
02350 
02351         pThisNodeShadow->InvalidateBoundingRect();
02352 
02353         dr= pThisNodeShadow->GetBoundingRect();
02354         TRACEUSER( "DavidM", _T("Rect after %d %d %d %d\n"),
02355             dr.lo.x, dr.lo.y, dr.hi.x, dr.hi.y);
02356 
02357         pDoc->ForceRedraw(pThisNodeShadow->GetShadow()->FindParentSpread(), 
02358                 pThisNodeShadow->GetBoundingRect(), FALSE, pThisNodeShadow);
02359     }
02360 
02361     return Ac;
02362 }
02363 
02364 /********************************************************************************************
02365 
02366 >   ActionCode ChangeFloorShadowAngleAction::Execute();
02367 
02368     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02369     Created:    07/01/96
02370     Inputs:     -
02371     Outputs:    -
02372     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
02373     Purpose:    Executes the action.  This will reset the num blend steps in pThisNodeBlend to OldNumSteps,
02374                 after creating another action to record the current num steps of pThisNodeBlend
02375     Errors:     -
02376     SeeAlso:    Action::Init()
02377 
02378 ********************************************************************************************/
02379 
02380 ActionCode ChangeFloorShadowAngleAction::Execute()
02381 {
02382     ActionCode Act;
02383     ChangeFloorShadowAngleAction* pAction;
02384 
02385     // force a redraw of the region
02386     DocRect dr = m_LastRect;
02387 
02388     Act = ChangeFloorShadowAngleAction::Init(   pOperation, 
02389                                         pOppositeActLst,
02390                                         m_pNodeShadowCont,
02391                                         m_LastAngle,
02392                                         &pAction,
02393                                         TRUE,
02394                                         m_bCache);
02395 
02396     if (Act != AC_FAIL)
02397     {
02398         Document * pDoc = Document::GetCurrent();
02399         
02400         if (pDoc)
02401         {
02402             m_LastRect = m_pNodeShadowCont->GetBoundingRect();
02403             pDoc->ForceRedraw(m_pNodeShadowCont->GetShadow()->FindParentSpread(), 
02404                 m_LastRect, FALSE, m_pNodeShadowCont);
02405         }
02406     }
02407     
02408     return Act;
02409 }
02410 
02411 ChangeFloorShadowAngleAction::~ChangeFloorShadowAngleAction()
02412 {
02413 }
02414 
02415 //------------------------------------------------------------------------------------------------
02416 //------------------------------------------------------------------------------------------------
02417 //------------------------------------------------------------------------------------------------
02418 // The ChangeShadowTypeAction class
02419 
02420 /********************************************************************************************
02421 
02422 >   ChangeShadowTypeAction::ChangeShadowTypeAction()
02423 
02424     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02425     Created:    07/01/97
02426     Inputs:     -
02427     Outputs:    -
02428     Returns:    -
02429     Purpose:    Constructor for the action
02430     Errors:     -
02431     SeeAlso:    -
02432 
02433 ********************************************************************************************/
02434 
02435 ChangeShadowTypeAction::ChangeShadowTypeAction()
02436 {
02437     m_pNodeShadowCont  = NULL;
02438     m_LastType = SHADOWTYPE_NONE;
02439 }
02440 
02441 
02442 /********************************************************************************************
02443 
02444 >   ActionCode ChangeShadowTypeAction::Init(    Operation*  pOp,
02445                                                 ActionList* pActionList,
02446                                                 NodeShadow*     pThisNodeShadow,
02447                                                 MILLIPOINT  PenumbraSize,
02448                                                 ChangePositionShadowXAction**   ppNewAction);
02449 
02450     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02451     Created:    07/01/96
02452     Inputs:     pOp             = ptr to the operation to which this action belongs
02453                 pActionList     =  ptr to action list to which this action should be added
02454                 pThisNodeShadow = ptr to NodeShadow to change 
02455                 PenumbraSize    = New position X to apply to pThisNodeShadow
02456     Outputs:    ppNewAction     = ptr to a ptr to an action, allowing the function to return
02457                                   a pointer to the created action
02458     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
02459     Purpose:    This is the function which creates an instance of this action. If there is no room 
02460                 in the undo buffer (which is determined by the base class Init function called within)
02461                 the function will either return AC_NO_RECORD which means the operation can continue, 
02462                 but no undo information needs to be stored, or AC_OK which means the operation should
02463                 continue AND record undo information. If the function returns AC_FAIL, there was not 
02464                 enough memory to record the undo information, and the user has decided not to continue
02465                 with the operation.
02466     Errors:     -
02467     SeeAlso:    Action::Init()
02468 
02469 ********************************************************************************************/
02470 
02471 
02472 
02473 ActionCode ChangeShadowTypeAction::Init(Operation* pOp,
02474                                         ActionList* pActionList,
02475                                         NodeShadowController* pThisNodeShadow,
02476                                         ShadowType NewShadowType,
02477                                         ChangeShadowTypeAction** ppNewAction,
02478                                         BOOL bReverse)
02479 {
02480     UINT32 ActSize = sizeof(ChangeShadowTypeAction);
02481 
02482     ActionCode Ac = Action::Init(pOp,pActionList,ActSize,
02483         CC_RUNTIME_CLASS(ChangeShadowTypeAction),
02484         (Action**)ppNewAction);
02485 
02486     Document * pDoc = Document::GetCurrent();
02487 
02488     if (Ac != AC_FAIL)
02489     {
02490         // reverse the action
02491         // DMc
02492         if (bReverse)
02493         {
02494             pActionList->RemoveItem(*ppNewAction);
02495             pActionList->AddHead(*ppNewAction);
02496         }
02497 
02498         if (pDoc)
02499         {
02500             pThisNodeShadow->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
02501             pDoc->ForceRedraw(pThisNodeShadow->FindParentSpread(),
02502                 pThisNodeShadow->GetBlobBoundingRect(), FALSE, pThisNodeShadow, FALSE);
02503         }
02504         
02505         // set the values, invalidate and regenerate
02506         (*ppNewAction)->m_pNodeShadowCont  = pThisNodeShadow;
02507         (*ppNewAction)->m_LastType = pThisNodeShadow->GetShadowType();
02508 
02509         pThisNodeShadow->SetShadowType(NewShadowType);
02510 
02511         pThisNodeShadow->RegenerateNode(NULL);
02512         
02513         (*ppNewAction)->m_LastRect = (*ppNewAction)->m_pNodeShadowCont->GetBoundingRect();
02514 
02515         if (pDoc)
02516         {
02517             pThisNodeShadow->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
02518             pDoc->ForceRedraw(pThisNodeShadow->FindParentSpread(),
02519                 pThisNodeShadow->GetBlobBoundingRect(), FALSE, pThisNodeShadow, FALSE);
02520         }
02521     }
02522 
02523     return Ac;
02524 }
02525 
02526 /********************************************************************************************
02527 
02528 >   ActionCode ChangeShadowTypeAction::Execute();
02529 
02530     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02531     Created:    07/01/96
02532     Inputs:     -
02533     Outputs:    -
02534     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
02535     Purpose:    Executes the action.  This will reset the num blend steps in pThisNodeBlend to OldNumSteps,
02536                 after creating another action to record the current num steps of pThisNodeBlend
02537     Errors:     -
02538     SeeAlso:    Action::Init()
02539 
02540 ********************************************************************************************/
02541 
02542 ActionCode ChangeShadowTypeAction::Execute()
02543 {
02544     ActionCode Act;
02545     ChangeShadowTypeAction* pAction;
02546 
02547     // force a redraw of the region
02548     DocRect dr = m_LastRect;
02549 
02550     Act = ChangeShadowTypeAction::Init( pOperation, 
02551                                         pOppositeActLst,
02552                                         m_pNodeShadowCont,
02553                                         m_LastType,
02554                                         &pAction);
02555 
02556     if (Act != AC_FAIL)
02557     {
02558         Document * pDoc = Document::GetCurrent();
02559         
02560         if (pDoc)
02561         {
02562             m_LastRect = m_pNodeShadowCont->GetBoundingRect();
02563             pDoc->ForceRedraw(m_pNodeShadowCont->GetShadow()->FindParentSpread(), 
02564                 m_LastRect, FALSE, m_pNodeShadowCont);
02565         }
02566     }
02567     
02568     return Act;
02569 }
02570 
02571 ChangeShadowTypeAction::~ChangeShadowTypeAction()
02572 {
02573 }
02574 
02579 
02580 /********************************************************************************************
02581 
02582 >   OpShadowAngle::OpShadowAngle()
02583 
02584     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02585     Created:    10/6/99
02586     Inputs: 
02587     Outputs:    
02588     Returns:    
02589     Purpose:    Constructor
02590 
02591 ********************************************************************************************/
02592 OpShadowAngle::OpShadowAngle()
02593 {
02594 }
02595 
02596 /********************************************************************************************
02597 
02598 >   OpShadowAngle::~OpShadowAngle()
02599 
02600     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02601     Created:    10/6/99
02602     Inputs: 
02603     Outputs:    
02604     Returns:    
02605     Purpose:    Destructor
02606 ********************************************************************************************/
02607 OpShadowAngle::~OpShadowAngle()
02608 {
02609 }
02610 
02611 
02612 /********************************************************************************************
02613 
02614 >   BOOL OpShadowAngle::Declare()
02615 
02616     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02617     Created:    10/6/99
02618     Inputs: 
02619     Outputs:    
02620     Returns:    
02621     Purpose:    
02622 
02623 ********************************************************************************************/
02624 
02625 BOOL OpShadowAngle::Declare()
02626 {
02627     return (RegisterOpDescriptor(
02628                                 0, 
02629                                 _R(IDS_ANGLESHADOWOP),
02630                                 CC_RUNTIME_CLASS(OpShadowAngle), 
02631                                 OPTOKEN_SHADOWANGLE,
02632                                 OpShadowAngle::GetState));
02633 }
02634 
02635 /********************************************************************************************
02636 
02637 >   OpShadowAngle::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
02638 
02639     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02640     Created:    10/6/99
02641     Inputs: 
02642     Outputs:    
02643     Returns:    
02644     Purpose:    
02645 
02646 ********************************************************************************************/
02647 void OpShadowAngle::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
02648 {
02649     BeginSlowJob();
02650     DoStartSelOp(TRUE);
02651 
02652     NodeShadowParam* pNSParam = (NodeShadowParam *)pParam;
02653 
02654     ENSURE(pNSParam->pShadowTool, "Op not given pointer to shadow tool");
02655     Range* pShadowRange = pNSParam->pShadowTool->GetShadowEditRange();
02656     Node* pNode = pShadowRange->FindFirst();
02657     if (pNode==NULL)
02658     {
02659         ERROR3("Nothing was selected in OpShadowAngle");
02660         FailAndExecute();
02661         End();
02662         return;
02663     }
02664 
02665     while (pNode)
02666     {
02667         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
02668         NodeShadowController* pController = (NodeShadowController*)pNode;
02669 
02670         pController->InvalidateBoundingRect();
02671 //      DoInvalidateNodeRegion(pController, TRUE);
02672         pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
02673         DoInvalidateNodeRegion(pController, TRUE, FALSE, FALSE, FALSE); // Don't force recache - we've already handled that
02674 
02675         ChangeFloorShadowAngleAction * pAction = NULL;
02676 
02677         if (!ChangeFloorShadowAngleAction::Init(this, GetUndoActionList(), pController,
02678             (INT32)pNSParam->m_FloorShadowAngle, &pAction))
02679         {
02680             ERROR3("Change floor shadow angle action failed\n");
02681         }
02682 
02683         pController->InvalidateBoundingRect();
02684 //      DoInvalidateNodeRegion(pController, TRUE);
02685         pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
02686         DoInvalidateNodeRegion(pController, TRUE, FALSE, FALSE, FALSE); // Don't force recache - we've already handled that
02687 
02688         // inform all parents
02689         ObjChangeFlags flgs(FALSE, FALSE, FALSE, FALSE);
02690         flgs.RegenerateNode = TRUE;
02691         ObjChangeParam OP(OBJCHANGE_FINISHED, flgs, pController, this, OBJCHANGE_CALLEDBYOP);
02692         Node * pParent = pController->FindParent();
02693     
02694         while (pParent)
02695         {           
02696             pParent->OnChildChange(&OP);
02697             pParent = pParent->FindParent();
02698         }           
02699 
02700         pNode = pShadowRange->FindNext(pNode);
02701     }
02702 
02703     End();
02704 }
02705 
02706 
02707 /********************************************************************************************
02708 
02709 >   OpState OpShadowAngle::GetState(String_256* Description, OpDescriptor*)
02710 
02711     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02712     Created:    16/12/96
02713     Outputs:    -
02714     Returns:    Ungreyed, Unticked
02715     Purpose:    Find out the state of the new regular shape at the specific time
02716 
02717 ********************************************************************************************/
02718 OpState OpShadowAngle::GetState(String_256* Description, OpDescriptor*)
02719 {
02720     OpState Blobby;
02721     
02722     return Blobby;
02723 }
02724 
02729 
02730 /********************************************************************************************
02731 
02732 >   OpShadowHeight::OpShadowHeight()
02733 
02734     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02735     Created:    10/6/99
02736     Inputs: 
02737     Outputs:    
02738     Returns:    
02739     Purpose:    Constructor
02740 
02741 ********************************************************************************************/
02742 OpShadowHeight::OpShadowHeight()
02743 {
02744 }
02745 
02746 /********************************************************************************************
02747 
02748 >   OpShadowHeight::~OpShadowHeight()
02749 
02750     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02751     Created:    10/6/99
02752     Inputs: 
02753     Outputs:    
02754     Returns:    
02755     Purpose:    Destructor
02756 ********************************************************************************************/
02757 OpShadowHeight::~OpShadowHeight()
02758 {
02759 }
02760 
02761 
02762 /********************************************************************************************
02763 
02764 >   BOOL OpShadowHeight::Declare()
02765 
02766     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02767     Created:    10/6/99
02768     Inputs: 
02769     Outputs:    
02770     Returns:    
02771     Purpose:    
02772 
02773 ********************************************************************************************/
02774 
02775 BOOL OpShadowHeight::Declare()
02776 {
02777     return (RegisterOpDescriptor(
02778                                 0, 
02779                                 _R(IDS_HEIGHTSHADOWOP),
02780                                 CC_RUNTIME_CLASS(OpShadowHeight), 
02781                                 OPTOKEN_SHADOWHEIGHT,
02782                                 OpShadowHeight::GetState));
02783 }
02784 
02785 /********************************************************************************************
02786 
02787 >   OpShadowHeight::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
02788 
02789     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02790     Created:    10/6/99
02791     Inputs: 
02792     Outputs:    
02793     Returns:    
02794     Purpose:    
02795 
02796 ********************************************************************************************/
02797 void OpShadowHeight::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
02798 {
02799     // Start a slow job
02800     BeginSlowJob();
02801     DoStartSelOp(TRUE);
02802 
02803     NodeShadowParam * pNSParam = (NodeShadowParam *)pParam;
02804 
02805     ENSURE(pNSParam->pShadowTool, "Op not given pointer to shadow tool");
02806     Range* pShadowRange = pNSParam->pShadowTool->GetShadowEditRange();
02807     Node* pNode = pShadowRange->FindFirst();
02808     if (pNode==NULL)
02809     {
02810         ERROR3("Nothing was selected in OpShadowHeight");
02811         FailAndExecute();
02812         End();
02813         return;
02814     }
02815     while (pNode)
02816     {
02817         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
02818         NodeShadowController* pController = (NodeShadowController*)pNode;
02819 
02820         pController->InvalidateBoundingRect();
02821         // DoInvalidateNodeRegion(pControl, TRUE);
02822 
02823         ChangeFloorShadowHeightAction * pAction = NULL;
02824 
02825         ChangeFloorShadowHeightAction::Init(this, GetUndoActionList(), pController,
02826             pNSParam->m_FloorShadowHeight, &pAction);
02827 
02828         pController->InvalidateBoundingRect();
02829         // DoInvalidateNodeRegion(pControl, TRUE);
02830 
02831         // inform all parents
02832         ObjChangeFlags flgs(FALSE, FALSE, FALSE, FALSE);
02833         flgs.RegenerateNode = TRUE;
02834         ObjChangeParam OP(OBJCHANGE_FINISHED, flgs, pController, this, OBJCHANGE_CALLEDBYOP);
02835         Node * pParent = pController->FindParent();
02836     
02837         while (pParent)
02838         {           
02839             pParent->OnChildChange(&OP);
02840             pParent = pParent->FindParent();
02841         }
02842 
02843         pNode = pShadowRange->FindNext(pNode);
02844     }
02845 
02846     End();
02847 }
02848 
02849 
02850 /********************************************************************************************
02851 
02852 >   OpState OpShadowHeight::GetState(String_256* Description, OpDescriptor*)
02853 
02854     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02855     Created:    16/12/96
02856     Outputs:    -
02857     Returns:    Ungreyed, Unticked
02858     Purpose:    Find out the state of the new regular shape at the specific time
02859 
02860 ********************************************************************************************/
02861 OpState OpShadowHeight::GetState(String_256* Description, OpDescriptor*)
02862 {
02863     OpState Blobby;
02864     
02865     return Blobby;
02866 }
02867 
02872 
02873 /********************************************************************************************
02874 
02875 >   OpShadowScale::OpShadowScale()
02876 
02877     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02878     Created:    10/6/99
02879     Inputs: 
02880     Outputs:    
02881     Returns:    
02882     Purpose:    Constructor
02883 
02884 ********************************************************************************************/
02885 OpShadowScale::OpShadowScale()
02886 {
02887 }
02888 
02889 /********************************************************************************************
02890 
02891 >   OpShadowScale::~OpShadowScale()
02892 
02893     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02894     Created:    10/6/99
02895     Inputs: 
02896     Outputs:    
02897     Returns:    
02898     Purpose:    Destructor
02899 ********************************************************************************************/
02900 OpShadowScale::~OpShadowScale()
02901 {
02902 }
02903 
02904 
02905 /********************************************************************************************
02906 
02907 >   BOOL OpShadowScale::Declare()
02908 
02909     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02910     Created:    10/6/99
02911     Inputs: 
02912     Outputs:    
02913     Returns:    
02914     Purpose:    
02915 
02916 ********************************************************************************************/
02917 
02918 BOOL OpShadowScale::Declare()
02919 {
02920     return (RegisterOpDescriptor(
02921                                 0, 
02922                                 _R(IDS_SCALESHADOWOP),
02923                                 CC_RUNTIME_CLASS(OpShadowScale), 
02924                                 OPTOKEN_SHADOWSCALE,
02925                                 OpShadowScale::GetState));
02926 }
02927 
02928 /********************************************************************************************
02929 
02930 >   OpShadowScale::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
02931 
02932     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
02933     Created:    10/6/99
02934     Inputs: 
02935     Outputs:    
02936     Returns:    
02937     Purpose:    
02938 
02939 ********************************************************************************************/
02940 void OpShadowScale::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
02941 {
02942     // Start a slow job
02943     BeginSlowJob();
02944     DoStartSelOp(TRUE);
02945 
02946     NodeShadowParam * pNSParam = (NodeShadowParam *)pParam;
02947 
02948     ENSURE(pNSParam->pShadowTool, "Op not given pointer to shadow tool");
02949     Range* pShadowRange = pNSParam->pShadowTool->GetShadowEditRange();
02950     Node* pNode = pShadowRange->FindFirst();
02951     if (pNode==NULL)
02952     {
02953         ERROR3("Nothing was selected in OpShadowScale");
02954         FailAndExecute();
02955         End();
02956         return;
02957     }
02958     while (pNode)
02959     {
02960         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
02961         NodeShadowController* pController = (NodeShadowController*)pNode;
02962 
02963         pController->InvalidateBoundingRect();
02964         // DoInvalidateNodeRegion(pControl, TRUE);
02965 
02966         ChangeShadowScaleAction * pAction = NULL;
02967 
02968         ChangeShadowScaleAction::Init(this, GetUndoActionList(), pController,
02969             pNSParam->m_Scale, &pAction);
02970 
02971         pController->InvalidateBoundingRect();
02972         // DoInvalidateNodeRegion(pControl, TRUE);
02973 
02974         // inform all parents
02975         ObjChangeFlags flgs(FALSE, FALSE, FALSE, FALSE);
02976         flgs.RegenerateNode = TRUE;
02977         ObjChangeParam OP(OBJCHANGE_FINISHED, flgs, pController, this, OBJCHANGE_CALLEDBYOP);
02978         Node * pParent = pController->FindParent();
02979     
02980         while (pParent)
02981         {           
02982             pParent->OnChildChange(&OP);
02983             pParent = pParent->FindParent();
02984         }
02985 
02986         pNode = pShadowRange->FindNext(pNode);
02987     }
02988 
02989     End();
02990 }
02991 
02992 
02993 /********************************************************************************************
02994 
02995 >   OpState OpShadowScale::GetState(String_256* Description, OpDescriptor*)
02996 
02997     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
02998     Created:    16/12/96
02999     Outputs:    -
03000     Returns:    Ungreyed, Unticked
03001     Purpose:    Find out the state of the new regular shape at the specific time
03002 
03003 ********************************************************************************************/
03004 OpState OpShadowScale::GetState(String_256* Description, OpDescriptor*)
03005 {
03006     OpState Blobby;
03007     
03008     return Blobby;
03009 }
03010 
03011 //------------------------------------------------------------------------------------------------
03012 //------------------------------------------------------------------------------------------------
03013 //------------------------------------------------------------------------------------------------
03014 // The ChangeShadowScaleAction class
03015 
03016 /********************************************************************************************
03017 
03018 >   ChangeShadowScaleAction::ChangeShadowScaleAction()
03019 
03020     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
03021     Created:    07/01/97
03022     Inputs:     -
03023     Outputs:    -
03024     Returns:    -
03025     Purpose:    Constructor for the action
03026     Errors:     -
03027     SeeAlso:    -
03028 
03029 ********************************************************************************************/
03030 
03031 ChangeShadowScaleAction::ChangeShadowScaleAction()
03032 {
03033     m_pNodeShadowCont  = NULL;
03034     m_LastScale = 0;
03035 }
03036 
03037 
03038 /********************************************************************************************
03039 
03040 >   ActionCode ChangeShadowScaleAction::Init(   Operation*  pOp,
03041                                                 ActionList* pActionList,
03042                                                 NodeShadow*     pThisNodeShadow,
03043                                                 MILLIPOINT  PenumbraSize,
03044                                                 ChangePositionShadowXAction**   ppNewAction);
03045 
03046     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03047     Created:    10/6/99
03048     Inputs:     pOp             = ptr to the operation to which this action belongs
03049                 pActionList     =  ptr to action list to which this action should be added
03050                 pThisNodeShadow = ptr to NodeShadow to change 
03051                 PenumbraSize    = New position X to apply to pThisNodeShadow
03052     Outputs:    ppNewAction     = ptr to a ptr to an action, allowing the function to return
03053                                   a pointer to the created action
03054     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
03055     Purpose:    This is the function which creates an instance of this action. If there is no room 
03056                 in the undo buffer (which is determined by the base class Init function called within)
03057                 the function will either return AC_NO_RECORD which means the operation can continue, 
03058                 but no undo information needs to be stored, or AC_OK which means the operation should
03059                 continue AND record undo information. If the function returns AC_FAIL, there was not 
03060                 enough memory to record the undo information, and the user has decided not to continue
03061                 with the operation.
03062     Errors:     -
03063     SeeAlso:    Action::Init()
03064 
03065 ********************************************************************************************/
03066 
03067 
03068 
03069 ActionCode ChangeShadowScaleAction::Init(Operation* pOp,
03070                                         ActionList* pActionList,
03071                                         NodeShadowController* pThisNodeShadow,
03072                                         double NewScale,
03073                                         ChangeShadowScaleAction** ppNewAction,
03074                                         BOOL bReverse)
03075 {
03076     UINT32 ActSize = sizeof(ChangeShadowScaleAction);
03077 
03078     ActionCode Ac = Action::Init(pOp,pActionList,ActSize,
03079         CC_RUNTIME_CLASS(ChangeShadowScaleAction),
03080         (Action**)ppNewAction);
03081 
03082 
03083     Document * pDoc = Document::GetCurrent();   
03084 
03085     DocRect dr;
03086 
03087     if (Ac != AC_FAIL)
03088     {
03089         // reverse the action
03090         // DMc
03091         if (bReverse)
03092         {
03093             pActionList->RemoveItem(*ppNewAction);
03094             pActionList->AddHead(*ppNewAction);
03095         }
03096         
03097         (*ppNewAction)->m_pNodeShadowCont  = pThisNodeShadow;
03098         (*ppNewAction)->m_LastScale = pThisNodeShadow->GetWallShadowScale();
03099 
03100         // set the values, invalidate and regenerate
03101         pThisNodeShadow->InvalidateBoundingRect();
03102 
03103         dr = pThisNodeShadow->GetBoundingRect();
03104         TRACEUSER( "DavidM", _T("Rect before %d %d %d %d\n"),
03105             dr.lo.x, dr.lo.y, dr.hi.x, dr.hi.y);
03106 
03107         pDoc->ForceRedraw(pThisNodeShadow->GetShadow()->FindParentSpread(), 
03108                 pThisNodeShadow->GetShadow()->GetBoundingRect(), FALSE, pThisNodeShadow);
03109 
03110         pThisNodeShadow->SetWallShadowScale((float)NewScale);
03111 
03112         pThisNodeShadow->RegenerateNode(NULL);
03113 
03114         pThisNodeShadow->InvalidateBoundingRect();
03115 
03116         dr= pThisNodeShadow->GetBoundingRect();
03117         TRACEUSER( "DavidM", _T("Rect after %d %d %d %d\n"),
03118             dr.lo.x, dr.lo.y, dr.hi.x, dr.hi.y);
03119 
03120         pDoc->ForceRedraw(pThisNodeShadow->GetShadow()->FindParentSpread(), 
03121                 pThisNodeShadow->GetShadow()->GetBoundingRect(), FALSE, pThisNodeShadow);
03122     }
03123 
03124     return Ac;
03125 }
03126 
03127 /********************************************************************************************
03128 
03129 >   ActionCode ChangeShadowScaleAction::Execute();
03130 
03131     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
03132     Created:    07/01/96
03133     Inputs:     -
03134     Outputs:    -
03135     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
03136     Purpose:    Executes the action.  This will reset the num blend steps in pThisNodeBlend to OldNumSteps,
03137                 after creating another action to record the current num steps of pThisNodeBlend
03138     Errors:     -
03139     SeeAlso:    Action::Init()
03140 
03141 ********************************************************************************************/
03142 
03143 ActionCode ChangeShadowScaleAction::Execute()
03144 {
03145     ActionCode Act;
03146     ChangeShadowScaleAction* pAction;
03147 
03148     // force a redraw of the region
03149     DocRect dr = m_LastRect;
03150 
03151     Act = ChangeShadowScaleAction::Init(    pOperation, 
03152                                         pOppositeActLst,
03153                                         m_pNodeShadowCont,
03154                                         m_LastScale,
03155                                         &pAction);
03156 
03157     if (Act != AC_FAIL)
03158     {
03159         Document * pDoc = Document::GetCurrent();
03160         
03161         if (pDoc)
03162         {
03163             m_LastRect = m_pNodeShadowCont->GetBoundingRect();
03164             pDoc->ForceRedraw(m_pNodeShadowCont->GetShadow()->FindParentSpread(), 
03165                 m_LastRect, FALSE, m_pNodeShadowCont);
03166         }
03167     }
03168     
03169     return Act;
03170 }
03171 
03172 ChangeShadowScaleAction::~ChangeShadowScaleAction()
03173 {
03174 }
03175 
03180 
03181 /********************************************************************************************
03182 
03183 >   OpShadowHeightAndAngle::OpShadowHeightAndAngle()
03184 
03185     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03186     Created:    10/6/99
03187     Inputs: 
03188     Outputs:    
03189     Returns:    
03190     Purpose:    Constructor
03191 
03192 ********************************************************************************************/
03193 OpShadowHeightAndAngle::OpShadowHeightAndAngle()
03194 {
03195 }
03196 
03197 /********************************************************************************************
03198 
03199 >   OpShadowHeightAndAngle::~OpShadowHeightAndAngle()
03200 
03201     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03202     Created:    10/6/99
03203     Inputs: 
03204     Outputs:    
03205     Returns:    
03206     Purpose:    Destructor
03207 ********************************************************************************************/
03208 OpShadowHeightAndAngle::~OpShadowHeightAndAngle()
03209 {
03210 }
03211 
03212 
03213 /********************************************************************************************
03214 
03215 >   BOOL OpShadowHeightAndAngle::Declare()
03216 
03217     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03218     Created:    10/6/99
03219     Inputs: 
03220     Outputs:    
03221     Returns:    
03222     Purpose:    
03223 
03224 ********************************************************************************************/
03225 
03226 BOOL OpShadowHeightAndAngle::Declare()
03227 {
03228     return (RegisterOpDescriptor(
03229                                 0, 
03230                                 _R(IDS_HEIGHTANDANGLESHADOWOP),
03231                                 CC_RUNTIME_CLASS(OpShadowHeightAndAngle), 
03232                                 OPTOKEN_SHADOWHEIGHTANDANGLE,
03233                                 OpShadowHeightAndAngle::GetState));
03234 }
03235 
03236 /********************************************************************************************
03237 
03238 >   OpShadowHeightAndAngle::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
03239 
03240     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03241     Created:    10/6/99
03242     Inputs: 
03243     Outputs:    
03244     Returns:    
03245     Purpose:    
03246 
03247 ********************************************************************************************/
03248 void OpShadowHeightAndAngle::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
03249 {
03250     BeginSlowJob();
03251     DoStartSelOp(TRUE);
03252 
03253     NodeShadowParam * pNSParam = (NodeShadowParam *)pParam;
03254 
03255     ENSURE(pNSParam->pShadowTool, "Op not given pointer to shadow tool");
03256     Range* pShadowRange = pNSParam->pShadowTool->GetShadowEditRange();
03257     Node* pNode = pShadowRange->FindFirst();
03258     if (pNode==NULL)
03259     {
03260         ERROR3("Nothing was selected in OpShadowHeightAndAndle");
03261         FailAndExecute();
03262         End();
03263         return;
03264     }
03265     while (pNode)
03266     {
03267         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
03268         NodeShadowController* pController = (NodeShadowController*)pNode;
03269 
03270         pController->InvalidateBoundingRect();
03271         // DoInvalidateNodeRegion(pControl, TRUE);
03272 
03273         ChangeFloorShadowAngleAction * pAction = NULL;
03274         ChangeFloorShadowHeightAction * pAction2 = NULL;
03275 
03276 
03277         if (!ChangeFloorShadowAngleAction::Init(this, GetUndoActionList(), pController,
03278             (INT32)pNSParam->m_FloorShadowAngle, &pAction, TRUE, TRUE))
03279         {
03280             ERROR3("Change floor shadow angle action failed\n");
03281         }
03282 
03283         if (!ChangeFloorShadowHeightAction::Init(this, GetUndoActionList(), pController,
03284             pNSParam->m_FloorShadowHeight, &pAction2, TRUE, TRUE))
03285         {
03286             ERROR3("Change floor shadow angle action failed\n");
03287         }
03288 
03289         pController->InvalidateBoundingRect();
03290         // DoInvalidateNodeRegion(pControl, TRUE);
03291 
03292         // do the object change on the node
03293         // inform all parents
03294         ObjChangeFlags flgs(FALSE, FALSE, FALSE, FALSE);
03295         flgs.RegenerateNode = TRUE;
03296         ObjChangeParam OP(OBJCHANGE_FINISHED, flgs, pController, this, OBJCHANGE_CALLEDBYOP);
03297         Node * pParent = pController->FindParent();
03298     
03299         while (pParent)
03300         {           
03301             pParent->OnChildChange(&OP);
03302             pParent = pParent->FindParent();
03303         }
03304 
03305         pNode = pShadowRange->FindNext(pNode);
03306     }
03307 
03308     End();
03309 
03310 }
03311 
03312 
03313 /********************************************************************************************
03314 
03315 >   OpState OpShadowHeightAndAngle::GetState(String_256* Description, OpDescriptor*)
03316 
03317     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
03318     Created:    16/12/96
03319     Outputs:    -
03320     Returns:    Ungreyed, Unticked
03321     Purpose:    Find out the state of the new regular shape at the specific time
03322 
03323 ********************************************************************************************/
03324 OpState OpShadowHeightAndAngle::GetState(String_256* Description, OpDescriptor*)
03325 {
03326     OpState Blobby;
03327     
03328     return Blobby;
03329 }
03330 
03331 //------------------------------------------------------------------------------------------------
03332 //------------------------------------------------------------------------------------------------
03333 //------------------------------------------------------------------------------------------------
03334 // The SaveShadowDataAction class
03335 
03336 /********************************************************************************************
03337 
03338 >   SaveShadowDataAction::SaveShadowDataAction()
03339 
03340     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
03341     Created:    07/01/97
03342     Inputs:     -
03343     Outputs:    -
03344     Returns:    -
03345     Purpose:    Constructor for the action
03346     Errors:     -
03347     SeeAlso:    -
03348 
03349 ********************************************************************************************/
03350 
03351 SaveShadowDataAction::SaveShadowDataAction()
03352 {
03353     m_pSelRange = NULL;
03354 }
03355 
03356 
03357 /********************************************************************************************
03358 
03359 >   ActionCode Init( Operation* pOp,
03360                             ActionList* pActionList,
03361                             Range &SelRange,
03362                             SaveShadowDataAction** NewAction,
03363                             BOOL bReverse = TRUE);
03364     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03365     Created:    10/6/99
03366     Inputs:     pOp             = ptr to the operation to which this action belongs
03367                 pActionList     =  ptr to action list to which this action should be added
03368                 pThisNodeShadow = ptr to NodeShadow to change 
03369                 PenumbraSize    = New position X to apply to pThisNodeShadow
03370     Outputs:    ppNewAction     = ptr to a ptr to an action, allowing the function to return
03371                                   a pointer to the created action
03372     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
03373     Purpose:    This is the function which creates an instance of this action. If there is no room 
03374                 in the undo buffer (which is determined by the base class Init function called within)
03375                 the function will either return AC_NO_RECORD which means the operation can continue, 
03376                 but no undo information needs to be stored, or AC_OK which means the operation should
03377                 continue AND record undo information. If the function returns AC_FAIL, there was not 
03378                 enough memory to record the undo information, and the user has decided not to continue
03379                 with the operation.
03380     Errors:     -
03381     SeeAlso:    Action::Init()
03382 
03383 ********************************************************************************************/
03384 
03385 
03386 
03387 ActionCode SaveShadowDataAction::Init( Operation* pOp,
03388                             ActionList* pActionList,
03389                             Range &MyRange,
03390                             SaveShadowDataAction** ppNewAction,
03391                             BOOL bReverse)
03392 {
03393     UINT32 ActSize = sizeof(SaveShadowDataAction);
03394 
03395     ActionCode Ac = Action::Init(pOp,pActionList,ActSize,
03396         CC_RUNTIME_CLASS(SaveShadowDataAction),
03397         (Action**)ppNewAction);
03398 
03399     ShadowDragData * pItem = NULL;
03400 
03401     if (Ac != AC_FAIL)
03402     {
03403         // reverse the action
03404         // DMc
03405         if (bReverse)
03406         {
03407             pActionList->RemoveItem(*ppNewAction);
03408             pActionList->AddHead(*ppNewAction);
03409         }
03410 
03411         (*ppNewAction)->m_LastRect = MyRange.GetBoundingRect(); 
03412         
03413         // save all the data in the range
03414         ALLOC_WITH_FAIL((*ppNewAction)->m_pSelRange, new Range(MyRange), pOp);
03415 
03416         Node * pNode = (*ppNewAction)->m_pSelRange->FindFirst();
03417 
03418         Spread *pSpread = NULL;
03419 
03420         while (pNode)
03421         {
03422             pSpread = pNode->FindParentSpread();
03423             
03424             if (pNode->IsKindOf(CC_RUNTIME_CLASS(NodeShadowController)))
03425             {
03426                 ALLOC_WITH_FAIL(pItem, new ShadowDragData, pOp);
03427 
03428                 if (!pItem)
03429                 {
03430                     return AC_FAIL;
03431                 }
03432 
03433                 pItem->PenumbraSize = ((NodeShadowController *)pNode)->GetPenumbraWidth();
03434                 pItem->PositionShadowX = ((NodeShadowController *)pNode)->GetOffsetX();
03435                 pItem->PositionShadowY = ((NodeShadowController *)pNode)->GetOffsetY();
03436                 pItem->ShadowAngle = ((NodeShadowController *)pNode)->GetFloorShadowAngle();
03437                 pItem->ShadowHeight = ((NodeShadowController *)pNode)->GetFloorShadowHeight();
03438                 pItem->ShadowScale = ((NodeShadowController *)pNode)->GetWallShadowScale();
03439                 pItem->GlowWidth   = ((NodeShadowController *)pNode)->GetGlowWidth();
03440                 pItem->FeatherWidth = ((NodeShadowController*)pNode)->GetFeatherWidth();
03441 
03442                 (*ppNewAction)->m_DataList.AddTail(pItem);
03443             }
03444 
03445             pNode = (*ppNewAction)->m_pSelRange->FindNext(pNode);
03446         }
03447     }
03448 
03449     return Ac;
03450 }
03451 
03452 /********************************************************************************************
03453 
03454 >   ActionCode SaveShadowDataAction::Execute();
03455 
03456     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
03457     Created:    07/01/96
03458     Inputs:     -
03459     Outputs:    -
03460     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
03461     Purpose:    Executes the action.  This will reset the num blend steps in pThisNodeBlend to OldNumSteps,
03462                 after creating another action to record the current num steps of pThisNodeBlend
03463     Errors:     -
03464     SeeAlso:    Action::Init()
03465 
03466 ********************************************************************************************/
03467 
03468 ActionCode SaveShadowDataAction::Execute()
03469 {
03470     ActionCode Act;
03471     SaveShadowDataAction* pAction;
03472 
03473     // force a redraw of the region
03474     DocRect dr = m_LastRect;
03475 
03476     Act = SaveShadowDataAction::Init(   pOperation, 
03477                                         pOppositeActLst,
03478                                         *m_pSelRange,
03479                                         &pAction);
03480 
03481     Document * pDoc = Document::GetCurrent();
03482 
03483     if (Act != AC_FAIL)
03484     {
03485         Node * pNode = m_pSelRange->FindFirst();
03486         ShadowDragData * pItem = (ShadowDragData *)m_DataList.GetHead();
03487 
03488         while (pNode)
03489         {
03490             if (pNode->IsKindOf(CC_RUNTIME_CLASS(NodeShadowController)) && pItem)
03491             {
03492                 // invalidate the last region
03493                 if (pDoc)
03494                 {
03495                     pDoc->ForceRedraw(pNode->FindParentSpread(), ((NodeShadowController *)pNode)->GetShadow()->GetBoundingRect(), TRUE, pNode);
03496                 }               
03497         
03498                 ((NodeShadowController *)pNode)->SetPenumbraWidth(pItem->PenumbraSize);
03499                 ((NodeShadowController *)pNode)->SetOffsetX(pItem->PositionShadowX);
03500                 ((NodeShadowController *)pNode)->SetOffsetY(pItem->PositionShadowY);
03501                 ((NodeShadowController *)pNode)->SetFloorShadowAngle(pItem->ShadowAngle);
03502                 ((NodeShadowController *)pNode)->SetFloorShadowHeight(pItem->ShadowHeight);
03503                 ((NodeShadowController *)pNode)->SetWallShadowScale(pItem->ShadowScale);
03504                 ((NodeShadowController *)pNode)->SetGlowWidth(pItem->GlowWidth);
03505                 ((NodeShadowController*)pNode)->SetFeatherWidth(pItem->FeatherWidth);
03506 
03507                 TRACEUSER( "DavidM", _T("Setting floor shadow angle %d\n"), pItem->ShadowAngle);
03508                 
03509                 pItem = (ShadowDragData *)m_DataList.GetNext(pItem);
03510 
03511                 // regenerate the node
03512                 pNode->RegenerateNode(NULL, FALSE);
03513 
03514                 // invalidate the last region
03515                 if (pDoc)
03516                 {
03517                     pDoc->ForceRedraw(pNode->FindParentSpread(), ((NodeShadowController *)pNode)->GetShadow()->GetBoundingRect(), TRUE, pNode);
03518                 }               
03519 
03520                 GetApplication()->ServiceRendering();
03521             }
03522 
03523             pNode = m_pSelRange->FindNext(pNode);
03524         }
03525     }
03526 
03527     return Act;
03528 }
03529 
03530 SaveShadowDataAction::~SaveShadowDataAction()
03531 {
03532     m_DataList.DeleteAll();
03533 
03534     if (m_pSelRange)
03535         delete m_pSelRange;
03536 }
03537 
03542 
03543 /********************************************************************************************
03544 
03545 >   OpSaveShadowData::OpSaveShadowData()
03546 
03547     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03548     Created:    10/6/99
03549     Inputs: 
03550     Outputs:    
03551     Returns:    
03552     Purpose:    Constructor
03553 
03554 ********************************************************************************************/
03555 OpSaveShadowData::OpSaveShadowData()
03556 {
03557     m_OpName = 0;
03558 }
03559 
03560 /********************************************************************************************
03561 
03562 >   OpSaveShadowData::~OpSaveShadowData()
03563 
03564     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03565     Created:    10/6/99
03566     Inputs: 
03567     Outputs:    
03568     Returns:    
03569     Purpose:    Destructor
03570 ********************************************************************************************/
03571 OpSaveShadowData::~OpSaveShadowData()
03572 {
03573 }
03574 
03575 /********************************************************************************************
03576 
03577 >   void OpSaveShadowData::GetOpName(String_256 * pString)
03578 
03579     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03580     Created:    10/6/99
03581     Inputs: 
03582     Outputs:    
03583     Returns:    
03584     Purpose:    Gets the op name
03585 ********************************************************************************************/
03586 void OpSaveShadowData::GetOpName(String_256 * pString)
03587 {
03588     if (pString && m_OpName != 0)
03589     {
03590         pString->Load(m_OpName);
03591     }
03592 }
03593 
03594 
03595 
03596 /********************************************************************************************
03597 
03598 >   BOOL OpSaveShadowData::Declare()
03599 
03600     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03601     Created:    10/6/99
03602     Inputs: 
03603     Outputs:    
03604     Returns:    
03605     Purpose:    
03606 
03607 ********************************************************************************************/
03608 
03609 BOOL OpSaveShadowData::Declare()
03610 {
03611     return (RegisterOpDescriptor(
03612                                 0, 
03613                                 _R(IDS_SAVESHADOWDATAOP),
03614                                 CC_RUNTIME_CLASS(OpSaveShadowData), 
03615                                 OPTOKEN_SAVESHADOWDATA,
03616                                 OpSaveShadowData::GetState));
03617 }
03618 
03619 /********************************************************************************************
03620 
03621 >   BOOL OpSaveShadowData::SaveShadowData(UndoableOperation * pOp)
03622 
03623     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03624     Created:    25/1/2000
03625     Inputs:     The undoable operation to use
03626     Outputs:    
03627     Returns:    TRUE for success, FALSE for failure
03628     Purpose:    Saves the shadow in the selection at this point, so it can be restored
03629                 on an undo
03630 
03631 ********************************************************************************************/
03632 BOOL OpSaveShadowData::SaveShadowData(UndoableOperation * pOp)
03633 {
03634     Range MyRange(*(GetApplication()->FindSelection()));
03635 
03636     RangeControl rg = MyRange.GetRangeControlFlags();
03637     rg.PromoteToParent = TRUE;
03638     MyRange.SetRangeControl(rg);
03639 
03640     Spread * pSpread = Document::GetSelectedSpread();
03641 
03642     SaveShadowDataAction * pAction = NULL;
03643 
03644     if (SaveShadowDataAction::Init(pOp, pOp->GetUndoActionList(), MyRange, &pAction) != AC_OK)
03645         return FALSE;
03646 
03647     // now, invalidate the whole range's blob bounds
03648     Node * pNode = MyRange.FindFirst();
03649     DocRect Bounds;
03650 
03651     while (pNode)
03652     {
03653         if (pNode->IsAnObject())
03654         {
03655 // Nothing changed - so why recache eveything?
03656 //          ((NodeRenderableInk *)pNode)->ReleaseCached();
03657             Bounds = Bounds.Union(((NodeRenderableInk *)pNode)->GetBlobBoundingRect());
03658         }
03659 
03660         pNode = MyRange.FindNext(pNode);
03661     }
03662 
03663     BlobManager * pBlobMgr = GetApplication()->GetBlobManager();
03664 
03665     if (pBlobMgr)
03666     {
03667         Bounds.Inflate(pBlobMgr->GetBlobSize());
03668     }
03669 
03670     if (pSpread)
03671     {
03672         if (!pOp->DoInvalidateRegion(pSpread, Bounds))
03673         {
03674             return FALSE;
03675         }
03676     }
03677 
03678     return TRUE;
03679 }
03680 
03681 /********************************************************************************************
03682 
03683 >   void OpSaveShadowData::DoWithParam(OpDescriptor* pOp, OpParam * pParam)
03684 
03685     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03686     Created:    10/6/99
03687     Inputs: 
03688     Outputs:    
03689     Returns:    
03690     Purpose:    Saves the shadow in the selection at this point, so it can be restored
03691                 on an undo
03692 
03693 ********************************************************************************************/
03694 void OpSaveShadowData::DoWithParam(OpDescriptor* pOp, OpParam * pParam)
03695 {
03696     // Start a slow job
03697     BeginSlowJob();
03698     DoStartSelOp(TRUE);
03699 
03700     m_OpName = ((SaveShadowDataInfo *)pParam)->ID;
03701 
03702     if (!SaveShadowData(this))
03703     {
03704         ERROR2RAW("Can't save shadow data");
03705     }
03706     
03707     End();
03708 }
03709 
03710 
03711 /********************************************************************************************
03712 
03713 >   OpState OpSaveShadowData::GetState(String_256* Description, OpDescriptor*)
03714 
03715     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
03716     Created:    16/12/96
03717     Outputs:    -
03718     Returns:    Ungreyed, Unticked
03719     Purpose:    Find out the state of the new regular shape at the specific time
03720 
03721 ********************************************************************************************/
03722 OpState OpSaveShadowData::GetState(String_256* Description, OpDescriptor*)
03723 {
03724     OpState Blobby;
03725     
03726     return Blobby;
03727 }
03728 
03729 
03730 //------------------------------------------------------------------------------------------------
03731 //------------------------------------------------------------------------------------------------
03732 //------------------------------------------------------------------------------------------------
03733 // The ChangeGlowWidthAction class
03734 
03735 /********************************************************************************************
03736 
03737 >   ChangeGlowWidthAction::ChangeGlowWidthAction()
03738 
03739     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
03740     Created:    07/01/97
03741     Inputs:     -
03742     Outputs:    -
03743     Returns:    -
03744     Purpose:    Constructor for the action
03745     Errors:     -
03746     SeeAlso:    -
03747 
03748 ********************************************************************************************/
03749 
03750 ChangeGlowWidthAction::ChangeGlowWidthAction()
03751 {
03752     m_pNodeShadowCont  = NULL;
03753     m_LastWidth = 0;
03754 }
03755 
03756 
03757 /********************************************************************************************
03758 
03759 >   ActionCode ChangeGlowWidthAction::Init(     Operation*  pOp,
03760                                                 ActionList* pActionList,
03761                                                 NodeShadow*     pThisNodeShadow,
03762                                                 MILLIPOINT  PenumbraSize,
03763                                                 ChangePositionShadowXAction**   ppNewAction);
03764 
03765     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03766     Created:    10/6/99
03767     Inputs:     pOp             = ptr to the operation to which this action belongs
03768                 pActionList     =  ptr to action list to which this action should be added
03769                 pThisNodeShadow = ptr to NodeShadow to change 
03770                 PenumbraSize    = New position X to apply to pThisNodeShadow
03771     Outputs:    ppNewAction     = ptr to a ptr to an action, allowing the function to return
03772                                   a pointer to the created action
03773     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
03774     Purpose:    This is the function which creates an instance of this action. If there is no room 
03775                 in the undo buffer (which is determined by the base class Init function called within)
03776                 the function will either return AC_NO_RECORD which means the operation can continue, 
03777                 but no undo information needs to be stored, or AC_OK which means the operation should
03778                 continue AND record undo information. If the function returns AC_FAIL, there was not 
03779                 enough memory to record the undo information, and the user has decided not to continue
03780                 with the operation.
03781     Errors:     -
03782     SeeAlso:    Action::Init()
03783 
03784 ********************************************************************************************/
03785 
03786 
03787 
03788 ActionCode ChangeGlowWidthAction::Init(Operation* pOp,
03789                                         ActionList* pActionList,
03790                                         NodeShadowController* pThisNodeShadow,
03791                                         INT32 NewWidth,
03792                                         ChangeGlowWidthAction** ppNewAction,
03793                                         BOOL bReverse, BOOL bCache)
03794 {
03795     UINT32 ActSize = sizeof(ChangeGlowWidthAction);
03796 
03797     ActionCode Ac = Action::Init(pOp,pActionList,ActSize,
03798         CC_RUNTIME_CLASS(ChangeGlowWidthAction),
03799         (Action**)ppNewAction);
03800 
03801 
03802     Document * pDoc = Document::GetCurrent();   
03803 
03804     DocRect dr;
03805 
03806     if (Ac != AC_FAIL)
03807     {
03808         // reverse the action
03809         // DMc
03810         if (bReverse)
03811         {
03812             pActionList->RemoveItem(*ppNewAction);
03813             pActionList->AddHead(*ppNewAction);
03814         }
03815         
03816         (*ppNewAction)->m_pNodeShadowCont  = pThisNodeShadow;
03817         (*ppNewAction)->m_LastWidth = pThisNodeShadow->GetGlowWidth();
03818         (*ppNewAction)->m_bCache = bCache;
03819 
03820         // set the values, invalidate and regenerate
03821         pThisNodeShadow->InvalidateBoundingRect();
03822 
03823         dr = pThisNodeShadow->GetBoundingRect();
03824         TRACEUSER( "DavidM", _T("Rect before %d %d %d %d\n"),
03825             dr.lo.x, dr.lo.y, dr.hi.x, dr.hi.y);
03826 
03827         pDoc->ForceRedraw(pThisNodeShadow->GetShadow()->FindParentSpread(), 
03828                 pThisNodeShadow->GetShadow()->GetBoundingRect(), FALSE, pThisNodeShadow);
03829 
03830         pThisNodeShadow->SetGlowWidth(NewWidth);
03831 
03832         pThisNodeShadow->RegenerateNode(NULL, bCache);
03833 
03834         pThisNodeShadow->InvalidateBoundingRect();
03835 
03836         dr= pThisNodeShadow->GetBoundingRect();
03837         TRACEUSER( "DavidM", _T("Rect after %d %d %d %d\n"),
03838             dr.lo.x, dr.lo.y, dr.hi.x, dr.hi.y);
03839 
03840         pDoc->ForceRedraw(pThisNodeShadow->GetShadow()->FindParentSpread(), 
03841                 pThisNodeShadow->GetShadow()->GetBoundingRect(), FALSE, pThisNodeShadow);
03842     }
03843 
03844     return Ac;
03845 }
03846 
03847 /********************************************************************************************
03848 
03849 >   ActionCode ChangeGlowWidthAction::Execute();
03850 
03851     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
03852     Created:    07/01/96
03853     Inputs:     -
03854     Outputs:    -
03855     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
03856     Purpose:    Executes the action.  This will reset the num blend steps in pThisNodeBlend to OldNumSteps,
03857                 after creating another action to record the current num steps of pThisNodeBlend
03858     Errors:     -
03859     SeeAlso:    Action::Init()
03860 
03861 ********************************************************************************************/
03862 
03863 ActionCode ChangeGlowWidthAction::Execute()
03864 {
03865     ActionCode Act;
03866     ChangeGlowWidthAction* pAction;
03867 
03868     // force a redraw of the region
03869     DocRect dr = m_LastRect;
03870 
03871     Act = ChangeGlowWidthAction::Init(  pOperation, 
03872                                         pOppositeActLst,
03873                                         m_pNodeShadowCont,
03874                                         m_LastWidth,
03875                                         &pAction,
03876                                         TRUE,
03877                                         m_bCache);
03878 
03879     if (Act != AC_FAIL)
03880     {
03881         Document * pDoc = Document::GetCurrent();
03882         
03883         if (pDoc)
03884         {
03885             m_LastRect = m_pNodeShadowCont->GetBoundingRect();
03886 
03887             pDoc->ForceRedraw(m_pNodeShadowCont->FindParentSpread(), 
03888                 m_LastRect, FALSE, m_pNodeShadowCont);
03889         }
03890     }
03891     
03892     return Act;
03893 }
03894 
03895 ChangeGlowWidthAction::~ChangeGlowWidthAction()
03896 {
03897 }
03898 
03903 
03904 /********************************************************************************************
03905 
03906 >   OpGlowWidth::OpGlowWidth()
03907 
03908     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03909     Created:    10/6/99
03910     Inputs: 
03911     Outputs:    
03912     Returns:    
03913     Purpose:    Constructor
03914 
03915 ********************************************************************************************/
03916 OpGlowWidth::OpGlowWidth()
03917 {
03918 }
03919 
03920 /********************************************************************************************
03921 
03922 >   OpGlowWidth::~OpGlowWidth()
03923 
03924     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03925     Created:    10/6/99
03926     Inputs: 
03927     Outputs:    
03928     Returns:    
03929     Purpose:    Destructor
03930 ********************************************************************************************/
03931 OpGlowWidth::~OpGlowWidth()
03932 {
03933 }
03934 
03935 
03936 /********************************************************************************************
03937 
03938 >   BOOL OpGlowWidth::Declare()
03939 
03940     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03941     Created:    10/6/99
03942     Inputs: 
03943     Outputs:    
03944     Returns:    
03945     Purpose:    
03946 
03947 ********************************************************************************************/
03948 
03949 BOOL OpGlowWidth::Declare()
03950 {
03951     return (RegisterOpDescriptor(
03952                                 0, 
03953                                 _R(IDS_GLOWWIDTHOP),
03954                                 CC_RUNTIME_CLASS(OpGlowWidth), 
03955                                 OPTOKEN_GLOWWIDTH,
03956                                 OpGlowWidth::GetState));
03957 }
03958 
03959 /********************************************************************************************
03960 
03961 >   OpGlowWidth::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
03962 
03963     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
03964     Created:    10/6/99
03965     Inputs: 
03966     Outputs:    
03967     Returns:    
03968     Purpose:    
03969 
03970 ********************************************************************************************/
03971 void OpGlowWidth::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
03972 {
03973     // Start a slow job
03974     BeginSlowJob();
03975     DoStartSelOp(TRUE);
03976 
03977     NodeShadowParam * pNSParam = (NodeShadowParam *)pParam;
03978 
03979     ENSURE(pNSParam->pShadowTool, "Op not given pointer to shadow tool");
03980     Range* pShadowRange = pNSParam->pShadowTool->GetShadowEditRange();
03981     Node* pNode = pShadowRange->FindFirst();
03982     if (pNode==NULL)
03983     {
03984         ERROR3("Nothing was selected in OpShadowPenumbra");
03985         FailAndExecute();
03986         End();
03987         return;
03988     }
03989     while (pNode)
03990     {
03991         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
03992         NodeShadowController* pController = (NodeShadowController*)pNode;
03993 
03994 //      pController->ReleaseCached();
03995 //      DoInvalidateRegion(pController->FindParentSpread(), pController->GetBlobBoundingRect());
03996         pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
03997         DoInvalidateNodeRegion(pController, TRUE, FALSE, FALSE, FALSE);
03998         
03999         ChangeGlowWidthAction * pAction = NULL;
04000 
04001         ChangeGlowWidthAction::Init(this, GetUndoActionList(), pController,
04002             pNSParam->m_GlowWidth, &pAction);
04003 
04004         // do the object change on the node
04005         ObjChangeFlags flgs(FALSE, FALSE, FALSE, TRUE);
04006         ObjChangeParam OP(OBJCHANGE_FINISHED, flgs, pController, this, OBJCHANGE_CALLEDBYOP);
04007         Node * pNodeParent = pController->FindParent();
04008 
04009         while (pNodeParent)
04010         {
04011             pNodeParent->OnChildChange(&OP);
04012 
04013             pNodeParent = pNodeParent->FindParent();
04014         }
04015 
04016 //      pController->ReleaseCached();
04017 //      DoInvalidateRegion(pController->FindParentSpread(), pController->GetBlobBoundingRect());
04018         pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
04019         DoInvalidateNodeRegion(pController, TRUE, FALSE, FALSE, FALSE);
04020 
04021         pNode = pShadowRange->FindNext(pNode);
04022     }
04023 
04024     End();
04025 }
04026 
04027 
04028 /********************************************************************************************
04029 
04030 >   OpState OpGlowWidth::GetState(String_256* Description, OpDescriptor*)
04031 
04032     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
04033     Created:    16/12/96
04034     Outputs:    -
04035     Returns:    Ungreyed, Unticked
04036     Purpose:    Find out the state of the new regular shape at the specific time
04037 
04038 ********************************************************************************************/
04039 OpState OpGlowWidth::GetState(String_256* Description, OpDescriptor*)
04040 {
04041     OpState Blobby;
04042     
04043     return Blobby;
04044 }
04045 
04050 
04051 /********************************************************************************************
04052 
04053 >   OpChangeShadowProfile::OpChangeShadowProfile()
04054 
04055     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
04056     Created:    10/6/99
04057     Inputs: 
04058     Outputs:    
04059     Returns:    
04060     Purpose:    Constructor
04061 
04062 ********************************************************************************************/
04063 OpChangeShadowProfile::OpChangeShadowProfile()
04064 {
04065 }
04066 
04067 /********************************************************************************************
04068 
04069 >   OpChangeShadowProfile::~OpChangeShadowProfile()
04070 
04071     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
04072     Created:    10/6/99
04073     Inputs: 
04074     Outputs:    
04075     Returns:    
04076     Purpose:    Destructor
04077 ********************************************************************************************/
04078 OpChangeShadowProfile::~OpChangeShadowProfile()
04079 {
04080 }
04081 
04082 
04083 /********************************************************************************************
04084 
04085 >   BOOL OpChangeShadowProfile::Declare()
04086 
04087     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
04088     Created:    10/6/99
04089     Inputs: 
04090     Outputs:    
04091     Returns:    
04092     Purpose:    
04093 
04094 ********************************************************************************************/
04095 
04096 BOOL OpChangeShadowProfile::Declare()
04097 {
04098     return (RegisterOpDescriptor(
04099                                 0, 
04100                                 _R(IDS_SHADOWPROFILE),
04101                                 CC_RUNTIME_CLASS(OpChangeShadowProfile), 
04102                                 OPTOKEN_SHADOWPROFILE,
04103                                 OpChangeShadowProfile::GetState));
04104 }
04105 
04106 /********************************************************************************************
04107 
04108 >   OpChangeShadowProfile::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
04109 
04110     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
04111     Created:    10/6/99
04112     Inputs: 
04113     Outputs:    
04114     Returns:    
04115     Purpose:    
04116 
04117 ********************************************************************************************/
04118 void OpChangeShadowProfile::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
04119 {
04120     // Start a slow job
04121     BeginSlowJob();
04122     DoStartSelOp(TRUE);
04123 
04124     // run through the selection changing all profiles
04125     CProfileBiasGain Profile;
04126 
04127     // recast the op param
04128     ShadowProfileOpParam * pProfileParam = (ShadowProfileOpParam *)pParam;
04129 
04130     CProfileBiasGain OldGain;
04131 
04132     ENSURE(pProfileParam->m_pTool, "Op not given pointer to shadow tool");
04133     Range* pShadowRange = pProfileParam->m_pTool->GetShadowEditRange();
04134     Node* pNode = pShadowRange->FindFirst();
04135 
04136     // If the range is empty just stop without doing anything
04137     // This allows Profile dialog to remain onscreen while selection changes
04138     // (Should really be greyed out)
04139     if (pNode==NULL)
04140     {
04141         FailAndExecute();
04142         End();
04143         return;
04144     }
04145 
04146     while (pNode)
04147     {
04148         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
04149         NodeShadowController* pController = (NodeShadowController*)pNode;
04150         NodeShadow* pShadow = pController->GetShadow();
04151 
04152         // initialise the action
04153         ChangeProfileAction * pAction;
04154         ChangeProfileAction::Init(this, GetUndoActionList(), pShadow, pProfileParam->Profile, &pAction);
04155 
04156         pNode = pShadowRange->FindNext(pNode);
04157     }
04158 
04159     End();
04160 }
04161 
04162 
04163 /********************************************************************************************
04164 
04165 >   OpState OpChangeShadowProfile::GetState(String_256* Description, OpDescriptor*)
04166 
04167     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
04168     Created:    16/12/96
04169     Outputs:    -
04170     Returns:    Ungreyed, Unticked
04171     Purpose:    Find out the state of the new regular shape at the specific time
04172 
04173 ********************************************************************************************/
04174 OpState OpChangeShadowProfile::GetState(String_256* Description, OpDescriptor*)
04175 {
04176     OpState Blobby;
04177     
04178     return Blobby;
04179 }
04180 
04181 //------------------------------------------------------------------------------------------------
04182 //------------------------------------------------------------------------------------------------
04183 //------------------------------------------------------------------------------------------------
04184 // The ChangeProfileAction class
04185 
04186 /********************************************************************************************
04187 
04188 >   ChangeProfileAction::ChangeProfileAction()
04189 
04190     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
04191     Created:    07/01/97
04192     Inputs:     -
04193     Outputs:    -
04194     Returns:    -
04195     Purpose:    Constructor for the action
04196     Errors:     -
04197     SeeAlso:    -
04198 
04199 ********************************************************************************************/
04200 
04201 ChangeProfileAction::ChangeProfileAction()
04202 {
04203     m_pNodeShadow  = NULL;
04204 }
04205 
04206 
04207 /********************************************************************************************
04208 
04209 >   ActionCode ChangeProfileAction::Init(   Operation*  pOp,
04210                                                 ActionList* pActionList,
04211                                                 NodeShadow*     pThisNodeShadow,
04212                                                 MILLIPOINT  PenumbraSize,
04213                                                 ChangePositionShadowXAction**   ppNewAction);
04214 
04215     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
04216     Created:    10/6/99
04217     Inputs:     pOp             = ptr to the operation to which this action belongs
04218                 pActionList     =  ptr to action list to which this action should be added
04219                 pThisNodeShadow = ptr to NodeShadow to change 
04220                 PenumbraSize    = New position X to apply to pThisNodeShadow
04221     Outputs:    ppNewAction     = ptr to a ptr to an action, allowing the function to return
04222                                   a pointer to the created action
04223     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
04224     Purpose:    This is the function which creates an instance of this action. If there is no room 
04225                 in the undo buffer (which is determined by the base class Init function called within)
04226                 the function will either return AC_NO_RECORD which means the operation can continue, 
04227                 but no undo information needs to be stored, or AC_OK which means the operation should
04228                 continue AND record undo information. If the function returns AC_FAIL, there was not 
04229                 enough memory to record the undo information, and the user has decided not to continue
04230                 with the operation.
04231     Errors:     -
04232     SeeAlso:    Action::Init()
04233 
04234 ********************************************************************************************/
04235 
04236 
04237 
04238 ActionCode ChangeProfileAction::Init( Operation* pOp,
04239                             ActionList* pActionList,
04240                             NodeShadow* pThisNodeShadow,
04241                             CProfileBiasGain &Profile,
04242                             ChangeProfileAction** ppNewAction,
04243                             BOOL bReverse,
04244                             BOOL bCache)
04245 {
04246     UINT32 ActSize = sizeof(ChangeProfileAction);
04247 
04248     ActionCode Ac = Action::Init(pOp,pActionList,ActSize,
04249         CC_RUNTIME_CLASS(ChangeProfileAction),
04250         (Action**)ppNewAction);
04251 
04252     Document * pDoc = Document::GetCurrent();   
04253 
04254     DocRect dr;
04255 
04256     if (Ac != AC_FAIL)
04257     {
04258         // reverse the action
04259         // DMc
04260         if (bReverse)
04261         {
04262             pActionList->RemoveItem(*ppNewAction);
04263             pActionList->AddHead(*ppNewAction);
04264         }
04265         
04266         (*ppNewAction)->m_pNodeShadow  = pThisNodeShadow;
04267         (*ppNewAction)->m_LastProfile  = pThisNodeShadow->GetBiasGain();
04268 
04269         // set the values, invalidate and regenerate
04270         pThisNodeShadow->InvalidateBoundingRect();
04271 
04272         pDoc->ForceRedraw(pThisNodeShadow->FindParentSpread(), 
04273                 pThisNodeShadow->GetBoundingRect(), FALSE, pThisNodeShadow);
04274 
04275         pThisNodeShadow->SetBiasGain(Profile);
04276 
04277         ((NodeShadowController*)pThisNodeShadow->GetParentController())->RegenerateNode(NULL, bCache);
04278 
04279         pThisNodeShadow->InvalidateBoundingRect();
04280 
04281         dr= ((NodeShadowController*)pThisNodeShadow->GetParentController())->GetBoundingRect();
04282         TRACEUSER( "DavidM", _T("Rect after %d %d %d %d\n"),
04283             dr.lo.x, dr.lo.y, dr.hi.x, dr.hi.y);
04284 
04285         pDoc->ForceRedraw(pThisNodeShadow->FindParentSpread(), 
04286                 pThisNodeShadow->GetBoundingRect(), FALSE, pThisNodeShadow);
04287     }
04288 
04289     return Ac;
04290 }
04291 
04292 
04293 
04294 /********************************************************************************************
04295 
04296 >   void ChangeProfileAction::ChangeShadowProfileWithNoUndo(CProfileBiasGain &Profile, SoftShadowTool* pShadowTool)
04297 
04298     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
04299     Created:    24/2/2000
04300     Inputs:     Profile - the profile that is to be applied directly (i.e.  applied with no undo)
04301     Purpose:    When applying shadow profiles, we only want to generate one bit of undo information.
04302                 This function allows us to meet this requirement (the one bit of undo information
04303                 is generated via OpChangeShadowProfile::DoWithParam ()).  This function is ONLY
04304                 called from within SoftShadowInfoBarOp::ChangeProfile () - after
04305                 OpChangeShadowProfile::DoWithParam () has been called.
04306     Errors:     -
04307     SeeAlso:    SoftShadowInfoBarOp::ChangeProfile (), OpChangeShadowProfile::DoWithParam ().
04308 
04309 ********************************************************************************************/
04310 
04311 void ChangeProfileAction::ChangeShadowProfileWithNoUndo (CProfileBiasGain &Profile, SoftShadowTool* pShadowTool)
04312 {
04313     // Start a slow job
04314     BeginSlowJob();
04315 
04316     // run through the selection changing all profiles
04317     CProfileBiasGain OldGain;
04318 
04319     Document * pDoc = Document::GetCurrent();
04320 
04321     ENSURE(pShadowTool, "Op not given pointer to shadow tool");
04322     Range* pShadowRange = pShadowTool->GetShadowEditRange();
04323     Node* pNode = pShadowRange->FindFirst();
04324     while (pNode)
04325     {
04326         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
04327         NodeShadowController* pController = (NodeShadowController*)pNode;
04328         NodeShadow* pThisNodeShadow = pController->GetShadow();
04329 
04330         pThisNodeShadow->SetBiasGain(Profile);
04331 
04332         pController->RegenerateNode(NULL, FALSE);                                       //bCache);
04333 
04334         pThisNodeShadow->InvalidateBoundingRect();
04335 
04336         pDoc->ForceRedraw(pThisNodeShadow->FindParentSpread(), 
04337                           pThisNodeShadow->GetBoundingRect(), FALSE, pThisNodeShadow);
04338 
04339         pNode = pShadowRange->FindNext(pNode);
04340     }
04341 
04342     EndSlowJob ();
04343 
04344     if (pDoc->GetOpHistory ().CanRedo ())
04345     {
04346         // then we need to clear out the redo information - since we are now 'before' it ....
04347         pDoc->GetOpHistory ().DeleteRedoableOps ();
04348 
04349         // and update the state of things ....
04350         DialogBarOp::SetSystemStateChanged();
04351         DialogBarOp::UpdateStateOfAllBars();
04352     }
04353 }
04354 
04355 /********************************************************************************************
04356 
04357 >   ActionCode ChangeProfileAction::Execute();
04358 
04359     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
04360     Created:    07/01/96
04361     Inputs:     -
04362     Outputs:    -
04363     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
04364     Purpose:    Executes the action.  This will reset the num blend steps in pThisNodeBlend to OldNumSteps,
04365                 after creating another action to record the current num steps of pThisNodeBlend
04366     Errors:     -
04367     SeeAlso:    Action::Init()
04368 
04369 ********************************************************************************************/
04370 
04371 ActionCode ChangeProfileAction::Execute()
04372 {
04373     ActionCode Act;
04374     ChangeProfileAction* pAction;
04375 
04376     Act = ChangeProfileAction::Init(    pOperation, 
04377                                         pOppositeActLst,
04378                                         m_pNodeShadow,
04379                                         m_LastProfile,
04380                                         &pAction,
04381                                         TRUE,
04382                                         FALSE);
04383 
04384     NodeCompound* pController = m_pNodeShadow->GetParentController();
04385 
04386     if (Act != AC_FAIL)
04387     {
04388         Document * pDoc = Document::GetCurrent();
04389         
04390         if (pDoc)
04391         {
04392             DocRect dr = pController->GetBoundingRect();
04393             
04394             pDoc->ForceRedraw(pController->FindParentSpread(), 
04395                 dr, FALSE, pController);
04396         }
04397     }
04398     
04399     return Act;
04400 }
04401 
04402 ChangeProfileAction::~ChangeProfileAction()
04403 {
04404 }
04405 
04410 
04411 /********************************************************************************************
04412 
04413 >   OpChangeShadowDarkness::OpChangeShadowDarkness()
04414 
04415     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
04416     Created:    10/6/99
04417     Inputs: 
04418     Outputs:    
04419     Returns:    
04420     Purpose:    Constructor
04421 
04422 ********************************************************************************************/
04423 OpChangeShadowDarkness::OpChangeShadowDarkness()
04424 {
04425 }
04426 
04427 /********************************************************************************************
04428 
04429 >   OpChangeShadowDarkness::~OpChangeShadowDarkness()
04430 
04431     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
04432     Created:    10/6/99
04433     Inputs: 
04434     Outputs:    
04435     Returns:    
04436     Purpose:    Destructor
04437 ********************************************************************************************/
04438 OpChangeShadowDarkness::~OpChangeShadowDarkness()
04439 {
04440 }
04441 
04442 
04443 /********************************************************************************************
04444 
04445 >   BOOL OpChangeShadowDarkness::Declare()
04446 
04447     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
04448     Created:    10/6/99
04449     Inputs: 
04450     Outputs:    
04451     Returns:    
04452     Purpose:    
04453 
04454 ********************************************************************************************/
04455 
04456 BOOL OpChangeShadowDarkness::Declare()
04457 {
04458     return (RegisterOpDescriptor(
04459                                 0, 
04460                                 _R(IDS_SHADOWDARKNESS),
04461                                 CC_RUNTIME_CLASS(OpChangeShadowDarkness), 
04462                                 OPTOKEN_SHADOWDARKNESS,
04463                                 OpChangeShadowDarkness::GetState));
04464 }
04465 
04466 /********************************************************************************************
04467 
04468 >   OpChangeShadowDarkness::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
04469 
04470     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
04471     Created:    10/6/99
04472     Inputs: 
04473     Outputs:    
04474     Returns:    
04475     Purpose:    
04476 
04477 ********************************************************************************************/
04478 void OpChangeShadowDarkness::DoWithParam(OpDescriptor* pOp, OpParam* pParam)
04479 {
04480     // Start a slow job
04481     BeginSlowJob();
04482     DoStartSelOp(TRUE);
04483 
04484     // recast the op param
04485     ShadowDarknessOpParam * pDarknessParam = (ShadowDarknessOpParam *)pParam;
04486 
04487     ENSURE(pDarknessParam->m_pTool, "Op not given pointer to shadow tool");
04488     Range* pShadowRange = pDarknessParam->m_pTool->GetShadowEditRange();
04489     Node* pNode = pShadowRange->FindFirst();
04490     if (pNode==NULL)
04491     {
04492         ERROR3("Nothing was selected in OpChangeShadowDarkness");
04493         FailAndExecute();
04494         End();
04495         return;
04496     }
04497     while (pNode)
04498     {
04499         ENSURE(pNode->IsAShadowController(), "Found unexpected node type");
04500         NodeShadowController* pController = (NodeShadowController*)pNode;
04501         NodeShadow* pShadow = pController->GetShadow();
04502             
04503         // invoke the action
04504         ChangeShadowDarknessAction * pAction = NULL;
04505 
04506         if (ChangeShadowDarknessAction::Init(this, this->GetUndoActionList(), pShadow,
04507             pDarknessParam->m_dDarkness, &pAction, FALSE, FALSE) != AC_OK)
04508         {
04509             FailAndExecute();
04510             End();
04511             return;
04512         }
04513 
04514         pController->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
04515 //      if (!DoInvalidateRegion(pController->FindParentSpread(), pController->GetBlobBoundingRect()))
04516         if (!DoInvalidateNodeRegion(pController, TRUE, FALSE, FALSE, FALSE))
04517         {
04518             FailAndExecute();
04519             End();
04520             return;
04521         }
04522 
04523         // tell all parents of the controller node
04524         // inform all parents
04525         ObjChangeFlags flgs(FALSE, FALSE, FALSE, FALSE);
04526         flgs.RegenerateNode = TRUE;
04527         ObjChangeParam OP(OBJCHANGE_FINISHED, flgs, pController, this, OBJCHANGE_CALLEDBYCHILD);
04528 
04529         Node *pParent = pController->FindParent();
04530         while (pParent)
04531         {           
04532             pParent->OnChildChange(&OP);
04533             pParent = pParent->FindParent();
04534         }
04535                 
04536                 
04537         pNode = pShadowRange->FindNext(pNode);
04538     }
04539 
04540     End();
04541 }
04542 
04543 
04544 /********************************************************************************************
04545 
04546 >   OpState OpChangeShadowDarkness::GetState(String_256* Description, OpDescriptor*)
04547 
04548     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
04549     Created:    16/12/96
04550     Outputs:    -
04551     Returns:    Ungreyed, Unticked
04552     Purpose:    Find out the state of the new regular shape at the specific time
04553 
04554 ********************************************************************************************/
04555 OpState OpChangeShadowDarkness::GetState(String_256* Description, OpDescriptor*)
04556 {
04557     OpState Blobby;
04558     
04559     return Blobby;
04560 }
04561 
04562 //------------------------------------------------------------------------------------------------
04563 //------------------------------------------------------------------------------------------------
04564 //------------------------------------------------------------------------------------------------
04565 // The ChangeShadowDarknessAction class
04566 
04567 /********************************************************************************************
04568 
04569 >   ChangeShadowDarknessAction::ChangeShadowDarknessAction()
04570 
04571     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
04572     Created:    07/01/97
04573     Inputs:     -
04574     Outputs:    -
04575     Returns:    -
04576     Purpose:    Constructor for the action
04577     Errors:     -
04578     SeeAlso:    -
04579 
04580 ********************************************************************************************/
04581 
04582 ChangeShadowDarknessAction::ChangeShadowDarknessAction()
04583 {
04584     m_pNodeShadow  = NULL;
04585 }
04586 
04587 
04588 /********************************************************************************************
04589 
04590 >   ActionCode ChangeShadowDarknessAction::Init(( Operation* pOp,
04591                             ActionList* pActionList,
04592                             NodeShadow* pThisNodeShadow,
04593                             double dDarkness;
04594                             ChangeShadowDarknessAction** NewAction,
04595                             BOOL bReverse = TRUE,
04596                             BOOL bCache = FALSE);
04597 
04598     Author:     David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
04599     Created:    10/6/99
04600     Inputs:     pOp             = ptr to the operation to which this action belongs
04601                 pActionList     =  ptr to action list to which this action should be added
04602                 pThisNodeShadow = ptr to NodeShadow to change 
04603                 PenumbraSize    = New position X to apply to pThisNodeShadow
04604     Outputs:    ppNewAction     = ptr to a ptr to an action, allowing the function to return
04605                                   a pointer to the created action
04606     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
04607     Purpose:    This is the function which creates an instance of this action. If there is no room 
04608                 in the undo buffer (which is determined by the base class Init function called within)
04609                 the function will either return AC_NO_RECORD which means the operation can continue, 
04610                 but no undo information needs to be stored, or AC_OK which means the operation should
04611                 continue AND record undo information. If the function returns AC_FAIL, there was not 
04612                 enough memory to record the undo information, and the user has decided not to continue
04613                 with the operation.
04614     Errors:     -
04615     SeeAlso:    Action::Init()
04616 
04617 ********************************************************************************************/
04618 
04619 
04620 
04621 ActionCode ChangeShadowDarknessAction::Init( Operation* pOp,
04622                             ActionList* pActionList,
04623                             NodeShadow* pThisNodeShadow,
04624                             double dDarkness,
04625                             ChangeShadowDarknessAction** NewAction,
04626                             BOOL bReverse,
04627                             BOOL bCache)
04628 {
04629     UINT32 ActSize = sizeof(ChangeShadowDarknessAction);
04630 
04631     ActionCode Ac = Action::Init(pOp,pActionList,ActSize,
04632         CC_RUNTIME_CLASS(ChangeShadowDarknessAction),
04633         (Action**)NewAction);
04634 
04635     Document * pDoc = Document::GetCurrent();   
04636 
04637     DocRect dr;
04638 
04639     if (Ac != AC_FAIL)
04640     {
04641         (*NewAction)->m_pNodeShadow  = pThisNodeShadow;
04642 
04643         double dOldDarkness = pThisNodeShadow->GetDarkness();
04644 
04645         (*NewAction)->m_dLastDarkness = dOldDarkness;
04646 
04647         // set the values, invalidate and regenerate
04648         pThisNodeShadow->InvalidateBoundingRect();
04649 
04650         pDoc->ForceRedraw(pThisNodeShadow->FindParentSpread(), 
04651                 pThisNodeShadow->GetBoundingRect(), FALSE, pThisNodeShadow);
04652 
04653         pThisNodeShadow->SetDarkness(dDarkness);
04654 
04655         pThisNodeShadow->InvalidateBoundingRect();
04656 
04657         dr = pThisNodeShadow->GetParentController()->GetBoundingRect();
04658 
04659         pDoc->ForceRedraw(pThisNodeShadow->FindParentSpread(), 
04660             pThisNodeShadow->GetBoundingRect(), FALSE, pThisNodeShadow);
04661     }
04662 
04663     return Ac;
04664 }
04665 
04666 /********************************************************************************************
04667 
04668 >   ActionCode ChangeShadowDarknessAction::Execute();
04669 
04670     Author:     Olivier_Gascoin (Xara Group Ltd) <camelotdev@xara.com>
04671     Created:    07/01/96
04672     Inputs:     -
04673     Outputs:    -
04674     Returns:    ActionCode, one of AC_OK, AC_NO_RECORD or AC_FAIL
04675     Purpose:    Executes the action.  This will reset the num blend steps in pThisNodeBlend to OldNumSteps,
04676                 after creating another action to record the current num steps of pThisNodeBlend
04677     Errors:     -
04678     SeeAlso:    Action::Init()
04679 
04680 ********************************************************************************************/
04681 
04682 ActionCode ChangeShadowDarknessAction::Execute()
04683 {
04684     ActionCode Act;
04685     ChangeShadowDarknessAction* pAction;
04686 
04687     Act = ChangeShadowDarknessAction::Init( pOperation, 
04688                                         pOppositeActLst,
04689                                         m_pNodeShadow,
04690                                         m_dLastDarkness,
04691                                         &pAction,
04692                                         TRUE,
04693                                         FALSE);
04694 
04695     NodeCompound* pController = m_pNodeShadow->GetParentController();
04696 
04697     if (Act != AC_FAIL)
04698     {
04699         Document * pDoc = Document::GetCurrent();
04700         
04701         if (pDoc)
04702         {
04703             DocRect dr = pController->GetBoundingRect();
04704             
04705             pDoc->ForceRedraw(pController->FindParentSpread(), 
04706                 dr, FALSE, pController);
04707         }
04708     }
04709     
04710     return Act;
04711 }
04712 
04713 ChangeShadowDarknessAction::~ChangeShadowDarknessAction()
04714 {
04715 }
04716 
04717 
04718 
04719 
04720 
04721 
04722 
04723 
04724 
04725 
04726 #endif  // BUILDSHADOWS

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