CCamDoc Class Reference

This is the wxWidgets class for a document type object in the OIL (it was originally part of wxWidgets example app. docvwmdi). It is very simple - its main use is getting hold of the relevant Document object from the kernel layer. wxWidgets calls various member functions when processing commands from the File menu. This class calls down into the kernel to do the actual work. More...

#include <camdoc.h>

List of all members.

Public Member Functions

 CCamDoc (Document *pKernelDoc=NULL)
 Creates a CCamDoc, optionally attached to a given pKernelDoc or if pKernelDoc is null, a new Document. Notes: m_pFor Scope: protected.
 ~CCamDoc ()
 Destructor - destroys the Document associated with this OIL document.
DocumentGetKernelDoc () const
 Find the Kernel document associated with this Oil document.
virtual bool OnNewDocument ()
 Called by MFC during the processing of a File/New command. Before this is called MFC/kernel have already contructed new instances of the CCamDoc / Document classes. Calls the kernel's Document and CCamDoc's base class to do the actual work.
virtual bool OnSaveDocument (const wxString &filename)
 Saves the document to the specified path. Calls the kernel to do the actual work.
virtual bool OnOpenDocument (const wxString &filename)
virtual bool SaveAs ()
void SetModifiedFlag (BOOL fMod=TRUE)
virtual void SetTitle (LPCTSTR lpszTitle)
 To set a new title for the document. Overide the parent class versions so we can do things like send a message to inform people that things have changed.
virtual void SetPathName (LPCTSTR lpszPathName, BOOL bAddToMRU=TRUE)
 To set a new pathname for the document. Overide the parent class versions so we can do things like send a message to inform people that things have changed.
void SetPathNameEmpty ()
 To set a new pathname for the document. Overide the parent class versions so we can do things like send a message to inform people that things have changed.
void SetDocName (LPCTSTR lpszTitle)
String_256 GetKernelTitle ()
 Good for finding out the title of the document. If the document has been saved as 'Blobby.art' then the title returned will be of the form 'Blobby.art (Modified)' etc. ie What you would see in the title of a non maximised document window.
String_256 GetKernelPathName (UINT32 MaxSize=0)
 Good for finding out the pathname of the document.
String_256 GetKernelDocName (BOOL IncludeFileType=TRUE)
 Good for finding out the name of the document. If the document has been saved as 'Blobby.art' then the title returned will be of the form 'Blobby.art etc. otherwise will be of the form Untitled#1. Similar to what the functions GetTitle() and GetKernelTitle() return but is just the document name with none of the modified etc.
String_256 GetKernelLocation (UINT32 MaxSize=0)
 Good for finding out the location of the document. This is the pathname minus the filename.
String_256 GetOriginalPath () const
void SetOriginalPath (const String_256 &strPath)
 Sets the path to the non-native document that this Camelot doc is based on. This path should be set to empty if the Camelot doc is no longer equivalent to the original non-native file, eg. if the Camelot doc becomes modified, or was loaded from a .ART native file, or is new (untitled).
void SetModified (bool fState)
 To tell the document that it has been modified. While MFC provides an implementation of this, it doesn't update the document's title, so call this function instead.
void SetReadOnly (bool fState)
 To tell the document whether it can be modified or not.
void SetCopy (bool fState)
 To tell the document whether it is a copy of an ineditable document.
bool IsReadOnly () const
 Provides a safe way to test the document's flags.
bool IsACopy () const
 Provides a safe way to test the document's flags.
bool IsUntouched () const
 Provides a safe way to test the document's flags. Note there's no equivalent Set function for this flag because only this class should ever set its state.
bool IsModifiable () const
 Because of a bodge in Operation::EndOp(), SetModified() is called needlessly. So we know whether to pay any attention to IsModified() we can use this.
void SetSaveFlags (BOOL fSameAsLoad, BOOL fRememberName)
PathName GetTemplate () const
 As above.
void SetTemplate (const PathName &pathToSet=PathName())
 As above.
virtual wxCommandProcessor * OnCreateCommandProcessor ()
bool IsVisible () const

Static Public Member Functions

static PathName GetNextTemplateToUse ()
 To find the path of the next template to use.
static void SetNextTemplateToUse (const PathName &pathToSet=PathName())
 To set the path of the next template to use.
static BOOL EnableRemoveUntouchedDocs ()
 Enable to idle-time removal of untouched documents. Called when the user creates new documents or opens existing documents from the highest possible level: menucmds.cpp.

Static Public Attributes

static BOOL s_RemoveExistingOnNewDoc = FALSE

Protected Member Functions

virtual CCLexFileCreateCCFile (LPCTSTR lpcszPath, INT32 nOpenMode)
 CCamDoc::OnOpenDocument and CCamDoc::OnSaveDocument call this to allocate a CCLexFile object to load ans save from/to.
virtual bool DefaultDocumentRequired (CCLexFile *pFile, UINT32 nPrefFilter)
 Given the pathname that we have been asked to open and before we actually go and open the file, we must ask the filter system to work out what filter is required to load the file, ask that filter if it requires a default document or not and if it says yes then load the default document in. This is required because if a file such as a bitmap is loaded the user would expect to see this loaded into the default document, as this file format defines no document structure, otherwise the default constructed document would be used and this is one that is never seen elsewhere by the user. Other file types apart form bitmaps might require the same treatment, examples at present are Corel palette files and Windows metafiles. Formats which define document structures, such as our native format and the EPS formats will be changing the default constructed document given information in the format and so there is no point in loading the default document. Would cause problems anyway as things like colours would need clearing out etc. Needs to be done here as otherwise we would be right in the middle of the loading process before we decide what filter is required and hence would be calling effectively the same code re-enterantly! Only returns False if a problem happened in the testing and loading process.
virtual bool LoadDefaultDocument ()
 Loads the default document. Called by CCamDoc::OnNewDocument etc.
