// $Id: impexpop.cpp 1690 2006-08-10 13:53:03Z gerry $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ // The operations for importing and exporting using the filter system. // These used to be are OILy as they used to invoke common dialogs etc // and hence used to be in OilFltrs.h/cpp // Moved to new kernel based impexpop.h/cpp 4/1/96 as there is now a class, BaseFileDialog // and derived classes which handle all of the OILy based common dialog functionality #include "camtypes.h" #include "camframe.h" #include "camelot.h" //#include "pathname.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "tim.h" //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "trans2d.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "andy.h" // for ID?_OVERWRITE, _R(IDE_FORMATNOTSUPPORTED) //#include "nev.h" // _R(IDN_USER_CANCELLED), _R(IDN_FILTERNOTPRESENT), _R(IDS_OPMENUIMPORT_ONE), _R(IDS_OPMENUEXPORT_ONE) #include "optsmsgs.h" // options messages IMPORTWITHLAYERS #include "bubbleid.h" //#include "simon.h" #include "impexpop.h" #include "filedlgs.h" // for ImportFileDialog & ExportFileDialog #include "helpuser.h" //#include "barsdlgs.h" // for the import/export bar controls #include "bitfilt.h" // BaseBitmapFilter #include "cameleps.h" //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "will3.h" #include "bmpsdlg.h" #include "exjpeg.h" #include "fileutil.h" #include "sgliboil.h" //#include "resimmap.h" // For _R(IDS_HTMLIMPORT_FILEDOWNLOAD) #include "webaddr.h" // For class WebAddress #include "opbevel.h" #include "bmapprev.h" #ifdef XAR_TREE_DIALOG #include "cxftree.h" #endif #if _DEBUG //#include "cmxtree.h" #endif //Webster-Ranbirr-12\11\96 #ifdef WEBSTER #define FILTER_JPEG 2 #define TWENTY_FOUR 24 #define ONE 1 #endif //webster // generic import filter //#include "gendwnd.h" //#include "webster.h" #include "ngsentry.h" #include "ngscan.h" //#include "justin3.h" #include "filtimag.h" // The imagemap filter class //#include "desnotes.h" // Dream weaver integration //#include "sliceres.h" // For _R(IDS_NOTES_WARNING) #include "strlist.h" CC_IMPLEMENT_DYNCREATE(OpMenuImport, SelOperation) CC_IMPLEMENT_DYNCREATE(OpMenuExport, SelOperation) CC_IMPLEMENT_DYNAMIC(BitmapExportParam, OpParam) CC_IMPLEMENT_DYNCREATE(OpDroppedFile, SelOperation) /******************************************************************************************** Preference: DefaultImportFilter Section: Filters Range: A filter ID. Purpose: The unique ID of the filter to default to when importing files. SeeAlso: DefaultImportFilterPath; DefaultExportFilter; DefaultExportFilterPath ********************************************************************************************/ /******************************************************************************************** Preference: DefaultImportFilterPath Section: Filters Range: A pathname. Purpose: The path to default to when opening the Import File dialog. SeeAlso: DefaultImportFilter; DefaultExportFilter; DefaultExportFilterPath ********************************************************************************************/ /******************************************************************************************** Preference: DefaultExportFilter Section: Filters Range: A filter ID. Purpose: The unique ID of the filter to default to when exporting files. SeeAlso: DefaultExportFilterPath; DefaultImportFilter; DefaultImportFilterPath ********************************************************************************************/ /******************************************************************************************** Preference: DefaultExportFilterPath Section: Filters Range: A pathname. Purpose: The path to default to when opening the Export File dialog. SeeAlso: DefaultExportFilter; DefaultImportFilter; DefaultImportFilterPath ********************************************************************************************/ // The most recently selected import filter UINT32 OpMenuImport::SelectedFilterID = FILTERID_GENERIC; INT32 OpMenuImport::SelectedFilter = -1; // String to hold the default path for both import and export filter dialogs. String_256 OpMenuImport::DefaultImportFilterPath; String_256 OpMenuExport::DefaultExportFilterPath; /******************************************************************************************** > BOOL OpMenuImport::Init() Author: Tim_Browse (Xara Group Ltd) Created: 22/02/94 Returns: TRUE if worked, FALSE if failed (out of memory) Purpose: Declares op descriptors for Acorn Draw file reading. Errors: Returns FALSE on failure. ********************************************************************************************/ BOOL OpMenuImport::Init() { // Derived off SelectionOperation which does not take 15 parameters. // (Misses out trhe vertical counterpart parameter) BOOL InitOK; InitOK = RegisterOpDescriptor( 0, // Tool ID _R(IDT_IMPORT), // String resource ID CC_RUNTIME_CLASS(OpMenuImport), // Runtime class OPTOKEN_MENUIMPORT, // Token string GetState, // GetState function 0, // help ID _R(IDBBL_FILEIMPORT), // bubble help _R(IDD_BARCONTROLSTORE), // resource ID _R(IDC_FILEIMPORT), // control ID SYSTEMBAR_FILE, // Bar ID TRUE, // Recieve system messages FALSE, // Smart duplicate operation TRUE, // Clean operation _R(IDS_OPMENUIMPORT_ONE), // String for one copy only error DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC // Auto state flags ); if (!InitOK) return FALSE; Camelot.DeclareSection(_T("Filters"), 5); Camelot.DeclarePref(_T("Filters"), _T("DefaultImportFilter"), &SelectedFilterID); Camelot.DeclarePref(_T("Filters"), _T("DefaultImportFilterPath"), &DefaultImportFilterPath); PORTNOTE("other", "Removed OpGenericDownload" ) #if 0 if (!OpGenericDownload::Init()) return FALSE; #endif return TRUE; } /******************************************************************************************** > void OpMenuImport::Do(OpDescriptor*) Author: Tim_Browse (Xara Group Ltd) Created: 22/02/94 Purpose: Imports a file into the current document. Errors: Various. Get reported to the user. ********************************************************************************************/ void OpMenuImport::Do(OpDescriptor*) { // zero is a bad state for this to be in so ensure its not in that state if (SelectedFilter == 0) SelectedFilter = -1; // Get the list of import filters FilterString = BaseFileDialog::BuildFilterString(TRUE, SelectedFilterID, &SelectedFilter); if (FilterString == 0) { // Unable to build filter string - report error and finish operation. InformError(); FailAndExecute(); // Finished the operation End(); return; } // Create the dialog box ImportFileDialog FDialog(FilterString); FDialog.SetTitle(_R(IDT_IMPORT_TITLE)); // Select the desired filter, if the default i.e. -1 then set 1 as this is the first valid index. if (SelectedFilter != -1) FDialog.SetSelectedFilterIndex(SelectedFilter); else FDialog.SetSelectedFilterIndex(1); // Select the desired path if (DefaultImportFilterPath.Length() > 0) FDialog.SetInitialDirectory(DefaultImportFilterPath); BOOL LayersImport = Filter::ImportWithLayers; // 'Do' the dialog and get that path/filename that we so desire BOOL DlgResult = FDialog.OpenAndGetFileName(); // Check if the import with layers button has been changed and if so send a message // to warn other users e.g. options dialog box if (LayersImport != Filter::ImportWithLayers) BROADCAST_TO_ALL(OptionsChangingMsg(OptionsChangingMsg::IMPORTWITHLAYERS)); if (!DlgResult) { // Get rid of the filter string buffer CCFree(FilterString); FilterString = 0; // User aborted - exit operation quietly. FailAndExecute(); End(); return; } // Remember the filter for next time. SelectedFilter = FDialog.GetSelectedFilterIndex(); TRACEUSER( "luke", _T("Looking for ordinal %d"), SelectedFilter ); // Get the filename, ensuring that the path is valid PathName Path; if (!FDialog.GetChosenFileName(&Path)) { InformError(); // Get rid of the filter string buffer CCFree(FilterString); FilterString = 0; FailAndExecute(); End(); return; } // Extract directory name (minus terminating backslash) and remember for next time. DefaultImportFilterPath = Path.GetLocation(FALSE); // Find the filter that the user chose Filter *pFilter = Filter::GetFirst(); while (pFilter != 0) { if( NULL != pFilter->pOILFilter ) { if( ( pFilter->GetFlags().CanImport && !IS_A( pFilter, CamelotEPSFilter ) ) && pFilter->pOILFilter->Position == SelectedFilter ) { TRACEUSER( "luke", _T("%s is THE filter (%d)"), (TCHAR*)pFilter->FilterName, pFilter->pOILFilter->Position ); // This is the filter! break; } TRACEUSER( "luke", _T("%s is not selected (ord=%d)"), (TCHAR*)pFilter->FilterName, pFilter->pOILFilter->Position ); } else TRACEUSER( "luke", _T("Can't handle NULL pFilter->pOILFilter for %s"), (TCHAR*)pFilter->FilterName ); // Try the next filter pFilter = Filter::GetNext(pFilter); } // Get rid of the filter string buffer CCFree(FilterString); FilterString = 0; if (pFilter == 0) { InformError(_R(IDT_CANT_FIND_FILTER)); FailAndExecute(); } else { SelectedFilterID = pFilter->FilterID; String_256 URL = Path.GetPath(); TRACEUSER( "luke", _T("Path = %s\n"), (TCHAR*)URL ); //Graham 14/7/97: Get the current view DocView* pDocView=DocView::GetCurrent(); //And find its centre import position ImportPosition posToUse=pDocView->GetCentreImportPosition(); // call the Import function DoImport(Path, pFilter, &URL, &posToUse); } } /******************************************************************************************** > void OpMenuImport::DoImport(PathName Path, Filter* pFilter, String_256* URL, ImportPosition* pImportPosition) Author: Olivier_Gascoin (Xara Group Ltd) gascoin Created: 07/05/97 Inputs: Path - local file pFilter - pointer to a filter URL - original URL of the imported file pImportPosition - position to import to (added by Graham 14/7/97) Purpose: import function ********************************************************************************************/ void OpMenuImport::DoImport(PathName Path, Filter* pFilter, String_256* URL, ImportPosition* pImportPosition) { // If this is not a filter family, check for compatibility before asking // filter to load the file. // This means the user has chosen an explicit filter to handle the import if (!pFilter->IS_KIND_OF(FilterFamily)) { UINT32 Size = 1024; size_t FileSize; ADDR FilterBuf = pFilter->LoadInitialSegment(Path, &Size, &FileSize); // If there has been a problem in the load initial segment then fail now. if (FilterBuf == 0) { // Tell the user about the problem and get out now while the goings good InformError(); FailAndExecute(); End(); return; } // Inform any filters that we are about to do a HowCompatible call. // This would allow a set of filters which have common functionality hidden in a // filter that cannot import and cannot export handle this call and hence set // itself up. This would allow it to maybe cache a result which should only be // checked by the first filter in the group. pFilter->PreHowCompatible(); // Change this to be less than 8 as the filters like the Accusoft forms return // 8 and 9 to make sure that they are last in the chain. if (pFilter->HowCompatible(Path, FilterBuf, Size, FileSize) < 8) { // Not 100% happy with this file - ask for confirmation. ErrorInfo Question; Question.ErrorMsg = _R(IDT_IMPQUERY_NOTSURE); Question.Button[0] = _R(IDB_IMPQUERY_IMPORT); Question.Button[1] = _R(IDB_IMPQUERY_DONTIMPORT); if (UINT32(AskQuestion(&Question)) != _R(IDB_IMPQUERY_IMPORT)) { // User asked for this to be cancelled. TRACEUSER( "Tim", _T("Filter compatibility was less than 10\n")); // Close the file, report the abort and finish. CCFree(FilterBuf); FailAndExecute(); InformMessage(_R(IDT_IMP_USERABORT)); End(); return; } } // Get rid of initial file header CCFree(FilterBuf); } // Start the selection operation if (DoStartSelOp(FALSE)) // We don't want to save the end selection status because // it will be restored automatically when the operation is // redone { // First off, we have to try and open the file CCDiskFile DiskFile(1024, FALSE, TRUE); // Get pointer to current doc 'cos we'll need it several times... Document* pCurDoc = Document::GetCurrent(); try { if (!DiskFile.open(Path, ios::in | ios::binary)) { // Failed to open the file... TRACEUSER( "Rik", _T("Failed to open file in MenuImport Do")); InformError(_R(IDT_IMPORT_NOTFOUND)); FailAndExecute(); End(); return; } // Import the file and see if Something went a bit wrong - tell the user what it was. if (!pFilter->DoImport(this, &DiskFile, pCurDoc, FALSE, pImportPosition, 0, 0, URL)) { // Only tell them if not special user cancelled error message if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) InformError(); else Error::ClearError(); // otherwise remove the error so it won't get reported FailAndExecute(); End(); // Close the file again if (DiskFile.isOpen()) DiskFile.close(); return; } // close the file if (DiskFile.isOpen()) DiskFile.close(); } // See if there was a file io error catch(CFileException e) { // Report the error if no one else did if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) InformError(); else Error::ClearError(); // otherwise remove the error so it won't get reported // Make sure that the file is closed try { if (DiskFile.isOpen()) DiskFile.close(); } catch(CFileException e) { // Failed to close the file - not much we can do about it really } // and fail FailAndExecute(); } } // grab the focus GetMainFrame()->SetFocus(); // Finished the operation End(); } /******************************************************************************************** > void OpMenuImport::EndImport() Author: Olivier_Gascoin (Xara Group Ltd) Created: 09/05/97 Purpose: End the operation. It's called by GenericDownloadOp::OnDownloadFail() ********************************************************************************************/ void OpMenuImport::EndImport() { FailAndExecute(); End(); } /******************************************************************************************** > BOOL OpMenuImport::OnDocChangingMsg(Document* pChangingDoc, DocChangingMsg::DocState State) Author: Olivier_Gascoin (Xara Group Ltd) Created: 15/05/97 Inputs: pChangingDoc - State - Returns: Purpose: End (abort) the operation when for instance the current document has been destroyed while downloading. Errors: ********************************************************************************************/ BOOL OpMenuImport::OnDocChangingMsg(Document* pChangingDoc, DocChangingMsg::DocState State) { if (State == DocChangingMsg::ABOUTTODIE && pChangingDoc == pOurDoc) { EndImport(); } return TRUE; } /******************************************************************************************** > OpMenuImport::OpMenuImport() Author: Tim_Browse (Xara Group Ltd) Created: 22/02/94 Purpose: Constructor for OpMenuImport operation. ********************************************************************************************/ OpMenuImport::OpMenuImport() { OpFlags.HasOwnTimeIndicator = TRUE; // The OpMenuImport op has its own time indicator } /******************************************************************************************** > OpState OpMenuImport::GetState(String_256*, OpDescriptor*) Author: Tim_Browse (Xara Group Ltd) Created: 22/02/94 Purpose: This item is always available, so long as a document is visible. ********************************************************************************************/ OpState OpMenuImport::GetState(String_256*, OpDescriptor*) { OpState OpSt; return OpSt; } INT32 OpMenuExport::SelectedFilter = -1; INT32 OpMenuExport::SelectedBitmapFilter = -1; // There was an #ifdef WEBSTER directive here that specified the initial file type for the // export menu. I've removed this, but should a new Webster ever be needed, the initial type // was: // // UINT32 OpMenuExport::SelectedFilterID = FILTERID_WEB; // UINT32 OpMenuExport::DefaultBitmapFilterID = FILTERID_BMP; // // The WEBSTER directive was being triggered by the full build of Camelot. UINT32 OpMenuExport::SelectedFilterID = FILTERID_EXPORT_JPEG; UINT32 OpMenuExport::DefaultBitmapFilterID = FILTERID_EXPORT_JPEG; List * OpMenuExport::m_pSelNodeList = 0; /******************************************************************************************** > BOOL OpMenuExport::Init() Author: Tim_Browse (Xara Group Ltd) Created: 22/03/94 Returns: TRUE if worked, FALSE if failed (out of memory) Purpose: Declares op descriptor for export operation. Errors: Returns FALSE on failure. ********************************************************************************************/ BOOL OpMenuExport::Init() { // derived off operation so takes 16 parameters including the vertical counterpart BOOL InitOK; InitOK = RegisterOpDescriptor( 0, // Tool ID _R(IDT_EXPORT), // String resource ID CC_RUNTIME_CLASS(OpMenuExport), // Runtime class OPTOKEN_MENUEXPORT, // Token string GetState, // GetState function 0, // help ID _R(IDBBL_FILEEXPORT), // bubble help _R(IDD_BARCONTROLSTORE), // resource ID _R(IDC_FILEEXPORT), // control ID SYSTEMBAR_FILE, // Bar ID TRUE, // Recieve system messages FALSE, // Smart duplicate operation FALSE, // Clean operation // 0, // No vertical counterpart _R(IDS_OPMENUEXPORT_ONE), // String for one copy only error DONT_GREY_WHEN_SELECT_INSIDE | GREY_WHEN_NO_CURRENT_DOC // Auto state flags ); if (!InitOK) return FALSE; Camelot.DeclareSection(_T("Filters"), 5); Camelot.DeclarePref(_T("Filters"), _T("DefaultExportFilter"), &SelectedFilterID); Camelot.DeclarePref(_T("Filters"), _T("DefaultExportFilterPath"), &DefaultExportFilterPath); Camelot.DeclarePref(_T("Filters"), _T("DefaultBitmapFilter"), &DefaultBitmapFilterID); return TRUE; } /******************************************************************************************** > void OpMenuExport::Do(OpDescriptor*) Author: Tim_Browse (Xara Group Ltd) Created: 22/03/94 Purpose: Exports a file from the current document. Most of the work is now done by the DoWithParam. Errors: Various. Get reported to the user. ********************************************************************************************/ void OpMenuExport::Do(OpDescriptor* OpDesc) { DoWithParam(OpDesc, 0); } /******************************************************************************************** > static void OpMenuExport::SaveSelection() Author: David_McClarnon (Xara Group Ltd) / JustinF Created: 9/1/2000 Purpose: Saves the selection so it can be restored ********************************************************************************************/ void OpMenuExport::SaveSelection() { if (m_pSelNodeList) { m_pSelNodeList->DeleteAll(); delete m_pSelNodeList; m_pSelNodeList = 0; } SelRange* pRng = GetApplication()->FindSelection(); if (pRng == 0) { ERROR3("No SelRange in OpMenuExport::SaveSelection"); return; } pRng->SetGag(TRUE); m_pSelNodeList = pRng->MakeListOfNodes(FALSE); } /******************************************************************************************** > static void OpMenuExport::NormaliseSelection() Author: Justin_Flude (Xara Group Ltd) Created: 9/1/2000 Purpose: Fixes-up the selection for compound objects. ********************************************************************************************/ void OpMenuExport::NormaliseSelection() { // run through the range selecting all PromoteToParent nodes SelRange* pRng = GetApplication()->FindSelection(); if (pRng == 0) { ERROR3("No range in OpMenuExport::NormaliseSelection"); return; } for (Node* pNode = pRng->FindFirst(FALSE); pNode != 0; pNode = pRng->FindNext(pNode, FALSE)) if (pNode->IsAnObject()) for (Node* pParent = pNode->FindParent(); pParent != 0 && pParent->IsAnObject(); pParent = pParent->FindParent()) if (pParent->ShouldITransformWithChildren()) { pParent->SetSelected(FALSE); pParent->SetSelected(TRUE); } pRng->Update(); } /******************************************************************************************** > static void OpMenuExport::RestoreSelection() Author: David_McClarnon (Xara Group Ltd) / JustinF Created: 9/1/2000 Inputs: Purpose: Restores the selection given in m_pSelNodeList ********************************************************************************************/ void OpMenuExport::RestoreSelection() { SelRange* pRng = GetApplication()->FindSelection(); if (pRng == 0) { ERROR3("No range in OpMenuExport::RestoreSelection"); return; } if (pRng->IsSelRangeGagged()) pRng->SetGag(FALSE); NodeRenderableInk::DeselectAll(FALSE, FALSE); if (!m_pSelNodeList) { ERROR3("Sel node list not set up"); return; } for (NodeListItem* pItem = (NodeListItem*) m_pSelNodeList->GetHead(); pItem != 0; pItem = (NodeListItem*) m_pSelNodeList->GetNext(pItem)) if (pItem->pNode != 0) pItem->pNode->SetSelected(TRUE); m_pSelNodeList->DeleteAll(); delete m_pSelNodeList; m_pSelNodeList = 0; RangeControl rg = pRng->GetRangeControlFlags(); rg.PromoteToParent = FALSE; pRng->Range::SetRangeControl(rg); pRng->Update(); // pRng->Update(TRUE); } void RemoveUneededReportedErrors() { // clear silly error before End()ing the op // Only tell them if not special user cancelled error message if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED) && Error::GetErrorNumber() != 0) InformError(); else Error::ClearError(); // otherwise remove the error so it won't get reported } /******************************************************************************************** > void OpMenuExport::DoWithParam(OpDescriptor*, OpParam* pParam) Author: Neville_Humphrys (Xara Group Ltd) Created: 25/04/95 Inputs: pParam if 0 then assumed to be a normal export using any filter if not 0 then assumed to be a KernelBitmap* and wanting to export as a bitmap. Purpose: Exports a file from the current document. Errors: Various. Get reported to the user. ********************************************************************************************/ void OpMenuExport::DoWithParam(OpDescriptor*, OpParam* pParam) { // DMc - need to do this so that compound nodes are treated appropriately SaveSelection(); NormaliseSelection(); //Webster-Ranbirr-12\11\96 #ifdef WEBSTER // Temp. variable to store the filter type. INT32 BitmapFilter = 0; #endif //webster // zero is a bad state for this to be in so ensure its not in that state if (SelectedFilter == 0) SelectedFilter = -1; if (SelectedBitmapFilter == 0) SelectedBitmapFilter = -1; ERROR3IF(pParam != 0 && !pParam->IS_KIND_OF(BitmapExportParam), "OpMenuExport::DoWithParam: OpParam passed is not a BitmapExportParam"); // Check whether a parameter has been specified UINT32 Bpp = 0; BitmapExportParam* pExportParam = (BitmapExportParam*) pParam; if (pExportParam != 0) { // At present, this is only used to export the specifed bitmap so use a list // of bitmap filters. We need to limit the bitmap filters to ones that can support // the colour depth of the specified bitmap. // Recover the bitmap pointer from the parameter passed in KernelBitmap* pTheBitmap; if (pExportParam->GetBitmapCount() == 0 || (pTheBitmap = pExportParam->GetBitmap(0)) == 0) { ERROR2RAW("OpMenuExport::DoWithParam: no bitmaps, or null pointer"); FailAndExecute(); RestoreSelection(); End(); return; } // If it is a 32 bpp bitmap then we do a conversion to 24. So really we should ask // the filters whether they like 24bpp files. Otherwise, just the BMP filter will say // yes. Bpp = pTheBitmap->GetBPP(); // if (Bpp == 32) Bpp = 24; //Webster-Ranbirr-12\11\96 /* #ifndef WEBSTER FilterString = BaseFileDialog::BuildFilterString( FALSE, DefaultBitmapFilterID, &SelectedBitmapFilter, CC_RUNTIME_CLASS(BitmapFilter), Bpp, pExportParam->GetBitmapCount()); #else */ // Save a reference to the last selected Filter, in case Cancel is entered. //BitmapFilter = SelectedBitmapFilter; // Is this bitmap a compressed JPEG? BitmapSource* pSource = 0; BaseBitmapFilter* pDummyFilter; BOOL OriginalSourcePresent = pTheBitmap->GetOriginalSource(&pSource,&pDummyFilter); if (OriginalSourcePresent) { DefaultBitmapFilterID = FILTERID_EXPORT_JPEG; SelectedBitmapFilter = 0; //FILTER_JPEG; } else { } FilterString = BaseFileDialog::BuildFilterString( FALSE, DefaultBitmapFilterID, &SelectedBitmapFilter, CC_RUNTIME_CLASS(BitmapFilter), Bpp, pExportParam->GetBitmapCount()); // #endif //webster } else { // Get the list of export filters using all filters available FilterString = BaseFileDialog::BuildFilterString( FALSE, SelectedFilterID, &SelectedFilter); } if (FilterString == 0) { // Unable to build filter string - report error and finish operation. InformError(); FailAndExecute(); // Finished the operation RestoreSelection(); End(); return; } // Create the dialog box ExportFileDialog FDialog(FilterString); INT32 TheSelectedFilter = -1; String_256 DefaultName; FDialog.SetTitle(_R(IDT_EXPORT_TITLE)); // Note this ptr for use in JPEG export. // KernelBitmap* pBitmap = pExportParam->GetBitmap(0); // JPEGExportOptions::SetKernelBitmap(pBitmap); if (pExportParam == 0) TheSelectedFilter = SelectedFilter; // Using all available filters else { // Exporting as a bitmap so fill in the name of the bitmap KernelBitmap* pTheBitmap = pExportParam->GetBitmap(0); if (pTheBitmap->ActualBitmap) DefaultName = pTheBitmap->ActualBitmap->GetName(); else SetBitmapName(pTheBitmap, &DefaultName, pExportParam); // Pass this name onto the dialog box FDialog.SetDefaultFileName(DefaultName); FDialog.ExportABitmap(TRUE, pTheBitmap); // Now work out the selected index, if there is one TheSelectedFilter = SelectedBitmapFilter; } // Select the desired filter, if the default i.e. -1 then set 1 as this is the first valid index. FDialog.SetSelectedFilterIndex(TheSelectedFilter != -1 ? TheSelectedFilter : 1); // Select the desired path if (DefaultExportFilterPath.Length() > 0) FDialog.SetInitialDirectory(DefaultExportFilterPath); // We maybe asking uses to specify a file name more than // once if theie first guess already exists PathName Path; Filter* pFilter; do { // 'Do' the dialog and get that filename that we require BOOL DlgResult = FDialog.OpenAndGetFileName(); if (!DlgResult) { //Webster-Ranbirr-12\11\96 #ifdef WEBSTER // If cancel is entered then ensure that our filter // is set to the previous selected filter. SelectedBitmapFilter = BitmapFilter; #endif //webster CCFree(FilterString); FilterString = 0; RestoreSelection(); End(); return; } // Remember the filter for next time. TheSelectedFilter = FDialog.GetSelectedFilterIndex(); if (pExportParam == 0) SelectedFilter = TheSelectedFilter; // Using all available filters else SelectedBitmapFilter = TheSelectedFilter; // Exporting as a bitmap only // Get the filename. FDialog.GetChosenFileName(&Path); // Find the filter that the user chose for (pFilter = Filter::GetFirst(); pFilter != 0; pFilter = Filter::GetNext(pFilter)) { if( NULL == pFilter->pOILFilter ) continue; if (pFilter->GetFlags().CanExport && pFilter->pOILFilter->Position == TheSelectedFilter) // This is the filter! break; } if (pFilter == 0) { InformError(_R(IDT_CANT_FIND_FILTER)); // Get rid of the filter string buffer CCFree(FilterString); FilterString = 0; RestoreSelection(); FailAndExecute(); End(); return; } // This is now taken care of in FileDlgs.cpp on the ok as it then checks if the file // exists or not. If we do it here then this does not happen. // Unfortunately, chnages made to the string in the dialog do not filter through // and so we must fix it up here as well. // Always make sure that the filter's default extension is on if the user has not // specified an extension. // Get the OILFilter class to check the extension for the selected or default filter // matches if (!pFilter->pOILFilter->DoesExtensionOfPathNameMatch(&Path)) { // Extension is either blank or does not match the one supplied by the filter // Ask the OILFilter class to fix it for us pFilter->pOILFilter->FixExtensionOfPathName(&Path); } // Ensure that the path is valid if (!Path.IsValid()) { InformError(); // Get rid of the filter string buffer CCFree(FilterString); FilterString = 0; FailAndExecute(); RestoreSelection(); End(); return; } // We must manually check the file doesn't exit here if( SGLibOil::FileExists( &Path ) ) { ErrorInfo Info; Info.ErrorMsg = _R(IDS_SAVEAS_OVERWRITE); Info.Button[0] = _R(IDS_OVERWRITE); Info.Button[1] = _R(IDB_SAVEAS); Info.Button[2] = _R(IDS_CANCEL); UINT32 Answer = AskQuestion(&Info); if (Answer==_R(IDS_OVERWRITE)) { // Just use the name the user selected to overwite the existing file break; } else if (Answer== _R(IDB_SAVEAS)) { // User wants to save as some other name continue; } else if (Answer==_R(IDS_CANCEL)) { // User has chosen to abort the operation End(); return; } else ERROR3("Unknown Answer from AskQuestion"); } } while( SGLibOil::FileExists( &Path ) ); PORTNOTE("other", "Removed BmapPrevDlg usage" ) #if !defined(EXCLUDE_FROM_XARALX) // Need to set the path for the export dialog (used for image map stuff etc) BmapPrevDlg::m_pthExport = Path; #endif // Extract directory name (minus terminating backslash) and remember for next time. DefaultExportFilterPath = Path.GetLocation(FALSE); UINT32 TheSelectedFilterID = pFilter->FilterID; if (pExportParam == 0) SelectedFilterID = TheSelectedFilterID; // Using all available filters else DefaultBitmapFilterID = TheSelectedFilterID; // Exporting as a bitmap only // If we are exporting using an EPS based filter and not the CamelotEPS or NativeEPS // filters then must warn the user that the EPS data does not save all info and question // whether they want to continue or not. // This used to use IS_KIND_OF VectorFilter before 29/4/96 but of course this // really wants to be for all the eps based filters and not all vector filters // Graeme (11-4-00) - Added FILTERID_AIEPS to stop the warnings when doing an // AI format export. After all, the AIEPS filter is probably better specified // these days than the other EPS filters. if (TheSelectedFilterID != FILTERID_CAMELOT_EPS && TheSelectedFilterID != FILTERID_NATIVE_EPS && TheSelectedFilterID != FILTERID_AIEPS && pFilter->IS_KIND_OF ( EPSFilter ) ) { // Warn the user that they are not exporting in Camelot EPS or native // format, and get them to confirm that this is what they want to do. // (We only do this for vector formats) ErrorInfo Info; Info.ErrorMsg = _R(IDT_EXPQUERY_NOTSURE); Info.Button[0] = _R(IDB_EXPQUERY_EXPORT); Info.Button[1] = _R(IDB_EXPQUERY_DONTEXPORT); if (UINT32(AskQuestion(&Info)) == _R(IDB_EXPQUERY_DONTEXPORT)) { // User decided not to export - abort. CCFree(FilterString); FilterString = 0; FailAndExecute(); RestoreSelection(); End(); return; } } BOOL fExportedOk = FALSE; /////////////////////////////////////////////////////////////////////////////// // for the future "Options" button handling // get the export options // what we need is for the export dlg to appear and give the user the chance // to fill in the export options // SMFIX BitmapExportOptions* pOptions = NULL; if (pFilter->IS_KIND_OF(BaseBitmapFilter)) { if (BmapPrevDlg::m_pExportOptions) { delete BmapPrevDlg::m_pExportOptions; BmapPrevDlg::m_pExportOptions = 0; } // only if it is a raster type and we are not saving from the gallery if (pExportParam == 0) { // set up with default attrib for this filter // and get the user to edit these default params in the export dlg (thats the FALSE param) PORTNOTE("other", "Use SetUpExportOptions to get defaults only and not do dialog" ) ((BaseBitmapFilter*) pFilter)->SetUpExportOptions(&pOptions, FALSE); // ((BaseBitmapFilter*) pFilter)->SetUpExportOptions(&pOptions, TRUE); // the dlg has been up and the user may have the graphic type // ask the dlg for the type that it used if (BmapPrevDlg::m_pExportOptions) pOptions = BmapPrevDlg::m_pExportOptions; // take responsibility for the export options away from the bmp preview dlg BmapPrevDlg::m_pExportOptions = 0; // the filter we want to export with will change too if the export options have changed type if (pOptions) { Filter * pOldFilter = pFilter; pFilter = pOptions->FindBitmapFilterForTheseExportOptions(); // change the export extent if we have changed filters if (pFilter && pFilter != pOldFilter) { // set the path extention Path.SetType(BmapPrevDlg::m_pthExport.GetType()); } else pFilter = pOldFilter; } if (!pOptions || !pFilter) { // User decided not to export - abort. RemoveUneededReportedErrors(); CCFree(FilterString); FilterString = 0; FailAndExecute(); RestoreSelection(); End(); return; } // do the odd details that a filter may need setting before it is ready to go (sjk 5/12/00) ((BaseBitmapFilter*) pFilter)->PostGetExportOptions(pOptions); } } BOOL bFinished = FALSE; // check if we can simply rename the temp file created during preview if (pOptions != 0 && pOptions->HasTempFile() && !pOptions->GetSeparateLayerFiles()) { // get the temp file name PathName TempPath = pOptions->GetPathName(); String_256 FinalName = Path.GetPath(); String_256 TempName = TempPath.GetPath(); // delete the empty file, if one was created, and try to rename the file FileUtil::DeleteFile(&Path); /* #if defined(__WXGTK__) && FALSE != wxUSE_UNICODE char pszTempName[256]; char pszFinalName[256]; wcstombs( pszTempName, TempName, 256 ); wcstombs( pszFinalName, FinalName, 256 ); #else char* pszTempName = TempName; char* pszFinalName = FinalName; #endif bFinished = !rename(pszTempName, pszFinalName); */ // This should do the trick but I've left the old code in case bFinished = !camRename(TempName, FinalName); if (bFinished) { fExportedOk = TRUE; // Only tell them if not special user cancelled error message RemoveUneededReportedErrors(); } } // Set flag telling exporter that we are NOT exporting a temporary file! if(pOptions) pOptions->SetTempFileFlag(FALSE); PORTNOTE( "export", "Removed image map code" ) #if !defined(EXCLUDE_FROM_XARALX) // Now export the image map if required if (pOptions && pOptions->GetSupportsImageMap() && pFilter->IS_KIND_OF(BaseBitmapFilter)) static_cast(pFilter)->ExportImagemap(this, &Path, GetWorkingDoc()); #endif if (pOptions != NULL) { //And if we should be exporting an HTML tag to the clipboard if (pOptions->ShouldPutHTMLTagOnClipboard() && pFilter->IS_KIND_OF(BaseBitmapFilter)) static_cast(pFilter)->ExportHTMLTag(&Path); PORTNOTE("other", "Removed DreamWeaver DesignNote code" ) #if 0 // Do we want to make the extra dream weaver design notes file? if (pOptions->GetCanUseDesignNotes() && UsesDesignNotes()) { if( !lstrcmpi( Path.GetType(), _T("gif") ) || !lstrcmpi( Path.GetType(), _T("jpg") ) || !lstrcmpi( Path.GetType(), _T("bmp") ) || !lstrcmpi( Path.GetType(), _T("png") ) ) { wxString DocName( (TCHAR *)Document::GetCurrent()->GetLocation() ); DocName += _T("\\"); DocName += (TCHAR *)Document::GetCurrent()->GetPathName(); if (DocName != _T("\\") ) { wxString GraphicFile( (const TCHAR *)Path.GetPath() ); // create or modify a .mno forward source file CreateDesignNoteWithForwardSource(GraphicFile, DocName); } else { InformWarning (_R(IDS_NOTES_WARNING)); } } } #endif } if (!bFinished) { // either no temp file, or failed to rename it, do normal export /////////////////////////////////////////////////////////////////////////////// // First off, we have to try and open the file CCDiskFile theDiskFile(1024, FALSE, TRUE); try { /* File now opened up, if not already opened inside the DoExport functions in the filters // themselves. This means this is done after the export options and so the file is not trashed // until we start doing something to it. // Open up the file. This will create a zero length file just to make sure that it // is possible, i.e. we have write access. // Opened up here so that the filters do not need to know about opening the files and // closing them and so the preview filter can easily be used to append data into the // middle of the native and eps files. // Added 27/9/95 ios::trunc as exporting a bitmap or eps file to the same file twice // appended the data to the end of the file on Windows 95. if (!theDiskFile.open(Path, ios::in | ios::out | ios::binary | ios::trunc)) { // Failed to open the file... InformError(_R(IDT_EXPORT_NOTFOUND)); FailAndExecute(); End(); return; } */ // Do we want a Preview Bitmap? if (pFilter->CanIncludePreviewBmp()) pFilter->IncludePreviewBmp(TRUE); // Export the file if (pExportParam != 0) { ERROR3IF(!pFilter->IS_KIND_OF(BaseBitmapFilter), "OpMenuExport::not a bitmap filter"); BaseBitmapFilter* pBitmapFilter = (BaseBitmapFilter*) pFilter; if (pExportParam->GetBitmapCount() != 1) fExportedOk = pBitmapFilter->DoExportBitmaps( this, // Export bitmaps &theDiskFile, &Path, pExportParam); else { /////////////////////////////////////////////////////////////////////////////// // for the future "Options" button handling if (pFilter->IS_KIND_OF(BaseBitmapFilter) && pOptions) fExportedOk = pBitmapFilter->DoExportBitmapWithOptions( this, // Export bitmap &theDiskFile, &Path, pExportParam->GetBitmap(0), pOptions); else /////////////////////////////////////////////////////////////////////////////// fExportedOk = pBitmapFilter->DoExportBitmap( this, // Export bitmap &theDiskFile, &Path, pExportParam->GetBitmap(0)); } } else { /////////////////////////////////////////////////////////////////////////////// // for the future "Options" button handling if (pFilter->IS_KIND_OF(BaseBitmapFilter) && pOptions/*&& CCamApp::IsNewWindowsUI()*/) fExportedOk = ((BaseBitmapFilter*) pFilter)->DoExportWithOptions( this, // Export drawing &theDiskFile, &Path, GetWorkingDoc(), pOptions); else fExportedOk = pFilter->DoExport(this, // Export drawing &theDiskFile, &Path, GetWorkingDoc()); } if (!fExportedOk) { if (Error::GetErrorNumber() == _R(IDN_USER_CANCELLED)) // Suppress the error if it was the 'user has cancelled one'. Error::ClearError(); else { // Something went a bit wrong - tell the user what it was. InformError(); pFilter->DeleteExportFile(&theDiskFile); } } // We had better tell the filter we no longer want Previews if (pFilter->CanIncludePreviewBmp()) pFilter->IncludePreviewBmp(FALSE); // close the file if (theDiskFile.isOpen()) theDiskFile.close(); } // See if there was a file io error catch( CFileException e ) { // Report the error if no one else did RemoveUneededReportedErrors(); // Make sure that the file is closed and deleted try { // First try and delete it (tries to close it first) and // double check to make sure it is closed. if (pFilter) pFilter->DeleteExportFile(&theDiskFile); if (theDiskFile.isOpen()) theDiskFile.close(); } catch(CFileException e) { // Failed to close the file - not much we can do about it really TRACE( _T("Failed to close file\n")); } fExportedOk = FALSE; } /////////////////////////////////////////////////////////////////////////////// // for the future "Options" button handling } /////////////////////////////////////////////////////////////////////////////// // Get rid of the filter string buffer and restore the original selection. CCFree(FilterString); FilterString = 0; RestoreSelection(); if (!fExportedOk) { // delete the export options if (pOptions) delete pOptions; FailAndExecute(); End(); return; } // TODO: did we export only the selection? BOOL fExportedSelection = FALSE; if (pFilter->IS_KIND_OF(BaseBitmapFilter) && pParam == 0 && pOptions) { fExportedSelection = (pOptions->GetSelectionType() == SELECTION); } // Make named export sets from the user's exported selections. if (fExportedSelection) CreateNamedSet(pFilter, Path); // this will call Fail or Succeed else SucceedAndDiscard(); // delete the export options if (pOptions) delete pOptions; End(); } /******************************************************************************************** > void OpMenuExport::CreateNamedSet(Filter* pFilter, const PathName& pthTarget) Author: Justin_Flude (Xara Group Ltd) Created: 4/1/96 Inputs: The context of the just-performed export of the selected objects. Purpose: Creates a named export set from the selected objects and the export information passed to it. ********************************************************************************************/ void OpMenuExport::CreateNamedSet(Filter* pFilter, const PathName& pthTarget) { PORTNOTETRACE("other", "CreateNamedSet - Do nothing - Use NgScan"); #if !defined(EXCLUDE_FROM_XARALX) // Try to create a named set for them based on the filename chosen. String_256 strName(pthTarget.GetFileName(FALSE)); NodeSetSentinel* pSentry = GetWorkingDoc()->GetSetSentinel(); NodeSetProperty* pSet = pSentry->FindPropertyNode(strName); // This code used to first check if a set of that the name & path existed with the // same type, then if it could find such a set it would reuse it rather than creating // a new set (w/ a unique name). I have changed this so the type of the export does // not matter any more (Jonathan 2 January 2001). BOOL fMustCreateNewSet = TRUE; if (pSet != 0) { NamedExportProp* pProp = (NamedExportProp*) pSet->GetProperty(NamedExportProp::nIndex); if (/* pProp->GetFilter() != pFilter || */ pProp->GetPath().GetLocation() != pthTarget.GetLocation() || pProp->GetPath().GetFileName(FALSE) != pthTarget.GetFileName(FALSE)) { // Make the set name unique by appending ascending numerals. String_256 strBase = strName; INT32 nAppend = 2; while (pSentry->GetNameAttr(strName) != 0) strName.MakeMsg(_R(IDS_NAMEDLG_UNIQUE_MASK), &strBase, nAppend++); } else // Same name & same path - it must be the existing set that is // being referred to so don't make a new one, just update the properties of // the one that exists (used to include filter type when checking to see if // we can reuse the existing name but not any more). fMustCreateNewSet = FALSE; } // If necessary, create a new named set of the selected objects. if (fMustCreateNewSet) { TRACEUSER( "JustinF", _T("Creating export set %s\n"), (LPCTSTR) strName); // This is taken from the implementation of OpApplyNameToSel. AllowOpScan aosSel(this, &theSelectedObjects), aosSentinel(this, &theSetSentinel); if (!aosSel.Scan() || !aosSentinel.Scan() || !DoStartSelOp(FALSE, FALSE) || !ApplySingleScan(this, &theSelectedObjects, strName).Scan() || !ApplySingleScan(this, &theSetSentinel, strName).Scan() || !ApplyPropScan(this, strName).Scan() || !aosSel.Update() || !aosSentinel.Update() || (pSet = pSentry->FindPropertyNode(strName)) == 0) { TRACEUSER( "JustinF", _T("OpMenuExport::CreateNamedSet: naming scan failed\n")); FailAndExecute(); return; } } // Remember the export filter and the path to the target. NamedExportProp* pProp = (NamedExportProp*) pSet->GetProperty(NamedExportProp::nIndex); ERROR3IF(pProp == 0, "OpMenuExport::CreateNamedSet: no export property"); pProp->SetFilter(pFilter); pProp->SetPath(pthTarget); pProp->SetDirty(); // Since the user has picked the graphic type it has been toutched and so in NOT a virgin // Remember the options associated with the filter. // TODO: fix this one day so that all filters are supported. ERROR3IF(!pFilter->IS_KIND_OF(BaseBitmapFilter), "OpMenuExport::CreateNamedSet: not a bitmap filter"); BitmapExportOptions* pOptions = ((BaseBitmapFilter*) pFilter)->GetBitmapExportOptions(); pProp->SetOptions(pOptions); #endif } /******************************************************************************************** > BOOL OpMenuExport::SetBitmapName(KernelBitmap* pTheBitmap, String_256 * DefaultName, BitmapExportParam* pExportParam = 0) Author: Neville_Humphrys (Xara Group Ltd) Created: 4/1/96 Inputs: pTheBitmap the bitmap that we are interested in pExportParam the BitmapExportParameters we're using to export this bitmap Outputs: DefaultName name to fill in Returns: TRUE if it worked, FALSE if not Purpose: Interegates the bitmap for its name and dumps this into the given string. If there is an extension on the bitmap name then it will fix this to be correct for the filter that will be selected. If there is no extension then it will just append the correct extension onto the name. ********************************************************************************************/ BOOL OpMenuExport::SetBitmapName(KernelBitmap * pTheBitmap, String_256 * DefaultName, BitmapExportParam* pExportParam) { OILBitmap* pOilBitmap = pTheBitmap->ActualBitmap; if (pOilBitmap) { *DefaultName = pOilBitmap->GetName(); // We must add the extension on for the selected or default filter // Only add the extension if none is present already. // If an extension is present then check that it corresponds to the selected or default filter PathName TempPath(*DefaultName); String_32 Extension = TempPath.GetType(); // Find the filter that the user chose Filter *pFilter = Filter::GetFirst(); while (pFilter != 0) { if ((pFilter->GetFlags().CanExport) && (pFilter->FilterID == DefaultBitmapFilterID)) // This is the filter! break; // Try the next filter pFilter = Filter::GetNext(pFilter); } if (pFilter && pFilter->pOILFilter) { // Get the OILFilter class to check the extension for the selected or default filter // matches if (!pFilter->pOILFilter->DoesExtensionOfPathNameMatch(&TempPath)) { // Extension is either blank or does not match the one supplied by the filter // Ask the OILFilter class to fix it for us pFilter->pOILFilter->FixExtensionOfPathName(&TempPath); // Now copy that back into the name *DefaultName = TempPath.GetPath(); } // If this was imported from a multi-image file // then we want to either bin the number or tag it on the end // Actually this whole practice is rather dubious since file names may // contain the search string. Wait for a proper fix to import bitmap! String_256 fileName = TempPath.GetFileName(FALSE); // without extension // Search for the image index and throw it away... String_32 searchString; searchString.MakeMsg(_R(IDS_BITMAP_NAME), "",""); INT32 index = fileName.Sub(searchString); if (index > 0) // it had a number...probably { if (pExportParam != 0 && pExportParam->GetBitmapCount() > 1) { // multiple bitmaps - throw away any numbering // oops...keeps the LHS (ignores #1 position) fileName.Left(&fileName, index); } else // single bitmap - tag the number on the end, no spaces { fileName.Remove(index, searchString.Length()); } TempPath.SetFileName(fileName); *DefaultName = TempPath.GetPath(); } } } return TRUE; } /******************************************************************************************** > OpState OpMenuExport::GetState(String_256*, OpDescriptor*) Author: Tim_Browse (Xara Group Ltd) Created: 22/03/94 Purpose: This item is always available, so long as a document is visible. ********************************************************************************************/ OpState OpMenuExport::GetState(String_256 * pUIDescription, OpDescriptor * pOpDesc) { //Removed - Ranbir. //Fixes a bug. //We cannot set the Greyed.State to TRUE, as the Save button in the bitmap gallery //also relies on this getstate function. /* #ifdef WEBSTER // In Webster, we will grey out the Export option if there are no visible objects on the page OpState OpSt; String_256 DisableReason; // Is there a selected spread? Spread * pSpread = Document::GetSelectedSpread(); if (pSpread) { DocRect VisibleRect = pSpread->GetPageVisibleBounds(); BOOL Empty = VisibleRect.IsEmpty(); if (!Empty) { // There's a visible rect, so there must be exportable objects, so don't grey out OpSt.Greyed = FALSE; } else { // No visible objects, so grey it out and say why OpSt.Greyed = TRUE; // Load reason why operation is disabled DisableReason = String_256(_R(IDS_NO_VISIBLE_OBJECTS)); if (pUIDescription) *pUIDescription = DisableReason; } } else { // No selected spread, so we are greyed OpSt.Greyed = TRUE; // Load reason why operation is disabled DisableReason = String_256(_R(IDS_NO_DOC)); if (pUIDescription) *pUIDescription = DisableReason; } return OpSt; #else */ OpState OpSt; return OpSt; //#endif // WEBSTER } /******************************************************************************************** > BOOL OpDroppedFile::Init() Author: Tim_Browse (Xara Group Ltd) Created: 22/03/94 Returns: TRUE if worked, FALSE if failed (out of memory) Purpose: Declares op descriptor for drag'n'drop file operation. Errors: Returns FALSE on failure. ********************************************************************************************/ BOOL OpDroppedFile::Init() { if (!RegisterOpDescriptor(0, _R(IDT_IMPORT), CC_RUNTIME_CLASS(OpDroppedFile), OPTOKEN_DROPPEDFILE, GetState, 0, // help ID 0, 0)) // bitmap ID return FALSE; return TRUE; } /******************************************************************************************** > void OpDroppedFile::DoWithParam(OpDescriptor*, OpParam* pOpParam) Author: Tim_Browse (Xara Group Ltd) Created: 29/07/94 Inputs: pOpDesc - the OpDescriptor for this operation pOpParam - parameters for this operations; actually an HDROP handle. Purpose: Import the files dropped onto the specified document. ********************************************************************************************/ #define PATH_BUF_SIZE (256) void OpDroppedFile::DoWithParam(OpDescriptor*, OpParam* pOpParam) { // Get the file list FileDropInfo* pFileInfo = (FileDropInfo*) pOpParam; List* pFileList = pFileInfo->GetFileList(); #ifdef XAR_TREE_DIALOG CXFTreeDlg* pCXFTreeDlg = CXFTreeDlg::GetCurrentCXFTreeDlg(); if (pCXFTreeDlg != 0) { StringListItem* pItem = (StringListItem*)(pFileList->GetHead()); if (pItem) pCXFTreeDlg->ShowFile((TCHAR*)(pItem->GetString())); End(); return; } #endif #if FALSE #if _DEBUG CMXTreeDlg* pCMXTreeDlg = CMXTreeDlg::GetCurrentCMXTreeDlg(); if (pCMXTreeDlg != 0) { char PathBuf[PATH_BUF_SIZE]; PathBuf[0] = 0; // Get the next filename UINT32 cBytes = DragQueryFile(hDrop, 0, PathBuf, PATH_BUF_SIZE); pCMXTreeDlg->ShowFile(PathBuf); End(); return; } #endif #endif // Make sure we have a generic filter! GenericFilter *pGenericFilter = Filter::GetGenericFilter(); if (pGenericFilter == 0) { InformError(_R(IDT_CANT_FIND_FILTER)); FailAndExecute(); End(); return; } // Get me a DocView! DocView *pDocView = DocView::GetCurrent(); // Sanity checks... if (pDocView == 0) { ERROR3("No current DocView while procesing drag'n'drop!"); // give the user a random error, should never happen but just in case give them some // indication that something has gone wrong. InformError(_R(IDT_CANT_FIND_FILTER)); FailAndExecute(); End(); // Exit cleanly return; } // Find out where the files were dropped... WinCoord DropPoint = pFileInfo->GetDropPoint(); // DragQueryPoint(hDrop, &DropPoint); // Turn this into Oil coordinates... OilCoord OilPos = DropPoint.ToOil(pDocView); // ...find the spread in which the click happened... ImportPosition Pos; Pos.pSpread = pDocView->FindEnclosingSpread(OilPos); if (Pos.pSpread == 0) { ERROR3("Could not find spread in which the drag'n'drop happened"); // give the user a random error, should never happen but just in case give them some // indication that something has gone wrong. InformError(_R(IDT_CANT_FIND_FILTER)); FailAndExecute(); End(); return; // Exit reasonably nicely } // First of all convert the OilCoord into device coords Pos.Position = OilPos.ToDoc(Pos.pSpread, pDocView); // Translate the coord to spread coords Pos.pSpread->DocCoordToSpreadCoord(&Pos.Position); // Find out how many files were dropped // UINT32 cFiles = DragQueryFile(hDrop, (UINT32) -1, 0, 0); UINT32 cFiles = pFileList->GetCount(); StringListItem* pItem = (StringListItem*)(pFileList->GetHead()); // Load each file in turn... for (UINT32 iFile = 0; iFile < cFiles; iFile++) { // char PathBuf[PATH_BUF_SIZE]; // PathBuf[0] = 0; // Get the next filename // UINT32 cBytes = DragQueryFile(hDrop, iFile, PathBuf, PATH_BUF_SIZE); String_256 Str = pItem->GetString(); // Check it's not too long // if (cBytes > (PATH_BUF_SIZE - 5)) // { // // Too long - inform user and try the next file. // Error::SetError(_R(IDT_FILENAME_TOO_LONG)); // InformError(); // } // else { // Import this file... // PathName Path(PathBuf); PathName Path(Str); // Ensure that the path is valid if ( !Path.IsValid() ) { // Pathname specified is invalid InformError(); FailAndExecute(); End(); return; } // First off, we have to try and open the file CCDiskFile DiskFile(1024, FALSE, TRUE); // Get pointer to current doc 'cos we'll need it several times... Document* pCurDoc = Document::GetCurrent(); try { if (!DiskFile.open(Path, ios::in | ios::binary)) { // Failed to open the file... TRACEUSER( "Rik", _T("Failed to open file in MenuImport Do")); InformError(_R(IDT_IMPORT_NOTFOUND)); FailAndExecute(); End(); return; } // Import the file and see if Something went a bit wrong - tell the user what it was. if (!pGenericFilter->DoImport(this, &DiskFile, pCurDoc, FALSE, &Pos)) { // Something went a bit wrong - tell the user what it was. // Only tell them if not special user cancelled error message if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) InformError(); else Error::ClearError(); // otherwise remove the error so it won't get reported FailAndExecute(); End(); // Close the file again if (DiskFile.isOpen()) DiskFile.close(); return; } // Close the file again if (DiskFile.isOpen()) DiskFile.close(); } // See if there was a file io error catch(CFileException e) { // Report the error if no one else did if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) InformError(); else Error::ClearError(); // otherwise remove the error so it won't get reported // Make sure that the file is closed try { if (DiskFile.isOpen()) DiskFile.close(); } catch(CFileException e) { // Failed to close the file - not much we can do about it really } // and fail FailAndExecute(); } } // Get the next file name item pItem = (StringListItem*)(pFileList->GetNext(pItem)); } // Finished the operation End(); return; } /******************************************************************************************** > OpState OpDroppedFile::GetState(String_256*, OpDescriptor*) Author: Tim_Browse (Xara Group Ltd) Created: 22/03/94 Purpose: This item is always available, so long as a document is visible. ********************************************************************************************/ OpState OpDroppedFile::GetState(String_256*, OpDescriptor*) { OpState OpSt; return OpSt; } /******************************************************************************************** > BitmapExportParam::BitmapExportParam() Author: Neville_Humphrys (Xara Group Ltd) Created: 13/5/97 Purpose: Default Constructor ********************************************************************************************/ BitmapExportParam::BitmapExportParam(): OpParam(0, 0) { m_pBmpDlgParam = 0; } /******************************************************************************************** > BitmapExportParam::BitmapExportParam(UINT32 Count, KernelBitmap** pBitmap) Author: Peter_Arnold (Xara Group Ltd) Created: 11/6/96 Inputs: Count - The number of indexes in the array pBitmap - pointer to an array of pointers to kernel bitmaps Outputs: - Returns: - Purpose: Used to pass around lists of bitmaps. Note that deleting the bitmap array is the responsibility of the caller. ********************************************************************************************/ BitmapExportParam::BitmapExportParam(UINT32 Count, KernelBitmap** pBitmap, BmpDlgParam* pParam) : OpParam((INT32)Count, (void *)pBitmap) { ERROR3IF(Count==0, "Zero bitmap count, that's not right"); ERROR3IF(pBitmap==0, "0 bitmap array"); ERROR3IF(!(*pBitmap)->IS_KIND_OF(KernelBitmap), "This dosen't seem to be an array of kernel bitmaps"); // Save a reference to the BmpDlgParam, for use in BmpPrefsDlg. SetBmpDlgParam(pParam); } /******************************************************************************************** > virtual UINT32 BitmapExportParam::GetBitmapCount() Author: Peter_Arnold (Xara Group Ltd) Created: 11/6/96 Inputs: - Outputs: - Returns: The number of bitmaps in the bitmap array. (The array runs 0..Count-1) Purpose: For getting the number of bitmaps in the array! ********************************************************************************************/ UINT32 BitmapExportParam::GetBitmapCount() { return (UINT32)Param1; } /******************************************************************************************** > virtual KernelBitmap* BitmapExportParam::GetBitmap(UINT32 Index) Author: Peter_Arnold (Xara Group Ltd) Created: 11/6/96 Inputs: Index - the index of the required bitmap Outputs: - Returns: Pointer to the nth bitmap, 0 if error Purpose: For safely getting a pointer to a bitmap in the bitmap array ********************************************************************************************/ KernelBitmap* BitmapExportParam::GetBitmap(UINT32 Index) { ERROR2IF(Index>=(UINT32)Param1, 0, "Index out of bounds"); ERROR2IF(Param2==0, 0, "0 array"); ERROR3IF( !( ( (KernelBitmap**)(void *)Param2 )[Index])->IS_KIND_OF(KernelBitmap), "This dosen't seem to be a pointer to a kernel bitmap"); return( (KernelBitmap**)(void *)Param2 )[Index]; } /******************************************************************************************** > void BitmapExportParam::SetBmpDlgParam(BmpDlgParam* pParam) Author: Ranbir_Rana (Xara Group Ltd) Created: 05/01/96 Inputs: pParam - Allows the transfer of bitmap info. Outputs: - Returns: - Purpose: - ********************************************************************************************/ BOOL BitmapExportParam::SetBmpDlgParam(BmpDlgParam* pParam) { ERROR2IF(pParam == 0,FALSE, "pParam is 0"); m_pBmpDlgParam = pParam; return TRUE; }