00001 // $Id: filtimag.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 #include "camtypes.h" 00100 #include "filtimag.h" 00101 00102 //#include "filters.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00103 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00104 00105 //#include "resource.h" // for _R(IDS_OUT_OF_MEMORY) 00106 00107 //#include "camfiltr.h" // for BaseCamelotFilter progress update - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "app.h" // Camelot - in camtypes.h [AUTOMATICALLY REMOVED] 00109 00110 //#include "resimmap.h" // Imagemap resources 00111 00112 #include "fimagdlg.h" //Imagemap dialog 00113 #include "filtimag.h" 00114 00115 //#include "docview.h" //For DocView::GetCurrent - in camtypes.h [AUTOMATICALLY REMOVED] 00116 #include "clipint.h" //For InternalClipboard::CopyText 00117 #include "helpuser.h" //For GetNextMsgHelpContext 00118 00119 #include "sgliboil.h" //For file utility functions to do with temp files 00120 #include "fileutil.h" //For file utility functions to do with temp files 00121 00122 #include "strlist.h" //For class StringListItem 00123 00124 //#include "osrndrgn.h" //For OSRenderRegion class to convert DocRect coords to WinRect -matt 24/08/2000 00125 //#include "htmlexp.h" //For WriteNumber 00126 //#include "dialogop.h" //For DialogOp::GetLongGadgetValue 00127 //#include "imagdlg.h" //_R(IDC_IMAGEMAP_HEIGHT) 00128 //#include "filtimop.h" 00129 00130 00131 00132 CC_IMPLEMENT_MEMDUMP(ImagemapFilter, Filter) 00133 00134 #define new CAM_DEBUG_NEW 00135 00136 TCHAR ImagemapFilter::ms_strApprox[] = _T("ExportImagemap\\CurveApproximation"); 00137 TCHAR ImagemapFilter::ms_strAllRectangles[] = _T("ExportImagemap\\AllRectangles"); 00138 TCHAR ImagemapFilter::ms_strClipboard[] = _T("ExportImagemap\\Clipboard"); 00139 TCHAR ImagemapFilter::ms_strFile[] = _T("ExportImagemap\\File"); 00140 TCHAR ImagemapFilter::ms_strInsert[] = _T("ExportImagemap\\Insert"); 00141 00142 ImagemapFilterOptions ImagemapFilter::ms_Options=ImagemapFilterOptions(); 00143 00144 /******************************************************************************************** 00145 00146 Constructors and initialiser 00147 00148 *********************************************************************************************/ 00149 00150 /******************************************************************************************** 00151 00152 > ImagemapFilter::ImagemapFilter() 00153 00154 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00155 Created: 9/4/97 00156 Purpose: Default constructor 00157 00158 ********************************************************************************************/ 00159 ImagemapFilter::ImagemapFilter() 00160 { 00161 //First set up the members of the filter class 00162 ExportMsgID = _R(IDS_EXPORTMSG_IMAGEMAP); 00163 00164 Flags.CanImport = FALSE; 00165 Flags.CanExport = TRUE; 00166 00167 Flags.CanExportMultipleImages = FALSE; 00168 Flags.ShowFilter = TRUE; 00169 00170 FilterID = FILTERID_IMAGEMAP; 00171 00172 //Set the pointer to our render region as NULL 00173 m_pRegion=NULL; 00174 00175 //And set up our options to a set of default values 00176 ImagemapFilter::ms_Options=ImagemapFilterOptions(); 00177 00178 BackgroundRedrawStateSet=FALSE; 00179 BackgroundRedrawState=FALSE; 00180 } 00181 00182 /******************************************************************************************** 00183 00184 > BOOL ImagemapFilter::Init() 00185 00186 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00187 Created: 9/4/97 00188 Returns: TRUE if the filter was initialized ok 00189 FALSE otherwise 00190 Purpose: Initializes the ImagemapFilter. 00191 00192 ********************************************************************************************/ 00193 BOOL ImagemapFilter::Init() 00194 { 00195 // Set up our associated oil filter 00196 pOILFilter = new ImagemapOILFilter(this); 00197 00198 //If we failed to set it up, return FALSE 00199 if (pOILFilter==NULL) 00200 return FALSE; 00201 00202 // Load the description strings 00203 FilterName.Load(_R(IDS_FILTERNAME_IMAGEMAP)); 00204 FilterInfo.Load(_R(IDS_FILTERINFO_IMAGEMAP)); 00205 00206 //And declare those variables which we want to save in the registry 00207 if (DeclareFilterPreferenceSection()) 00208 { 00209 Camelot.DeclarePref( NULL, ms_strApprox, (INT32*) &ms_Options.m_ffApprox, FF_VERYCLOSELY, FF_NOTATALL); 00210 Camelot.DeclarePref( NULL, ms_strAllRectangles, &ms_Options.m_fAllRectangles, FALSE, TRUE); 00211 Camelot.DeclarePref( NULL, ms_strClipboard, &ms_Options.m_fClipboard, FALSE, TRUE); 00212 Camelot.DeclarePref( NULL, ms_strFile, &ms_Options.m_fFile, FALSE, TRUE); 00213 Camelot.DeclarePref( NULL, ms_strInsert, &ms_Options.m_fInsert, FALSE, TRUE); 00214 } 00215 00216 PORTNOTE("other","Remove ImagemapDlg usage - not defined yet"); 00217 #ifndef EXCLUDE_FROM_XARALX 00218 //Initialise the ExportOptions dialog 00219 ImagemapDlg::Init(); 00220 #endif 00221 00222 //And return 00223 return TRUE; 00224 } 00225 00226 /******************************************************************************************** 00227 00228 > ImagemapFilter::~ImagemapFilter() 00229 00230 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00231 Created: 9/4/97 00232 Purpose: Destructor. Deletes the render region pointer. 00233 00234 ********************************************************************************************/ 00235 ImagemapFilter::~ImagemapFilter() 00236 { 00237 //Delete our render region pointer if it's pointing to something 00238 m_pRegion=NULL; 00239 00240 } 00241 00242 00243 /******************************************************************************************** 00244 00245 Filter entry points 00246 00247 *********************************************************************************************/ 00248 00249 /******************************************************************************************** 00250 00251 > BOOL ImagemapFilter::DoExport(Operation* pOp, 00252 CCLexFile* pFile, 00253 PathName* pPath, 00254 Document* pDoc, 00255 BOOL ShowOptions); 00256 00257 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00258 Created: 9/4/97 00259 Returns: TRUE if the export was OK 00260 FALSE if there were any errors 00261 00262 Purpose: This function is called when the user has gone to the 00263 Export... dialog box, chosen the imagemap filter and 00264 clicked the Export button. 00265 00266 This function simply calls three member functions in turn 00267 in order to: 00268 00269 - Put up a dialog box to get some options from the user 00270 - Set those options as current within the filter 00271 - Export the file using those options 00272 00273 ********************************************************************************************/ 00274 00275 BOOL ImagemapFilter::DoExport(Operation* pOp, 00276 CCLexFile* pFile, 00277 PathName* pPath, 00278 Document* pDoc, 00279 BOOL ShowOptions) 00280 { 00281 //First we need to get some ImagemapFilterOptions from the user 00282 //To do this, create a blank set of ImagemapFilterOptions 00283 ImagemapFilterOptions ifoNew=ms_Options; 00284 00285 //And specify within those options that we want to 00286 //export to a file 00287 ifoNew.m_fFile=TRUE; 00288 00289 //And specify the name of that file as being the path we have been given 00290 ifoNew.m_pthFile=*pPath; 00291 00292 //And specify a pointer to that file 00293 ifoNew.m_pfileFile=pFile; 00294 00295 //And remember we're reporting errors 00296 ifoNew.m_fReportErrors=TRUE; 00297 00298 //And call up the dialog box to fill them in 00299 //If this function returns FALSE, the user has cancelled the dialog 00300 if (GetOptionsFromUser(&ifoNew, pPath, pFile)) 00301 { 00302 00303 //Set those options as current within the filter 00304 SetFilterOptions(ifoNew); 00305 00306 //And export to the file using those options 00307 return PrepareAndWriteData(pDoc); 00308 } 00309 else 00310 //If the user has cancelled the dialog, return TRUE anyway 00311 return TRUE; 00312 } 00313 00314 00315 /******************************************************************************************** 00316 00317 > BOOL ImagemapFilter::PrepareAndWriteData(Document* pDoc) 00318 00319 00320 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00321 Created: 9/4/97 00322 Returns: TRUE if the export was OK 00323 FALSE if there were any errors 00324 00325 Purpose: Calculates an imagemap based on the file pDoc and the current 00326 set of ImagemapFilterOptions. Then writes this out to 00327 either a file or the clipboard (as specified in the options). 00328 00329 This function is called by both ImagemapFilter::DoExport 00330 and the BaseBitmapFilter class. 00331 00332 ********************************************************************************************/ 00333 00334 BOOL ImagemapFilter::PrepareAndWriteData(Document* pDoc) 00335 { 00336 //This variable will keep track of any problems 00337 BOOL ok=TRUE; 00338 00339 //First set up the data to export 00340 ok=PrepareData(pDoc); 00341 00342 // if there was a problem, or the region is empty 00343 if (!ok || m_pRegion->IsEmpty()) 00344 { 00345 //delete the render region 00346 if (m_pRegion) 00347 delete m_pRegion; 00348 m_pRegion = NULL; 00349 00350 //If there was a problem, return FALSE 00351 if (!ok) 00352 return FALSE; 00353 00354 //If there is no data, and we are reporting errors, put up a message box to say so 00355 if (ms_Options.m_fReportErrors) 00356 { 00357 ERROR1(TRUE, _R(IDE_IMAGEMAP_NODATA)); 00358 } 00359 else 00360 return TRUE; 00361 } 00362 00363 //Otherwise, export the data 00364 ok=WriteData(); 00365 00366 //And delete the render region 00367 if (m_pRegion) 00368 delete m_pRegion; 00369 m_pRegion = NULL; 00370 00371 return ok; 00372 00373 } 00374 00375 /******************************************************************************************** 00376 00377 > BOOL ImagemapFilter::PrepareData(Document* pdocToExport) 00378 00379 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00380 Created: 29/4/97 00381 Returns: TRUE if successful 00382 00383 Purpose: Sets up the imagemap data in the render region. 00384 00385 Does not export that data to the file. 00386 00387 ********************************************************************************************/ 00388 00389 BOOL ImagemapFilter::PrepareData(Document* pdocToExport) 00390 { 00391 //Set up the render region 00392 BOOL ok=PrepareRenderRegion(pdocToExport); 00393 00394 //If that worked... 00395 if (ok) 00396 { 00397 //Render into our ImagemapRenderRegion 00398 //to set the data 00399 ExportRender(m_pRegion); 00400 00401 //Restore the settings of the render region 00402 RestoreBackgroundRedraw(pView); 00403 } 00404 00405 //And return 00406 return ok; 00407 } 00408 00409 /******************************************************************************************** 00410 00411 > BOOL ImagemapFilter::WriteData() 00412 00413 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00414 Created: 9/4/97 00415 Returns: TRUE if the export was OK 00416 FALSE if there were any errors 00417 00418 Purpose: Writes the data in the ImagemapRenderRegion either to a file 00419 or to the clipboard, as specified in the ImagemapFilterOptions. 00420 00421 00422 00423 ********************************************************************************************/ 00424 BOOL ImagemapFilter::WriteData() 00425 { 00426 //And this variable will keep track of errors 00427 BOOL ok=TRUE; 00428 00429 //Now, should we be writing to a file? 00430 if (ms_Options.m_fFile) 00431 { 00432 //Yes, we should. So we should have been passed a path name 00433 //and a pointer to that file. So retrieve them. 00434 PathName pthExportFile=ms_Options.m_pthFile; 00435 CCLexFile* pfileExportFile=ms_Options.m_pfileFile; 00436 00437 //Now, does this path name refer to an existing file? And if 00438 //it does refer to an existing file, then have we been told to insert 00439 //our imagemap into that file? 00440 if (SGLibOil::FileExists(&pthExportFile) && ms_Options.Insert()) 00441 { 00442 //Yes. So insert the data into the file 00443 ok=WriteDataToExistingFile(pfileExportFile, &pthExportFile); 00444 } 00445 else 00446 { 00447 //No, either it's a new file or we haven't been told to 00448 //insert our data into the file. So write to a new file 00449 //(and if the file does exist, it will be overwritten). 00450 ok=WriteDataToNewFile(pfileExportFile, &pthExportFile); 00451 } 00452 } 00453 else 00454 { 00455 //No. So should we be writing to the clipboard? 00456 if (ms_Options.m_fClipboard) 00457 { 00458 //Yes. So do that now. 00459 ok=WriteDataToNewFile(NULL, NULL); 00460 } 00461 } 00462 00463 //And delete the render region 00464 if (m_pRegion) 00465 delete m_pRegion; 00466 m_pRegion=NULL; 00467 00468 //And return 00469 return ok; 00470 } 00471 00472 /******************************************************************************************** 00473 00474 > virtual BOOL ImagemapFilter::WillAcceptExistingFile(PathName pthToReplace) 00475 00476 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00477 Created: 9/5/97 00478 Returns: TRUE if this filter is willing to accept this existing file 00479 FALSE otherwise 00480 Purpose: Checks if the user wants to export to this existing file. 00481 00482 To do this, we put up a message box with three options: Insert, 00483 Overwrite and Cancel. 00484 00485 ********************************************************************************************/ 00486 00487 BOOL ImagemapFilter::WillAcceptExistingFile(PathName pthToReplace) 00488 { 00489 //So first get the truncated path name 00490 String_256 strToReplace = pthToReplace.GetTruncatedPath(50); 00491 00492 //Now create a string to put our error message in 00493 String_256 strError; 00494 00495 //And make the error message up using the file name 00496 strError.MakeMsg(_R(IDM_IMAGEMAP_INSERT), &strToReplace); 00497 00498 //Now, set that error message as the next one to display 00499 Error::SetError( 0, strError, 0 ); 00500 00501 //And set up the message help context 00502 SetNextMsgHelpContext(_R(IDM_IMAGEMAP_INSERT)); 00503 00504 //Now set up the buttons 00505 ErrorInfo Info; 00506 Info.Button[0] = _R(IDB_IMAGEMAP_INSERT); 00507 Info.Button[1] = _R(IDB_IMAGEMAP_REPLACE); 00508 Info.Button[2] = _R(IDS_CANCEL); 00509 00510 //Make Insert the default 00511 //and Cancel the cancel button 00512 Info.OK = 1; 00513 Info.Cancel = 3; 00514 00515 //And put the error box up 00516 const UINT32 uResult = AskQuestion( &Info ); 00517 if( uResult == _R(IDB_IMAGEMAP_INSERT) ) 00518 ms_Options.m_fInsert=TRUE; 00519 else 00520 if( uResult == _R(IDB_IMAGEMAP_REPLACE) ) 00521 ms_Options.m_fInsert=FALSE; 00522 else 00523 if( uResult ==_R(IDS_CANCEL) ) 00524 return FALSE; 00525 00526 return TRUE; 00527 } 00528 00529 /******************************************************************************************** 00530 00531 > void ImagemapFilter::SearchFileForImagemaps(const PathName& pthSearch, List* plstToAdd) 00532 00533 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00534 Created: 4/7/97 00535 Inputs: pthSearch The path of the file to search 00536 plstToAdd Pointer to a list to add the map names to 00537 00538 Returns: - 00539 00540 Purpose: Goes through the file pointed to by pthSearch. 00541 00542 Each time it finds an imagemap tag <MAP NAME=xxx>, it adds 00543 the value of the NAME parameter into the list pointed to by 00544 plstToAdd. 00545 00546 It does this all by calling the function BuildMapNamesList. 00547 00548 See Also: ImagemapFilter::BuildMapNamesList(); 00549 00550 ********************************************************************************************/ 00551 00552 void ImagemapFilter::SearchFileForImagemaps(const PathName& pthSearch, List* plstToAdd) 00553 { 00554 //First create a disk file 00555 CCDiskFile fileOpen(1024, FALSE, TRUE); 00556 00557 //Create a copy of the path name we've been given 00558 PathName pthOpen=pthSearch; 00559 00560 //And call BuildMapNamesList to do all the work 00561 BuildMapNamesList(&fileOpen, &pthOpen, plstToAdd); 00562 00563 } 00564 00565 00566 00567 00568 00569 00570 00571 /******************************************************************************************** 00572 00573 Access functions 00574 00575 Functions to set and get the values of member variables 00576 00577 *********************************************************************************************/ 00578 00579 00580 /******************************************************************************************** 00581 00582 > void ImagemapFilter::SetFilterOptions(ImagemapFilterOptions ifoOptions) 00583 00584 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00585 Created: 9/4/97 00586 Inputs: ifoOptions The options to set as current within the filter 00587 Returns: - 00588 00589 Purpose: Sets ifoOptions as current within the filter 00590 00591 ********************************************************************************************/ 00592 00593 void ImagemapFilter::SetFilterOptions(ImagemapFilterOptions ifoOptions) 00594 { 00595 //Simply copy the options into our static member variable 00596 ms_Options=ifoOptions; 00597 } 00598 00599 /******************************************************************************************** 00600 00601 > ImagemapFilterOptions ImagemapFilter::GetFilterOptions() 00602 00603 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00604 Created: 9/4/97 00605 Inputs: - 00606 Returns: The current set of imagemap filter options 00607 00608 Purpose: Returns the current set of imagemap filter options 00609 00610 ********************************************************************************************/ 00611 00612 ImagemapFilterOptions ImagemapFilter::GetFilterOptions() 00613 { 00614 //Return the filter options 00615 return ms_Options; 00616 } 00617 00618 00619 /******************************************************************************************** 00620 00621 Action functions 00622 00623 Functions which are called by the entry point functions to do things 00624 00625 *********************************************************************************************/ 00626 00627 /******************************************************************************************** 00628 00629 BOOL ImagemapFilter::GetOptionsFromUser(ImagemapFilterOptions* pifoDefault, 00630 PathName* pPath, CCLexFile* pFile) 00631 00632 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00633 Created: 9/4/97 00634 Inputs: pifoDefault A set of ImagemapFilterOptions that 00635 will appear in the dialog box when it starts 00636 pPath Path to the file we are writing to 00637 pFile The file we are writing to 00638 Outputs: A set of ImagemapFilterOptions from the user 00639 Returns: FALSE if the dialog was cancelled 00640 00641 Purpose: Puts up the Export Options... dialog box to get a 00642 set of ImagemapFilterOptions from the user. 00643 00644 ********************************************************************************************/ 00645 00646 BOOL ImagemapFilter::GetOptionsFromUser(ImagemapFilterOptions* pifoDefault, PathName* ppthFile, CCLexFile* pFile) 00647 { 00648 ERROR2IF (pifoDefault==NULL, FALSE, "ImagemapFilter::GetOptionsFromUser - NULL parameter"); 00649 00650 PORTNOTETRACE("other","ImagemapFilter::GetOptionsFromUser - Do nothing"); 00651 #ifndef EXCLUDE_FROM_XARALX 00652 //Now, if the file we are writing to exists already, and if 00653 //we are writing to that file 00654 if (SGLibOil::FileExists(ppthFile) && ms_Options.Insert()) 00655 { 00656 //Then we want to create a list of all the imagemap names in the existing file 00657 //This variable will hold the list 00658 List lstNames; 00659 00660 //Then go through the file and get a list of all the imagemap names 00661 //in the file 00662 BuildMapNamesList(pFile, ppthFile, &lstNames); 00663 00664 //Then put up the modal dialog with that list of names shown 00665 //in the map name combo box 00666 BOOL ok=ImagemapDlg::InvokeDialog(pifoDefault, &lstNames); 00667 00668 //Delete the list of names 00669 lstNames.DeleteAll(); 00670 00671 //And return 00672 return ok; 00673 } 00674 else 00675 { 00676 //Put up the dialog box with nothing shown in the map name 00677 //combo box 00678 //The dialog will start with the inital values of pifoReturn 00679 //in it. When the dialog closes, it will put the values that the user 00680 //chose back into *pifoDefault 00681 return ImagemapDlg::InvokeDialog(pifoDefault); 00682 } 00683 #endif 00684 00685 return FALSE; 00686 } 00687 00688 00689 /******************************************************************************************** 00690 00691 Toolkit functions 00692 00693 Protected functions which are called by other functions as helpers. 00694 00695 *********************************************************************************************/ 00696 00697 /******************************************************************************************** 00698 00699 > BOOL ImagemapFilter::PrepareRenderRegion(Document* pDoc) 00700 00701 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00702 Created: 15/4/97 00703 Inputs: pDoc - The document to export 00704 Returns: TRUE if successful 00705 FALSE if there was an error 00706 Purpose: a. Creates a new render region with the current set of options 00707 b. Attaches a device to that render region 00708 00709 ********************************************************************************************/ 00710 00711 BOOL ImagemapFilter::PrepareRenderRegion(Document* pDoc) 00712 { 00713 PORTNOTETRACE("other","ImagemapFilter::PrepareRenderRegion - Do nothing"); 00714 #ifndef EXCLUDE_FROM_XARALX 00715 // First, create the render region from our current options 00716 if (m_pRegion) 00717 delete m_pRegion; 00718 00719 m_pRegion = new ImagemapRenderRegion(ms_Options); 00720 00721 //Now we must attach a device to our render region 00722 //For this, we must find the current view and spread 00723 00724 pView = DocView::GetCurrent(); 00725 Spread* pSpread = Filter::GetFirstSpread(pDoc); 00726 00727 ERROR2IF(pView==NULL, FALSE, "ImagemapFilter::PrepareToExport - no current view!"); 00728 ERROR2IF(pSpread==NULL, FALSE, "ImagemapFilter::PrepareToExport - no current spread!"); 00729 00730 //And attach the device to our render region 00731 //The middle parameter is the device context, which we set as NULL 00732 m_pRegion->AttachDevice(pView, NULL, pSpread); 00733 00734 //We also need to switch background rendering off in the view 00735 ForceBackgroundRedrawOff(pView); 00736 #endif 00737 00738 return TRUE; 00739 } 00740 00741 /******************************************************************************************** 00742 00743 > void ImagemapFilter::ForceBackgroundRedrawOff(DocView* pView) 00744 00745 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00746 Created: 1/5/97 - Britain deserves better! 00747 Inputs: pView 00748 Returns: - 00749 Purpose: Switches background rendering off in pView 00750 00751 ********************************************************************************************/ 00752 00753 void ImagemapFilter::ForceBackgroundRedrawOff(DocView* pView) 00754 { 00755 // We wan't to make sure we only remember the old state once ... 00756 if (!BackgroundRedrawStateSet) 00757 { 00758 BackgroundRedrawState = pView->GetForeBackMode(); 00759 BackgroundRedrawStateSet = TRUE; // So we don't do this more than once 00760 } 00761 00762 pView->SetForeBackMode(FALSE); 00763 } 00764 00765 /******************************************************************************************** 00766 00767 > void ImagemapFilter::RestoreBackgroundRedraw(DocView* pView) 00768 00769 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00770 Created: 1/5/97 - Tough on bugs, tough on the causes of bugs 00771 Inputs: pView 00772 Returns: - 00773 Purpose: Restores pView's background redraw state 00774 00775 ********************************************************************************************/ 00776 00777 00778 void ImagemapFilter::RestoreBackgroundRedraw(DocView* pView) 00779 { 00780 // We wan't to make sure we only remember the old state once ... 00781 pView->SetForeBackMode(BackgroundRedrawState); 00782 } 00783 00784 /******************************************************************************************** 00785 00786 > BOOL ImagemapFilter::OpenImagemapFile(CCLexFile* pFile, PathName* pPath) 00787 00788 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00789 Created: 17/4/97 00790 Inputs: pFile, pPath - the file to export to 00791 Returns: TRUE if successful 00792 FALSE if there was an error 00793 Purpose: Opens the export file 00794 00795 ********************************************************************************************/ 00796 00797 BOOL ImagemapFilter::OpenImagemapFile(CCLexFile* pFile, PathName* pPath) 00798 { 00799 BOOL ok; 00800 if (!pFile->isOpen()) 00801 { 00802 if (pFile->IsKindOf(CC_RUNTIME_CLASS(CCDiskFile))) 00803 { 00804 ok = OpenExportFile((CCDiskFile*) pFile, pPath); 00805 if (!ok) return FALSE; 00806 } 00807 else 00808 { 00809 TRACEUSER( "JustinF", _T("Tried to open non-CCDiskFile in ImagemapFilter::DoExport\n")); 00810 return FALSE; 00811 } 00812 } 00813 00814 return TRUE; 00815 } 00816 00817 /******************************************************************************************** 00818 00819 > BOOL ImagemapFilter::CloseImagemapFile(CCLexFile* pFile) 00820 00821 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00822 Created: 17/4/97 00823 Inputs: pFile - the file to close 00824 Returns: TRUE if successful (no way of erroring at present) 00825 00826 Purpose: Closes the export file 00827 00828 ********************************************************************************************/ 00829 00830 BOOL ImagemapFilter::CloseImagemapFile(CCLexFile* pFile) 00831 { 00832 if (pFile->isOpen()) 00833 pFile->close(); 00834 00835 return TRUE; 00836 00837 } 00838 00839 /******************************************************************************************** 00840 00841 > void ImagemapFilter::Write(CCLexFile* pfileToWrite, TCHAR** ppcBuffer=NULL) 00842 00843 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00844 Created: 16/4/97 00845 Inputs: pfileToWrite - The file to write to 00846 00847 This may be NULL 00848 00849 Purpose: Writes out the imagemap to a file or a text buffer or both. This 00850 works as follows: 00851 00852 If pfileToWrite is not NULL, this function will write the 00853 imagemap to that file. 00854 00855 If ms_Options.fClipboard is TRUE, this function will also 00856 set up a text buffer, write the imagemap to that text buffer 00857 and then copy the text buffer to the clipboard. 00858 00859 This function calls our toolkit function WriteHelper to do 00860 most of the work. 00861 00862 But what is actually written out? 00863 00864 The only thing that will ever be written to the text buffer 00865 is the imagemap itself: 00866 00867 <MAP> 00868 <AREA SHAPE=RECTANGLE ...> 00869 <AREA SHAPE=POLYGON ...> 00870 </MAP> 00871 00872 What is written to the file depends on whether we have 00873 told that this imagemap is associated with a particular bitmap 00874 file. In other words, it depends on whether the Path To Bitmap 00875 File member variable of our ImagemapFilterOptions member variable 00876 is valid. 00877 00878 If we have been given a bitmap file, then an entire HTML file 00879 embedding the bitmap will be written to the imagemap file: 00880 00881 <HTML> 00882 ... 00883 <IMG SRC="c:\dir\bitmap.gif"> 00884 </HTML> 00885 00886 <MAP> 00887 ... 00888 </MAP> 00889 00890 If not, only the portion between the <MAP> tags will be written. 00891 00892 SeeAlso: ImagemapFilter::WriteHelper() 00893 00894 ********************************************************************************************/ 00895 00896 void ImagemapFilter::Write(CCLexFile* pfileToWrite) 00897 { 00898 //If we need to copy the imagemap to the clipboard, this variable 00899 //will point to a text buffer to store the string in. 00900 TCHAR* pBuffer=NULL; 00901 00902 //Now, do we need to copy the imagemap to the clipboard? 00903 if (ms_Options.m_fClipboard) 00904 { 00905 //Yes. So we need to set up a text buffer. 00906 00907 //First find out the length of this buffer by calling our helper 00908 //function with no parameters 00909 INT32 lBufferLength=WriteHelper(); 00910 00911 //And set up a buffer of that length + length of hint line (determined by 00912 //calling WritePreamble()) - Matt 31/08/2000 00913 if (lBufferLength>0) 00914 { 00915 lBufferLength += WritePreamble(NULL); 00916 00917 pBuffer=new TCHAR[lBufferLength+1]; 00918 00919 //And NULL terminate the buffer at the first character 00920 *pBuffer=0; 00921 00922 //If we have a text buffer, then write to it 00923 if (pBuffer) 00924 { 00925 //Write to the buffer our hint... 00926 WritePreamble(pBuffer); 00927 } 00928 } 00929 00930 } 00931 00932 //And write the imagemap out to both the file and, if necessary, the 00933 //text buffer 00934 WriteHelper(pfileToWrite, pBuffer); 00935 00936 //And finally, if we have a text buffer 00937 if (pBuffer) 00938 { 00939 //Copy it to the clipboard 00940 CopyToClipboard(pBuffer); 00941 00942 //Then delete it 00943 delete pBuffer; 00944 } 00945 00946 } 00947 00948 00949 /************************************************* 00950 00951 Toolkit functions 00952 00953 ***********************************************/ 00954 00955 00956 /******************************************************************************************** 00957 00958 > INT32 ImagemapFilter::WriteHelper(CCLexFile* pfileToWrite=NULL, TCHAR* pcBuffer=NULL) 00959 00960 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00961 Created: 16/4/97 00962 Inputs: pfileToWrite - The file to write to 00963 pcBuffer - Pointer to a text buffer to write to 00964 00965 Either of the above may be NULL. 00966 00967 Returns: The number of TCHARs written. 00968 00969 Purpose: This function will be called twice: 00970 00971 a. First with all parameters NULL, simply to calculate how 00972 INT32 the text buffer for the imagemap must be 00973 00974 b. Secondly with the parameters pointing to a file, or a text buffer 00975 or both, to actually write the imagemap out. 00976 00977 It's assumed that the text buffer is long enough for the imagemap. 00978 00979 This function simply iterates through the list and calls on 00980 the members to write themselves out. 00981 00982 SeeAlso: ImagemapFilter::WriteHelper() 00983 00984 ********************************************************************************************/ 00985 00986 INT32 ImagemapFilter::WriteHelper(CCLexFile* pfileToWrite, TCHAR* pcBuffer) 00987 { 00988 //Set up a variable to remember how many chars we have written 00989 INT32 lCharsWritten=0; 00990 00991 //Write the imagemap HTML 00992 lCharsWritten+=WriteImagemapHTML(pfileToWrite, pcBuffer); 00993 00994 //And return the number of characters written 00995 return lCharsWritten; 00996 00997 } 00998 00999 /******************************************************************************************** 01000 01001 > INT32 ImagemapFilter::WriteBitmapHTML(CCLexFile* pfileToWrite=NULL, TCHAR* pcBuffer=NULL) 01002 01003 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 01004 Created: 16/4/97 01005 Inputs: pfileToWrite - The file to write to 01006 pcBuffer - Pointer to a text buffer to write to 01007 01008 Either of the above may be NULL. 01009 01010 Returns: The number of TCHARs written. 01011 01012 Purpose: Writes the bitmap HTML. 01013 01014 SeeAlso: ImagemapRenderRegion::WriteHelper() 01015 01016 ********************************************************************************************/ 01017 /* 01018 INT32 ImagemapFilter::WriteBitmapHTML(CCLexFile* pfileToWrite, TCHAR* pcBuffer) 01019 { 01020 //Set up a variable to remember how many chars we have written 01021 INT32 lCharsWritten=0; 01022 01023 //Now, first write <HTML> followed by an end of line 01024 lCharsWritten+=HTMLExportFilter::WriteTag(_R(IDS_HTMLEXPORT_HTML), pfileToWrite, pcBuffer); 01025 lCharsWritten+=HTMLExportFilter::WriteEOL(pfileToWrite, pcBuffer); 01026 01027 //Put the bitmap path in a variable 01028 String_256 strBitmapPath=ms_Options.m_pthBitmapFile.GetWebAddress(); 01029 01030 //Now make the HEAD portion from our resource string 01031 String_256 strHead; 01032 strHead.MakeMsg(_R(IDS_HTMLEXPORT_IMAGEMAP_HEAD), (TCHAR*) strBitmapPath); 01033 01034 //And write it out 01035 lCharsWritten+=HTMLExportFilter::Write(strHead, pfileToWrite, pcBuffer); 01036 01037 //And make up the BODY portion 01038 String_256 strBody; 01039 strBody.MakeMsg(_R(IDS_HTMLEXPORT_IMAGEMAP_BODY), (TCHAR*) strBitmapPath, (TCHAR*) ms_Options.m_strName); 01040 01041 //And write it out 01042 lCharsWritten+=HTMLExportFilter::Write(strBody, pfileToWrite, pcBuffer); 01043 01044 //Write the HTML closing tag 01045 lCharsWritten+=HTMLExportFilter::WriteCloseTag(_R(IDS_HTMLEXPORT_HTML), pfileToWrite, pcBuffer); 01046 lCharsWritten+=HTMLExportFilter::WriteEOL(pfileToWrite, pcBuffer); 01047 01048 //And return the number of characters written 01049 return lCharsWritten; 01050 01051 } */ 01052 01053 /******************************************************************************************** 01054 01055 > INT32 ImagemapFilter::WriteImagemapHTML(CCLexFile* pfileToWrite=NULL, TCHAR* pcBuffer=NULL) 01056 01057 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 01058 Created: 16/4/97 01059 Inputs: pfileToWrite - The file to write to 01060 pcBuffer - Pointer to a text buffer to write to 01061 01062 Either of the above may be NULL. 01063 01064 Returns: The number of TCHARs written. 01065 01066 Purpose: Writes the imagemap HTML. 01067 01068 SeeAlso: ImagemapFilter::WriteHelper(), ImagemapRenderRegion::Write() 01069 01070 ********************************************************************************************/ 01071 01072 INT32 ImagemapFilter::WriteImagemapHTML(CCLexFile* pfileToWrite, TCHAR* pcBuffer) 01073 { 01074 //Keep a count of the characters we write out 01075 INT32 lCharsWritten=0; 01076 01077 PORTNOTETRACE("other","ImagemapFilter::WriteImagemapHTML - Do nothing"); 01078 #ifndef EXCLUDE_FROM_XARALX 01079 //Do we have an imagemap render region member? 01080 if (m_pRegion) 01081 { 01082 //Yes. So we write out the imagemap 01083 01084 //First write out <MAP NAME="MyMap"> 01085 lCharsWritten+=WriteStartOfTag(_R(IDS_HTMLEXPORT_MAP), pfileToWrite, pcBuffer); 01086 01087 lCharsWritten+=WriteParameterInQuotes(_R(IDS_HTMLEXPORT_NAME), ms_Options.m_strName, pfileToWrite, pcBuffer); 01088 01089 lCharsWritten+=WriteEndOfTag(pfileToWrite, pcBuffer); 01090 01091 lCharsWritten+=WriteEOL(pfileToWrite,pcBuffer); 01092 01093 //And write the imagemap itself 01094 lCharsWritten+=m_pRegion->Write(pfileToWrite, pcBuffer); 01095 01096 //Then write out </MAP> 01097 lCharsWritten+=WriteCloseTag(_R(IDS_HTMLEXPORT_MAP), pfileToWrite, pcBuffer); 01098 01099 //And a new line 01100 //lCharsWritten+=WriteEOL(pfileToWrite, pcBuffer); 01101 } 01102 #endif 01103 01104 //And return the number of characters written 01105 return lCharsWritten; 01106 } 01107 01108 /******************************************************************************************** 01109 01110 > void ImagemapFilter::CopyToClipboard(TCHAR* pcBuffer=NULL) 01111 01112 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 01113 Created: 16/4/97 01114 Inputs: pcBuffer The text to put on the clipboard 01115 01116 Purpose: Puts the text on the clipboard 01117 01118 ********************************************************************************************/ 01119 01120 void ImagemapFilter::CopyToClipboard(TCHAR* pcBuffer) 01121 { 01122 //Put the text on the clipboard 01123 InternalClipboard::CopyText(pcBuffer); 01124 } 01125 01126 /******************************************************************************************** 01127 01128 > BOOL ImagemapFilter::WriteDataToExistingFile(CCLexFile* pFile, PathName* pPath) 01129 01130 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 01131 Created: 9/4/97 01132 Returns: TRUE if the export was OK 01133 FALSE if there were any errors 01134 01135 Purpose: Writes the data in the imagemap region into an existing file and/or 01136 to the clipboard. 01137 01138 ********************************************************************************************/ 01139 01140 BOOL ImagemapFilter::WriteDataToExistingFile(CCLexFile* pFile, PathName* pPath) 01141 { 01142 //Check parameters 01143 ERROR2IF (pFile==NULL || pPath==NULL, FALSE, "ImagemapFilter::WriteDataToExistingFile - null parameter"); 01144 01145 PORTNOTETRACE("other","ImagemapFilter::WriteDataToExistingFile - Do nothing"); 01146 #ifndef EXCLUDE_FROM_XARALX 01147 //Now let's create a new Xara temporary file 01148 PathName pthTemp=FileUtil::GetTemporaryPathName(); 01149 01150 //And open that temporary file for writing 01151 CCDiskFile fileTemp(1024, FALSE, TRUE); 01152 01153 OpenImagemapFile(&fileTemp, &pthTemp); 01154 01155 //Now write our existing file across to our temporary file, 01156 //parsing it as we do so, and inserting the imagemap data 01157 //in the appropriate position 01158 WriteExistingDataHelper(&fileTemp, pFile, pPath); 01159 01160 //And close the files 01161 fileTemp.close(); 01162 01163 //Finally, delete our existing file 01164 BOOL ok=SGLibOil::FileDelete(pPath); 01165 01166 //Copy our temporary file across 01167 if (ok) 01168 SGLibOil::FileCopy(&pthTemp, pPath); 01169 01170 //Then delete our temporary file 01171 if (ok) 01172 ok=SGLibOil::FileDelete(&pthTemp); 01173 01174 //And return 01175 return ok; 01176 #endif 01177 01178 return TRUE; 01179 } 01180 01181 /******************************************************************************************** 01182 01183 > BOOL ImagemapFilter::WriteDataToNewFile(CCLexFile* pFile, PathName* pPath) 01184 01185 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 01186 Created: 9/4/97 01187 Returns: TRUE if the export was OK 01188 FALSE if there were any errors 01189 01190 Purpose: Writes the data in the imagemap region into a new file and/or 01191 to the clipboard. 01192 01193 ********************************************************************************************/ 01194 01195 BOOL ImagemapFilter::WriteDataToNewFile(CCLexFile* pFile, PathName* pPath) 01196 { 01197 //Have we been passed a file to write to? 01198 if (pFile!=NULL) 01199 { 01200 //Yes. So open it. 01201 if (!OpenImagemapFile(pFile, pPath)) 01202 return FALSE; 01203 } 01204 01205 01206 // add a header to the new file so that if a 01207 // dumb user looks at it it will show the image 01208 // this isn't in the "replace an image map" code 01209 // since that will already have an image file indicated 01210 // Note that it is valid for this function to be called with 2 NULL arguments ( exporting 01211 // to the clipboard only ). So, no use in testing for NULL arguments. 01212 // ASSERT(pPath); 01213 if( pFile != NULL ) // Only write information out to pFile if it exists. 01214 { 01215 String_256 Temp = "<img src=\"file:///"; 01216 *pFile << Temp; 01217 *pFile << ms_Options.m_GraphicPath.GetPath(); // the path and file name of the graphic 01218 Temp = "\""; 01219 *pFile << Temp; 01220 01221 /********************************************************************************************* 01222 // matt - 25/08/2000 - added the following to ensure HTML has height and width data 01223 // matt - 04/09/2000 - OK, this only works when the image is not resized during export 01224 01225 // Get the dimensions of the image map area 01226 DocRect rectDocRect; 01227 rectDocRect = ms_Options.GetSizeOfExportArea(ms_Options.m_stExportArea); 01228 01229 // use the matrix to work out the pixel values of height and width 01230 Matrix Identity; 01231 WinRect rectWinRect = OSRenderRegion::BitmapDocRectToWin( Identity, rectDocRect, 96.0 ); 01232 01233 // save the width and height data 01234 Temp = " width=\""; 01235 *pFile << Temp; 01236 INT32 lToWrite = rectWinRect.right - rectWinRect.left; 01237 HTMLExportFilter::WriteNumber(lToWrite, pFile, NULL); 01238 Temp = "\""; 01239 *pFile << Temp; 01240 Temp = " height=\""; 01241 *pFile << Temp; 01242 lToWrite = rectWinRect.bottom - rectWinRect.top; 01243 HTMLExportFilter::WriteNumber(lToWrite, pFile, NULL); 01244 Temp = "\""; 01245 *pFile << Temp; 01246 **************************************************************************************************/ 01247 01248 01249 //Now write the remaining details 01250 01251 Temp = " usemap=\"#"; 01252 *pFile << Temp; 01253 *pFile << ms_Options.GetImagemapName(); 01254 Temp = "\" border=\"0\">\r\n"; 01255 *pFile << Temp; 01256 01257 } 01258 01259 //Write the imagemap to the file and/or to the clipboard 01260 Write(pFile); 01261 01262 //If we have been passed a file to write to 01263 if (pFile!=NULL) 01264 { 01265 //Then close it. 01266 CloseImagemapFile(pFile); 01267 } 01268 01269 //Delete the render region 01270 delete m_pRegion; 01271 m_pRegion=NULL; 01272 01273 return TRUE; 01274 } 01275 01276 /******************************************************************************************** 01277 01278 > BOOL ImagemapFilter::WriteExistingDataHelper(CCLexFile* pfileTo, CCLexFile* pfileFrom, PathName* ppathFrom) 01279 01280 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 01281 Created: 14/4/97 01282 Inputs: pfileTo Ptr to the file to copy to 01283 pfileFrom Ptr to the file to copy from 01284 ppathFrom Ptr to a pathname of the file to copy from 01285 01286 Returns: TRUE if OK 01287 FALSE if there were any errors 01288 01289 Purpose: This function does most of the hard work in writing an 01290 imagemap into an existing file. 01291 01292 It takes the data from pfileFrom, parses it and writes it 01293 to pfileTo, but inserting the imagemap data in an appropriate place. 01294 01295 The appropriate place is, in order of preference: 01296 01297 1. In place of an imagemap in pfileFrom that has the same 01298 map name as the imagemap we are writing 01299 2. Before the </BODY> tag of pfileFrom has been written 01300 3. After all the data from pfileFrom has been written 01301 01302 ********************************************************************************************/ 01303 01304 BOOL ImagemapFilter::WriteExistingDataHelper(CCLexFile* pfileTo, CCLexFile* pfileFrom, PathName* ppathFrom) 01305 { 01306 ERROR2IF(pfileTo == NULL,FALSE,"Bad params - pfileTo"); 01307 ERROR2IF(pfileFrom == NULL,FALSE,"Bad params - pfileFrom"); 01308 ERROR2IF(ppathFrom == NULL,FALSE,"Bad params - ppathFrom"); 01309 01310 //Set up some strings which we will search for 01311 String_256 strMap("MAP"); 01312 String_256 strCloseMap("/MAP"); 01313 String_256 strName("NAME"); 01314 String_256 strCloseBody("/BODY"); 01315 01316 String_256 strImagemapName=ms_Options.GetImagemapName(); 01317 strImagemapName.toUpper(); 01318 01319 //First we're going to do a first pass through the file 01320 01321 //This will determine two things: one, if the file contains an existing image map 01322 //with the same name as the one we were about to write out. If it does, 01323 //we will overwrite it 01324 01325 //Two, if the file contains a closing </BODY> tag. If it does, and if 01326 //there is no existing image map in the file with the same name 01327 //as the one we were about to write out, we will write the imagemap 01328 //before that closing tag 01329 01330 //Start off by assuming we're not going to overwrite an existing imagemap 01331 //and we're not going to insert the imagemap before the closing body tag 01332 BOOL fOverwriteExistingImageMap=FALSE; 01333 BOOL fInsertBeforeBodyTag=FALSE; 01334 01335 //So open the file for reading 01336 CCDiskFile* pdiskfileFrom=(CCDiskFile*) pfileFrom; 01337 01338 pdiskfileFrom->open(*ppathFrom, ios::in | ios::binary); 01339 01340 //Initialise the HTML Lexer 01341 pfileFrom->InitLexer(); 01342 01343 //And until we reach the end of the file 01344 while(!pfileFrom->IsEndOfHTMLFile()) 01345 { 01346 //Get the next HTML token in the file 01347 //This will either be a tag <xxxxxx> 01348 //or text (where text is in between tags) 01349 pfileFrom->GetHTMLToken(FALSE, FALSE); 01350 01351 //Is that string a <MAP> tag with the same name as the 01352 //imagemap we are about to write out? 01353 if (pfileFrom->GetHTMLTagName()==strMap 01354 && pfileFrom->GetHTMLParameterValue(strName)==strImagemapName) 01355 { 01356 //Yes. So remember that we want to overwrite the 01357 //existing image map 01358 fOverwriteExistingImageMap=TRUE; 01359 } 01360 01361 //Is that string a </BODY> tag? 01362 if (pfileFrom->GetHTMLTagName()==strCloseBody) 01363 { 01364 //Yes. So remember that we want to insert before the 01365 //closing body tag 01366 fInsertBeforeBodyTag=TRUE; 01367 } 01368 } 01369 01370 //Finally, close the file and deinit the lexer 01371 pdiskfileFrom->close(); 01372 pfileFrom->DeinitLexer(); 01373 01374 //Now go through the file again, and insert the imagemap in the correct place 01375 01376 //So open the file for reading 01377 pdiskfileFrom->open(*ppathFrom, ios::in | ios::binary); 01378 01379 //Initialise the HTML Lexer 01380 pfileFrom->InitLexer(); 01381 01382 //And until we reach the end of the file 01383 while(!pfileFrom->IsEndOfHTMLFile()) 01384 { 01385 //Get the next HTML token in the file 01386 //This will either be a tag <xxxxxx> 01387 //or text (where text is in between tags) 01388 pfileFrom->GetHTMLToken(FALSE, FALSE); 01389 01390 //Now, if that tag is a closing BODY tag, and we should be inserting 01391 //the imagemap before that closing body tag, and we are not replacing 01392 //an existing imagemap 01393 if (pfileFrom->GetHTMLTagName()==strCloseBody 01394 && fInsertBeforeBodyTag 01395 && !fOverwriteExistingImageMap) 01396 { 01397 //Then write out our imagemap & image details now - Matt 31/08/2000 01398 String_256 Temp = "<img src=\"file:///"; 01399 *pfileTo << Temp; 01400 *pfileTo << ms_Options.m_GraphicPath.GetPath(); // the path and file name of the graphic 01401 Temp = "\""; 01402 *pfileTo << Temp; 01403 01404 /***************************************************************************************************** 01405 // Get the dimensions of the image map area 01406 DocRect rectDocRect; 01407 rectDocRect = ms_Options.GetSizeOfExportArea(ms_Options.m_stExportArea); 01408 01409 // use the matrix to work out the pixel values of height and width 01410 Matrix Identity; 01411 WinRect rectWinRect = OSRenderRegion::BitmapDocRectToWin( Identity, rectDocRect, 96.0 ); 01412 01413 // save the width and height data 01414 Temp = " width=\""; 01415 *pfileTo << Temp; 01416 INT32 lToWrite = rectWinRect.right - rectWinRect.left; 01417 HTMLExportFilter::WriteNumber(lToWrite, pfileTo, NULL); 01418 Temp = "\""; 01419 *pfileTo << Temp; 01420 Temp = " height=\""; 01421 *pfileTo << Temp; 01422 lToWrite = rectWinRect.bottom - rectWinRect.top; 01423 HTMLExportFilter::WriteNumber(lToWrite, pfileTo, NULL); 01424 Temp = "\""; 01425 *pfileTo << Temp; 01426 *************************************************************************************************/ 01427 01428 //Now write the remaining details 01429 Temp = " usemap=\"#"; 01430 *pfileTo << Temp; 01431 *pfileTo << ms_Options.GetImagemapName(); 01432 Temp = "\" border=\"0\">\r\n"; 01433 *pfileTo << Temp; 01434 01435 01436 01437 Write(pfileTo); 01438 } 01439 01440 //If the tag is a MAP tag with the same 01441 //name as the map we are about to write out, and we should 01442 //be writing the imagemap in place of the existing imagemap 01443 if (pfileFrom->GetHTMLTagName()==strMap 01444 && pfileFrom->GetHTMLParameterValue(strName)==strImagemapName 01445 && fOverwriteExistingImageMap) 01446 { 01447 //Then write out our imagemap 01448 Write(pfileTo); 01449 01450 //Now we want to carry on copying the file we are reading from, 01451 //starting from the closing </MAP> tag. So we must find that closing map 01452 //tag. 01453 01454 //So read HTML tokens from the file until either we 01455 //find a </MAP> tag or we reach the end of the file 01456 while (pfileFrom->GetHTMLTagName()!=strCloseMap && !pfileFrom->IsEndOfHTMLFile()) 01457 { 01458 //Get the next HTML token 01459 pfileFrom->GetHTMLToken(FALSE, FALSE); 01460 } 01461 01462 //And if we haven't reached the end of the file, get another token, 01463 //which we will write out 01464 if (!pfileFrom->IsEndOfHTMLFile()) 01465 pfileFrom->GetHTMLToken(FALSE, FALSE); 01466 } 01467 01468 //Then get a pointer to the last HTML token we read 01469 char* pcBufferToWrite=pfileFrom->GetHTMLTokenBuffer(); 01470 01471 //And write it out 01472 if (pcBufferToWrite) 01473 pfileTo->write(pcBufferToWrite, strlen(pcBufferToWrite)); 01474 } 01475 01476 //Now, if we haven't inserted an imagemap before a closing body tag, 01477 //and we haven't replaced an existing image map, then we must write 01478 //out the imagemap now 01479 if (!fOverwriteExistingImageMap && !fInsertBeforeBodyTag) 01480 { 01481 //Then write out the imagemap now 01482 String_256 Temp = "<img src=\"file:///"; 01483 *pfileTo << Temp; 01484 *pfileTo << ms_Options.m_GraphicPath.GetPath(); // the path and file name of the graphic 01485 Temp = "\""; 01486 *pfileTo << Temp; 01487 01488 /***************************************************************************************************** 01489 // Get the dimensions of the image map area 01490 DocRect rectDocRect; 01491 rectDocRect = ms_Options.GetSizeOfExportArea(ms_Options.m_stExportArea); 01492 01493 // use the matrix to work out the pixel values of height and width 01494 Matrix Identity; 01495 WinRect rectWinRect = OSRenderRegion::BitmapDocRectToWin( Identity, rectDocRect, 96.0 ); 01496 01497 // save the width and height data 01498 Temp = " width=\""; 01499 *pfileTo << Temp; 01500 INT32 lToWrite = rectWinRect.right - rectWinRect.left; 01501 HTMLExportFilter::WriteNumber(lToWrite, pfileTo, NULL); 01502 Temp = "\""; 01503 *pfileTo << Temp; 01504 Temp = " height=\""; 01505 *pfileTo << Temp; 01506 lToWrite = rectWinRect.bottom - rectWinRect.top; 01507 HTMLExportFilter::WriteNumber(lToWrite, pfileTo, NULL); 01508 Temp = "\""; 01509 *pfileTo << Temp; 01510 ******************************************************************************************************/ 01511 01512 //Now write the remaining details 01513 Temp = " usemap=\"#"; 01514 *pfileTo << Temp; 01515 *pfileTo << ms_Options.GetImagemapName(); 01516 Temp = "\" border=\"0\">\r\n"; 01517 *pfileTo << Temp; 01518 01519 01520 01521 Write(pfileTo); 01522 } 01523 01524 //And finally close the file and deinit the lexer 01525 pdiskfileFrom->close(); 01526 pfileFrom->DeinitLexer(); 01527 01528 01529 return TRUE; 01530 } 01531 01532 /******************************************************************************************** 01533 01534 > void ImagemapFilter::BuildMapNamesList(CCLexFile* pfileSearch, PathName* ppthSearch, List* plstToAdd) 01535 01536 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 01537 Created: 19/5/97 01538 Inputs: plstToAdd Pointer to the list to add the names to 01539 pfileSearch Pointer to the file to search 01540 ppthSearch Pointer to the path of the file to search 01541 01542 01543 Returns: - 01544 01545 Purpose: Goes through the file pointed to by pfileSearch. 01546 01547 Each time it finds an imagemap tag <MAP NAME=xxx>, it adds 01548 the value of the NAME parameter into the list pointed to by 01549 plstToAdd. 01550 01551 This may seem a strange function to be an "entry point" to the filter, 01552 but it's here so that the file parsing code is available to 01553 BaseBitmapFilter. 01554 01555 ********************************************************************************************/ 01556 01557 void ImagemapFilter::BuildMapNamesList(CCLexFile* pfileSearch, PathName* ppthSearch, List* plstToAdd) 01558 { 01559 PORTNOTETRACE("other","ImagemapFilter::BuildMapNamesList - Do nothing"); 01560 #ifndef EXCLUDE_FROM_XARALX 01561 //First we must open the file for reading 01562 CCDiskFile* pDiskFile=(CCDiskFile*) pfileSearch; 01563 01564 pDiskFile->open(*ppthSearch, ios::in | ios::binary); 01565 01566 //Initialise the HTML lexer 01567 pfileSearch->InitLexer(); 01568 01569 //Set up two strings which we will search for 01570 String_256 strMap("MAP"); 01571 String_256 strName("NAME"); 01572 01573 //And until we reach the end of the file 01574 while(!pfileSearch->IsEndOfHTMLFile()) 01575 { 01576 //Get the next HTML token in the file 01577 pfileSearch->GetHTMLToken(TRUE, FALSE); 01578 01579 //And if the token is an HTML MAP tag 01580 if (pfileSearch->GetHTMLTagName()==strMap) 01581 { 01582 //Then add the value of the NAME parameter to the list 01583 String_256 strToAdd=pfileSearch->GetHTMLParameterValue(strName, FALSE); 01584 01585 StringListItem* psliToAdd=new StringListItem(strToAdd); 01586 01587 plstToAdd->AddTail(psliToAdd); 01588 } 01589 01590 } 01591 01592 //And deinitialise the lexer 01593 pfileSearch->DeinitLexer(); 01594 01595 //Then close the file 01596 pDiskFile->close(); 01597 #endif 01598 } 01599 01600 01601 01602 01603 01604 /******************************************************************************************** 01605 01606 > INT32 ImagemapFilter::WritePreamble(TCHAR* pcBuffer) 01607 01608 Author: Priestley (Xara Group Ltd) <camelotdev@xara.com> 01609 Created: 31/8/2000 01610 Inputs: pcBuffer The text buffer to write to (may be NULL) 01611 01612 Returns: The number of TCHARs written to the text buffer 01613 Purpose: Helper for writing imagemaps - this function will write the 'preamble' to 01614 pcBuffer. The 'preamble' consists of the image source, dimensions, which 01615 map it is bound to, and a tag indicating the border has 0 width. 01616 01617 If this function is called with pcBuffer as NULL, it will return the length 01618 of text buffer required to write the current preamble information 01619 01620 Notes: pcBuffer is assumed to be null terminated 01621 01622 ********************************************************************************************/ 01623 01624 INT32 ImagemapFilter::WritePreamble(TCHAR* pcBuffer) 01625 { 01626 String_256 temp; 01627 INT32 nChars = 0; 01628 01629 temp = "<!-- HINT : The next line describes the file used for this image map. It can be deleted if you have already included this information in your HTML page. -->\r\n"; 01630 01631 if (pcBuffer) 01632 { 01633 //Hint line for novice users 01634 nChars = camStrlen(pcBuffer); 01635 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), temp); 01636 01637 //Image Path and filename... 01638 nChars = camStrlen(pcBuffer); 01639 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), _T("<img src=\"file:///")); 01640 01641 nChars = camStrlen(pcBuffer); 01642 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), ms_Options.m_GraphicPath.GetPath() ); // the path and file name of the graphic 01643 01644 nChars = camStrlen(pcBuffer); 01645 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), _T("\"")); 01646 01647 /******************************************************************************************************************************* 01648 // Get the dimensions of the image map area 01649 DocRect rectDocRect; 01650 rectDocRect = ms_Options.GetSizeOfExportArea(ms_Options.m_stExportArea); 01651 01652 // use the matrix to work out the pixel values of height and width 01653 Matrix Identity; 01654 WinRect rectWinRect = OSRenderRegion::BitmapDocRectToWin( Identity, rectDocRect, 96.0 ); 01655 01656 //Image Width and Height... 01657 nChars = camStrlen(pcBuffer); 01658 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), _T(" width=\"")); 01659 01660 INT32 tempLong = rectWinRect.right - rectWinRect.left; 01661 nChars = camStrlen(pcBuffer); 01662 01663 //Format the INT32 as a string 01664 temp.MakeMsg(_R(IDS_HTMLEXPORT_NUMBERFORMAT), tempLong); 01665 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), _T(temp)); 01666 01667 nChars = camStrlen(pcBuffer); 01668 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), _T("\"")); 01669 01670 01671 nChars = camStrlen(pcBuffer); 01672 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), _T(" height=\"")); 01673 01674 tempLong = rectWinRect.bottom - rectWinRect.top; 01675 nChars = camStrlen(pcBuffer); 01676 01677 //Format the INT32 as a string 01678 temp.MakeMsg(_R(IDS_HTMLEXPORT_NUMBERFORMAT), tempLong); 01679 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), _T(temp)); 01680 01681 nChars = camStrlen(pcBuffer); 01682 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), _T("\"")); 01683 01684 ************************************************************************************************************/ 01685 01686 //Now the remaining details... 01687 nChars = camStrlen(pcBuffer); 01688 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), _T(" usemap=\"#")); 01689 01690 nChars = camStrlen(pcBuffer); 01691 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), ms_Options.GetImagemapName() ); 01692 01693 nChars = camStrlen(pcBuffer); 01694 camStrcpy(pcBuffer+nChars*sizeof(TCHAR), _T("\" border=\"0\">\r\n")); 01695 01696 01697 nChars = camStrlen(pcBuffer); 01698 01699 return nChars; 01700 } 01701 01702 //Hint line for novice users 01703 nChars += camStrlen(temp); 01704 01705 //Image Path and filename... 01706 nChars += camStrlen(_T("<img src=\"file:///")); 01707 nChars += camStrlen( ms_Options.m_GraphicPath.GetPath() ); // the path and file name of the graphic 01708 nChars += camStrlen(_T("\"")); 01709 01710 /************************************************************************************ 01711 // Get the dimensions of the image map area 01712 DocRect rectDocRect; 01713 rectDocRect = ms_Options.GetSizeOfExportArea(ms_Options.m_stExportArea); 01714 01715 // use the matrix to work out the pixel values of height and width 01716 Matrix Identity; 01717 WinRect rectWinRect = OSRenderRegion::BitmapDocRectToWin( Identity, rectDocRect, 96.0 ); 01718 01719 //Image Width and Height... 01720 nChars += camStrlen(_T(" width=\"")); 01721 INT32 tempLong = rectWinRect.right - rectWinRect.left; 01722 01723 01724 //Format our INT32 01725 temp.MakeMsg(_R(IDS_HTMLEXPORT_NUMBERFORMAT), tempLong); 01726 01727 nChars += camStrlen(temp); 01728 nChars += camStrlen(_T("\"")); 01729 01730 nChars += camStrlen(_T(" height=\"")); 01731 tempLong = rectWinRect.bottom - rectWinRect.top; 01732 01733 01734 //Format our INT32 01735 temp.MakeMsg(_R(IDS_HTMLEXPORT_NUMBERFORMAT), tempLong); 01736 01737 nChars += camStrlen(temp); 01738 nChars += camStrlen(_T("\"")); 01739 01740 ************************************************************************************/ 01741 01742 //Now the remaining details... 01743 nChars += camStrlen(_T(" usemap=\"#")); 01744 nChars += camStrlen( ms_Options.GetImagemapName() ); 01745 nChars += camStrlen(_T("\" border=\"0\">\r\n")); 01746 01747 return nChars*sizeof(TCHAR); 01748 }