virtual bool GeneralOpenDocument (CCLexFile *pFile, UINT32 nPrefFilter)
 This function will load a document with the name provided to help out the OnNewDocument and the OpOpenDocument, since they do mostly the same thing.
virtual bool OnSaveModified ()
 Prompts user to save document if required. MFCCOPY. Normal MFC uses non- UI compliant Yes/No box.
virtual bool DoSave (LPCTSTR lpszPathName, BOOL bReplace=TRUE)
 This is an exact copy of the CDocument version of this function. I had to copy it out as I need to change the bit that displays the SaveAs dialog so that I could set it to the correct directory and generally change it about to meet our requirements. This function ends up calling OnSaveDocument above to do the actual saving.
virtual bool DeleteContents ()
 Deletes this document's data. Called by MFC in various situations.
BOOL RemoveExistingDocs ()
 Removed existing documents, when a new document is created.
virtual bool DoNewDocument ()
 Called to load the default document etc by CCamDoc::OnNewDocument. Does the actual load of the document data, without changin any flags etc.
virtual bool DoOpenDocument (const wxString &strFilename)
 Helper function to CCamDoc::OnOpenDocument. Does the actual load of the data, without disturbing any flags etc.
virtual bool DoSaveDocument (const wxString &strFilename)
 Helper function for CCamDoc::OnSaveDocument. Does the actual saving of the data, without disturbing aby flags etc.

Protected Attributes

PathName m_pathTemplate

Static Protected Attributes

static PathName ms_pathNextTemplateToUse

Private Member Functions

void UpdateTitle ()
 Sets the (window) titles of all views onto this document to the contained title of the document, plus a suffix if the document has been modified (cf. Visual C++ & Word), is read-only, or a copy.

Private Attributes

Documentm_pKernelDoc
bool m_fIsReadOnly
bool m_fIsACopy
bool m_fIsUntouched
String_256 m_TitlePrefix
String_256 m_strOriginalPath
bool m_bIsModifiable
LPTSTR m_lpszInitialZoomOp
bool m_fDoneNewDoc

Static Private Attributes

static Documents_pForceDocument = NULL


Detailed Description

This is the wxWidgets class for a document type object in the OIL (it was originally part of wxWidgets example app. docvwmdi). It is very simple - its main use is getting hold of the relevant Document object from the kernel layer. wxWidgets calls various member functions when processing commands from the File menu. This class calls down into the kernel to do the actual work.

Author:
Luke_Hart (Xara Group Ltd) <camelotdev@xara.com> (originally from samples) with mods.
Date:
01/07/05
See also:
Document

Definition at line 129 of file camdoc.h.


Constructor & Destructor Documentation

CCamDoc::CCamDoc Document pKernelDoc = NULL  ) 
 

Creates a CCamDoc, optionally attached to a given pKernelDoc or if pKernelDoc is null, a new Document. Notes: m_pFor Scope: protected.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
ages ago
Parameters:
pKernelDoc --- the kernel Document to attach to this [INPUTS] CCamDoc, or m_pForceDoc, a global override of all default creations.
Returns:
Errors: May throw an MFC memory exception!

Definition at line 141 of file camdoc.cpp.

00142   : m_pKernelDoc( NULL ),
00143     m_fIsReadOnly( false ),
00144     m_fIsACopy( false ),
00145     m_fIsUntouched( false ),
00146     m_bIsModifiable( false ),
00147 #if (_OLE_VER >= 0x200)
00148     m_fExportPreview( true ),
00149     m_fIsVisible( false ),
00150     m_fDoneInitialShow( false ),
00151 #endif
00152     m_lpszInitialZoomOp( NULL ),
00153     m_fDoneNewDoc( false )
00154 {
00155 #if (_OLE_VER >= 0x200)
00156     // For most apps enable compound documents.
00157     EnableCompoundFile();
00158     EnableAutomation();
00159 #endif
00160 
00161     // Graham 22/10/97: Set the template path name as empty
00162     SetTemplate();
00163 
00164     // If the default was passed then use the 'forced' one (which may also
00165     // be null, meaning 'create a Document'.
00166     if( NULL == pKernelDoc )
00167         pKernelDoc = s_pForceDocument;
00168 
00169     // Connect with a ready-made kernel Document type?
00170     if( pKernelDoc )
00171     {
00172         // Attach this CCamDoc to the Document type.
00173         ERROR3IF(pKernelDoc->GetOilDoc(),
00174                     "Document already attached in CCamDoc::CCamDoc");
00175         m_pKernelDoc = pKernelDoc;
00176     }
00177     else
00178     {
00179         // Default - connect to a newly-created standard kernel Document.
00180         m_pKernelDoc = new Document;
00181         if( !m_pKernelDoc )
00182             throw CMemoryException();
00183     }
00184 
00185     // Try to initialise the kernel Document type and attach it to this CCamDoc.
00186     if( !m_pKernelDoc->Init( this ) )
00187     {
00188         // Didn't work - delete the Document object and throw an exception
00189         delete m_pKernelDoc;
00190         throw CMemoryException();
00191     }
00192 
00193     // Initialise the document flags.
00194     SetModifiedFlag(FALSE);
00195 
00196 #if (_OLE_VER >= 0x200)
00197     // All done - now claim the OLE 2.0 libraries.
00198     AfxOleLockApp();
00199 #endif
00200 }

CCamDoc::~CCamDoc  ) 
 

Destructor - destroys the Document associated with this OIL document.

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/5/93

Definition at line 210 of file camdoc.cpp.

00211 {
00212     // Get rid of the Document associated with this CCamDoc.
00213 //  wxDocument::SetNoCurrent();
00214     m_pKernelDoc->SetCurrent();
00215     delete m_pKernelDoc;
00216     m_pKernelDoc = NULL;
00217     
00218     // Under OLE 2.0 we must release our claim on the OLE libraries.
00219 #if (_OLE_VER >= 0x200)
00220     AfxOleUnlockApp();
00221 #endif
00222 }


Member Function Documentation

