00001 // $Id: nativeop.cpp 1461 2006-07-18 09:50:40Z luke $ 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 // The Native Save/Load operations 00099 00100 /* 00101 */ 00102 00103 #include "camtypes.h" 00104 #include "nativeop.h" 00105 //#include "filters.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 #include "native.h" // proper native filter designed by us 00107 #include "nativeps.h" // old native filter based on eps, used for version 1.1 00108 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 //#include "tim.h" 00110 //#include "nev.h" 00111 //#include "rik.h" 00112 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 #include "filedlgs.h" 00114 //#include "oilfiles.h" 00115 #include <stdlib.h> 00116 #include <errno.h> 00117 //#include "barsdlgs.h" 00118 #include "webop.h" 00119 //#include "filtrres.h" // New native filter strings 00120 //#include "fixmem.h" // CCFree - in camtypes.h [AUTOMATICALLY REMOVED] 00121 #include "bubbleid.h" 00122 #include "tmplmngr.h" 00123 #include "fileutil.h" 00124 00125 #include "camdoc.h" // for CCamDoc::GetTemplateFilename 00126 //#include "justin3.h" // for _R(IDS_SAVE_AS_DEFAULT_EMBEDDED) 00127 //#include "app.h" // GetApplication - in camtypes.h [AUTOMATICALLY REMOVED] 00128 #include "sgliboil.h" // for SGLibOil::FileExists 00129 //#include "resimmap.h" // for various resources 00130 00131 #include "menuops.h" 00132 00133 // An implement to match the Declare in the .h file. 00134 CC_IMPLEMENT_DYNCREATE(OpMenuLoad, SelOperation) 00135 #ifdef DO_EXPORT 00136 CC_IMPLEMENT_DYNCREATE(OpMenuSave, Operation) 00137 CC_IMPLEMENT_DYNCREATE(OpSaveAsNativeV1, Operation) 00138 #endif 00139 00140 // This will get Camelot to display the filename and linenumber of any memory allocations 00141 // that are not released at program exit 00142 // Declare smart memory handling in Debug builds 00143 #define new CAM_DEBUG_NEW 00144 00145 00146 00147 /******************************************************************************************** 00148 > BOOL InvokeNativeFileOp(const TCHAR* pOpName, CCLexFile* pFile, UINT32 nPrefFilter) 00149 00150 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00151 Created: 18/8/96 00152 Inputs: pOpName - the OPTOKEN of the Operation to invoke on pFile. 00153 pFile - pointer to the CCLexFile to use for this operation. 00154 nPrefFilter - the filter to use to import the native file, usually 00155 FILTERID_GENERIC. Set to -1 to use the last known 00156 filter the user selected in a file dialog. 00157 Returns: TRUE if the Operation is performed successfully, FALSE if it can't be 00158 found or performed. 00159 Purpose: Shorthand for invoking the native file Operations. 00160 SeeAlso: OpMenuLoad; OpMenuSave; CCFile; Operation; OpDescriptor; OpParam 00161 ********************************************************************************************/ 00162 00163 BOOL InvokeNativeFileOp(const TCHAR* pOpName, CCLexFile* pFile, UINT32 nPrefFilter) 00164 { 00165 // Find the requested Operation. 00166 OpDescriptor* pOp = OpDescriptor::FindOpDescriptor((TCHAR*) pOpName); 00167 if (pOp == 0) 00168 { 00169 ERROR3("Can't find OpDescriptor in InvokeNativeFileOp"); 00170 return FALSE; 00171 } 00172 00173 // Build the parameter block. 00174 NativeFileOpParams pm; 00175 pm.pFile = pFile; 00176 pm.fStatus = FALSE; 00177 pm.nPrefFilter = nPrefFilter; 00178 00179 // Invoke it with the given parameters, returning its status. 00180 OpParam param( &pm, INT32(0) ); 00181 pOp->Invoke( ¶m ); 00182 return pm.fStatus; 00183 } 00184 00185 00186 00187 /******************************************************************************************** 00188 00189 > static BOOL OpMenuLoad::Init() 00190 00191 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00192 Created: 21/12/94 00193 Returns: TRUE if it worked, FALSE if not. 00194 Purpose: Registers the opdescriptor for the Native Load operation. 00195 00196 ********************************************************************************************/ 00197 00198 BOOL OpMenuLoad::Init() 00199 { 00200 // Register this operations descriptor 00201 return RegisterOpDescriptor(0, _R(IDT_IMPORT), CC_RUNTIME_CLASS(OpMenuLoad), 00202 OPTOKEN_NATIVELOAD, GetState, 00203 0, _R(IDBBL_IMPORTFILEOP), 0,0,SYSTEMBAR_ILLEGAL, 00204 TRUE, FALSE, TRUE); 00205 00206 return false; 00207 } 00208 00209 00210 00211 /******************************************************************************************** 00212 00213 > OpState OpMenuLoad::GetState(String_256*, OpDescriptor*) 00214 00215 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00216 Created: 21/12/94 00217 Purpose: Yet another annoying OpState function that does nothing 00218 00219 ********************************************************************************************/ 00220 00221 OpState OpMenuLoad::GetState(String_256*, OpDescriptor*) 00222 { 00223 // Dunno 00224 OpState Blobby; 00225 return Blobby; 00226 } 00227 00228 00229 00230 /******************************************************************************************** 00231 > void OpMenuLoad::DoWithParam(OpDescriptor*, OpParam* pOpParam) 00232 00233 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00234 Created: 18/8/96 00235 Inputs: OpDescriptor - Not Used. 00236 pOpParam->Param1 - a pointer to the NativeFileOpParams for this invokation. 00237 Purpose: Loads a Camelot Native EPS file. 00238 ********************************************************************************************/ 00239 00240 void OpMenuLoad::DoWithParam(OpDescriptor*, OpParam* pOpParam) 00241 { 00242 // Extract the parameters. 00243 NativeFileOpParams* ppm = (NativeFileOpParams*)(void *)(pOpParam->Param1); 00244 00245 // Try to load the file. 00246 ERROR3IF(!ppm->pFile, "Null CCLexFile* in OpMenuLoad::DoWithParam"); 00247 ppm->fStatus = ppm->pFile && LoadFile(ppm->pFile, ppm->nPrefFilter); 00248 if (!ppm->fStatus) FailAndExecute(); 00249 00250 // Before we call End() we must ensure that CurrentDoc == SelectedDoc 00251 Document::GetSelected()->SetCurrent(); 00252 End(); 00253 } 00254 00255 00256 00257 /******************************************************************************************** 00258 > BOOL OpMenuLoad::LoadFile(CCLexFile* pFileToLoad, UINT32 nPrefFilter) 00259 00260 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> & JustinF 00261 Created: 3/1/95 00262 Inputs: pFileToLoad - the file to load from. 00263 nPreFilter - the ID of the filter to use 00264 Returns: TRUE if it worked, FALSE if it failed 00265 Purpose: Tries to load the file specified. If it is not a Camelot file then it 00266 should report errors etc. Most of this function is actually looking for 00267 the Native Load/Save filter to try and load. 00268 SeeAlso: OpMenuLoad; RecentFileOp 00269 ********************************************************************************************/ 00270 00271 BOOL OpMenuLoad::LoadFile(CCLexFile* pFileToLoad, UINT32 nPrefFilter) 00272 { 00273 // Make sure we have a valid file to load. 00274 /* TRACEUSER( "JustinF", _T("In OpMenuLoad::LoadFile(%p, %u)\n"), 00275 (LPVOID) pFileToLoad, nPrefFilter); 00276 */ ERROR3IF(!pFileToLoad, "Null CCLexFile* in OpMenuLoad::LoadFile"); 00277 00278 // Find out the position of the filter selected by the user in the open dialog 00279 INT32 SelectedPos = 0; 00280 00281 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00282 SelectedPos = BaseFileDialog::SelectedFilter; 00283 #endif 00284 00285 // Go get the first filter in the list 00286 Filter* pFilter = Filter::GetFirst(); 00287 00288 // Do we know which filter was used? (we know nothing about things in the recent file 00289 // list). If we don't, then use the preferred one, by default the generic filter. 00290 if (nPrefFilter != FILTERID_USERCHOICE || SelectedPos == 0) 00291 { 00292 // We know nothing. We will have to go and have a look at all the possibles 00293 // We will find the Filter Family and ask it to try and load the file. 00294 UINT32 nID = (nPrefFilter != FILTERID_USERCHOICE) ? nPrefFilter : FILTERID_GENERIC; 00295 while (pFilter != NULL && pFilter->FilterID != nID) 00296 { 00297 // Try the next filter 00298 pFilter = Filter::GetNext(pFilter); 00299 } 00300 } 00301 else 00302 { 00303 // We know which type of filter the user had selected in the file dialog 00304 // Find the filter that the user chose. 00305 while (pFilter != NULL) 00306 { 00307 // This is the filter? 00308 if (pFilter->GetFlags().CanImport && 00309 pFilter->pOILFilter->Position == SelectedPos) 00310 break; 00311 00312 // Try the next filter 00313 pFilter = Filter::GetNext(pFilter); 00314 } 00315 } 00316 00317 // Check that the Filter existed 00318 if (pFilter == NULL) 00319 { 00320 // It did not... 00321 InformError(_R(IDT_CANT_FIND_FILTER)); 00322 return FALSE; 00323 } 00324 00325 // Get pointer to current doc 'cos we'll need it several times... 00326 Document* pCurDoc = Document::GetCurrent(); 00327 00328 // If this is not a filter family, check for compatibility before asking 00329 // filter to load the file. 00330 // This means the user has chosen an explicit filter to handle the import 00331 PathName Path = pFileToLoad->GetPathName(); 00332 String_256 FilePath = Path.GetPath(); 00333 // FilePath will be null if a pathname is not valid 00334 if (!pFilter->IS_KIND_OF(FilterFamily) && !FilePath.IsEmpty()) 00335 { 00336 UINT32 Size = 1024; 00337 size_t FileSize; 00338 ADDR FilterBuf = pFilter->LoadInitialSegment(Path, &Size, &FileSize); 00339 00340 // If there has been a problem in the load initial segment then fail now. 00341 if (FilterBuf == NULL) 00342 { 00343 // Tell the user about the problem and get out now while the goings good 00344 InformError(); 00345 return FALSE; 00346 } 00347 00348 // Inform any filters that we are about to do a HowCompatible call. 00349 // This would allow a set of filters which have common functionality hidden in a 00350 // filter that cannot import and cannot export handle this call and hence set 00351 // itself up. This would allow it to maybe cache a result which should only be 00352 // checked by the first filter in the group. 00353 pFilter->PreHowCompatible(); 00354 00355 // Change this to be less than 8 as the filters like the Accusoft forms return 00356 // 8 and 9 to make sure that they are last in the chain. 00357 if (pFilter->HowCompatible(Path, FilterBuf, Size, UINT32(FileSize)) < 8) 00358 { 00359 // Not 100% happy with this file - ask for confirmation. 00360 ErrorInfo Question; 00361 Question.ErrorMsg = _R(IDW_OPENQUERY_NOTSURE); 00362 Question.Button[0] = _R(IDB_OPENQUERY_OPEN); 00363 Question.Button[1] = _R(IDB_OPENQUERY_DONTOPEN); 00364 00365 if ((ResourceID)AskQuestion(&Question) != _R(IDB_OPENQUERY_OPEN)) 00366 { 00367 // User asked for this to be cancelled. 00368 TRACEUSER( "Tim", _T("Filter compatibility was less than 10\n")); 00369 00370 // Close the file, report the abort and finish. 00371 CCFree(FilterBuf); 00372 //InformMessage(_R(IDT_IMP_USERABORT)); 00373 return FALSE; 00374 } 00375 } 00376 00377 // Get rid of initial file header 00378 CCFree(FilterBuf); 00379 } 00380 00381 // we have to try and open the file 00382 try 00383 { 00384 // Found the Filter, so ask it to import the file please 00385 if (!pFilter->DoImport(this, pFileToLoad, pCurDoc)) 00386 { 00387 // Something went a bit wrong - tell the user what it was. 00388 // Only tell them if not special user cancelled error message 00389 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 00390 { 00391 // Only supress the error if not the special user abort error 00392 // ***** For now use the native EPS filter 00393 if (pFilter->FilterID == FILTERID_NATIVE_EPS && 00394 Error::GetErrorNumber() != _R(IDT_IMPORT_USERABORT)) 00395 { 00396 Error::ClearError(); 00397 InformError(_R(IDS_ERRORINARTFILE)); 00398 } 00399 else 00400 { 00401 // Tell the user what the problem was 00402 InformError(); 00403 wxMessageDialog dlg( 00404 NULL, 00405 _T( "Xara LX failed to load the design.\n\n") 00406 _T( "This is an early demonstration version of the program which does ") 00407 _T( "not yet support all of the data types that can appear in XAR designs."), 00408 _T("Load failed"), 00409 wxOK 00410 ); 00411 dlg.ShowModal() ; 00412 } 00413 } 00414 else 00415 { 00416 // otherwise remove the error so it won't get reported 00417 Error::ClearError(); 00418 } 00419 00420 // and fail 00421 return FALSE; 00422 } 00423 00424 } 00425 // See if there was a file io errir 00426 catch( CFileException ) 00427 { 00428 // Report the error if no one else did, otherwise clear it. 00429 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 00430 InformError(); 00431 else 00432 Error::ClearError(); 00433 00434 // and fail 00435 return FALSE; 00436 } 00437 00438 // Success. 00439 return TRUE; 00440 } 00441 00442 00443 00444 #ifdef DO_EXPORT 00445 00446 /******************************************************************************************** 00447 00448 > void OpMenuSave::DoWithParam(OpDescriptor*, OpParam* pOpParam) 00449 00450 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00451 Created: 21/12/94 00452 Inputs: OpDescriptor - Not Used 00453 pOpParam->Param1 - A TCHAR* pointer to the filename of the file to save 00454 pOpParam->Param2 - Should be 0 00455 Purpose: Saves the document into the file specified using the Native EPS filter 00456 00457 ********************************************************************************************/ 00458 00459 void OpMenuSave::DoWithParam(OpDescriptor*, OpParam* pOpParam) 00460 { 00461 // Extract the parameters. 00462 NativeFileOpParams* ppm = (NativeFileOpParams*) (void *) (pOpParam->Param1); 00463 00464 // Try to save the file. 00465 ERROR3IF(!ppm->pFile, "Null CCLexFile* in OpMenuSave::DoWithParam"); 00466 ppm->fStatus = ppm->pFile && FindFilterAndSave(ppm->pFile, ppm->nPrefFilter); 00467 End(); 00468 } 00469 00470 00471 00472 /******************************************************************************************** 00473 00474 > virtual void OpMenuSave::Do(OpDescriptor* pOpDesc) 00475 00476 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00477 Created: 31/3/95 00478 Inputs: pOpDesc - the OpDescriptor that called this op 00479 Purpose: Saves the Current Doc as the default document 00480 00481 ********************************************************************************************/ 00482 00483 void OpMenuSave::Do(OpDescriptor* pOpDesc) 00484 { 00485 //First get the selected document 00486 Document* pdocToSave=Document::GetSelected(); 00487 CCamDoc* pccamdocToSave = pdocToSave->GetOilDoc(); 00488 00489 if (pdocToSave==NULL || pccamdocToSave==NULL) 00490 { 00491 ERROR2RAW("No default document!"); 00492 return; 00493 } 00494 00495 //And we'll need a pointer to the application 00496 Application* pCamelot = GetApplication(); 00497 CTemplateManager& TemplateManager( pCamelot->GetTemplateManager() ); 00498 00499 //And put the default templates path in the dialog 00500 PathName pathToPutInDialog = TemplateManager.GetTemplatesPath(); 00501 00502 FileUtil::RecursiveCreateDirectory( pathToPutInDialog.GetPath() ); 00503 00504 //Now create the dialog 00505 SaveTemplateDialog dialogToDisplay(pathToPutInDialog); 00506 00507 //And show it 00508 if (dialogToDisplay.ShowModal() == wxID_OK) 00509 { 00510 //Then get the path they specified, using this amazingly bad, confusing and 00511 //undocumented file dialog code 00512 00513 //The "CString" reference should ideally go in Winoil 00514 PathName pathToSaveTo; 00515 dialogToDisplay.GetChosenFileName(&pathToSaveTo); 00516 00517 wxString cstrPathToSaveTo=pathToSaveTo.GetPath(FALSE); 00518 dialogToDisplay.AppendExtension(&cstrPathToSaveTo); 00519 00520 String_256 strPathToSaveTo=cstrPathToSaveTo; 00521 pathToSaveTo=strPathToSaveTo; 00522 00523 // Create the save file. 00524 CCDiskFile file(pathToSaveTo, ios::out | ios::binary | ios::trunc); 00525 00526 // First find the filter. 00527 Filter *pFilter = FindFilter ( FILTERID_NATIVE ); 00528 00529 // Tell it to save attributes. 00530 pFilter->SetSaveAttributes ( TRUE ); 00531 00532 // Then save the image to the file. 00533 Save ( pFilter, &file ); 00534 00535 //Now, if we should make that path the default path 00536 if (SaveTemplateDialog::m_fUseAsDefault) 00537 { 00538 if (pdocToSave->IsAnimated()) 00539 { 00540 CTemplateManager::SetDefaultAnimationTemplate( strPathToSaveTo ); 00541 } 00542 else 00543 { 00544 CTemplateManager::SetDefaultDrawingTemplate( strPathToSaveTo ); 00545 } 00546 } 00547 00548 if (SaveTemplateDialog::m_fDefaultTemplatesFolder) 00549 { 00550 String_256 strDefaultPath = pathToSaveTo.GetLocation( TRUE ); 00551 CTemplateManager::SetTemplatesPath( strDefaultPath ); 00552 } 00553 } 00554 00555 // Finished the operation 00556 End(); 00557 } 00558 00559 00560 00561 /******************************************************************************************** 00562 00563 > virtual UINT32 OpMenuSave::GetSearchFilterId() 00564 00565 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00566 Created: 16/7/96 00567 Inputs: - 00568 Returns: The id of the filter to search for. 00569 Purpose: To allow different ops to just specify different filters and reuse 00570 the same operation code to save out the file in different file 00571 formats. 00572 00573 ********************************************************************************************/ 00574 00575 UINT32 OpMenuSave::GetSearchFilterId() 00576 { 00577 //#ifdef NEW_NATIVE_FILTER 00578 // Use the new native filter 00579 return FILTERID_NATIVE; 00580 //#else 00581 // return FILTERID_NATIVE_EPS; 00582 //#endif 00583 } 00584 00585 00586 00587 /******************************************************************************************** 00588 00589 > virtual BOOL OpMenuSave::FixFileType() 00590 00591 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00592 Created: 1/8/96 00593 Inputs: - 00594 Outputs: - 00595 Returns: TRUE if fixing is required, FALSE otherwise 00596 Purpose: To determine whether this operation requires the file type or extension on 00597 the specified file path to be correct and match the filter we are about to use. 00598 This baseclass version says no as the old native save operation did not do 00599 it. 00600 00601 ********************************************************************************************/ 00602 00603 BOOL OpMenuSave::FixFileType() 00604 { 00605 //#ifdef NEW_NATIVE_FILTER 00606 // // Say we do want it in this baseclass version 00607 // return TRUE; 00608 //#else 00609 // Say we do not want it in this baseclass version 00610 return FALSE; 00611 //#endif 00612 } 00613 00614 00615 00616 /******************************************************************************************** 00617 00618 > virtual BOOL OpMenuSave::EnsureFileTypeCorrectId(Filter*, PathName& Path) 00619 00620 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00621 Created: 16/7/96 00622 Inputs: pFilter - The filter to save with 00623 Path - The pathname of the file to save to 00624 Returns: TRUE if it worked, FALSE if there was an error 00625 Purpose: To ensure that the file type or extension on the specified file path is 00626 correct and matches the filter we are about to use. 00627 00628 ********************************************************************************************/ 00629 00630 BOOL OpMenuSave::EnsureFileTypeCorrectId(Filter* pFilter, PathName& Path) 00631 { 00632 if (pFilter && pFilter->pOILFilter) 00633 { 00634 // Get the OILFilter class to check the extension for the selected or default filter 00635 // matches 00636 if (!pFilter->pOILFilter->DoesExtensionOfPathNameMatch(&Path)) 00637 { 00638 // Extension is either blank or does not match the one supplied by the filter 00639 // Ask the OILFilter class to fix it for us 00640 pFilter->pOILFilter->FixExtensionOfPathName(&Path); 00641 } 00642 } 00643 00644 return TRUE; 00645 } 00646 00647 00648 00649 /******************************************************************************************** 00650 00651 > virtual BOOL OpMenuSave::FindFilterAndSave ( CCLexFile* pFile, UINT32 nPrefFilter ) 00652 00653 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> and Graeme 00654 Created: 31/3/95 00655 Inputs: pFile - the file to save into 00656 nPrefFilter - the filter to use, or FILTERID_USERCHOICE if this 00657 Operation's default GetSearchFilterId filter should be 00658 used. 00659 Returns: TRUE if it worked, FALSE if not. FailAndExecute will have been called if 00660 FALSE is returned. 00661 Purpose: This function finds the appropriate filter to save with and saves the 00662 current doc into the file specified. This version is a wrapper around two 00663 methods, FindFilter () and Save (), which allows for a bit more flexibility 00664 in how the file output is handled. 00665 00666 ********************************************************************************************/ 00667 00668 BOOL OpMenuSave::FindFilterAndSave ( CCLexFile* pFile, UINT32 nPrefFilter ) 00669 { 00670 // Find the appropriate filter. 00671 Filter *pFilter = FindFilter ( nPrefFilter ); 00672 00673 // And save the file using it. 00674 return Save ( pFilter, pFile ); 00675 } 00676 00677 /******************************************************************************************** 00678 00679 > virtual Filter* OpMenuSave::FindFilter ( UINT32 nPrefFilter ) 00680 00681 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> and Graeme 00682 Created: 14/3/00 00683 Inputs: nPrefFilter - the filter to use, or FILTERID_USERCHOICE if this 00684 Operation's default GetSearchFilterId filter should be 00685 used. 00686 Returns: A pointer to a filter if successful, NULL otherwise. 00687 Purpose: Finds the appropriate filter type for the export being done. 00688 00689 ********************************************************************************************/ 00690 00691 Filter* OpMenuSave::FindFilter ( UINT32 nPrefFilter ) 00692 { 00693 UINT32 SearchFilterId = ( nPrefFilter != FILTERID_USERCHOICE ) ? nPrefFilter 00694 : GetSearchFilterId (); 00695 Filter* pFilter = Filter::GetFirst (); 00696 00697 while ( pFilter != NULL && pFilter->FilterID != SearchFilterId ) 00698 { 00699 // Try the next filter 00700 pFilter = Filter::GetNext ( pFilter ); 00701 } 00702 00703 // Make sure that we found the Native Filter 00704 if ( pFilter == NULL ) 00705 { 00706 InformError ( _R(IDT_CANT_FIND_FILTER) ); 00707 FailAndExecute (); 00708 } 00709 00710 return pFilter; 00711 } 00712 00713 /******************************************************************************************** 00714 00715 > virtual BOOL OpMenuSave::Save ( Filter *pFilter, CCLexFile *pFile ) 00716 00717 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> and Graeme 00718 Created: 14/3/00 00719 Inputs: pFilter - A pointer to an output filter. 00720 pFile - A pointer to the output file. 00721 Returns: TRUE if the file was successfully exported, FALSE if there was a problem. 00722 Purpose: Finds the appropriate filter type for the export being done. 00723 00724 ********************************************************************************************/ 00725 00726 BOOL OpMenuSave::Save ( Filter *pFilter, CCLexFile *pFile ) 00727 { 00728 // Check that the extension is ok according to this filter 00729 // But only if the operation requires it 00730 if (FixFileType()) 00731 { 00732 PathName pth = pFile->GetPathName(); 00733 if (pth.IsValid()) EnsureFileTypeCorrectId(pFilter, pth); 00734 } 00735 00736 // open the file and export into it 00737 if (!SaveSpecificFile(pFilter, pFile)) 00738 { 00739 FailAndExecute(); 00740 return FALSE; 00741 } 00742 00743 // Success. 00744 return TRUE; 00745 } 00746 00747 00748 00749 /******************************************************************************************** 00750 00751 > virtual BOOL OpMenuSave::SaveSpecificFile(Filter* pFilter, CCLexFile* pFile) 00752 00753 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00754 Created: 1/2/95 00755 Inputs: pFilter - The filter to save with 00756 pFile - The file to save to 00757 Returns: TRUE if it worked, FALSE if there was an error 00758 Purpose: Opens the file and calls the DoExport member of the filter, before closing 00759 the file again. If everything works as planned it returns TRUE 00760 00761 ********************************************************************************************/ 00762 00763 BOOL OpMenuSave::SaveSpecificFile(Filter* pFilter, CCLexFile* pFile) 00764 { 00765 ERROR2IF(pFilter == NULL,FALSE,"OpMenuSave::SaveSpecificFile null filter specified"); 00766 00767 // First off, we have to try and open the file 00768 BOOL AllOK = TRUE; 00769 // TRY 00770 { 00771 // Tell the filter we would like a Preview Bitmap please 00772 if (pFilter->CanIncludePreviewBmp()) pFilter->IncludePreviewBmp(TRUE); 00773 00774 // Try and export the file 00775 PathName pth = pFile->GetPathName(); 00776 00777 if (!pFilter->DoExport(this, pFile, &pth, Document::GetCurrent(), FALSE)) 00778 { 00779 // Something went a bit wrong - tell the user what it was. 00780 // Supress the error if it was the 'user has cancelled one' 00781 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 00782 { 00783 // Clean up after ourselves 00784 InformError(); 00785 } 00786 else 00787 Error::ClearError(); // otherwise remove the error so it won't get reported 00788 00789 // Set the error 00790 AllOK = FALSE; 00791 } 00792 } 00793 #if 0 00794 // See if there was a file io error 00795 CATCH(CFileException, e) 00796 { 00797 // Report the error if no one else did 00798 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 00799 { 00800 InformError(); 00801 } 00802 else 00803 Error::ClearError(); 00804 00805 // and fail 00806 return FALSE; 00807 } 00808 END_CATCH 00809 #endif 00810 // Tell the filter we would NOT like a Preview Bitmap ready for next time 00811 if (pFilter->CanIncludePreviewBmp()) pFilter->IncludePreviewBmp(FALSE); 00812 00813 // return 00814 return AllOK; 00815 } 00816 00817 00818 00819 /******************************************************************************************** 00820 00821 > BOOL OpMenuSave::Init() 00822 00823 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00824 Created: 21/12/94 00825 Returns: TRUE if it worked, FALSE if not 00826 Purpose: Registers the OpDescriptor for the Save Operation. 00827 00828 ********************************************************************************************/ 00829 00830 BOOL OpMenuSave::Init() 00831 { 00832 BOOL InitOK = TRUE; 00833 00834 // Register the save / save as... version 00835 // InitOK = RegisterOpDescriptor( 00836 // 0, // Tool ID 00837 // _R(IDT_IMPORT), // String resource ID 00838 // CC_RUNTIME_CLASS(OpMenuSave), // Runtime class 00839 // OPTOKEN_NATIVESAVE, // Token string 00840 // GetState, // GetState function 00841 // 0, // help ID 00842 // _R(IDBBL_FILESAVEOP), // bubble help 00843 // _R(IDD_BARCONTROLSTORE), // resource ID 00844 // _R(IDC_BTN_FILESAVE), // control ID 00845 // SYSTEMBAR_FILE, // Bar ID 00846 // TRUE, // Recieve system messages 00847 // FALSE, // Smart duplicate operation 00848 // TRUE, // Clean operation 00849 // 0, // No vertical counterpart 00850 // 0, // String for one copy only error 00851 // (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags 00852 // ); 00853 // if (!InitOK) return FALSE; 00854 if (!RegisterOpDescriptor(0, _R(IDT_IMPORT), CC_RUNTIME_CLASS(OpMenuSave), 00855 OPTOKEN_NATIVESAVE, GetState, 00856 0, _R(IDBBL_IMPORTFILEOP), 0)) 00857 return FALSE; 00858 00859 // Register the Save As Default version 00860 // if (!RegisterOpDescriptor(0, _R(IDT_SAVEASDEFAULT), CC_RUNTIME_CLASS(OpMenuSave), 00861 // OPTOKEN_SAVEASDEFAULT, GetState, 00862 // 0, _R(IDBBL_IMPORTFILEOP), 0)) 00863 // return FALSE; 00864 InitOK = RegisterOpDescriptor( 00865 0, // Tool ID 00866 _R(IDT_SAVEASDEFAULT), // String resource ID 00867 CC_RUNTIME_CLASS(OpMenuSave), // Runtime class 00868 OPTOKEN_SAVEASDEFAULT, // Token string 00869 GetState, // GetState function 00870 0, // help ID 00871 _R(IDBBL_FILESAVETEMPLATE), // bubble help 00872 _R(IDD_BARCONTROLSTORE), // resource ID 00873 _R(IDC_FILESAVETEMPLATE), // control ID 00874 SYSTEMBAR_FILE, // Bar ID 00875 TRUE, // Recieve system messages 00876 FALSE, // Smart duplicate operation 00877 TRUE, // Clean operation 00878 0, // No vertical counterpart 00879 0, // String for one copy only error 00880 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags 00881 ); 00882 if (!InitOK) return FALSE; 00883 00884 #ifdef NEW_NATIVE_FILTER 00885 // Only used by batching at present 00886 if (!OpSaveAsWeb::Init()) return FALSE; 00887 #endif 00888 // Used by the new saving code 00889 if (!OpSaveAsNativeV2::Init()) return FALSE; 00890 if (!OpSaveAsNativeV1::Init()) return FALSE; 00891 00892 // All worked 00893 return TRUE; 00894 } 00895 00896 00897 00898 00899 /******************************************************************************************** 00900 00901 > OpState OpMenuSave::GetState(String_256*, OpDescriptor*) 00902 00903 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00904 Created: 21/12/94 00905 Purpose: Another empty OpState function 00906 00907 ********************************************************************************************/ 00908 00909 OpState OpMenuSave::GetState( String_256* pUIDescription, OpDescriptor* pDesc ) 00910 { 00911 OpState OpSt; 00912 00913 return OpSt; 00914 } 00915 00916 00917 00918 /******************************************************************************************** 00919 / ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/ 00920 ********************************************************************************************/ 00921 00922 /******************************************************************************************** 00923 00924 > virtual UINT32 OpSaveAsNativeV1::GetSearchFilterId() 00925 00926 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00927 Created: 1/8/96 00928 Inputs: - 00929 Returns: The id of the filter to search for. 00930 Purpose: To allow different ops to just specify different filters and reuse 00931 the same operation code to save out the file in different file 00932 formats. 00933 00934 ********************************************************************************************/ 00935 00936 UINT32 OpSaveAsNativeV1::GetSearchFilterId() 00937 { 00938 return FILTERID_NATIVE_EPS; 00939 } 00940 00941 00942 00943 /******************************************************************************************** 00944 00945 > virtual BOOL OpSaveAsNativeV1::FixFileType() 00946 00947 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00948 Created: 1/8/96 00949 Inputs: - 00950 Outputs: - 00951 Returns: TRUE if fixing is required, FALSE otherwise 00952 Purpose: To determine whether this operation requires the file type or extension on 00953 the specified file path to be correct and match the filter we are about to use. 00954 This baseclass version says no as the old native save operation did not do 00955 it. 00956 00957 ********************************************************************************************/ 00958 00959 BOOL OpSaveAsNativeV1::FixFileType() 00960 { 00961 // Say we do want it in this baseclass version 00962 return TRUE; 00963 } 00964 00965 00966 00967 /******************************************************************************************** 00968 00969 > BOOL OpSaveAsNativeV1::Init() 00970 00971 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00972 Created: 1/8/96 00973 Returns: TRUE if it worked, FALSE if not 00974 Purpose: Registers the OpDescriptor for the Save Operation. 00975 00976 ********************************************************************************************/ 00977 00978 BOOL OpSaveAsNativeV1::Init() 00979 { 00980 BOOL InitOK = TRUE; 00981 00982 // Register the save as web op desciptor 00983 InitOK = RegisterOpDescriptor( 00984 0, // Tool ID 00985 _R(IDS_SAVEASNATIVEV1), // String resource ID 00986 CC_RUNTIME_CLASS(OpSaveAsNativeV1), // Runtime class 00987 OPTOKEN_SAVEASNATIVEV1, // Token string 00988 GetState, // GetState function 00989 0, // help ID 00990 _R(IDBBL_SAVEASNATIVEV1), // bubble help 00991 0, //_R(IDD_BARCONTROLSTORE), // resource ID 00992 0, //_R(IDC_FILESAVETEMPLATE), // control ID 00993 SYSTEMBAR_ILLEGAL, // Bar ID 00994 TRUE, // Recieve system messages 00995 FALSE, // Smart duplicate operation 00996 TRUE, // Clean operation 00997 0, // No vertical counterpart 00998 0, // String for one copy only error 00999 (DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC) // Auto state flags 01000 ); 01001 if (!InitOK) return FALSE; 01002 01003 // All worked 01004 return TRUE; 01005 } 01006 01007 01008 01009 /******************************************************************************************** 01010 01011 > OpState OpSaveAsNativeV1::GetState(String_256*, OpDescriptor*) 01012 01013 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01014 Created: 1/8/96 01015 Purpose: The OpState function 01016 01017 ********************************************************************************************/ 01018 01019 OpState OpSaveAsNativeV1::GetState(String_256 * pUIDescription, OpDescriptor*) 01020 { 01021 OpState OpSt; 01022 01023 return OpSt; 01024 } 01025 01026 #endif // DO_EXPORT