00001 // $Id: mkshapes.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 /* 00099 //*/ 00100 00101 #include "camtypes.h" 00102 #include "mkshapes.h" 00103 00104 // code headers 00105 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 #include "nodepath.h" 00108 #include "objchge.h" 00109 00110 //#include "becomea.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 //#include "group.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 #include "nodeblnd.h" 00113 #include "bubbleid.h" 00114 00115 // resource headers 00116 //#include "simon.h" 00117 //#include "extendres.h" 00118 00119 DECLARE_SOURCE("$Revision: 1282 $"); 00120 00121 CC_IMPLEMENT_DYNCREATE(OpMakeShapes, SelOperation) 00122 CC_IMPLEMENT_DYNCREATE(OpMakeNodesShapes, UndoableOperation); 00123 00124 // ------------------------------------------------------------------------------------------ 00125 // OpMakeShapes methods 00126 00127 /******************************************************************************************** 00128 > OpMakeShapes::OpMakeShapes() 00129 00130 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00131 Created: 29/04/94 00132 Purpose: OpMakeShapes constructor 00133 ********************************************************************************************/ 00134 OpMakeShapes::OpMakeShapes(): SelOperation() 00135 { 00136 } 00137 00138 00139 00140 /******************************************************************************************** 00141 > BOOL OpMakeShapes::Init() 00142 00143 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00144 Created: 29/04/94 00145 Inputs: - 00146 Outputs: - 00147 Returns: TRUE if the operation could be successfully initialised 00148 FALSE if no more memory could be allocated 00149 00150 Purpose: OpMakeShapes initialiser method 00151 Errors: ERROR will be called if there was insufficient memory to allocate the 00152 operation. 00153 SeeAlso: - 00154 ********************************************************************************************/ 00155 BOOL OpMakeShapes::Init() 00156 { 00157 return (RegisterOpDescriptor(0, // tool id 00158 _R(IDS_MAKESHAPESOP), // Ops name 00159 CC_RUNTIME_CLASS(OpMakeShapes), // Ops class 00160 OPTOKEN_MAKE_SHAPES, // Op token 00161 OpMakeShapes::GetState, // Get state function 00162 0, // help ID 00163 _R(IDBBL_MAKESHAPES), // Bubble help 00164 0, // Bitmap ID 00165 0, // Control ID 00166 SYSTEMBAR_ILLEGAL, // Bar to appear on 00167 TRUE, // Recieve messages 00168 FALSE, // Smart 00169 FALSE, // Clean 00170 0, // One open string ID 00171 GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION | DONT_GREY_WHEN_SELECT_INSIDE)); 00172 } 00173 00174 00175 00176 /******************************************************************************************** 00177 > OpState OpMakeShapes::GetState(String_256*, OpDescriptor*) 00178 00179 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00180 Created: 29/04/94 00181 Inputs: - 00182 Outputs: - 00183 Returns: The state of the OpMakeShapes 00184 Purpose: For finding the OpMakeShapes's state. 00185 ********************************************************************************************/ 00186 OpState OpMakeShapes::GetState(String_256* UIDescription, OpDescriptor*) 00187 { 00188 OpState OpSt; 00189 00190 SelRange Sel(*(GetApplication()->FindSelection())); 00191 RangeControl rg = Sel.GetRangeControlFlags(); 00192 rg.PromoteToParent = TRUE; 00193 Sel.Range::SetRangeControl(rg); 00194 00195 00196 // Set up the ObjChangeParam so we can ask the selected nodes if they mind being deleted 00197 ObjChangeFlags cFlags(TRUE); 00198 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL); 00199 00200 // Will one or more selected nodes allow this op? 00201 if (!Sel.AllowOp(&ObjChange,FALSE)) 00202 OpSt.Greyed = TRUE; 00203 00204 return(OpSt); 00205 } 00206 00207 00208 00209 /******************************************************************************************** 00210 > void OpMakeShapes::Do(OpDescriptor*) 00211 00212 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00213 Created: 29/04/94 00214 Inputs: OpDescriptor (unused) 00215 Outputs: - 00216 Returns: - 00217 Purpose: Performs the MakeShapes operation. 00218 ********************************************************************************************/ 00219 void OpMakeShapes::Do(OpDescriptor*) 00220 { 00221 // Obtain the current selections 00222 Range Selection(*GetApplication()->FindSelection()); 00223 RangeControl rg = Selection.GetRangeControlFlags(); 00224 rg.PromoteToParent = TRUE; 00225 Selection.Range::SetRangeControl(rg); 00226 00227 // change the selection flags 00228 00229 Node* CurrentNode = Selection.FindFirst(); 00230 BOOL Success = TRUE; 00231 00232 ERROR3IF(CurrentNode == NULL, "Make shapes called with no nodes selected"); 00233 00234 if (CurrentNode != NULL) // No nodes selected so End 00235 { 00236 // We need to invalidate the region 00237 if (Success) 00238 Success = DoInvalidateNodesRegions(Selection, TRUE, FALSE, FALSE, FALSE); // Don't recache 00239 00240 // Try to record the selection state, don't render the blobs though 00241 if (Success) 00242 Success = DoStartSelOp(FALSE,FALSE); 00243 00244 // The DoMakeShapes function does all the work 00245 while (Success && CurrentNode!=NULL) 00246 { 00247 Node* Next = Selection.FindNext(CurrentNode); 00248 00249 // BODGE - since the group is selected and won't be replaced by anything else, no need to reselect it 00250 // this fixes a bug where make shapes on grouped text stories/molds/blends don't leave the parent group 00251 // selected but selects the objects inside! 00252 BOOL reselect = !IS_A(CurrentNode,NodeGroup) && !IS_A(CurrentNode,NodeBlend); 00253 // BOOL ok = TRUE; 00254 00255 00256 ObjChangeFlags cFlags(TRUE); 00257 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL); 00258 if (CurrentNode->AllowOp(&ObjChange)) 00259 { 00260 BecomeA BecomeAPath(BECOMEA_REPLACE,CC_RUNTIME_CLASS(NodePath), this, reselect); 00261 BecomeAPath.SetResultsStayInPlace(TRUE); 00262 Success = CurrentNode->DoBecomeA(&BecomeAPath); 00263 } 00264 00265 CurrentNode = Next; 00266 } 00267 00268 // We need to invalidate the region again for the new positions 00269 GetApplication()->FindSelection()->Update(); 00270 if (Success) 00271 Success = DoInvalidateNodesRegions(*GetApplication()->FindSelection(), TRUE); 00272 } 00273 00274 if (!Success) 00275 { 00276 InformError(); 00277 FailAndExecute(); 00278 } 00279 00280 End(); 00281 } 00282 00283 00284 00285 //------------------------------------------------------------------------------------------- 00286 //------------------------------------------------------------------------------------------- 00287 //------------------------------------------------------------------------------------------- 00288 //------------------------------------------------------------------------------------------- 00289 00290 00291 00292 /******************************************************************************************** 00293 00294 > void OpMakeNodesShapes::DoWithParam(OpDescriptor* pOp, OpParam* pParam) 00295 00296 Author: Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com> 00297 Created: 23/11/1999 00298 Inputs: pOp unused pointer to an OpDescriptor. 00299 pParam pointer to an OpParamMakeNodesShapes data information structure. 00300 00301 Outputs: The list of nodes, passed in through the OpParam, is converted in place 00302 into paths. 00303 Purpose: This undoable operation converts a given list of nodes to editable shapes 00304 (paths), each new node retaining the selection status of the original. 00305 See also: OpParamMakeNodesShapes 00306 00307 ********************************************************************************************/ 00308 void OpMakeNodesShapes::DoWithParam(OpDescriptor* pOp, OpParam* pParam) 00309 { 00310 std::list<Node*>* plpNodes = ((OpParamMakeNodesShapes*)pParam)->m_plpNodes; 00311 00312 Node* pNode; 00313 BOOL bFirst = FALSE; 00314 BOOL ok = TRUE; 00315 for ( std::list<Node*>::iterator iterNode = plpNodes->begin(); 00316 iterNode != plpNodes->end() && ok; 00317 iterNode++ ) 00318 { 00319 pNode = *iterNode; 00320 BecomeA baInfo(BECOMEA_REPLACE, CC_RUNTIME_CLASS(NodePath), this, 00321 pNode->IsSelected(), bFirst); 00322 baInfo.SetResultsStayInPlace(TRUE); 00323 ok = pNode->DoBecomeA(&baInfo); 00324 00325 #ifdef _DEBUG 00326 if (ok) 00327 TRACEUSER( "Karim", _T("converted %s to editable shapes\n"), pNode->Name()); 00328 #endif 00329 00330 bFirst = TRUE; 00331 } 00332 00333 if (!ok) 00334 { 00335 InformError(); 00336 FailAndExecute(); 00337 } 00338 00339 End(); 00340 return; 00341 } 00342 00343 00344 00345 /******************************************************************************************** 00346 00347 > BOOL OpMakeNodesShapes::Init() 00348 00349 Author: Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com> 00350 Created: 23/11/1999 00351 Returns: TRUE if successful, 00352 FALSE otherwise. 00353 Purpose: Initialise this operation. 00354 00355 ********************************************************************************************/ 00356 BOOL OpMakeNodesShapes::Init() 00357 { 00358 return (RegisterOpDescriptor(0, // Tool ID 00359 _R(IDS_MAKENODESSHAPES), // string resource ID for Op description 00360 CC_RUNTIME_CLASS(OpMakeNodesShapes),// Op's Runtime class 00361 OPTOKEN_MAKE_NODES_SHAPES, // Op's OPTOKEN string 00362 NULL, // Op's GetState function 00363 0, // associated Help system ID 00364 _R(IDBBL_MAKENODESSHAPES), // string resource ID for bubble help 00365 0, // bitmap ("icon") or resource ID 00366 0, // associated gadget control ID 00367 SYSTEMBAR_ILLEGAL, // associated info-bar ID 00368 FALSE, // receive system messages 00369 FALSE, // Op does smart attr optimisation 00370 FALSE, // Op doesn't modify document 00371 0, // when non-0, only one instance of the 00372 // Op is permitted, and this is the ID 00373 // of a string resource explaining why. 00374 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) 00375 )); // flags indicating conditions when the Op 00376 // should automatically be greyed/ticked etc. 00377 }