CCLexFile * CCamDoc::CreateCCFile LPCTSTR  lpcszPath,
INT32  nOpenMode
[protected, virtual]
 

CCamDoc::OnOpenDocument and CCamDoc::OnSaveDocument call this to allocate a CCLexFile object to load ans save from/to.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/8/96
Parameters:
lpcszPath - path to the disk file to open, or if NULL then open the [INPUTS] "CONTENTS" stream of the CCamDoc's root-storage member. nOpenMode - opening mode, eg. ios::in. ios::binary is assumed.
Returns:
A pointer to a CCLexFile derivative on the heap that represents the given file object, either on disk or in structured storage. The caller should deallocate this file when finished with it. Returns NULL if there was an error (eg. file not found) - if so then the error has already been reported.
See also:
CCamDoc::OnOpenDocument; CCamDoc::OnSaveDocument

Definition at line 2528 of file camdoc.cpp.

02529 {
02530     // Fix-up the flags.
02531     nOpenMode |= ios::binary;
02532     if (nOpenMode & ios::out) nOpenMode |= ios::trunc;
02533 
02534     // Allocate the appropriate kind of file.
02535     CCLexFile* pFile = 0;
02536     if (lpcszPath)
02537     {
02538         // A path was passed, so open a disk-file on it.
02539         pFile = new CCDiskFile(PathName(lpcszPath), nOpenMode);
02540 //      TRACEUSER( "JustinF", _T("\t- a new CCDiskFile at 0x%p, no sweat\n"), (LPVOID) pFile);
02541     }
02542 
02543 #if (_OLE_VER >= 0x200)
02544 
02545     else
02546     {
02547         // No path was passed, so open the 'native XaraDrawing' stream of CCamDoc's
02548         // m_lpRootStg storage, inherited from CCamDocBase (COleServerDoc).
02549         ERROR2IF(!m_lpRootStg, 0, "No IStorage interface in CCamDoc::CreateCCFile");
02550 
02551         // We have to create or open the stream, depending on whether we are opening for read,
02552         // write, or read/write.
02553         //
02554         // JCF: version 2.0 change - embedded native XaraDrawings no longer have
02555         // version numbers as the native filter handles all versioning itself.
02556         // So we will try to transparently rename on opening any old style streams
02557         // we come across.
02558         LPCWSTR pszStreamName = L"Xara Drawing (native)";
02559         LPSTREAM pIStream;
02560         HRESULT hr;
02561         if (nOpenMode & ios::in)
02562         {
02563             // Loading, so open an existing stream.
02564             ERROR2IF(nOpenMode & ios::out, FALSE,
02565                             "CCamDoc::CreateCCFile: OLE read AND write not implemented");
02566             hr = m_lpRootStg->OpenStream(pszStreamName, 0,
02567                                          STGM_READ | STGM_SHARE_EXCLUSIVE,
02568                                          0, &pIStream);
02569 
02570             // Try the old native format if opening the new stream didn't work.
02571             if (hr == STG_E_FILENOTFOUND)
02572             {
02573                 LPCWSTR pszOldStreamName = L"XaraDrawing 1.5 (Native)";
02574                 hr = m_lpRootStg->OpenStream(pszOldStreamName, 0,
02575                                              STGM_READ | STGM_SHARE_EXCLUSIVE,
02576                                              0, &pIStream);
02577                 
02578                 if (SUCCEEDED(hr))
02579                 {
02580                     // Try to modernise the old stream's name.
02581                     HRESULT hr2 = m_lpRootStg->RenameElement(pszOldStreamName, pszStreamName);
02582                     TRACEUSER( "JustinF", _T("\t- tried to rename v1.5 stream (HRESULT 0x%lX)\n"),
02583                                                     (UINT32) hr2);
02584                     
02585                     // Pass any error along if there's not a good reason for it.
02586                     if (FAILED(hr2) &&
02587                         hr2 != STG_E_DISKISWRITEPROTECTED &&
02588                         hr2 != STG_E_ACCESSDENIED)
02589                             hr = hr2;
02590                 }
02591             }
02592         }
02593         else
02594         {
02595             // If there's a Camelot class factory around then associate this storage with it.
02596             if (m_pFactory) WriteClassStg(m_lpRootStg, m_pFactory->GetClassID());
02597 
02598             // Saving, so create a new stream / truncate an existing stream.
02599             ERROR3IF(!(nOpenMode & ios::out), "No I/O mode in CCamDoc::CreateCCFile");
02600             hr = m_lpRootStg->CreateStream(pszStreamName,
02601                                            STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
02602                                            0, 0, &pIStream);
02603         }
02604 
02605         // Do we have a valid IStream?
02606         if (FAILED(hr))
02607         {
02608             // No, so report the error and fail.
02609             TRACE( _T("Couldn't open IStream in CCamDoc::CreateCCFile (HRESULT 0x%lX)\n"),
02610                     (UINT32) hr);
02611             InformError(_R(IDE_OPEN_ERROR));
02612             return 0;
02613         }
02614 
02615 #ifdef WEBSTER      
02616         // WEBSTER-Martin-29/12/96
02617         // no accusoft stuff so wrap a boring old CCOleStream around it
02618         pFile = new CCOleStream(pIStream, nOpenMode, filebuf::sh_none);
02619 #else
02620         // Yes, so wrap a CCAccusoftOleStream around it.
02621         pFile = new CCOleAccusoftStream(pIStream, nOpenMode, filebuf::sh_none);
02622 #endif
02623 /*      TRACEUSER( "JustinF", _T("\t- a new CCAccusoftOleStream at 0x%p, take cover!\n"),
02624                     (LPVOID) pFile);
02625 */  }
02626 
02627 #endif
02628 
02629     // Check if we managed to allocate the file.
02630     if (!pFile)
02631     {
02632         // No, so report the error and fail.
02633         InformError( _R(IDE_NOMORE_MEMORY) );
02634         return 0;
02635     }
02636 
02637     // Was the file opened sucessfully?
02638     if (!pFile->isOpen())
02639     {
02640         // Couldn't open the file, so deallocate it.  Any error will have already been
02641         // reported.
02642         delete pFile;
02643         pFile = 0;
02644     }
02645 
02646     // Return the file (or null).
02647     return pFile;
02648 }

