00001 // $Id: frameops.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 // The Frame Operations source file 00100 00101 /* 00102 */ 00103 00104 #include "camtypes.h" 00105 #include "frameops.h" 00106 00107 //#include "prevwres.h" // _R(IDS_DISPLAY_FRAME_GALLERY) _R(IDD_ANIMATIONBAR) ... 00108 #include "sgframe.h" // FrameSGallery 00109 //#include "spread.h" // Spread - in camtypes.h [AUTOMATICALLY REMOVED] 00110 //#include "simon.h" // _R(IDS_NO_DOC) 00111 //#include "app.h" // GetApplication() - in camtypes.h [AUTOMATICALLY REMOVED] 00112 //#include "fixmem.h" // CCMalloc - in camtypes.h [AUTOMATICALLY REMOVED] 00113 #include "prevwdlg.h" // OPTOKEN_PREVIEWDIALOG 00114 #include "grndbmp.h" // GRenderBitmap 00115 #include "filedlgs.h" // ExportFileDialog 00116 //#include "tim.h" // _R(IDT_CANT_FIND_FILTER) 00117 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00118 //#include "nev.h" // _R(IDN_USER_CANCELLED) 00119 #include "layermsg.h" // layer messages REDRAW_LAYER 00120 00121 //#include "accures.h" // _R(IDN_FILTEREXT_GIF) 00122 00123 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00124 00125 #include "nodebmp.h" // NodeBitmap 00126 #include "insertnd.h" // InsertionNode 00127 #include "aprps.h" 00128 00129 // browser preview 00130 #include "fileutil.h" // FileUtil::GetTemporaryPathName() 00131 #include "cbmpdata.h" // CBitmapData 00132 00133 #include "palman.h" // MakePaletteBrowserCompatible 00134 00135 //#include "xshelpid.h" //For the help ID 00136 00137 #include "gpalopt.h" // for the palette optimiser 00138 #include "mrhbits.h" 00139 #include "page.h" 00140 //#include "quality.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00141 00142 DECLARE_SOURCE("$Revision: 1282 $"); 00143 00144 CC_IMPLEMENT_DYNCREATE(OpSelectStartFrame, OpLayerGalChange); 00145 CC_IMPLEMENT_DYNCREATE(OpSelectEndFrame, OpLayerGalChange); 00146 CC_IMPLEMENT_DYNCREATE(OpSelectPrevFrame, OpLayerGalChange); 00147 CC_IMPLEMENT_DYNCREATE(OpSelectNextFrame, OpLayerGalChange); 00148 CC_IMPLEMENT_DYNCREATE(OpCreateNewFrame, OpLayerGalChange); 00149 CC_IMPLEMENT_DYNCREATE(OpCopyFrame, OpLayerGalChange); 00150 CC_IMPLEMENT_DYNCREATE(OpDeleteFrame, OpLayerGalChange); 00151 00152 CC_IMPLEMENT_DYNCREATE(OpFrameProperties, Operation); 00153 CC_IMPLEMENT_DYNCREATE(OpAnimationProperties, Operation); 00154 00155 00156 PORTNOTE("other", "Removed GrabFrameFilter, OpGrabFrame, OpGrabAllFrames") 00157 #ifndef EXCLUDE_FROM_XARALX 00158 CC_IMPLEMENT_DYNAMIC(GIFAnimationExportParam, BitmapExportParam); 00159 CC_IMPLEMENT_DYNCREATE(OpGrabFrame, Operation); 00160 CC_IMPLEMENT_DYNCREATE(OpGrabAllFrames, OpGrabFrame); 00161 CC_IMPLEMENT_DYNAMIC(GrabFrameFilter, MakeBitmapFilter); 00162 CC_IMPLEMENT_DYNCREATE(OpSaveAnimatedGIF, OpGrabAllFrames); 00163 CC_IMPLEMENT_DYNCREATE(OpBrowserPreview, OpSaveAnimatedGIF); 00164 00165 BOOL OpGrabAllFrames::ms_ForceRefreshOfAllFrames = FALSE; 00166 #endif 00167 00168 // This will get Camelot to display the filename and linenumber of any memory allocations 00169 // that are not released at program exit 00170 // This line mustn't go before any CC_IMPLEMENT_... macros 00171 #define new CAM_DEBUG_NEW 00172 00173 00174 //------------------------------------------------------------------------------------------ 00175 // Methods for the OpSelectStartFrame 00176 //------------------------------------------------------------------------------------------ 00177 00178 /******************************************************************************************** 00179 00180 > OpState OpSelectStartFrame::GetState(String_256*, OpDescriptor*) 00181 00182 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00183 Created: 21/4/97 00184 Inputs: Name of the OpDescriptor being queried 00185 Outputs: The string to show to the user 00186 Returns: The state of the OpSelectStartFrame operation 00187 Purpose: For finding the OpSelectStartFrame's state. 00188 Errors: - 00189 SeeAlso: - 00190 00191 ********************************************************************************************/ 00192 00193 OpState OpSelectStartFrame::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 00194 { 00195 OpState OpSt; 00196 00197 // Is there a selected spread? 00198 Spread * pSpread = Document::GetSelectedSpread(); 00199 if (pSpread) 00200 { 00201 // yes, so check if there is an active layer 00202 Layer * pLayer = pSpread->FindActiveLayer(); 00203 Layer * pPrevLayer = pLayer->FindPrevLayer(); 00204 // The previous layer should really be a frame layer but we cannot guarantee that but 00205 // it mustn't be a guide, a page background or a background layer. 00206 while ( pPrevLayer && !pPrevLayer->IsPseudoFrame()) 00207 { 00208 pPrevLayer = pPrevLayer->FindPrevLayer(); 00209 } 00210 00211 if (pLayer && pPrevLayer) 00212 { 00213 // Yes, so we are allowed to move to the next one 00214 OpSt.Greyed = FALSE; 00215 } 00216 else 00217 { 00218 // No, so we are greyed 00219 OpSt.Greyed = TRUE; 00220 } 00221 } 00222 else 00223 { 00224 // No selected spread, so we are greyed 00225 OpSt.Greyed = TRUE; 00226 } 00227 00228 return OpSt; 00229 } 00230 00231 /******************************************************************************************** 00232 00233 > void OpSelectStartFrame::Do(OpDescriptor * pOpDesc) 00234 00235 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00236 Created: 21/4/97 00237 Inputs: OpDescriptor (unused) 00238 Outputs: - 00239 Returns: - 00240 Purpose: Tries to select the bottom most animation frame (i.e. layer). 00241 Errors: - 00242 SeeAlso: - 00243 00244 ********************************************************************************************/ 00245 00246 void OpSelectStartFrame::Do( OpDescriptor * pOpDesc ) 00247 { 00248 // Just find the background layer and then ask our baseclass to delete it for us 00249 // Is there a selected spread? 00250 Spread * pSpread = Document::GetSelectedSpread(); 00251 if (pSpread) 00252 { 00253 PORTNOTE("other", "Disabled FrameSGallery") 00254 #ifndef EXCLUDE_FROM_XARALX 00255 // Check that all visible layers are actually frame layers 00256 FrameSGallery::EnsureFrameLayerIntegrity(pSpread); 00257 #endif 00258 // yes, so find the first layer and try to move to it 00259 Layer * pLayer = pSpread->FindFirstFrameLayer(); 00260 if (pLayer) 00261 { 00262 OpLayerGalParam Param(FRAME_SELECT, pSpread); 00263 Param.pLayer = pLayer; 00264 DoWithParam(pOpDesc, (OpParam*)&Param); 00265 } 00266 } 00267 00268 // End the operation, but we are calling DoWithParam() which we will assume does it for us. 00269 //End(); 00270 00271 return; 00272 } 00273 00274 /******************************************************************************************** 00275 // End of OpSelectStartFrame 00276 ********************************************************************************************/ 00277 00278 //------------------------------------------------------------------------------------------ 00279 // Methods for the OpSelectEndFrame 00280 //------------------------------------------------------------------------------------------ 00281 00282 /******************************************************************************************** 00283 00284 > OpState OpSelectEndFrame::GetState(String_256*, OpDescriptor*) 00285 00286 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00287 Created: 22/4/97 00288 Inputs: Name of the OpDescriptor being queried 00289 Outputs: The string to show to the user 00290 Returns: The state of the OpSelectEndFrame operation 00291 Purpose: For finding the OpSelectEndFrame's state. 00292 Errors: - 00293 SeeAlso: - 00294 00295 ********************************************************************************************/ 00296 00297 OpState OpSelectEndFrame::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 00298 { 00299 OpState OpSt; 00300 00301 // Is there a selected spread? 00302 Spread * pSpread = Document::GetSelectedSpread(); 00303 if (pSpread) 00304 { 00305 // yes, so check if there is an active layer 00306 Layer * pLayer = pSpread->FindActiveLayer(); 00307 // If there is an active layer and one following then we are not greyed 00308 Layer * pNextLayer = pLayer->FindNextLayer(); 00309 // The next layer should really be a frame layer but we cannot guarantee that but 00310 // it mustn't be a guide, a page background or a background layer. 00311 while ( pNextLayer && !pNextLayer->IsPseudoFrame()) 00312 { 00313 pNextLayer = pNextLayer->FindNextLayer(); 00314 } 00315 00316 if (pLayer && pNextLayer) 00317 { 00318 // Yes, so we are allowed to move to the previous one 00319 OpSt.Greyed = FALSE; 00320 } 00321 else 00322 { 00323 // No, so we are greyed 00324 OpSt.Greyed = TRUE; 00325 } 00326 } 00327 else 00328 { 00329 // No selected spread, so we are greyed 00330 OpSt.Greyed = TRUE; 00331 } 00332 00333 return OpSt; 00334 } 00335 00336 /******************************************************************************************** 00337 00338 > void OpSelectEndFrame::Do(OpDescriptor * pOpDesc) 00339 00340 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00341 Created: 22/4/97 00342 Inputs: OpDescriptor (unused) 00343 Outputs: - 00344 Returns: - 00345 Purpose: Tries to select the bottom most animation frame (i.e. layer). 00346 Errors: - 00347 SeeAlso: - 00348 00349 ********************************************************************************************/ 00350 00351 void OpSelectEndFrame::Do( OpDescriptor * pOpDesc ) 00352 { 00353 // Just find the background layer and then ask our baseclass to delete it for us 00354 // Is there a selected spread? 00355 Spread * pSpread = Document::GetSelectedSpread(); 00356 if (pSpread) 00357 { 00358 PORTNOTE("other", "Disabled FrameSGallery") 00359 #ifndef EXCLUDE_FROM_XARALX 00360 // Check that all visible layers are actually frame layers 00361 FrameSGallery::EnsureFrameLayerIntegrity(pSpread); 00362 #endif 00363 // yes, so find the last layer and try to move to it 00364 Layer * pLayer = pSpread->FindLastFrameLayer(); 00365 if (pLayer) 00366 { 00367 OpLayerGalParam Param(FRAME_SELECT, pSpread); 00368 Param.pLayer = pLayer; 00369 DoWithParam(pOpDesc, (OpParam*)&Param); 00370 } 00371 } 00372 00373 // End the operation, but we are calling DoWithParam() which we will assume does it for us. 00374 //End(); 00375 00376 return; 00377 } 00378 00379 /******************************************************************************************** 00380 // End of OpSelectEndFrame 00381 ********************************************************************************************/ 00382 00383 //------------------------------------------------------------------------------------------ 00384 // Methods for the OpSelectPrevFrame 00385 //------------------------------------------------------------------------------------------ 00386 00387 /******************************************************************************************** 00388 00389 > OpState OpSelectPrevFrame::GetState(String_256*, OpDescriptor*) 00390 00391 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00392 Created: 22/4/97 00393 Inputs: Name of the OpDescriptor being queried 00394 Outputs: The string to show to the user 00395 Returns: The state of the OpSelectPrevFrame operation 00396 Purpose: For finding the OpSelectPrevFrame's state. 00397 Errors: - 00398 SeeAlso: - 00399 00400 ********************************************************************************************/ 00401 00402 OpState OpSelectPrevFrame::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 00403 { 00404 //The frame movement controls on the GIF animation bar now work on frames only. 00405 OpState OpSt; 00406 00407 #ifdef WEBSTER 00408 00409 // Is there a selected spread? 00410 Spread * pSpread = Document::GetSelectedSpread(); 00411 if (pSpread) 00412 { 00413 // yes, so check if there is an active layer 00414 Layer * pLayer = pSpread->FindActiveLayer(); 00415 // If there is an active layer and one preceeding then we are not greyed 00416 Layer * pPrevLayer = pLayer->FindPrevLayer(); 00417 // The previous layer should really be a frame layer but we cannot guarantee that but 00418 // it mustn't be a guide, a page background or a background layer. 00419 while ( pPrevLayer && !pPrevLayer->IsPseudoFrame()) 00420 { 00421 pPrevLayer = pPrevLayer->FindPrevLayer(); 00422 } 00423 00424 if (pLayer && pPrevLayer) 00425 { 00426 // Yes, so we are allowed to move to the previous one 00427 OpSt.Greyed = FALSE; 00428 } 00429 else 00430 { 00431 // No, so we are greyed 00432 OpSt.Greyed = TRUE; 00433 } 00434 } 00435 else 00436 { 00437 // No selected spread, so we are greyed 00438 OpSt.Greyed = TRUE; 00439 } 00440 00441 #else 00442 // Are we in frame mode. 00443 BOOL FrameMode = IsFrameMode(); 00444 00445 if(FrameMode) 00446 { 00447 // Is there a selected spread? 00448 Spread * pSpread = Document::GetSelectedSpread(); 00449 if (pSpread) 00450 { 00451 // yes, so check if there is an active layer 00452 Layer * pLayer = pSpread->FindActiveLayer(); 00453 // If there is an active layer and one preceeding then we are not greyed 00454 Layer * pPrevLayer = pLayer->FindPrevLayer(); 00455 // The previous layer should really be a frame layer but we cannot guarantee that but 00456 // it mustn't be a guide, a page background or a background layer. 00457 while ( pPrevLayer && !pPrevLayer->IsPseudoFrame()) 00458 { 00459 pPrevLayer = pPrevLayer->FindPrevLayer(); 00460 } 00461 00462 if (pLayer && pPrevLayer) 00463 { 00464 // Yes, so we are allowed to move to the previous one 00465 OpSt.Greyed = FALSE; 00466 } 00467 else 00468 { 00469 // No, so we are greyed 00470 OpSt.Greyed = TRUE; 00471 } 00472 } 00473 else 00474 { 00475 // No selected spread, so we are greyed 00476 OpSt.Greyed = TRUE; 00477 } 00478 } 00479 else 00480 { 00481 // The document is layer based, so we are greyed. 00482 OpSt.Greyed = TRUE; 00483 } 00484 #endif 00485 00486 return OpSt; 00487 } 00488 00489 /******************************************************************************************** 00490 00491 > void OpSelectPrevFrame::Do(OpDescriptor * pOpDesc) 00492 00493 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00494 Created: 22/4/97 00495 Inputs: OpDescriptor (unused) 00496 Outputs: - 00497 Returns: - 00498 Purpose: Tries to select the previous animation frame (i.e. layer). 00499 Errors: - 00500 SeeAlso: - 00501 00502 ********************************************************************************************/ 00503 00504 void OpSelectPrevFrame::Do( OpDescriptor * pOpDesc ) 00505 { 00506 // Just find the background layer and then ask our baseclass to delete it for us 00507 // Is there a selected spread? 00508 Spread * pSpread = Document::GetSelectedSpread(); 00509 if (pSpread) 00510 { 00511 PORTNOTE("other", "Disabled FrameSGallery") 00512 #ifndef EXCLUDE_FROM_XARALX 00513 // Check that all visible layers are actually frame layers 00514 FrameSGallery::EnsureFrameLayerIntegrity(pSpread); 00515 #endif 00516 // yes, so find the last layer and try to move to it 00517 Layer * pLayer = pSpread->FindActiveLayer(); 00518 Layer * pPrevLayer = NULL; 00519 if (pLayer) 00520 pPrevLayer = pLayer->FindPrevFrameLayer(); 00521 if (pPrevLayer) 00522 { 00523 OpLayerGalParam Param(FRAME_SELECT, pSpread); 00524 Param.pLayer = pPrevLayer; 00525 DoWithParam(pOpDesc, (OpParam*)&Param); 00526 } 00527 } 00528 00529 // End the operation, but we are calling DoWithParam() which we will assume does it for us. 00530 //End(); 00531 00532 return; 00533 } 00534 00535 /******************************************************************************************** 00536 // End of OpSelectPrevFrame 00537 ********************************************************************************************/ 00538 00539 //------------------------------------------------------------------------------------------ 00540 // Methods for the OpSelectNextFrame 00541 //------------------------------------------------------------------------------------------ 00542 00543 /******************************************************************************************** 00544 00545 > OpState OpSelectNextFrame::GetState(String_256*, OpDescriptor*) 00546 00547 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00548 Created: 22/4/97 00549 Inputs: Name of the OpDescriptor being queried 00550 Outputs: The string to show to the user 00551 Returns: The state of the OpSelectNextFrame operation 00552 Purpose: For finding the OpSelectNextFrame's state. 00553 Errors: - 00554 SeeAlso: - 00555 00556 ********************************************************************************************/ 00557 00558 OpState OpSelectNextFrame::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 00559 { 00560 //The frame movement controls on the GIF animation bar now work on frames only. 00561 00562 OpState OpSt; 00563 00564 #ifdef WEBSTER 00565 00566 // Is there a selected spread? 00567 Spread * pSpread = Document::GetSelectedSpread(); 00568 if (pSpread) 00569 { 00570 // yes, so check if there is an active layer 00571 Layer * pLayer = pSpread->FindActiveLayer(); 00572 // If there is an active layer and one following then we are not greyed 00573 Layer * pNextLayer = pLayer->FindNextLayer(); 00574 // The next layer should really be a frame layer but we cannot guarantee that but 00575 // it mustn't be a guide, a page background or a background layer. 00576 while ( pNextLayer && !pNextLayer->IsPseudoFrame()) 00577 { 00578 pNextLayer = pNextLayer->FindNextLayer(); 00579 } 00580 00581 if (pLayer && pNextLayer) 00582 { 00583 // Yes, so we are allowed to move to the previous one 00584 OpSt.Greyed = FALSE; 00585 } 00586 else 00587 { 00588 // No, so we are greyed 00589 OpSt.Greyed = TRUE; 00590 } 00591 } 00592 else 00593 { 00594 // No selected spread, so we are greyed 00595 OpSt.Greyed = TRUE; 00596 } 00597 00598 #else 00599 // Are we in frame mode. 00600 BOOL FrameMode = IsFrameMode(); 00601 00602 if(FrameMode) 00603 { 00604 // Is there a selected spread? 00605 Spread * pSpread = Document::GetSelectedSpread(); 00606 if (pSpread) 00607 { 00608 // yes, so check if there is an active layer 00609 Layer * pLayer = pSpread->FindActiveLayer(); 00610 // If there is an active layer and one following then we are not greyed 00611 Layer * pNextLayer = pLayer->FindNextLayer(); 00612 // The next layer should really be a frame layer but we cannot guarantee that but 00613 // it mustn't be a guide, a page background or a background layer. 00614 while ( pNextLayer && !pNextLayer->IsPseudoFrame()) 00615 { 00616 pNextLayer = pNextLayer->FindNextLayer(); 00617 } 00618 00619 if (pLayer && pNextLayer) 00620 { 00621 // Yes, so we are allowed to move to the previous one 00622 OpSt.Greyed = FALSE; 00623 } 00624 else 00625 { 00626 // No, so we are greyed 00627 OpSt.Greyed = TRUE; 00628 } 00629 } 00630 else 00631 { 00632 // No selected spread, so we are greyed 00633 OpSt.Greyed = TRUE; 00634 } 00635 } 00636 else 00637 { 00638 // The document is layer based, so we are greyed. 00639 OpSt.Greyed = TRUE; 00640 } 00641 #endif 00642 00643 return OpSt; 00644 } 00645 00646 /******************************************************************************************** 00647 00648 > void OpSelectNextFrame::Do(OpDescriptor * pOpDesc) 00649 00650 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00651 Created: 22/4/97 00652 Inputs: OpDescriptor (unused) 00653 Outputs: - 00654 Returns: - 00655 Purpose: Tries to select the next animation frame (i.e. layer). 00656 Errors: - 00657 SeeAlso: - 00658 00659 ********************************************************************************************/ 00660 00661 void OpSelectNextFrame::Do( OpDescriptor * pOpDesc ) 00662 { 00663 // Just find the background layer and then ask our baseclass to delete it for us 00664 // Is there a selected spread? 00665 Spread * pSpread = Document::GetSelectedSpread(); 00666 if (pSpread) 00667 { 00668 PORTNOTE("other", "Disabled BrowserPreviewOptions") 00669 #ifndef EXCLUDE_FROM_XARALX 00670 // Check that all visible layers are actually frame layers 00671 FrameSGallery::EnsureFrameLayerIntegrity(pSpread); 00672 #endif 00673 // yes, so find the next layer and try to move to it 00674 Layer * pLayer = pSpread->FindActiveLayer(); 00675 Layer * pNextLayer = NULL; 00676 if (pLayer) 00677 pNextLayer = pLayer->FindNextFrameLayer(); 00678 if (pNextLayer) 00679 { 00680 OpLayerGalParam Param(FRAME_SELECT, pSpread); 00681 Param.pLayer = pNextLayer; 00682 DoWithParam(pOpDesc, (OpParam*)&Param); 00683 } 00684 } 00685 00686 // End the operation, but we are calling DoWithParam() which we will assume does it for us. 00687 //End(); 00688 00689 return; 00690 } 00691 00692 /******************************************************************************************** 00693 // End of OpSelectNextFrame 00694 ********************************************************************************************/ 00695 00696 //------------------------------------------------------------------------------------------ 00697 // Methods for the OpCreateNewFrame 00698 //------------------------------------------------------------------------------------------ 00699 00700 /******************************************************************************************** 00701 00702 > OpState OpCreateNewFrame::GetState(String_256*, OpDescriptor*) 00703 00704 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00705 Created: 22/4/97 00706 Inputs: Name of the OpDescriptor being queried 00707 Outputs: The string to show to the user 00708 Returns: The state of the OpCreateNewFrame operation 00709 Purpose: For finding the OpCreateNewFrame's state. 00710 Errors: - 00711 SeeAlso: - 00712 00713 ********************************************************************************************/ 00714 00715 OpState OpCreateNewFrame::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 00716 { 00717 //The frame movement controls on the GIF animation bar now work on frames only. 00718 OpState OpSt; 00719 00720 #ifdef WEBSTER 00721 // Is there a selected spread? 00722 Spread * pSpread = Document::GetSelectedSpread(); 00723 if (pSpread) 00724 { 00725 // Yes, so we are allowed to move to the previous one 00726 OpSt.Greyed = FALSE; 00727 } 00728 else 00729 { 00730 // No selected spread, so we are greyed 00731 OpSt.Greyed = TRUE; 00732 } 00733 #else 00734 // Are we in frame mode. 00735 BOOL FrameMode = IsFrameMode(); 00736 00737 if(FrameMode) 00738 { 00739 // Is there a selected spread? 00740 Spread * pSpread = Document::GetSelectedSpread(); 00741 if (pSpread) 00742 { 00743 // Yes, so we are allowed to move to the previous one 00744 OpSt.Greyed = FALSE; 00745 } 00746 else 00747 { 00748 // No selected spread, so we are greyed 00749 OpSt.Greyed = TRUE; 00750 } 00751 } 00752 else 00753 { 00754 // The document is layer based, so we are greyed. 00755 OpSt.Greyed = TRUE; 00756 } 00757 #endif 00758 00759 return OpSt; 00760 } 00761 00762 /******************************************************************************************** 00763 00764 > void OpCreateNewFrame::Do(OpDescriptor * pOpDesc) 00765 00766 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00767 Created: 22/4/97 00768 Inputs: OpDescriptor (unused) 00769 Outputs: - 00770 Returns: - 00771 Purpose: Tries to create a new animation frame (i.e. layer). 00772 Errors: - 00773 SeeAlso: - 00774 00775 ********************************************************************************************/ 00776 00777 void OpCreateNewFrame::Do( OpDescriptor * pOpDesc ) 00778 { 00779 PORTNOTE("other", "Disabled BrowserPreviewOptions") 00780 #ifndef EXCLUDE_FROM_XARALX 00781 // Just find the background layer and then ask our baseclass to delete it for us 00782 // Is there a selected spread? 00783 Spread * pSpread = Document::GetSelectedSpread(); 00784 if (pSpread) 00785 { 00786 // Check that all visible layers are actually frame layers 00787 FrameSGallery::EnsureFrameLayerIntegrity(pSpread); 00788 // Use the spread as the context node 00789 OpLayerGalParam Param(FRAME_NEW, pSpread); 00790 Param.pLayer = NULL; 00791 Param.pContextNode = pSpread; 00792 Param.AttDir = LASTCHILD; 00793 // Set up the name that is going to be applied to the frame 00794 String_256 NewName = FrameSGallery::CreateUniqueLayerID(pSpread); 00795 //String_256 NewName(_R(IDS_DEFAULTFRAMENAME)); 00796 Param.Status.StringLayerID = NewName; 00797 DoWithParam(pOpDesc, (OpParam*)&Param); 00798 } 00799 00800 // End the operation, but we are calling DoWithParam() which we will assume does it for us. 00801 //End(); 00802 #endif 00803 00804 return; 00805 } 00806 00807 /******************************************************************************************** 00808 // End of OpCreateNewFrame 00809 ********************************************************************************************/ 00810 00811 //------------------------------------------------------------------------------------------ 00812 // Methods for the OpCopyFrame 00813 //------------------------------------------------------------------------------------------ 00814 00815 /******************************************************************************************** 00816 00817 > OpState OpCopyFrame::GetState(String_256*, OpDescriptor*) 00818 00819 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00820 Created: 22/4/97 00821 Inputs: Name of the OpDescriptor being queried 00822 Outputs: The string to show to the user 00823 Returns: The state of the OpCopyFrame operation 00824 Purpose: For finding the OpCopyFrame's state. 00825 Errors: - 00826 SeeAlso: - 00827 00828 ********************************************************************************************/ 00829 00830 OpState OpCopyFrame::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 00831 { 00832 //The frame movement controls on the GIF animation bar now work on frames only. 00833 OpState OpSt; 00834 00835 #ifdef WEBSTER 00836 // Is there a selected spread? 00837 Spread * pSpread = Document::GetSelectedSpread(); 00838 if (pSpread) 00839 { 00840 // yes, so check if there is an active layer 00841 Layer * pLayer = pSpread->FindActiveLayer(); 00842 // If there is an active layer then we are not greyed 00843 if (pLayer) 00844 { 00845 OpSt.Greyed = FALSE; 00846 } 00847 else 00848 { 00849 // No, so we are greyed 00850 OpSt.Greyed = TRUE; 00851 } 00852 } 00853 else 00854 { 00855 // No selected spread, so we are greyed 00856 OpSt.Greyed = TRUE; 00857 } 00858 #else 00859 // Are we in frame mode. 00860 BOOL FrameMode = IsFrameMode(); 00861 00862 if(FrameMode) 00863 { 00864 // Is there a selected spread? 00865 Spread * pSpread = Document::GetSelectedSpread(); 00866 if (pSpread) 00867 { 00868 // yes, so check if there is an active layer 00869 Layer * pLayer = pSpread->FindActiveLayer(); 00870 // If there is an active layer then we are not greyed 00871 if (pLayer) 00872 { 00873 OpSt.Greyed = FALSE; 00874 } 00875 else 00876 { 00877 // No, so we are greyed 00878 OpSt.Greyed = TRUE; 00879 } 00880 } 00881 else 00882 { 00883 // No selected spread, so we are greyed 00884 OpSt.Greyed = TRUE; 00885 } 00886 } 00887 else 00888 { 00889 // The document is layer based, so we are greyed. 00890 OpSt.Greyed = TRUE; 00891 } 00892 #endif 00893 00894 return OpSt; 00895 } 00896 00897 /******************************************************************************************** 00898 00899 > void OpCopyFrame::Do(OpDescriptor * pOpDesc) 00900 00901 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00902 Created: 22/4/97 00903 Inputs: OpDescriptor (unused) 00904 Outputs: - 00905 Returns: - 00906 Purpose: Tries to create a new frame by copying the present one. 00907 Errors: - 00908 SeeAlso: - 00909 00910 ********************************************************************************************/ 00911 00912 void OpCopyFrame::Do( OpDescriptor * pOpDesc ) 00913 { 00914 PORTNOTE("other", "Disabled FrameSGallery") 00915 #ifndef EXCLUDE_FROM_XARALX 00916 // Just find the background layer and then ask our baseclass to delete it for us 00917 // Is there a selected spread? 00918 Spread * pSpread = Document::GetSelectedSpread(); 00919 if (pSpread) 00920 { 00921 // Check that all visible layers are actually frame layers 00922 FrameSGallery::EnsureFrameLayerIntegrity(pSpread); 00923 00924 // yes, so check that there is a presently active layer and try to copy it 00925 // Use the spread as the context node 00926 Layer * pLayer = pSpread->FindActiveLayer(); 00927 if (pLayer) 00928 { 00929 OpLayerGalParam Param(FRAME_COPY, pSpread); 00930 Param.pLayer = pLayer; 00931 Param.pContextNode = pSpread; 00932 Param.AttDir = LASTCHILD; 00933 // Set up the name that is going to be applied to the frame 00934 String_256 NewName = FrameSGallery::CreateUniqueLayerID(pSpread); 00935 //String_256 NewName(_R(IDS_DEFAULTFRAMENAME)); 00936 Param.Status.StringLayerID = NewName; 00937 DoWithParam(pOpDesc, (OpParam*)&Param); 00938 } 00939 } 00940 00941 // End the operation, but we are calling DoWithParam() which we will assume does it for us. 00942 //End(); 00943 #endif 00944 return; 00945 } 00946 00947 /******************************************************************************************** 00948 // End of OpCopyFrame 00949 ********************************************************************************************/ 00950 00951 //------------------------------------------------------------------------------------------ 00952 // Methods for the OpDeleteFrame 00953 //------------------------------------------------------------------------------------------ 00954 00955 /******************************************************************************************** 00956 00957 > OpState OpDeleteFrame::GetState(String_256*, OpDescriptor*) 00958 00959 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00960 Created: 23/4/97 00961 Inputs: Name of the OpDescriptor being queried 00962 Outputs: The string to show to the user 00963 Returns: The state of the OpDeleteFrame operation 00964 Purpose: For finding the OpDeleteFrame's state. 00965 Errors: - 00966 SeeAlso: - 00967 00968 ********************************************************************************************/ 00969 00970 OpState OpDeleteFrame::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 00971 { 00972 //The frame movement controls on the GIF animation bar now work on frames only. 00973 OpState OpSt; 00974 00975 #ifdef WEBSTER 00976 // Is there a selected spread? 00977 Spread * pSpread = Document::GetSelectedSpread(); 00978 if (pSpread) 00979 { 00980 // yes, so check if there is an active layer 00981 Layer * pLayer = pSpread->FindActiveLayer(); 00982 00983 // Get ptr's to the next and previous frame layers. 00984 Layer* pNextLayer = pLayer->FindNextFrameLayer(); 00985 Layer* pPrevLayer = pLayer->FindPrevFrameLayer(); 00986 00987 // If there is an active layer and a previous/next layer then we are not greyed. 00988 if ( pLayer && (pPrevLayer || pNextLayer) ) 00989 { 00990 OpSt.Greyed = FALSE; 00991 } 00992 else 00993 { 00994 // No, so we are greyed 00995 OpSt.Greyed = TRUE; 00996 } 00997 } 00998 else 00999 { 01000 // No selected spread, so we are greyed 01001 OpSt.Greyed = TRUE; 01002 } 01003 #else 01004 // Are we in frame mode. 01005 BOOL FrameMode = IsFrameMode(); 01006 01007 if(FrameMode) 01008 { 01009 // Is there a selected spread? 01010 Spread * pSpread = Document::GetSelectedSpread(); 01011 if (pSpread) 01012 { 01013 // yes, so check if there is an active layer 01014 Layer * pLayer = pSpread->FindActiveLayer(); 01015 01016 // Get ptr's to the next and previous frame layers. 01017 Layer* pNextLayer = pLayer->FindNextFrameLayer(); 01018 Layer* pPrevLayer = pLayer->FindPrevFrameLayer(); 01019 01020 // If there is an active layer and a previous/next layer then we are not greyed. 01021 if (pLayer && (pPrevLayer || pNextLayer) ) 01022 { 01023 OpSt.Greyed = FALSE; 01024 } 01025 else 01026 { 01027 // No, so we are greyed 01028 OpSt.Greyed = TRUE; 01029 } 01030 } 01031 else 01032 { 01033 // No selected spread, so we are greyed 01034 OpSt.Greyed = TRUE; 01035 } 01036 } 01037 else 01038 { 01039 // We are in layer mode, so we are greyed. 01040 OpSt.Greyed = TRUE; 01041 } 01042 #endif 01043 01044 return OpSt; 01045 } 01046 01047 /******************************************************************************************** 01048 01049 > void OpDeleteFrame::Do(OpDescriptor * pOpDesc) 01050 01051 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01052 Created: 23/4/97 01053 Inputs: OpDescriptor (unused) 01054 Outputs: - 01055 Returns: - 01056 Purpose: Tries to create a new frame by copying the present one. 01057 Errors: - 01058 SeeAlso: - 01059 01060 ********************************************************************************************/ 01061 01062 void OpDeleteFrame::Do( OpDescriptor * pOpDesc ) 01063 { 01064 // Just find the background layer and then ask our baseclass to delete it for us 01065 // Is there a selected spread? 01066 Spread * pSpread = Document::GetSelectedSpread(); 01067 if (pSpread) 01068 { 01069 PORTNOTE("other", "Disabled FrameSGallery") 01070 #ifndef EXCLUDE_FROM_XARALX 01071 // Check that all visible layers are actually frame layers 01072 FrameSGallery::EnsureFrameLayerIntegrity(pSpread); 01073 #endif 01074 // yes, so check that there is a presently active layer and try to delete it 01075 Layer * pLayer = pSpread->FindActiveLayer(); 01076 if (pLayer) 01077 { 01078 OpLayerGalParam Param(FRAME_DELETE, pSpread); 01079 Param.pLayer = pLayer; 01080 DoWithParam(pOpDesc, (OpParam*)&Param); 01081 } 01082 } 01083 01084 // End the operation, but we are calling DoWithParam() which we will assume does it for us. 01085 //End(); 01086 01087 return; 01088 } 01089 01090 /******************************************************************************************** 01091 // End of OpDeleteFrame 01092 ********************************************************************************************/ 01093 01094 //------------------------------------------------------------------------------------------ 01095 // Methods for the OpFrameProperties 01096 //------------------------------------------------------------------------------------------ 01097 01098 /******************************************************************************************** 01099 01100 > OpState OpFrameProperties::GetState(String_256*, OpDescriptor*) 01101 01102 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01103 Created: 29/4/97 01104 Inputs: Name of the OpDescriptor being queried 01105 Outputs: The string to show to the user 01106 Returns: The state of the OpFrameProperties operation 01107 Purpose: For finding the OpFrameProperties's state. 01108 Errors: - 01109 SeeAlso: - 01110 01111 ********************************************************************************************/ 01112 01113 OpState OpFrameProperties::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 01114 { 01115 //The frame movement controls on the GIF animation bar now work on frames only. 01116 OpState OpSt; 01117 01118 #ifdef WEBSTER 01119 // Is there a selected spread? 01120 Spread * pSpread = Document::GetSelectedSpread(); 01121 if (pSpread) 01122 { 01123 // yes, so check if there is an active layer 01124 Layer * pLayer = pSpread->FindActiveLayer(); 01125 // If there is an active layer and one following then we are not greyed 01126 if (pLayer) 01127 { 01128 // Yes, so we are allowed to move to the previous one 01129 OpSt.Greyed = FALSE; 01130 } 01131 else 01132 { 01133 // No, so we are greyed 01134 OpSt.Greyed = TRUE; 01135 } 01136 } 01137 else 01138 { 01139 // No selected spread, so we are greyed 01140 OpSt.Greyed = TRUE; 01141 } 01142 #else 01143 01144 BOOL FrameMode = FALSE; // Flag to determine the document mode. 01145 01146 // Is there a selected spread? 01147 Spread* pSpread = Document::GetSelectedSpread(); 01148 01149 // Ensure a valid spread ptr. 01150 if(pSpread) 01151 { 01152 // Are there any frame layers? 01153 Layer* pFrameLayer = pSpread->FindFirstFrameLayer(); 01154 01155 //If a frame layer exists, then this is an animation doc. 01156 if (pFrameLayer) 01157 FrameMode = TRUE; 01158 } 01159 01160 if(FrameMode) 01161 { 01162 if (pSpread) 01163 { 01164 // yes, so check if there is an active layer 01165 Layer * pLayer = pSpread->FindActiveLayer(); 01166 // If there is an active layer and one following then we are not greyed 01167 if (pLayer) 01168 // Yes, so we are allowed to move to the previous one 01169 OpSt.Greyed = FALSE; 01170 else 01171 // No, so we are greyed 01172 OpSt.Greyed = TRUE; 01173 } 01174 else 01175 // No selected spread, so we are greyed 01176 OpSt.Greyed = TRUE; 01177 } 01178 else 01179 { 01180 // The document is layer based, so we are greyed. 01181 OpSt.Greyed = TRUE; 01182 } 01183 #endif 01184 01185 return OpSt; 01186 } 01187 01188 /******************************************************************************************** 01189 01190 > void OpFrameProperties::Do(OpDescriptor * pOpDesc) 01191 01192 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01193 Created: 29/4/97 01194 Inputs: OpDescriptor (unused) 01195 Outputs: - 01196 Returns: - 01197 Purpose: Tries to set some new animation properties. 01198 Errors: - 01199 SeeAlso: - 01200 01201 ********************************************************************************************/ 01202 01203 void OpFrameProperties::Do( OpDescriptor * pOpDesc ) 01204 { 01205 // Just find the background layer and then ask our baseclass to delete it for us 01206 // Is there a selected spread? 01207 Spread * pSpread = Document::GetSelectedSpread(); 01208 if (pSpread) 01209 { 01210 PORTNOTE("other", "Disabled FrameSGallery") 01211 #ifndef EXCLUDE_FROM_XARALX 01212 // Check that all visible layers are actually frame layers 01213 FrameSGallery::EnsureFrameLayerIntegrity(pSpread); 01214 #endif 01215 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_GIFANIMPROPERTYTABS); 01216 01217 if (pOpDesc != NULL) 01218 { 01219 // Select the "Frame properties tab". 01220 GIFAnimationPropertyTabsDlg::SetPageToOpen(GIFAnimationPropertyTabs::FramePropertiesTabNumber); 01221 01222 String_256 Str; 01223 OpState State = pOpDesc->GetOpsState(&Str); 01224 if (!State.Greyed) 01225 pOpDesc->Invoke(); 01226 else 01227 { 01228 GIFAnimationPropertyTabs * pTabHandler = GIFAnimationPropertyTabsDlg::GetGIFAnimationPropertiesTabs(); 01229 if (pTabHandler) 01230 { 01231 DialogTabOp* pDlg = pTabHandler->GetTabbedDlg(); 01232 if (pDlg != NULL) 01233 pDlg->Open(); 01234 } 01235 } 01236 } 01237 } 01238 01239 // End the operation 01240 End(); 01241 01242 return; 01243 } 01244 01245 /******************************************************************************************** 01246 // End of OpFrameProperties 01247 ********************************************************************************************/ 01248 01249 //------------------------------------------------------------------------------------------ 01250 // Methods for the OpAnimationProperties 01251 //------------------------------------------------------------------------------------------ 01252 01253 /******************************************************************************************** 01254 01255 > OpState OpAnimationProperties::GetState(String_256*, OpDescriptor*) 01256 01257 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01258 Created: 29/4/97 01259 Inputs: Name of the OpDescriptor being queried 01260 Outputs: The string to show to the user 01261 Returns: The state of the OpAnimationProperties operation 01262 Purpose: For finding the OpAnimationProperties's state. 01263 Errors: - 01264 SeeAlso: - 01265 01266 ********************************************************************************************/ 01267 01268 OpState OpAnimationProperties::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 01269 { 01270 //The frame movement controls on the GIF animation bar now work on frames only. 01271 OpState OpSt; 01272 01273 #ifdef WBSTER 01274 // Is there a selected spread? 01275 Spread * pSpread = Document::GetSelectedSpread(); 01276 if (pSpread) 01277 { 01278 // yes, so check if there is an active layer 01279 Layer * pLayer = pSpread->FindActiveLayer(); 01280 // If there is an active layer and one following then we are not greyed 01281 if (pLayer) 01282 { 01283 // Yes, so we are allowed to move to the previous one 01284 OpSt.Greyed = FALSE; 01285 } 01286 else 01287 { 01288 // No, so we are greyed 01289 OpSt.Greyed = TRUE; 01290 } 01291 } 01292 else 01293 { 01294 // No selected spread, so we are greyed 01295 OpSt.Greyed = TRUE; 01296 } 01297 #else 01298 01299 BOOL FrameMode = FALSE; // Flag to determine the document mode. 01300 01301 // Is there a selected spread? 01302 Spread * pSpread = Document::GetSelectedSpread(); 01303 01304 // Ensure a valid spread ptr. 01305 if(pSpread) 01306 { 01307 // Are there any frame layers? 01308 Layer* pFrameLayer = pSpread->FindFirstFrameLayer(); 01309 01310 //If a frame layer exists, then this is an animation doc. 01311 if (pFrameLayer) 01312 FrameMode = TRUE; 01313 } 01314 01315 if(FrameMode) 01316 { 01317 if (pSpread) 01318 { 01319 // yes, so check if there is an active layer 01320 Layer * pLayer = pSpread->FindActiveLayer(); 01321 01322 // If there is an active layer and one following, then we are not greyed. 01323 if (pLayer) 01324 { 01325 // Yes, so we are allowed to move to the previous one 01326 OpSt.Greyed = FALSE; 01327 } 01328 else 01329 { 01330 // No, so we are greyed 01331 OpSt.Greyed = TRUE; 01332 } 01333 } 01334 else 01335 { 01336 // No selected spread, so we are greyed 01337 OpSt.Greyed = TRUE; 01338 } 01339 } 01340 else 01341 { 01342 // The document is layer based, so we are greyed. 01343 OpSt.Greyed = TRUE; 01344 *pUIDescription = String_256 (_R(IDS_NO_FRAMES)); 01345 } 01346 #endif 01347 01348 return OpSt; 01349 } 01350 01351 /******************************************************************************************** 01352 01353 > void OpAnimationProperties::Do(OpDescriptor * pOpDesc) 01354 01355 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01356 Created: 29/4/97 01357 Inputs: OpDescriptor (unused) 01358 Outputs: - 01359 Returns: - 01360 Purpose: Tries to set some new animation properties. 01361 Errors: - 01362 SeeAlso: - 01363 01364 ********************************************************************************************/ 01365 01366 void OpAnimationProperties::Do( OpDescriptor * pOpDesc ) 01367 { 01368 // Just find the background layer and then ask our baseclass to delete it for us 01369 // Is there a selected spread? 01370 Spread * pSpread = Document::GetSelectedSpread(); 01371 if (pSpread) 01372 { 01373 PORTNOTE("other", "Disabled FrameSGallery") 01374 #ifndef EXCLUDE_FROM_XARALX 01375 // Check that all visible layers are actually frame layers. 01376 FrameSGallery::EnsureFrameLayerIntegrity(pSpread); 01377 #endif 01378 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_GIFANIMPROPERTYTABS); 01379 01380 if (pOpDesc != NULL) 01381 { 01382 // Select the "Animation properties tab" on start up. 01383 GIFAnimationPropertyTabsDlg::SetPageToOpen(GIFAnimationPropertyTabs::AnimationColoursTabNumber); 01384 01385 String_256 Str; 01386 OpState State = pOpDesc->GetOpsState(&Str); 01387 if (!State.Greyed) 01388 pOpDesc->Invoke(); 01389 else 01390 { 01391 GIFAnimationPropertyTabs * pTabHandler = GIFAnimationPropertyTabsDlg::GetGIFAnimationPropertiesTabs(); 01392 if (pTabHandler) 01393 { 01394 DialogTabOp* pDlg = pTabHandler->GetTabbedDlg(); 01395 if (pDlg != NULL) 01396 pDlg->Open(); 01397 } 01398 } 01399 } 01400 } 01401 01402 // End the operation 01403 End(); 01404 01405 return; 01406 } 01407 01408 /******************************************************************************************** 01409 // End of OpAnimationProperties 01410 ********************************************************************************************/ 01411 01412 PORTNOTE("other", "Removed GrabFrameFilter, OpGrabFrame, OpGrabAllFrames") 01413 #ifndef EXCLUDE_FROM_XARALX 01414 01415 //------------------------------------------------------------------------------------------ 01416 // Methods for the OpGrabFrame 01417 //------------------------------------------------------------------------------------------ 01418 01419 BitmapPreviewData * OpGrabFrame::m_pBitmapData = NULL; 01420 01421 /******************************************************************************************** 01422 01423 > BOOL OpGrabFrame::Init() 01424 01425 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01426 Created: 19/6/97 01427 Returns: TRUE if the operation could be successfully initialised 01428 FALSE if no more memory could be allocated 01429 Purpose: OpGrabFrame initialiser method 01430 Errors: ERROR will be called if there was insufficient memory to allocate the 01431 operation. 01432 01433 ********************************************************************************************/ 01434 01435 BOOL OpGrabFrame::Init() 01436 { 01437 BOOL ok = FALSE; 01438 01439 // start of non-undoable operations 01440 ok = RegisterOpDescriptor( 01441 0, // Tool ID 01442 _R(IDS_FRAMEPROPERTIES), // String resource ID 01443 CC_RUNTIME_CLASS(OpFrameProperties), // Runtime class 01444 OPTOKEN_FRAME_PROPERTIES, // Token string 01445 OpFrameProperties::GetState, // GetState function 01446 0, // help ID 01447 _R(IDBBL_FRAMEPROPERTIES), // bubble help 01448 _R(IDD_ANIMATIONBAR), // resource ID 01449 _R(IDC_FRAME_FRAMEPROPERTIES), // control ID 01450 SYSTEMBAR_ANIMATION, // Bar ID 01451 TRUE, // Recieve system messages 01452 FALSE, // Smart duplicate operation 01453 TRUE, // Clean operation 01454 NULL, // No vertical counterpart 01455 0, // String for one copy only error 01456 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags 01457 ); 01458 if(ok) 01459 ok = RegisterOpDescriptor( 01460 0, // Tool ID 01461 _R(IDS_ANIMATIONPROPERTIES), // String resource ID 01462 CC_RUNTIME_CLASS(OpAnimationProperties), // Runtime class 01463 OPTOKEN_FRAME_ANIPROPERTIES, // Token string 01464 OpAnimationProperties::GetState, // GetState function 01465 0, // help ID 01466 _R(IDBBL_ANIMATIONPROPERTIES), // bubble help 01467 _R(IDD_ANIMATIONBAR), // resource ID 01468 _R(IDC_FRAME_ANIMATIONPROPERTIES), // control ID 01469 SYSTEMBAR_ANIMATION, // Bar ID 01470 TRUE, // Recieve system messages 01471 FALSE, // Smart duplicate operation 01472 TRUE, // Clean operation 01473 NULL, // No vertical counterpart 01474 0, // String for one copy only error 01475 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags 01476 ); 01477 if(ok) 01478 ok = RegisterOpDescriptor( 01479 0, // Tool ID 01480 _R(IDS_GRABFRAME), // String resource ID 01481 CC_RUNTIME_CLASS(OpGrabFrame), // Runtime class 01482 OPTOKEN_FRAME_GRABFRAME, // Token string 01483 OpGrabFrame::GetState, // GetState function 01484 _R(IDH_Command_Preview_All_Frames), // help ID 01485 _R(IDBBL_GRABFRAME), // bubble help 01486 _R(IDD_ANIMATIONBAR), // resource ID 01487 _R(IDC_FRAME_GRABFRAME), // control ID 01488 SYSTEMBAR_ANIMATION, // Bar ID 01489 TRUE, // Recieve system messages 01490 FALSE, // Smart duplicate operation 01491 TRUE, // Clean operation 01492 NULL, // No vertical counterpart 01493 0, // String for one copy only error 01494 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags 01495 ); 01496 if(ok) 01497 ok = RegisterOpDescriptor( 01498 0, // Tool ID 01499 _R(IDS_GRABALLFRAMES), // String resource ID 01500 CC_RUNTIME_CLASS(OpGrabAllFrames), // Runtime class 01501 OPTOKEN_FRAME_GRABALLFRAMES, // Token string 01502 OpGrabAllFrames::GetState, // GetState function 01503 _R(IDH_Command_Preview_All_Frames), // help ID 01504 _R(IDBBL_GRABALLFRAMES), // bubble help 01505 _R(IDD_ANIMATIONBAR), // resource ID 01506 _R(IDC_FRAME_GRABALLFRAMES), // control ID 01507 SYSTEMBAR_ANIMATION, // Bar ID 01508 TRUE, // Recieve system messages 01509 FALSE, // Smart duplicate operation 01510 TRUE, // Clean operation 01511 NULL, // No vertical counterpart 01512 0, // String for one copy only error 01513 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags 01514 ); 01515 if(ok) 01516 ok = RegisterOpDescriptor( 01517 0, // Tool ID 01518 _R(IDS_FRAME_SAVEANIMATEDGIF), // String resource ID 01519 CC_RUNTIME_CLASS(OpSaveAnimatedGIF), // Runtime class 01520 OPTOKEN_SAVEANIMATEDGIF, // Token string 01521 OpSaveAnimatedGIF::GetState, // GetState function 01522 0, // help ID 01523 _R(IDBBL_SAVEANIMATEDGIF), // bubble help 01524 _R(IDD_ANIMATIONBAR), // resource ID 01525 _R(IDC_FRAME_SAVEANIMATEDGIF), // control ID 01526 SYSTEMBAR_ANIMATION, // Bar ID 01527 TRUE, // Recieve system messages 01528 FALSE, // Smart duplicate operation 01529 TRUE, // Clean operation 01530 NULL, // No vertical counterpart 01531 0, // String for one copy only error 01532 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags 01533 ); 01534 if(ok) 01535 ok = RegisterOpDescriptor( 01536 0, // Tool ID 01537 _R(IDS_BROWSERPREVIEW), // String resource ID 01538 CC_RUNTIME_CLASS(OpBrowserPreview), // Runtime class 01539 OPTOKEN_FRAME_BROWSERPREVIEW, // Token string 01540 OpBrowserPreview::GetState, // GetState function 01541 _R(IDH_Command_Preview_Animation_in_Browser), // help ID 01542 _R(IDBBL_BROWSERPREVIEW), // bubble help 01543 _R(IDD_ANIMATIONBAR), // resource ID 01544 _R(IDC_FRAME_GOTOBROWSER), // control ID 01545 SYSTEMBAR_ANIMATION, // Bar ID 01546 TRUE, // Recieve system messages 01547 FALSE, // Smart duplicate operation 01548 TRUE, // Clean operation 01549 NULL, // No vertical counterpart 01550 0, // String for one copy only error 01551 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags 01552 ); 01553 // end of non-undoable operations 01554 01555 if(ok) 01556 ok = PreviewInBrowserTab::Declare(); 01557 01558 return ok; 01559 } 01560 01561 /******************************************************************************************** 01562 01563 > static void OpGrabFrame::DeInit(void) 01564 01565 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01566 Created: 3/7/97 01567 Purpose: De-Initialises OpGrabFrame 01568 01569 ********************************************************************************************/ 01570 01571 void OpGrabFrame::DeInit(void) 01572 { 01573 // Deinit our static preview bitmap data pointer if allocated 01574 // This should clean up any temp files that we have used 01575 if (m_pBitmapData != NULL) 01576 { 01577 delete m_pBitmapData; 01578 m_pBitmapData = NULL; 01579 } 01580 01581 // Give the browser preview chance to clean up its temp file useage 01582 OpBrowserPreview::RemoveTempFile(); 01583 } 01584 01585 /******************************************************************************************** 01586 01587 > OpState OpGrabFrame::GetState(String_256*, OpDescriptor*) 01588 01589 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01590 Created: 23/4/97 01591 Inputs: Name of the OpDescriptor being queried 01592 Outputs: The string to show to the user 01593 Returns: The state of the OpGrabFrame operation 01594 Purpose: For finding the OpGrabFrame's state. 01595 Errors: - 01596 SeeAlso: - 01597 01598 ********************************************************************************************/ 01599 01600 OpState OpGrabFrame::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 01601 { 01602 01603 //The frame movement controls on the GIF animation bar now work on frames only. 01604 OpState OpSt; 01605 01606 #ifdef WEBSTER 01607 String_256 DisableReason; 01608 01609 // Is there a selected spread? 01610 Spread * pSpread = Document::GetSelectedSpread(); 01611 if (pSpread) 01612 { 01613 // yes, so check if there is an active layer 01614 Layer * pLayer = pSpread->FindActiveLayer(); 01615 if (pLayer) 01616 { 01617 // Ensure that we have some visible objects on the specified layer to render 01618 // Could use a range but easier just to check if there are visible objects on the page 01619 DocRect VisibleRect = pSpread->GetPageVisibleBounds(); 01620 BOOL Empty = VisibleRect.IsEmpty(); 01621 // If this frame has nothing visible on it then check if there are renderable objects 01622 // on any other frames in the animation. 01623 if (Empty) 01624 { 01625 // Cannot assume that all the frame layers are actually frame layers so 01626 // go through all those that might be frame layers. 01627 Layer * pFrame = pSpread->FindFirstLayer(); 01628 while (pFrame && Empty) 01629 { 01630 if (pFrame->IsPseudoFrame() && pFrame->HasLayerGotRenderableChildren()) 01631 Empty = FALSE; 01632 pFrame = pFrame->FindNextLayer(); 01633 } 01634 } 01635 if (pOpDesc && pOpDesc->Token != String(OPTOKEN_FRAME_GRABFRAME) && !Empty) 01636 { 01637 // Cannot assume that all the frame layers are actually frame layers so 01638 // go through all those that might be frame layers. 01639 Layer * pFrame = pSpread->FindFirstLayer(); 01640 BOOL AllHidden = TRUE; 01641 while (pFrame && AllHidden) 01642 { 01643 if (pFrame->IsPseudoFrame() && !pFrame->IsHiddenFrame()) 01644 AllHidden = FALSE; 01645 pFrame = pFrame->FindNextLayer(); 01646 } 01647 if (AllHidden) 01648 { 01649 OpSt.Greyed = TRUE; 01650 // Load reason why operation is disabled 01651 DisableReason = String_256(_R(IDS_ALLFRAMESAREHIDDEN)); 01652 if (pUIDescription) 01653 *pUIDescription = DisableReason; 01654 } 01655 else 01656 { 01657 // Yes, so we are allowed to grab the frame or all the frames 01658 OpSt.Greyed = FALSE; 01659 } 01660 } 01661 else if (pOpDesc && pOpDesc->Token == String(OPTOKEN_FRAME_GRABFRAME) && pLayer->IsHiddenFrame()) 01662 { 01663 // If we are the grab frame op then check that the current layer is not 01664 // hidden. If so then disallow 01665 OpSt.Greyed = TRUE; 01666 // Load reason why operation is disabled 01667 DisableReason = String_256(_R(IDS_FRAMEISHIDDEN)); 01668 if (pUIDescription) 01669 *pUIDescription = DisableReason; 01670 } 01671 else if (!Empty) 01672 { 01673 // Yes, so we are allowed to grab the frame or all the frames 01674 OpSt.Greyed = FALSE; 01675 } 01676 else 01677 { 01678 OpSt.Greyed = TRUE; 01679 // Load reason why operation is disabled 01680 DisableReason = String_256(_R(IDS_NO_VISIBLE_OBJECTS)); 01681 if (pUIDescription) 01682 *pUIDescription = DisableReason; 01683 } 01684 } 01685 else 01686 { 01687 // No, so we are greyed 01688 OpSt.Greyed = TRUE; 01689 } 01690 } 01691 else 01692 { 01693 // No selected spread, so we are greyed 01694 OpSt.Greyed = TRUE; 01695 01696 // Load reason why operation is disabled 01697 DisableReason = String_256(_R(IDS_NO_DOC)); 01698 if (pUIDescription) 01699 *pUIDescription = DisableReason; 01700 } 01701 01702 #else 01703 // Flag to determine the document mode. 01704 BOOL FrameMode = FALSE; 01705 01706 // Get a ptr to the selected spread 01707 Spread* pSpread = Document::GetSelectedSpread(); 01708 01709 // Ensure a valid spread ptr. 01710 if(pSpread) 01711 { 01712 // Are there any frame layers? 01713 Layer* pFrameLayer = pSpread->FindFirstFrameLayer(); 01714 01715 //If a frame layer exists, then this is an animation doc. 01716 if (pFrameLayer) 01717 FrameMode = TRUE; 01718 } 01719 01720 if(FrameMode) 01721 { 01722 String_256 DisableReason; 01723 01724 if (pSpread) 01725 { 01726 // yes, so check if there is an active layer 01727 Layer * pLayer = pSpread->FindActiveLayer(); 01728 01729 if (pLayer) 01730 { 01731 // Ensure that we have some visible objects on the specified layer to render 01732 // Could use a range but easier just to check if there are visible objects on the page 01733 DocRect VisibleRect = pSpread->GetPageVisibleBounds(); 01734 BOOL Empty = VisibleRect.IsEmpty(); 01735 // If this frame has nothing visible on it then check if there are renderable objects 01736 // on any other frames in the animation. 01737 if (Empty) 01738 { 01739 // Cannot assume that all the frame layers are actually frame layers so 01740 // go through all those that might be frame layers. 01741 Layer * pFrame = pSpread->FindFirstLayer(); 01742 while (pFrame && Empty) 01743 { 01744 if (pFrame->IsPseudoFrame() && pFrame->HasLayerGotRenderableChildren()) 01745 Empty = FALSE; 01746 01747 pFrame = pFrame->FindNextLayer(); 01748 } 01749 } 01750 01751 if (pOpDesc && pOpDesc->Token != String(OPTOKEN_FRAME_GRABFRAME) && !Empty) 01752 { 01753 // Cannot assume that all the frame layers are actually frame layers so 01754 // go through all those that might be frame layers. 01755 Layer * pFrame = pSpread->FindFirstLayer(); 01756 BOOL AllHidden = TRUE; 01757 while (pFrame && AllHidden) 01758 { 01759 if (pFrame->IsPseudoFrame() && !pFrame->IsHiddenFrame()) 01760 AllHidden = FALSE; 01761 01762 pFrame = pFrame->FindNextLayer(); 01763 } 01764 01765 if (AllHidden) 01766 { 01767 OpSt.Greyed = TRUE; 01768 // Load reason why operation is disabled 01769 DisableReason = String_256(_R(IDS_ALLFRAMESAREHIDDEN)); 01770 if (pUIDescription) 01771 *pUIDescription = DisableReason; 01772 } 01773 else 01774 { 01775 // Yes, so we are allowed to grab the frame or all the frames 01776 OpSt.Greyed = FALSE; 01777 } 01778 } 01779 else if (pOpDesc && pOpDesc->Token == String(OPTOKEN_FRAME_GRABFRAME) && pLayer->IsHiddenFrame()) 01780 { 01781 // If we are the grab frame op then check that the current layer is not 01782 // hidden. If so then disallow 01783 OpSt.Greyed = TRUE; 01784 // Load reason why operation is disabled 01785 DisableReason = String_256(_R(IDS_FRAMEISHIDDEN)); 01786 if (pUIDescription) 01787 *pUIDescription = DisableReason; 01788 } 01789 else if (!Empty) 01790 { 01791 // Yes, so we are allowed to grab the frame or all the frames 01792 OpSt.Greyed = FALSE; 01793 } 01794 else 01795 { 01796 OpSt.Greyed = TRUE; 01797 // Load reason why operation is disabled 01798 DisableReason = String_256(_R(IDS_NO_VISIBLE_OBJECTS)); 01799 if (pUIDescription) 01800 *pUIDescription = DisableReason; 01801 } 01802 } 01803 else 01804 { 01805 // No, so we are greyed 01806 OpSt.Greyed = TRUE; 01807 } 01808 } 01809 else 01810 { 01811 // No selected spread, so we are greyed 01812 OpSt.Greyed = TRUE; 01813 01814 // Load reason why operation is disabled 01815 DisableReason = String_256(_R(IDS_NO_DOC)); 01816 if (pUIDescription) 01817 *pUIDescription = DisableReason; 01818 } 01819 } 01820 else 01821 { 01822 // The document is layer based, so we are greyed. 01823 OpSt.Greyed = TRUE; 01824 *pUIDescription = String_256 (_R(IDS_NO_FRAMES)); 01825 } 01826 #endif 01827 01828 return OpSt; 01829 } 01830 01831 /******************************************************************************************** 01832 01833 > OpGrabFrame::OpGrabFrame() 01834 01835 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01836 Created: 29/4/97 01837 Purpose: Constructor 01838 01839 ********************************************************************************************/ 01840 01841 OpGrabFrame::OpGrabFrame() 01842 { 01843 m_pDocument = NULL; 01844 m_pSpread = NULL; 01845 m_pLayer = NULL; 01846 m_pView = NULL; 01847 01848 m_pBitmapFilter = NULL; 01849 m_pSelState = NULL; 01850 01851 //m_pBitmapData = NULL; 01852 01853 m_pBrowserPalette = NULL; 01854 } 01855 01856 /******************************************************************************************** 01857 01858 > OpGrabFrame::~OpGrabFrame() 01859 01860 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01861 Created: 29/4/97 01862 Purpose: Destructor 01863 01864 ********************************************************************************************/ 01865 01866 OpGrabFrame::~OpGrabFrame() 01867 { 01868 if (m_pBitmapFilter != NULL) 01869 { 01870 delete m_pBitmapFilter; 01871 m_pBitmapFilter = NULL; 01872 } 01873 01874 if (m_pSelState != NULL) 01875 { 01876 delete m_pSelState; 01877 m_pSelState = NULL; 01878 } 01879 01880 /* if (m_pBitmapData != NULL) 01881 { 01882 delete m_pBitmapData; 01883 m_pBitmapData = NULL; 01884 } */ 01885 01886 if (m_pBrowserPalette != NULL) 01887 { 01888 CCFree(m_pBrowserPalette); 01889 m_pBrowserPalette = NULL; 01890 } 01891 } 01892 01893 /************************************************************************************************************ 01894 01895 > void OpGrabFrame::Do(OpDescriptor * pOpDesc) 01896 01897 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01898 Created: 23/4/97 01899 Inputs: OpDescriptor (unused) 01900 Outputs: - 01901 Returns: - 01902 Purpose: Tries to grab the selected animation frame (i.e. layer). 01903 01904 This Op can be invoked under a number of circumstances:- 01905 1. When the preview dialog is open. 01906 Dissplay the bitmap corresponding to the selected frame layer. 01907 If the selected frame layer is not in the Preview list (i.e has not been generated) 01908 then generate the bitmap and add it to the list of bitmaps which be will included in the Preview. 01909 2. When the preview dialog is closed. 01910 In this case we need to generate the bitmap corresponding to the selected Frame layer. 01911 01912 ****************************************************************************************************************/ 01913 01914 void OpGrabFrame::Do( OpDescriptor * pOpDesc ) 01915 { 01916 DoWithParam(pOpDesc, NULL); 01917 return; 01918 } 01919 01920 /******************************************************************************************** 01921 01922 > void OpGrabFrame::DoWithParam(OpDescriptor * pOpDesc, Param* pParam) 01923 01924 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> (From Neville code.) 01925 Created: 21/05/97 01926 Inputs: OpDescriptor (unused) 01927 pParam - NULL - means grab the active frame 01928 - Param1 = pLayer - means grab the specified layer 01929 Outputs: - 01930 Returns: - 01931 Purpose: Regenerate the bitmap associated with the active frame layer. 01932 Errors: - 01933 SeeAlso: - 01934 01935 ********************************************************************************************/ 01936 void OpGrabFrame::DoWithParam(OpDescriptor * pOpDesc, OpParam* pParam) 01937 { 01938 // ERROR3IF(pParam == NULL, "OpGrabFrame::DoWithParam - NULL Param passed in"); 01939 01940 // Get useful data and set up items before starting the grab process 01941 if (!StartGrab()) 01942 { 01943 // We failed to grab the frame 01944 FailAndExecute(); 01945 End(); 01946 return; 01947 } 01948 01949 // If a parameter has been supplied then this should be a layer pointer, which we 01950 // should then use to grab the frame 01951 // Otherwise, we assume we must grab the active frame (StartGrab sets m_pLayer to the active layer) 01952 if (pParam != NULL) 01953 { 01954 // recover the layer pointer that has been specified 01955 Layer* pLayer = (Layer *) (void *) pParam->Param1; 01956 if (pLayer) 01957 { 01958 ERROR3IF(!pLayer->IS_KIND_OF(Layer), "OpParam passed is not a Layer"); 01959 01960 // Note the layer we are expected to grab in our class variable 01961 m_pLayer = pLayer; 01962 01963 // Set up the visibility of the other layers using this layer 01964 // as the new temporary and acting active layer 01965 FrameSGallery::FixOtherLayersFromActive(m_pLayer); 01966 } 01967 } 01968 01969 // Are we trying to grab a hidden frame? 01970 if (m_pLayer->IsHiddenFrame()) 01971 { 01972 // yes, tell the user 01973 InformError(_R(IDS_FRAMEISHIDDEN)); 01974 //ERROR3IF(m_pLayer->IsHiddenFrame(),"OpGrabFrame::DoWithParam Frame is hidden"); 01975 // and then fail 01976 FailAndExecute(); 01977 End(); 01978 return; 01979 } 01980 01981 // If required, allow the op to get a filename from the user. 01982 // This also allows them access to the options via the button on the save dialog box. 01983 // This is why we must do this first rather than after we have generated the frames. 01984 if (!GetFileNameFromUser()) 01985 { 01986 // We failed to grab the frame 01987 FailAndExecute(); 01988 End(); 01989 return; 01990 } 01991 01992 // Get our static pointer to the Preview Dialog. 01993 PreviewDialog* pPreviewDlg = PreviewDialog::GetPreviewDialog(); 01994 // If the preview dialog is already open, find the selected frame layer. 01995 if (pPreviewDlg) 01996 pPreviewDlg->StopPreviewing(); 01997 01998 // Go and do the work to grab the frame 01999 KernelBitmap* pBitmap = GrabFrame(); 02000 if (pBitmap == NULL) 02001 { 02002 // We failed to grab the frame. 02003 // Try and put back the selection that we recorded at the start 02004 PutBackTheSelection(); 02005 FailAndExecute(); 02006 End(); 02007 return; 02008 } 02009 02010 // If we have grabbed the non-active layer then make sure the active layer 02011 // is set up as current 02012 Layer *pActiveLayer = m_pSpread->FindActiveLayer(); 02013 if (pActiveLayer && m_pLayer != pActiveLayer) 02014 FrameSGallery::FixOtherLayersFromActive(pActiveLayer); 02015 02016 // Clean up after the grabbing process. 02017 if (!EndGrab()) 02018 { 02019 // We failed to clean up after grabbing the frame. 02020 FailAndExecute(); 02021 End(); 02022 return; 02023 } 02024 02025 // Add this bitmap and layer pairing to our export list 02026 if (!m_ExportParams.AddLayerAndBitmap(m_pLayer, pBitmap)) 02027 { 02028 FailAndExecute(); 02029 End(); 02030 return; 02031 } 02032 02033 // Open the preview dialog, and display the selected frame. 02034 if(!PreviewAnimation()) 02035 { 02036 // We failed to preview the bitmap 02037 FailAndExecute(); 02038 End(); 02039 return; 02040 } 02041 02042 // Finish the operation 02043 End(); 02044 02045 return; 02046 } 02047 02048 /******************************************************************************************** 02049 02050 > BOOL OpGrabFrame::StartGrab() 02051 02052 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02053 Created: 29/4/97 02054 Inputs: 02055 Returns: True if worked ok, False otherwise 02056 Purpose: Tries to set up useful items prior to doing the grab. 02057 02058 ********************************************************************************************/ 02059 02060 BOOL OpGrabFrame::StartGrab() 02061 { 02062 // Is there a selected Document? 02063 m_pDocument = Document::GetSelected(); 02064 if (m_pDocument == NULL) 02065 { 02066 ERROR3("Called OpGrabFrame with no selected document!"); 02067 return FALSE; 02068 } 02069 02070 // Is there a selected spread? 02071 m_pSpread = Document::GetSelectedSpread(); 02072 if (m_pSpread == NULL) 02073 { 02074 ERROR3("Called OpGrabFrame with no selected spread!"); 02075 return FALSE; 02076 } 02077 02078 // Is there a selected view? 02079 m_pView = DocView::GetSelected(); 02080 if (m_pView == NULL) 02081 { 02082 ERROR3("Called OpGrabFrame with no selected view!"); 02083 return FALSE; 02084 } 02085 02086 // Check that all visible layers are actually frame layers 02087 FrameSGallery::EnsureFrameLayerIntegrity(m_pSpread); 02088 02089 // yes, so check if there is an active layer and try to grab it 02090 m_pLayer = m_pSpread->FindActiveLayer(); 02091 if (m_pLayer == NULL) 02092 { 02093 ERROR3("Called OpGrabFrame with no active layer!"); 02094 return FALSE; 02095 } 02096 02097 // Find all objects on this spread from the specified layer, 02098 // selected or unselected, and get the bounding them. 02099 // Range Control parameters are:- 02100 // Include selected nodes - we want TRUE. 02101 // Include Unselected nodes - we want TRUE. 02102 // Cross layers - we want TRUE 02103 // Ignore locked layers - we want FALSE so that we include locked layers. 02104 // IsRenderable if set then calls NeedsToRender - we want TRUE 02105 // Ignore invisible layers - we want FALSE so that we don't include invisible layers. 02106 //Range SearchRange(m_pLayer, NULL, RangeControl(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE)); 02107 02108 // We need to invalidate the region 02109 /* if (!DoInvalidateNodesRegions(SearchRange, TRUE)) 02110 { 02111 return FALSE; 02112 } */ 02113 02114 /* if (!DoStartSelOp(FALSE,FALSE)) // Try to record the selection state , don't render the blobs though 02115 { 02116 return FALSE; 02117 }*/ 02118 02119 // Remember the selection so that we can put it back at the end of the operation 02120 RememberTheSelection(); 02121 02122 // Copy all the current animation parameters from the spread into our export 02123 // params. 02124 m_ExportParams.SetSpreadAnimPropertiesParam(m_pSpread->GetSpreadAnimPropertiesParam()); 02125 02126 return TRUE; 02127 } 02128 02129 /******************************************************************************************** 02130 02131 > virtual BOOL OpGrabFrame::RememberTheSelection() 02132 02133 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02134 Created: 19/6/97 02135 Returns: True if worked ok, False otherwise 02136 Purpose: Tries to remember the current selection state so that we can put it back 02137 at the end of the operation. 02138 Don't error if it fails as the loss of the selection is no great hardship 02139 when memory is tight! 02140 02141 ********************************************************************************************/ 02142 02143 BOOL OpGrabFrame::RememberTheSelection() 02144 { 02145 // Create a SelectionState object 02146 m_pSelState = new SelectionState(); 02147 if (m_pSelState == NULL) 02148 { 02149 return FALSE; // Failure 02150 } 02151 02152 // We have managed to create a SelectionState instance, now lets try and 02153 // record the current selections 02154 if (!m_pSelState->Record()) // We failed to allocate enough memory to store the selection state 02155 { 02156 // There was insufficient memory to record the selections 02157 delete m_pSelState; // Delete the selection state 02158 m_pSelState = NULL; 02159 return FALSE; 02160 } 02161 02162 return TRUE; 02163 } 02164 02165 /******************************************************************************************** 02166 02167 > virtual BOOL OpGrabFrame::PutBackTheSelection() 02168 02169 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02170 Created: 19/6/97 02171 Returns: True if worked ok, False otherwise 02172 Purpose: Tries to put back the remembered selection state at the start of the operation. 02173 02174 ********************************************************************************************/ 02175 02176 BOOL OpGrabFrame::PutBackTheSelection() 02177 { 02178 if (m_pSelState == NULL) 02179 return FALSE; 02180 02181 BOOL RestoreSelBlobs = TRUE; //FALSE; 02182 BOOL RemoveBlobs = FALSE; //TRUE; 02183 // Restores the recorded selected state 02184 m_pSelState->Restore(RestoreSelBlobs, RemoveBlobs); 02185 02186 delete m_pSelState; 02187 m_pSelState = NULL; 02188 02189 return TRUE; 02190 } 02191 02192 /******************************************************************************************** 02193 02194 > KernelBitmap* OpGrabFrame::GrabFrame() 02195 02196 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02197 Created: 29/4/97 02198 Inputs: 02199 Returns: KernelBitmap if worked ok, NULL otherwise 02200 Purpose: Tries to grab the currently selected frame/layer into a bitmap. 02201 02202 ********************************************************************************************/ 02203 02204 KernelBitmap* OpGrabFrame::GrabFrame() 02205 { 02206 ERROR2IF(m_pDocument == NULL,FALSE,"GrabFrame bad document pointer"); 02207 ERROR2IF(m_pSpread == NULL,FALSE,"GrabFrame bad spread pointer"); 02208 ERROR2IF(m_pLayer == NULL,FALSE,"GrabFrame bad layer pointer"); 02209 ERROR2IF(m_pView == NULL,FALSE,"GrabFrame bad view pointer"); 02210 02211 // Create a special Bitmap filter, that creates a bitmap 02212 // and puts it in the tree 02213 ERROR3IF(m_pBitmapFilter != NULL,"Already have a pBitmapFilter!"); 02214 m_pBitmapFilter = new GrabFrameFilter(); 02215 if (m_pBitmapFilter == NULL) 02216 { 02217 return NULL; 02218 } 02219 02220 // Get the filter to work out the new rectangle 02221 m_pBitmapFilter->SetUpClippingRectangleForExport(m_pSpread, DRAWING); 02222 DocRect NewBoundingRect = m_pBitmapFilter->GetClipRect(); 02223 // Save away the new bounding rectangle 02224 m_pSpread->SetAnimationBoundingRect(NewBoundingRect); 02225 m_ExportParams.SetAnimationBoundingRect(NewBoundingRect); 02226 02227 // Save away the quality that this was grabbed at 02228 Quality NewQuality = m_pView->RenderQuality; 02229 m_pSpread->SetAnimationQuality(NewQuality); 02230 02231 // Check all the layers to see if they contain a single bitmap which we can use 02232 // instead of generating one. 02233 // This will mark all valid single bitmaps using the reference in the layer 02234 if (!CheckAllForSingleBitmaps(m_pSpread, m_pBitmapFilter)) 02235 { 02236 delete m_pBitmapFilter; 02237 m_pBitmapFilter = NULL; 02238 return NULL; 02239 } 02240 02241 // Check if we are grabbing a changed background layer frame, if it is then 02242 // we will then clear the edited bit on this. Once this happens then if the 02243 // user grabs all frames then the dependent frames wont be updated. 02244 if (m_pLayer->IsEdited() && m_pLayer->IsSolid()) 02245 { 02246 // Mark all frames above this as edited until we reach the last frame 02247 // OR we hit a solid/background layer. 02248 Layer * pFrame = m_pLayer->FindNextFrameLayer(); 02249 while (pFrame != NULL && !pFrame->IsSolid()) 02250 { 02251 // Mark that frame as edited 02252 pFrame->SetEdited(TRUE); 02253 pFrame = pFrame->FindNextFrameLayer(); 02254 } 02255 } 02256 02257 // Check to see if we have a single bitmap on the layer which is stored 02258 // in a NodeBitmap at a 1:1 scale and is 8bpp or less and the palette matches 02259 // the present options. 02260 // If it passes all these tests, then set pBitmapToCreate to be that bitmap. 02261 // Otherwise, we will need to go and convert the current frame into a bitmap 02262 KernelBitmap* pBitmapToCreate = NULL; 02263 //if (!CheckIfSingleBitmap(m_pLayer, &pBitmapToCreate)) 02264 // If there is a referenced bitmap then we can use this instead of generating one 02265 pBitmapToCreate = m_pLayer->GetReferencedBitmap(); 02266 if (pBitmapToCreate == NULL) 02267 { 02268 // Grab the frame 02269 02270 02271 // As this will affect us during grabbing, we should force it into the known 02272 // non-interferring state 02273 BOOL CurrentVisEdState = Layer::ActiveLayerVisibleAndEditable; 02274 Layer::ActiveLayerVisibleAndEditable = FALSE; 02275 // The all visible flag will also do this for us. 02276 Document* pDoc = m_pSpread->FindParentDocument(); 02277 BOOL CurrentAllVisibleState = FALSE; 02278 if (pDoc != NULL) 02279 { 02280 CurrentAllVisibleState = pDoc->IsAllVisible(); 02281 pDoc->SetAllVisible(FALSE); 02282 } 02283 02284 // Go and convert the frame into its bitmap form 02285 pBitmapToCreate = GrabTheFrame(); 02286 02287 // Put back the active layer's visibilty and selection 02288 Layer::ActiveLayerVisibleAndEditable = CurrentVisEdState; 02289 // Put back the all visible state 02290 if (pDoc != NULL) 02291 pDoc->SetAllVisible(CurrentAllVisibleState); 02292 } 02293 02294 // Note the capture quality that the frame was captured at but only if we worked correctly 02295 if (pBitmapToCreate) 02296 m_pLayer->SetCaptureQuality(NewQuality); 02297 02298 // remove the filter as we have no more use for it 02299 delete m_pBitmapFilter; 02300 m_pBitmapFilter = NULL; 02301 02302 // Clear the edited flag on the layer 02303 m_pLayer->SetEdited(FALSE); 02304 #ifdef _DEBUG 02305 // Tell the frame gallery to update its display of the frame 02306 BROADCAST_TO_ALL(LayerMsg(m_pLayer, LayerMsg::REDRAW_LAYER)); 02307 #endif 02308 02309 // return the bitmap to the caller 02310 return pBitmapToCreate; 02311 } 02312 02313 /******************************************************************************************** 02314 02315 > KernelBitmap* OpGrabFrame::GrabTheFrame() 02316 02317 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02318 Created: 11/6/97 02319 Inputs: 02320 Returns: KernelBitmap if worked ok, NULL otherwise 02321 Purpose: Tries to grab the currently selected frame/layer into a bitmap. 02322 Same as GrabFrame but assumes that the filter to do the grab, m_pBitmapFilter, 02323 is already present. 02324 02325 ********************************************************************************************/ 02326 02327 KernelBitmap* OpGrabFrame::GrabTheFrame() 02328 { 02329 ERROR2IF(m_pDocument == NULL,FALSE,"GrabFrame bad document pointer"); 02330 ERROR2IF(m_pLayer == NULL,FALSE,"GrabFrame bad layer pointer"); 02331 ERROR2IF(m_pBitmapFilter == NULL,FALSE,"GrabFrame m_pBitmapFilter pointer"); 02332 02333 // Tell it about the layer that is being captured 02334 // This supplies the name of the bitmap and the export parameters 02335 m_pBitmapFilter->SetLayerBeingCaptured(m_pLayer); 02336 02337 KernelBitmap* pBitmapToCreate = NULL; 02338 if (!m_pBitmapFilter->DoCreateBitmap(this, m_pDocument, &pBitmapToCreate) || pBitmapToCreate == NULL) 02339 { 02340 return NULL; 02341 } 02342 02343 // Copy across the delay from the layer (Andy 5/1/01) 02344 DWORD delay = m_pLayer->GetFrameDelay(); 02345 pBitmapToCreate->SetDelay(delay); 02346 02347 // Make the layer remember this bitmap as the one that was generated 02348 if (!m_pLayer->SetGeneratedBitmap(pBitmapToCreate)) 02349 { 02350 ERROR3("Couldn't add bitmap to layer!"); 02351 if (pBitmapToCreate) 02352 delete pBitmapToCreate; 02353 return NULL; 02354 } 02355 02356 // DO NOT unset the edited flag. This version is used in GrabAllFrames and we need the 02357 // edited flags present until we have finished grabbing so that we can work out dependent 02358 // layers. 02359 02360 // return the bitmap to the caller 02361 return pBitmapToCreate; 02362 } 02363 02364 /******************************************************************************************** 02365 02366 > BOOL OpGrabFrame::EndGrab() 02367 02368 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02369 Created: 29/4/97 02370 Inputs: 02371 Returns: True if worked ok, False otherwise 02372 Purpose: Tries to clean up after doing the grab. 02373 02374 ********************************************************************************************/ 02375 02376 BOOL OpGrabFrame::EndGrab() 02377 { 02378 // Try and put back the selection that we recorded at the start 02379 PutBackTheSelection(); 02380 02381 // Make sure that the new selection is up to date 02382 //Range * pSelRange = GetApplication()->FindSelection(); 02383 /* if (pSelRange == NULL || !DoInvalidateNodesRegions(*pSelRange, TRUE)) 02384 { 02385 // We failed to invalidate the region 02386 return FALSE; 02387 } */ 02388 02389 /* // Recover the active layer again and make sure that it is being shown correctly. 02390 ERROR2IF(m_pSpread == NULL,FALSE,"bad spread in EndGrab()"); 02391 Layer *pLayer = m_pSpread->FindActiveLayer(); 02392 ERROR2IF(pLayer == NULL,"No active layer in EndGrab()") 02393 if (pLayer) 02394 { 02395 FrameSGallery::FixOtherLayersFromActive(pLayer); 02396 } */ 02397 02398 return TRUE; 02399 } 02400 02401 /******************************************************************************************** 02402 02403 > BOOL OpGrabFrame::GetFileNameFromUser() 02404 02405 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02406 Created: 7/7/97 02407 Returns: True if worked ok, False otherwise 02408 Purpose: Gives the operation chance to get the filename from the user. 02409 In this baseclass version we do nothing as we preview a single frame and 02410 so have no need of a filename. 02411 02412 ********************************************************************************************/ 02413 02414 BOOL OpGrabFrame::GetFileNameFromUser() 02415 { 02416 // Baseclass version, do nothing 02417 return TRUE; 02418 } 02419 02420 /******************************************************************************************** 02421 02422 > BOOL OpGrabFrame::PreviewAnimation() 02423 02424 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02425 Created: 29/4/97 02426 Returns: True if worked ok, False otherwise 02427 Purpose: Tries to preview the frames that have been grabbed. 02428 Uses the stored animation details in m_ExportParams 02429 02430 ********************************************************************************************/ 02431 02432 BOOL OpGrabFrame::PreviewAnimation() 02433 { 02434 // Copy all the current animation parameters from the spread into our export 02435 // params. 02436 m_ExportParams.SetSpreadAnimPropertiesParam(m_pSpread->GetSpreadAnimPropertiesParam()); 02437 02438 // See if there is a currently open preview dialog box 02439 PreviewDialog * pPreviewDialog = PreviewDialog::GetPreviewDialog(); 02440 02441 // Check that we have a list of bitmaps to preview. If not then complain bitterly. 02442 // Hidden frames allow us to get this far. 02443 if (m_ExportParams.GetBitmapCount() == 0) 02444 { 02445 // If the preview dialog is open then force it into an idle state 02446 if (pPreviewDialog != NULL) 02447 pPreviewDialog->SetDialogToIdleState(); 02448 02449 // tell the user about the problems 02450 InformError(_R(IDS_NOFRAMESTOPREVIEW)); 02451 return FALSE; 02452 } 02453 02454 // If the preview dialog is currently open, pass it the list of bitmaps. 02455 // We must do this on all types of preview e.g. save, as we will have stopped 02456 // the animation before previewing and so we need to ensure that the preview 02457 // dialog box is restored to a known state. 02458 if (pPreviewDialog != NULL) 02459 { 02460 // Pass the preview dialog box the new list of bitmaps 02461 pPreviewDialog->SetBitmapList(&m_ExportParams); 02462 02463 PreviewDialog::ToggleViaBitmapGallery (FALSE); 02464 //pPreviewDialog->ToggleViaBitmapGallery (FALSE); 02465 pPreviewDialog->SetPlayAnimation(TRUE); 02466 02467 // Call the dialog box so that it sets up the necessary states 02468 pPreviewDialog->ReInitDialog(); 02469 } 02470 02471 // This does the actually job in hand, e.g. preview, save, preview in browser 02472 BOOL ok = SaveOrShowTheAnimation(pPreviewDialog, &m_ExportParams); 02473 02474 return ok; 02475 } 02476 02477 /******************************************************************************************** 02478 02479 > BOOL OpGrabFrame::SaveOrShowTheAnimation(PreviewDialog * pPreviewDialog, BitmapExportParam* pExportParam) 02480 02481 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02482 Created: 4/8/97 02483 Inputs: pPreviewDialog the preview dialog box, if open 02484 pExportParam the export param which we will use 02485 Returns: True if worked ok, False otherwise 02486 Purpose: Tries to actually do the preview operation required. 02487 In this case we just start up the preview dialog box, if not already open, 02488 to show the frames that have been grabbed. 02489 Uses the stored animation details in m_ExportParams 02490 02491 ********************************************************************************************/ 02492 02493 BOOL OpGrabFrame::SaveOrShowTheAnimation(PreviewDialog * pPreviewDialog, BitmapExportParam* pExportParam) 02494 { 02495 // Only boot up the preview dialog box if it is not already on display 02496 // If it is already on display then we will have already dealt with it 02497 if (pPreviewDialog == NULL) 02498 { 02499 // Invoke the preview operation 02500 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_PREVIEWDIALOG); 02501 if (pOpDesc) 02502 { 02503 PreviewDialog::ToggleViaBitmapGallery (FALSE); 02504 pOpDesc->Invoke(&m_ExportParams); 02505 pPreviewDialog = PreviewDialog::GetPreviewDialog(); 02506 //pPreviewDialog->ToggleViaBitmapGallery (FALSE); 02507 } 02508 } 02509 02510 return TRUE; 02511 } 02512 02513 /**************************************************************************************************** 02514 02515 > BOOL OpGrabFrame::SetSingleBitmapInList() 02516 02517 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 02518 Created: 14/05/97 02519 Inputs: - 02520 Returns: True if worked ok, False otherwise. 02521 Purpose: If the Preview Dialog is open and we regenerate a single frame, 02522 this function allows us to update our Bitmap list in the Preview Dialog. 02523 02524 ******************************************************************************************************/ 02525 02526 /* BOOL OpGrabFrame::SetSingleBitmapInList() 02527 { 02528 // Copy all the current animation parameters from the spread into our export params. 02529 m_ExportParams.SetSpreadAnimPropertiesParam(m_pSpread->GetSpreadAnimPropertiesParam()); 02530 02531 // Get our static pointer to the Preview Dialog. 02532 PreviewDialog* pPreviewDialog = PreviewDialog::GetPreviewDialog(); 02533 02534 if (!pPreviewDialog) 02535 return FALSE; 02536 02537 pPreviewDialog->SetRegeneratedBitmapInList(&m_ExportParams); 02538 02539 return TRUE; 02540 } */ 02541 02542 /****************************************************************************************************** 02543 02544 > BOOL OpGrabFrame::SetBitmapToListTail() 02545 02546 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 02547 Created: 14/05/97 02548 Inputs: - 02549 Returns: True if worked ok, False otherwise. 02550 Purpose: If the Preview Dialog is open and we regenerate a single frame, this function 02551 allows us to add that Bitmap to the head of the preview dialog bitmap list. 02552 02553 ********************************************************************************************************/ 02554 02555 /* BOOL OpGrabFrame::SetBitmapToListTail() 02556 { 02557 // Copy all the current animation parameters from the spread into our export params. 02558 m_ExportParams.SetSpreadAnimPropertiesParam(m_pSpread->GetSpreadAnimPropertiesParam()); 02559 02560 // Get our static pointer to the Preview Dialog. 02561 PreviewDialog* pPreviewDialog = PreviewDialog::GetPreviewDialog(); 02562 02563 if (!pPreviewDialog) 02564 return FALSE; 02565 02566 // Add this bitmap to the list tail. 02567 pPreviewDialog->SetBitmapToListTail(&m_ExportParams); 02568 02569 return TRUE; 02570 } */ 02571 02572 /**************************************************************************************************** 02573 02574 > BOOL OpGrabFrame::SetFullBitmapList() 02575 02576 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 02577 Created: 14/05/97 02578 Inputs: SetFlagState: If this is specified, it allows us to set the state of certain flags 02579 in the Preview dialog. 02580 Returns: True if worked ok, False otherwise. 02581 Purpose: If the Preview Dialog is open and we regenerate the frames in the animation, 02582 this function allows us to update our Bitmap list in the Preview Dialog. 02583 02584 ******************************************************************************************************/ 02585 02586 /* BOOL OpGrabFrame::SetFullBitmapList(BOOL SetFlagState) 02587 { 02588 // Copy all the current animation parameters from the spread into our export params. 02589 m_ExportParams.SetSpreadAnimPropertiesParam(m_pSpread->GetSpreadAnimPropertiesParam()); 02590 02591 // Get our static pointer to the Preview Dialog. 02592 PreviewDialog* pPreviewDialog = PreviewDialog::GetPreviewDialog(); 02593 02594 if (!pPreviewDialog) 02595 return FALSE; 02596 02597 // If the animation is playing, stop the animation before we pass it our new list of bitmaps. 02598 if(pPreviewDialog->GetPlayAnimation()) 02599 pPreviewDialog->SetPlayAnimation(FALSE); 02600 02601 pPreviewDialog->SetBitmapList(&m_ExportParams); 02602 02603 // Set the state of the preview dlg flags. 02604 if(SetFlagState) 02605 { 02606 // Call the dialog box so that it sets up the necessary states 02607 pPreviewDialog->ReInitDialog(); 02608 } 02609 02610 // Play the animation. 02611 pPreviewDialog->SetPlayAnimation(TRUE); 02612 02613 return TRUE; 02614 } */ 02615 02616 02617 /******************************************************************************************** 02618 02619 > BOOL OpGrabFrame::CheckIfSingleBitmap(Layer * pLayer, KernelBitmap ** ppBitmap) 02620 02621 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02622 Created: 16/6/97 02623 Inputs: pLayer - the layer we need to check 02624 Outputs: The bitmap to use for this frame 02625 Returns: True if found a single bitmap on the frame/layer. False otherwise. 02626 Purpose: For finding out if there is a single bitmap on the layer which is stored 02627 in a NodeBitmap at a 1:1 scale and is 8bpp or less and the palette matches 02628 the present options. This palette testing is now done after this 02629 If it passes all these tests, then set pBitmap to be that bitmap and return 02630 True. Also note in the layer that this bitmap can possibly be used to specify 02631 this layer. We can only say for sure when we have checked that its palette 02632 matches the current animation options. 02633 SeeAlso: CheckAllForSingleBitmaps; 02634 02635 ********************************************************************************************/ 02636 02637 BOOL OpGrabFrame::CheckIfSingleBitmap(Layer * pLayer, KernelBitmap ** ppBitmap) 02638 { 02639 ERROR2IF(pLayer == NULL, FALSE,"CheckIfSingleBitmap bad layer pointer"); 02640 ERROR2IF(ppBitmap == NULL, FALSE,"CheckIfSingleBitmap bad bitmap pointer"); 02641 02642 // Get some of the current export options 02643 DocRect BoundingRect = m_ExportParams.GetAnimationBoundingRect(); 02644 ERROR3IF(BoundingRect.IsEmpty(),"Bounding rect not set up"); 02645 // PALETTE_COLOURS Palette = m_ExportParams.GetPaletteCols(); 02646 // WEB_PALETTE WebPalette = m_ExportParams.GetPalette(); 02647 02648 KernelBitmap * pBitmap = NULL; 02649 BOOL Scaled1to1 = FALSE; 02650 BOOL PaletteOk = FALSE; 02651 BOOL InsideBoundingRect = TRUE; 02652 BOOL FullFirstFrame = TRUE; 02653 UINT32 Bpp = 0; 02654 INT32 NodeCount = 0; 02655 NodeBitmap *pNodeBmp = NULL; 02656 02657 // check if we are the first animation frame, if so then we the bitmap must be the same 02658 // size as the animation bounding rect. Otherwise, the first frame will not be the size 02659 // of the animation which highlights a bug in MS IE 3.0 02660 Layer * pPreviousFrame = pLayer->FindPrevFrameLayer(); 02661 02662 Node * pNode = pLayer->FindFirstChild(); 02663 while (pNode != NULL) 02664 { 02665 // If the node renders something on the screen then we count it as this will mean that 02666 // the single bitmap does not fully define the layer. 02667 // It ignores attributes, hidden nodes, etc - nodes that don't render anything themselves. 02668 if (pNode->IsBounded()) 02669 NodeCount++; 02670 02671 // We need to note any NodeBitmap nodes 02672 if (pNode->IS_KIND_OF(NodeBitmap) && NodeCount == 1) 02673 { 02674 // Convert the node to a nodebitmap so we can get at the useful NodeBitmap 02675 // related data 02676 pNodeBmp = (NodeBitmap *)pNode; 02677 02678 // Get the size and position of the node bitmap 02679 DocRect rect = pNodeBmp->GetBoundingRect(TRUE, FALSE); 02680 02681 // If we have no previous frame then check that the first frame is the 02682 // size of the animation 02683 if (pPreviousFrame == NULL) 02684 { 02685 DocRect AniBoundingRect = m_ExportParams.GetAnimationBoundingRect(); 02686 ERROR3IF(AniBoundingRect.IsEmpty(),"CheckIfSingleBitmap Animation bounding rect not set up!"); 02687 02688 // REMEMBER account for rounding errors 02689 const INT32 delta = 50; 02690 if ( 02691 (AniBoundingRect.lo.x >= (rect.lo.x - delta)) && (AniBoundingRect.lo.x <= (rect.lo.x + delta)) && 02692 (AniBoundingRect.hi.x >= (rect.hi.x - delta)) && (AniBoundingRect.hi.x <= (rect.hi.x + delta)) && 02693 (AniBoundingRect.lo.y >= (rect.lo.y - delta)) && (AniBoundingRect.lo.y <= (rect.lo.y + delta)) && 02694 (AniBoundingRect.hi.y >= (rect.hi.y - delta)) && (AniBoundingRect.hi.y <= (rect.hi.y + delta)) 02695 ) 02696 { 02697 FullFirstFrame = TRUE; 02698 } 02699 else 02700 { 02701 FullFirstFrame = FALSE; 02702 } 02703 } 02704 02705 // Get the bitmap stored inside the node, if any 02706 pBitmap = pNodeBmp->GetBitmap(); 02707 if (pBitmap) 02708 { 02709 // Get the width/height of the bitmap in millipoints 02710 INT32 BmpWidth = pBitmap->GetRecommendedWidth(); 02711 INT32 BmpHeight = pBitmap->GetRecommendedHeight(); 02712 02713 // Get the Width of the Bitmap in Millipoints 02714 INT32 Width = INT32(pNodeBmp->Parallel[0].Distance(pNodeBmp->Parallel[1])); 02715 INT32 Height = INT32(pNodeBmp->Parallel[1].Distance(pNodeBmp->Parallel[2])); 02716 02717 // REMEMBER account for rounding errors and the orientation being the other 02718 // way round 02719 const INT32 delta = 2; 02720 if ((Width >= BmpWidth - delta && Width <= BmpWidth + delta && 02721 Height >= BmpHeight - delta && Height <= BmpHeight + delta) || 02722 (Height >= BmpWidth - delta && Height <= BmpWidth + delta && 02723 Width >= BmpHeight - delta && Width <= BmpHeight + delta) ) 02724 Scaled1to1 = TRUE; 02725 02726 Bpp = pBitmap->GetBPP(); 02727 02728 // If the bitmap is 8bpp of less then assume this is ok for now 02729 // We will check the palette in a second pass 02730 if (Bpp <= 8) 02731 { 02732 PaletteOk = TRUE; 02733 } 02734 02735 /* // We cannot cope with GLOBAL OPTIMISED palettes at present as we 02736 // would need to wait until the palette was generated before we could 02737 // check. 02738 if (Palette == PALCOL_OPTIMIZED && WebPalette == PAL_LOCAL) 02739 { 02740 // Saving local palette so any palette ok 02741 PaletteOk = TRUE; 02742 } 02743 else if (Palette == PALCOL_BROWSER && WebPalette == PAL_GLOBAL) 02744 { 02745 // Check if we have a browser palette on this bitmap 02746 //PaletteOk = pBitmap->IsBrowserPalette(); 02747 // Old way of testing. Too lenient as all it does it check that the palette 02748 // has the correct colours in it, not that the palette will be the same one 02749 // that we are going to output as the browser palette 02750 02751 // Obviously, browser palettes can only happen on 8bpp bitmaps 02752 if (Bpp == 8) 02753 { 02754 // First of all, if we haven't already got our palette that we check against 02755 // then construct it. 02756 if (m_pBrowserPalette == NULL) 02757 { 02758 UINT32 PaletteSize = UINT32(pow(2,Bpp)); 02759 m_pBrowserPalette = DIBUtil::AllocateLogPalette(PaletteSize); 02760 if (m_pBrowserPalette != NULL) 02761 { 02762 // Now force it into a browser compatible state 02763 BOOL AvoidSystemColours = TRUE; 02764 PaletteManager::MakePaletteBrowserCompatible(m_pBrowserPalette, AvoidSystemColours); 02765 } 02766 } 02767 02768 INT32 TransColour = -1; 02769 pBitmap->GetTransparencyIndex(&TransColour); 02770 02771 if (m_pBrowserPalette != NULL) 02772 { 02773 PaletteOk = pBitmap->ArePalettesTheSame(m_pBrowserPalette, TransColour); 02774 } 02775 else 02776 { 02777 ERROR3("Couldn't allocate browser palette"); 02778 PaletteOk = FALSE; 02779 } 02780 } 02781 else 02782 PaletteOk = FALSE; 02783 } 02784 } */ 02785 02786 if (Scaled1to1 && PaletteOk && !rect.IsEmpty() && !BoundingRect.IsEmpty()) 02787 { 02788 // Work out the position of the bitmap relative to the top left hand 02789 // corner of the bounding rectangle in terms of pixels and put this 02790 // in the bitmap 02791 MILLIPOINT LeftOffsetMP = rect.lo.x - BoundingRect.lo.x; 02792 MILLIPOINT TopOffsetMP = BoundingRect.hi.y - rect.hi.y; 02793 if (LeftOffsetMP >= 0 && TopOffsetMP >= 0) 02794 { 02795 const UINT32 dpi = 96; 02796 UINT32 LeftOffset = LeftOffsetMP * dpi/72000; 02797 UINT32 TopOffset = TopOffsetMP * dpi/72000; 02798 02799 pBitmap->SetLeftOffset(LeftOffset); 02800 pBitmap->SetTopOffset(TopOffset); 02801 InsideBoundingRect = TRUE; 02802 } 02803 } 02804 } 02805 } 02806 02807 pNode = pNode->FindNext(); 02808 } 02809 02810 // If all these checks are TRUE then return the bitmap as the source of the frame 02811 if (pBitmap != NULL && Scaled1to1 && Bpp <= 8 && NodeCount == 1 && 02812 PaletteOk && InsideBoundingRect && FullFirstFrame) 02813 { 02814 if (ppBitmap) 02815 *ppBitmap = pBitmap; 02816 02817 // Make the layer remember this bitmap 02818 // Remember this bitmap as the reference one 02819 pLayer->SetReferencedBitmap(pBitmap); 02820 02821 //TRACEUSER( "Neville", _T("Using single bitmap\n")); 02822 02823 return TRUE; 02824 } 02825 02826 // Ensure that we have no reference saved 02827 pLayer->SetReferencedBitmap(NULL); 02828 02829 return FALSE; 02830 } 02831 02832 02833 /******************************************************************************************** 02834 02835 > BOOL OpGrabFrame::CheckAllForSingleBitmaps(Spread * pSpread) 02836 02837 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02838 Created: 9/7/97 02839 Inputs: pLayer - the layer we need to check 02840 pBitmapFilter - a grab frame filter we can use 02841 Returns: True if worked correctly, False otherwise. 02842 Purpose: For going through all the frames and seeing if there is a single bitmap 02843 on the frame/layer which is stored in a NodeBitmap at a 1:1 scale and is 8bpp 02844 or less and the palette matches the present options. 02845 We use the grab frame filter as this is derived off GIF filter and this must 02846 already cope with this when loading animations so that it can set the animation 02847 options accordingly. 02848 02849 ********************************************************************************************/ 02850 02851 BOOL OpGrabFrame::CheckAllForSingleBitmaps(Spread * pSpread, GrabFrameFilter * pBitmapFilter) 02852 { 02853 ERROR2IF(pSpread == NULL, FALSE,"CheckIfSingleBitmap bad Spread pointer"); 02854 ERROR2IF(pBitmapFilter == NULL, FALSE,"CheckIfSingleBitmap bad GrabFrameFilter pointer"); 02855 02856 // So we can do the optimised palette case, we must go though all the 02857 // layers/frames and see if there is a single bitmap present. We don't worry 02858 // about the palette on this first pass. We just set up the referenced bitmap 02859 // to be the single bitmap if it passes all the tests. 02860 KernelBitmap * pBitmap = NULL; 02861 BOOL Found = FALSE; 02862 BOOL SolidSet = FALSE; 02863 BOOL OverlaySet = FALSE; 02864 BOOL OverlayedBitmapSet = FALSE; 02865 Layer* pCurrentLayer = pSpread->FindFirstFrameLayer(); 02866 Layer* pNextLayer = NULL; 02867 Layer* pPrevFrameLayer = NULL; 02868 while (pCurrentLayer != NULL) 02869 { 02870 // Move to the next bitmap in the animation 02871 pNextLayer = pCurrentLayer->FindNextFrameLayer(); 02872 02873 // This is just as a double check 02874 if (pCurrentLayer->IsPseudoFrame()) 02875 { 02876 Found = CheckIfSingleBitmap(pCurrentLayer, &pBitmap); 02877 // If the solid flag is set on anything but the last layer then note this 02878 // as dangerous 02879 if (pCurrentLayer->IsSolid() && pNextLayer != NULL) 02880 SolidSet = TRUE; 02881 if (pCurrentLayer->IsOverlay()) 02882 { 02883 // If overlay is set then we can allow it if the previous bitmap has a restore 02884 // type of overlay as this may be an animation that we have saved out 02885 // and then loaded in. If a diff has happened then overlay will be set. 02886 // We can only ever allow this if the layers consist of all bitmaps as 02887 // otherwise the layer may be overlaying a vector layer and hence be wrong. 02888 KernelBitmap * pPrevBitmap = NULL; 02889 if (pPrevFrameLayer) 02890 pPrevBitmap = pPrevFrameLayer->GetReferencedBitmap(); 02891 // Check that we have a single reuseable bitmap on this layer plus one of the previous 02892 if (pPrevBitmap != NULL && pBitmap != NULL) 02893 { 02894 GIFDisposalMethod restore = pPrevBitmap->GetAnimationRestoreType(); 02895 // Do we include GDM_NONE? Not for now. 02896 if (restore != GDM_LEAVE) 02897 { 02898 // We cannot use the bitmap so set the reference to NULL 02899 pCurrentLayer->SetReferencedBitmap(NULL); 02900 OverlaySet = TRUE; 02901 } 02902 else 02903 OverlayedBitmapSet = TRUE; 02904 } 02905 else if (pPrevFrameLayer != NULL) 02906 { 02907 // If overlay set on the first frame then ignore 02908 // We cannot use the bitmap so set the reference to NULL 02909 pCurrentLayer->SetReferencedBitmap(NULL); 02910 OverlaySet = TRUE; 02911 } 02912 } 02913 } 02914 02915 // Move to the next bitmap in the animation 02916 pPrevFrameLayer = pCurrentLayer; 02917 pCurrentLayer = pNextLayer; 02918 } 02919 02920 // Find out about the palettes that the bitmaps have 02921 // Our filter has a useful function for this 02922 UINT32 ReqNumberOfColours = m_ExportParams.GetNumColsInPalette(); 02923 BOOL SamePalettes = FALSE; 02924 BOOL OurBrowserPalette = FALSE; 02925 BOOL AllHaveBitmaps = FALSE; 02926 BOOL AllWithinCount = FALSE; 02927 UINT32 NumberOfColours = ReqNumberOfColours; 02928 pBitmapFilter->CheckSingleBitmapsOnSpread(pSpread, &SamePalettes, &OurBrowserPalette, &AllHaveBitmaps, 02929 &AllWithinCount, &NumberOfColours); 02930 02931 PALETTE_COLOURS Palette = m_ExportParams.GetPaletteCols(); 02932 WEB_PALETTE WebPalette = m_ExportParams.GetPalette(); 02933 02934 BOOL OptionsOk = FALSE; 02935 // If OverlaySet is true then we have found an overlay situation which we cannot cope with and 02936 // so will have set the referenced bitmap to null. 02937 if (OverlaySet && AllHaveBitmaps) 02938 AllHaveBitmaps = FALSE; 02939 02940 // If solid is set on any of the frames then it is too dangerous to reuse any single bitmaps 02941 // We can only allow overlay, if all layers are single bitmaps and the bitmap concerned is 02942 // of type GDM_LEAVE. Otherwise, it is too dangerous. 02943 BOOL BitmapOverlayOk = TRUE; 02944 if (OverlayedBitmapSet && !AllHaveBitmaps) 02945 BitmapOverlayOk = FALSE; 02946 02947 if (!SolidSet && BitmapOverlayOk) 02948 { 02949 // Check from the most fussy option to the least fussy option 02950 if (Palette == PALCOL_BROWSER && WebPalette == PAL_GLOBAL && OurBrowserPalette) 02951 { 02952 OptionsOk = TRUE; 02953 //TRACEUSER( "Neville", _T("Global browser, palettes ok\n")); 02954 } 02955 else if (Palette == PALCOL_OPTIMIZED && WebPalette == PAL_GLOBAL && SamePalettes && AllHaveBitmaps && 02956 NumberOfColours <= ReqNumberOfColours) 02957 { 02958 OptionsOk = TRUE; 02959 //TRACEUSER( "Neville", _T("Global opt, palettes ok\n")); 02960 // Force the global optimised palette to be null for now 02961 pBitmapFilter->SetGlobalOptimisedPalette(NULL); 02962 } 02963 else if (Palette == PALCOL_OPTIMIZED && WebPalette == PAL_LOCAL && AllWithinCount) 02964 { 02965 // Saving local palette so any palette ok but must be within the count 02966 OptionsOk = TRUE; 02967 //TRACEUSER( "Neville", _T("Local Opt, palettes ok\n")); 02968 } 02969 } 02970 02971 // Now we need to go through the layers again and ratify our check 02972 pCurrentLayer = pSpread->FindFirstFrameLayer(); 02973 pBitmap = NULL; 02974 while (pCurrentLayer != NULL) 02975 { 02976 // This is just as a double check 02977 if (pCurrentLayer->IsPseudoFrame()) 02978 { 02979 pBitmap = pCurrentLayer->GetReferencedBitmap(); 02980 if (OptionsOk && pBitmap) 02981 { 02982 // We can use the bitmap instead of generating one 02983 // So make sure that the generated bitmap is clean out 02984 pCurrentLayer->SetGeneratedBitmap(NULL); 02985 // And ensure that the bitmap has the layer's delay 02986 pBitmap->SetDelay(pCurrentLayer->GetFrameDelay()); 02987 02988 // If we are in 02989 if (Palette == PALCOL_OPTIMIZED && WebPalette == PAL_GLOBAL) 02990 { 02991 // If we haven't set up the global optimised palette then do so now 02992 // Pull it from the first bitmap that we find 02993 LPLOGPALETTE pOptPal = pBitmapFilter->GetGlobalOptimisedPalette(); 02994 if (pOptPal == NULL) 02995 { 02996 pOptPal = DIBUtil::CopyBitmapPaletteIntoLogPalette(pBitmap); 02997 // Something went a bit wrong 02998 if (pOptPal == NULL) 02999 return FALSE; 03000 pBitmapFilter->SetGlobalOptimisedPalette(pOptPal); 03001 } 03002 } 03003 } 03004 else 03005 { 03006 // We cannot use the bitmap so set the reference to NULL 03007 pCurrentLayer->SetReferencedBitmap(NULL); 03008 } 03009 } 03010 03011 // Move to the next bitmap in the animation 03012 pCurrentLayer = pCurrentLayer->FindNextFrameLayer(); 03013 } 03014 03015 return TRUE; 03016 } 03017 03018 /******************************************************************************************** 03019 // End of OpGrabFrame 03020 ********************************************************************************************/ 03021 03022 //------------------------------------------------------------------------------------------ 03023 // Methods for the OpGrabAllFrames 03024 //------------------------------------------------------------------------------------------ 03025 03026 // Macro to determine the bytes in a DWORD aligned DIB scanline 03027 #define BYTESPERLINE(Width, BPP) ((WORD)((((DWORD)(Width) * (DWORD)(BPP) + 31) >> 5)) << 2) 03028 03029 void OpGrabAllFrames::CreateGlobalPalette(DWORD NumColsInPalette, BOOL RegenerateAllFrames) 03030 { 03031 ERROR3IF(!m_pBitmapFilter, "No bitmap filter to use when generating global palette"); 03032 if (!m_pBitmapFilter) 03033 return; 03034 03035 PaletteOptimiser* pPalOpt = new PaletteOptimiser(); 03036 if (!pPalOpt) 03037 return; 03038 pPalOpt->Initialise(); 03039 03040 // Go through all the frame layers in the spread and export them 03041 KernelBitmap * pBitmap = NULL; 03042 Layer* pCurrentLayer = NULL; 03043 03044 // Set the filter to generate preview bitmaps 03045 m_pBitmapFilter->SetGrabMode(GrabFrameFilter::GRABMODE_PREVIEW); 03046 03047 pBitmap = NULL; 03048 pCurrentLayer = m_pSpread->FindFirstFrameLayer(); 03049 03050 while (pCurrentLayer != NULL) 03051 { 03052 // see if the user has hidden the frame 03053 if (!pCurrentLayer->IsPseudoFrame() || pCurrentLayer->IsHiddenFrame()) 03054 { 03055 // It is either an invalid frame or it is hidden. In both cases but especially 03056 // the second we should ensure that if there is a generated bitmap then we 03057 // vape it as it is now out of date. 03058 pCurrentLayer->SetGeneratedBitmap(NULL); 03059 03060 // Move to the next bitmap in the animation 03061 pCurrentLayer = pCurrentLayer->FindNextFrameLayer(); 03062 03063 // Go to the next frame 03064 continue; 03065 } 03066 03067 // Set up the visibility of the other layers using this layer 03068 // as the new temporary and acting active layer 03069 FrameSGallery::FixOtherLayersFromActive(pCurrentLayer); 03070 // This is the layer that we are adding to the global palette 03071 m_pLayer = pCurrentLayer; 03072 03073 // Render a bitmap of the entire image being exported 03074 KernelBitmap* pTestBitmap=NULL; 03075 m_pBitmapFilter->DoCreateBitmap(this, m_pDocument, &pTestBitmap); 03076 03077 // not enough memory? or no content worth talking about then give up! 03078 if (!pTestBitmap || !pTestBitmap->GetActualBitmap()) 03079 { 03080 FailAndExecute(); 03081 End(); 03082 return; 03083 } 03084 03085 // We need to pass Gavin a 32bbp bitmap with an empty channel (rather than an 03086 // alpha channel). Lets quickly create one (I am sure this is not the best way 03087 // of doing this but it will do for now). 03088 UINT32 nPixels = pTestBitmap->GetActualBitmap()->GetBitmapSize() / 3; 03089 RGBQUAD* pNewBitmap = new RGBQUAD[nPixels]; 03090 UINT32 width = pTestBitmap->GetActualBitmap()->GetBitmapInfoHeader()->biWidth; 03091 UINT32 height = pTestBitmap->GetActualBitmap()->GetBitmapInfoHeader()->biHeight; 03092 BYTE* pOldBitmapBytes = (BYTE*)pTestBitmap->GetActualBitmap()->GetBitmapBits(); 03093 UINT32 bytesPerLine = BYTESPERLINE(width, 24); 03094 for (UINT32 y = 0; y < height; ++y) 03095 for (UINT32 x = 0; x < width; x++) 03096 { 03097 pNewBitmap[y * width + x].rgbBlue = pOldBitmapBytes[bytesPerLine * y + x * 3 + 0]; 03098 pNewBitmap[y * width + x].rgbGreen = pOldBitmapBytes[bytesPerLine * y + x * 3 + 1]; 03099 pNewBitmap[y * width + x].rgbRed = pOldBitmapBytes[bytesPerLine * y + x * 3 + 2]; 03100 pNewBitmap[y * width + x].rgbReserved = 0; 03101 } 03102 03103 // add the stats to the palette optimiser 03104 pPalOpt->AddStats(pNewBitmap, nPixels); 03105 03106 delete pNewBitmap; 03107 delete pTestBitmap; 03108 03109 // Move to the next bitmap in the animation 03110 pCurrentLayer = pCurrentLayer->FindNextFrameLayer(); 03111 } 03112 03113 // set the global palette 03114 pPalOpt->SnapToBrowserPalette(0); 03115 pPalOpt->SnapToPrimaries(1); 03116 pPalOpt->AddSystemColours((m_pSpread->GetSpreadAnimPropertiesParam().GetUseSystemCols() == TRUE)); 03117 pPalOpt->UseBrowserPalette(0); 03118 pPalOpt->SetFast(TRUE); 03119 03120 INT32 ColoursToOptimise = camMax(2, NumColsInPalette-1); 03121 03122 // tell the optimiser that we have finished gathering the stats 03123 pPalOpt->GenPalette(ColoursToOptimise); 03124 03125 LOGPALETTE * pGlobalPal = DIBUtil::AllocateLogPalette(ColoursToOptimise + 1); 03126 03127 pGlobalPal->palNumEntries = ColoursToOptimise; 03128 03129 // get the optimised palette from the optimser 03130 pPalOpt->GetPalette( pGlobalPal, ColoursToOptimise); 03131 03132 // we want to add a transparent colour to this palette 03133 pGlobalPal->palNumEntries = camMin(255,pGlobalPal->palNumEntries+1); 03134 03135 // the first entry in the palette is special it should be the background colour as it will 03136 // be what is visible if the background is not transparent so swap the first entry into 03137 // the last and set the last 03138 pGlobalPal->palPalEntry[ pGlobalPal->palNumEntries-1 ].peRed = pGlobalPal->palPalEntry[ 0 ].peRed; 03139 pGlobalPal->palPalEntry[ pGlobalPal->palNumEntries-1 ].peGreen = pGlobalPal->palPalEntry[ 0 ].peGreen; 03140 pGlobalPal->palPalEntry[ pGlobalPal->palNumEntries-1 ].peBlue = pGlobalPal->palPalEntry[ 0 ].peBlue; 03141 pGlobalPal->palPalEntry[ pGlobalPal->palNumEntries-1 ].peFlags = 0; 03142 03143 DocColour dcol = Page::GetPageColour(); 03144 INT32 r = 255, g = 255, b = 255; 03145 dcol.GetRGBValue(&r,&g,&b); 03146 03147 pGlobalPal->palPalEntry[ 0 ].peRed = (BYTE)r; 03148 pGlobalPal->palPalEntry[ 0 ].peGreen = (BYTE)g; 03149 pGlobalPal->palPalEntry[ 0 ].peBlue = (BYTE)b; 03150 pGlobalPal->palPalEntry[ 0 ].peFlags = 255; // the transp entry - not renderable 03151 03152 // remove the optimiser 03153 delete pPalOpt; 03154 03155 // save this global palette for later 03156 m_pBitmapFilter->SetGlobalOptimisedPalette(pGlobalPal); 03157 m_pBitmapFilter->AlterPaletteContents(pGlobalPal); 03158 03159 // Undo our change to the filter 03160 m_pBitmapFilter->SetGrabMode(GrabFrameFilter::GRABMODE_FOROUTPUT); 03161 } 03162 03163 /******************************************************************************************** 03164 03165 > void OpGrabAllFrames::Do(OpDescriptor * pOpDesc) 03166 03167 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03168 Created: 22/4/97 03169 Inputs: OpDescriptor (unused) 03170 Outputs: - 03171 Returns: - 03172 Purpose: Tries to grab the selected animation frame (i.e. layer). 03173 Errors: - 03174 SeeAlso: - 03175 03176 ********************************************************************************************/ 03177 03178 void OpGrabAllFrames::Do( OpDescriptor * pOpDesc ) 03179 { 03180 // Get useful data and set up items before starting the grab process 03181 if (!StartGrab()) 03182 { 03183 // We failed to grab the frame 03184 FailAndExecute(); 03185 End(); 03186 return; 03187 } 03188 03189 // If required, allow the op to get a filename from the user. 03190 // This also allows them access to the options via the button on the save dialog box. 03191 // This is why we must do this first rather than after we have generated the frames. 03192 if (!GetFileNameFromUser()) 03193 { 03194 // We failed to grab the frame 03195 FailAndExecute(); 03196 End(); 03197 return; 03198 } 03199 03200 // Get our static pointer to the Preview Dialog. 03201 PreviewDialog* pPreviewDlg = PreviewDialog::GetPreviewDialog(); 03202 // If the preview dialog is already open, find the selected frame layer. 03203 BOOL PlayAnimation = TRUE; 03204 if (pPreviewDlg) 03205 { 03206 // Note the current state of the playing 03207 PlayAnimation = pPreviewDlg->GetPlayAnimation(); 03208 // Force the dialog into stop mode 03209 pPreviewDlg->StopPreviewing(); 03210 } 03211 03212 // Create a special Bitmap filter, that creates a bitmap 03213 // and puts it in the tree 03214 ERROR3IF(m_pBitmapFilter != NULL,"Already have a pBitmapFilter!"); 03215 m_pBitmapFilter = new GrabFrameFilter(); 03216 if (m_pBitmapFilter == NULL) 03217 { 03218 // We failed to grab the frame 03219 // Try and put back the selection that we recorded at the start 03220 PutBackTheSelection(); 03221 FailAndExecute(); 03222 End(); 03223 return; 03224 } 03225 03226 // Get the stored cliprect from the spread. 03227 // This may be blank if the frames have not been generated before. 03228 DocRect OldBoundingRect = m_pSpread->GetAnimationBoundingRect(); 03229 // Get the filter to work out the new rectangle 03230 m_pBitmapFilter->SetUpClippingRectangleForExport(m_pSpread, DRAWING); 03231 DocRect NewBoundingRect = m_pBitmapFilter->GetClipRect(); 03232 // Save away the new bounding rectangle 03233 m_pSpread->SetAnimationBoundingRect(NewBoundingRect); 03234 m_ExportParams.SetAnimationBoundingRect(NewBoundingRect); 03235 // If they are different then we must regenerate all frames 03236 BOOL RegenerateAllFrames = ms_ForceRefreshOfAllFrames; // used to be = FALSE (sjk) 03237 ms_ForceRefreshOfAllFrames = FALSE; // have used the force refresh 03238 03239 if (NewBoundingRect != OldBoundingRect) 03240 RegenerateAllFrames = TRUE; 03241 03242 Quality OldQuality = m_pSpread->GetAnimationQuality(); 03243 03244 // AMB doesn't understand what the following lines were meant to do. Quality 03245 // is a linear scale. And in any case this doesn't compile (unsurprisingly) 03246 // Quality NewQuality = m_pView->RenderQuality; 03247 // NewQuality.Antialias = Quality::FullAntialias; 03248 // NewQuality.Transparency = Quality::FullTransparency; 03249 Quality NewQuality(Quality::QualityMax); 03250 03251 // Save away the new quality 03252 m_pSpread->SetAnimationQuality(NewQuality); 03253 if (NewQuality != OldQuality) 03254 RegenerateAllFrames = TRUE; 03255 03256 // Check if somebody has edited the page background layer. If they have then 03257 // regenerate all frames 03258 Layer * pPageBackground = m_pSpread->FindFirstPageBackgroundLayer(); 03259 if (pPageBackground) 03260 { 03261 if (pPageBackground->IsEdited()) 03262 RegenerateAllFrames = TRUE; 03263 } 03264 03265 // If the user has a global optimised palette and they have edited one layer 03266 // then we have really no choice but to always regenerate all frames 03267 // as the user may have changed something that will affect the colours in the palette. 03268 //DITHER Dither; 03269 WEB_PALETTE WebPalette = PAL_GLOBAL; 03270 PALETTE_COLOURS ColoursPalette = PALCOL_BROWSER; 03271 DWORD NumColsInPalette; 03272 m_pSpread->GetAnimationColours(NULL, &WebPalette, &ColoursPalette, &NumColsInPalette, NULL); 03273 if (WebPalette == PAL_GLOBAL && ColoursPalette == PALCOL_OPTIMIZED) 03274 { 03275 // check to see if one of the frame layers has been edited 03276 Layer * pTestLayer = m_pSpread->FindFirstFrameLayer(); 03277 while (pTestLayer) 03278 { 03279 if (pTestLayer->IsEdited() && pTestLayer->IsPseudoFrame()) 03280 { 03281 // Somebody has edited one of the frames so we must regenerate all 03282 RegenerateAllFrames = TRUE; 03283 break; 03284 } 03285 pTestLayer = pTestLayer->FindNextFrameLayer(); 03286 } 03287 } 03288 03289 // Check all the layers to see if they contain a single bitmap which we can use 03290 // instead of generating one. 03291 // This will mark all valid single bitmaps using the reference in the layer 03292 if (!CheckAllForSingleBitmaps(m_pSpread, m_pBitmapFilter)) 03293 { 03294 // Try and put back the selection that we recorded at the start 03295 PutBackTheSelection(); 03296 delete m_pBitmapFilter; 03297 m_pBitmapFilter = NULL; 03298 // We failed to clean up after grabbing the frame 03299 FailAndExecute(); 03300 End(); 03301 return; 03302 } 03303 03304 // As this will affect us during grabbing, we should force it into the known 03305 // non-interferring state 03306 BOOL CurrentVisEdState = Layer::ActiveLayerVisibleAndEditable; 03307 Layer::ActiveLayerVisibleAndEditable = FALSE; 03308 // The all visible flag will also do this for us. 03309 Document* pDoc = m_pSpread->FindParentDocument(); 03310 BOOL CurrentAllVisibleState = FALSE; 03311 if (pDoc != NULL) 03312 { 03313 CurrentAllVisibleState = pDoc->IsAllVisible(); 03314 pDoc->SetAllVisible(FALSE); 03315 } 03316 03317 // SMFIX Do we need a global palette for all the frames? 03318 BOOL CreatingGlobalPalette = (WebPalette == PAL_GLOBAL && ColoursPalette == PALCOL_OPTIMIZED); 03319 03320 03321 // if we are having a global palette then get an optimiser to create one from the bitmaps 03322 if (CreatingGlobalPalette) 03323 CreateGlobalPalette(NumColsInPalette, RegenerateAllFrames); 03324 03325 // Go through all the frame layers in the spread and export them 03326 KernelBitmap * pBitmap = NULL; 03327 Layer* pCurrentLayer = NULL; 03328 03329 // Set the filter to generate output bitmaps 03330 m_pBitmapFilter->SetGrabMode(GrabFrameFilter::GRABMODE_FOROUTPUT); 03331 03332 // go round once unless we are creating a global palette then go round twice 03333 pBitmap = NULL; 03334 pCurrentLayer = m_pSpread->FindFirstFrameLayer(); 03335 03336 while (pCurrentLayer != NULL) 03337 { 03338 // see if the user has hidden the frame 03339 if (!pCurrentLayer->IsPseudoFrame() || pCurrentLayer->IsHiddenFrame()) 03340 { 03341 // It is either an invalid frame or it is hidden. In both cases but especially 03342 // the second we should ensure that if there is a generated bitmap then we 03343 // vape it as it is now out of date. 03344 pCurrentLayer->SetGeneratedBitmap(NULL); 03345 03346 // Move to the next bitmap in the animation 03347 pCurrentLayer = pCurrentLayer->FindNextFrameLayer(); 03348 03349 // Go to the next frame 03350 continue; 03351 } 03352 03353 // Set up the visibility of the other layers using this layer 03354 // as the new temporary and acting active layer 03355 FrameSGallery::FixOtherLayersFromActive(pCurrentLayer); 03356 03357 // This is where the real work starts! 03358 // This is the layer that we want grabbing 03359 m_pLayer = pCurrentLayer; 03360 03361 // Check to see if we have a single bitmap on the layer which is stored 03362 // in a NodeBitmap at a 1:1 scale and is 8bpp or less and the palette matches 03363 // the present options. 03364 // If it passes all these tests, then set pBitmap to be that bitmap. 03365 //if (!CheckIfSingleBitmap(pCurrentLayer, &pBitmap)) 03366 // If there is a referenced bitmap then we can use this instead of generating one 03367 pBitmap = m_pLayer->GetReferencedBitmap(); 03368 if (pBitmap == NULL) 03369 { 03370 // Look to see if we have a bitmap for this layer 03371 KernelBitmap * pOldBitmap = pCurrentLayer->GetGeneratedBitmap(); 03372 03373 // Look to see if any visible foreground layers below this one have 03374 // been edited 03375 BOOL LayersBelowEdited = FALSE; 03376 // Only check if we are not already forced to regnerate all frames 03377 if (!RegenerateAllFrames) 03378 { 03379 Layer * pTestLayer = pCurrentLayer; 03380 pTestLayer = pTestLayer->FindPrevFrameLayer(); 03381 while (pTestLayer) 03382 { 03383 // Dont disclude hidden frames as they can affect the make up of the current frame 03384 if (pTestLayer->IsEdited() && pTestLayer->IsPseudoFrame() && 03385 pTestLayer->IsVisible()) 03386 { 03387 LayersBelowEdited = TRUE; 03388 break; 03389 } 03390 pTestLayer = pTestLayer->FindPrevFrameLayer(); 03391 } 03392 } 03393 03394 // we are getting the bitmaps themselves 03395 // check that the quality it was last captured at was the same as the current quality 03396 Quality CurrentFrameQuality = pCurrentLayer->GetCaptureQuality(); 03397 03398 // For a number of reasons we may need to regenerate the bitmap for this frame 03399 // If nay are true then regenerate, otherwise reuse the old one 03400 if (pOldBitmap == NULL || LayersBelowEdited || RegenerateAllFrames || 03401 pCurrentLayer->IsEdited() || CurrentFrameQuality != NewQuality) 03402 { 03403 // Turn this frame into a bitmap 03404 pBitmap = GrabTheFrame(); 03405 } 03406 else 03407 { 03408 // Reuse the old bitmap that was generated 03409 pBitmap = pOldBitmap; 03410 03411 // test to see that this bitmap uses the correct palette if required 03412 // otherwise we will have to grab it anyway 03413 if (CreatingGlobalPalette) 03414 { 03415 // compare palettes 03416 LOGPALETTE * pGlobalPalette = m_pBitmapFilter->GetGlobalOptimisedPalette(); 03417 if (!pBitmap->GetActualBitmap()->ArePalettesTheSame(pGlobalPalette, 0)) 03418 { 03419 // NOTE: This happens when the preview window has just gone and generated a bitmap 03420 // using a locally optimal palette rather than our globally optimal palette and in 03421 // the process it has replaced our cache version with its dodgy bitmap. 03422 TRACEALL( _T("Bum bitmap passed to us with wrong palette, grab a fresh one")); 03423 pBitmap = GrabTheFrame(); 03424 } 03425 } 03426 } 03427 } 03428 03429 BOOL bAddLayer = pBitmap != 0; 03430 if (bAddLayer) 03431 { 03432 // We have a bitmap so add this layer pairing to our export list 03433 bAddLayer = m_ExportParams.AddLayerAndBitmap(pCurrentLayer, pBitmap); 03434 } 03435 03436 if (!bAddLayer) 03437 { 03438 // We failed to grab the frame or failed to add it to our export list 03439 03440 // Put back the active layer's visibilty and selection 03441 Layer::ActiveLayerVisibleAndEditable = CurrentVisEdState; 03442 FrameSGallery::FixOtherLayersFromActive(m_pLayer); 03443 // Try and put back the selection that we recorded at the start 03444 PutBackTheSelection(); 03445 FailAndExecute(); 03446 End(); 03447 return; 03448 } 03449 03450 //TRACEUSER( "SimonK", _T("colours in frame %d\n"), pBitmap->GetNumPaletteEntries()); 03451 03452 // Note the capture quality that the frame was captured at but only if we worked correctly 03453 pCurrentLayer->SetCaptureQuality(NewQuality); 03454 03455 // Move to the next bitmap in the animation 03456 pCurrentLayer = pCurrentLayer->FindNextFrameLayer(); 03457 } 03458 03459 // Put back the active layer's visibilty and selection 03460 Layer::ActiveLayerVisibleAndEditable = CurrentVisEdState; 03461 03462 // Put back the all visible state 03463 if (pDoc != NULL) 03464 pDoc->SetAllVisible(CurrentAllVisibleState); 03465 03466 Layer *pActiveLayer = m_pSpread->FindActiveLayer(); 03467 if (pActiveLayer) 03468 FrameSGallery::FixOtherLayersFromActive(pActiveLayer); 03469 03470 // Go and mark all layers as not edited now that we have finished the grabbing 03471 // process 03472 Layer* pLayer = m_pSpread->FindFirstFrameLayer(); 03473 while (pLayer != NULL) 03474 { 03475 // This is just as a double check 03476 if (pLayer->IsPseudoFrame()) 03477 { 03478 // Clear the edited flag on the layer 03479 pLayer->SetEdited(FALSE); 03480 #ifdef _DEBUG 03481 // Tell the frame gallery to update its display of the frame 03482 BROADCAST_TO_ALL(LayerMsg(pLayer, LayerMsg::REDRAW_LAYER)); 03483 #endif 03484 } 03485 03486 // Move to the next frame layer in the animation 03487 pLayer = pLayer->FindNextFrameLayer(); 03488 } 03489 03490 // If we found a page background layer above, now mark it as not edited 03491 if (pPageBackground) 03492 pPageBackground->SetEdited(FALSE); 03493 03494 // Clean up after the grabbing process 03495 if (!EndGrab()) 03496 { 03497 // We failed to clean up after grabbing the frame 03498 delete m_pBitmapFilter; 03499 m_pBitmapFilter = NULL; 03500 FailAndExecute(); 03501 End(); 03502 return; 03503 } 03504 03505 03506 // Grab all frames should usually play the animation. 03507 // If the preview dialog is open and in stop mode then it should continue in stop mode. 03508 // In this case we should have noted this before calling stop at the start of this function 03509 // So up the play state we noted earlier before we preview 03510 PreviewDialog * pPreviewDialog = PreviewDialog::GetPreviewDialog(); 03511 INT32 CurrentFrame = 0; 03512 if (pPreviewDialog != NULL) 03513 { 03514 pPreviewDialog->SetPlayAnimation(PlayAnimation); 03515 CurrentFrame = pPreviewDialog->GetCurrentItem(); 03516 } 03517 03518 // Fire up the preview dialog box with the bitmaps in our list 03519 if (!PreviewAnimation()) 03520 { 03521 // We failed to preview the bitmap 03522 delete m_pBitmapFilter; 03523 m_pBitmapFilter = NULL; 03524 FailAndExecute(); 03525 End(); 03526 return; 03527 } 03528 03529 // If the dialog is still there then select the new frame to be displayed 03530 // Default is frame 0 so only do it if the requested item is different to this 03531 pPreviewDialog = PreviewDialog::GetPreviewDialog(); 03532 if (pPreviewDialog && CurrentFrame != 0) 03533 pPreviewDialog->SelectCurrentFrame(CurrentFrame); 03534 03535 // remove the filter as we have no more use for it 03536 delete m_pBitmapFilter; 03537 m_pBitmapFilter = NULL; 03538 03539 End(); 03540 return; 03541 } 03542 03543 /******************************************************************************************** 03544 // End of OpGrabAllFrames 03545 ********************************************************************************************/ 03546 03547 //----------------------------------------------------------------------------------------------- 03548 // GrabFrameFilter - Dummy filter, used to render the selection into a bitmap 03549 //----------------------------------------------------------------------------------------------- 03550 03551 /******************************************************************************************** 03552 03553 > GrabFrameFilter::GrabFrameFilter() 03554 03555 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03556 Created: 24/4/97 03557 Purpose: Constructor for an GrabFrameFilter object. The object should be initialised 03558 before use. 03559 03560 ********************************************************************************************/ 03561 03562 GrabFrameFilter::GrabFrameFilter() 03563 { 03564 pTheBitmap = NULL; 03565 m_pLayer = NULL; 03566 m_pOptimisedPalette = NULL; 03567 m_pMkBmpOptions = NULL; 03568 m_pCopyMkBmpOptions = NULL; 03569 m_GrabMode = GRABMODE_FOROUTPUT; 03570 03571 // Override this to say something more useful 03572 ExportingMsgID = _R(IDS_EXPORTINGANIMATEDGIF); // "Exporting animated GIF file..." 03573 } 03574 03575 /******************************************************************************************** 03576 03577 > GrabFrameFilter::GrabFrameFilter() 03578 03579 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03580 Created: 9/6/97 03581 Purpose: Destructor for an GrabFrameFilter object. 03582 ********************************************************************************************/ 03583 03584 GrabFrameFilter::~GrabFrameFilter() 03585 { 03586 if (m_pOptimisedPalette != NULL) 03587 { 03588 CCFree(m_pOptimisedPalette); 03589 m_pOptimisedPalette = NULL; 03590 } 03591 if (m_pCopyMkBmpOptions != NULL) 03592 { 03593 delete m_pCopyMkBmpOptions; 03594 m_pCopyMkBmpOptions = NULL; 03595 } 03596 } 03597 03598 /******************************************************************************************** 03599 03600 > virtual BOOL GrabFrameFilter::GenerateOptimisedPalette(Spread *pSpread, UINT32 Depth, double DPI, 03601 BOOL SnapToBrowserPalette, UINT32 NumColsInPalette, 03602 BOOL UsePrimaryCols) 03603 03604 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> based on Will code 03605 Created: 9/6/97 03606 Inputs: pSpread = ptr to spread 03607 Depth = The BPP of the bitmap 03608 DPI = the dpi of the bitmap 03609 NumColsInPalette = prefered number of cols in palette (0 = select maximum allowed) 03610 (only applies when Depth == 8) 03611 UsePrimaryCols = Put primary colours in palette 03612 (only applies when Depth == 8) 03613 SnapToBrowserPalette= TRUE if the palette should be snapped to the browser palette after generation 03614 03615 Returns: TRUE if Palette generated ok 03616 Purpose: Generates an optimised palette to use during export 03617 We override the baseclass form so that we generate one optimised palette for 03618 all frames if we are in global optimised mode. 03619 Otherwise, we can just call the base class version. 03620 SeeAlso: - 03621 03622 ********************************************************************************************/ 03623 03624 BOOL GrabFrameFilter::GenerateOptimisedPalette(Spread *pSpread, UINT32 Depth, double DPI, 03625 BOOL SnapToBrowserPalette, UINT32 NumColsInPalette, BOOL UsePrimaryCols) 03626 03627 { 03628 03629 // SMFIX it will pick a valid palette as it goes along 03630 // optimal palettes are no longer created in this manner 03631 // sjk 03632 03633 return TRUE; 03634 } 03635 03636 /******************************************************************************************** 03637 03638 > BOOL GrabFrameFilter::SetLayerBeingCaptured(Layer * pNewLayer) 03639 03640 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03641 Created: 7/5/97 03642 Inputs: pNewLayer the layer which is being captured. 03643 Purpose: This remembers the layer that is being captured. It sets the member variable 03644 up to the specified layer. 03645 03646 ********************************************************************************************/ 03647 03648 BOOL GrabFrameFilter::SetLayerBeingCaptured(Layer * pNewLayer) 03649 { 03650 m_pLayer = pNewLayer; 03651 return TRUE; 03652 } 03653 03654 /******************************************************************************************** 03655 03656 > virtual BOOL GrabFrameFilter::SetUpClippingRectangleForExport(Spread *pSpread, SelectionType Selection) 03657 03658 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03659 Created: 29/4/97 03660 Inputs: pSpread the spread to export 03661 Selection the selection type to use during export 03662 Returns: TRUE if the operation was successful 03663 FALSE otherwise 03664 Purpose: Sets up the class variable ClipRect to be the clipping rectangle to be used 03665 during export. 03666 See Also: PrepareToExport() 03667 03668 ********************************************************************************************/ 03669 03670 BOOL GrabFrameFilter::SetUpClippingRectangleForExport(Spread *pSpread, SelectionType Selection) 03671 { 03672 ERROR2IF(pSpread == NULL,FALSE,"SetUpClippingRectangleForExport Bad spread"); 03673 03674 // Make an empty rect to start with in the class variable 03675 ClipRect.MakeEmpty(); 03676 03677 // Walk through all the frame layers and work out the bounding boxes of each 03678 Layer* pCurrentLayer = pSpread->FindFirstFrameLayer(); 03679 Layer* pNextLayer = NULL; 03680 while (pCurrentLayer != NULL) 03681 { 03682 pNextLayer = pCurrentLayer->FindNextFrameLayer(); 03683 // Double check that it is a suitable frame layer and check it is not hidden 03684 if (pCurrentLayer->IsPseudoFrame()) 03685 { 03686 // Cannot include a simple hidden check as the purpose of hidden frames is to 03687 // act as backgrounds for the animation. Could check for hidden and solid but 03688 // would also need to check for an overlay onto the hidden frame 03689 if ( 03690 (!pCurrentLayer->IsHiddenFrame()) || 03691 (pCurrentLayer->IsHiddenFrame() && pCurrentLayer->IsSolid()) || 03692 (pCurrentLayer->IsHiddenFrame() && pNextLayer && pNextLayer->IsOverlay()) 03693 ) 03694 { 03695 // Get the bounding rect for this layer 03696 DocRect LayerRect = pCurrentLayer->GetBoundingRect(); 03697 // Add this to our clipping rectangle 03698 ClipRect = ClipRect.Union(LayerRect); 03699 } 03700 } 03701 03702 // Move to the next bitmap in the animation 03703 pCurrentLayer = pNextLayer; 03704 } 03705 03706 return TRUE; 03707 } 03708 03709 /******************************************************************************************** 03710 03711 > virtual BOOL GrabFrameFilter::GetExportOptions(BitmapExportOptions* pOptions) 03712 03713 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03714 Created: 24/4/97 03715 Purpose: See BaseBitmapFilter for interface details 03716 03717 ********************************************************************************************/ 03718 03719 BOOL GrabFrameFilter::GetExportOptions(BitmapExportOptions* pOptions) 03720 { 03721 ERROR2IF(pOptions == NULL, FALSE, "pOptions NULL"); 03722 ERROR3IF(!pOptions->IS_KIND_OF(MakeBitmapExportOptions), "pOptions isn't of type MakeBitmapExportOptions"); 03723 03724 m_pMkBmpOptions = (MakeBitmapExportOptions*) pOptions; 03725 03726 // Determine the filter type currently in use in Accusoft format 03727 s_FilterType = MAKE_BITMAP_FILTER; 03728 03729 // Force the selection type to be DRAWING as this should render all visible objects 03730 m_pMkBmpOptions->SetSelectionType(DRAWING); 03731 03732 m_pMkBmpOptions->SetDPI(96.0); 03733 03734 if (m_GrabMode == GRABMODE_PREVIEW) 03735 { 03736 // We want a 24bbp bitmap to pass to Gavin's code but using 32bbp to 03737 // store each pixel (ie the 4 channel of each pixel is waste). This 03738 // should do the trick. 03739 m_pMkBmpOptions->SetDepth(24); 03740 } 03741 else 03742 { 03743 // Force the depth to be 8bpp 03744 m_pMkBmpOptions->SetDepth(8); 03745 } 03746 03747 // Force the interlacing off 03748 m_pMkBmpOptions->SetMakeInterlaced(FALSE); 03749 03750 // Force the transparency to on. 03751 //m_pMkBmpOptions->SetMakeTransparent(TRUE); 03752 03753 // recover the relevant animation options from the spread 03754 if (pSpread) 03755 { 03756 DWORD Loop = 0; 03757 DWORD GlobalDelay = 10; 03758 DITHER Dither = XARADITHER_ORDERED_GREY; 03759 WEB_PALETTE WebPalette = PAL_GLOBAL; 03760 PALETTE_COLOURS ColoursPalette = PALCOL_BROWSER; 03761 DWORD NumColsInPalette = 255; 03762 BOOL UseSystemColours = FALSE; 03763 // Ask the spread for its version of these values 03764 pSpread->GetSpreadAnimPropertiesParam(&Loop, &GlobalDelay, &Dither, &WebPalette, 03765 &ColoursPalette, &NumColsInPalette, &UseSystemColours, NULL); 03766 03767 // set to use background transp if it is set in the animation properties dlg 03768 m_pMkBmpOptions->SetBackgroundTransparency(pSpread->GetSpreadAnimPropertiesParam().GetIsBackGroundTransp()); 03769 03770 // Ensure the dependent options are set correctly 03771 // There are 20 colours in the system palette 03772 switch (ColoursPalette) 03773 { 03774 case PALCOL_STANDARD: 03775 case PALCOL_BROWSER: 03776 // Fixed browser palette 03777 // SMFIX we want a browser palette 03778 m_pMkBmpOptions->SetToUseBrowserPalette(TRUE); 03779 m_pMkBmpOptions->CreateValidBrowserPalette(TRUE); 03780 // set this as the palette being used in output dib 03781 AlterPaletteContents(m_pMkBmpOptions->GetLogicalPalette()); 03782 break; 03783 03784 case PALCOL_OPTIMIZED: 03785 // Optimised, so take the user's chosen number of required colours 03786 // Check if local or globally optimised 03787 /* if (WebPalette == PAL_GLOBAL) 03788 TRACEUSER( "SimonK", _T("PAL_GLOBALOPTIMISED\n")); 03789 else 03790 TRACEUSER( "SimonK", _T("PAL_OPTIMISED\n")); 03791 */ //m_pMkBmpOptions->SetNumColsInPalette(NumColsInPalette); 03792 // store the number of user defined colours in the options 03793 m_pMkBmpOptions->SetNumberOfUserRequestedColours(NumColsInPalette); 03794 // In optimised mode we cannot have ordered dithering as it 03795 // must have a known palette. So switch the dithering to error 03796 // diffusion. 03797 if (Dither == XARADITHER_ORDERED_GREY) 03798 Dither = XARADITHER_ERROR_DIFFUSION; 03799 03800 // Set up whether we save system colours or not 03801 //m_pMkBmpOptions->SetUseSystemColours(UseSystemColours); 03802 //m_pMkBmpOptions->SetToUseSystemPalette(UseSystemColours); 03803 break; 03804 default: 03805 ERROR3("Bad ColoursPalette option"); 03806 break; 03807 } 03808 03809 switch (WebPalette) 03810 { 03811 case PAL_GLOBAL: 03812 // If global set then must be browser palette selected 03813 //TRACEUSER( "SimonK", _T("PAL_GLOBAL\n")); 03814 // ColoursPalette = PALCOL_BROWSER; 03815 // use the global palette here 03816 if (GetGlobalOptimisedPalette()) 03817 { 03818 m_pMkBmpOptions->CreateValidPalette(GetGlobalOptimisedPalette(), 03819 m_pMkBmpOptions->IsBackgroundTransparent() ? 0 : -1); 03820 // set this as the palette being used in output dib 03821 AlterPaletteContents(m_pMkBmpOptions->GetLogicalPalette()); 03822 } 03823 break; 03824 case PAL_LOCAL: 03825 // If local palette selected then must be optimised as 03826 // no point saving out a global palette 03827 //TRACEUSER( "SimonK", _T("PAL_LOCAL\n")); 03828 // ColoursPalette = PALCOL_OPTIMIZED; 03829 // SMFIX 03830 // if we are the first frame generate a new valid palette 03831 // we could use that as a first guess at a global palette 03832 // but we do know that if we do not have a global palette we 03833 // should be getting a different palette for each frame 03834 m_pMkBmpOptions->InvalidatePalette(); 03835 break; 03836 default: 03837 ERROR3("Bad WebPalette option"); 03838 break; 03839 } 03840 03841 // Set up the dithering that we are going to use 03842 m_pMkBmpOptions->SetDither(Dither); 03843 } 03844 03845 03846 // We have all the options that we require so don't ask the user for anything 03847 03848 // Take a copy of these options for latter use (Browser Preview) 03849 if (m_pCopyMkBmpOptions == NULL) 03850 { 03851 m_pCopyMkBmpOptions = (MakeBitmapExportOptions *)m_pMkBmpOptions->MakeCopy(); 03852 // don't complain about null as only required by browser preview at present 03853 } 03854 03855 // All ok 03856 return TRUE; 03857 } 03858 03859 /******************************************************************************************** 03860 03861 > virtual BOOL GrabFrameFilter::SetupExportOptions(BitmapExportOptions* pOptions, Spread * pCurrentSpread) 03862 03863 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03864 Created: 4/8/97 03865 Inputs: pCurrentSpread The spread we are currently working with 03866 Purpose: This is just a public interface on the normal filter's GetExportOptions which is protected. 03867 It also ensures that the pSpread is set up. 03868 03869 ********************************************************************************************/ 03870 03871 BOOL GrabFrameFilter::SetupExportOptions(BitmapExportOptions* pOptions, Spread * pCurrentSpread) 03872 { 03873 // Ensure that the spread pointer is set up 03874 // If we haven't actually grabbed any frames then it will be NULL 03875 pSpread = pCurrentSpread; 03876 // Set up those export options 03877 return GetExportOptions(pOptions); 03878 } 03879 03880 03881 /******************************************************************************************** 03882 03883 > virtual KernelBitmap* GrabFrameFilter::GetTheBitmap() 03884 03885 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03886 Created: 24/4/97 03887 Purpose: Creates a kernel bitmap from the Export RenderRegion 03888 Overrides the baseclass version as that uses MakeKernelBitmap which does 03889 check to see if the OIL bitmap pointers are the same but does not check that 03890 the contents are the same. This means we end up with duplicated versions. 03891 This is bad. We use TryAndUseExistingBitmap which does this extra check. 03892 This is ok in the Creat bitmap copy case as this is the only way to generate 03893 duplicate frames. 03894 Returns: Ptr to the bitmap, or NULL if error 03895 03896 Note: 03897 We cannot even do it this way as 03898 a) the code which checks for duplicates in the global bitmap list complains as the bitmap 03899 is already attached to the list 03900 b) even after this, using the TryAndUseExistingBitmap does not reuse the existing bitmap 03901 So try plan c. Add the extra code to ExtractBitmapCopy so when it tries to attach the oilbitmap 03902 it sees if it is reusing an existing bitmap. If so then it will just return the existing bitmap 03903 rather than adding a new duplicate to the system. 03904 ********************************************************************************************/ 03905 03906 KernelBitmap* GrabFrameFilter::GetTheBitmap() 03907 { 03908 // Extract a copy of the bitmap from the RenderRegion 03909 // We need to generate new bitmaps as we delete them and also name them ourselves. 03910 BOOL LookForDuplicates = FALSE; 03911 OILBitmap* pOilBitmap = ExportRegion->ExtractBitmapCopy(pOptimisedPalette, pDestBMInfo, pDestBMBytes, 03912 TransColour, LookForDuplicates); 03913 03914 if (pOilBitmap == NULL) 03915 { 03916 CleanUpAfterExport(); 03917 return NULL; 03918 } 03919 03920 if (m_pLayer) 03921 { 03922 // Make the bitmap name the layer name 03923 String_256 Name = m_pLayer->GetLayerID(); 03924 pOilBitmap->SetName(Name); 03925 03926 // Copy across the delay from the layer 03927 DWORD delay = m_pLayer->GetFrameDelay(); 03928 pOilBitmap->SetBitmapAnimDelay(delay); 03929 03930 // As all these frames are complete, we output them using 03931 // a replace background restore type. 03932 // It is only later that we may do some trickery on them so that 03933 // we can overlay them. 03934 pOilBitmap->SetAnimationRestoreType(GDM_BACKTOBACK); 03935 03936 // The exception is if the frame is solid in which case we invariably 03937 // want that one to overlay 03938 //if (m_pLayer->IsSolid()) 03939 // pOilBitmap->SetAnimationRestoreType(GDM_LEAVE); 03940 //else 03941 } 03942 03943 // Make a kernel bitmap from the oily one 03944 // The class variable pDocument should be holding the document required 03945 // Must check it as TryAndUseExistingBitmap does not! 03946 // ERROR2IF(TheDocument == NULL,NULL,"GrabFrameFilter::GetTheBitmap null document") 03947 // BOOL IsNew = TRUE; 03948 // return KernelBitmap::TryAndUseExistingBitmap(pOilBitmap, TheDocument, &IsNew); 03949 return KernelBitmap::MakeKernelBitmap(pOilBitmap, TheDocument); 03950 } 03951 03952 /******************************************************************************************** 03953 03954 > virtual BOOL GrabFrameFilter::ExportVisibleLayersOnly() 03955 03956 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03957 Created: 29/04/97 03958 Inputs: - 03959 Outputs: - 03960 Returns: True if this filter wants to exclude invisible layers and so export only 03961 visible items Or False if want to export everything. 03962 Purpose: Determines if the filter wants to export only visible layers. 03963 In the base bitmap filters class version the default action will be to 03964 export only those layers which are visible. 03965 SeeAlso: Filter::ExportRender; 03966 03967 ********************************************************************************************/ 03968 03969 BOOL GrabFrameFilter::ExportVisibleLayersOnly() 03970 { 03971 #ifdef DO_EXPORT 03972 MaskedFilterExportOptions* pMaskedOptions = (MaskedFilterExportOptions*)GetBitmapExportOptions(); 03973 ERROR2IF(pMaskedOptions == NULL, FALSE, "NULL Args"); 03974 ERROR3IF(!pMaskedOptions->IS_KIND_OF(MaskedFilterExportOptions), "pMaskedOptions isn't"); 03975 03976 ERROR2IF(pSpread == NULL, FALSE,"GrabFrameFilter::VisibleLayersOnly no spread to export"); 03977 03978 // We always want to export oONLY the visible layers. 03979 // When we are exporting in transparent mode and making up the mask, we must go and set the 03980 // page background layer to be invisible 03981 // We are just taking the oppurtunity that this call gives us to fix up the page background 03982 // layer to be invisible 03983 if (pMaskedOptions->WantTransparent() && !SecondPass && !GeneratingOptimisedPalette()) 03984 { 03985 // Masking operation 03986 // If we find a page background layer then make sure it is invisible 03987 Layer * pLayer = pSpread->FindFirstPageBackgroundLayer(); 03988 if (pLayer) 03989 pLayer->SetVisible(FALSE); 03990 } 03991 else 03992 { 03993 // Normal export operation 03994 // If we find a page background layer then make sure it is visible 03995 Layer * pLayer = pSpread->FindFirstPageBackgroundLayer(); 03996 if (pLayer) 03997 pLayer->SetVisible(TRUE); 03998 } 03999 04000 // only include all layer that are visible in this bitmap export 04001 return TRUE; 04002 #else 04003 // only include all layer that are visible in this bitmap export 04004 return TRUE; 04005 #endif 04006 } 04007 04008 04009 /******************************************************************************************** 04010 04011 > virtual BOOL GrabFrameFilter::ExportSelectionOnly() 04012 04013 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04014 Created: 29/04/97 04015 Returns: True if this filter wants check if an object is selected or not and so export 04016 only the selected items Or False if want to export everything. 04017 Purpose: Determines if the filter wants to export only selected items. 04018 In the base bitmap filters class version the default action will be to 04019 export all objects by default 04020 SeeAlso: Filter::ExportRender; 04021 04022 ********************************************************************************************/ 04023 04024 BOOL GrabFrameFilter::ExportSelectionOnly(BOOL MaskedRender) 04025 { 04026 // We always export all the objects 04027 return FALSE; 04028 } 04029 04030 /******************************************************************************************** 04031 04032 > BOOL GrabFrameFilter::IsSecondPassRequired() 04033 04034 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04035 Created: 29/04/97 04036 Returns: True if this filter wants a second export rendering pass and so have a chance 04037 to setup semething like a mask. 04038 Purpose: Determines if the a second rendering pass is required or not. 04039 04040 ********************************************************************************************/ 04041 04042 BOOL GrabFrameFilter::IsSecondPassRequired() 04043 { 04044 #ifdef DO_EXPORT 04045 MaskedFilterExportOptions* pMaskedOptions = (MaskedFilterExportOptions*)GetBitmapExportOptions(); 04046 ERROR2IF(pMaskedOptions == NULL, FALSE, "NULL Args"); 04047 ERROR3IF(!pMaskedOptions->IS_KIND_OF(MaskedFilterExportOptions), "pMaskedOptions isn't"); 04048 04049 // Only require a second pass if wanting transparency 04050 if (pMaskedOptions->WantTransparent()) 04051 return TRUE; 04052 else 04053 return FALSE; 04054 #else 04055 return FALSE; 04056 #endif 04057 } 04058 04059 04060 /******************************************************************************************** 04061 04062 > virtual BOOL GrabFrameFilter::DoExportBitmaps(Operation* pOp, CCLexFile* pFile, PathName* pPath, 04063 BitmapExportParam* pParam, BOOL DontShowFileName = FALSE) 04064 04065 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04066 Created: 30/04/97 04067 Inputs: pOp - the operation that started the export off 04068 pDiskFile - the file to put the exported data into 04069 pPath - the pathname of the file to be exported to 04070 pParam - the data to use when exporting the bitmaps 04071 Returns: TRUE if worked, FALSE if failed. 04072 Purpose: Exports the bitmaps specified by the BitmapExportParam object to a multi- 04073 image capable filter. 04074 04075 ********************************************************************************************/ 04076 04077 BOOL GrabFrameFilter::DoExportBitmaps(Operation *pOp, CCLexFile* pFile, PathName* pPath, 04078 BitmapExportParam* pParam, BOOL DontShowFileName) 04079 { 04080 #ifdef DO_EXPORT 04081 ERROR2IF(pOp == NULL || pFile == NULL || pPath == NULL, FALSE,"NULL Parameters"); 04082 ERROR2IF(pParam == NULL,FALSE,"GrabFrameFilter::DoExportBitmaps null BitmapExportParam specified"); 04083 04084 // We could just call the function direct but this may give us some more functionality 04085 // in the long term 04086 return SaveExportBitmapsToFile(pFile, pPath, pParam, DontShowFileName); 04087 #endif 04088 return FALSE; 04089 } 04090 04091 04092 /******************************************************************************************** 04093 04094 > void GrabFrameFilter::SetGlobalOptimisedPalette(LPLOGPALETTE pOptimisedPalette) 04095 04096 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04097 Created: 09/07/97 04098 Inputs: pOptimisedPalette - the new global optimised palette 04099 Returns: TRUE if worked, FALSE if failed. 04100 Purpose: Sets up a new optimised palette ready to be applied to all frames in the 04101 animation. Should be used with care. 04102 At present, only used if we discover that all frames contain compatible 04103 bitmaps that have the same palette on them. 04104 04105 ********************************************************************************************/ 04106 04107 void GrabFrameFilter::SetGlobalOptimisedPalette(LPLOGPALETTE pOptimisedPalette) 04108 { 04109 if (m_pOptimisedPalette != NULL) 04110 { 04111 CCFree(m_pOptimisedPalette); 04112 m_pOptimisedPalette = NULL; 04113 } 04114 04115 m_pOptimisedPalette = pOptimisedPalette; 04116 } 04117 04118 /******************************************************************************************** 04119 04120 > virtual UINT32 GrabFrameFilter::GetExportMsgID() 04121 04122 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04123 Created: 28/07/97 04124 Returns: The id of the message to put on the progress display whilst exporting. 04125 Purpose: Used to get the message id to be used during export. 04126 Virtual, so that two stage exporters can change the message. 04127 SeeAlso: DoExport; 04128 04129 ********************************************************************************************/ 04130 04131 UINT32 GrabFrameFilter::GetExportMsgID() 04132 { 04133 // Always return this message regardless of the stage that we are on 04134 return _R(IDS_GENERATINGFRAMES); // "Generating animation frames..." 04135 } 04136 04137 /******************************************************************************************** 04138 // End of GrabFrameFilter 04139 ********************************************************************************************/ 04140 04141 //------------------------------------------------------------------------------------------ 04142 // GIFAnimationExportParam 04143 //------------------------------------------------------------------------------------------ 04144 04145 /******************************************************************************************** 04146 04147 > GIFAnimationExportParam::GIFAnimationExportParam() 04148 04149 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04150 Created: 13/05/97 04151 Purpose: Default constructor 04152 04153 ********************************************************************************************/ 04154 04155 GIFAnimationExportParam::GIFAnimationExportParam() 04156 { 04157 m_BitmapCount = 0; 04158 m_pBitmaps = NULL; 04159 04160 m_LayerCount = 0; 04161 m_pLayers = NULL; 04162 04163 m_RegeneratedBitmapPosition = 0; 04164 } 04165 04166 /******************************************************************************************** 04167 04168 > GIFAnimationExportParam::~GIFAnimationExportParam() 04169 04170 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04171 Created: 13/05/97 04172 Purpose: Default destructor 04173 04174 ********************************************************************************************/ 04175 04176 GIFAnimationExportParam::~GIFAnimationExportParam() 04177 { 04178 // free up the arrays that we grabbed 04179 if (m_pBitmaps != NULL) 04180 { 04181 CCFree(m_pBitmaps); 04182 m_pBitmaps = NULL; 04183 m_BitmapCount = 0; 04184 } 04185 if (m_pLayers != NULL) 04186 { 04187 CCFree(m_pLayers); 04188 m_pLayers = NULL; 04189 m_LayerCount = 0; 04190 } 04191 } 04192 04193 /******************************************************************************************** 04194 04195 > GIFAnimationExportParam::GIFAnimationExportParam(UINT32 Count, KernelBitmap** pBitmap) 04196 04197 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04198 Created: 13/05/97 04199 Inputs: Count - The number of indexes in the array 04200 pBitmap - pointer to an array of pointers to kernel bitmaps 04201 Outputs: - 04202 Returns: - 04203 Purpose: Used to pass around lists of bitmaps. Note that deleting the bitmap array 04204 is the responsibility of the caller. 04205 ********************************************************************************************/ 04206 04207 GIFAnimationExportParam::GIFAnimationExportParam(UINT32 Count, KernelBitmap** pBitmap) 04208 { 04209 ERROR3IF(Count == 0, "Zero bitmap count, that's not right"); 04210 ERROR3IF(pBitmap == NULL, "NULL bitmap array"); 04211 ERROR3IF(!(*pBitmap)->IS_KIND_OF(KernelBitmap), "This dosen't seem to be an array of kernel bitmaps"); 04212 04213 m_BitmapCount = Count; 04214 m_pBitmaps = pBitmap; 04215 04216 // set up everything else to defaults 04217 m_RegeneratedBitmapPosition = 0; 04218 m_LayerCount = 0; 04219 m_pLayers = NULL; 04220 } 04221 04222 /******************************************************************************************** 04223 04224 > virtual UINT32 GIFAnimationExportParam::GetBitmapCount() 04225 04226 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04227 Created: 13/05/97 04228 Returns: The number of bitmaps in the bitmap array. (The array runs 0..Count-1) 04229 Purpose: For getting the number of bitmaps in the array! 04230 04231 ********************************************************************************************/ 04232 04233 UINT32 GIFAnimationExportParam::GetBitmapCount() 04234 { 04235 return m_BitmapCount; 04236 } 04237 04238 /******************************************************************************************** 04239 04240 > virtual KernelBitmap* GIFAnimationExportParam::GetBitmap(UINT32 Index) 04241 04242 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04243 Created: 13/05/97 04244 Inputs: Index - the index of the required bitmap 04245 Outputs: - 04246 Returns: Pointer to the nth bitmap, NULL if error 04247 Purpose: For safely getting a pointer to a bitmap in the bitmap array 04248 04249 ********************************************************************************************/ 04250 04251 KernelBitmap* GIFAnimationExportParam::GetBitmap(UINT32 Index) 04252 { 04253 ERROR2IF(Index >= m_BitmapCount, NULL, "Index out of bounds"); 04254 ERROR2IF(m_pBitmaps == NULL, NULL, "NULL array"); 04255 04256 ERROR3IF(!(m_pBitmaps[Index])->IS_KIND_OF(KernelBitmap), "This dosen't seem to be a pointer to a kernel bitmap"); 04257 return m_pBitmaps[Index]; 04258 } 04259 04260 04261 /******************************************************************************************** 04262 04263 > virtual UINT32 GIFAnimationExportParam::GetLayerCount() 04264 04265 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04266 Created: 13/05/97 04267 Returns: The number of bitmaps/layers in the layers/bitmap array. (The array runs 0..Count-1) 04268 Purpose: For getting the number of layers/bitmaps in the array! 04269 04270 ********************************************************************************************/ 04271 04272 UINT32 GIFAnimationExportParam::GetLayerCount() 04273 { 04274 return m_LayerCount; 04275 } 04276 04277 /******************************************************************************************** 04278 04279 > virtual Layer * GIFAnimationExportParam::GetLayer(UINT32 Index) 04280 04281 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04282 Created: 13/05/97 04283 Inputs: Index - the index of the required bitmap 04284 Outputs: - 04285 Returns: Pointer to the nth bitmap, NULL if error 04286 Purpose: For safely getting a pointer to a bitmap in the bitmap array 04287 04288 ********************************************************************************************/ 04289 04290 Layer* GIFAnimationExportParam::GetLayer(UINT32 Index) 04291 { 04292 ERROR2IF(Index >= m_LayerCount, NULL, "Index out of bounds"); 04293 ERROR2IF(m_pLayers == NULL, NULL, "NULL array"); 04294 04295 ERROR3IF(!(m_pLayers[Index])->IS_KIND_OF(Layer), "This dosen't seem to be a pointer to a layer"); 04296 return m_pLayers[Index]; 04297 } 04298 04299 /******************************************************************************************** 04300 04301 > virtual BOOL GIFAnimationExportParam::AddLayerAndBitmap(Layer * pLayer, KernelBitmap * pBitmap) 04302 04303 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04304 Created: 13/05/97 04305 Inputs: pLayer the layer to be added to the list/array 04306 pBitmap the bitmap associated with this layer to be added to the list/array 04307 Returns: True if worked ok, False otherwise. 04308 Purpose: For adding a layer to list ready for exporting the GIF animation. 04309 Uses the class variables m_pLayers and m_LayerCount. 04310 04311 ********************************************************************************************/ 04312 04313 BOOL GIFAnimationExportParam::AddLayerAndBitmap(Layer * pLayer, KernelBitmap * pBitmap) 04314 { 04315 // Let the called functions do the parameter checking! 04316 return AddLayer(pLayer) && AddBitmap(pBitmap); 04317 } 04318 04319 /******************************************************************************************** 04320 04321 > virtual BOOL GIFAnimationExportParam::AddLayer(Layer * pLayer) 04322 04323 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04324 Created: 13/05/97 04325 Inputs: pLayer the layer to be added to the list/array 04326 Outputs: - 04327 Returns: True if worked ok, False otherwise. 04328 Purpose: For adding a layer to list ready for exporting the GIF animation. 04329 Uses the class variables m_pLayers and m_LayerCount. 04330 04331 ********************************************************************************************/ 04332 04333 BOOL GIFAnimationExportParam::AddLayer(Layer * pLayer) 04334 { 04335 ERROR2IF(pLayer == NULL,FALSE,"AddLayer given null layer"); 04336 BOOL ok = TRUE; 04337 04338 // If we have a null list then just allocate the first item 04339 if (m_pLayers == NULL) 04340 { 04341 // Claim selected space 04342 m_pLayers = (Layer**) CCMalloc(sizeof(Layer*)); 04343 if (m_pLayers == NULL) 04344 ok = FALSE; 04345 else 04346 m_pLayers[0] = pLayer; 04347 m_LayerCount = 1; 04348 } 04349 else 04350 { 04351 // Add to end of selection 04352 Layer** pTemp = (Layer**) CCRealloc(m_pLayers, (m_LayerCount + 1) * sizeof(Layer*)); 04353 if (pTemp == NULL) 04354 ok = FALSE; 04355 else 04356 { 04357 m_pLayers = pTemp; 04358 m_pLayers[m_LayerCount] = pLayer; 04359 } 04360 m_LayerCount++; 04361 } 04362 04363 return ok; 04364 } 04365 04366 /******************************************************************************************** 04367 04368 > BOOL GIFAnimationExportParam::AddBitmap(KernelBitmap * pBitmap) 04369 04370 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04371 Created: 13/05/97 04372 Inputs: pBitmap the bitmap to add to our list in the animation 04373 Returns: True if worked ok, False otherwise 04374 Purpose: Tries to add the bitmap to the list. 04375 Uses the class variables m_pBitmaps and m_BitmapCount. 04376 Copied from BitmapSGallery and BitmapExportParam way of doing things so that 04377 we are compatible. Not the best way of doing it! 04378 SeeAlso: BitmapSGallery::GetSelectedBitmaps 04379 04380 ********************************************************************************************/ 04381 04382 BOOL GIFAnimationExportParam::AddBitmap(KernelBitmap * pBitmap) 04383 { 04384 ERROR2IF(pBitmap == NULL,FALSE,"Addbitmap given null bitmap"); 04385 BOOL ok = TRUE; 04386 04387 // If we have a null list then just allocate the first item 04388 if (m_pBitmaps == NULL) 04389 { 04390 // Claim selected space 04391 m_pBitmaps = (KernelBitmap**) CCMalloc(sizeof(KernelBitmap*)); 04392 if (m_pBitmaps == NULL) 04393 ok = FALSE; 04394 else 04395 m_pBitmaps[0] = pBitmap; 04396 m_BitmapCount = 1; 04397 } 04398 else 04399 { 04400 // Add to end of selection 04401 KernelBitmap** pTemp = (KernelBitmap**) CCRealloc(m_pBitmaps, (m_BitmapCount + 1) * sizeof(KernelBitmap*)); 04402 if (pTemp == NULL) 04403 ok = FALSE; 04404 else 04405 { 04406 m_pBitmaps = pTemp; 04407 m_pBitmaps[m_BitmapCount] = pBitmap; 04408 } 04409 m_BitmapCount++; 04410 } 04411 04412 return ok; 04413 } 04414 04415 /******************************************************************************************** 04416 04417 > BOOL GIFAnimationExportParam::SetAnimPropertiesParam(AnimPropertiesParam* pParam) 04418 04419 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04420 Created: 13/05/97 04421 Inputs: pParam - Sets the Animation Properties details for this GIFAnimationExportParam. 04422 Returns: TRUE if ok, FALSE otherwise. 04423 04424 ********************************************************************************************/ 04425 04426 void GIFAnimationExportParam::SetSpreadAnimPropertiesParam(const AnimPropertiesParam& Param) 04427 { 04428 m_AnimPropertiesParam = Param; 04429 } 04430 04431 /******************************************************************************************** 04432 04433 > void GIFAnimationExportParam::GetAnimPropertiesParam() 04434 04435 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04436 Created: 13/05/97 04437 Purpose: Returns the Animation Properties details for this GIFAnimationExportParam. 04438 04439 ********************************************************************************************/ 04440 04441 AnimPropertiesParam& GIFAnimationExportParam::GetSpreadAnimPropertiesParam() 04442 { 04443 return m_AnimPropertiesParam; 04444 } 04445 04446 /******************************************************************************************** 04447 04448 > DocRect GIFAnimationExportParam::GetBoundingRect() const 04449 04450 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04451 Created: 11/06/97 04452 Purpose: Returns the bounding rectangle of the animation. 04453 04454 ********************************************************************************************/ 04455 04456 DocRect GIFAnimationExportParam::GetBoundingRect() const 04457 { 04458 // Recover the bounding rect of the animation from our copy of the spread's 04459 // animation properties. 04460 DocRect BoundingRect = m_AnimPropertiesParam.GetBoundingRect(); 04461 // We are only interested in the size and so translate it to zero 04462 BoundingRect.Translate(-BoundingRect.lo.x, -BoundingRect.lo.y); 04463 // return it to the caller 04464 return BoundingRect; 04465 } 04466 04467 04468 //------------------------------------------------------------------------------------------ 04469 // end of GIFAnimationExportParam 04470 //------------------------------------------------------------------------------------------ 04471 04472 /******************************************************************************************** 04473 // OpSaveAnimatedGIF 04474 ********************************************************************************************/ 04475 04476 /******************************************************************************************** 04477 04478 > OpState OpSaveAnimatedGIF::GetState(String_256*, OpDescriptor*) 04479 04480 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04481 Created: 9/9/97 04482 Inputs: Name of the OpDescriptor being queried 04483 Outputs: The string to show to the user 04484 Returns: The state of the OpSaveAnimatedGIF operation 04485 Purpose: For finding the OpSaveAnimatedGIF's state. 04486 04487 ********************************************************************************************/ 04488 04489 OpState OpSaveAnimatedGIF::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 04490 { 04491 // else just use the base class version 04492 return OpGrabAllFrames::GetState(pUIDescription, pOpDesc); 04493 } 04494 04495 /******************************************************************************************** 04496 04497 > BOOL OpSaveAnimatedGIF::GetFileNameFromUser() 04498 04499 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04500 Created: 7/7/97 04501 Returns: True if worked ok, False otherwise 04502 Purpose: Gives the operation chance to get the filename from the user. 04503 In this version we need to do this before grabbing the frames so that the 04504 user is given the oppurtunity to change the options using the button on the 04505 file save dialog box. 04506 04507 ********************************************************************************************/ 04508 04509 BOOL OpSaveAnimatedGIF::GetFileNameFromUser() 04510 { 04511 // This is used to export an animated GIF. So we need only show the normal 04512 // GIF filter. This is despite the fact that this is not going to be the filter 04513 // that we use for the job. 04514 04515 // We are just going to show the animated GIF filter and all files 04516 String_256 FilterString(_R(IDS_SAVEGIFANIFILTERS)); 04517 04518 // Ensure that all the filters have a -1 in their position string so any matching 04519 // of selected filter will fail. Make only the GIF filter have 1 in there. 04520 Filter* pFilter = Filter::GetFirst(); 04521 while (pFilter != NULL) 04522 { 04523 if (IS_A(pFilter, TI_GIFFilter)) 04524 { 04525 // Its the GIF filter we want, mark it as the first position 04526 pFilter->pOILFilter->Position = 1; 04527 } 04528 else 04529 { 04530 // Make sure we don't try this one later 04531 pFilter->pOILFilter->Position = -1; 04532 } 04533 04534 // Try the next filter 04535 pFilter = Filter::GetNext(pFilter); 04536 } 04537 04538 // Create the dialog box 04539 GIFExportFileDialog FDialog(FilterString); 04540 04541 FDialog.SetTitle(_R(IDS_SAVEGIFANI_TITLE)); 04542 04543 // Use the document name as the default name of animation 04544 String_256 DefaultName(_R(IDS_BUTTBAR_ANIMATION)); // GIF Animation 04545 if (m_pDocument) 04546 DefaultName = m_pDocument->GetDocName(FALSE); 04547 // This is the pathname that we are going to save to 04548 m_SavePath = DefaultName; 04549 // Ensure that we have the correct extension on the filename we have allocated 04550 EnsureFileType(&m_SavePath); 04551 04552 // Pass this name onto the dialog box 04553 DefaultName = m_SavePath.GetFileName(); 04554 FDialog.SetDefaultFileName(DefaultName); 04555 04556 //FDialog.SetSelectedFilterIndex(1); 04557 04558 // Select the desired path 04559 String_256 ExportFilterPath = OpMenuExport::DefaultExportFilterPath; 04560 //Camelot.GetPrefDirect("Filters", "DefaultExportFilterPath",&ExportFilterPath); 04561 if (ExportFilterPath.Length() > 0) 04562 FDialog.SetInitialDirectory(ExportFilterPath); 04563 04564 // 'Do' the dialog and get that filename that we require 04565 BOOL DlgResult = FDialog.OpenAndGetFileName(); 04566 if (!DlgResult) 04567 { 04568 return FALSE; 04569 } 04570 04571 // Get the filename. 04572 FDialog.GetChosenFileName(&m_SavePath); 04573 04574 // This is now taken care of in FileDlgs.cpp on the ok as it then checks if the file 04575 // exists or not. If we do it here then this does not happen. 04576 // Unfortunately, changes made to the string in the dialog do not filter through 04577 // and so we ust fix it up here as well. 04578 // Always make sure that the filter's default extension is on if the user has not 04579 // specified an extension. 04580 EnsureFileType(&m_SavePath); 04581 04582 // Ensure that the path is valid 04583 if (!m_SavePath.IsValid()) 04584 { 04585 InformError(); 04586 //delete m_pBitmapFilter; 04587 //m_pBitmapFilter = NULL; 04588 return FALSE; 04589 } 04590 04591 // Extract directory name (minus terminating backslash) and remember for next time. 04592 ExportFilterPath = m_SavePath.GetLocation(FALSE); 04593 if (ExportFilterPath.Length() > 0) 04594 OpMenuExport::DefaultExportFilterPath = ExportFilterPath; 04595 //Camelot.SetPrefDirect("Filters", "DefaultExportFilterPath",DefaultExportFilterPath, TRUE); 04596 04597 //UINT32 TheSelectedFilterID = m_pBitmapFilter->FilterID; 04598 04599 // Everything got so return to the grabbing process 04600 return TRUE; 04601 } 04602 04603 /******************************************************************************************** 04604 04605 > virtual BOOL OpSaveAnimatedGIF::SaveOrShowTheAnimation(PreviewDialog * pPreviewDialog, BitmapExportParam* pExportParam) 04606 04607 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04608 Created: 4/8/97 04609 Inputs: pPreviewDialog the preview dialog box, if open 04610 pExportParam the export param which we will use 04611 Returns: True if worked ok, False otherwise 04612 Purpose: Tries to actually do the preview operation required. 04613 In this case we just save the animation out to the file that the user specified. 04614 04615 ********************************************************************************************/ 04616 04617 BOOL OpSaveAnimatedGIF::SaveOrShowTheAnimation(PreviewDialog * pPreviewDialog, BitmapExportParam* pExportParam) 04618 { 04619 // A bit of checking on parameters 04620 if (pExportParam != NULL) 04621 { 04622 ERROR3IF(!pExportParam->IS_KIND_OF(BitmapExportParam), "OpParam passed is not a BitmapExportParam"); 04623 04624 if (pExportParam->GetBitmapCount() == 0) 04625 { 04626 ERROR2RAW("OpSaveAnimatedGIF::DoWithParam no bitmaps to export"); 04627 return FALSE; 04628 } 04629 } 04630 else 04631 { 04632 ERROR2RAW("OpSaveAnimatedGIF::DoWithParam bad params!"); 04633 return FALSE; 04634 } 04635 04636 // Recover the bitmap pointer from the parameter passed in 04637 // This is to ensure that we have at least one bitmap to save 04638 KernelBitmap* pTheBitmap = pExportParam->GetBitmap(0); 04639 if (pTheBitmap == NULL) 04640 { 04641 ERROR2RAW("OpSaveAnimatedGIF::DoWithParam bitmap pointer is null"); 04642 return FALSE; 04643 } 04644 04645 // Ensure that we have a special grab frame filter available 04646 if (m_pBitmapFilter == NULL) 04647 m_pBitmapFilter = new GrabFrameFilter(); 04648 if (m_pBitmapFilter == NULL) 04649 { 04650 InformError(_R(IDT_CANT_FIND_FILTER)); 04651 return FALSE; 04652 } 04653 04654 // Should really check that the pathname is not null 04655 String_256 Filename; 04656 Filename = m_SavePath.GetPath(); 04657 ERROR2IF(Filename.IsEmpty(),FALSE,"OpSaveAnimatedGIF::SaveAnimation Save path not set up!"); 04658 04659 // First off, we have to try and open the file 04660 CCDiskFile DiskFile(1024, FALSE, TRUE); 04661 04662 BOOL ExportedOk = TRUE; 04663 try 04664 { 04665 // Export bitmaps 04666 ExportedOk = m_pBitmapFilter->DoExportBitmaps(this, &DiskFile, &m_SavePath, pExportParam); 04667 04668 if (!ExportedOk) 04669 { 04670 // Something went a bit wrong - tell the user what it was. 04671 // Supress the error if it was the 'user has cancelled one' 04672 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 04673 { 04674 InformError(); 04675 m_pBitmapFilter->DeleteExportFile(&DiskFile); 04676 } 04677 else 04678 { 04679 // otherwise remove the error so it won't get reported 04680 Error::ClearError(); 04681 } 04682 } 04683 04684 // close the file 04685 if (DiskFile.isOpen()) 04686 DiskFile.close(); 04687 } 04688 04689 // See if there was a file io error 04690 catch(CFileException) 04691 { 04692 // Report the error if no one else did 04693 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 04694 { 04695 InformError(); 04696 } 04697 else 04698 Error::ClearError(); // otherwise remove the error so it won't get reported 04699 04700 // Make sure that the file is closed and deleted 04701 try 04702 { 04703 // First try and delete it (tries to close it first) 04704 if (m_pBitmapFilter) 04705 m_pBitmapFilter->DeleteExportFile(&DiskFile); 04706 04707 // Double check to make sure it is closed. 04708 if (DiskFile.isOpen()) 04709 DiskFile.close(); 04710 } 04711 catch(CFileException) 04712 { 04713 // Failed to close the file - not much we can do about it really 04714 } 04715 04716 // Fail 04717 ExportedOk = FALSE; 04718 } 04719 04720 // Clean out the filter we created 04721 delete m_pBitmapFilter; 04722 m_pBitmapFilter = NULL; 04723 04724 // Blank the path 04725 //m_SavePath.SetPathName(TEXT("")); 04726 // This will give us a nice pathname is invalid error! Don't you just love the pathname class! 04727 04728 return ExportedOk; 04729 } 04730 04731 /******************************************************************************************** 04732 04733 > BOOL OpSaveAnimatedGIF::EnsureFileType(PathName * pPath) 04734 04735 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04736 Created: 1/5/97 04737 Inputs: pPath the pathname in use 04738 Purpose: Ensures that the pathname has the file extension/type that we require. 04739 04740 ********************************************************************************************/ 04741 04742 BOOL OpSaveAnimatedGIF::EnsureFileType(PathName * pPath) 04743 { 04744 ERROR2IF(pPath == NULL,FALSE,"EnsureFileExtension bad path specified"); 04745 04746 // we are essentially a GIF filter so we need that extension 04747 String_32 ExtStr(_R(IDN_FILTEREXT_GIF)); 04748 ExtStr.toLower(); 04749 String_256 Extension = pPath->GetType(); 04750 Extension.toLower(); 04751 if (Extension.IsEmpty() || Extension != ExtStr) 04752 { 04753 // There is no extension set for this file, so give it one 04754 pPath->SetType(ExtStr); 04755 } 04756 04757 return TRUE; 04758 } 04759 04760 /******************************************************************************************** 04761 // end of OpSaveAnimatedGIF 04762 ********************************************************************************************/ 04763 04764 04765 //------------------------------------------------------------------------------------------ 04766 // Methods for the OpBrowserPreview 04767 //------------------------------------------------------------------------------------------ 04768 04769 // Init the static that we have 04770 PathName OpBrowserPreview::m_TempPath; 04771 04772 /******************************************************************************************** 04773 04774 > BOOL OpBrowserPreview::GetFileNameFromUser() 04775 04776 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04777 Created: 7/7/97 04778 Returns: True if worked ok, False otherwise 04779 Purpose: Gives the operation chance to get the filename from the user. 04780 In this version we need to override the OpSaveAnimation's version so that 04781 we do nothing. 04782 04783 ********************************************************************************************/ 04784 04785 BOOL OpBrowserPreview::GetFileNameFromUser() 04786 { 04787 // This version, do nothing 04788 return TRUE; 04789 } 04790 04791 /******************************************************************************************** 04792 04793 > virtual BOOL OpBrowserPreview::SaveOrShowTheAnimation(PreviewDialog * pPreviewDialog, BitmapExportParam* pExportParam) 04794 04795 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04796 Created: 4/8/97 04797 Inputs: pPreviewDialog the preview dialog box, if open 04798 pExportParam the export param which we will use 04799 Returns: True if worked ok, False otherwise 04800 Purpose: Tries to actually do the preview operation required. 04801 In this case we just save the animation out to a temporary file and then fire 04802 up the browser with an html wrapper which references that file. 04803 04804 ********************************************************************************************/ 04805 04806 BOOL OpBrowserPreview::SaveOrShowTheAnimation(PreviewDialog * pPreviewDialog, BitmapExportParam* pExportParam) 04807 { 04808 // A bit of checking on parameters 04809 if (pExportParam != NULL) 04810 { 04811 ERROR3IF(!pExportParam->IS_KIND_OF(BitmapExportParam), "OpParam passed is not a BitmapExportParam"); 04812 04813 if (pExportParam->GetBitmapCount() == 0) 04814 { 04815 ERROR2RAW("OpSaveAnimatedGIF::DoWithParam no bitmaps to export"); 04816 return FALSE; 04817 } 04818 } 04819 else 04820 { 04821 ERROR2RAW("OpSaveAnimatedGIF::DoWithParam bad params!"); 04822 return FALSE; 04823 } 04824 04825 // Go and preview it in a browser. 04826 // Get our saving filter 04827 if (m_pBitmapFilter == NULL) 04828 m_pBitmapFilter = new GrabFrameFilter(); 04829 if (m_pBitmapFilter == NULL) 04830 { 04831 InformError(_R(IDT_CANT_FIND_FILTER)); 04832 return FALSE; 04833 } 04834 04835 // create a disk file 04836 CCDiskFile TempDiskFile(1024, FALSE, TRUE); 04837 04838 // Ensure that if we have been using a previous temp file then 04839 // it is cleaned up 04840 RemoveTempFile(); 04841 04842 // Create the required unique temporary of the correct filetype 04843 String_32 ExtStr(_R(IDN_FILTEREXT_GIF)); 04844 ExtStr.toLower(); 04845 if (!FileUtil::GetTemporaryPathName(ExtStr, &m_TempPath)) 04846 return FALSE; 04847 04848 // Ensure that we have the correct extension on the filename we have allocated 04849 EnsureFileType(&m_TempPath); 04850 04851 // First off, we have to try and open the file 04852 CCDiskFile DiskFile(1024, FALSE, TRUE); 04853 04854 BOOL ExportedOk = TRUE; 04855 04856 try 04857 { 04858 // Export bitmaps supressing the filename so that the user does not see the temp filename 04859 ExportedOk = m_pBitmapFilter->DoExportBitmaps(this, &TempDiskFile, &m_TempPath, &m_ExportParams, TRUE); 04860 04861 if (!ExportedOk) 04862 { 04863 // Something went a bit wrong - tell the user what it was. 04864 // Supress the error if it was the 'user has cancelled one' 04865 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 04866 { 04867 InformError(); 04868 m_pBitmapFilter->DeleteExportFile(&DiskFile); 04869 } 04870 else 04871 { 04872 // otherwise remove the error so it won't get reported 04873 Error::ClearError(); 04874 } 04875 } 04876 04877 // close the file 04878 if (DiskFile.isOpen()) 04879 DiskFile.close(); 04880 } 04881 04882 // See if there was a file io error 04883 catch(CFileException) 04884 { 04885 // Report the error if no one else did 04886 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 04887 { 04888 InformError(); 04889 } 04890 else 04891 Error::ClearError(); // otherwise remove the error so it won't get reported 04892 04893 // Make sure that the file is closed and deleted 04894 try 04895 { 04896 // First try and delete it (tries to close it first) 04897 if (m_pBitmapFilter) 04898 m_pBitmapFilter->DeleteExportFile(&DiskFile); 04899 04900 // Double check to make sure it is closed. 04901 if (DiskFile.isOpen()) 04902 DiskFile.close(); 04903 } 04904 catch(CFileException) 04905 { 04906 // Failed to close the file - not much we can do about it really 04907 } 04908 04909 // Fail 04910 ExportedOk = FALSE; 04911 } 04912 04914 // Now we have the file, we can go and preview it in the browser 04915 04916 // Allocate our preview class, must keep it around as destruction causes 04917 // it to clean up the temp files, which is bad if this is before it has 04918 // had a chance to fire up the browser! 04919 if (m_pBitmapData == NULL) 04920 { 04921 m_pBitmapData = new BitmapPreviewData; 04922 if (m_pBitmapData == NULL) 04923 return FALSE; 04924 } 04925 // Now a static pointer as otherwise the temp file is deleted too quickly 04926 04927 MakeBitmapExportOptions * pBmpOptions = NULL; 04928 // Recover the options from the filter that it saved during the preparation of the bitmaps 04929 // They are helpfully vaped by now! So, we took a copy during GetExportOptions 04930 // But if all the frame are already captured then we will not have any options 04931 pBmpOptions = m_pBitmapFilter->GetCurrentExportOptionsCopy(); 04932 BOOL MadeBitmapOptions = FALSE; 04933 if (pBmpOptions == NULL) 04934 { 04935 // Get the filter to set up the bitmap options for us (Use out public version of CreateExportOptions) 04936 pBmpOptions = m_pBitmapFilter->MakeExportOptions(); 04937 // Use our public interface onto the GetExportOptions protected function 04938 if (pBmpOptions != NULL) 04939 { 04940 MadeBitmapOptions = TRUE; 04941 m_pBitmapFilter->SetupExportOptions(pBmpOptions, m_pSpread); 04942 } 04943 } 04944 ERROR2IF(pBmpOptions == NULL,FALSE,"OpBrowserPreview::PreviewAnimation No current bitmap options"); 04945 04946 // Get the first bitmap in the list, this will give us the size of the animation 04947 KernelBitmap* pTheBitmap = pExportParam->GetBitmap(0); 04948 // Get the filesize that we have exported 04949 UINT32 FileSize = TempDiskFile.Size(); 04950 04951 // tell the options about the temp file that we are using 04952 pBmpOptions->SetPathName(&m_TempPath); 04953 04954 // This is our copy of the BitmapExportParam 04955 m_pBitmapData->SetNewBitmap(pTheBitmap, FileSize, pBmpOptions); 04956 04957 // Set up the options that we require 04958 /* BrowserBackground Bgr = BROWSER_BGR_DOC; //BROWSER_BGR_CHECKER; 04959 BOOL ShowInfo = TRUE; 04960 BOOL GenerateImagemap = FALSE; 04961 */ 04962 // Get the values from our global variables. 04963 BrowserBackground Bgr = PreviewInBrowserTab::g_Background; 04964 BOOL ShowInfo = PreviewInBrowserTab::g_InfoInHtmlStub; 04965 BOOL GenerateImagemap = FALSE; 04966 04967 BrowserPreviewOptions PreviewOptions(Bgr, ShowInfo, GenerateImagemap); 04968 04969 //BrowserPreviewOptions PreviewOptions(PreviewInBrowserTab::GetBrowserOptions()); 04970 04971 // tell it what spread to use when getting the document background 04972 PreviewOptions.SetSpread(m_pSpread); 04973 04974 // This should actually preview it in the browser 04975 m_pBitmapData->GenerateHTMLStub(PreviewOptions); 04976 04977 04978 // Clean out the filter we created 04979 delete m_pBitmapFilter; 04980 m_pBitmapFilter = NULL; 04981 04982 if (MadeBitmapOptions && pBmpOptions != NULL) 04983 delete pBmpOptions; 04984 04985 return ExportedOk; 04986 } 04987 04988 /******************************************************************************************** 04989 04990 > OpState OpBrowserPreview::GetState(String_256*, OpDescriptor*) 04991 04992 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04993 Created: 20/6/97 04994 Inputs: Name of the OpDescriptor being queried 04995 Outputs: The string to show to the user 04996 Returns: The state of the OpBrowserPreview operation 04997 Purpose: For finding the OpBrowserPreview's state. 04998 04999 ********************************************************************************************/ 05000 05001 /* OpState OpBrowserPreview::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) 05002 { 05003 // This is always unavailable for the present moment 05004 OpState OpSt; 05005 OpSt.Greyed = TRUE; 05006 return OpSt; 05007 } */ 05008 05009 /******************************************************************************************** 05010 05011 > static BOOL OpBrowserPreview::RemoveTempFile() 05012 05013 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 05014 Created: 7/7/97 05015 Returns: True if worked correctly, False otherwise. 05016 Purpose: For cleaning up any temp file useage that we may have made. 05017 This should be called in the DeInit during program shut down. 05018 05019 ********************************************************************************************/ 05020 05021 BOOL OpBrowserPreview::RemoveTempFile() 05022 { 05023 // If we have used the m_TempPath during this session then ensure that we have cleaned up 05024 // any temp files 05025 String_256 Filename; 05026 Filename = m_TempPath.GetPath(); 05027 if (!Filename.IsEmpty() && m_TempPath.IsValid()) 05028 { 05029 FileUtil::DeleteFile(&m_TempPath); 05030 } 05031 05032 return TRUE; 05033 } 05034 05035 /******************************************************************************************** 05036 // End of OpBrowserPreview 05037 ********************************************************************************************/ 05038 05039 #endif // EXCLUDE_FROM_XARALX 05040 05041