opdupbar.cpp

Go to the documentation of this file.
00001 // $Id: opdupbar.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 // Code for the Duplication of bars
00099 // and the synchronisation of text across a bar
00100 
00101 
00102 #include "camtypes.h"
00103 //#include "sliceres.h"
00104 //#include "simon.h"
00105 
00106 #include "transop.h"
00107 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 
00109 #include "slice.h"
00110 
00111 //#include "cxfrech.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "userattr.h"
00113 #include "tmpltatr.h"
00114 
00115 #include "progress.h"
00116 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00117 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00118 
00119 #include "ngcore.h"
00120 #include "ngitem.h"
00121 #include "ngprop.h"
00122 #include "ngsentry.h"
00123 
00124 #include "slicehelper.h"
00125 #include "opdupbar.h"
00126 #include "slicetool.h"
00127 
00128 #include "nodetxtl.h" // for textline def
00129 #include "objchge.h" // for child change stuff
00130 #include "sprdmsg.h"    // SpreadMsg
00131 
00132 #ifdef _DEBUG
00133 #undef THIS_FILE
00134 static char BASED_CODE THIS_FILE[] = __FILE__;
00135 #endif
00136 
00137 DECLARE_SOURCE("$Revision: 1282 $");
00138 
00139 CC_IMPLEMENT_DYNCREATE(OpDuplicateBar, CarbonCopyOp)
00140 CC_IMPLEMENT_DYNCREATE(OpShortenBar, CarbonCopyOp)
00141 CC_IMPLEMENT_DYNCREATE(OpDelBar, CarbonCopyOp)
00142 CC_IMPLEMENT_DYNCREATE(OpShowState, UndoableOperation)
00143 
00144 
00145 #define new CAM_DEBUG_NEW
00146 
00147 
00148 
00149 /********************************************************************************************
00150 
00151 >   OpClone::OpDuplicateBar() 
00152 
00153     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00154     Created:    30/9/99
00155     Purpose:    OpBarCreation constructor
00156     Errors:     -
00157     SeeAlso:    CarbonCopyOp
00158 
00159 ********************************************************************************************/            
00160 OpDuplicateBar::OpDuplicateBar(): CarbonCopyOp()                                
00161 {
00162     m_ExistingButtonsInBar = 0;
00163 }
00164 
00165 
00166 
00167 /********************************************************************************************
00168 
00169 >   BOOL OpDuplicateBar::Init()
00170 
00171     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00172     Created:    30/9/99
00173     Returns:    TRUE if the operation could be successfully initialised 
00174                 FALSE if no more memory could be allocated 
00175     Purpose:    OpDuplicateBar initialiser method
00176     Errors:     ERROR will be called if there was insufficient memory to allocate the 
00177                 operation.
00178     SeeAlso:    -
00179 
00180 ********************************************************************************************/
00181 BOOL OpDuplicateBar::Init()
00182 {
00183     return  (RegisterOpDescriptor(0,
00184                                 _R(IDS_BARDUPLICATIONOP),
00185                                 CC_RUNTIME_CLASS(OpDuplicateBar),
00186                                 OPTOKEN_BARDUPLICATIONOP,
00187                                 OpDuplicateBar::GetState,
00188                                 0,                  // help ID 
00189                                 0, //_R(IDBBL_BARDUPLICATIONOP),// bubble help
00190                                 0,                  // resource ID
00191                                 0, //_R(IDC_BC_CREATE),     // control ID
00192                                 SYSTEMBAR_ILLEGAL,  // Bar ID
00193                                 TRUE,               // Receive messages
00194                                 FALSE,
00195                                 FALSE,
00196                                 0,
00197                                 (GREY_WHEN_NO_CURRENT_DOC | DONT_GREY_WHEN_SELECT_INSIDE) ));
00198 }
00199 
00200 
00201 
00202 /********************************************************************************************
00203 
00204 >   OpState OpDuplicateBar::GetState(String_256*, OpDescriptor*)
00205 
00206     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com> based on Jason
00207     Created:    30/9/99
00208     Returns:    The state of the OpDuplicateBar
00209     Purpose:    For finding the operations state.  
00210 
00211 ********************************************************************************************/
00212 OpState OpDuplicateBar::GetState(String_256* UIDescription, OpDescriptor *Bob)
00213 {
00214     OpState OpSt;
00215 
00216     // if we don't allow it
00217     OpSt.Greyed = TRUE;
00218     Spread* pSpread = Document::GetSelectedSpread();
00219     if (pSpread && !pSpread->FindActiveLayer()->IsFrame())
00220         OpSt.Greyed = FALSE;
00221 
00222     return(OpSt);   
00223 }
00224 
00225 /********************************************************************************************
00226 
00227 >   void OpDuplicateBar::DoWithParam(OpDescriptor* token, OpParam* pOpParam)
00228 
00229     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00230     Created:    30/9/99
00231     Inputs:     OpParam - describes the bar to be dupicated
00232                         - and the name to call the copy
00233     Outputs:    -
00234     Returns:    -
00235     Purpose:    Clones a bar, but gives the bar a new name and each button in the bar
00236                 and new name. This is so each bar can work independantly or together.
00237                 If they are just copied they would have the same bar IDs and the same
00238                 button names which is not likely to be what the user would expect.
00239     Errors:     -
00240     SeeAlso:    OpBarCreation::DoWithParam, CarbonCopyOp::DoProcessing
00241 
00242 ********************************************************************************************/   
00243 void OpDuplicateBar::DoWithParam(OpDescriptor* token, OpParam* pOpParam)
00244 {
00245     if (DoStartSelOp(FALSE,TRUE))  // Try to record the selection state
00246     {
00247         // unpack the names of the bar to be copied and the new bars name from the params
00248         DuplicateBar(((OpParamBarDuplication *)pOpParam)->m_OldBarName,
00249                     ((OpParamBarDuplication *)pOpParam)->m_NewBarName,
00250                     ((OpParamBarDuplication *)pOpParam)->m_ButtonsToAdd,
00251                     ((OpParamBarDuplication *)pOpParam)->m_Spacing,
00252                     ((OpParamBarDuplication *)pOpParam)->m_IsHoriz);
00253 
00254 
00255         // end the op
00256         End();
00257 
00258         DialogBarOp::SetSystemStateChanged();
00259         DialogBarOp::UpdateStateOfAllBars(); 
00260 
00261     }
00262     else
00263     {
00264         FailAndExecute();
00265         End();
00266     }
00267 }
00268 
00269 
00270 /********************************************************************************************
00271 
00272 >   void OpDuplicateBar::DuplicateBar(String_256 &OriginalBarName, String_256 &NewBarName)
00273 
00274     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00275     Created:    30/9/99
00276     Inputs:     OriginalBarName - the bar to be dupicated
00277                 NewBarName      - the name to call the copy
00278                 ButtonsToAdd    - 0 means it copies the bar over with an exact clone
00279                                   any other number implies add this many buttons to the bar
00280                                   must be less or equal to the number of buttons in the bar
00281                                   to start with, since it duplicates the existing ones of
00282                                   that number.
00283                 Spacing         - In conjunction with the buttons to add only spaces out the
00284                                   new buttons.
00285     Outputs:    -
00286     Returns:    -
00287     Purpose:    Clones a bar, but gives the bar a new name and each button in the bar
00288                 and new name. This is so each bar can work independantly or together.
00289                 If they are just copied they would have the same bar IDs and the same
00290                 button names which is not likely to be what the user would expect.
00291 
00292 ********************************************************************************************/   
00293 void OpDuplicateBar::DuplicateBar(String_256 &OriginalBarName, String_256 &NewBarName, INT32 ButtonsToAdd, INT32 Spacing, BOOL IsHoriz)
00294 {
00295 
00296     // scan each of the special state layers for the original bar members
00297     // pionters to these template attributes are stored in the BarList
00298 
00299     // I don't want bar duplication at the moment thanks.
00300     // I just want to 
00301     ASSERT (ButtonsToAdd > 0);
00302 
00303     String_256 templayer;
00304     Layer * pLayer = NULL;
00305 
00306     List BarList;
00307 
00308     templayer.Load(_R(IDS_ROLLOVER_DEFAULT));
00309     pLayer = SliceHelper::FindLayerCalled(templayer);
00310     Layer * pDefLayer = pLayer;
00311     if (pLayer)
00312         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, OriginalBarName);
00313 
00314     templayer.Load(_R(IDS_ROLLOVER_MOUSE));
00315     pLayer = SliceHelper::FindLayerCalled(templayer);
00316     if (pLayer)
00317         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, OriginalBarName);
00318 
00319     templayer.Load(_R(IDS_ROLLOVER_CLICKED));
00320     pLayer = SliceHelper::FindLayerCalled(templayer);
00321     if (pLayer)
00322         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, OriginalBarName);
00323 
00324     templayer.Load(_R(IDS_ROLLOVER_SELECTED));
00325     pLayer = SliceHelper::FindLayerCalled(templayer);
00326     if (pLayer)
00327         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, OriginalBarName);
00328 
00329     // calculate the dimensions of the bar
00330     // this is so we can work out where to place the bar copy
00331     // which is incidently placed either just to the right
00332     // or just bellow depending upon orientation
00333 
00334     NodeListItem *pNodeListItem = (NodeListItem *)BarList.GetHead();
00335     NodeListItem *pDelThisToo = NULL;
00336 
00337     // find the number of buttons in the bar and what they are called
00338     m_ExistingButtonsInBar = 0;
00339     SliceHelper::CountButtonsInBarScan(pDefLayer, (TemplateAttribute **) m_ppFoundButton, &m_ExistingButtonsInBar, OriginalBarName);
00340 
00341     templayer = ((TemplateAttribute *) m_ppFoundButton[0])->GetParam();
00342 
00343     DocRect BarDim;
00344     DocRect FirstButtonDim;
00345 
00346     BarDim.MakeEmpty();
00347     FirstButtonDim.MakeEmpty();
00348 
00349     while(pNodeListItem)
00350     {
00351         Node* pNode = pNodeListItem->pNode->FindParent();
00352         if (pNode)
00353         {
00354             BarDim = BarDim.Union(((NodeRenderableBounded *) pNode)->GetBoundingRect());
00355             if (templayer.CompareTo(((TemplateAttribute *)pNodeListItem->pNode)->GetParam()) == 0)
00356                 FirstButtonDim = FirstButtonDim.Union(((NodeRenderableBounded *) pNode)->GetBoundingRect());
00357         }
00358         pNodeListItem = (NodeListItem *)BarList.GetNext(pNodeListItem);
00359     }
00360     
00361     // calc the transform matrix to be applied to each element when we copy it
00362     Trans2DMatrix Transformer;
00363 
00364     // test differences between the first button and the whole bar in with compared to height
00365     if (BarDim.hix - BarDim.lox + FirstButtonDim.hix - FirstButtonDim.lox > 
00366         BarDim.hiy - BarDim.loy + FirstButtonDim.hiy - FirstButtonDim.loy)
00367         Transformer.SetTransform(0, BarDim.loy - BarDim.hiy);
00368     else
00369         Transformer.SetTransform(BarDim.hix - BarDim.lox, 0);
00370 
00371     // find new names for the new buttons
00372     String_256 TempButtonName;
00373     INT32 i = 0, listbuttonno = 0;
00374     for (i = 0; i < MAX_BUTTONS_IN_A_BAR; i++)
00375     {
00376         m_ButtonNumberList[i] = i;
00377         if (i < max(m_ExistingButtonsInBar, ButtonsToAdd))
00378         {
00379             // get the next free button name and put it into listbuttonno
00380             SliceHelper::GetNextFreeButtonName(listbuttonno);
00381 
00382             m_ButtonNumberList[i] = listbuttonno;
00383         }
00384     }
00385 
00386     // copy each item referenced by a template attrib marked with this bar ID
00387     pNodeListItem = (NodeListItem *)BarList.GetHead();
00388     String_256 Name = "";
00389 
00390     // Prepare an ObjChangeParam so we can mark which nodes will allow this op to happen to them
00391     ObjChangeFlags cFlags;
00392     //cFlags.MultiReplaceNode = TRUE;
00393     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00394 
00395     while(pNodeListItem)
00396     {
00397         pDelThisToo = pNodeListItem;
00398         Node *pNode = pNodeListItem->pNode;
00399         if (pNode && pNode->AllowOp(&ObjChange))
00400         {
00401             if (ButtonsToAdd == 0) // add the whole lot as a new bar
00402             {
00403                 Node * NewNode = CopyBarMember(pNode, OriginalBarName, NewBarName, &Transformer);
00404                 if (NewNode)
00405                     NewNode->AllowOp(&ObjChange);
00406             }
00407             else
00408             {
00409                 // add a few buttons on the end
00410                 Name = ((TemplateAttribute *)pNode)->GetParam();
00411 
00412                 // note it just copies the first button several times to make the new buttons
00413                 if (Name.CompareTo(((TemplateAttribute *) m_ppFoundButton[0])->GetParam()) == 0)
00414                     for (i = 0; i < ButtonsToAdd; i++)
00415                     {
00416                         // alter tranformer for each button
00417                         if (IsHoriz)
00418                             Transformer.SetTransform(BarDim.hix - BarDim.lox + (i+1)*(Spacing) + i*(FirstButtonDim.hix - FirstButtonDim.lox), 0);
00419                         else
00420                             Transformer.SetTransform(0, BarDim.loy - BarDim.hiy - ((i+1)*(Spacing) + i*( FirstButtonDim.hiy - FirstButtonDim.loy)));
00421 
00422                         Node * NewNode = CopyBarMember(pNode, OriginalBarName, OriginalBarName, &Transformer, &i);
00423                         if (NewNode)
00424                             NewNode->AllowOp(&ObjChange);
00425                     }
00426             }
00427         }
00428 
00429         pNodeListItem = (NodeListItem *)BarList.GetNext(pNodeListItem);
00430 
00431         // tidy up the list as we go along
00432         BarList.RemoveItem((NodeListItem *)pDelThisToo);
00433         delete pDelThisToo;
00434     }
00435 
00436     // touch the bar in question
00437     NameGallery * pNameGallery = NameGallery::Instance();
00438     if (pNameGallery)
00439     {
00440         pNameGallery->m_TouchedBar = SliceHelper::GetBarNumberFromBarName(NewBarName);
00441     }
00442 
00443     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
00444     UpdateChangedNodes(&ObjChange);
00445 
00446 
00447     BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::NONCOLOURATTCHANGED));
00448 
00449 }
00450 
00451 
00452 /********************************************************************************************
00453 
00454 >   void OpDuplicateBar::CopyBarMember(Node * pNode, const String_256 &OriginalBarName, const String_256 &NewBarName, Trans2DMatrix * pTransformer)
00455 
00456     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00457     Created:    30/9/99
00458     Inputs:     pNode           -   Ptr to the Template attribute that marks this 
00459                                     nodes parent as being a member of the bar
00460                 OriginalBarName -   The name of the bar that is being copied
00461                 NewBarName      -   The name of the copy of the bar
00462                 pTransformer    -   The transform matrix that is applied to all copies
00463                 pKnownButtonIndex-  Ptr to an INT32 that if defined saves a bit of calculation
00464                                     since it is the index into the m_ButtonNumberList that
00465                                     stores the button number of the button being made.
00466                                     If not defined it gets this number from a scan based on
00467                                     the button name of this node being copied.
00468     Outputs:    -
00469     Returns:    -
00470     Purpose:    Copies a single member of a bar.
00471                 Any template attributes that relate to the old original bar
00472                 are replaced with references to the new bar.
00473                 Also will generate new stretching attributes for a new button
00474                 based on those of the source.
00475     Errors:     -
00476 
00477 ********************************************************************************************/   
00478 Node* OpDuplicateBar::CopyBarMember(Node * pNode, const String_256 &OriginalBarName, const String_256 &NewBarName, Trans2DMatrix * pTransformer, const INT32 * pKnownButtonIndex)
00479 {
00480     // Make a copy of the current node
00481     Node* pTheCopy;
00482 
00483     // Assumes that the parent of the wix attribute is the main node that needs
00484     // copying. This is a fair assumption being as that is where the bar creation
00485     // op puts it.
00486     Node* pCurrent = pNode->FindParent();
00487     BOOL CopiedOK = TRUE;
00488 
00489     String_256  Target = ""; // the button name of the selection
00490     String_256  Extender = ""; // the thing in this button that extends it
00491     DocRect rTarget;
00492     DocRect rExtender;
00493     BYTE ExtenderFlags = 0;
00494     INT32 RequiredLevel = 0;
00495     RequiredLevel = SliceHelper::FindTargetAndExtender(pCurrent, Target, Extender, RequiredLevel, &ExtenderFlags, &rTarget, &rExtender);
00496 
00497     // no longer unselect the old bar as this fn is only used for adding buttons from button 1 really now
00498     //pCurrent->SetSelected(FALSE);
00499 
00500     // where to insert this new node
00501     Node * pInsertPt = pCurrent->FindParent();
00502     while (!pInsertPt->IsLayer())
00503         pInsertPt = pInsertPt->FindParent();
00504 
00505     // create a copy of the node
00506     CALL_WITH_FAIL(pCurrent->NodeCopy(&pTheCopy), this, CopiedOK);
00507     if (!CopiedOK) return NULL; // couldn't copy -> fail
00508 
00509     // insert the copy into the tree
00510     DoInsertNewNode((NodeRenderableBounded *)pTheCopy, pInsertPt, LASTCHILD,
00511                                                      TRUE,      // Do Invalidate region 
00512                                                      FALSE);    // Don't Clear the selections
00513     // don't have any of these new nodes selected
00514     pTheCopy->SetSelected(FALSE);
00515 
00516     // clean the attributes of the copy.
00517     // remove all references to the old bar and
00518     // replace with references to the new bar.
00519     // Also update the name given to the button set.
00520     Node* pAttrib = pTheCopy->FindFirstChild();
00521     Node* pNext = NULL;
00522 
00523     BOOL goon = TRUE;
00524     while(pAttrib && goon)
00525     {
00526         pNext = pAttrib->FindNext();
00527         if (pAttrib->IsAnAttribute())
00528         {
00529             if (IS_A(pAttrib, TemplateAttribute))
00530             {
00531                 String_256 ButtonName = ((TemplateAttribute *)pAttrib)->GetParam();
00532                 String_256 AttrName = ((TemplateAttribute *)pAttrib)->GetQuestion();
00533                 // found the actual button marker
00534                 // since this has the marker of the bar name
00535                 BOOL IsBarButton = (OriginalBarName.CompareTo(AttrName) == 0);
00536                 BOOL IsExtender = (ButtonName.CompareTo(Extender) == 0);
00537 
00538                 if (IsBarButton || IsExtender)
00539                 {
00540                     String_256 NewButtonName = "";
00541                     
00542                     if (pKnownButtonIndex)
00543                         NewButtonName.MakeMsg(_R(IDS_BUTTONNAME), m_ButtonNumberList[*pKnownButtonIndex]);
00544                     else
00545                         NewButtonName = GetNewButtonName(ButtonName);
00546 
00547                     String_256 ExtenderPostfix;
00548                     ExtenderPostfix.Load(_R(IDS_EXTENDER_POSTFIX));
00549                     String_256 NewExtenderName = NewButtonName;
00550                     NewExtenderName += ExtenderPostfix;
00551 
00552                     TemplateAttribute* pNewAttr = new TemplateAttribute(String_256(TEXT("ObjectName")),
00553                                                                         IsBarButton ? NewBarName : "",
00554                                                                         IsBarButton ? NewButtonName : NewExtenderName);
00555 
00556                     if (pNewAttr) // create the node ok
00557                     {
00558                         pNewAttr->AttachNode(pTheCopy, FIRSTCHILD);
00559 
00560                         if (IsBarButton)
00561                         {
00562                             if (!Target.IsEmpty() && RequiredLevel > 1)
00563                                 // create the properties for the button/Target that this extender extends
00564                                 SliceHelper::CreatePropertiesForSet(NewButtonName, NewBarName, TRUE, TRUE, FALSE, ExtenderFlags,
00565                                                                         NewExtenderName, FALSE, &rTarget, &rExtender, this);
00566                             else // create none stretching attribs for the button
00567                                 SliceHelper::CreatePropertiesForSet(NewButtonName, NewBarName, TRUE, FALSE, FALSE, 0,
00568                                                                         TEXT(""), FALSE, NULL, NULL, this);
00569 
00570                             // test to see if this button is in fact a trigger for something bigger
00571                             // if the source is ButtonName then add NewButtonName to that list
00572                             SliceHelper::MakeTriggerLikeExample(NewButtonName, ButtonName);
00573                         }
00574                         else // create the properties for the extender
00575                         {
00576                             SliceHelper::CreatePropertiesForSet(NewExtenderName, TEXT(""), FALSE, FALSE, FALSE, 0,
00577                                                                     TEXT(""), FALSE, NULL, NULL, this);
00578                             // test to see if this extender is in fact a trigger for something bigger
00579                             // but not just the button we already know it to trigger
00580                             // if the source is ButtonName then add NewButtonName to that list
00581                             SliceHelper::MakeTriggerLikeExample(NewExtenderName, Extender, &Target);
00582                         }
00583 
00584                         DoHideNode(pAttrib, TRUE);
00585                     }
00586                 }
00587             }
00588         }
00589 
00590         pAttrib = pNext;
00591     }
00592 
00593     // transform the node into its new location in the bar
00594     ((NodeRenderableBounded *)pTheCopy)->Transform(*pTransformer);
00595 
00596     return pTheCopy;
00597 }
00598 
00599 /********************************************************************************************
00600 
00601 >   String_256 OpDuplicateBar::GetNewButtonName(String_256 &Name)
00602 
00603     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00604     Created:    30/9/99
00605     Inputs:     Name    -   The name of the button in the original bar
00606     Outputs:    -
00607     Returns:    The corresponding button in the new bar
00608     Purpose:    Generates names for the new bar.
00609 
00610 ********************************************************************************************/   
00611 String_256 OpDuplicateBar::GetNewButtonName(String_256 &Name)
00612 {
00613     String_256 TempButtonName;
00614     INT32 butno = -1;
00615     INT32 i = 0;
00616     for (i = 0; butno < 0 && i < m_ExistingButtonsInBar; i++)
00617     {
00618         if (Name.CompareTo(((TemplateAttribute *) m_ppFoundButton[i])->GetParam()) == 0)
00619             butno = i;
00620     }
00621 
00622     // return the button if we have found the extender
00623     if (butno < 0)
00624     {
00625         String_256 ExtenderPostfix;
00626         ExtenderPostfix.Load(_R(IDS_EXTENDER_POSTFIX));
00627 
00628         for (i = 0; butno < 0 && i < m_ExistingButtonsInBar; i++)
00629         {
00630             TempButtonName = ((TemplateAttribute *) m_ppFoundButton[i])->GetParam();
00631             TempButtonName += ExtenderPostfix;
00632 
00633             if (Name.CompareTo(TempButtonName) == 0)
00634                 butno = i;
00635         }
00636     }
00637 
00638     if (butno < 0)
00639         butno = m_ExistingButtonsInBar;
00640 
00641     TempButtonName.MakeMsg(_R(IDS_BUTTONNAME), m_ButtonNumberList[butno]);
00642     return TempButtonName;
00643 }
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 /********************************************************************************************
00652 
00653 >   OpShortenBar::OpShortenBar() 
00654 
00655     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00656     Created:    15/10/99
00657     Purpose:    OpShortenBar constructor
00658     Errors:     -
00659     SeeAlso:    CarbonCopyOp
00660 
00661 ********************************************************************************************/            
00662 OpShortenBar::OpShortenBar(): CarbonCopyOp()                                
00663 {                              
00664 }
00665 
00666 
00667 
00668 /********************************************************************************************
00669 
00670 >   BOOL OpShortenBar::Init()
00671 
00672     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00673     Created:    15/10/99
00674     Returns:    TRUE if the operation could be successfully initialised 
00675                 FALSE if no more memory could be allocated 
00676     Purpose:    OpShortenBar initialiser method
00677     Errors:     ERROR will be called if there was insufficient memory to allocate the 
00678                 operation.
00679     SeeAlso:    -
00680 
00681 ********************************************************************************************/
00682 BOOL OpShortenBar::Init()
00683 {
00684     return  (RegisterOpDescriptor(0,
00685                                 _R(IDS_BARDUPLICATIONOP),
00686                                 CC_RUNTIME_CLASS(OpShortenBar),
00687                                 OPTOKEN_SHORTENBAROP,
00688                                 OpShortenBar::GetState,
00689                                 0,                  // help ID 
00690                                 0, //_R(IDBBL_BARDUPLICATIONOP),// bubble help
00691                                 0,                  // resource ID
00692                                 0, //_R(IDC_BC_CREATE),     // control ID
00693                                 SYSTEMBAR_ILLEGAL,  // Bar ID
00694                                 TRUE,               // Receive messages
00695                                 FALSE,
00696                                 FALSE,
00697                                 0,
00698                                 (GREY_WHEN_NO_CURRENT_DOC | DONT_GREY_WHEN_SELECT_INSIDE) ));
00699 }
00700 
00701 
00702 
00703 /********************************************************************************************
00704 
00705 >   OpState OpShortenBar::GetState(String_256*, OpDescriptor*)
00706 
00707     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com> based on Jason
00708     Created:    15/10/99
00709     Returns:    The state of the OpShortenBar
00710     Purpose:    For finding the operations state.  
00711 
00712 ********************************************************************************************/
00713 OpState OpShortenBar::GetState(String_256* UIDescription, OpDescriptor *Bob)
00714 {
00715     OpState OpSt;
00716 
00717     // if we don't allow it
00718     OpSt.Greyed = TRUE;
00719     Spread* pSpread = Document::GetSelectedSpread();
00720     if (pSpread && !pSpread->FindActiveLayer()->IsFrame())
00721         OpSt.Greyed = FALSE;
00722 
00723     return(OpSt);   
00724 }
00725 
00726 /********************************************************************************************
00727 
00728 >   void OpShortenBar::DoWithParam(OpDescriptor* token, OpParam* pOpParam)
00729 
00730     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00731     Created:    15/10/99
00732     Inputs:     OpParam - describes the bar to be dupicated
00733                         - and the name to call the copy
00734     Outputs:    -
00735     Returns:    -
00736     Purpose:    Removes buttons from the bar so as to leave fewer.
00737     Errors:     -
00738     SeeAlso:    TrimBarDownToThisManyButtons
00739 ********************************************************************************************/   
00740 void OpShortenBar::DoWithParam(OpDescriptor* token, OpParam* pOpParam)
00741 {
00742     if (DoStartSelOp(FALSE,TRUE))  // Try to record the selection state
00743     {
00744         // unpack the names of the bar to be copied and the new bars name from the params
00745         TrimBarDownToThisManyButtons(((OpParamShortenBar *)pOpParam)->m_BarName,
00746                                     ((OpParamShortenBar *)pOpParam)->m_NoOfButtons);
00747 
00748         // end the op
00749         End();
00750 
00751         DialogBarOp::SetSystemStateChanged();
00752         DialogBarOp::UpdateStateOfAllBars(); 
00753 
00754     }
00755     else
00756     {
00757         FailAndExecute();
00758         End();
00759     }
00760 }
00761 
00762 /********************************************************************************************
00763 
00764 >   BOOL OpShortenBar::TrimBarDownToThisManyButtons(const StringBase &BarName, INT32 NewNoOfButtons)
00765 
00766     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00767     Created:    15/10/99
00768     Inputs:     BarName         - Name of the bar in for a trim
00769                 NewNoOfButtons  - No of buttons that we want in this bar
00770     Outputs:    -
00771     Returns:    TRUE if it succeeds. FALSE if you try to increase the number of
00772                 buttons by using this function or it fails in some way.
00773     Purpose:    Removes buttons from the bar so as to leave fewer.
00774     Errors:     -
00775 ********************************************************************************************/   
00776 BOOL OpShortenBar::TrimBarDownToThisManyButtons(const StringBase &BarName, INT32 NewNoOfButtons)
00777 {
00778     // find me the buttons in this bar
00779     String_256 templayer;
00780     templayer.Load(_R(IDS_ROLLOVER_DEFAULT));
00781 
00782     // count the buttons on the default layer
00783     // every button bar requires a member to be on the default layer
00784     // so there is no point in counting any other layer
00785     Layer * pDef = SliceHelper::FindLayerCalled(templayer);
00786 
00787     if (!pDef) return FALSE; // no default layer found
00788 
00789     INT32 NumberOfButtons = 0;
00790 
00791     // store of example attribs of each button in this bar
00792     // but we don't need this data so we can throw it away afterwards
00793     // MAX_BUTTONS_IN_A_BAR = 20
00794     TemplateAttribute ** ppFoundButton[MAX_BUTTONS_IN_A_BAR];
00795     DocRect ButtonRect[MAX_BUTTONS_IN_A_BAR];
00796     BYTE    Order[MAX_BUTTONS_IN_A_BAR];
00797 
00798     // scan down from the default layer counting the different button names
00799     // that all have the same bar name
00800     SliceHelper::CountButtonsInBarScan(pDef, (TemplateAttribute **) ppFoundButton, &NumberOfButtons, BarName);
00801 
00802     if (NumberOfButtons == 0 || NumberOfButtons <= NewNoOfButtons ) return FALSE;
00803 
00804 
00805     // build up a list of the buttons in the bar
00806     // so that we can shift them along
00807     // it must be better to use a list than keep on
00808     // scanning each time
00809 
00810     Layer * pLayer = NULL;
00811 
00812     List BarList;
00813 
00814     templayer.Load(_R(IDS_ROLLOVER_DEFAULT));
00815     pLayer = SliceHelper::FindLayerCalled(templayer);
00816     if (pLayer)
00817         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, BarName);
00818 
00819     templayer.Load(_R(IDS_ROLLOVER_MOUSE));
00820     pLayer = SliceHelper::FindLayerCalled(templayer);
00821     if (pLayer)
00822         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, BarName);
00823 
00824     templayer.Load(_R(IDS_ROLLOVER_CLICKED));
00825     pLayer = SliceHelper::FindLayerCalled(templayer);
00826     if (pLayer)
00827         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, BarName);
00828 
00829     templayer.Load(_R(IDS_ROLLOVER_SELECTED));
00830     pLayer = SliceHelper::FindLayerCalled(templayer);
00831     if (pLayer)
00832         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, BarName);
00833 
00834     // init stuff for the translation
00835     String_256  ButtonName = "";
00836     NodeListItem *pNodeListItem = NULL;
00837     NodeListItem *pDelThisToo = NULL;
00838     Node *pNode = NULL;
00839     Node *pParent = NULL;
00840     
00841     INT32 i = 0;
00842 
00843     // how big is each rect of the gallery?
00844     for (i = 0; i < NumberOfButtons; i++)
00845     {
00846         Order[i] = i; // init order
00847 
00848         ButtonName = ((TemplateAttribute *) ppFoundButton[i])->GetParam();
00849         pNodeListItem = (NodeListItem *)BarList.GetHead();
00850         ButtonRect[i].MakeEmpty();
00851 
00852         while(pNodeListItem)
00853         {
00854             pNode = pNodeListItem->pNode;
00855             if (pNode) 
00856             {
00857                 pParent = pNode->FindParent();
00858                 if (pParent && ButtonName.CompareTo(((TemplateAttribute *)pNode)->GetParam()) == 0)
00859                 {
00860                     // transform the node into its new location in the bar
00861                     ButtonRect[i] = ButtonRect[i].Union(((NodeRenderableBounded *)pParent)->GetBoundingRect());
00862                 }
00863             }
00864             // find the next item in the list
00865             pNodeListItem = (NodeListItem *)BarList.GetNext(pNodeListItem);
00866         }
00867     }
00868 
00869     // sort them by location
00870     for (i = 0; i < NumberOfButtons; i++)
00871     {
00872         for (INT32 j = i+1; j < NumberOfButtons; j++)
00873         {
00874             if (ButtonRect[Order[j]].hiy > ButtonRect[Order[i]].hiy)
00875             {
00876                 BYTE t = Order[j];
00877                 Order[j] = Order[i];
00878                 Order[i] = t;
00879             }
00880             else
00881             if (ButtonRect[Order[j]].hiy == ButtonRect[Order[i]].hiy &&
00882                 ButtonRect[Order[j]].lox < ButtonRect[Order[i]].lox)
00883             {
00884                 BYTE t = Order[j];
00885                 Order[j] = Order[i];
00886                 Order[i] = t;
00887             }
00888         }
00889     }
00890 
00891     // tidy up the list
00892     pNodeListItem = (NodeListItem *)BarList.GetHead();
00893     pParent = NULL;
00894     // Prepare an ObjChangeParam so we can mark which nodes will allow this op to happen to them
00895     ObjChangeFlags cFlags(TRUE); // flag says deleting okay?
00896     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00897 
00898 
00899     while(pNodeListItem)
00900     {
00901         pDelThisToo = pNodeListItem;
00902 
00903         // delete any node that is ordered after NewNoOfButtons
00904         // by finding out if the name of this item in the bar
00905         // is the same as any that occur after the required
00906         // number of buttons in the bar
00907         pParent = pNodeListItem->pNode->FindParent();
00908         if (pParent)
00909             {
00910                 ButtonName = ((TemplateAttribute *)pNodeListItem->pNode)->GetParam();
00911 
00912                 for (i = NewNoOfButtons; i < NumberOfButtons; i++)
00913                 {
00914                     if (ButtonName.CompareTo(((TemplateAttribute *) ppFoundButton[Order[i]])->GetParam()) == 0
00915                         && pParent->AllowOp(&ObjChange))
00916                     {
00917                         // We also need to invalidate the region of the node now that it has been transformed
00918                         DoInvalidateNodeRegion((NodeRenderableBounded*) pParent, TRUE, FALSE);
00919 
00920                         // remove the node from the excess button
00921                         pParent->SetSelected(FALSE);
00922                         DoHideNode(pParent, TRUE);
00923                         
00924                         i = NumberOfButtons; // shortcut out
00925                     }
00926                 }
00927             }
00928 
00929         pNodeListItem = (NodeListItem *)BarList.GetNext(pNodeListItem);
00930 
00931         // tidy up the list as we go along
00932         BarList.RemoveItem((NodeListItem *)pDelThisToo);
00933         delete pDelThisToo;
00934     }
00935 
00936     // touch the bar in question
00937     NameGallery * pNameGallery = NameGallery::Instance();
00938     if (pNameGallery)
00939     {
00940         pNameGallery->m_TouchedBar = SliceHelper::GetBarNumberFromBarName(BarName);
00941     }
00942 
00943     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
00944     UpdateChangedNodes(&ObjChange);
00945     
00946     BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::NONCOLOURATTCHANGED));
00947 
00948     return TRUE;
00949 }
00950 
00951 
00952 
00953 
00954 
00955 
00956 
00957 
00958 
00959 // contructor
00960 OpDelBar::OpDelBar(): CarbonCopyOp()                                
00961 {                              
00962 }
00963 /********************************************************************************************
00964 
00965 >   BOOL OpDelBar::Init()
00966 
00967     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
00968     Created:    3/5/00
00969     Returns:    TRUE if the operation could be successfully initialised 
00970                 FALSE if no more memory could be allocated 
00971     Purpose:    OpDelBar initialiser method
00972     Errors:     ERROR will be called if there was insufficient memory to allocate the 
00973                 operation.
00974     SeeAlso:    -
00975 
00976 ********************************************************************************************/
00977 BOOL OpDelBar::Init()
00978 {
00979     return  (RegisterOpDescriptor(0,
00980                                 _R(IDS_DEL_BAR),
00981                                 CC_RUNTIME_CLASS(OpDelBar),
00982                                 OPTOKEN_DELBAROP,
00983                                 OpDelBar::GetState,
00984                                 0,                  // help ID 
00985                                 0,                  // bubble help
00986                                 0,                  // resource ID
00987                                 0,                  // control ID
00988                                 SYSTEMBAR_ILLEGAL,  // Bar ID
00989                                 TRUE,               // Receive messages
00990                                 FALSE,
00991                                 FALSE,
00992                                 0,
00993                                 (GREY_WHEN_NO_CURRENT_DOC | DONT_GREY_WHEN_SELECT_INSIDE) ));
00994 }
00995 
00996 
00997 
00998 /********************************************************************************************
00999 
01000 >   OpState OpDelBar::GetState(String_256* UIDescription, OpDescriptor *Bob)
01001 
01002     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com> based on Jason
01003     Created:    3/5/00
01004     Purpose:    For finding the operations state.  
01005 
01006 ********************************************************************************************/
01007 OpState OpDelBar::GetState(String_256* UIDescription, OpDescriptor *Bob)
01008 {
01009     OpState OpSt;
01010 
01011     // if we don't allow it
01012     OpSt.Greyed = TRUE;
01013     Spread* pSpread = Document::GetSelectedSpread();
01014     if (pSpread && !pSpread->FindActiveLayer()->IsFrame())
01015         OpSt.Greyed = FALSE;
01016 
01017     return(OpSt);   
01018 }
01019 
01020 /********************************************************************************************
01021 
01022 >   void OpDelBar::DoWithParam(OpDescriptor* token, OpParam* pOpParam)
01023 
01024     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
01025     Created:    3/5/00
01026     Inputs:     OpParam - describes the bar to be deleted
01027                         - and the layers to delete it from
01028     Outputs:    -
01029     Returns:    -
01030     Errors:     -
01031 *******************************************************************************************/    
01032 void OpDelBar::DoWithParam(OpDescriptor* token, OpParam* pOpParam)
01033 {
01034     if (DoStartSelOp(FALSE,TRUE))  // Try to record the selection state
01035     {
01036         // Delete the bar
01037         DelBar(((OpParamDelBar *)pOpParam)->m_BarName, ((OpParamDelBar *)pOpParam)->m_State, this);
01038 
01039         // end the op
01040         End();
01041 
01042         DialogBarOp::SetSystemStateChanged();
01043         DialogBarOp::UpdateStateOfAllBars(); 
01044 
01045     }
01046     else
01047     {
01048         FailAndExecute();
01049         End();
01050     }
01051 }
01052 
01053 BOOL OpDelBar::DelBar(const StringBase &BarName, INT32 State, UndoableOperation * pOp)
01054 {
01055     String_256 templayer;
01056     Layer * pLayer = NULL;
01057 
01058     // Prepare an ObjChangeParam so we can mark which nodes will allow this op to happen to them
01059     ObjChangeFlags cFlags;
01060     cFlags.DeleteNode = TRUE;
01061     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,pOp);
01062 
01063     List BarList;
01064 
01065     templayer.Load(_R(IDS_ROLLOVER_DEFAULT));
01066     pLayer = SliceHelper::FindLayerCalled(templayer);
01067     Layer * pDefLayer = pLayer;
01068     if ((State == 0 || State == 5 ) && pLayer)
01069         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, BarName);
01070 
01071     templayer.Load(_R(IDS_ROLLOVER_MOUSE));
01072     pLayer = SliceHelper::FindLayerCalled(templayer);
01073     if ((State == 1 || State == 5 ) && pLayer)
01074         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, BarName);
01075 
01076     templayer.Load(_R(IDS_ROLLOVER_CLICKED));
01077     pLayer = SliceHelper::FindLayerCalled(templayer);
01078     if ((State == 2 || State == 5 ) && pLayer)
01079         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, BarName);
01080 
01081     templayer.Load(_R(IDS_ROLLOVER_SELECTED));
01082     pLayer = SliceHelper::FindLayerCalled(templayer);
01083     if ((State == 3 || State == 5 ) && pLayer)
01084         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, BarName);
01085     
01086     templayer.Load(_R(IDS_BACK_BAR));
01087     pLayer = SliceHelper::FindLayerCalled(templayer);
01088     if ((State == 4 || State == 5 ) && pLayer)
01089         SliceHelper::BuildListOfNodesInBar(&BarList, pLayer, BarName);
01090 
01091 
01092 
01093     
01094     // loop through all nodes in the list to delete
01095     NodeListItem *pNodeListItem = (NodeListItem *)BarList.GetHead();
01096 
01097     while (pNodeListItem)
01098     {
01099         NodeListItem *pNextNodeListItem = (NodeListItem *)BarList.GetNext(pNodeListItem);
01100 
01101         Node * pNode = pNodeListItem->pNode->FindParent();
01102 
01103         if (pNode && pNode->AllowOp(&ObjChange))
01104         {
01105             pOp->DoInvalidateNodeRegion((NodeRenderableBounded*) pNode, TRUE, FALSE);
01106             pOp->DoHideNode(pNode, TRUE);
01107         }
01108 
01109         // tidy up the list as we go along
01110         BarList.RemoveItem((NodeListItem *)pNodeListItem);
01111         delete pNodeListItem;
01112 
01113         pNodeListItem = pNextNodeListItem;
01114     }
01115 
01116     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,pOp);
01117     pOp->UpdateChangedNodes(&ObjChange);
01118 
01119     BROADCAST_TO_ALL(SelChangingMsg(SelChangingMsg::NONCOLOURATTCHANGED));
01120 
01121     return TRUE;
01122 }
01123 
01124 
01125 
01126 // contructor
01127 OpShowState::OpShowState(): UndoableOperation()                             
01128 {                              
01129 }
01130 /********************************************************************************************
01131 
01132 >   BOOL OpShowState::Init()
01133 
01134     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
01135     Created:    6/7/00
01136     Returns:    TRUE if the operation could be successfully initialised 
01137                 FALSE if no more memory could be allocated 
01138     Purpose:    OpShowState initialiser method
01139     Errors:     ERROR will be called if there was insufficient memory to allocate the 
01140                 operation.
01141     SeeAlso:    -
01142 
01143 ********************************************************************************************/
01144 BOOL OpShowState::Init()
01145 {
01146     return  (RegisterOpDescriptor(0,
01147                                 _R(IDS_SHOWSTATEOP),
01148                                 CC_RUNTIME_CLASS(OpShowState),
01149                                 OPTOKEN_SHOWSTATE,
01150                                 OpShowState::GetState,
01151                                 0,                  // help ID 
01152                                 0,                  // bubble help
01153                                 0,                  // resource ID
01154                                 0,                  // control ID
01155                                 SYSTEMBAR_ILLEGAL,  // Bar ID
01156                                 TRUE,               // Receive messages
01157                                 FALSE,
01158                                 FALSE,
01159                                 0,
01160                                 (GREY_WHEN_NO_CURRENT_DOC | DONT_GREY_WHEN_SELECT_INSIDE) ));
01161 }
01162 
01163 
01164 
01165 /********************************************************************************************
01166 
01167 >   OpState OpShowState::GetState(String_256* UIDescription, OpDescriptor *Bob)
01168 
01169     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com> based on Jason
01170     Created:    6/7/00
01171     Purpose:    For finding the operations state.  
01172 
01173 ********************************************************************************************/
01174 OpState OpShowState::GetState(String_256* UIDescription, OpDescriptor *Bob)
01175 {
01176     OpState OpSt;
01177 
01178     // if we don't allow it
01179     OpSt.Greyed = TRUE;
01180     Spread* pSpread = Document::GetSelectedSpread();
01181     if (pSpread && !pSpread->FindActiveLayer()->IsFrame())
01182         OpSt.Greyed = FALSE;
01183 
01184     return(OpSt);   
01185 }
01186 
01187 /********************************************************************************************
01188 
01189 >   void OpShowState::DoWithParam(OpDescriptor* token, OpParam* pOpParam)
01190 
01191     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
01192     Created:    6/7/00
01193     Inputs:     OpParam - Param1 has the layer/state id in it
01194     Outputs:    -
01195     Returns:    -
01196     Errors:     -
01197 *******************************************************************************************/    
01198 void OpShowState::DoWithParam(OpDescriptor* token, OpParam* pOpParam)
01199 {
01200     // Delete the bar
01201     ShowState(pOpParam->Param1, this);
01202 
01203     // end the op
01204     End();
01205 
01206     DialogBarOp::SetSystemStateChanged();
01207     DialogBarOp::UpdateStateOfAllBars(); 
01208 }
01209 
01210 
01211 /********************************************************************************************
01212 
01213 >   void OpShowState::ShowState(INT32 ShowLayer, UndoableOperation * pOp)
01214 
01215     Author:     Simon_Knight (Xara Group Ltd) <camelotdev@xara.com>
01216     Created:    6/7/00
01217     Inputs:     ShowLayer   -   number of the specail layers to display 0 = mouseoff, 1 = mouseover, 2= clicked, 3 = selected, 4 = all the above
01218                 pOp         -   Unodable Op to use, can be NULL in which case not undoable.
01219     Outputs:    -
01220     Returns:    -
01221 *******************************************************************************************/    
01222 void OpShowState::ShowState(INT32 ShowLayer, UndoableOperation * pOp)
01223 {
01224     Spread* pSelSpread = Document::GetSelectedSpread();
01225     if (pSelSpread == NULL)
01226         return;
01227 
01228     String_32 StateName[4];
01229 
01230     StateName[DEFAULT].Load(_R(IDS_ROLLOVER_DEFAULT)); // = "Default";
01231     StateName[MOUSE].Load(_R(IDS_ROLLOVER_MOUSE)); // = "Mouse";
01232     StateName[CLICKED].Load(_R(IDS_ROLLOVER_CLICKED)); // = "Clicked";
01233     StateName[SELECTED].Load(_R(IDS_ROLLOVER_SELECTED)); // = "Selected";
01234 
01235     Layer * pLayer = pSelSpread->FindFirstLayer();
01236 
01237     Layer * pLayerTopLayer = NULL;
01238     BOOL ActiveLayerIsAState = FALSE;
01239     BOOL SetAnActiveLayer = FALSE;
01240 
01241     DocRect InvalidRect;
01242 
01243     InvalidRect.MakeEmpty();
01244 
01245     while (pLayer)
01246     {
01247         BOOL IsStateLayer = FALSE;
01248         INT32 i = 0;
01249         for (i = 0; i < 4 ; i++)
01250         {
01251             if (pLayer->GetLayerID().CompareTo(StateName[i]) == 0)
01252             {
01253                 IsStateLayer = TRUE;
01254                 if (ShowLayer == 4 /* show all layers at once */
01255                     || ShowLayer == i)
01256                 {
01257                     if (!pLayer->IsVisible())
01258                     {
01259                         if (pOp)
01260                             SliceHelper::ShowLayer(TRUE, pLayer, pSelSpread, pOp);
01261                         else
01262                             pLayer->SetVisible(TRUE);
01263 
01264                         InvalidRect = InvalidRect.Union(pLayer->GetBoundingRect());
01265                     }
01266                 }
01267                 else
01268                 {
01269                     if (pLayer->IsVisible())
01270                     {
01271                         if (pOp)
01272                             SliceHelper::ShowLayer(FALSE, pLayer, pSelSpread, pOp);
01273                         else
01274                             pLayer->SetVisible(FALSE);
01275 
01276                         InvalidRect = InvalidRect.Union(pLayer->GetBoundingRect());
01277                         // If layer has just about to become invisible,
01278                         // remove the selections on the layer 
01279                         //NodeRenderableInk::DeselectAllOnLayer(pLayer); 
01280                     }
01281                 }
01282 
01283                 if (pLayer->IsActive())
01284                     ActiveLayerIsAState = TRUE;
01285             }
01286         }
01287 
01288         if (pLayer->IsVisible() && !IsStateLayer)
01289             pLayerTopLayer = pLayer;
01290 
01291         pLayer = pLayer->FindNextLayer();
01292     }
01293 }

Generated on Sat Nov 10 03:46:13 2007 for Camelot by  doxygen 1.4.4