bool CCamDoc::DefaultDocumentRequired CCLexFile pFile,
UINT32  nPrefFilter
[protected, virtual]
 

Given the pathname that we have been asked to open and before we actually go and open the file, we must ask the filter system to work out what filter is required to load the file, ask that filter if it requires a default document or not and if it says yes then load the default document in. This is required because if a file such as a bitmap is loaded the user would expect to see this loaded into the default document, as this file format defines no document structure, otherwise the default constructed document would be used and this is one that is never seen elsewhere by the user. Other file types apart form bitmaps might require the same treatment, examples at present are Corel palette files and Windows metafiles. Formats which define document structures, such as our native format and the EPS formats will be changing the default constructed document given information in the format and so there is no point in loading the default document. Would cause problems anyway as things like colours would need clearing out etc. Needs to be done here as otherwise we would be right in the middle of the loading process before we decide what filter is required and hence would be calling effectively the same code re-enterantly! Only returns False if a problem happened in the testing and loading process.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/10/95
Parameters:
pFile - file to check [INPUTS]
Returns:
TRUE if the process went ok, FALSE if there was a problem

Errors: -

See also:
CCamDoc::GeneralOpenDocument; CCamDoc::OnOpenDocument; Filter::IsDefaultDocRequired;

Definition at line 1062 of file camdoc.cpp.

01063 {
01064 #if defined(EXCLUDE_FROM_RALPH)
01065     return true;
01066 #else
01067 
01068     // NULL pathname implies that we can't do any checking so return immediately
01069     // Shouldn't happen, maybe we should error?
01070 //  TRACEUSER( "JustinF", _T("In CCamDoc::DefaultDocumentRequired(%p)\n"), (LPVOID) pFile);
01071     PathName            pth = pFile->GetPathName();
01072     if (!pth.IsValid())
01073     {
01074 //      TRACEUSER( "JustinF", _T("\t- file has no valid path, assuming it's OK\n"));
01075         return TRUE;
01076     }
01077 
01078     // Find out the position of the filter selected by the user in the open dialog
01079     INT32 SelectedPos = BaseFileDialog::SelectedFilter;
01080 
01081     // Do we know which filter was used (we know nothing about things in the recent file list)
01082     Filter* pFilter = Filter::GetFirst();
01083     if (nPrefFilter != FILTERID_USERCHOICE || SelectedPos == 0)
01084     {
01085         // We know nothing. We will have to go and have a look at all the possibles
01086         // We will find the Filter Family and ask it to try and load the file
01087         // Find the filter that the user chose.
01088         UINT32 nID = (nPrefFilter != FILTERID_USERCHOICE) ? nPrefFilter : FILTERID_GENERIC;
01089         while (pFilter != NULL && pFilter->FilterID != nID)
01090         {
01091             // Try the next filter
01092             pFilter = Filter::GetNext(pFilter);
01093         }
01094     }
01095     else
01096     {
01097         // We know which type of filter the user had selected in the file dialog
01098         // Find the filter that the user chose
01099         while (pFilter != NULL)
01100         {
01101             // This is the filter?
01102             if (pFilter->GetFlags().CanImport && 
01103                 pFilter->pOILFilter->Position == SelectedPos)
01104                     break;
01105 
01106             // Try the next filter
01107             pFilter = Filter::GetNext(pFilter);
01108         }
01109     }
01110     
01111     // Check that the Filter existed
01112     if (pFilter == NULL)
01113     {
01114         // It did not...
01115         TRACE( _T("Can't find filter #%u in CCamDoc::DefaultDocumentRequired\n"),
01116                 (UINT32) nPrefFilter);
01117         InformError(_R(IDT_CANT_FIND_FILTER));
01118         return FALSE;
01119     }
01120 
01121     // Ask the filter or filter family about whether a default document is required.
01122     // If it is a filter family then we will have to work out what filter is actually
01123     // required and hence ask that filter the qeustion.
01124     if (!pFilter->IsDefaultDocRequired(pth.GetPath())) return TRUE;
01125 
01126     //Graham 22/10/97: First set the template that this document is based on
01127     SetTemplate(GetNextTemplateToUse());
01128 
01129     SetNextTemplateToUse();
01130 
01131     // Try to load the default document.
01132     return LoadDefaultDocument();
01133 #endif
01134 }

bool CCamDoc::DeleteContents  )  [protected, virtual]
 

Deletes this document's data. Called by MFC in various situations.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/3/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
Document::DeleteContents

Definition at line 2289 of file camdoc.cpp.

02290 {
02291     m_pKernelDoc->SetCurrent();
02292     m_pKernelDoc->DeleteContents();
02293 
02294     return true;
02295 }

bool CCamDoc::DoNewDocument  )  [protected, virtual]
 

Called to load the default document etc by CCamDoc::OnNewDocument. Does the actual load of the document data, without changin any flags etc.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/10/96
Returns:
TRUE if successful.
See also:
CCamDoc::OnNewDocument

Definition at line 676 of file camdoc.cpp.

00677 {
00678     // Set up the kernel.
00679     m_pKernelDoc->SetCurrent();
00680 
00681     // If we've already 'new-ed' this document then bail out now.
00682     if (m_fDoneNewDoc) return TRUE;
00683 
00684     // Try to load the default document.
00685     if (!LoadDefaultDocument()) return FALSE;
00686     m_fDoneNewDoc = TRUE;
00687 
00688 #if (_OLE_VER >= 0x200)
00689     // Embedded docs (OLE or hidden) don't export preview bitmaps.
00690     if (IsEmbedded()) SetExportPreview(FALSE);
00691 #endif
00692 
00693     // Success.
00694     return TRUE;
00695 }

