// $Id: document.cpp 1668 2006-08-04 11:45:17Z alex $ /* @@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============================ */ #include "camtypes.h" #include //#include // this seems to be deprecated #include #include #include // for rand() fn #include "camdoc.h" //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "docmsgs.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "dumbnode.h" #include "noderect.h" //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "lineattr.h" #include "colcontx.h" //#include "doccolor.h" //#include "colourix.h" //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "readeps.h" //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "csrstack.h" #include "grid.h" #include "nodedoc.h" #include "chapter.h" #include "page.h" //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "wrkrect.h" //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "msg.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "sprdmsg.h" #include "layer.h" #include "insertnd.h" //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "camview.h" //#include "native.h" // The new designed native filter, used for v2 #include "nativeps.h" // The old style EPS native filter, used in v1.1 #include "saveeps.h" #include "zoomops.h" #include "qualops.h" #include "ai_eps.h" #include "ai_epsrr.h" #include "fontlist.h" #include "fontman.h" #include "progress.h" #include "bmpcomp.h" #include "ralphdoc.h" #include "camelot.h" // For SafeRender Critical section stuff //#include "clipint.h" #include "nodedoc.h" #include "ngsentry.h" #include "opnudge.h" #include "ophist.h" #include "cutop.h" //#include "ralphvw.h" #include "vstate.h" DECLARE_SOURCE("$Revision: 1668 $"); CC_IMPLEMENT_DYNAMIC(Document, BaseDocument) CC_IMPLEMENT_DYNAMIC(DocChangingMsg, Msg) CC_IMPLEMENT_DYNAMIC(SpreadMsg, Msg) CC_IMPLEMENT_DYNAMIC(TranspModeMsg, Msg) CC_IMPLEMENT_DYNAMIC(SafeRenderPointer, CCObject) // Declare smart memory handling in Debug builds #define new CAM_DEBUG_NEW const MILLIPOINT PageWidth = ( 8 * 72000); const MILLIPOINT PageHeight = (11 * 72000); // Default page size/position. const MILLIPOINT Gap = 72000L; const MILLIPOINT PasteBoardWidth = PageWidth + (Gap * 2); const MILLIPOINT PasteBoardHeight = PageHeight + (Gap * 2); const MILLIPOINT DefBleedSize = 72000L/4; Document* Document::Current = NULL; Document* Document::Selected = NULL; Spread* Document::pGlobalSelSpread = NULL; BOOL Document::fRestoreViewOnImport = TRUE; static String_256 ClipboardNameText(TEXT("Clipboard")); // the default nudge size for our documents .... // NOTE: if you change this, you should also update the hard-coded value within: // GeneralRecordHandler::HandleTagNudeSizeRecord (). I could move this to the .h; but I can't // be bothered .... const UINT32 DEFAULT_NUDGE_SIZE = 2835; /*********************************************************************************************** > Document::Document(BOOL IsAHiddenDoc = FALSE) Author: Tim_Browse (Xara Group Ltd) Created: 19/5/93 Inputs: IsAHiddenDoc - FALSE for a normal document (see below) TRUE for a hidden document (including clipboards, etc) Purpose: Constructor. Initialises the link to the OIL document. Notes: You MUST call Document::Init after Creation of the document, to fill in the defaults and build the document tree root. HIDDEN DOCUMENTS A hidden document is one which is not shown to the user in any UI. Hidden docs are used mainly for clipboard (and OLE) data transfer operations. Note that if you pass in (pCCamDoc = NULL) then the document is forced to be hidden. SeeAlso IsAHiddenDoc() and IsNotAHiddenDoc() in document.h The InternalClipboard is now based upon Document. It creates a Hidden Document. Generally nobody should care about this, but some bits of code might have to be careful of the differences. Use IsAClipboard() to check if the doc is really a clipboard. Note also that Clipboard documents do not broadcast DocChangingMsgs. Errors: None. SeeAlso: Document::Init; InternalClipboard; BaseDocument ***********************************************************************************************/ Document::Document(BOOL bIsAHiddenDoc) : BaseDocument(bIsAHiddenDoc), OilDoc(0) { // NB. Make sure all the Document stuff is set up before calling routines which // might interrogate the Document object. // Set the default state of the flags. DocFlags.LayerMultilayer = FALSE; DocFlags.LayerAllVisible = FALSE; DocFlags.SaveWithUndo = TRUE; // Set the times CreationTime = ::time(NULL); LastSaveTime = 0; // Set up default bleed offset BleedOffset = DefBleedSize; // Set up our array of default colour contexts by copying the 'global' array ColourContext::GetGlobalDefaults( &DefaultColourContexts ); // Add this document to the list of all documents in Camelot #ifdef RALPH Camelot.Documents.AddHead(this); #else if (IsNotAHiddenDoc()) { Camelot.Documents.AddHead(this); } #endif // Set this document to be the current one this->SetCurrent(); NodesInTree = 0; // Initialise pointers to sensible values (they are set up in the Init() function) OpHistory = 0; AttributeMgr = 0; m_pSetSentinel = 0; pDocUnitList = 0; pSelSpread = 0; IsARalph = FALSE; pRalphDocument =NULL; Viewmode = DOCUMENT_VIEW; // Always keep this flag TRUE except when Loading New Files in DocIsImporting = TRUE; // Always keep this False unless loading a template document DocTemplateLoading = FALSE; // Make sure that the loaded as old version file is set to a known state LoadedAsVersion1File = FALSE; m_docNudge = DEFAULT_NUDGE_SIZE; SetBitmapSmoothing(TRUE); m_DuplicationOffset = DocCoord(OpDuplicate::DuplicatePlacementX, OpDuplicate::DuplicatePlacementY); // Document is not yet "born and stable". m_fStable = FALSE; } /******************************************************************************************** > BOOL Document::Init(CCamDoc* pOilDoc) Author: Tim_Browse (Xara Group Ltd) Created: 20/7/93 Inputs: pOilDoc --- the CCamDoc to attach this Document too Returns: TRUE if the document initialised ok, FALSE otherwise. Purpose: Sets up the document tree. At the moment it fills it with test data (paths etc) but in future only the initial tree nodes will be set up. When the document has been completely initialised, it becomes the selected and current document: DocChangingMsg message broadcasts will occur (in the order BORN, CURRENT, SELECTED). Notes: This now also sets up the default list of indexed (named) colours which the user can base their document upon [in the BaseDocument Init method]. These should be set up from a default document (or whatever) in future. Errors: Out of memory. SeeAlso: ReadEPSData; Document::Document; Document::SetSelectedViewAndSpread; Document::SetCurrent ********************************************************************************************/ BOOL Document::Init(CCamDoc* pOilDoc) { // Ralph has a NULL oildoc... #ifndef RALPH ERROR2IF(OilDoc, FALSE, "Document already attached to a CCamDoc in Document::Init"); #endif OilDoc = pOilDoc; NodeDocument* Doc; EndDocument* End; // Make this the current document - NOTE! no broadcast as of 22/7/94 SetCurrent(); // Set the busy cursor . . . BeginSlowJob(-1, FALSE); // First, call the base class Init method to set up for us. // This creates the StartDocument, NodeDocument, & EndDocument, and sets up // a default colour list and other doc components. if (!BaseDocument::Init()) return InitFailed(); // Check that the document is OK ERROR3IF(GetFirstNode() == NULL,"StartDoc not found"); Doc = (NodeDocument*)GetFirstNode()->FindNext(); ERROR3IF(Doc == NULL, "NodeDocument not found"); End = (EndDocument*)Doc->FindNext(); ERROR3IF(End == NULL, "EndDocument not found"); // Make the doc unit list pDocUnitList = new DocUnitList; if (pDocUnitList == NULL || !pDocUnitList->MakeDefaultUnits()) return(InitFailed()); // Create the Operation history for the document OpHistory = new OperationHistory; if (OpHistory == NULL) return(InitFailed()); // Create the attribute manager for the document AttributeMgr = new AttributeManager; if (AttributeMgr == NULL || !AttributeMgr->InitInstance()) return(InitFailed()); // Build the basic tree structure (Chapter, spread, layer) if (!InitTree(Doc)) return(InitFailed()); if (IsNotAHiddenDoc()) { // Broadcast a message to all that there's a new document on the block . . . BROADCAST_TO_ALL(DocChangingMsg(this, DocChangingMsg::BORN)); } // Add the default attributes as Nodes at the start of the tree // The clipboard document does not need default attributes, as things copied into it // are always kept attribute complete. But now that we're importing into the clipboard, // it is a very good idea to have safe defaults lying about. InitDefaultAttributeNodes(); // Take the hourglass off EndSlowJob(); return(TRUE); } /******************************************************************************************** > BOOL Document::InitTree(NodeDocument *RootNode) Author: Jason_Williams (Xara Group Ltd) Created: 23/4/95 Inputs: RootNode - points at the basic NodeDocument from which the main documet tree hangs. Returns: TRUE if it succeeds, FALSE if it failed (in which case you should call InitFailed() and possibly InformError()) Purpose: Called by Document::Init to initialise the document tree structure. Mainly intended for use by the internal clipboard in order to delete and recreate the standard tree whenever it is wiped - I've done this here dso that any chnages to the normal document layout will also affect the clipboard document in an appropriate manner. Errors: Lack of memory might make 'new' fail SeeAlso: Document::Init ********************************************************************************************/ BOOL Document::InitTree(NodeDocument* pRootNode) { if (pRootNode == NULL || !pRootNode->IsNodeDocument()) { ERROR3("This doc's NodeDocument is NULL or isn't really a NodeDocument"); return(FALSE); } // Temporary bodge to construct example document tree for Target 1. Chapter* pChapter = new Chapter(pRootNode, LASTCHILD); if (pChapter == 0) return FALSE; // Create the sentinel node for all object names within the chapter, and a // child NodeBarProperty. m_pSetSentinel = new NodeSetSentinel(pChapter, FIRSTCHILD); if (m_pSetSentinel == 0) return FALSE; NodeBarProperty* pbp = new NodeBarProperty(m_pSetSentinel, LASTCHILD); if (pbp == 0) return FALSE; // Create a rectangle for the pasteboard DocRect PasteRect(MinDocCoord + 0x10000, MaxDocCoord - 0x10000 - 1 * PasteBoardHeight, MinDocCoord + 0x10000 + 2 * PasteBoardWidth, MaxDocCoord - 0x10000); // Create the spread Spread *pSpread = new Spread(pChapter, FIRSTCHILD, PasteRect); if (pSpread == NULL) return FALSE; // Create the default page and grid (JustinF says: even if we are a hidden document) if (!pSpread->CreateDefaultPageAndGrid(TRUE)) return FALSE; // Create the Insertion node which must always live as a last child of the selected // spreads active layer. The Insertion node holds a pointer to this document so that // if for whatever reason the InsertionNode is destroyed (eg. Delete layer) then // we can Inform this document and it can NULLIFY the InsertPos pointer. InsertPos = new InsertionNode(this); if (InsertPos == NULL) return FALSE; InsertPos->AttachNode(pSpread, LASTCHILD); return TRUE; } /******************************************************************************************** > BOOL Document::InitDefaultAttributeNodes() Author: Simon_Maneggio (Xara Group Ltd) Created: 22/06/94 Inputs: - Outputs: - Returns: TRUE if the default attributes have been added to the tree OK FALSE if we run out of memory. Purpose: This function adds the document's default attributes as nodes at the start of the tree (i.e. as first children of the NodeDocument). The Attribute optimisation routines will not work if the document does not contain the default attributes. Note: This function must be called after the initial document structure has been set up and all default attributes have been registered. Errors: The Out Of Memory Error is set if we run out of memory, FALSE is returned in this situation. ********************************************************************************************/ BOOL Document::InitDefaultAttributeNodes() { ENSURE(AttributeMgr != NULL, "Attribute Manager pointer is NULL"); // Find out the number of default attributes UINT32 NumDefaultAttribs = AttributeMgr->GetNumAttributes(); ENSURE(NumDefaultAttribs != 0, "The document has no default attributes"); AttributeEntry* DefaultAttribs = AttributeMgr->GetDefaultAttributes(); if (DefaultAttribs == NULL) return FALSE; // ---------------------------------------------------------------------------------------- // Try and find the NodeDocument node - to which the attributes will be added Node* TreeRoot; ENSURE(TreeStart != NULL, "The initial tree structure has not been initialised"); TreeRoot = TreeStart->FindNext(); ENSURE(TreeRoot != NULL, "Can't find NodeDocument"); ENSURE(TreeRoot->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeDocument), "Alien tree structure"); // ---------------------------------------------------------------------------------------- // Create a NodeAttribute for each of the default attributes and add them into the // tree as first children of the NodeDocument. for(UINT32 i=0; iMakeNode(); if (NodeAttr != NULL) { // Add the Attribute as a first child of the NodeDocument. Note that we suppress // the transparency check for default attributes. NodeAttr->AttachNode(TreeRoot, FIRSTCHILD, FALSE); NodeAttribute* pNa = (NodeAttribute*)NodeAttr; if(pNa->IsLinkedToNodeGeometry()) { pNa->NewlyCreatedDefaultAttr((NodeDocument*)TreeRoot); } } } // ---------------------------------------------------------------------------------------- // Default attribute array no longer required so we can safely delete it CCFree(DefaultAttribs); return TRUE; } /******************************************************************************************** > BOOL Document::ReInit() Author: Chris_Parks (Xara Group Ltd) Created: 16/4/96 Returns: Init ok Purpose: Calls InitFailed to delete the Tree and various others and follows this with an Init to put the Document back into a virgin state Not used just yet... Errors: ********************************************************************************************/ BOOL Document::ReInit() { // RALPH InitFailed(); return Init(OilDoc); /* TreeStart->CascadeDelete(); ERROR3IF(GetFirstNode() == NULL,"StartDoc not found"); NodeDocument *Doc = (NodeDocument*)GetFirstNode()->FindNext(); return InitTree(Doc); */ // return TRUE; } /******************************************************************************************** > BOOL Document::InitFailed(void) Author: Jason_Williams (Xara Group Ltd) Created: 8/12/94 Returns: FALSE Purpose: Called by Document::Init when it fails; encapsulates all necessary tidying up, and then returns FALSE so that it can be called as part of the final return statement. Replaces some completely unnecessary goto code. SeeAlso: Document::Init ********************************************************************************************/ BOOL Document::InitFailed(void) { if (TreeStart != 0) { TreeStart->CascadeDelete(); delete TreeStart; m_pSetSentinel = 0; } if (OpHistory != 0) { delete OpHistory; OpHistory = 0; } if (AttributeMgr != 0) { delete AttributeMgr; AttributeMgr = 0; } if (pDocUnitList != 0) { delete pDocUnitList; pDocUnitList = 0; } EndSlowJob(); return(FALSE); } /*********************************************************************************************** > Document::~Document() Author: Tim_Browse (Xara Group Ltd) Created: 19/5/93 Purpose: Destructor. Deletes the whole document tree of this object, and all memory is returned to the heaps whence it came. The busy cursor is displayed while this is happening. ***********************************************************************************************/ Document::~Document() { // Set the busy cursor . . . BeginSlowJob(-1, FALSE); #ifndef RALPH // Broadcast to everyone that this document is a dead duck. if (IsNotAHiddenDoc()) #endif { // Document no longer stable. SetStable(FALSE); BROADCAST_TO_ALL(DocChangingMsg(this, DocChangingMsg::ABOUTTODIE)); } #ifdef _DEBUG // DocViews should be closed before Documents, so all render regions for this document // should have been deleted - make sure they have. Camelot.DeleteRenderRegions(this); #endif #ifndef RALPH // Remove Document from list of all documents if (IsNotAHiddenDoc()) #endif { Camelot.Documents.RemoveItem(this); // Is this the last document in the program? BOOL ThisIsTheLastDoc = (Camelot.Documents.GetHead() == NULL); if (ThisIsTheLastDoc) { // There are no more documents, so ensure that the system is in the correct state. // If the system is working correctly, then the following should be true: // If Current != NULL, Current must be this document // If Selected != NULL, Selected must be this document // We will ensure this is the case in debug builds ENSURE((Current == NULL) || (Current == this),"Current document is garbage"); ENSURE((Selected == NULL) || (Selected == this),"Selected document is garbage"); // Reset Current and Selected document and DocView SetNoCurrent(); SetNoSelectedViewAndSpread(); DocView::SetNoCurrent(); // DocView::SetNoSelected(); -- now done in SetNoSelectedViewAndSpread(), above } else { // Make sure that Current and Selected do not refer to the dying document if (this == Current) SetNoCurrent(); if (this == Selected) SetNoSelectedViewAndSpread(); // This special test added to fix a problem whereby current doc was being set to null // above and hence causing unit display problems (ERROR2s) in the selector tool when // opening a bitmap had been aborted. 18/9/96 Neville if (Selected != NULL && Current == NULL) Current = Selected; } } // Delete all DocViews attached to document DocViews.DeleteAll(); #ifndef RALPH // Broadcast to everyone that this document is a dead duck. if (IsNotAHiddenDoc()) { BROADCAST_TO_ALL(DocChangingMsg(this, DocChangingMsg::KILLED)); } #endif // Destroy the operation history. This must get destroyed before the tree is destroyed if (OpHistory != NULL) delete (OpHistory); // Destroy the attribute manager if (AttributeMgr != NULL) delete (AttributeMgr); // Destroy the list of units in this document if (pDocUnitList != NULL) delete (pDocUnitList); // All done... EndSlowJob(); // Note that the tree is deleted in the base class destructor } /******************************************************************************************** > BOOL Document::IsModified() const Author: Justin_Flude (Xara Group Ltd) Created: 23/3/94 Inputs: - Outputs: - Returns: Returns TRUE if the document has been modified since last being saved. Purpose: Tests the "Modified" flag. Errors: - SeeAlso: CCamDoc::IsModified ********************************************************************************************/ BOOL Document::IsModified() const { if (OilDoc) return OilDoc->IsModified(); return(FALSE); } /******************************************************************************************** > BOOL Document::IsReadOnly() const Author: Justin_Flude (Xara Group Ltd) Created: 23/3/94 Inputs: - Outputs: - Returns: Returns TRUE if the document is read-only, ie. cannot be modified. Purpose: Tests the "Read Only" flag. Errors: - SeeAlso: CCamDoc::IsReadOnly ********************************************************************************************/ BOOL Document::IsReadOnly() const { if (OilDoc) return OilDoc->IsReadOnly(); return(FALSE); } /******************************************************************************************** > BOOL Document::IsACopy() const Author: Justin_Flude (Xara Group Ltd) Created: 23/3/94 Inputs: - Outputs: - Returns: Returns TRUE if the document is a copy of another document. Purpose: Tests the "Copy" flag. Errors: - SeeAlso: CCamDoc::IsACopy ********************************************************************************************/ BOOL Document::IsACopy() const { if (OilDoc) return OilDoc->IsACopy(); return(FALSE); } /******************************************************************************************** > void Document::SetModified(BOOL fState = TRUE) Author: Justin_Flude (Xara Group Ltd) Created: 23/3/94 Inputs: - Outputs: - Returns: - Purpose: Sets (or clears) the "document is modified" flag. Errors: - SeeAlso: CCamDoc::SetModified ********************************************************************************************/ void Document::SetModified(BOOL fState /* = TRUE */) { if (OilDoc) OilDoc->SetModified( fState != FALSE ); } /******************************************************************************************** > void Document::IsLoadedAsVersion1File() const Author: Neville_Humphrys (Xara Group Ltd) Created: 30/7/96 Inputs: - Outputs: - Returns: - Purpose: Returns the current state of the IsLoadedAsVersion1File flag. Flag to say that the document was loaded as a version 1 file and so the user needs to be given the option of saving it in this form when the document is saved ********************************************************************************************/ BOOL Document::IsLoadedAsVersion1File() const { return LoadedAsVersion1File; } /******************************************************************************************** > BOOL Document::ISetLoadedAsVersion1File(BOOL NewState) Author: Neville_Humphrys (Xara Group Ltd) Created: 30/7/96 Inputs: New state of the flag required Outputs: - Returns: Old state of the flag Purpose: Sets a new current state of the IsLoadedAsVersion1File flag. Flag to say that the document was loaded as a version 1 file and so the user needs to be given the option of saving it in this form when the document is saved ********************************************************************************************/ BOOL Document::SetLoadedAsVersion1File(BOOL NewState) { BOOL OldState = LoadedAsVersion1File; LoadedAsVersion1File = NewState; return OldState; } /******************************************************************************************** > BOOL Document::CreateDragTargets() Author: Chris_Parks (Xara Group Ltd) Created: 22/1/95 Inputs: - Outputs: - Returns: - Purpose: Calls all (OILY) views to create their drag targets. Errors: - SeeAlso: CCamDoc::SetModified ********************************************************************************************/ BOOL Document::CreateDragTargets(DragInformation * DragInfo) { if (IsNotAClipboard()) { DocView * Ptr= (DocView*) DocViews.GetHead(); CCamView* TheView; while(Ptr) { TheView = Ptr->GetConnectionToOilView(); if(TheView) TheView->CreateDragTarget(DragInfo); Ptr= (DocView*) DocViews.GetNext(Ptr); } } return TRUE; } /******************************************************************************************** > String_256 Document::GetTitle() const Author: Justin_Flude (Xara Group Ltd) Created: 15/3/94 Returns: A String_256 that holds the document title Purpose: Returns the Title of the document. The title is the text that appears in the documents windows (when it is not maximised). For example 'Untitled #1' or 'Untitled #1 (Modified)' or even 'Blobby.art (Modified)'. SeeAlso: Document::GetProducer; Document::GetComment; CCamDoc::GetKernelTitle ********************************************************************************************/ String_256 Document::GetTitle() const { if (OilDoc) return OilDoc->GetKernelTitle(); return(ClipboardNameText); } /******************************************************************************************** > String_256 Document::GetDocName(BOOL IncludeFileType = TRUE) const Author: Neville_Humphrys (Xara Group Ltd) Created: 27/3/95 Inputs: IncludeFileType - TRUE if the filetype is required. Defaults to TRUE. Returns: A String_256 that holds the document name Purpose: Returns the name of the document. The name will be the first part of the title which is the text that appears in the document windows (when it is not maximised). For example 'Untitled #1' or 'Untitled #1 (Modified)' or even 'Blobby.art (Modified)'. SeeAlso: Document::GetTitle(); CCamDoc::GetKernelTitle(); CCamDoc::GetKernelDocName(); SeeAlso: Document::GetProducer; Document::GetComment; ********************************************************************************************/ String_256 Document::GetDocName(BOOL IncludeFileType) const { if (OilDoc) return OilDoc->GetKernelDocName(IncludeFileType); return(ClipboardNameText); } /******************************************************************************************** > String_256 Document::GetPathName(UINT32 MaxSize = 0) const Author: Neville_Humphrys (Xara Group Ltd) Created: 20/3/95 Inputs: MaxSize - This is the size we have to fit the pathname into. Defaults to zero , meaning all off the pathname. Returns: A String_256 that holds the pathname for the document. Purpose: Returns the pathname of the document. SeeAlso: CCamDoc::GetKernelPathName; PathName::GetTruncatedPathName; SeeAlso: Document::GetLocation; CCamDoc::GetTruncatedLocation; ********************************************************************************************/ String_256 Document::GetPathName(UINT32 MaxSize) const { if (OilDoc) return OilDoc->GetKernelPathName(MaxSize); return(ClipboardNameText); } /******************************************************************************************** > String_256 Document::GetLocation(UINT32 MaxSize = 0) const Author: Neville_Humphrys (Xara Group Ltd) Created: 20/3/95 Inputs: MaxSize - This is the size we have to fit the pathname into. Defaults to zero , meaning all off the pathname. Returns: A String_256 that holds the location for the document. Purpose: Returns the location of the document, which is the pathname with no filename. SeeAlso: CCamDoc::GetKernelLocation; PathName::GetTruncatedLocation; SeeAlso: Document::GetPathName; CCamDoc::GetKernelPathName; ********************************************************************************************/ String_256 Document::GetLocation(UINT32 MaxSize) const { if (OilDoc) return OilDoc->GetKernelLocation(MaxSize); return(ClipboardNameText); } /******************************************************************************************** > const String_256& Document::GetProducer() const Author: Justin_Flude (Xara Group Ltd) Created: 15/3/94 Inputs: - Outputs: - Returns: A reference to the (constant) producer's name of this document. Purpose: Errors: - SeeAlso: Document::GetTitle; Document::GetComment ********************************************************************************************/ const String_256& Document::GetProducer() const { return Producer; } /******************************************************************************************** > const String_256& Document::GetComment() const Author: Justin_Flude (Xara Group Ltd) Created: 15/3/94 Inputs: - Outputs: - Returns: A reference to the (constant) producer's name of this document. Purpose: Getting the time the document was created. Errors: - SeeAlso: Document::GetTitle; Document::GetProducer ********************************************************************************************/ const String_256& Document::GetComment() const { return Comment; } /******************************************************************************************** > void Document::SetComment(String_256* NewComment) Author: Peter_Arnold (Xara Group Ltd) Created: 31/8/94 Inputs: A pointer to the new comment string. Outputs: - Returns: - Purpose: Setting the document's comment string. Errors: - SeeAlso: Document::GetComment ********************************************************************************************/ void Document::SetComment(String_256* NewComment) { Comment = *NewComment; } /******************************************************************************************** > const time_t& Document::GetCreationTime() const Author: Peter_Arnold (Xara Group Ltd) Created: 31/08/94 Inputs: - Outputs: - Returns: A reference to the time of the document's creation. Purpose: Errors: - SeeAlso: Document::GetLastSaveTime ********************************************************************************************/ const time_t& Document::GetCreationTime() const { return CreationTime; } /******************************************************************************************** > const time_t& Document::GetLastSaveTime() const Author: Peter_Arnold (Xara Group Ltd) Created: 31/08/94 Inputs: - Outputs: - Returns: A reference to the time of the document's creation. Will be 0 if the document is unsaved. Purpose: Getting the time the document was last saved. Errors: - SeeAlso: Document::GetCreationTime ********************************************************************************************/ const time_t& Document::GetLastSaveTime() const { return LastSaveTime; } /******************************************************************************************** > void Document::SetLastSaveTime() const Author: Peter_Arnold (Xara Group Ltd) Created: 1/09/94 Inputs: - Outputs: - Returns: - Purpose: Call on saving a document. Sets the document's last saved time. Errors: - SeeAlso: Document::GetLastSaveTime ********************************************************************************************/ void Document::SetLastSaveTime() { LastSaveTime = ::time(NULL); } /******************************************************************************************** > void Document::SetLastSaveTime(time_t) Author: Neville_Humphrys (Xara Group Ltd) Created: 30/7/96 Inputs: - Outputs: - Returns: - Purpose: Allows setting of the document's last saved time. Errors: - SeeAlso: Document::GetLastSaveTime ********************************************************************************************/ void Document::SetLastSaveTime(time_t NewTime) { LastSaveTime = NewTime; } /******************************************************************************************** > void Document::SetCreationTime(time_t) Author: Neville_Humphrys (Xara Group Ltd) Created: 30/7/96 Inputs: - Outputs: - Returns: - Purpose: Allows setting of the document's creation time. Errors: - SeeAlso: Document::GetLastSaveTime ********************************************************************************************/ void Document::SetCreationTime(time_t NewTime) { CreationTime = NewTime; } /******************************************************************************************** > void Document::MakeJustCreated() Author: Peter_Arnold (Xara Group Ltd) Created: 11/5/95 Inputs: - Outputs: Sets member variables Returns: - Purpose: Resets member variables of the document so it abbears as if the document has just been created (eg CreationTime is set to the current time) Errors: - SeeAlso: - ********************************************************************************************/ void Document::MakeJustCreated() { LastSaveTime = 0; // Zero means not saved CreationTime = ::time(NULL); } /******************************************************************************************** > void Document::InsertNewNode( Node* NewNode, DocCoord* Point ) Author: Rik_Heywood (Xara Group Ltd) Created: 3/9/93 Inputs: NewNode - A Pointer to the New node to be inserted pDestSpread - pointer to the spread which this new node should be inserted, If this is NULL then the object is inserted on the selected spread. Purpose: Inserts the Node into the Document at the position specified. The node is added to the active layer on this spread SeeAlso: Document::FindEnclosingChapter(); Document::FindEnclosingPage() ********************************************************************************************/ void Document::InsertNewNode( Node* NewNode, Spread *pDestSpread ) { SetCurrent(); Node *pNode; // Most of the time we will be inserting onto the selected spread // So find out what this is. if ((pDestSpread == NULL) || (pDestSpread == Document::GetSelectedSpread())) { // We need to insert the node onto the selected spread. This is very quick because we // keep an Insertion node there. pNode = GetInsertionPosition(); ENSURE(pNode != NULL, "Could not find insertion position in Document::InsertNewNode()"); // Attach the node to the left of the insertion node NewNode -> AttachNode( pNode, PREV ); } else { // This is assuming that we are inserting into the non-selected spread and so does // not use the insertion position. Unfortunately, there is a chance that this MAY happen // as the selected spread may be in a different document and so we are inserting into a // single spread document with an insertion node. The code below will insert AFTER the // insertion node and so will be in an illegal position. We really should check this!!! // As we are close to release I will put an error 3 in just in case. Neville 24/9/96 TRACE( _T("\aDocument::InsertNewNode inserting into the unselected spread. Is this correct?\n") ); pNode = pDestSpread->FindActiveLayer(); ENSURE(pNode != NULL, "Could not find layer in Document::InsertNewNode()"); // Attach this node to the tree at this point NewNode -> AttachNode( pNode, LASTCHILD ); } } /*********************************************************************************************** DocView *Document::GetSpareDocView() Author: Tim_Browse (Xara Group Ltd) Created: 19/5/93 Inputs: - Outputs: - Returns: NULL, or a spare DocView Purpose: Looks for a DocView with no attached OilView, so we can recycle it Errors: None. ***********************************************************************************************/ DocView* Document::GetSpareDocView() { if (IsNotAClipboard()) { DocView *View = (DocView *) DocViews.GetHead(); while (View != NULL) { CCamView *pCamView = View->GetConnectionToOilView(); if (pCamView == NULL) return View; View = (DocView *) DocViews.GetNext(View); } } return NULL; // No free views found } /*********************************************************************************************** > DocView* Document::GetNewDocView() Author: Tim_Browse (Xara Group Ltd) Created: 19/5/93 Inputs: - Outputs: - Returns: - Purpose: Returns a new DocView for the client. If any unconnected views already exist for this document, the first is returned. Otherwise a new DocView is created and returned. If a new DocView is obtained, it becomes the 'current' DocView before it is returned to the caller. Errors: None. ***********************************************************************************************/ DocView* Document::GetNewDocView() { // Is there a spare view knocking about? DocView *pDocView = GetSpareDocView(); if (pDocView != NULL) // Yes - so return it. return pDocView; if (IsAClipboard()) { TRACEUSER( "Jason",_T("\n\nXX Attempting to add a DocView to a clipboard!\n") ); } else { // No views spare - create a new one connected to this document... pDocView = new DocView(this); if (pDocView != NULL) { if (pDocView->Init()) DocViews.AddTail(pDocView); // link it into the DocView list ... else { delete pDocView; pDocView=NULL; } } // Make it the current DocView pDocView->SetCurrent(); } // ...and return this new view to the caller. return pDocView; } void Document::OnDocViewDying(DocView *pDocViewToDelete) { // Look for this DocView in the list DocView *pDocView = (DocView *) DocViews.GetHead(); // Traverse List of DocViews while (pDocView != NULL) { // Is this the DocView that is closing down? if (pDocView == pDocViewToDelete) { // Yes - remove it from the list and return DocViews.RemoveItem(pDocView); return; } // Try the next one pDocView = (DocView *) DocViews.GetNext(pDocView); } } /*********************************************************************************************** > void Document::ShowViewScrollers(BOOL fIsVisible) Author: Justin_Flude (Xara Group Ltd) Created: 2/11/94 Inputs: - Outputs: - Returns: - Purpose: Show or Hide Scollers on all Views SeeAlso: - *********************************************************************************************/ void Document::ShowViewScrollers(BOOL fIsVisible) { if (IsNotAClipboard()) { DocView* pDocView = (DocView*) DocViews.GetHead(); while (pDocView != NULL) { pDocView->ShowViewScrollers(fIsVisible); pDocView = (DocView *) DocViews.GetNext(pDocView); } } } /*********************************************************************************************** > void Document::ShowViewRulers(BOOL fIsVisible) Author: Chris_Snook (Xara Group Ltd) Created: 2/11/94 Inputs: - Outputs: - Returns: - Purpose: Show or Hide Rulers all Views SeeAlso: - *********************************************************************************************/ void Document::ShowViewRulers(BOOL fIsVisible) { #if !defined(EXCLUDE_FROM_RALPH) if (IsNotAClipboard()) { DocView* pDocView = (DocView*) DocViews.GetHead(); while (pDocView != NULL) { pDocView->ShowViewRulers(fIsVisible); pDocView = (DocView *) DocViews.GetNext(pDocView); } } #endif } /*********************************************************************************************** > CCamDoc* Document::GetOilDoc() const Author: Tim_Browse (Xara Group Ltd) Created: 19/5/93 Inputs: - Outputs: - Returns: NULL or a pointer to the CCamDoc object associated with this object. Purpose: Find the Oil document associated with the Document. Notes: IMPORTANT: Clipboard Documents may NOT have an attached OilDoc -> will return NULL Errors: None. ***********************************************************************************************/ CCamDoc* Document::GetOilDoc() const { return OilDoc; } /*********************************************************************************************** > static Document* Document::GetCurrent() Author: Tim_Browse (Xara Group Ltd) Created: 21/5/93 Inputs: - Outputs: - Returns: Pointer to the current Document object. Purpose: Find the current Document object. Errors: None. ***********************************************************************************************/ Document* Document::GetCurrent() { #ifdef RALPH if(::GetCurrentThreadId() == RalphDocument::GetImportingThreadID()) { //TRACEUSER( "Richard", _T("+++++ GetCurrent called from Load Thread\n")); return RalphDocument::GetImportingDoc(); } #endif //TRACEUSER( "Richard", _T(">>> Document::GetCurrent returning Current\n")); return Current; } /*********************************************************************************************** > static Document* Document::GetSelected() Author: Tim_Browse (Xara Group Ltd) Created: 21/5/93 Inputs: - Outputs: - Returns: Pointer to the selected Document object. Purpose: Find the selected Document object. Errors: None. ***********************************************************************************************/ Document* Document::GetSelected() { #ifdef RALPH // if we are being called from the load thread return the current load thread document if(::GetCurrentThreadId() == RalphDocument::GetImportingThreadID()) { //TRACEUSER( "Richard", _T("+++++ GetSelected called from Load Thread\n")); return RalphDocument::GetImportingDoc(); } #endif //TRACEUSER( "Richard", _T(">>> Document::GetSelected returning Selected\n")); return Selected; } /*********************************************************************************************** > void Document::SetCurrent() Author: Tim_Browse (Xara Group Ltd) Created: 21/5/93 Inputs: - Outputs: - Returns: - Purpose: Make this object be the 'current' document. **** Changed 22/7/94 by MarkN **** Does NOT broadcasts a message to all that this is happening any more. Errors: None. ***********************************************************************************************/ void Document::SetCurrent() { #ifdef RALPH // if we are being called from the load thread just ignore if(::GetCurrentThreadId() == RalphDocument::GetImportingThreadID()) return ; #endif Current = this; } /*********************************************************************************************** > static void Document::SetNoCurrent() Author: Tim_Browse (Xara Group Ltd) Created: 21/5/93 Inputs: - Outputs: - Returns: - Purpose: Set the current document pointer to be NULL, i.e., there is no current document object. **** Changed 22/7/94 by MarkN **** Does NOT broadcasts a message to all that this is happening any more. Errors: None. ***********************************************************************************************/ void Document::SetNoCurrent() { #ifdef RALPH // if we are being called from the load thread just ignore if(::GetCurrentThreadId() == RalphDocument::GetImportingThreadID()) return ; #endif Current = NULL; } /*********************************************************************************************** > void Document::SetNoSelectedViewAndSpread(void) Author: Jason_Williams (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: - Purpose: To set the Selected Document, DocView, and Spread. This sets all three of these entities to NULL - no selected entity. These 3 items are interlinked - changing the spread may mean changing to a different document and view - these changes can cause several messages (DocChangingMsg, SpreadMsg, etc) to be broadcast, so they must be treated as a single indivisble operation, which only broadcasts the necessary messages when the entrie state has been changed. Notes: If the Selected docuemnt changes, a DocChangingMsg (SELCHANGED) will be broadcast, with pOldDoc == the last selected Doc, and pNewDoc == the new selected document. Either/both of pOldDoc and pNewDoc may be NULL! If the Selected DocView changes, a DocViewMsg (SELCHANGED) will be broadcast, with the pOldDocView and pNewDocView fields indicating the old and new DocViews. If the Selected spread changes, a SpreadMsg (SELCHANGED) will be broadcast. pOldSpread and pNewSpread will point at the spreads involved. This does NOT affect the Current doc. ***********************************************************************************************/ void Document::SetNoSelectedViewAndSpread(void) { TRACEUSER("Gerry", _T("Document::SetNoSelectedViewAndSpread")); #ifdef RALPH // if we are being called from the load thread just ignore if(::GetCurrentThreadId() == RalphDocument::GetImportingThreadID()) return ; #endif // Remember if each of the selected things has chnaged as a result of this call Document *OldSelDocument = Selected; DocView *OldSelView = DocView::GetSelected(); Spread *OldSelSpread = pGlobalSelSpread; // Tell those that care that the selected view is about to become null. BROADCAST_TO_ALL(DocViewMsg(OldSelView, NULL, DocViewMsg::SELABOUTTOCHANGE)); // --- Set no selected spread pGlobalSelSpread = NULL; if (Selected != NULL) Selected->pSelSpread = NULL; // --- Set no selected document Selected = NULL; // --- Set no selected docview DocView::SetSelectedInternal(NULL); // --- And broadcast appropriate message(s) if (Selected != OldSelDocument) { BROADCAST_TO_ALL(DocChangingMsg(OldSelDocument, NULL, DocChangingMsg::SELCHANGED)); } if (DocView::GetSelected() != OldSelView) { DocView::SendSelectedMessage(OldSelView, DocView::GetSelected()); } if (pGlobalSelSpread != OldSelSpread) { BROADCAST_TO_ALL(SpreadMsg(OldSelSpread, NULL, SpreadMsg::SELCHANGED)); } // Ensure any delayed Selection message broadcasts are sent now GetApplication()->FindSelection()->BroadcastAnyPendingMessages(); } /*********************************************************************************************** > static void Document::SetSelectedViewAndSpread(Document *TheDocument = NULL, DocView *TheView = NULL, Spread *TheSpread = NULL); Author: Jason_Williams (Xara Group Ltd) Created: 13/2/95 Inputs: TheDocument - NULL, or a pointer to the document to make selected TheView - NULL, or the docview for TheDocument which should be made selected TheSpread - NULL or the Spread in TheDocument which should be made selected Outputs: - Returns: - Purpose: To set the Selected Document, DocView, and Spread. These 3 items are interlinked - changing the spread may mean changing to a different document and view - these changes can cause several messages (DocChangingMsg, SpreadMsg, etc) to be broadcast, so they must be treated as a single indivisble operation, which only broadcasts the necessary messages when the entrie state has been changed. Notes: If any of the parameters are NULL, sensible defaults (The currently selected document, the currently selected or first docview of that document, and the currently selected or first spread of that document, respectively) will be used. If the Selected document changes, a DocChangingMsg (SELCHANGED) will be broadcast, with pOldDoc == the last selected Doc, and pNewDoc == the new selected document. Either/both of pOldDoc and pNewDoc may be NULL. If the Selected DocView changes, a DocViewMsg (SELCHANGED) will be broadcast, with the pOldDocView and pNewDocView fields indicating the old and new DocViews. If the Selected spread changes, a SpreadMsg (SELCHANGED) will be broadcast. pOldSpread and pNewSpread will point at the spreads involved. This also sets CurrentDoc to equal the Selected Doc. Ths state should remain true during the broadcast of the DocChanging Message. Errors: ERROR2's will be generated if the parameters are incompatible (TheView must be a view onto TheDocuemnt; TheSpread must lie within TheDocument) ***********************************************************************************************/ void Document::SetSelectedViewAndSpread(Document *TheDocument, DocView *TheView, Spread *TheSpread) { // TRACEUSER("Gerry", _T("Document::SetSelectedViewAndSpread(0x%08x, 0x%08x, 0x%08x)"), TheDocument, TheView, TheSpread); #ifdef RALPH // if we are being called from the load thread just ignore if(::GetCurrentThreadId() == RalphDocument::GetImportingThreadID()) return ; #endif // We must remember if each of the selected things has changed as a result of this call Document *OldSelDocument = Selected; DocView *OldSelView = DocView::GetSelected(); Spread *OldSelSpread = pGlobalSelSpread; // Ensure that all parameters are valid pointers if (TheDocument == NULL) TheDocument = Selected; if (TheDocument == NULL) { // The caller is obviously trying to set the selected spread/view when there is // no valid document around ERROR3("Can't set selected spread/view when there is no selected doc!"); return; } if (TheView == NULL) { // The caller supplied no docview - try the selected docview, and if that is not // in the document becoming selected, then use the first view for the sel doc. TheView = DocView::GetSelected(); if (TheView == NULL || TheView->GetDoc() != TheDocument) TheView = (DocView *) TheDocument->DocViews.GetHead(); } if (TheSpread == NULL) { // The caller specified no spread - Try the globally selected spread, then the // document's memory of the selected spread, and finally, the first spread in the // document. if (pGlobalSelSpread != NULL && SpreadBelongsToDoc(TheDocument, pGlobalSelSpread)) TheSpread = pGlobalSelSpread; else { if (TheDocument->pSelSpread != NULL) TheSpread = TheDocument->pSelSpread; else TheSpread = TheDocument->FindFirstSpread(); } } // Tell those that care that the selected view is about to change if (TheView!=OldSelView) { BROADCAST_TO_ALL(DocViewMsg(OldSelView, OldSelView, DocViewMsg::SELABOUTTOCHANGE)); } // --- Set the new selected document, and also update CurrentDoc to be this one // (so that CurrentDoc points at selected while the broadcast goes around) Selected = TheDocument; Selected->SetCurrent(); OpNudge::SetNudgeStep (Selected->GetDocNudge ()); // CGS: since documents now store the nudge // --- Set the new selected DocView DocView::SetSelectedInternal(TheView); // --- Set the new selected spread ERROR3IF(TheSpread != NULL && !SpreadBelongsToDoc(Selected, TheSpread), "Selected spread should be in the Selected Doc!"); pGlobalSelSpread = TheSpread; if (Selected != NULL) Selected->pSelSpread = TheSpread; // --- Now, check if any have changed, and broadcast appropriate messages if (Selected != OldSelDocument) { BROADCAST_TO_ALL(DocChangingMsg(OldSelDocument, Selected, DocChangingMsg::SELCHANGED)); } if (DocView::GetSelected() != OldSelView) { DocView::SendSelectedMessage(OldSelView, DocView::GetSelected()); } if (pGlobalSelSpread != OldSelSpread) { BROADCAST_TO_ALL(SpreadMsg(OldSelSpread, pGlobalSelSpread, SpreadMsg::SELCHANGED)); } // Ensure any delayed Selection message broadcasts are sent now GetApplication()->FindSelection()->BroadcastAnyPendingMessages(); } /*********************************************************************************************** > void Document::SetSelected() Author: Tim_Browse (Xara Group Ltd) / MarkN Created: 21/5/93 Inputs: - Outputs: - Returns: - Purpose: THIS METHOD IS DEFUNCT! DO NOT CALL IT! Use Document::SetSelectedViewAndSpread() instead (This call is currently indirected to that one, and gives TRACE warnings) Make this object be the 'selected' document object. It sets the selected spread to be a relevent spread in this document. If there is a change in selected spread as a result, a SpreadMsg::SELCHANGED message is broadcast. A message is broadcast called SELCHANGED. On receipt of this message, pOldDoc is the one being deselected, and pNewDoc is the one being selected, NOTE!! pOldDoc and/or pNewDoc can be NULL!!! This does NOT effect the Current doc. If the new selected document is not the document associated with the selected DocView, then DocView::SetNoSelected() is called. This is because the selected DocView must be a view onto the selected document. Errors: None. ***********************************************************************************************/ #if 0 void Document::SetSelected() { #if FALSE /* // Defunct code - see below for replacement code if (Selected == this) return; Document* pOldDoc = Selected; Selected = this; // The selected document has changed, so ensure that the selected DocView belongs to the new // selected document // This is based on the rule that the selected DocView MUST be a view onto the selected document DocView* pSelDocView = DocView::GetSelected(); if ((pSelDocView != NULL) && (pSelDocView->GetDoc() != Selected)) DocView::SetNoSelected(); if (pSelSpread == NULL) pSelSpread = FindFirstSpread(); BROADCAST_TO_ALL(DocChangingMsg(pOldDoc,Selected,DocChangingMsg::DocState::SELCHANGED)); Document::SetSelectedSpread(pSelSpread); */ #else // Now just indirects to the centralised Doc/DocView/Spread selector TRACE( _T("WARNING: Illegal call to defunct Document::SetSelected\n")); Document::SetSelectedViewAndSpread(this, NULL, NULL); #endif } #endif /*********************************************************************************************** > static void Document::SetNoSelected() Author: Tim_Browse (Xara Group Ltd) Created: 21/5/93 Inputs: - Outputs: - Returns: - Purpose: THIS METHOD IS DEFUNCT! DO NOT CALL IT! Use Document::SetNoSelectedViewAndSpread() instead (This call is currently indirected to that one, and gives TRACE warnings) Set the selected document pointer to be NULL, i.e., there is no selected document object. This does NOT effect the Current doc. **** Changed 22/7/94 by MarkN **** A new message is broadcast that combines the SELECTED and UNSELECTED messages in one called SELCHANGED. On receipt of this message, pOldDoc is the one being deselected, and pNewDoc is the one being selected, NOTE!! pOldDoc and/or pNewDoc can be NULL!!! Errors: None. ***********************************************************************************************/ #if 0 void Document::SetNoSelected() { #if FALSE /* if (Selected == NULL) return; Document* pOldDoc = Selected; Selected = NULL; Document::SetSelectedSpread(NULL); BROADCAST_TO_ALL(DocChangingMsg(pOldDoc,NULL,DocChangingMsg::DocState::SELCHANGED)); */ #else TRACE( _T("WARNING: Illegal call to defunct Document::SetNoSelected\n")); Document::SetNoSelectedViewAndSpread(); #endif } #endif /*********************************************************************************************** > static void Document::SetSelectedSpread(Spread* pNewSelSpread) Author: Mark_Neves (Xara Group Ltd) Created: 3/8/94 Inputs: pNewSelSpread = ptr to the spread that is the new selected spread Outputs: - Returns: - Purpose: THIS METHOD IS DEFUNCT! DO NOT CALL IT! Use Document::SetSelectedViewAndSpread() instead (This call is currently indirected to that one, and gives TRACE warnings) Sets the global instance of the selected spread. pNewSelSpread must be a spread belonging to the selected document. Errors: - SeeAlso: - ***********************************************************************************************/ #if 0 void Document::SetSelectedSpread(Spread* pNewSelSpread) { #if FALSE /* // if no change return if (pGlobalSelSpread == pNewSelSpread) return; Spread* pOldSelSpread = pGlobalSelSpread; if (Selected == NULL && pNewSelSpread == NULL) // If there's no selected document, then there's no selected spread pGlobalSelSpread = NULL; else { // Make sure there is at least a selected doc ENSURE(Selected != NULL,"Can't set selected spread if there isn't a selected document"); // if there's a new sel spread, ensure it belongs to the selected doc if (pNewSelSpread != NULL) { ENSURE(SpreadBelongsToDoc(Selected,pNewSelSpread),"Trying to set the selected spread which doesn't belong to the selected doc."); } // We've ensured that there's a selected doc, and the new sel spread belongs to it pGlobalSelSpread = pNewSelSpread; Selected->pSelSpread = pNewSelSpread; } // Clear all current selections, and remove the blobs //NodeRenderableInk::DeselectAll(); // Inform the SelRange that it has changed, get it to broadcast //GetApplication()->FindSelection()->Update(TRUE); BROADCAST_TO_ALL(SpreadMsg(pOldSelSpread,pNewSelSpread,SpreadMsg::SpreadReason::SELCHANGED)); */ #else TRACE( _T("WARNING: Illegal call to defunct Document::SetSelectedSpread\n")); Document::SetSelectedViewAndSpread(Selected, NULL, pNewSelSpread); #endif } #endif /*********************************************************************************************** > static Spread *Document::GetSelectedSpread() Author: Mark_Neves (Xara Group Ltd) Created: 3/8/94 Inputs: - Outputs: - Returns: The selected spread in the system Purpose: Returns the selected spread Errors: - SeeAlso: - ***********************************************************************************************/ Spread *Document::GetSelectedSpread() { #ifdef RALPH // if we are being called from the load thread return the first spread in the current load // thread document if(::GetCurrentThreadId() == RalphDocument::GetImportingThreadID()) { //TRACEUSER( "Richard", _T("+++++ GetSelectedSpread called from Load Thread\n")); return RalphDocument::GetImportingDoc()->FindFirstSpread(); } #endif //TRACEUSER( "Richard", _T(">>> Document::GetSelectedSpread returning pGlobalSelSpread\n")); return (pGlobalSelSpread); } /*********************************************************************************************** > static BOOL Document::SpreadBelongsToDoc(Document* pDoc,Spread* pSpread) Author: Mark_Neves (Xara Group Ltd) Created: 3/8/94 Inputs: pDoc = ptr to a document pSpread = ptr to a spread Outputs: - Returns: TRUE if pSpread is a child of the NodeDocument belonging to pDoc FALSE otherwise Purpose: Tests to see if the spread belongs to the document Errors: - SeeAlso: - ***********************************************************************************************/ BOOL Document::SpreadBelongsToDoc(Document* pDoc,Spread* pSpread) { if (pDoc == NULL) return FALSE; // Find pDoc's first node Node* pNode = pDoc->GetFirstNode(); ENSURE(pNode != NULL,"No first node!"); // The next node should be the NodeDocument node pNode = pNode->FindNext(); ENSURE(pNode != NULL,"No next node!"); ENSURE(pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeDocument),"Next node is not a NodeDocument"); // pNode should now point to pDoc's NodeDocument node // Find pSpread's parent NodeDocument node Node* pParentNodeDoc = pSpread->FindParent(CC_RUNTIME_CLASS(NodeDocument)); ENSURE(pParentNodeDoc != NULL,"The spread has no NodeDocument parent"); // Return TRUE if pSpread's parent NodeDocument node == pDoc's NodeDocument node return ((pParentNodeDoc == pNode) && (pNode != NULL) && (pParentNodeDoc != NULL)); } /*********************************************************************************************** > Spread* Document::FindFirstSpread() Author: Mark_Neves (Xara Group Ltd) Created: 3/8/94 Inputs: - Outputs: - Returns: The first spread in this document. A document always has at least one spread Purpose: Finds the first spread in this document. Errors: - SeeAlso: - ***********************************************************************************************/ Spread* Document::FindFirstSpread() { Node* pNode = GetFirstNode(); ERROR3IF(pNode == NULL,"Document::FindFirstSpread No first node!"); if (pNode == NULL) return NULL; pNode = pNode->FindNext(); if (pNode != NULL) { ERROR3IF(pNode->GetRuntimeClass() != CC_RUNTIME_CLASS(NodeDocument),"Next node is not a NodeDocument"); pNode = pNode->FindFirstChild(); if (pNode != NULL) { if (pNode->GetRuntimeClass() != CC_RUNTIME_CLASS(Chapter)) pNode = pNode->FindNext(CC_RUNTIME_CLASS(Chapter)); if (pNode != NULL) { pNode = pNode->FindFirstChild(); if (pNode != NULL) { if (pNode->GetRuntimeClass() != CC_RUNTIME_CLASS(Spread)) pNode = pNode->FindNext(CC_RUNTIME_CLASS(Spread)); ERROR3IF(pNode == NULL,"Can't find a spread as a child of Chapter"); } else ERROR3("No child of Chapter node"); } else ERROR3("Can't find a chapter as a child of NodeDocument"); } else ERROR3("No child of NodeDocument node"); } else ERROR3("No next node!"); return ((Spread*)pNode); } /*********************************************************************************************** > void Document::GetExtents(DocCoord* Lo, DocCoord* Hi, DocRect* Extent, View *pView) Author: Tim_Browse (Xara Group Ltd) Created: 28/5/93 Inputs: pView - the View to pixelise the extents to. Outputs: Lo, Hi - the extents of the document. Returns: - Purpose: Find the extents of the document. These are in DocCoords - Lo is the bottom-left corner of the last chapter, and Hi is the top-right corner of the first chapter. Errors: - SeeAlso: - ***********************************************************************************************/ void Document::GetExtents(DocCoord* Lo, DocCoord* Hi, DocRect* Extent, View *pView) { NodeDocument* DocNode = (NodeDocument*) TreeStart->FindNext(); // Just to be on the safe side ENSURE(DocNode->IsKindOf(CC_RUNTIME_CLASS(NodeDocument)), "Document.cpp: This node is not a NodeDocument"); *Lo = DocNode->LoExtent(); *Hi = DocNode->HiExtent(); *Extent = DocNode->GetPasteboardRect(TRUE, pView); } /*********************************************************************************************** > void Document::UpdateExtents(const DocCoord& Lo, const DocCoord& Hi) Author: Tim_Browse (Xara Group Ltd) Created: 29/5/93 Inputs: Lo, Hi - the new Extents in document coordinates. Outputs: - Returns: - Purpose: Change the document extents. This will only be done by objects of class NodeDocument. All related DocViews are informed of the change. Errors: - SeeAlso: NodeDocument SeeAlso: GetExtents ***********************************************************************************************/ void Document::UpdateExtents(const DocCoord& Lo, const DocCoord& Hi) { DocView *pView = (DocView*) DocViews.GetHead(); // Scan list of all DocView of this Document while (pView != NULL) { // Inform DocView of the new document extent. pView->SetExtent(Lo, Hi); pView = (DocView*) DocViews.GetNext(pView); } } /******************************************************************************************** > OperationHistory& Document::GetOpHistory() Author: Simon_Maneggio (Xara Group Ltd) Created: 1/7/93 Inputs: - Outputs: - Returns: A reference to the documents operation history Purpose: For finding the documents operation history Errors: - SeeAlso: - ********************************************************************************************/ OperationHistory& Document::GetOpHistory() { return (*OpHistory); } /******************************************************************************************** > BOOL Document::EmptyOperationHistory() Author: Rik_Heywood (Xara Group Ltd) Created: 6/4/95 Returns: TRUE if the Operation History was empied ok, FALSE if there is a problem Purpose: This function deletes the operation history, destroying everything in it. It then creates a new empty Operation History and sets it up ready for use. This function was really created to allow the New and Open Document options to get rid of the undo that is created by the file importing. ********************************************************************************************/ BOOL Document::EmptyOperationHistory() { // If there was no Operation History in the first place, then there is a problem if (OpHistory==NULL) return FALSE; // Before we delete th history find out what its maximum size is UINT32 MaxSize = OpHistory->GetMaxSize(); // There is an Operation History, so toast it delete OpHistory; OpHistory = NULL; // Now try and replace it with a new one OpHistory = new OperationHistory(MaxSize); // If we did not get the memory to create a new one, then fail if (OpHistory==NULL) return FALSE; // We now have a nice new empty operation history, so return happy return TRUE; } /******************************************************************************************** > AttributeManager& GetAttributeMgr() const; Author: Simon_Maneggio (Xara Group Ltd) Created: 1/7/93 Inputs: - Outputs: - Returns: A reference to the documents operation history Purpose: For finding the documents operation history Errors: - SeeAlso: - ********************************************************************************************/ AttributeManager& Document::GetAttributeMgr() const { ENSURE(AttributeMgr != NULL, "Pointer to Attribute Manager is NULL in Document::GetAttributeMgr()"); return (*AttributeMgr); } /******************************************************************************************** > BOOL Document::IsMultilayer() Author: Mark_Neves (Xara Group Ltd) Created: 11/8/94 Inputs: - Outputs: - Returns: TRUE if the multilayer flag for the document is set. FALSE otherwise Purpose: Interogate the multilayer status of this document Errors: - SeeAlso: - ********************************************************************************************/ BOOL Document::IsMultilayer() { return (DocFlags.LayerMultilayer != 0); } /******************************************************************************************** > BOOL Document::IsAllVisible() Author: Mark_Neves (Xara Group Ltd) Created: 11/8/94 Inputs: - Outputs: - Returns: TRUE if the "all visible" flag for the document is set. FALSE otherwise Purpose: Interogate the "all visible" status of this document Errors: - SeeAlso: - ********************************************************************************************/ BOOL Document::IsAllVisible() { return (DocFlags.LayerAllVisible != 0); } /******************************************************************************************** > void Document::SetMultilayer(BOOL state) Author: Mark_Neves (Xara Group Ltd) Created: 11/8/94 Inputs: state = TRUE or FALSE Outputs: - Returns: - Purpose: Lets you set the state of the multilayer document flag Errors: - SeeAlso: - ********************************************************************************************/ void Document::SetMultilayer(BOOL state) { DocFlags.LayerMultilayer = state; } /******************************************************************************************** > void Document::SetAllVisible(BOOL state) Author: Mark_Neves (Xara Group Ltd) Created: 11/8/94 Inputs: state = TRUE or FALSE Outputs: - Returns: - Purpose: Lets you set the state of the "all visible" document flag Errors: - SeeAlso: - ********************************************************************************************/ void Document::SetAllVisible(BOOL state) { DocFlags.LayerAllVisible = state; } /******************************************************************************************** > NodeAttribute* Document::GetDefaultAttr(CCRuntimeClass* RequiredAttr) Author: Tim_Browse (Xara Group Ltd) Created: 25/10/93 Inputs: RequiredAttr - the type of attribute to look for. Returns: Pointer to the default attribute node, or NULL if the attribute was not found. Purpose: Finds the default attribute node for a document, given the attribute class to look for. For instance, to find out the default line width for a document: MonoOn AttrLineWidth *pAttr = pDoc->GetDefaultAttr(CC_RUNTIME_CLASS(AttrLineWidth)); MonoOff ********************************************************************************************/ NodeAttribute* Document::GetDefaultAttr(CCRuntimeClass* RequiredAttr) { // Search for line width attribute as a child of the NodeDocument. Node *pNode = TreeStart->FindNext(); if (pNode == NULL) { // Error in document tree return NULL; } if (!pNode->IsKindOf(CC_RUNTIME_CLASS(NodeDocument))) { // Error in document tree return NULL; } // Find the attribute in question for (pNode = pNode->FindFirstChild(); pNode != NULL; pNode = pNode->FindNext()) { if (pNode->IsKindOf(RequiredAttr)) return (NodeAttribute *) pNode; } // Required attribute was not found - just return NULL return NULL; } /******************************************************************************************** > NodeSetSentinel* Document::GetSetSentinel() const Author: Justin_Flude (Xara Group Ltd) Created: 30/11/93 Returns: A (cached) pointer to the document's NodeSetSentinel node. SeeAlso: NameGallery; NodeSetSentinel; Document::InitTree ********************************************************************************************/ NodeSetSentinel* Document::GetSetSentinel() const { ERROR3IF(m_pSetSentinel == 0, "Document::GetSetSentinel: no NodeSetSentinel"); return m_pSetSentinel; } /******************************************************************************************** > static void Document::IncCurrentNodeCount() Author: Justin_Flude (Xara Group Ltd) Created: 30/11/93 Inputs: - Outputs: - Returns: - Purpose: Adds one to the NodesInTree counter of the Current Document object, if it exists. Called by the constructors of class Node. Errors: - SeeAlso: Document::DecCurrentNodeCount; Document::NodesInDocument ********************************************************************************************/ void Document::IncCurrentNodeCount() { if (Current) Current->NodesInTree++; } /******************************************************************************************** > static void Document::DecCurrentNodeCount() Author: Justin_Flude (Xara Group Ltd) Created: 30/11/93 Inputs: - Outputs: - Returns: - Purpose: Decrements the node counter in the current Document, if there is one. Called by the destructor of class Node. Errors: - SeeAlso: Document::IncCurrentNodeCount; Document::NodesInDocument ********************************************************************************************/ void Document::DecCurrentNodeCount() { if (Current) Current->NodesInTree--; } /******************************************************************************************** > void Document::DeleteContents() Author: Justin_Flude (Xara Group Ltd) Created: 25/3/94 Inputs: - Outputs: - Returns: - Purpose: None. Nothing. Does not do anything. And don't even think about making it do anything! Errors: - SeeAlso: CCamDoc::DeleteContents ********************************************************************************************/ void Document::DeleteContents() { // This function does nothing because MFC calls it in a completely brain-damaged way. // It calls it when the document is about to be destroyed, and ALSO calls it just // after a new document has just been created. Fabby eh? Those boys from Redmond strike // again! (Tim) // DON'T make it do anything! } /******************************************************************************************** > void Document::ForceRedraw(FRDocViewFunc pFunc) Author: Justin_Flude (Xara Group Ltd) Created: 29/4/94 Inputs: pFunc = ptr to func to equire whether a particular DocView should be redrawn Purpose: Calls DocView::ForceRedraw() for each DocView attached to this Document. i.e. This forces a *complete* redraw for the whole document in all views attached to it. SeeAlso: DocView::ForceRedraw ********************************************************************************************/ void Document::ForceRedraw(FRDocViewFunc pFunc) { ListItem* pItem = DocViews.GetHead(); while (pItem != NULL) { BOOL ok = TRUE; DocView* pDocView = (DocView*)pItem; if (pFunc != NULL) ok = pFunc(pDocView); if (ok) { // Pass TRUE to DocView::ForceRedraw() so that we force an immediate update of // the paper, because this function is used when something pretty fundamental has // changed in the document, quite often related to spreads/pages etc. ((DocView*) pItem)->ForceRedraw(TRUE); } pItem = DocViews.GetNext(pItem); } } /******************************************************************************************** > void Document::ForceRedraw(WorkRect& forceRect) Author: Justin_Flude (Xara Group Ltd) Created: 29/4/94 Inputs: A WorkRect bounding the area to be redrawn Outputs: - Returns: - Purpose: Calls DocView::ForceRedraw(WorkRect&) for each DocView attached to this Document. Errors: - SeeAlso: DocView::ForceRedraw ********************************************************************************************/ void Document::ForceRedraw(WorkRect& forceRect) { ListItem* pItem = DocViews.GetHead(); while (pItem != NULL) { ((DocView*) pItem)->ForceRedraw(forceRect); pItem = DocViews.GetNext(pItem); } } /******************************************************************************************** > void Document::ForceRedraw(Spread* pSpread, DocRect spreadRect, BOOL Accumulate = FALSE, Node* pInvalidNode = NULL, BOOL bAutoRelease = TRUE) Author: Justin_Flude (Xara Group Ltd) Created: 29/4/94 Inputs: A pointer to a spread and the area within that spread to redraw. Outputs: - Returns: - Purpose: Calls DocView::ForceRedraw(Spread*, DocRect) for each DocView attached to this Document. Errors: - SeeAlso: DocView::ForceRedraw ********************************************************************************************/ void Document::ForceRedraw(Spread* pSpread, DocRect spreadRect, BOOL Accumulate, Node* pInvalidNode, BOOL bAutoRelease) { // If the caller has told us about a node that has become invalid (probably causing this redraw) // Then make sure it doesn't hold on to any cached rendering before we force the redraw if (pInvalidNode && bAutoRelease) { if (pInvalidNode->IsAnObject()) ((NodeRenderableInk*)pInvalidNode)->ReleaseCached(TRUE, TRUE); } ListItem* pItem = DocViews.GetHead(); while (pItem != NULL) { ((DocView*) pItem)->ForceRedraw(pSpread, spreadRect, Accumulate, pInvalidNode); pItem = DocViews.GetNext(pItem); } } /******************************************************************************************** > void Document::FlushRedraw() Author: Tim_Browse (Xara Group Ltd) Created: 22/12/94 Purpose: Calls DocView::FlushRedraw() for each DocView attached to this Document. SeeAlso: DocView::FlushRedraw ********************************************************************************************/ void Document::FlushRedraw() { ListItem* pItem = DocViews.GetHead(); while (pItem != NULL) { ((DocView*) pItem)->FlushRedraw(); pItem = DocViews.GetNext(pItem); } } /******************************************************************************************** > void Document::HandleNodeDeletion(Node* pNode) Author: Justin_Flude (Xara Group Ltd) Created: 29/4/94 Inputs: A WorkRect bounding the area to be redrawn Outputs: - Returns: - Purpose: Calls DocView::ForceRedraw(WorkRect&) for each DocView attached to this Document. Errors: - SeeAlso: DocView::ForceRedraw ********************************************************************************************/ void Document::HandleNodeDeletion(Node* pNode) { ListItem* pItem = DocViews.GetHead(); while (pItem != NULL) { ((DocView*) pItem)->HandleNodeDeletion(pNode); pItem = DocViews.GetNext(pItem); } } /******************************************************************************************** > InsertionNode* Document::GetInsertionPosition(); Author: Simon_Maneggio (Xara Group Ltd) Created: 18/7/94 Returns: The Insertion position. This will be the InsertionNode (Insert as a Previous child of this) Purpose: This function should be called to find the position in the document where a new object should be inserted. The object should always be inserted as a previous child of the InsertionNode which is returned. SeeAlso: UndoableOperation::DoInsertNewNode ********************************************************************************************/ InsertionNode* Document::GetInsertionPosition() { // Is the Insertion node in the corrrect spread ? Spread* SelSpread = Document::GetSelectedSpread(); ENSURE(SelSpread != NULL, "The selected spread is NULL"); // I think it's ok to search for the active layer here cos there is not likely // to be zillions of layers. Layer* SelActiveLyr = SelSpread->FindActiveLayer(); ENSURE(SelActiveLyr != NULL, "Could not find active layer on selected spread"); Node* InsertLyr = NULL; // The layer containing the InsertionNode. If one // exists. See the InsertionNode's destructor. if (InsertPos) { ERROR3IF(InsertPos->FindNext(), "InsertionNode is not the last node on a layer"); InsertLyr = InsertPos->FindParent(); // In a retail if the InsertPos' parent is NULL then we will survive this ERROR3IF(!InsertLyr, "The Insertion node's parent has been deleted"); // If the parent of the Insertion node is not a Layer then there is probably // cause for concern. Not very likely this. ENSURE(InsertLyr->GetRuntimeClass() == CC_RUNTIME_CLASS(Layer), "Parent of insertion node is not a layer"); } else { // Weve lost our Insertion Node. Create a new one InsertPos = new InsertionNode(this); if (!InsertPos) { return NULL; // Not v. likely } } if (SelActiveLyr != ((Layer*)InsertLyr)) { // The InsertionNode should be moved // this is the slow bit, but it will only happen when the selected spread // changes. InsertPos->MoveNode(SelActiveLyr, LASTCHILD); } // otherwise the InsertPos is in the correct position return InsertPos; } /******************************************************************************************** > void Document::ResetInsertionPosition() Author: Tim_Browse (Xara Group Ltd) Created: 18/08/94 Purpose: Forces the insertion node to move to the end of the layer that it is currently on. This is used by the filters so they can insert an arbitrary number of nodes into the tree without worryng about the insertion position being updated every time and then it can just update it at the end using this function. SeeAlso: Document::GetInsertionPosition ********************************************************************************************/ void Document::ResetInsertionPosition() { // Is the Insertion node in the correct spread ? Spread* SelSpread = Document::GetSelectedSpread(); if (SelSpread==NULL) { SelSpread = FindFirstSpread(); if (SelSpread==NULL) { ERROR3("Fialed to ResetInsertPosition(), unable to find a spread in this document"); return; } } // I think it's ok to search for the active layer here cos there is not likely // to be zillions of layers. Layer* pSelActiveLyr = SelSpread->FindActiveLayer(); if ( pSelActiveLyr ) { ERROR3IF(pSelActiveLyr == NULL, "Could not find active layer on selected spread"); //Node* InsertLyr = InsertPos->FindParent(); //ENSURE(InsertLyr->GetRuntimeClass() == CC_RUNTIME_CLASS(Layer), // "Parent of insertion node is not a layer") if (InsertPos == NULL) GetInsertionPosition(); // The InsertionNode should be moved if (InsertPos != NULL && pSelActiveLyr != NULL) InsertPos->MoveNode(pSelActiveLyr, LASTCHILD); /* Node* pInsertPosNode = GetInsertionPosition(); ERROR3IF(pInsertPosNode == NULL,"Can't get hold of the insert node"); // The InsertionNode should be moved if (pInsertPosNode != NULL) pInsertPosNode->MoveNode(SelActiveLyr, LASTCHILD); */ } } /******************************************************************************************** > static BOOL Document::ReadPrefs() Author: Justin_Flude (Xara Group Ltd) Created: 5/1/95 Inputs: - Outputs: - Returns: TRUE if successful. Purpose: Reads preferences for the Document class from the program's .INI file. Errors: - SeeAlso: InitKernel ********************************************************************************************/ BOOL Document::ReadPrefs() { if (Camelot.DeclareSection(TEXT("Preferences"), 1)) { Camelot.DeclarePref(TEXT("Preferences"), TEXT("RemoveExistingDocs"), &CCamDoc::s_RemoveExistingOnNewDoc, FALSE, TRUE); } return TRUE; } /******************************************************************************************** > BOOL Document::EPSStartImport(EPSFilter *pFilter) Author: Tim_Browse (Xara Group Ltd) Created: 03/08/94 Inputs: pFilter - the EPS filter that is being used to import a file. Returns: TRUE if the document was able to prepare for importing; FALSE if not (e.g. out of memory) Purpose: Inform the document that an EPS import is about to start. SeeAlso: DocComponent ********************************************************************************************/ BOOL Document::EPSStartImport(EPSFilter *pFilter) { return TRUE; } /******************************************************************************************** > void Document::EPSEndImport(EPSFilter *pFilter, BOOL Success) Author: Tim_Browse (Xara Group Ltd) Created: 03/08/94 Inputs: pFilter - the EPS filter that is being used to import a file. Success - TRUE => The import was successful; FALSE => The import failed - abandon any changes. Purpose: Inform the document that an EPS import has just finished. SeeAlso: DocComponent ********************************************************************************************/ void Document::EPSEndImport(EPSFilter *pFilter, BOOL Success) { } /******************************************************************************************** > BOOL Document::EPSStartExport(EPSFilter *pFilter) Author: Tim_Browse (Xara Group Ltd) Created: 03/08/94 Returns: TRUE if the document was able to prepare for exporting; FALSE if not (e.g. out of memory) Inputs: pFilter - the EPS filter that is being used to export a file. Purpose: Inform the document that an EPS export is about to start. SeeAlso: DocComponent ********************************************************************************************/ BOOL Document::EPSStartExport(EPSFilter *pFilter) { return TRUE; } /******************************************************************************************** > void Document::EPSEndExport(EPSFilter *pFilter) Author: Tim_Browse (Xara Group Ltd) Created: 03/08/94 Inputs: pFilter - the EPS filter that is being used to import a file. Purpose: Inform the document that an EPS export has just finished. SeeAlso: DocComponent ********************************************************************************************/ void Document::EPSEndExport(EPSFilter *pFilter) { } /******************************************************************************************** > BOOL Document::WriteEPSProlog ( EPSFilter *pFilter ) Author: Tim_Browse (Xara Group Ltd) Created: 01/08/94 Inputs: pFilter - the EPS filter that is being used to export a file. Returns: TRUE if the Prolog for this document was written out successfully; FALSE if not (e.g. out of disk space etc) Purpose: Write out the EPS prolog for this document, using the EPS filter object supplied. (The base class does nothing except return TRUE) SeeAlso: Document::WriteEPSSetup; Document::WriteEPSComments; Document::ProcessEPSComment; DocComponent; EPSFilter ********************************************************************************************/ BOOL Document::WriteEPSProlog ( EPSFilter *pFilter ) { // This function is only called from the AIEPS render region. EPSExportDC *pDC = pFilter->GetExportDC (); AIExportProlog ( pDC ); return TRUE; } /******************************************************************************************** > BOOL Document::WriteEPSFonts(EPSFilter *pFilter) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pFilter - the EPS filter that is being used to export a file. Returns: TRUE if the fonts for this document was written out successfully; FALSE if not (e.g. out of disk space etc) Purpose: Write out the EPS fonts for this document, using the EPS filter object supplied. (The base class does nothing except return TRUE) SeeAlso: Document::WriteEPSProlog; Document::WriteEPSComments; Document::ProcessEPSComment; DocComponent; EPSFilter ********************************************************************************************/ BOOL Document::WriteEPSFonts(EPSFilter *pFilter) { if ( (pFilter->IS_KIND_OF(CamelotNativeEPSFilter)) || (pFilter->IS_KIND_OF(AIEPSFilter)) ) { EPSExportDC *pDC = pFilter->GetExportDC(); String_64 FontName; String_64 EFont; INT32 Style; FontList CurFontList; BOOL first=TRUE; if (!CurFontList.Build(this)) return FALSE; FontListItem* pItem = CurFontList.GetFirstItem(); while (pItem) { FontName = pItem->GetFontName(); Style = pItem->GetFontStyle(); // Graeme (31-3-00) - Map the encoded name onto the PS font name. FONTMANAGER->EncodeAndMapFontName(FontName, EFont, Style); if (first) pDC->OutputToken(_T("%%DocumentFonts:")); else pDC->OutputToken(_T("%%+")); pDC->OutputToken((TCHAR*)EFont); pDC->OutputNewLine(); first=FALSE; pItem = CurFontList.GetNextItem(pItem); } } return TRUE; } /******************************************************************************************** > BOOL Document::WriteEPSResources(EPSFilter *pFilter) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pFilter - the EPS filter that is being used to export a file. Returns: TRUE if the resources for this document was written out successfully; FALSE if not (e.g. out of disk space etc) Purpose: Write out the EPS resources for this document, using the EPS filter object supplied. (The base class does nothing except return TRUE) SeeAlso: Document::WriteEPSProlog; Document::WriteEPSComments; Document::ProcessEPSComment; DocComponent; EPSFilter ********************************************************************************************/ BOOL Document::WriteEPSResources(EPSFilter *pFilter) { // Graeme (24/3/00) - Removed the IsKindOf ( AIEPSFilter ) calls because this is now // only called from the AI render region. EPSExportDC *pDC = pFilter->GetExportDC(); pDC->OutputToken(_T("%%DocumentNeededResources:")); AIExportResources(pDC,TRUE); return TRUE; } /******************************************************************************************** > BOOL Document::WriteEPSSetup(EPSFilter *pFilter) Author: Tim_Browse (Xara Group Ltd) Created: 01/08/94 Inputs: pFilter - the EPS filter that is being used to export a file. Returns: TRUE if the Prolog for this document was written out successfully; FALSE if not (e.g. out of disk space etc) Purpose: Write out the EPS setup for this document, using the EPS filter object supplied. (The base class does nothing except return TRUE) SeeAlso: Document::WriteEPSProlog; Document::WriteEPSComments; Document::ProcessEPSComment; DocComponent; EPSFilter ********************************************************************************************/ BOOL Document::WriteEPSSetup(EPSFilter *pFilter) { // only do something if the filter is an Illustrator one if (pFilter->IS_KIND_OF(AIEPSFilter)) { EPSExportDC *pDC = pFilter->GetExportDC(); ExportTextSetup(pFilter); AIExportExtras(pDC); AIExportCharEncoding(pDC); AIExportFontEncoding(pDC); } return TRUE; } /******************************************************************************************** > BOOL Document::WriteEPSComments(EPSFilter *pFilter) Author: Tim_Browse (Xara Group Ltd) Created: 01/08/94 Inputs: pFilter - the EPS filter that is being used to export a file. Outputs: - Returns: TRUE if the EPS comments for this document were written out successfully; FALSE if not (e.g. out of disk space etc) Purpose: Write out any comments that need to be in the initial batch of EPS comments (i.e. before the %%EndComments line), using the specified EPS Filter object. (The base class does nothing except return TRUE) SeeAlso: Document::WriteEPSSetup; Document::WriteEPSProlog; Document::ProcessEPSComment; DocComponent; EPSFIlter ********************************************************************************************/ BOOL Document::WriteEPSComments(EPSFilter *pFilter) { // only do something if the filter is a Native one if (pFilter->IS_KIND_OF(CamelotNativeEPSFilter)) { // NOTE: If you add something new then ensure you export it at the end of the list. // This is because older versions of the program (1.0b and before) will stop // processing at unknown comments and can cause immense problems. // Output the colour table in ArtWorks format. EPSExportDC *pDC = pFilter->GetExportDC(); // The Page List comment: pDC->OutputToken(_T("%%DocumentInfo")); pDC->OutputNewLine(); // Export the Units. These should really be saved out as early as possible // as other things (such as the grid settings) can make use of them. ExportUnitInfo(pDC); // Export the page layout ExportPageInfo(pDC); // The Document Comment comment: ExportDocumentComment(pDC); // Now save out the Views ScaleFactor and Scroll Offsets ExportViewInfo(pDC); // Now save out the State vars of the view ExportStateInfo(pDC); // Save out the View Quality ExportQualityInfo(pDC); // Grid settings ExportGridInfo(pDC); // View flags (always on top, maximised etc) ExportFlagInfo(pDC); // Export the date info ExportDateInfo(pDC); // Export the undo info (document history) ExportUndoInfo(pDC); // These were all exported in version 1.00b of Studio // These are new ones after the this release version. // Export the default units. Must be saved after the user units as we // might have defined a user unit as the default. ExportDefaultUnitsInfo(pDC); //Export the ruler and scroller visible states // removed by Chris 27/10/95 // Ruler/Scroller state now set only from a global preference // see ImportRulerState(); //ExportRulerState(pDC); // export the origin info - must be output after grid and page info as they both // reset the origin so must both be imported before the origin is finally set ExportOriginInfo(pDC); } return TRUE; } /******************************************************************************************** > BOOL Document::WriteEPSTrailer(EPSFilter *pFilter) Author: Mike_Kenny (Xara Group Ltd) Created: 19/4/94 Inputs: pFilter - the EPS filter that is being used to export a file. Returns: TRUE if the Trailer for this document was written out successfully; FALSE if not (e.g. out of disk space etc) Purpose: Write out the EPS trailer for this document, using the EPS filter object supplied. (The base class does nothing except return TRUE) SeeAlso: Document::WriteEPSProlog; Document::WriteEPSComments; Document::ProcessEPSComment; DocComponent; EPSFilter ********************************************************************************************/ BOOL Document::WriteEPSTrailer(EPSFilter *pFilter) { // only do something if the filter is an Illustrator one if (pFilter->IS_KIND_OF(AIEPSFilter)) { EPSExportDC *pDC = pFilter->GetExportDC(); AIExportTrailer(pDC); } ExportTextTrailer(pFilter); return TRUE; } /******************************************************************************************** > BOOL ReadNextNumber(INT32* Number, TCHAR* Comment, INT32* Offset) Author: Rik_Heywood (Xara Group Ltd) Created: 15/2/95 Inputs: Comment - The string we are reading from Offset - the offset into the string that we start from Outputs: Number - holds the number in the string if the function returns TRUE Offset - Holds the offset to just after the number in the string if the function returns TRUE Returns: TRUE if it worked, FALSE if it could not find a number Purpose: Called by Document::ProcessEPSComment to help tidy up the code a little. This actually just reads a number out of a string. ********************************************************************************************/ BOOL ReadNextNumber(INT32* Number, TCHAR* Comment, INT32* Offset) { INT32& i = *Offset; BOOL IsNegative = FALSE; // Skip till we get to the first number while (!isdigit(Comment[i]) && (Comment[i] != 0) && (Comment[i]!='-')) i++; if (Comment[i]=='-') { // Negative number IsNegative = TRUE; i++; } // Read in the number if (isdigit(Comment[i])) { // get the Number *Number=0; camSscanf(&(Comment[i]),_T("%d"),Number); // Set the sign if (IsNegative) *Number = -(*Number); // Skip to the next number while (isdigit(Comment[i])) i++; // finished return TRUE; } // Failed return FALSE; } /******************************************************************************************** > BOOL ReadNextNumber(UINT32* Number, TCHAR* Comment, INT32* Offset) Author: Simon_Maneggio (Xara Group Ltd) Created: 07/07/95 Inputs: Comment - The string we are reading from Offset - the offset into the string that we start from Outputs: Number - holds the number in the string if the function returns TRUE Offset - Holds the offset to just after the number in the string if the function returns TRUE Returns: TRUE if it worked, FALSE if it could not find a number Purpose: Called by Document::ProcessEPSComment to help tidy up the code a little. This actually just reads a number out of a string. ********************************************************************************************/ BOOL ReadNextNumber(UINT32* Number, TCHAR* Comment, INT32* Offset) { INT32& i = *Offset; // Skip till we get to the first number while (!isdigit(Comment[i]) && (Comment[i] != 0)) i++; // Read in the number if (isdigit(Comment[i])) { // get the Number *Number=0; camSscanf(&(Comment[i]),_T("%ud"),Number); // Skip to the next number while (isdigit(Comment[i])) i++; // finished return TRUE; } // Failed return FALSE; } /******************************************************************************************** > BOOL ReadNextNumber(double* Number, TCHAR* Comment, INT32* Offset) Author: Rik_Heywood (Xara Group Ltd) Created: 15/2/95 Inputs: Comment - The string we are reading from Offset - the offset into the string that we start from Outputs: Number - holds the number in the string if the function returns TRUE Offset - Holds the offset to just after the number in the string if the function returns TRUE Returns: TRUE if it worked, FALSE if it could not find a number Purpose: Called by Document::ProcessEPSComment to help tidy up the code a little. This actually just reads a number out of a string. ********************************************************************************************/ BOOL ReadNextNumber(double* Number, TCHAR* Comment, INT32* Offset) { INT32& i = *Offset; // Skip till we get to the first number while (camIsspace(Comment[i]) && (Comment[i]!=0)) i++; // Read in the number if (!camIsspace(Comment[i])) { // get the Number *Number=0.0; camSscanf(&(Comment[i]),_T("%lf"),Number); // Skip to the next number while (!camIsspace(Comment[i])) i++; // finished return TRUE; } // Failed return FALSE; } /******************************************************************************************** > BOOL GetNextString(StringBase* pString, INT32 MaxLen, TCHAR* Comment, INT32* Offset)) Author: Rik_Heywood (Xara Group Ltd) Created: 28/3/95 Inputs: MaxLen - the max length of the output string Comment - The string we are reading from Offset - the offset into the string that we start from Outputs: pString - Holds the string Offset - Holds the offset to just after the number in the string if the function returns TRUE Returns: TRUE if it worked, FALSE if it could not find a string Purpose: Called by Document::ProcessEPSComment to help tidy up the code a little. This actually just reads a string out of a string. ********************************************************************************************/ BOOL ReadNextString(StringBase* pString, INT32 MaxLen, TCHAR* Comment, INT32* Offset) { INT32& i = *Offset; TCHAR TempStr[256]; // Skip till we get to the start of the string (Which is the '(' char) while ((Comment[i]!='(') && (Comment[i]!=0)) i++; // ok, read the string in if (Comment[i]=='(') { // Eat the open bracket i++; // Start to copy the string TCHAR Ch; INT32 Dst = 0; do { // Get this char and store it Ch = Comment[i]; TempStr[Dst] = Ch; Dst++; i++; if (Ch=='\\') { // This is the escape char, so store the char that follows it, // but do not change the value of Ch or it may think that the comment is ending TempStr[Dst-1] = Comment[i]; i++; } } while (((Ch!=0) && (Ch!=')')) || (Dst==MaxLen-1)); // Terminate the string TempStr[Dst-1] = 0; // Copy the string into the StringBase pString->Empty(); *pString += (TCHAR*)TempStr; return TRUE; } // if we get here, we did not extract the string return FALSE; } /******************************************************************************************** > ProcessEPSResult Document::ProcessEPSComment(EPSFilter *pFilter, const TCHAR *pComment) Author: Tim_Browse (Xara Group Ltd) Created: 01/08/94 Inputs: pFilter - the EPS filter that is being used to import a file. pComment - read only buffer containing - This EPS comment is not recognised by the document. EPSCommentSy the whole EPS comment to parse. Returns: EPSCommentUnknown ntaxError - This EPS comment was recognised by this document but it contained an error. EPSCommentSystemError - This EPS comment was recognised by this document but a system error occured that was not caused directly by the comment, e.g. out of memory. EPSCommentOK - This EPS comment was recognised as a legal comment by this document, and was processed successfully. Purpose: Process an EPS comment found in the file, if it 'belongs' to the document. If it does not, then the document should return EPSCommentUnknown, and the comment will be passed on to the document components. If the function returns EPSCommentOK, and the next line in the file starts with "%%+", i.e. an EPS/PostScript continuation comment, then this will be passed to this document immediately, without trying any of the document components first. This allows items such a colour lists to be imported easily, as they are usually specified on multiple lines in the file, using "%%+" comments. (The base class does nothing - it returns EPSCommentUnknown) SeeAlso: Document::EndOfEPSComment; Document::WriteEPSProlog; Document::WriteEPSSetup; Document::WriteEPSComments; DocComponent; ProcessEPSResult; EPSFIlter ********************************************************************************************/ ProcessEPSResult Document::ProcessEPSComment(EPSFilter *pFilter, const TCHAR *pComment) { // OK, to begin with, set the current doc and view to this doc and it's first view. SetCurrent(); if (GetFirstDocView() != NULL){ GetFirstDocView()->SetCurrent(); } if ((pFilter->IS_KIND_OF(CamelotNativeEPSFilter)) && !IsImporting()) { // Take a copy of the comment TCHAR Comment[256]; camStrcpy(Comment, pComment); // Look for Document info if (camStrncmp(pComment, _T("%%NativePageList"), 16) == 0) { // Found the page description table return EPSCommentOK; } else if (camStrncmp(pComment, _T("%%DocumentInfo"), 14) == 0) { // Found the page description table // Set the Documents Comment to nothing String_256 Empty(""); SetComment(&Empty); return EPSCommentOK; } else if (camStrncmp(pComment, _T("%%+"), 3) == 0) { // Assume we do not know about this comment until we can prove that we do. // // NOTE: If you add something new then ensure you export it at the end of the list. // This is because older versions of the program (1.0b and before) will stop // processing at unknown comments and can cause immense problems. ProcessEPSResult Result = EPSCommentUnknown; TCHAR InfoType = pComment[3]; switch (InfoType) { // The Document Info Comment (as seen in the Document Info dialog in the File menu) case 'c' : { Result = ImportDocumentComment(Comment); break; } // Read in the Creation and Last Saved dates case 'd' : { Result = ImportDateInfo(Comment); break; } // Read in the View Flags case 'f': { break; } // Read in the Grid Settings case 'g': { Result = ImportGridInfo(Comment); break; } // Read in the Grid Settings case 'o': { Result = ImportOriginInfo(Comment); break; } // Document history which is the specified undo size case 'h': { Result = ImportUndoInfo(Comment); break; } // Page Description case 'p' : { // load in the new page layout Result = ImportPageInfo(Comment); // adjust the page origin to match the new page. pFilter->ResetImportOrigin(); break; } // Read in the View Quality Settings case 'q': { // Load in the new view quality Result = ImportQualityInfo(Comment); #if !defined(EXCLUDE_FROM_RALPH) // update all the view quality sliders QualitySliderDescriptor::Update(); #endif break; } // The DocView State Info (Grid on/off, Snapping on/off etc) case 's' : { Result = ImportStateInfo(Comment); break; } // The Unit settings case 'u' : { Result = ImportUnitInfo(Comment); break; } // The default display unit settings case 'U' : { Result = ImportDefaultUnitsInfo(Comment); break; } // The Ruler and Scroller visible state case 'r' : { //Result = ImportRulerState(Comment); // removed by Chris 27/10/95 // just ignore this token now // Ruler/Scroller state now set only from a global preference Result = EPSCommentOK; break; } // The View Setting (Scale Factor, Scroll offsets etc) case 'v' : { Result = ImportViewInfo(Comment); break; } default : { Result = EPSCommentUnknown; break; } } // Result will hold the result of any processing of this continuation comment return Result; } } else if (pFilter->IS_KIND_OF(CamelotNativeEPSFilter)) { // Importing a native file - we need to get the page origin so that the filter // can position the objects correctly. // Take a copy of the comment TCHAR Comment[256]; camStrcpy(Comment, pComment); // Look for Document info if (camStrncmp(pComment, _T("%%NativePageList"), 16) == 0) { // Found the page description table return EPSCommentOK; } else if (camStrncmp(pComment, _T("%%DocumentInfo"), 14) == 0) { // Found the page description table // Set the Documents Comment to nothing String_256 Empty(""); SetComment(&Empty); return EPSCommentOK; } else if (camStrncmp(pComment, _T("%%+"), 3) == 0) { // Default to recognising this comment - all we care about is extracting the page origin. ProcessEPSResult Result = EPSCommentOK; TCHAR InfoType = pComment[3]; if (InfoType == 'p') { // Set the default version INT32 Version = -1; // Where in the comment to start looking from (skip over %%+p) INT32 i = 4; // Read in the version number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Descide what to do based on the version number switch (Version) { case 0 : { // Version 0 expects to find the following infomation // Width, Height, Margin, Bleed, Dps, ShowDropShadow // Get something to put all the numbers into MILLIPOINT Dummy, Margin; // Read in the Width of the page if (!ReadNextNumber(&Dummy, Comment, &i)) return EPSCommentSyntaxError; // Read in the Height of the page if (!ReadNextNumber(&Dummy, Comment, &i)) return EPSCommentSyntaxError; // Read in the Margin of the page if (!ReadNextNumber(&Margin, Comment, &i)) return EPSCommentSyntaxError; // Ok, we've got the margin, so tell the EPS filter about it. DocCoord NewOrigin(Margin, Margin); pFilter->ResetImportOrigin(NewOrigin); } // Unknown version default: { // Here we have got a version number we do not know how to process // so just ignore this comment happy. we will say that the comment // was OK as an error is technically wrong in this case } } } // Result will hold the result of any processing of this continuation comment return Result; } } return EPSCommentUnknown; } /******************************************************************************************** > void Document::EndOfEPSComment(EPSFilter *pFilter) Author: Tim_Browse (Xara Group Ltd) Created: 02/08/94 Inputs: pFilter - the EPS filter that is being used to import a file. Purpose: Informs the document that the comment it has been decoding has now finished, and it should take whatever action required to act on the comment. This call is made even for single-line comments, because by the nature of DSC comments, it is not known until the next comment starts or a non-comment line is encountered that the comment is over and is not multi-line. SeeAlso: Document::ProcessEPSComment; Document::WriteEPSProlog; Document::WriteEPSSetup; Document::WriteEPSComments; DocComponent; EPSFilter ********************************************************************************************/ void Document::EndOfEPSComment(EPSFilter *pFilter) { } /******************************************************************************************** > INT32 Document::GetSizeOfExport(Filter *pFilter) Author: Tim_Browse (Xara Group Ltd) Created: 27/01/95 Inputs: pFilter - the export filter that will be used. Returns: An approximation of the size of data that will be exported by this document, in terms of nodes. (see NodeRenderable::GetSizeOfExport). Purpose: Find out how many nodes will be exported when this document is exported. The node can use the filter to find out how it will be exported. NB. This is virtual - the default implementation just returns 1 - only override if this is not accurate. SeeAlso: Node::NeedsToExport; Node::ExportRender; NodeRenderable::GetSizeOfExport ********************************************************************************************/ INT32 Document::GetSizeOfExport( Filter * ) { // Default value is one node... return 1; } /******************************************************************************************** > DocView* Document::GetTopmostView() const Author: Justin_Flude (Xara Group Ltd) Created: 5/10/96 Returns: A pointer to the DocView of this Document that is top-most in the Z-order window list. It's the view onto this document that was last worked in by the user. Returns NULL if this document has no visible views. Purpose: Finds out which of this Document's DocViews is 'selected'. SeeAlso: CCamDoc::SetPageSize ********************************************************************************************/ DocView* Document::GetTopmostView() const { // Search through all the views onto this document. DocView* pvTop = 0; INT32 zTop = -1; for (DocView* pv = GetFirstDocView(); pv; pv = GetNextDocView(pv)) { // Is this view above our current highest? if (pv->pVState && pv->pVState->zPos > zTop) { // It is, so remember it as the new highest. zTop = pv->pVState->zPos; pvTop = pv; } } // Return the highest, if any. return pvTop; } /******************************************************************************************** > MILLIPOINT Document::GetBleedOffset() const Author: Neville_Humphrys (Xara Group Ltd) Created: 14/12/94 Inputs: - Outputs: - Returns: The current size in millipoints of this Document's bleed area. Purpose: For getting the Document's bleed area size. Errors: - SeeAlso: SetBleedOffset(); ********************************************************************************************/ MILLIPOINT Document::GetBleedOffset() const { return BleedOffset; } /******************************************************************************************** > BOOL Document::SetBleedOffset(MILLIPOINT Bleed) Author: Neville_Humphrys (Xara Group Ltd) Created: 14/12/94 Inputs: - Outputs: - Returns: The current size in millipoints of this document's bleed area. Purpose: For setting a new value for the Document's bleed area size. Errors: - SeeAlso: Document::GetBleedOffset(); ********************************************************************************************/ BOOL Document::SetBleedOffset(MILLIPOINT Bleed) { BleedOffset = Bleed; // set up new bleed value return TRUE; } /******************************************************************************************** > BOOL Document::ExportPageInfo(EPSExportDC *pDC) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: pDC - The DC to render to Returns: TRUE Purpose: Exports a Document Info continuation comment that describes the page layout. It takes the following form :- %%+p VersionNum if VersionNum is zero then the following will be on the rest of the line Width Height Margin Bleed DPS(1 for yes, 0 for no) ShowDropShadow(1 for yes, 0 for no) ********************************************************************************************/ BOOL Document::ExportPageInfo(EPSExportDC *pDC) { // Find the first spread to get the page info from // Don't use the selected spread as it breaks save all // do don't do Spread* pSpread = GetSelectedSpread(); Node *pANode = GetFirstNode()->FindNext()->FindFirstChild(); while ((pANode != NULL) && (!pANode->IsKindOf(CC_RUNTIME_CLASS(Chapter)))) pANode = pANode->FindNext(); ERROR2IF(!pANode->IsKindOf(CC_RUNTIME_CLASS(Chapter)), FALSE, "Document::Export(something)(): Could not find Chapter"); Chapter *pChapter = (Chapter *) pANode; // pSpread is a child of pChapter Spread *pSpread = (Spread *) pChapter->FindFirstChild(); ERROR2IF(!pSpread->IsKindOf(CC_RUNTIME_CLASS(Spread)), FALSE, "Document::Export(something)(): Could not find Spread"); // get something to put all the page info into TCHAR Buffer[256]; MILLIPOINT Width, Height; MILLIPOINT Margin, Bleed; BOOL Dps, ShowDropShadow; INT32 Version = 0; // and go and get all the page info BOOL Worked = pSpread->GetPageSize(&Width, &Height, &Margin, &Bleed, &Dps, &ShowDropShadow); // If it worked, we had better try and output some info if (Worked) { // Build a string with all the data in it camSprintf(Buffer, _T("%d %d %d %d %d %d %d"), Version, (INT32)Width, (INT32)Height, (INT32)Margin, (INT32)Bleed, Dps, ShowDropShadow); // Output the line to the file pDC->OutputToken(_T("%%+p")); pDC->OutputToken(Buffer); pDC->OutputNewLine(); } return TRUE; } /******************************************************************************************** > BOOL Document::ExportDocumentComment(EPSExportDC *pDC) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: pDC - The DC to render to Returns: TRUE Purpose: Will export as many Document Info continuation comments as are needed to save out the whole comment. Each continuation comment takes the form as follows :- %%+c CommentHere Each line will not have more that about 100 chars of comment on it (they will all be simple joined together when importing). If there is a new line char in the comment the continuation comment will end at that point, but the last char of the continuation comment will be ^. ********************************************************************************************/ BOOL Document::ExportDocumentComment(EPSExportDC *pDC) { #if !defined(EXCLUDE_FROM_RALPH) // Save this out in 200 Char lines, using many continuation comments if needed String_256 Comment = GetComment(); INT32 StrLength = Comment.Length(); // Go though the string splitting it up as needed TCHAR OneLine[256]; TCHAR Buffer[256]; camStrcpy(Buffer, (TCHAR*)Comment); // vars to keep track of where we are INT32 Src = 0; INT32 Dest = 0; // Loop through the string they have entered and split it up into lines of text while (Src100)) { // deal with it being the CR. if ((Buffer[Src]=='\n') || (Buffer[Src]=='\r')) { OneLine[Dest] = '^'; Dest++; } // Skim till we find something that is not a CR while ((Buffer[Src]=='\n') || (Buffer[Src]=='\r')) Src++; // Output the line if (Dest>0) { OneLine[Dest] = 0; pDC->OutputToken(_T("%%+c")); pDC->OutputToken(OneLine); pDC->OutputNewLine(); Dest = 0; } } // Lets have this char OneLine[Dest] = Buffer[Src]; Dest++; Src++; } // Output the last line if (Dest>0) { OneLine[Dest] = 0; pDC->OutputToken(_T("%%+c")); pDC->OutputToken(OneLine); pDC->OutputNewLine(); Dest = 0; } #endif return TRUE; } /******************************************************************************************** > BOOL Document::ExportRulerState(EPSExportDC *pDC) Author: Chris_Snook (Xara Group Ltd) Created: 21/3/95 Inputs: pDC - The DC to render to Returns: TRUE Purpose: Exports the View Settings continuation comment (part of the Document Info comment). It has the following form %%+r VersionNum(0) ScrollersVisible RulersVisible ********************************************************************************************/ BOOL Document::ExportRulerState(EPSExportDC *pDC) { // A buffer // Find the view to get the info from // don't do DocView* pView = DocView::GetSelected(); as it breaks save all DocView* pView = GetFirstDocView(); if (this==Document::GetSelected()) pView = DocView::GetSelected(); if (pView!=NULL) { INT32 Version =0; // Export it pDC->OutputToken(_T("%%+r")); // buffer the version number,ruler and scroller state TCHAR Buffer[256]; camSprintf(Buffer, _T("%d %ld %ld"), Version, pView->AreScrollersVisible(),pView->AreRulersVisible()); pDC->OutputToken(Buffer); pDC->OutputNewLine(); } return TRUE; } /******************************************************************************************** > BOOL Document::ExportViewInfo(EPSExportDC *pDC) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: pDC - The DC to render to Returns: TRUE Purpose: Exports the View Settings continuation comment (part of the Document Info comment). It has the following form %%+v VersionNum(1) XScrollOffset YScrollOffset ScaleFactor Active DrawingScale RealScale. ScaleFactor is represented 1000 times the actual scale factor. eg when the document is viewed at 100% the scale factor is 1.0. This is export as 1000. 200% would be 2000 etc. Active is a flag to say if the Document Scale Factor is active or not. It is followed by the Drawing and Real scales in the document ********************************************************************************************/ BOOL Document::ExportViewInfo(EPSExportDC *pDC) { // A buffer TCHAR Buffer[256]; // Find the view to get the info from // don't do DocView* pView = DocView::GetSelected(); as it breaks save all DocView* pView = GetFirstDocView(); if (this==Document::GetSelected()) pView = DocView::GetSelected(); if (pView!=NULL) { // Find out the Scroll Offsets and the Scale Factor WorkCoord ScrollOffsets = pView->GetScrollOffsets(); INT32 XOffset = ScrollOffsets.x; INT32 YOffset = ScrollOffsets.y; double ScaleFactor = pView->GetViewScale().MakeDouble(); INT32 Version = 1; // Find the spread that we are saving // Find the first spread to get the page info from // Don't use the selected spread as it breaks save all // do don't do Spread* pSpread = GetSelectedSpread(); Node *pANode = GetFirstNode()->FindNext()->FindFirstChild(); while ((pANode != NULL) && (!pANode->IsKindOf(CC_RUNTIME_CLASS(Chapter)))) pANode = pANode->FindNext(); ERROR2IF(!pANode->IsKindOf(CC_RUNTIME_CLASS(Chapter)), FALSE, "Document::Export(something)(): Could not find Chapter"); Chapter *pChapter = (Chapter *) pANode; // pSpread is a child of pChapter Spread *pSpread = (Spread *) pChapter->FindFirstChild(); ERROR2IF(!pSpread->IsKindOf(CC_RUNTIME_CLASS(Spread)), FALSE, "Document::Export(something)(): Could not find Spread"); if (pSpread != NULL) { DimScale* pDimScale = pSpread->GetPtrDimScale(); if (pDimScale != NULL) { // Find out if it is active BOOL Active = pDimScale->IsActive(); // Find out about the scale factor strings String_32 DrawingScale = pDimScale->GetDrawingScaleStr(); String_32 RealScale = pDimScale->GetRealScaleStr(); // Build the comment for the scroll offsets etc camSprintf(Buffer, _T("%d %d %d %d %d"), Version, XOffset, YOffset, (INT32)(ScaleFactor*1000), Active); // Export it pDC->OutputToken(_T("%%+v")); pDC->OutputToken(Buffer); pDC->OutputString(DrawingScale); pDC->OutputString(RealScale); pDC->OutputNewLine(); } } } return TRUE; } /******************************************************************************************** > BOOL Document::ExportStateInfo(EPSExportDC *pDC) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: pDC - The DC to render to Returns: TRUE Purpose: Part of the Document Info comment. This is document state information It takes the following form :- %%+s VersionNum Version 0 comment lines follows this with ShowGrid SnapToGrid SnapToMagObjects SnapToObjects ForeBackMode (and zero as a dummy value, see comments in the function). Each of the values is a flag and will hold either 0 for FALSE or 1 for TRUE ********************************************************************************************/ BOOL Document::ExportStateInfo(EPSExportDC *pDC) { // A buffer TCHAR Buffer[512]; // Find the view to get the info from // don't do DocView* pView = DocView::GetSelected(); as it breaks save all DocView* pView = GetFirstDocView(); if (this==Document::GetSelected()) pView = DocView::GetSelected(); if (pView!=NULL) { INT32 Version = 1; // Find all the State flags for version 0 BOOL ShowGrid = pView->GetShowGridState(); BOOL SnapToGrid = pView->GetSnapToGridState(); BOOL SnapToMagObjects = pView->GetSnapToMagObjectsState(); BOOL SnapToObjects = pView->GetSnapToObjectsState(); BOOL ForeBackMode = pView->GetForeBackMode(); // Find all the State flags for version 1 BOOL ShowGuides = pView->GetShowGuidesState(); BOOL SnapToGuides = pView->GetSnapToGuidesState(); BOOL Multilayer = IsMultilayer(); BOOL AllLayersVisible = IsAllVisible(); // Init the buffer with the version numbet camSprintf(Buffer,_T("%d "),Version); // Build the comment string switch (Version) { case 1: // Write verison 1 flags (*Note* the space after the last '%d' - this is important) camSprintf( Buffer + camStrlen( Buffer ), _T("%d %d %d %d "), ShowGuides, SnapToGuides, Multilayer, AllLayersVisible); // Fall through for version 0 flags case 0: // Note: There was a bug here - the format string had six %ds but // only five parameters. There were only supposed to be five parameters // so the sixth %d was a typo, not noticed by the compiler (or anyone // who looked at the output and should have wondered what that random // number was at the end of the line. // In order to reduce the possibility of bugs, I'm instituting a dummy // sixth parameter, and altering the code that reads it in. camSprintf( Buffer + camStrlen( Buffer ), _T("%d %d %d %d %d %d"), ShowGrid, SnapToGrid, SnapToMagObjects, SnapToObjects, ForeBackMode, 0); break; // Stop here. Version 0 was the first default: ERROR3_PF(("Dont know how to write this version for the state flags %d",Version)); break; } // Export it pDC->OutputToken(_T("%%+s")); pDC->OutputToken(Buffer); pDC->OutputNewLine(); } return TRUE; } /******************************************************************************************** > BOOL Document::ExportQualityInfo(EPSExportDC *pDC) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: pDC - The DC to render to Returns: TRUE Purpose: Part of the Document Info comment. It takes the following form :- %%+q VersionNum(0) ViewQuality. ViewQuality is the numerical value of the view Quality SeeAlso: Quality ********************************************************************************************/ BOOL Document::ExportQualityInfo(EPSExportDC *pDC) { // A buffer TCHAR Buffer[256]; // Find the view to get the info from // don't do DocView* pView = DocView::GetSelected(); as it breaks save all DocView* pView = GetFirstDocView(); if (this==Document::GetSelected()) pView = DocView::GetSelected(); if (pView!=NULL) { // Find out what the View Quality is... INT32 ViewQuality = pView->RenderQuality.GetQuality(); INT32 Version = 0; // Build the Comment camSprintf(Buffer, _T("%d %d"), Version, ViewQuality); // Export it pDC->OutputToken(_T("%%+q")); pDC->OutputToken(Buffer); pDC->OutputNewLine(); } return TRUE; } /******************************************************************************************** > BOOL Document::ExportGridInfo(EPSExportDC *pDC) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: pDC - The DC to render to Returns: - Purpose: ********************************************************************************************/ BOOL Document::ExportGridInfo(EPSExportDC *pDC) { // A buffer TCHAR Buffer[256]; // Start off from the default spread // Find the first spread to get the page info from // Don't use the selected spread as it breaks save all // do don't do Spread* pSpread = GetSelectedSpread(); Node *pANode = GetFirstNode()->FindNext()->FindFirstChild(); while ((pANode != NULL) && (!pANode->IsKindOf(CC_RUNTIME_CLASS(Chapter)))) pANode = pANode->FindNext(); ERROR2IF(!pANode->IsKindOf(CC_RUNTIME_CLASS(Chapter)), FALSE, "Document::Export(something)(): Could not find Chapter"); Chapter *pChapter = (Chapter *) pANode; // pSpread is a child of pChapter Spread *pSpread = (Spread *) pChapter->FindFirstChild(); ERROR2IF(!pSpread->IsKindOf(CC_RUNTIME_CLASS(Spread)), FALSE, "Document::Export(something)(): Could not find Spread"); if (pSpread!=NULL) { // Find the first child of the spread Node* pNode = pSpread->FindFirstChild(); while (pNode!=NULL) { // For each of the child nodes of the spread, we will check to see if it is a Node Grid if (pNode->IS_KIND_OF(NodeGrid)) { // Get the Node Grid NodeGrid* pGrid = (NodeGrid*) pNode; // Only do this if this is the default Grid. // That means that it is the full size grid that is toggled // from the Show grid thing. if (pGrid->IsDefault()) { // This version of the grid saving info is zero INT32 Version = 0; // Go and get the numbers out of the grid // BODGE - old builds (hence docs) save the grid spacing in divisions and units but don't // account for unit scaling, so as not to change doc format new docs do the same so we must // read the grid 'Divisions' with scaling turned off - yuk! BOOL Scale=FALSE; double Divisions = pGrid->GetDivisions(Scale); UnitType Unit = pGrid->GetUnits(Scale); UINT32 SubDivisions = pGrid->GetSubdivisions(); GridType TypeOfGrid = pGrid->GetGridType(); // Build the Comment camSprintf(Buffer, _T("%d %f %d %d %d"), Version, Divisions, SubDivisions, (INT32)Unit, (INT32)TypeOfGrid); // Export it pDC->OutputToken(_T("%%+g")); pDC->OutputToken(Buffer); pDC->OutputNewLine(); // once we have found a grid and saved it, then we want to stop. // This version only saves the default grid. return TRUE; } } // Oh well, that node was not a grid, so lets see if the next one is pNode = pNode->FindNext(); } } // Did not save a grid... return FALSE; } /******************************************************************************************** > BOOL Document::ExportOriginInfo(EPSExportDC *pDC) Author: Ed_Cornes (Xara Group Ltd) Created: 11/10/95 Inputs: pDC - The DC to render to Returns: FALSE if fails Purpose: Export grid/user origin Note: Should be exported after grid and page info as when importing, these both reset the origin to the origin of the page ********************************************************************************************/ BOOL Document::ExportOriginInfo(EPSExportDC *pDC) { // find the first (and currently) only spread PORTNOTE("spread", "Multi-spread warning!") Spread* pSpread = FindFirstSpread(); ERROR2IF(pSpread==NULL,FALSE,"Document::ExportOriginInfo() - could not find spread"); NodeGrid* pDefaultGrid = pSpread->FindFirstDefaultGridInSpread(); ERROR2IF(pDefaultGrid==NULL,FALSE,"Document::ExportOriginInfo() - could not find default grid"); // read the grid (user) origin DocCoord Origin(0,0); pDefaultGrid->GetOrigin(&Origin.x, &Origin.y); // Build the Comment TCHAR Buffer[256]; // a buffer INT32 Version = 0; camSprintf(Buffer, _T("%d %d %d"), Version, Origin.x, Origin.y); // Export it pDC->OutputToken(_T("%%+o")); pDC->OutputToken(Buffer); pDC->OutputNewLine(); return TRUE; } /******************************************************************************************** > BOOL Document::ExportFlagInfo(EPSExportDC *pDC) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: pDC - The DC to render to Returns: - Purpose: ********************************************************************************************/ BOOL Document::ExportFlagInfo(EPSExportDC *pDC) { return TRUE; } /******************************************************************************************** > BOOL Document::ExportUnitInfo(EPSExportDC *pDC) Author: Rik_Heywood (Xara Group Ltd) Created: 28/3/95 Inputs: pDC - The DC to export the Units to Returns: TRUE Purpose: Saves out all the user defined units. These are saved in version 0 comments lines, 1 unit per line. The default units being used for page and fonts are exported in:- SeeAlso: ExportDefaultUnitsInfo; ********************************************************************************************/ BOOL Document::ExportUnitInfo(EPSExportDC *pDC) { #if !defined(EXCLUDE_FROM_RALPH) // A buffer #define EUI_BUFFER_SIZE 256 TCHAR Buffer[EUI_BUFFER_SIZE]; // If there is no valid DocUnit list in this document then give up if (pDocUnitList==NULL) return FALSE; // Find the first relevant unit in the list Unit* pUnit = (Unit*)pDocUnitList->GetHead(); while (pUnit!=NULL) { // HACK: Export pixel units for compatibiility with old camelot. // Really need version control // Although somewhat crypticly coded this is handled as PIXELS has a NOTYPE base unit if (pUnit->IsDefault() && (pUnit->GetUnitType() != PIXELS)) { // Find the next unit in the list pUnit = (Unit*)pDocUnitList->GetNext(pUnit); continue; } // OK, we have a unit, so save out its info // Extract the values INT32 Version = 0; MILLIPOINT Size = (MILLIPOINT) pUnit->GetMillipoints(); UnitType BaseUnit = pUnit->GetBaseUnitType(); double Numerator; double Denominator; // default units can have NOTYPE so supply sensible values if (BaseUnit == NOTYPE) { BaseUnit = MILLIPOINTS; // complains in previous camelots if NOTYPE used... Numerator = 0.0; // set gibberish numerator so can be picked up in import Denominator = 1.2; // use this for version number in which units first appeared } else { Numerator = pUnit->GetBaseNumerator(); ERROR3IF(Numerator == 0.0, "Document::ExportUnitInfo() - Numerator == 0.0"); Denominator = pUnit->GetBaseDenominator(); } BOOL IsPrefix = pUnit->IsPrefix(); String_32 UnitToken = pUnit->GetToken(); String_32 UnitName = pUnit->GetSpecifier(); // Build the Comment INT32 nBytes = camSnprintf(Buffer, EUI_BUFFER_SIZE, _T("%d %ld %d %f %f %d"), Version, Size, (INT32)BaseUnit, Numerator, Denominator, IsPrefix); if (nBytes > EUI_BUFFER_SIZE - 1) { ERROR3("Document::ExportUnitInfo - nBytes > EUI_BUFFER_SIZE - 1"); return FALSE; } // Export it pDC->OutputToken(_T("%%+u")); pDC->OutputToken(Buffer); pDC->OutputString(UnitToken); pDC->OutputString(UnitName); pDC->OutputNewLine(); // Find the next unit in the list pUnit = (Unit*)pDocUnitList->GetNext(pUnit); } #endif return TRUE; } /******************************************************************************************** > BOOL Document::ExportDefaultUnitsInfo(EPSExportDC *pDC) Author: Neville_Humphrys (Xara Group Ltd) Created: 4/9/95 Inputs: pDC - The DC to export the Units to Returns: TRUE Purpose: Saves out the user default units for displaying things like page units and font units to the user. These are saved in version 0 comments lines followed by a string for the page units and a string for the font units. Must come after the user units section as the default might be one of these user units. The usert unit definitions are exported in:- SeeAlso: ExportUnitInfo; ********************************************************************************************/ BOOL Document::ExportDefaultUnitsInfo(EPSExportDC *pDC) { #if !defined(EXCLUDE_FROM_RALPH) // If there is no valid DocUnit list in this document then give up if (pDocUnitList != NULL) { // A buffer TCHAR Buffer[256]; // Now output the default units being used for page and fonts // We will save all this out as version 1 information, this is deemed to be all // the standard units info // Cannot use the units field as on earlier versions of Studio, before 1.00b, // it will be imported as a new user unit with the default settings. INT32 Version = 0; // Get the current default settings UnitType PageUnits = pDocUnitList->GetPageUnits(); // The units used to display page measurements UnitType FontUnits = pDocUnitList->GetFontUnits(); // The units to display font measurements // Find out the full names for these units String_32 PageUnitToken = pDocUnitList->GetToken(PageUnits); String_32 FontUnitToken = pDocUnitList->GetToken(FontUnits); // Build the Comment camSnprintf(Buffer, 256, _T("%d"), Version); // Export the font and pages units as a line of info pDC->OutputToken(_T("%%+U")); pDC->OutputToken(Buffer); pDC->OutputString(PageUnitToken); pDC->OutputString(FontUnitToken); pDC->OutputNewLine(); } #endif return TRUE; } /******************************************************************************************** > BOOL Document::ExportDateInfo(EPSExportDC *pDC) Author: Rik_Heywood (Xara Group Ltd) Created: 28/3/95 Inputs: pDC - the dc to export to Returns: TRUE Purpose: exports a continuation comment that holds the Last Saved Date and the Creation Date. It takes the follwoing form :- %%+d Version(0) CreationDate LastSavedDate ********************************************************************************************/ BOOL Document::ExportDateInfo(EPSExportDC *pDC) { // A buffer TCHAR Buffer[256]; // Set the last saved date to now SetLastSaveTime(); // Find out what they are time_t Creation = GetCreationTime(); time_t LastSaved = GetLastSaveTime(); // Make a string out of them camSprintf(Buffer, _T("%d %ld %ld"), 0, Creation, LastSaved); // Export them pDC->OutputToken(_T("%%+d")); pDC->OutputToken(Buffer); pDC->OutputNewLine(); return TRUE; } /******************************************************************************************** > BOOL Document::ExportTextSetup(EPSFilter* pFilter) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pFilter - the EPS filter that is being used to export a file. Returns: TRUE if the text setup for this document was written out successfully; FALSE if not (e.g. out of disk space etc) Purpose: ********************************************************************************************/ BOOL Document::ExportTextSetup(EPSFilter* pFilter) { if ( (pFilter->IS_KIND_OF(CamelotNativeEPSFilter)) || (pFilter->IS_KIND_OF(AIEPSFilter)) ) { // Output the colour table in ArtWorks format. EPSExportDC *pDC = pFilter->GetExportDC(); String_64 FontName; String_64 EFont; INT32 Style; FontList CurFontList; if (!CurFontList.Build(this)) return FALSE; FontListItem* pItem = CurFontList.GetFirstItem(); while (pItem) { FontName = pItem->GetFontName(); Style = pItem->GetFontStyle(); // Graeme (31-3-00) - Map the encoded name onto the PS font name. FONTMANAGER->EncodeAndMapFontName(FontName, EFont, Style); // The Page List comment: pDC->OutputToken(_T("%%IncludeFont:")); pDC->OutputToken((TCHAR*)EFont); pDC->OutputNewLine(); pItem = CurFontList.GetNextItem(pItem); } } return TRUE; } /******************************************************************************************** > BOOL Document::ExportTextTrailer(EPSFilter* pFilter) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pFilter - the EPS filter that is being used to export a file. Returns: TRUE if the text trailer for this document was written out successfully; FALSE if not (e.g. out of disk space etc) Purpose: ********************************************************************************************/ BOOL Document::ExportTextTrailer(EPSFilter* pFilter) { return TRUE; } /******************************************************************************************** > BOOL Document::ExportUndoInfo(EPSExportDC *pDC) Author: Simon_Maneggio (Xara Group Ltd) Created: 06/07/95 Inputs: pDC - The DC to render to Returns: TRUE Purpose: Exports a Document Info continuation comment that describes the document's OperationHistory size. It takes the following form :- %%+h VersionNum if VersionNum is zero then the following will be on the rest of the line Size(bytes) ********************************************************************************************/ BOOL Document::ExportUndoInfo(EPSExportDC *pDC) { // Find the size of the operation history UINT32 Size = GetOpHistory().GetMaxSize(); // get something to put the operation history size info into TCHAR Buffer[256]; INT32 Version = 0; // Build a string with all the data in it camSprintf(Buffer, _T("%d %lu"), Version, Size); // Output the line to the file pDC->OutputToken(_T("%%+h")); pDC->OutputToken(Buffer); pDC->OutputNewLine(); return TRUE; } /******************************************************************************************** > BOOL Document::AIExportResources(EPSExportDC *pDC, BOOL first) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pDC - the dc to export to Returns: TRUE Purpose: Export an Illustrator standard needed resources ********************************************************************************************/ BOOL Document::AIExportResources(EPSExportDC *pDC, BOOL first) { if (!first) pDC->OutputToken(_T("%%+")); // Graeme (28-3-00) - I've updated these to bring them in line with the procset // definitions from Fireworks 3 and CorelDraw 9. These have upgraded the file // to AI version 7.0, and should hopefully offer gradient fill support. pDC->OutputToken ( _T("procset Adobe_level2_AI5 1.2 0 ") ); pDC->OutputNewLine (); pDC->OutputToken ( _T("%%+ procset Adobe_packedarray 2.0 0") ); pDC->OutputNewLine (); pDC->OutputToken ( _T("%%+ procset Adobe_ColorImage_AI6 1.1 0") ); pDC->OutputNewLine (); pDC->OutputToken ( _T("%%+ procset Adobe_cshow 2.0 8") ); pDC->OutputNewLine (); pDC->OutputToken ( _T("%%+ procset Adobe_cmykcolor 1.1 0") ); pDC->OutputNewLine (); pDC->OutputToken ( _T("%%+ procset Adobe_customcolor 1.0 0") ); pDC->OutputNewLine (); pDC->OutputToken ( _T("%%+ procset Adobe_typography_AI5 1.0 1") ); pDC->OutputNewLine (); pDC->OutputToken ( _T("%%+ procset Adobe_pattern_AI3 1.0 1") ); pDC->OutputNewLine (); pDC->OutputToken ( _T("%%+ procset Adobe_Illustrator_AI5 1.2 0") ); pDC->OutputNewLine (); return TRUE; } /******************************************************************************************** > BOOL Document::AIExportProlog(EPSExportDC *pDC) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pDC - the dc to export to Returns: TRUE Purpose: Export an Illustrator standard prolog ********************************************************************************************/ BOOL Document::AIExportProlog(EPSExportDC *pDC) { pDC->OutputToken(_T("%%IncludeResource: procset Adobe_level2_AI5 1.2 0")); pDC->OutputNewLine(); pDC->OutputToken(_T("%%IncludeResource: procset Adobe_packedarray 2.0 0")); pDC->OutputNewLine(); pDC->OutputToken(_T("%%IncludeResource: procset Adobe_ColorImage_AI6 1.1 0")); pDC->OutputNewLine(); pDC->OutputToken(_T("%%IncludeResource: procset Adobe_cshow 2.0 8")); pDC->OutputNewLine(); pDC->OutputToken(_T("%%IncludeResource: procset Adobe_cmykcolor 1.1 0")); pDC->OutputNewLine(); pDC->OutputToken(_T("%%IncludeResource: procset Adobe_customcolor 1.0 0")); pDC->OutputNewLine(); pDC->OutputToken(_T("%%IncludeResource: procset Adobe_typography_AI5 1.1 0")); pDC->OutputNewLine(); pDC->OutputToken(_T("%%IncludeResource: procset Adobe_pattern_AI3 1.0 1")); pDC->OutputNewLine(); pDC->OutputToken(_T("%%IncludeResource: procset Adobe_Illustrator_AI5 1.2 0")); pDC->OutputNewLine(); return TRUE; } /******************************************************************************************** > BOOL Document::AIExportCharEncoding(EPSExportDC *pDC) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pDC - the dc to export to Returns: TRUE Purpose: Export an Illustrator compatible character encoding vector but only in EPS format. ********************************************************************************************/ BOOL Document::AIExportCharEncoding(EPSExportDC *pDC) { // Temporarily output an inline encoding. This should really be read from a file. pDC->OutputToken(_T("[")); pDC->OutputNewLine(); pDC->OutputToken(_T("39/quotesingle 96/grave 128/Adieresis/Aring/Ccedilla/Eacute/Ntilde/Odieresis")); pDC->OutputNewLine(); pDC->OutputToken(_T("/Udieresis/aacute/agrave/acircumflex/adieresis/atilde/aring/ccedilla/eacute")); pDC->OutputNewLine(); pDC->OutputToken(_T("/egrave/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis/ntilde")); pDC->OutputNewLine(); pDC->OutputToken(_T("/oacute/ograve/ocircumflex/odieresis/otilde/uacute/ugrave/ucircumflex")); pDC->OutputNewLine(); pDC->OutputToken(_T("/udieresis/dagger/degree/cent/sterling/section/bullet/paragraph/germandbls")); pDC->OutputNewLine(); pDC->OutputToken(_T("/registered/copyright/trademark/acute/dieresis/.notdef/AE/Oslash")); pDC->OutputNewLine(); pDC->OutputToken(_T("/.notdef/plusminus/.notdef/.notdef/yen/mu/.notdef/.notdef")); pDC->OutputNewLine(); pDC->OutputToken(_T("/.notdef/.notdef/.notdef/ordfeminine/ordmasculine/.notdef/ae/oslash")); pDC->OutputNewLine(); pDC->OutputToken(_T("/questiondown/exclamdown/logicalnot/.notdef/florin/.notdef/.notdef")); pDC->OutputNewLine(); pDC->OutputToken(_T("/guillemotleft/guillemotright/ellipsis/.notdef/Agrave/Atilde/Otilde/OE/oe")); pDC->OutputNewLine(); pDC->OutputToken(_T("/endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright/divide")); pDC->OutputNewLine(); pDC->OutputToken(_T("/.notdef/ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright")); pDC->OutputNewLine(); pDC->OutputToken(_T("/fi/fl/daggerdbl/periodcentered/quotesinglbase/quotedblbase/perthousand")); pDC->OutputNewLine(); pDC->OutputToken(_T("/Acircumflex/Ecircumflex/Aacute/Edieresis/Egrave/Iacute/Icircumflex")); pDC->OutputNewLine(); pDC->OutputToken(_T("/Idieresis/Igrave/Oacute/Ocircumflex/.notdef/Ograve/Uacute/Ucircumflex")); pDC->OutputNewLine(); pDC->OutputToken(_T("/Ugrave/dotlessi/circumflex/tilde/macron/breve/dotaccent/ring/cedilla")); pDC->OutputNewLine(); pDC->OutputToken(_T("/hungarumlaut/ogonek/caron")); pDC->OutputNewLine(); pDC->OutputToken(_T("TE")); pDC->OutputNewLine(); return TRUE; } /******************************************************************************************** > BOOL Document::AIExportFontEncoding(EPSExportDC *pDC) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pDC - the dc to export to Returns: TRUE Purpose: Export an Illustrator compatible font encodings but only in EPS format. ********************************************************************************************/ BOOL Document::AIExportFontEncoding(EPSExportDC *pDC) { #if !defined(EXCLUDE_FROM_RALPH) // need to enumerate all fonts for this encodeing String_64 FName; INT32 Style; FontList CurFontList; if (!CurFontList.Build(this)) return FALSE; FontListItem* pItem = CurFontList.GetFirstItem(); while (pItem) { FName = pItem->GetFontName(); Style = pItem->GetFontStyle(); AIExportFontEncoding(pDC,FName,Style); pItem = CurFontList.GetNextItem(pItem); } #endif return TRUE; } /******************************************************************************************** > BOOL Document::AIExportFontEncoding(EPSExportDC *pDC, String_64& FontName, INT32 Style) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pDC - the dc to export to FontName - a reference to a font name Style - a font style b0 = 1 bold b1 = 1 italic Returns: TRUE Purpose: Export an Illustrator compatible font encoding but only in EPS format. ********************************************************************************************/ BOOL Document::AIExportFontEncoding(EPSExportDC *pDC, String_64& FontName, INT32 Style) { String_64 EFont; // Graeme (31-3-00) - Map the encoded name onto the PS font name. FONTMANAGER->EncodeAndMapFontName(FontName, EFont, Style); String_256 Line(_T("%AI3_BeginEncoding: _")); Line+=(TCHAR*)EFont; Line+=_T(" "); Line+=(TCHAR*)EFont; pDC->OutputToken((TCHAR*)Line); pDC->OutputNewLine(); Line=_T("[/_"); Line+=(TCHAR*)EFont; Line+=_T("/"); Line+=(TCHAR*)EFont; Line+=_T(" 0 0 1 TZ"); pDC->OutputToken((TCHAR*)Line); pDC->OutputNewLine(); Line=_T("%AI3_EndEncoding"); pDC->OutputToken((TCHAR*)Line); pDC->OutputNewLine(); return TRUE; } /******************************************************************************************** > BOOL Document::AIExportExtras(EPSExportDC *pDC) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pDC - the dc to export to Returns: TRUE Purpose: Export an Illustrator compatible trailer ********************************************************************************************/ BOOL Document::AIExportExtras(EPSExportDC *pDC) { pDC->OutputToken(_T("Adobe_level2_AI5 /initialize get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_packedarray /initialize get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_ColorImage_AI6 /initialize get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_cshow /initialize get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_cmykcolor /initialize get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_customcolor /initialize get exec")); pDC->OutputNewLine(); // ChrisG (31/10/00) Changed typography line to match Illustrator and CorelDraw. // This allows photoshop to import the file correctly. pDC->OutputToken(_T("Adobe_Illustrator_AI5_vars Adobe_Illustrator_AI5")); pDC->OutputToken(_T("Adobe_typography_AI5 /initialize get exec")); pDC->OutputNewLine(); // End of typography output. pDC->OutputToken(_T("Adobe_pattern_AI3 /initialize get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_Illustrator_AI5 /initialize get exec")); pDC->OutputNewLine(); return TRUE; } /******************************************************************************************** > BOOL Document::AIExportTrailer(EPSExportDC *pDC) Author: Mike_Kenny (Xara Group Ltd) Created: 20/4/95 Inputs: pDC - the dc to export to Returns: TRUE Purpose: Export an Illustrator compatible trailer ********************************************************************************************/ BOOL Document::AIExportTrailer(EPSExportDC *pDC) { pDC->OutputToken(_T("Adobe_Illustrator_AI5 /terminate get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_level2_AI5 /terminate get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_packedarray /terminate get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_ColorImage_AI6 /terminate get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_cshow /terminate get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_cmykcolor /terminate get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_customcolor /terminate get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_typography_AI5 /terminate get exec")); pDC->OutputNewLine(); pDC->OutputToken(_T("Adobe_pattern_AI3 /terminate get exec")); pDC->OutputNewLine(); return TRUE; } /******************************************************************************************** > BOOL Document::ImportPageInfo() Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Returns: TRUE if the import worked, FALSE means that there was a problem. Purpose: Tries to import the page info. This function only returns FALSE if there was an actual error in the file that needs reporting. ********************************************************************************************/ ProcessEPSResult Document::ImportPageInfo(TCHAR* Comment) { // Set the default version INT32 Version = -1; // Where in the comment to start looking from (skip over %%+p) INT32 i = 4; // Read in the version number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Descide what to do based on the version number switch (Version) { case 0 : { // Version 0 expects to find the following infomation // Width, Height, Margin, Bleed, Dps, ShowDropShadow // Get something to put all the numbers into MILLIPOINT Width, Height; MILLIPOINT Margin, Bleed; BOOL Dps, ShowDropShadow; Width = Height = 0; // Read in the Width of the page if (!ReadNextNumber(&Width, Comment, &i)) return EPSCommentSyntaxError; // Read in the Height of the page if (!ReadNextNumber(&Height, Comment, &i)) return EPSCommentSyntaxError; // Read in the Margin of the page if (!ReadNextNumber(&Margin, Comment, &i)) return EPSCommentSyntaxError; // Read in the Bleed of the page if (!ReadNextNumber(&Bleed, Comment, &i)) return EPSCommentSyntaxError; // Read in the DPS of the page INT32 TempNum; if (!ReadNextNumber(&TempNum, Comment, &i)) return EPSCommentSyntaxError; // Copy it to the bool Dps = (BOOL) TempNum; // Read in the Drop shadow state of the page if (!ReadNextNumber(&TempNum, Comment, &i)) return EPSCommentSyntaxError; // Copy it to the bool ShowDropShadow = (BOOL) TempNum; // Find the spread to change Spread* pSpread = GetSelectedSpread(); if (pSpread == NULL) return EPSCommentSystemError; // Ask the pages to change themselves BOOL Worked = FALSE; if ((Width>0) && (Height>0)) { Worked = pSpread->SetPageSize(Width, Height, Margin, Bleed, Dps, ShowDropShadow); } } // Unknown version default: { // Here we have got a version number we do not know how to process // so just ignore this comment happy. we will say that the comment // was OK as an error is technically wrong in this case } } // if we get here, then everything went smoothly so return Happy return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportDocumentComment(TCHAR* Comment) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: Comment - The EPS comment that we have to process Returns: ProcessEPSResult - the result of the import - see ProcessEPSComment() Purpose: ********************************************************************************************/ ProcessEPSResult Document::ImportDocumentComment(TCHAR* Comment) { // Check that this comment line ended in a CR size_t StrLength = camStrlen( Comment ); // If the string was too long, then mark it as an error if (StrLength>=254) return EPSCommentSyntaxError; // check to see if this line should have a CR in it if (Comment[StrLength-1]==_T('^')) { Comment[StrLength-1] = _T('\r'); Comment[StrLength] = _T('\n'); Comment[StrLength+1] = 0; } // append this line to the document comment String_256 DocComment( GetComment() ); String_256 NewComment( Comment + 5 ); DocComment += NewComment; // Set the comment back into the document and say that all went well SetComment(&DocComment); return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportViewInfo(TCHAR* Comment) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: Comment - The EPS comment that we have to process Returns: ProcessEPSResult - the result of the import - see ProcessEPSComment() Purpose: ********************************************************************************************/ ProcessEPSResult Document::ImportViewInfo(TCHAR* Comment) { #if !defined(EXCLUDE_FROM_RALPH) INT32 Version = -1; INT32 i = 4; // Read in the Version Number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Act on the version number switch (Version) { case 0 : case 1 : // Version 1 is the same, only it has some extra info at the end { INT32 XOffset = 0; INT32 YOffset = 0; INT32 ScaleFactor = 1000; // Read in the Version Number if (!ReadNextNumber(&XOffset, Comment, &i)) return EPSCommentSyntaxError; // Read in the Version Number if (!ReadNextNumber(&YOffset, Comment, &i)) return EPSCommentSyntaxError; // Read in the Version Number if (!ReadNextNumber(&ScaleFactor, Comment, &i)) return EPSCommentSyntaxError; // Adjust the scale factor by a factor of 1000 // go via a double to avoid getting negative scales when ScaleFactor > 32k FIXED16 RealScale = ((double)ScaleFactor) / 1000.0; // See if we have a View to change // DocView* pView = DocView::GetSelected(); DocView* pView = GetFirstDocView(); if (pView != NULL && fRestoreViewOnImport) { // Set the view for the following code. The zoom ops work on the current // view, as do the coordinate conversion functions. ERROR3IF(pView != DocView::GetCurrent(), "DocView::Current is screwed in Document::ImportViewInfo"); pView->SetCurrent(); // Change the view scale pView->SetViewScale(RealScale); // Change the scroll offsets WorkCoord TopCorner(XOffset, YOffset); pView->SetScrollOffsets(TopCorner, FALSE); // Update the button bar OpZoomComboDescriptor::Update(); } // Deal with the Version 1 bits if (Version==1) { // The params we will read in INT32 Active; String_32 DrawingScale; String_32 RealScale; // Find the DimScale to set DimScale* pDimScale = NULL; Spread* pSpread = GetSelectedSpread(); if (pSpread!=NULL) pDimScale = pSpread->GetPtrDimScale(); if (pDimScale!=NULL) { // Read in the Version Number if (!ReadNextNumber(&Active, Comment, &i)) return EPSCommentSyntaxError; // And set the active state of the scaleing pDimScale->SetActiveState(Active); // And read in the two scaling strings if (!ReadNextString(&DrawingScale, 32, Comment, &i)) return EPSCommentSyntaxError; // Set the Drawing Scale BOOL Worked = pDimScale->SetDrawingScaleStr(DrawingScale); if (!ReadNextString(&RealScale, 32, Comment, &i)) return EPSCommentSyntaxError; // Set the real scale if (Worked) Worked = pDimScale->SetRealScaleStr(RealScale); // Set the scale factor using the new strings if (Worked) pDimScale->SetScaleFactor(); // None of the the above functions report errors if there were problems // should really inform the user about the problem using _R(IDW_BADDOCUMENTSCALE) in nev.h/rc } } break; } default : { break; } } #endif return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportStateInfo(TCHAR* Comment) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: Comment - The EPS comment that we have to process Returns: ProcessEPSResult - the result of the import - see ProcessEPSComment() Purpose: Imports state information. Version 0 holds view state information such as:- grid showing and snap to grid magnetic snap to objects foregound background redraw modes. ********************************************************************************************/ ProcessEPSResult Document::ImportStateInfo(TCHAR* Comment) { #if !defined(EXCLUDE_FROM_RALPH) // The version of the state info and the read position in the string INT32 Version = -1; INT32 i = 4; // Find the first DocView (if there is one) DocView* pFirstView = GetFirstDocView(); // Read in the Version Number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Act on the version number switch (Version) { case 1 : { INT32 ShowGuides = TRUE; INT32 SnapToGuides = TRUE; INT32 Multilayer = FALSE; INT32 AllLayersVisible = FALSE; // Read the ShowGuides flag if (!ReadNextNumber(&ShowGuides, Comment, &i)) return EPSCommentSyntaxError; // Read the SnapToGuides flag if (!ReadNextNumber(&SnapToGuides, Comment, &i)) return EPSCommentSyntaxError; // Read the Multilayer flag if (!ReadNextNumber(&Multilayer, Comment, &i)) return EPSCommentSyntaxError; // Read the AllLayersVisible flag if (!ReadNextNumber(&AllLayersVisible, Comment, &i)) return EPSCommentSyntaxError; // In viewer leave these alone #ifndef STANDALONE // Now try and set the values in the view if (pFirstView != NULL) { // Set all the flags to either TRUE or FALSE pFirstView->SetShowGuidesState(ShowGuides?TRUE:FALSE); pFirstView->SetSnapToGuidesState(SnapToGuides?TRUE:FALSE); SetMultilayer(Multilayer?TRUE:FALSE); SetAllVisible(AllLayersVisible?TRUE:FALSE); } #endif } // Fall through for version 0 flags case 0 : { INT32 ShowGrid = FALSE; INT32 SnapToGrid = FALSE; INT32 SnapToMagObjects = FALSE; INT32 SnapToObjects = FALSE; INT32 ForeBackMode = FALSE; // Read the Grid visible flag if (!ReadNextNumber(&ShowGrid, Comment, &i)) return EPSCommentSyntaxError; // Snap to Grids yes/no if (!ReadNextNumber(&SnapToGrid, Comment, &i)) return EPSCommentSyntaxError; // Snap to Magnetic Objects yes/no if (!ReadNextNumber(&SnapToMagObjects, Comment, &i)) return EPSCommentSyntaxError; // Snap to Objects yes/no if (!ReadNextNumber(&SnapToObjects, Comment, &i)) return EPSCommentSyntaxError; // Background rendering yes/no if (!ReadNextNumber(&ForeBackMode, Comment, &i)) return EPSCommentSyntaxError; // Read in the dummy sixth value. This is necessary because // a printf function had too many %ds in it for the output // so the program always outputs a random value after the // rest of them. We have to skip it, just in case. // Notice that we ignore any errors - if the dummy value is not there, // who cares? INT32 dummy = 0; ReadNextNumber(&dummy, Comment, &i); // In viewer leave these alone #ifndef STANDALONE // Now try and set the values in the view if (pFirstView != NULL) { // Set all the flags to either TRUE or FALSE pFirstView->SetShowGridState(ShowGrid?TRUE:FALSE); pFirstView->SetSnapToGridState(SnapToGrid?TRUE:FALSE); pFirstView->SetSnapToMagObjectsState(SnapToMagObjects?TRUE:FALSE); pFirstView->SetSnapToObjectsState(SnapToObjects?TRUE:FALSE); pFirstView->SetForeBackMode(ForeBackMode?TRUE:FALSE); } #endif break; } // Unknown version number default: { // This is not an error, as this would stop the file from loading. // We will just ignore this little section of information break; } } #endif return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportQualityInfo(TCHAR* Comment) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: Comment - The EPS comment that we have to process Returns: ProcessEPSResult - the result of the import - see ProcessEPSComment() Purpose: ********************************************************************************************/ ProcessEPSResult Document::ImportQualityInfo(TCHAR* Comment) { #if !defined(EXCLUDE_FROM_RALPH) // The version of the state info and the read position in the string INT32 Version = -1; INT32 i = 4; // Read in the Version Number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Act on the version number switch (Version) { case 0 : { // The View Quality - default to something sensible INT32 ViewQuality = 100; // Read in the Version Number if (!ReadNextNumber(&ViewQuality, Comment, &i)) return EPSCommentSyntaxError; // OK, we got the view quality ok, so try and set it // DocView* pView = DocView::GetSelected(); DocView* pView = GetFirstDocView(); if (pView!=NULL) { // Actually set the quality in the view /*BOOL Worked = */pView->RenderQuality.SetQuality((INT32)ViewQuality); } break; } default: { break; } } #endif return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportGridInfo(TCHAR* Comment) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: Comment - The EPS comment that we have to process Returns: ProcessEPSResult - the result of the import - see ProcessEPSComment() Purpose: Imports the global grid that covers the whole spread ********************************************************************************************/ ProcessEPSResult Document::ImportGridInfo(TCHAR* Comment) { #if !defined(EXCLUDE_FROM_RALPH) // The version of the state info and the read position in the string INT32 Version = -1; INT32 i = 4; // Read in the Version Number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Act on the version number switch (Version) { case 0 : { double Divisions; INT32 SubDiv, Units, Type; UINT32 SubDivisions; UnitType Unit; GridType TypeOfGrid; // Read in the Divisions if (!ReadNextNumber(&Divisions, Comment, &i)) return EPSCommentSyntaxError; // read in the sub-divisions if (!ReadNextNumber(&SubDiv, Comment, &i)) return EPSCommentSyntaxError; // Read in the unit if (!ReadNextNumber(&Units, Comment, &i)) return EPSCommentSyntaxError; // Read in the type of grid if (!ReadNextNumber(&Type, Comment, &i)) return EPSCommentSyntaxError; // Put everything into the correct types SubDivisions = (UINT32)SubDiv; Unit = (UnitType)Units; TypeOfGrid = (GridType) Type; // Get rid of the old grid, if there was one // and find out where the page corner is, so that the origin of the grid can be set BOOL FoundPage = FALSE; DocCoord Corner(0,0); Spread* pSpread = GetSelectedSpread(); if (pSpread!=NULL) { // Find the first child of the spread Node* pNode = pSpread->FindFirstChild(); while (pNode!=NULL) { // Go find the next node now Node* pNext = pNode->FindNext(); // For each of the child nodes of the spread, we will check to see if it is a Node Grid if (pNode->IS_KIND_OF(NodeGrid)) { // This is a grid all right, so toast it pNode->CascadeDelete(); delete pNode; } // see if it is a page if ((!FoundPage) && (pNode->IS_KIND_OF(Page))) { // We have found one, so stop looking FoundPage = TRUE; // Find out the coord of the bottom corner DocRect PageRect = ((Page*)pNode)->GetPageRect(); Corner = PageRect.LowCorner(); } // Find the next node pNode = pNext; } // Set all the global variables - What a load of B******** NodeGrid::SetDefaultDivisions(Divisions); NodeGrid::SetDefaultSubdivisions(SubDivisions); NodeGrid::SetDefaultUnits(Unit); NodeGrid::SetDefaultGridType(TypeOfGrid); // Make a grid // BODGE - old builds (hence docs) save the grid spacing in divisions and units but don't // account for unit scaling, so as not to change doc format new docs do the same so we must // set the grid with scaling turned off - yuk! BOOL Scale=FALSE; NodeGrid::MakeDefaultGrid(pSpread, Scale); // Set the origin to 0,0 for now if (FoundPage) { // Find the first child of the spread Node* pNode = pSpread->FindFirstChild(); while (pNode!=NULL) { // For each of the child nodes of the spread, we will check to see if it is a Node Grid if (pNode->IS_KIND_OF(NodeGrid)) // This is a grid all right, so Set its origin ((NodeGrid*)pNode)->SetOrigin(Corner.x, Corner.y); // Find the next node pNode = pNode->FindNext(); } } } break; } default: { break; } } #endif return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportOriginInfo(TCHAR* Comment) Author: Ed_Cornes (Xara Group Ltd) Created: 11/10/95 Inputs: Comment - The EPS comment that we have to process Returns: ProcessEPSResult - the result of the import Purpose: Imports the spread grid/user origin Note: The origin should already have been set up to the page origin when importing the grid (ie already has a sensible default if the origin import fails) Also since the origin does not affect the look of the doc, if possible don't abort importing if an error is encountered so the doc can be recovered ********************************************************************************************/ ProcessEPSResult Document::ImportOriginInfo(TCHAR* Comment) { #if !defined(EXCLUDE_FROM_RALPH) // find the selected spread in the doc, and it's default grid Spread* pSpread = GetSelectedSpread(); ERROR2IF(pSpread==NULL,EPSCommentOK,"Document::ImportOriginInfo() - could not find first spread in doc"); NodeGrid* pDefaultGrid = pSpread->FindFirstDefaultGridInSpread(); ERROR2IF(pDefaultGrid==NULL,EPSCommentOK,"Document::ImportOriginInfo() - could not find default grid"); // init read position in string - ie after "%%+o" INT32 i = 4; // Read in the Version Number INT32 Version = -1; if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Act on the version number switch (Version) { case 0 : { // Read in the origin DocCoord Origin(0,0); if (!ReadNextNumber(&Origin.x, Comment, &i)) return EPSCommentSyntaxError; if (!ReadNextNumber(&Origin.y, Comment, &i)) return EPSCommentSyntaxError; // set the grid (and user) origin pDefaultGrid->SetOrigin(Origin.x,Origin.y); break; } default: ERROR2(EPSCommentOK,"Document::ImportOriginInfo() - unknown origin version"); } #endif return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportRulerState(TCHAR* Comment) Author: Chris_Snook (Xara Group Ltd) Created: 21/3/95 Inputs: Comment - The EPS comment that we have to process Returns: ProcessEPSResult - the result of the import - see ProcessEPSComment() Purpose: ********************************************************************************************/ ProcessEPSResult Document::ImportRulerState(TCHAR* Comment) { #if !defined(EXCLUDE_FROM_RALPH) INT32 Version = -1; INT32 i = 4; // Read in the Version Number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; switch (Version) { case 0 : { INT32 ScrollerState =1; INT32 RulerState =0; // Read in the Version Number if (!ReadNextNumber(&ScrollerState, Comment, &i)) return EPSCommentSyntaxError; if (!ReadNextNumber(&RulerState, Comment, &i)) return EPSCommentSyntaxError; // See if we have a View to change // DocView* pView = DocView::GetSelected(); DocView* pView = GetFirstDocView(); // we use default visibility states if this is a new file // (ie. we are not opening an existing file ) // this flag is set in CCamDoc::OnNewDocument() // see also CCamDoc::OnOpenDocument() if(CCamView::GetUseVisibleDefaults()) { ScrollerState = CCamView::GetDefaultScrollersState(); RulerState = CCamView::GetDefaultRulersState(); } if (pView != NULL) { pView->ShowViewScrollers((BOOL)ScrollerState); pView->ShowViewRulers((BOOL)RulerState); } break; } default : { break; } } #endif return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportFlagInfo(TCHAR* Comment) Author: Rik_Heywood (Xara Group Ltd) Created: 21/3/95 Inputs: Comment - The EPS comment that we have to process Returns: ProcessEPSResult - the result of the import - see ProcessEPSComment() Purpose: ********************************************************************************************/ ProcessEPSResult Document::ImportFlagInfo(TCHAR* Comment) { return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportUnitInfo(TCHAR* Comment) Author: Rik_Heywood (Xara Group Ltd) Created: 28/3/95 Inputs: Comment - The comment line to process Returns: EPSCommentSyntaxError if there was a systax error in the comment EPSCommentOK if the comment was processed ok Purpose: Imports a continuation comment with details about a user defined unit on it There is 1 unit per comment. This comment always creates a new user unit in version prior to Studio 1.00b, code updated to not do this 4/9/95. ********************************************************************************************/ ProcessEPSResult Document::ImportUnitInfo(TCHAR* Comment) { // If there is no valid DocUnit list in this document then give up ERROR3IF(pDocUnitList==NULL,"Document::ImportUnitInfo null pDocUnitList"); if (pDocUnitList==NULL) return EPSCommentOK; // Set up some variables. // The version of the state info and the read position in the string INT32 Version = -1; INT32 i = 4; // Read in the Version Number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Act on the version number switch (Version) { case 0 : { // We need to make a new unit // Older code had this outside the version loop so you cannot use the 'u' // comment field for other unit field without creating a new unit in older // versions e.g. viewer 1.00 and Studio 1.00b and before. // Read in values & validate them before creating the unit INT32 Size; INT32 BaseUnit; double Numerator; double Denominator; INT32 IsPrefix; String_64 TokenStr; String_64 SpecifierStr; // Read in the Millipoint size of the unit if (!ReadNextNumber(&Size, Comment, &i)) return EPSCommentSyntaxError; // Read in the base UnitType if (!ReadNextNumber(&BaseUnit, Comment, &i)) return EPSCommentSyntaxError; // Read in the unit Numerator if (!ReadNextNumber(&Numerator, Comment, &i)) return EPSCommentSyntaxError; // Read in the unit Denominator if (!ReadNextNumber(&Denominator, Comment, &i)) return EPSCommentSyntaxError; // Read in whether the unit specifier is prefixed (0 == FALSE) if (!ReadNextNumber(&IsPrefix, Comment, &i)) return EPSCommentSyntaxError; // Finally read in the string values if (!ReadNextString(&TokenStr, 32, Comment, &i)) return EPSCommentSyntaxError; // Read in the specifier string if (!ReadNextString(&SpecifierStr, 32, Comment, &i)) return EPSCommentSyntaxError; // Throw away units that have been exported for compatibility with older versions (see ExportUnitInfo()) if (Numerator == 0.0 && Denominator <= 2.0) break; Unit* pNewUnit = NULL; if (!pDocUnitList->MakeNewUnit(&pNewUnit, TRUE)) return EPSCommentSystemError; // Set the values in the units up pNewUnit->SetMillipoints((double)Size); pNewUnit->SetBaseUnitType((UnitType) BaseUnit); pNewUnit->SetBaseNumerator(Numerator); pNewUnit->SetBaseDenominator(Denominator); pNewUnit->SetPrefixState((BOOL)IsPrefix); // Set the token pNewUnit->SetToken(TokenStr); // Set the Specifier pNewUnit->SetSpecifier(SpecifierStr); break; } default: { // Do nothing with unknown versions as this means info we know nothing about. // Do not error though as this might be bad. break; } } return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportDefaultUnitsInfo(TCHAR* Comment) Author: Neville_Humphrys (Xara Group Ltd) Created: 4/9/95 Inputs: Comment - The comment line to process Returns: EPSCommentSyntaxError if there was a systax error in the comment EPSCommentOK if the comment was processed ok Purpose: Imports a continuation comment with details about the default units which are going to be used for showing page and font measurements. Cannot use units as on older version will always create a new user unit for each ++u found.. ********************************************************************************************/ ProcessEPSResult Document::ImportDefaultUnitsInfo(TCHAR* Comment) { // In viewer leave these alone as not useful #ifndef STANDALONE // If there is no valid DocUnit list in this document then give up ERROR3IF(pDocUnitList==NULL,"Document::ImportDefaultUnitsInfo null pDocUnitList"); if (pDocUnitList==NULL) return EPSCommentOK; // Set up some variables. // The version of the state info and the read position in the string INT32 Version = -1; INT32 i = 4; // Read in the Version Number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Act on the version number switch (Version) { case 0 : { // Read in the string values which define the units to use // First the page units, the units used to display page measurements String_64 PageUnitsStr; if (!ReadNextString(&PageUnitsStr, 32, Comment, &i)) return EPSCommentSyntaxError; // Then the font units, the units to display font measurements String_64 FontUnitsStr; if (!ReadNextString(&FontUnitsStr, 32, Comment, &i)) return EPSCommentSyntaxError; // Find the unit in the list, if present, otherwise will return NOTYPE UnitType PageUnits = pDocUnitList->FindUnitTypeFromToken(PageUnitsStr); UnitType FontUnits = pDocUnitList->FindUnitTypeFromToken(FontUnitsStr); // Set the new current default settings, if valid units were found if (PageUnits != NOTYPE) pDocUnitList->SetPageUnits(PageUnits); if (FontUnits!= NOTYPE) pDocUnitList->SetFontUnits(FontUnits); break; } default: { // Do nothing with unknown versions as this means info we know nothing about. // Do not error though as this might be bad. break; } } #endif return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportDateInfo(TCHAR* Comment) Author: Rik_Heywood (Xara Group Ltd) Created: 28/3/95 Inputs: Comment - The Comment that we have to process Returns: EPSCommentOK Purpose: Reads in the Last saved Date and Creation Date from the file. ********************************************************************************************/ ProcessEPSResult Document::ImportDateInfo(TCHAR* Comment) { #if !defined(EXCLUDE_FROM_RALPH) // The version of the state info and the read position in the string INT32 Version = -1; INT32 i = 4; // Read in the Version Number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Act on the version number switch (Version) { case 0 : { INT32 Creation, LastSaved; // Read in the Creation Date if (!ReadNextNumber(&Creation, Comment, &i)) return EPSCommentSyntaxError; // Read in the Last Saved Date if (!ReadNextNumber(&LastSaved, Comment, &i)) return EPSCommentSyntaxError; // Set the vars in the document CreationTime = (time_t)Creation; LastSaveTime = (time_t)LastSaved; break; } default: { break; } } #endif return EPSCommentOK; } /******************************************************************************************** > ProcessEPSResult Document::ImportUndoInfo(TCHAR* Comment) Author: Simon_Maneggio (Xara Group Ltd) Created: 06/07/95 Inputs: Comment - The Comment that we have to process Returns: EPSCommentOK Purpose: Reads in the Last saved operation history size from the file. ********************************************************************************************/ ProcessEPSResult Document::ImportUndoInfo(TCHAR* Comment) { // The version of the state info and the read position in the string INT32 Version = -1; INT32 i = 4; // Read in the Version Number if (!ReadNextNumber(&Version, Comment, &i)) return EPSCommentSyntaxError; // Act on the version number switch (Version) { case 0 : { UINT32 UndoSize; // Read the size for the operation history if (!ReadNextNumber(&UndoSize, Comment, &i)) return EPSCommentSyntaxError; // Minimum size = 1K if (UndoSize < 1024) UndoSize = 1024; // Set the size of the Operation History in // the document. GetOpHistory().SetNewMaxSize(UndoSize); break; } default: { break; } } return EPSCommentOK; } /******************************************************************************************** > BOOL Document::IsImporting() Author: Rik_Heywood (Xara Group Ltd) Created: 28/3/95 Returns: TRUE if the document is importing a file as apposed to Opening a file Purpose: Helps work out if the document is in the process of opening an existing file or if it is importing data into itself. Called during the reading of the Document Info section of the .art files. All the DocInfo section is ignored if the file is actually being imported. ********************************************************************************************/ BOOL Document::IsImporting() { return DocIsImporting; } /******************************************************************************************** > void Document::SetIsImporting(BOOL NewIsImporting) Author: Rik_Heywood (Xara Group Ltd) Created: 28/3/95 Inputs: NewIsImporting - The new state of the importing flag Purpose: Sets the IsImporting flag for the document ********************************************************************************************/ void Document::SetIsImporting(BOOL NewIsImporting) { // Set the flag to either TRUE or FALSE if (NewIsImporting) DocIsImporting = TRUE; else DocIsImporting = FALSE; } /******************************************************************************************** > BOOL Document::IsTemplateLoading() Author: Neville_Humphrys (Xara Group Ltd) Humprhys Created: 6/8/97 Returns: TRUE if the document is importing a file as apposed to Opening a file Purpose: Helps work out if the document being opened or imported is a default or template document. At present, used in Webster to check if we need to use layers or not. Template documents are allowed to have layers. Non-template docs are not. SeeAlso: ********************************************************************************************/ BOOL Document::IsTemplateLoading() { return DocTemplateLoading; } /******************************************************************************************** > void Document::SetTemplateLoading(BOOL NewTemplateLoading) Author: Neville_Humphrys (Xara Group Ltd) Humprhys Created: 6/8/97 Inputs: NewTemplateLoading - The new state of the template loading flag Purpose: Sets the TemplateLoading flag for the document ********************************************************************************************/ void Document::SetTemplateLoading(BOOL NewTemplateLoading) { // Set the flag to either TRUE or FALSE if (NewTemplateLoading) DocTemplateLoading = TRUE; else DocTemplateLoading = FALSE; } /******************************************************************************************** > static void Document::ShouldRestoreViewOnImport(BOOL fNewState) Author: Justin_Flude (Xara Group Ltd) Created: 12/10/95 Inputs: fNewState new value of the flag Purpose: Sets/clears a flag that if TRUE will ask this document to restore the view saved within the doc, if FALSE it won't bother. Normally we want the view saved in the doc to be restore, but if we are restoring the entire workspace then this is dealt with elsewhere. Errors: - SeeAlso: Document::ImportViewInfo; LoadAppWindowState ********************************************************************************************/ void Document::ShouldRestoreViewOnImport(BOOL fNewState) { fRestoreViewOnImport = fNewState; } /*********************************************************************************************** > Document::GetDocFontUnits() Author: Chris_Parks (Xara Group Ltd) Created: 6/5/95 Returns: Returns Font UnitType for this document Purpose: return Font Units for this document default to COMP_POINTS if no unit list available *************************************************************************************************/ UnitType Document::GetDocFontUnits() { if(pDocUnitList) return pDocUnitList->GetFontUnits(); else return COMP_POINTS; } /*********************************************************************************************** > BitmapList* Document::GetBitmapList() Author: Will_Cowling (Xara Group Ltd) Created: 20/8/96 Returns: Returns this document's bitmap list Purpose: Gets the bitmap list from this documents doc component *************************************************************************************************/ BitmapList* Document::GetBitmapList() { // Find this documents BitmapListComponent DocComponent* DocBitmapList = GetDocComponent(CC_RUNTIME_CLASS(BitmapListComponent)); ERROR2IF(DocBitmapList == NULL, FALSE, "Couldn't find document bitmap list"); if (DocBitmapList == NULL) return NULL; // Now get the actual bitmap list return ((BitmapListComponent*)DocBitmapList)->GetBitmapList(); } /******************************************************************************************** > BOOL Document::SetDocNudge (UINT32 newVal) Author: Chris_Snook (Xara Group Ltd) Created: 31/8/2000 Inputs: newVal - the new documents nudge size Returns: - Purpose: Sets the documents nudge size Errors: - SeeAlso: - ********************************************************************************************/ BOOL Document::SetDocNudge (UINT32 newVal) { m_docNudge = newVal; OpNudge::SetNudgeStep (m_docNudge); // I need to call this directly to get camelot to // use the new value. return (TRUE); } /*********************************************************************************************** > INT32 Document::GetNumLayers() const Author: Graham_Walmsley (Xara Group Ltd) Created: 8/7/97 Returns: - Purpose: Counts the layers in this document. This function assumes there is only one spread in the document, so it will fail if we ever implement multiple spread documents (chuckle). *************************************************************************************************/ INT32 Document::GetNumLayers() { //Find the first spread in the document PORTNOTE("spread", "Multi-spread warning!") Spread* pSpread = FindFirstSpread(); //Now find the first layer in that spread Layer* pLayer = NULL; if (pSpread != NULL) pLayer = pSpread->FindFirstLayer(); //And count the layers INT32 iCount = 0; while (pLayer != NULL) { iCount++; pLayer=pLayer->FindNextLayer(); } return iCount; } /*********************************************************************************************** > BOOL Document::IsAnimated() const Author: Graham_Walmsley (Xara Group Ltd) Created: 27/10/97 Returns: - Purpose: Finds whether this document is an animation. We assume the document is an animation if it contains one or more frame layers *************************************************************************************************/ BOOL Document::IsAnimated() { //Find the first spread in the document PORTNOTE("spread", "Multi-spread warning!") Spread* pSpread = FindFirstSpread(); //Find the first frame layer in that spread Layer * pFrame = pSpread->FindFirstFrameLayer(); //If there is one, return TRUE. Otherwise return FALSE return !(pFrame==NULL); } /*********************************************************************************************** > Progressive Rendering *************************************************************************************************/ /*********************************************************************************************** > Node* Document::GetLastSafeNodeToRender() Author: Will_Cowling (Xara Group Ltd) Created: 6/9/96 Purpose: Returns a reference to the document's 'Safe render pointer' *************************************************************************************************/ SafeRenderPointer& Document::GetSafeRenderPointer() { return TheSafeRenderPointer; } /*********************************************************************************************** > SafeRenderPointer::SafeRenderPointer() Author: Will_Cowling (Xara Group Ltd) Created: 6/9/96 Purpose: Constructs a SafeRenderPointer object *************************************************************************************************/ SafeRenderPointer::SafeRenderPointer() { m_bPointerValid = TRUE; pLastSafeNodeToRender = NULL; } /*********************************************************************************************** > SafeRenderPointer::~SafeRenderPointer() Author: Will_Cowling (Xara Group Ltd) Created: 6/9/96 Purpose: Destroys a SafeRenderPointer object *************************************************************************************************/ SafeRenderPointer::~SafeRenderPointer() { // Empty. } /*********************************************************************************************** > BOOL SafeRenderPointer::UpdateLastSafeNode(Node* pNewNode) Author: Will_Cowling (Xara Group Ltd) Created: 6/9/96 Purpose: Updates the last safe node that can be rendered *************************************************************************************************/ BOOL SafeRenderPointer::UpdateLastSafeNode(Node* pNewNode) { ERROR2IF(!m_bPointerValid, FALSE, "Trying to set safe pointer when it's invalid."); #ifdef RALPH if ((!pLastSafeNodeToRender) && pNewNode) { NodeDocument* pNodeDoc = (NodeDocument*) pNewNode->FindParent(CC_RUNTIME_CLASS(NodeDocument)); ASSERT (pNodeDoc); if (pNodeDoc) { Document* TheDoc = (Document*)pNodeDoc->GetParentDoc(); ASSERT(TheDoc); if (TheDoc) { RalphDocument* pRalphDoc = TheDoc->GetRalphDoc(); if (pRalphDoc) { RalphView * pRalphView = pRalphDoc->GetRalphView(); if(pRalphView) { /* OpZoomDescriptor::FakeZoomToRect(&(pRalphDoc->GetViewportRect())); pRalphView->SetSafeToDraw(TRUE); */ //Beep(1500,15); SendMessage(pRalphView->GetSafeHwnd(),WM_ZOOMTORECT,NULL,(INT32)(pRalphDoc->GetViewportRect())); } } } } } #endif // Make sure this pointer cannot be accessed by other threads // while we update it // CCamApp::EnterSafeRenderCriticalSection(); // TRACEUSER( "Will", _T("Thread %d is setting safe node to %x\n"), GetCurrentThreadId(), pNewNode); pLastSafeNodeToRender = pNewNode; // Ok, it's safe for other threads to access us now // CCamApp::ExitSafeRenderCriticalSection(); return TRUE; } /*********************************************************************************************** > Node* SafeRenderPointer::GetLastSafeNode() Author: Will_Cowling (Xara Group Ltd) Created: 6/9/96 Purpose: Returns a pointer to the last safe node that can be rendered *************************************************************************************************/ Node* SafeRenderPointer::GetLastSafeNode() { if (!m_bPointerValid) return NULL; Node* pSafeNode = NULL; // Make sure this pointer cannot be updated by another thread while we read it // CCamApp::EnterSafeRenderCriticalSection(); pSafeNode = pLastSafeNodeToRender; // TRACEUSER( "Will", _T("Thread %d is reading safe node as %x\n"), GetCurrentThreadId(), pSafeNode); // Ok, it's safe for other threads to update it now // CCamApp::ExitSafeRenderCriticalSection(); return pSafeNode; } /*********************************************************************************************** > void SafeRenderPointer::SetPointerValid() Author: Will_Cowling (Xara Group Ltd) Created: 6/9/96 Purpose: Sets the pointer as being valid *************************************************************************************************/ void SafeRenderPointer::SetPointerValid() { // TRACEUSER( "Will", _T("Thread %d is setting safe node ptr as VALID\n"), GetCurrentThreadId()); m_bPointerValid = TRUE; } /*********************************************************************************************** > void SafeRenderPointer::SetPointerInValid() Author: Will_Cowling (Xara Group Ltd) Created: 6/9/96 Purpose: Sets the pointer as being invalid *************************************************************************************************/ void SafeRenderPointer::SetPointerInValid() { // TRACEUSER( "Will", _T("Thread %d is setting safe node ptr as INVALID\n"), GetCurrentThreadId()); m_bPointerValid = FALSE; } /*********************************************************************************************** > BOOL SafeRenderPointer::IsPointerValid() Author: Will_Cowling (Xara Group Ltd) Created: 6/9/96 Purpose: Returns whether or not the pointer is valid *************************************************************************************************/ BOOL SafeRenderPointer::IsPointerValid() { return m_bPointerValid; }