--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textrendering/word/SRC/WPDOC.CPP Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,555 @@
+/*
+* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <s32std.h>
+#include <s32stor.h>
+#include <s32file.h>
+
+#include <f32file.h>
+
+#include <gdi.h>
+
+#include <txtrich.h>
+#include "txtmrtsr.h"
+
+#include <frmprint.h>
+
+#include <prnsetup.h>
+
+#include <basched.h>
+
+#include <coemain.h>
+
+#include <apparc.h>
+#include <apgdoor.h>
+
+#include <eikproc.h>
+#include <techview/eikpword.h>
+#include <techview/eikon.rsg>
+#include <eikfutil.h>
+#include <techview/eikdialg.h>
+#include <eikenv.h>
+
+#include "WNGMODEL.H"
+
+#include "WPDOC.H"
+#include "WPAPPUI.H"
+#include "WPMAIN.H"
+#include "WPPANIC.H"
+#include "wpresources.h"
+#include <word.rsg>
+#include "WORD.HRH"
+
+//#define ALLOC_TESTING
+
+//
+// CWordDocument
+//
+
+const TUid KUidWordAppUiStream={268436035};
+
+CWordDocument* CWordDocument::NewL(CEikApplication& aApp)
+// Return a handle to a new instance of this class.
+//
+ {
+#if defined(ALLOC_TESTING)
+ // reserve some space on the cleanup stack
+ {for (TInt ii=0;ii<1000;++ii)
+ CleanupStack::PushL(&ii);}
+ CleanupStack::Pop(1000);
+ //
+ __UHEAP_MARK;
+ {
+ CWordDocument* self=NULL;
+ for (TInt ii=2;;++ii)
+ {
+ __UHEAP_SETFAIL(RHeap::EDeterministic,ii);
+ __UHEAP_MARK;
+ TInt err=KErrNone;
+ self=new(ELeave) CWordDocument(aApp);
+ if (self)
+ {
+ TRAP(err,self->ConstructL());
+ delete self;
+ self=NULL;
+ }
+ __UHEAP_MARKEND;
+ User::Heap().Check();
+ if (err==KErrNone)
+ break;
+ }
+ __UHEAP_MARKEND;
+ __UHEAP_RESET;
+ User::Heap().Check();
+ }
+#endif
+ CWordDocument* self=new(ELeave) CWordDocument(aApp);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+
+void CWordDocument::ConstructL()
+// Complete initialisation
+//
+ {
+ CreateModelL();
+ ConstructPrintL();
+ iUiData=new(ELeave) TWordUiData;
+ }
+
+
+CWordDocument::~CWordDocument()
+ {
+ delete iModel;
+ delete iPrint;
+ delete iUiData;
+ }
+
+
+void CWordDocument::CreateModelL()
+ {iModel=CWordModel::NewL(this,this);}
+
+
+void CWordDocument::ConstructPrintL()
+// Print initialisation
+//
+ {
+ CCoeEnv* coeEnv=CCoeEnv::Static();
+ CWordModel& model=*Model();
+ CPrintSetup& printSetup=*model.PrintSetup();
+ printSetup.CreatePrinterDeviceL(KUidPrinterDevice,coeEnv->FsSession());
+ iPrint=CTextPageRegionPrinter::NewL(model.Text(),printSetup.PrinterDevice());
+ //
+ TPageMargins margins;
+ margins.iMargins.iLeft=1440;
+ margins.iMargins.iRight=1440;
+ margins.iMargins.iTop=1440;
+ margins.iMargins.iBottom=1440;
+ margins.iHeaderOffset=720;
+ margins.iFooterOffset=720;
+ TPageSpec pageSpec;
+ pageSpec.iPortraitPageSize=TSize(11906,16838); // A4 !!
+ printSetup.iPageMarginsInTwips=margins;
+ printSetup.PrinterDevice()->SelectPageSpecInTwips(pageSpec); // A4 !!
+ }
+
+
+void CWordDocument::NewDocumentL()
+// Builds a new main (container) document, creating content from a standard file.
+// If a leave occurs whilst loading the standard document, current document
+// content will not be lost.
+//
+ {
+ TFileName templateFileName;
+ TWordFilePath::GetNormalTemplateFolderName(templateFileName);
+ TFindFile* ff = new(ELeave) TFindFile(Process()->FsSession());
+ CleanupStack::PushL(ff);
+ TFileName* tempFileName = new(ELeave) TFileName();
+ CleanupStack::PushL(tempFileName);
+ CCoeEnv* coeEnv = CCoeEnv::Static();
+ coeEnv->ReadResource(*tempFileName, R_WORD_NORMAL_TEMPLATE_FILE_NAME);
+ templateFileName.Append(*tempFileName);
+ // look for a normal template
+ templateFileName[0] = 'Y';
+ TParsePtrC tParse(templateFileName);
+ TInt error = ff->FindByDir(templateFileName,tParse.DriveAndPath());
+ if(error)
+ {
+ // no normal template, search ROM for blank
+ TWordFilePath::GetNormalTemplateFolderName(templateFileName);
+ coeEnv->ReadResource(*tempFileName, R_WORD_BLANK_TEMPLATE_FILE_NAME);
+ templateFileName.Append(*tempFileName);
+ templateFileName[0] = 'Z';
+ TParsePtr blankParse(templateFileName);
+ error = ff->FindByDir(blankParse.NameAndExt(),blankParse.DriveAndPath());
+ }
+ CleanupStack::PopAndDestroy(); // tempFileName
+ if(error!=KErrNone)
+ Panic(EDefaultTemplateNotPresent);
+ templateFileName = ff->File();
+ CleanupStack::PopAndDestroy(); // ff
+ DoNewDocumentL(templateFileName);
+ if (iAppUi)
+ WordAppUi().NotifyNewTextL(); // edwin must know of new text for focus loss etc...
+ }
+
+
+CFileStore* CWordDocument::DoNewDocumentL(const TDesC& aStandardDocument,TKeepStoreOpen aKeepStoreOpen/*=EKeepFalse*/)
+// Open and restore the specified valid document.
+// The store that is opened over the file for restoration may be kept open, or destroyed, depending on
+// the value of aKeepStoreOpen.
+//
+ {
+ CFileStore* store=NULL;
+ CStreamDictionary* dictionary=CApaProcess::ReadRootStreamLC(Process()->FsSession(),store,aStandardDocument,EFileShareExclusive|EFileRead); // takes ownership of store
+ CleanupStack::PushL(store);
+ iNewDocument = ETrue;
+ RestoreL(*store,*dictionary);
+ iNewDocument = EFalse;
+ iModel->Text()->DetachFromStoreL(CPicture::EDetachFull);
+ if (aKeepStoreOpen==EKeepTrue)
+ CleanupStack::Pop(); // store
+ else
+ CleanupStack::PopAndDestroy(); // store
+ CleanupStack::PopAndDestroy(); // dictionary
+ return (aKeepStoreOpen==EKeepTrue)
+ ? store
+ : NULL;
+ }
+
+
+void CWordDocument::LocateTemplateL(const TDes& aFullFileName) const
+// Verify that the template file selected by the user is still present
+//
+ {
+ TFindFile ff(Process()->FsSession());
+ TParsePtrC tParse(aFullFileName);
+ User::LeaveIfError(ff.FindByDir(aFullFileName,tParse.DriveAndPath()));
+ VerifyDocumentTypeL(aFullFileName);
+ }
+
+void CWordDocument::VerifyDocumentTypeL(const TFileName& aFileName)const
+// Verify the document of the specified name is indeed of the
+// same type as this document object.
+//
+ {
+ TEntry entry;
+ User::LeaveIfError(Process()->FsSession().Entry(aFileName,entry));
+ if (entry.MostDerivedUid()!=Application()->AppDllUid())
+ User::Leave(KErrCorrupt);
+ }
+
+
+const CStreamStore& CWordDocument::StreamStoreL(TInt /*aPos*/)const
+// In this case the store does not vary with document position.
+//
+ {return *iEditStore;}
+
+
+void CWordDocument::DetachFromStoreL(CPicture::TDetach aDegree)
+// Propogate the detachFromStore to all picture container components.
+//
+ {
+ iModel->Text()->DetachFromStoreL(aDegree);
+ CRichText* text=iModel->PrintSetup()->Header()->Text();
+ if (text)
+ text->DetachFromStoreL(aDegree);
+ text=iModel->PrintSetup()->Footer()->Text();
+ if (text)
+ text->DetachFromStoreL(aDegree);
+ iEditStore=NULL;
+ }
+
+void CWordDocument::StoreUiDataL(CStreamStore& aStore,CStreamDictionary& aStreamDic)const
+// Write any Ui data
+//
+ {
+ if (iAppUi)
+ WordAppUi().GetUiData(*iUiData);
+
+ RStoreWriteStream stream;
+ TStreamId id=stream.CreateLC(aStore);
+ stream <<*iUiData;
+ stream.CommitL();
+ CleanupStack::PopAndDestroy(); // stream
+
+ aStreamDic.AssignL(KUidWordAppUiStream,id);
+ }
+
+
+void CWordDocument::StoreL(CStreamStore& aStore,CStreamDictionary& aStreamDic)const
+// Write this object network.
+//
+ {
+ if (iAppUi)
+ CEikonEnv::Static()->BusyMsgL(R_EIK_TBUF_SAVING_FILE,KFileBusyInitialDelayInMicroSeconds);
+ StoreUiDataL(aStore,aStreamDic);
+ iModel->StoreL(aStore, aStreamDic, 0);
+ if (iAppUi)
+ CEikonEnv::Static()->BusyMsgCancel();
+ }
+
+
+void CWordDocument::RestoreUiDataL(const CStreamStore& aStore,const CStreamDictionary& aStreamDic)
+// Restore any ui data for future use
+//
+ {
+ TStreamId id=aStreamDic.At(KUidWordAppUiStream);
+ if (id==KNullStreamId)
+ iUiData->Reset();
+ else
+ {
+ RStoreReadStream stream;
+ stream.OpenLC(aStore,id);
+ stream>> *iUiData;
+ CleanupStack::PopAndDestroy(); // stream
+ }
+ }
+
+
+void CWordDocument::RestoreL(const CStreamStore& aStore,const CStreamDictionary& aStreamDic)
+// Restore this document.
+// All model restoration is done here, to save having a temporary model member data,
+// implementing a rollback robust model restore.
+//
+ {
+ CEikonEnv* eikonEnv=CEikonEnv::Static();
+ if (iAppUi && !iNewDocument)
+ eikonEnv->BusyMsgL(R_EIK_TBUF_OPENING_FILE,KFileBusyInitialDelayInMicroSeconds);
+ else if (iAppUi && iNewDocument)
+ eikonEnv->BusyMsgL(R_WORD_FILE_CREATE_FILE,KFileBusyInitialDelayInMicroSeconds);
+ //
+ CWordModel* tempModel=CWordModel::NewL(this,this);
+ CleanupStack::PushL(tempModel);
+ //
+ CStreamStore* oldStore=iEditStore;
+ iEditStore=CONST_CAST(CStreamStore*,&aStore);
+ //
+ tempModel->Text()->SetPictureFactory(&iPictureFactory,this); // rich text callbacks
+ TRAPD(ret,
+ tempModel->RestoreL(aStore,aStreamDic,0,this,this,eikonEnv->PictureFactory())); // print setup field callbacks
+ if (ret!=KErrNone)
+ {
+ iEditStore=oldStore;
+ User::Leave(ret);
+ }
+ delete iModel;
+ iModel=tempModel; // document takes over ownership
+ CleanupStack::Pop(); // tempModel
+
+ SetChanged(EFalse); // this is a brand new document - it cannot yet have been changed.
+
+ TRAP(ret,
+ RestoreUiDataL(aStore,aStreamDic));
+ if (ret!=KErrNone)
+ iUiData->Reset(); // do not propogate. We can handle this.
+ //
+ if (iAppUi)
+ {
+ WordAppUi().SetUiData();
+// CEikonEnv::Static()->BusyMsgCancel();
+ }
+ }
+
+
+TInt CWordDocument::UpdateFieldFileName(TPtr& aValueText)const
+// Set aValueText with the current document filename only.
+// (No path or extension).
+//
+ {
+ TParsePtrC parser(Process()->MainDocFileName());
+ TPtrC pp=parser.NameAndExt();
+ if (pp.Length()>aValueText.MaxLength())
+ return pp.Length();
+ aValueText=pp;
+ return 0;
+ }
+
+
+TInt CWordDocument::UpdateFieldNumPages()const
+// Return the number of pages currently in this document.
+// Precondition: pagination of the document has already occured.
+//
+ {return iModel->PageTable()->Count();}
+
+
+void CWordDocument::DoFileNewL(const TFileName& aNewFilename, const TFileName& aTemplateFileName)
+// Create an initialised document instance with the specified name,
+// and initialise a new file store to store the document in.
+// (A new document is not created, *this* instance is re-used).
+//
+ {
+ //
+ // Create the file store for the new document
+ LocateTemplateL(aTemplateFileName);
+ User::LeaveIfError(EikFileUtils::CopyFile(aTemplateFileName,aNewFilename));
+ CCoeEnv* coeEnv=CCoeEnv::Static();
+ User::LeaveIfError(coeEnv->FsSession().SetAtt(aNewFilename,KEntryAttNormal,KEntryAttReadOnly));
+ // turn read-only file attribute if set, just to be safe.
+ //
+ CFileStore* store=DoNewDocumentL(aNewFilename,EKeepTrue);
+ __ASSERT_DEBUG(store,Panic(ENewFileNullStore));
+ //
+ SetMainStoreAndMainDocFileName(store,aNewFilename);
+ SetChanged(ETrue);
+ TUint appFileMode=AppFileMode();
+ appFileMode|=EFileWrite;
+ SetAppFileMode(appFileMode);
+ WordAppUi().SetReadOnly((TBool)!(appFileMode&EFileWrite));
+ }
+
+
+void CWordDocument::SetMainStoreAndMainDocFileName(CFileStore* aMainStore,const TDesC& aMainDocFileName)
+ {
+ CEikProcess& process=REINTERPRET_CAST(CEikProcess&,*Process());
+ delete process.MainStore(); // remove the [original] store
+ process.SetMainStore(aMainStore); // set the new file store as the main one.
+ process.SetMainDocFileName(aMainDocFileName);
+ }
+
+
+void CWordDocument::DoFileOpenL(const TFileName& aFileName,TUint aFileMode)
+// Open the Word document specified by aFileName.
+//
+ {
+ VerifyDocumentTypeL(aFileName);
+ RFs session=Process()->FsSession();
+ GetFileOpenModeL(aFileMode,aFileName,session);
+//
+ CFileStore* store=NULL;
+ CStreamDictionary* dic=CApaProcess::ReadRootStreamLC(session,store,aFileName,EFileShareExclusive|aFileMode);
+ CleanupStack::PushL(store);
+ RestoreL(*store,*dic);
+ CleanupStack::Pop(); // store
+ CleanupStack::PopAndDestroy(); // dictionary
+ //
+ SetMainStoreAndMainDocFileName(store,aFileName);
+ SetAppFileMode(aFileMode);
+ WordAppUi().SetReadOnly((TBool)!(aFileMode&EFileWrite));
+ }
+
+
+void CWordDocument::GetFileOpenModeL(TUint& aFileMode,const TDesC& aFilename,RFs& aSession)
+// Attempt to open the specified file in the specified mode.
+// If this fails because write access was requested on a read-only file,
+// the file is opened read-only.
+// Any other error (leave) is propogated.
+// aFileMode is set to the mode that the file was successfully opened in.
+//
+ {
+ CFileStore* store=NULL;
+ TRAPD(ret,
+ store=CFileStore::OpenL(aSession,aFilename,aFileMode));
+ if (ret==KErrAccessDenied && aFileMode&EFileWrite)
+ {
+ ret=KErrNone;
+ aFileMode&=~EFileWrite;
+ store=CFileStore::OpenL(aSession,aFilename,aFileMode);
+ }
+ //
+ User::LeaveIfError(ret);
+ __ASSERT_DEBUG(ret==KErrNone && store,Panic(EFileOpenIntegrityError));
+ delete store;
+ }
+
+
+void CWordDocument::DoFileSaveToCurrentL()
+ {
+ SaveL();
+ }
+
+
+void CWordDocument::DoFileSaveToNewL(const TFileName& aNewFileName)
+ {
+ ((CEikProcess*)Process())->SaveToDirectFileStoreL(this,&aNewFileName); // writes root stream
+ SetAppFileMode(EFileWrite);
+ }
+
+void CWordDocument::DoFileSaveToNewNoSwitchL(const TFileName& aNewFileName)
+// Save the current file to a new file, but don't open the new file
+ {
+ // From CEikProcess::SaveToDirectFileStoreL but without the close iMainDoc at the end
+ //
+ CApaProcess* proc = Process();
+ RFs& fsSession=proc->FsSession();
+ CDirectFileStore* store;
+ store = CDirectFileStore::CreateLC(fsSession,aNewFileName,EFileWrite);
+ store->SetTypeL(REINTERPRET_CAST(CEikProcess*,proc)->MainStore()->Type());
+ CStreamDictionary* streamDic=CStreamDictionary::NewL();
+ CleanupStack::PushL(streamDic);
+ proc->MainDocument()->StoreL(*store,*streamDic);
+ // write root stream
+ proc->WriteRootStreamL(*store,*streamDic,*(this->Application()));
+ CleanupStack::PopAndDestroy(); // streamDic
+ // close the new store
+ store->CommitL();
+ CleanupStack::PopAndDestroy(); // store
+ }
+
+void CWordDocument::DoFileRevertL()
+ {
+ CStreamDictionary* streamDic=CStreamDictionary::NewL();
+ CleanupStack::PushL(streamDic);
+ CFileStore* mainStore=REINTERPRET_CAST(CEikProcess*,Process())->MainStore();
+ RStoreReadStream root;
+ root.OpenLC(*mainStore,mainStore->Root());
+ root>> *streamDic;
+ root.Close();
+ CleanupStack::PopAndDestroy(); // root
+ RestoreL(*mainStore,*streamDic);
+ CleanupStack::PopAndDestroy(); // streamDic
+ }
+
+//
+// CWordApplication
+//
+
+TUid CWordApplication::AppDllUid() const
+ {
+ return KUidWordAppValue;
+ }
+
+CApaDocument* CWordApplication::CreateDocumentL()
+ {return CWordDocument::NewL(*this);}
+
+
+CEikAppUi* CWordDocument::CreateAppUiL()
+ {
+#if defined(ALLOC_TESTING)
+ // reserve some space on the cleanup stack
+ {for (TInt ii=0;ii<1000;++ii)
+ CleanupStack::PushL(&ii);}
+ CleanupStack::Pop(1000);
+ // construct the appUi before the setfail loop so that cached resources
+ // do not cause alloc failure
+ CWordAppUi* appUi=NULL;
+ appUi=new(ELeave) CWordAppUi;
+ appUi->SetDocument(this);
+ appUi->ConstructL();
+ delete appUi;
+ appUi=NULL;
+ __UHEAP_MARK;
+ {
+ for (TInt ii=2;;++ii)
+ {
+ __UHEAP_SETFAIL(RHeap::EDeterministic,ii);
+ __UHEAP_MARK;
+ appUi=new(ELeave) CWordAppUi;
+ appUi->SetDocument(this);
+ TInt err=KErrNone;
+ if (appUi)
+ {
+ TRAP(err,appUi->ConstructL());
+ delete appUi;
+ appUi=NULL;
+ }
+ __UHEAP_MARKEND;
+ User::Heap().Check();
+ if (err==KErrNone)
+ break;
+ }
+ __UHEAP_MARKEND;
+ __UHEAP_RESET;
+ User::Heap().Check();
+ }
+#endif
+ return(new(ELeave) CWordAppUi);
+ }