bool CCamDoc::DoOpenDocument const wxString &  strFilename  )  [protected, virtual]
 

Helper function to CCamDoc::OnOpenDocument. Does the actual load of the data, without disturbing any flags etc.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/10/96
Parameters:
pcszPathName --- path to file to open (NULL means an embeddeding). [INPUTS]
Returns:
TRUE if successful.
See also:
CCamDoc::OnOpenDocument; CCamDoc::LoadFromStorage

Definition at line 975 of file camdoc.cpp.

00976 {
00977     // Create and open the appropriate kind of file.
00978     CCLexFile          *pFile = CreateCCFile( strFilename.c_str(), ios::in );
00979     if (!pFile) return FALSE;
00980 
00981     // Set up the kernel.
00982     m_pKernelDoc->SetCurrent();
00983 
00984     // Try to load the document and it's item, if it's embedded.
00985     bool                fOK = false;
00986     try
00987     {
00988     #ifndef STANDALONE
00989         // Before we open the file we must ask the filter system to work out what filter is
00990         // required to load the file, ask that filter if it requires a default document or not
00991         // and if it says yes then load the default document in. Required because if a file such
00992         // as a bitmap is loaded the user would expect to see this loaded into the default
00993         // document, as this file format defines no document structure, otherwise the default
00994         // constructed document would be used.
00995         // Only returns False if a problem happened in the testing and loading process.
00996         // -- Standalone
00997         // Don't do it on a standalone version otherwise the items get loaded on top of the  
00998         // document with all the info on rather than a blank page.
00999         // Note the selected document before we start anything
01000 //      DocView* pOldSelView = DocView::GetSelected();
01001         if (!DefaultDocumentRequired(pFile, FILTERID_USERCHOICE))
01002         {
01003             TRACE( wxT("DefaultDocumentRequired failed in CCamDoc::OnOpenDocument - doh?\n") );
01004             delete pFile;
01005             return FALSE;
01006         }
01007     #endif
01008         
01009         // Try to load the file.
01010         m_pKernelDoc->SetTemplateLoading(FALSE); // Note that it is not a template being loaded
01011         fOK = GeneralOpenDocument(pFile, FILTERID_USERCHOICE);
01012 
01013     #if (_OLE_VER >= 0x200)
01014         // Embedded docs (OLE or hidden) don't export preview bitmaps.
01015         if (IsEmbedded()) SetExportPreview(FALSE);
01016     #endif
01017     }
01018     catch( ... )
01019     {
01020         // Tidy up.
01021         delete pFile;
01022         return FALSE;
01023     }
01024 
01025     // Did this work?
01026     delete pFile;
01027     return fOK;
01028 }

bool CCamDoc::DoSave LPCTSTR  lpszPathName,
BOOL  bReplace = TRUE
[protected, virtual]
 

This is an exact copy of the CDocument version of this function. I had to copy it out as I need to change the bit that displays the SaveAs dialog so that I could set it to the correct directory and generally change it about to meet our requirements. This function ends up calling OnSaveDocument above to do the actual saving.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/1/95
Parameters:
lpszPathName - path name where to save document file [INPUTS] if 'bReplace' is TRUE will change file name if successful (SaveAs) if 'bReplace' is FALSE will not change path name (SaveCopyAs) or clear the "dirty" flag.
Returns:
TRUE if it worked, FALSE if not

Definition at line 1844 of file camdoc.cpp.

01845 {
01846 #ifdef STANDALONE
01847     // Do nothing on a standalone version
01848     return true;
01849 #else
01850 
01851     // Get the name to save it as and see if it is empty
01852     bool                SaveAsNewName = false;
01853     wxString            newName = lpszPathName;
01854 
01855     // See if we have loaded this document as an old EPS native format
01856     // If so, then give the user the oppertunity to rename the file so that we don't
01857     // overwrite the original old format document.
01858     // Don't though, if the document is unnamed, so we are going to do a 'save as ...'
01859     // operation anyway.
01860     if( m_pKernelDoc && m_pKernelDoc->IsLoadedAsVersion1File() && !newName.IsEmpty() )
01861     {
01862 #ifndef _DEBUG
01863         // Old EPS format document so ask the user which format to save in
01864         ErrorInfo Info;
01865         Info.ErrorMsg = _R(IDS_OVERWRITEOLDFILE);
01866         Info.Button[0] = _R(IDS_OVERWRITE);
01867         Info.Button[1] = _R(IDB_SAVEAS);
01868         Info.Button[2] = _R(IDS_CANCEL);
01869         UINT32 Answer = AskQuestion(&Info);
01870 #else
01871         UINT32 Answer;
01872         if (!OpConvertFileFormats::IsActive ())
01873         {
01874             // Old EPS format document so ask the user which format to save in
01875             ErrorInfo Info;
01876             Info.ErrorMsg = _R(IDS_OVERWRITEOLDFILE);
01877             Info.Button[0] = _R(IDS_OVERWRITE);
01878             Info.Button[1] = _R(IDB_SAVEAS);
01879             Info.Button[2] = _R(IDS_CANCEL);
01880             Answer = AskQuestion(&Info);
01881         }
01882         else
01883         {
01884             Answer = SaveAsNewName;
01885         }
01886 #endif
01887         if (Answer==_R(IDS_OVERWRITE))
01888             // Rename the new file to make sure we don't overwrite old
01889             SaveAsNewName = FALSE;
01890         else if (Answer== _R(IDB_SAVEAS))
01891             // Rename the new file to make sure we don't overwrite old
01892             SaveAsNewName = TRUE;
01893         else if (Answer==_R(IDS_CANCEL))
01894             // User has chosen to abort the operation
01895             return FALSE;
01896         else
01897             ERROR3("Unknown Answer from AskQuestion");
01898 
01899         // Once we have asked the question ensure that the user is not asked again
01900         // We need to set the loaded flag as FALSE to effectively say that the document
01901         // is now considered version 2.
01902         // In a save as operation, the document will switch to the new name.
01903         // Now Disabled, as cannot set it until actually saved the document as the user may choose
01904         // something like save as and then cancel the file dialog box
01905         //KernelDoc->SetLoadedAsVersion1File(FALSE);
01906     }
01907 
01908     // If the name is empty, i.e. wasn't loaded as a .xar (e.g. open a tiff file) or newly created
01909     // then ask the user for a name i.e. do a 'save as....' operation.
01910     // Also, if we loaded an old format eps xar file and the user has chosen to not overwrite the
01911     // file then we must give them a 'save as....' option.
01912     if (newName.IsEmpty() || SaveAsNewName)
01913     {
01914         // Its empty, so create a default name
01915         CDocTemplate* pTemplate = GetDocTemplate();
01916         ASSERT(pTemplate != NULL);
01917 
01918         newName = m_strPathName;
01919         if (bReplace && newName.IsEmpty())
01920         {
01921             // No path means untitled, so use the made-up name instead.
01922             // This is our stored form of the title before having any items such as ' * '
01923             // or '(Copy)' appended. It is used by the close unsaved document, so warn user code
01924             // so should be reasonably safe.
01925             newName = (const TCHAR*) TitlePrefix;
01926         }
01927 
01928         // we will do it like this instead...
01929         // Set up the dialog
01930         String_256 FilterString(_R(IDS_SAVEFILTERS));
01931 
01932         // Get the filename.
01933         String_256 Str((const char*)newName);
01934 
01935         // If the string is still empty, get a default out
01936         if (Str.IsEmpty()) Str.Load(_R(IDS_DEFAULTFILENAME));
01937 
01938         // Build a pathname out of it
01939         PathName Path(Str);
01940 
01941         // Get some details, ready for the dialog
01942         String_256 LowxString = Path.GetLocation(FALSE);
01943         String_256 NameString = Path.GetFileName();
01944 
01945         // create a dialog and use the path and name of the file if available, or
01946         // use the default path if not.
01947         String_256 DocName = GetKernelDocName();
01948 
01949         // Sorry about the long names, but we are into OS Specific scary stuff here
01950         // Under Windows 95 the OnFileNameOK() function of CFileDialog does not work
01951         // As a Result we have to do the tests ourselves afterwards under win95
01952         // by default we do not need to put the dialog up
01953         BOOL WeNeedToPutSaveAsDialogUpAgain = FALSE;
01954         
01955         // try the dialog
01956         do
01957         {
01958             // Default to only putting the dialog up the once.
01959             WeNeedToPutSaveAsDialogUpAgain = FALSE;
01960 
01961             // Create and display prepare the dialog
01962             SaveFileDialog SaveDialog(FilterString, LowxString, NameString, DocName);
01963             SaveDialog.PrepareDialog();     
01964     
01965             // Display the dialog
01966             TRACE( _T("Display the dialog\n"));
01967             BOOL Result = SaveDialog.OpenAndGetFileName();
01968 
01969             // If they did not click on OK then stop right now
01970             if (!Result)
01971                 return FALSE;
01972 
01973             // Make sure that the file name is OK
01974             // we only need to do this under windows 95, as other OS's will have already done it
01975             // Disable for VC4.0/MFC 4.0 as they have fixed it.
01976         #if _MFC_VER < 0x400
01977             if (IsWin32c())
01978             {
01979                 TRACE( _T("Windows 95, testing for same file name after the event\n"));
01980                 if (!SaveDialog.IsValidFilename()) WeNeedToPutSaveAsDialogUpAgain = TRUE;
01981             }
01982         #endif
01983 
01984             // Get the filename.
01985             wxString TempName(SaveDialog.m_ofn.lpstrFile);
01986             SaveDialog.AppendExtension(&TempName);
01987             Str = String_256(TempName);
01988             Path = PathName(Str);
01989 
01990             // Extract directory name (minus terminating backslash) and remember for next time.
01991             SaveDialog.SetDefaultPath(Path.GetLocation(FALSE));
01992 
01993         } while(WeNeedToPutSaveAsDialogUpAgain);
01994 
01995         // Put the file name into the var set aside for it
01996         newName = (const char*) Str;
01997     
01998     }
01999 
02000         
02001     // Check that the document isn't already open. NOTE: this is only relevant
02002     //  to OLE documents, as attempting to save a document with the same name as
02003     //  an existing, open doc will stuff up the OLE registration code in the 
02004     //  CCamDoc::OnSaveDocument function, after overwriting the file itself...
02005     
02006     BOOL isDocumentOpen = FALSE;
02007 
02008 PORTNOTETRACE("other","CCamDoc::DoSave - remove OLE usage");
02009 #ifndef EXCLUDE_FROM_XARALX
02010 #if (_OLE_VER >= 0x200)
02011 
02012     POSITION pos = AfxGetApp()->GetFirstDocTemplatePosition();
02013 
02014     CDocTemplate::Confidence match = CDocTemplate::noAttempt;
02015     CDocTemplate* pTemplate = NULL;
02016     CDocument* pOpenDocument = NULL;
02017 
02018     // cycle through the document types until we've done them all, or we find that
02019     //  the document is already open.
02020     while ((pos != NULL) && (match != CDocTemplate::yesAlreadyOpen))
02021     {
02022         pTemplate = AfxGetApp()->GetNextDocTemplate(pos);
02023         ASSERT (pTemplate->IsKindOf(RUNTIME_CLASS(CDocTemplate)));
02024 
02025         ASSERT (pOpenDocument == NULL);
02026         match = pTemplate->MatchDocType(newName, pOpenDocument);
02027 
02028             // NOTE: make sure that the match isn't the document that we're editing,
02029             //  otherwise we wouldn't be able to save documents at all...
02030         if (this == pOpenDocument)
02031         {
02032             match =  CDocTemplate::noAttempt;
02033             pOpenDocument = NULL;
02034         }
02035     }
02036 
02037     // Determine whether document is already open or not
02038     if (match == CDocTemplate::yesAlreadyOpen)
02039         isDocumentOpen = TRUE;
02040     else
02041         isDocumentOpen = FALSE;
02042 
02043 #endif      // (OLE_VER >= 0x200)
02044 #endif
02045 
02046     // End 'Already Open' check.
02047 
02048     if (isDocumentOpen == FALSE)
02049     {
02050 
02051         // Make a .bak version of the file here in case the save screws up
02052         // This will be removed after the save, unless they have the keep bak files option in
02053         // Rename the current version of the file to the same with a .bak extension
02054         // get the old filename
02055         String_256 BakFileName(newName);
02056         String_256 OldFileName = BakFileName;
02057         
02058         // Change the extension on NewFileName...
02059         PathName NewPathName = BakFileName;
02060 
02061         // and change its extension
02062         String_256 Extension(_R(IDS_BAKEXTENSION));
02063         NewPathName.SetType(Extension);
02064 
02065         // Go find out where the temp directory is so that we can put the .bak file in there
02066         String_256 TempFileName;
02067         char* pTempName = _tgetenv("TEMP");
02068         if (pTempName!=NULL)
02069         {
02070             TempFileName = String_256(pTempName);
02071             
02072             // See if we have a backslash
02073             String_8 LastChar;
02074             TempFileName.Right(&LastChar, 1);
02075 
02076             // if it isn't a \ then add one
02077             if (LastChar!=String_8("\\"))
02078                 TempFileName += String_8("\\");
02079 
02080             // Add the leaf name to it
02081             TempFileName += NewPathName.GetFileName();
02082             TRACEUSER( "Neville", _T("TEMP file is %s\n"), (const char*)TempFileName);
02083         }
02084 
02085         // Copy the version with the new extension back over the original
02086         BakFileName = NewPathName.GetPath();
02087 
02088         // Get these as strings we can use
02089         TCHAR* pBakName = NULL;
02090         TCHAR* pOldName = (TCHAR*) OldFileName;
02091         
02092         // If the user want .bak files then use a local name,
02093         // otherwise put the bak file in the temp directory
02094         if ((BaseFileDialog::MakeBakFiles) || (pTempName==NULL))
02095             pBakName = (TCHAR*) BakFileName;
02096         else
02097             pBakName = (TCHAR*) TempFileName;
02098 
02099         // make sure they are not the same (ie, let them save files with a .bak extension)
02100         BOOL FileNamesSame = (BakFileName == OldFileName);
02101         if (!FileNamesSame)
02102         {
02103             // Make sure that the .bak version of the file does not exist
02104             // If these do not work (eg the .bak is read-only) then you
02105             // simply will not get your .bak file updated and run the risk
02106             // of loosing your current changes if the save fails.
02107             TRACEUSER( "Neville", _T("Check to see if %s exists\n"), pBakName);
02108             if (_taccess(pBakName, 0)==0)
02109             {
02110                 TRACEUSER( "Neville", _T("deleteing %s\n"), pBakName);
02111                 unlink(pBakName);
02112             }
02113         
02114             // Now rename the original file (but only if the old filename exists)
02115             TRACEUSER( "Neville", _T("Check to see if %s exists\n"), pOldName);
02116             if (_taccess(pOldName, 0)==0)
02117             {
02118                 // Rename the original artwork to a .bak version of the file
02119                 TRACEUSER( "Neville", _T("Renaming %s to %s\n"), pOldName, pBakName);
02120                 INT32 RenameResult = _trename(pOldName, pBakName);
02121 
02122                 // if we fail to rename the file, but the user wants renamed files, complain
02123                 if ((RenameResult!=0) && (BaseFileDialog::MakeBakFiles))
02124                 {
02125                     // There was a problem renaming the file, ask if we want to go on
02126                     ErrorInfo Info;
02127                     Info.ErrorMsg = _R(IDS_RENAMEFAILED);
02128                     Info.Button[0] = _R(IDS_SAVEANYWAY);
02129                     Info.Button[1] = _R(IDS_ABORTSAVE);
02130 
02131                     // If not then stop right away.
02132                     if (AskQuestion(&Info)==_R(IDS_ABORTSAVE))
02133                         return FALSE;
02134                 }
02135             }
02136         }
02137 
02138         // This may take a while ...
02139         String_64 strProgress;
02140         strProgress.MakeMsg(_R(IDS_WAIT_UPDATING_DOC_PFX), (LPCTSTR) GetTitle());
02141         BeginSlowJob( -1, FALSE, NULL );
02142 
02143     #if (_OLE_VER >= 0x200)
02144         // If the document is embedded and this isn't SaveCopyAs then don't export a preview
02145         // bitmap.
02146         BOOL fOldPrev;
02147         if (IsEmbedded() && !bReplace)
02148         {
02149             TRACEUSER( "JustinF", _T("Exporting preview for embedded item in CCamDoc::DoSave\n"));
02150             fOldPrev = SetExportPreview(TRUE);
02151         }
02152     #endif
02153 
02154         // Do the actual saving
02155         BOOL fOK = OnSaveDocument(newName);
02156 
02157     #if (_OLE_VER >= 0x200)
02158         // Restore the original setting if we changed it.
02159         if (IsEmbedded() && !bReplace) SetExportPreview(fOldPrev);
02160     #endif
02161 
02162         // Was the save successful?
02163         if (!fOK)
02164         {
02165             // The save failed here, so tidy up
02166             // be sure to delete the corrupt file
02167             TRACEUSER( "Neville", _T("Save failed, removing %s\n"), newName);
02168             remove(newName);
02169 
02170             // Well, something went a bit wrong there, so copy the old version of the file
02171             // over the top of the rubbish one if we have the .bak version that is
02172             if (!FileNamesSame)
02173             {
02174                 // If the bak file exists, rename it over the original
02175                 TRACEUSER( "Neville", _T("Check to see if %s exists\n"), pBakName);
02176                 if (_taccess(pBakName, 0) == 0)
02177                 {
02178                     TRACEUSER( "Neville", _T("renaming %s to %s\n"), pBakName, pOldName);
02179                     _trename(pBakName, pOldName);
02180                 }
02181             }
02182 
02183             // return that we failed
02184             EndSlowJob();
02185             return FALSE;
02186         }
02187 
02188         // The save worked, so get rid of the bak file if they do not want it
02189         // if we do not want bak file around the place, then get rid of them
02190         if (!BaseFileDialog::MakeBakFiles)
02191         {
02192             TRACEUSER( "Neville", _T("bak files not wanted, getting rid of it\n"));
02193             // Make sure the .bak file was not the real file as well!
02194             if (!FileNamesSame)
02195             {
02196                 // If the bak file exists, delete it
02197                 TRACEUSER( "Neville", _T("Check to see if %s exists\n"), pBakName);
02198                 if (_taccess(pBakName, 0)==0)
02199                 {
02200                     TRACEUSER( "Neville", _T("Deleting %s\n"), pBakName);
02201                     unlink(pBakName);
02202                 }
02203             }       
02204         }
02205 
02206         // Once we have saved the document ok, then ensure that the user is not asked again
02207         if (KernelDoc) KernelDoc->SetLoadedAsVersion1File(FALSE);
02208 
02209         // reset the title and change the document name
02210         if (bReplace)
02211         {
02212             // If we have just changed the name of the document, then get rid of the copy flag
02213             SetCopy(FALSE);
02214         
02215             // We saved the file under a new name, as opposed to a copy of the file, so it is
02216             // no longer "dirty".
02217             SetModified(FALSE);
02218 
02219             // Set the name of the document
02220             SetPathName(newName);
02221         }
02222 
02223         EndSlowJob();
02224         return TRUE;        // success
02225     }       // Document is already open and registered
02226     else
02227     {
02228 //      MessageBox (NULL, _R(IDS_OVERWRITEOPENFILE), NULL, MB_ICONERROR);
02229         UINT32 Answer;
02230         ErrorInfo Info;
02231 
02232         Info.ErrorMsg = _R(IDS_OVERWRITEOPENFILE);
02233         Info.Button[0] = _R(IDS_CANCEL);
02234         Answer = AskQuestion(&Info);
02235 
02236         return FALSE;       // could not open document
02237 
02238     }       // End of isDocumentOpen (OLE registration check)
02239 #endif  // Not standalone (see first few lines)
02240 }

bool CCamDoc::DoSaveDocument const wxString &  strPathName  )  [protected, virtual]
 

Helper function for CCamDoc::OnSaveDocument. Does the actual saving of the data, without disturbing aby flags etc.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/10/96
Parameters:
pcszPathName --- path to the file to load (NULL means an embedding) [INPUTS]
Returns:
TRUE if successful.
See also:
CCamDoc::OnSaveDocument; CCamDoc::SaveToStorage

Definition at line 805 of file camdoc.cpp.

00806 {
00807     // Create and open the appropriate kind of file.
00808     CCLexFile* pFile = CreateCCFile( strPathName, ios::out | ios::trunc);
00809     if (!pFile) return FALSE;
00810 
00811     // Make sure the kernel is set up.
00812     m_pKernelDoc->SetCurrent();
00813 
00814     // Try to save the document.
00815 // WEBSTER - markn 28/1/97
00816 // Native file saving is to be .web, not .xar
00817 #ifndef WEBSTER
00818     bool                fOK = FALSE != InvokeNativeFileOp( OPTOKEN_NATIVESAVE, pFile, FILTERID_NATIVE );
00819 #else
00820     bool                fOK = FALSE != InvokeNativeFileOp( OPTOKEN_NATIVESAVE, pFile, FILTERID_WEB );
00821 #endif // WEBSTER
00822 
00823     // Did that work?
00824     delete pFile;
00825     return fOK;
00826 }

BOOL CCamDoc::EnableRemoveUntouchedDocs  )  [static]
 

Enable to idle-time removal of untouched documents. Called when the user creates new documents or opens existing documents from the highest possible level: menucmds.cpp.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/10/96
Returns:
TRUE if successful, FALSE otherwise

Definition at line 563 of file camdoc.cpp.

00564 {
00565 PORTNOTE("other", "Removed idle processing");
00566 #ifndef EXCLUDE_FROM_XARALX
00567     s_fRunIdleProcessing = TRUE;
00568 #endif
00569     return TRUE;
00570 }

bool CCamDoc::GeneralOpenDocument CCLexFile pFile,
UINT32  nPrefFilter
[protected, virtual]
 

This function will load a document with the name provided to help out the OnNewDocument and the OpOpenDocument, since they do mostly the same thing.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/4/95
Parameters:
pFile - the file to load the document from. [INPUTS] nPrefFilter - the preferred filter to use, usually FILTERID_GENERIC. Pass -1 to use the last filter the user chose in a file dialog box.
Returns:
TRUE if the document was opened ok, FALSE if there was a problem
See also:
CCamDoc::OnOpenDocument; CCamDoc::OnNewDocument

Definition at line 240 of file camdoc.cpp.

00241 {
00242     // We need to make sure that the Current DocView is the same as the Selected DocView here
00243 /*  TRACEUSER( "JustinF", _T("In CCamDoc::GeneralOpenDocument(%p, %u)\n"),
00244                 (LPVOID) pFile, nPrefFilter);
00245 */  DocView            *pDocView = DocView::GetCurrent();
00246     DocView            *pOldSelView = DocView::GetSelected();
00247     if (pDocView != NULL)
00248     {
00249         // There was a current DocView, see if its got anything to do with out new doc
00250         // it should do
00251         if (pDocView->GetDoc() == m_pKernelDoc)
00252         {
00253             // make it the selected view
00254             Document::SetSelectedViewAndSpread( m_pKernelDoc, pDocView, NULL );
00255         }