First public contribution.
2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
42 #include <techview/eikpword.h>
43 #include <techview/eikon.rsg>
45 #include <techview/eikdialg.h>
54 #include "wpresources.h"
58 //#define ALLOC_TESTING
64 const TUid KUidWordAppUiStream={268436035};
66 CWordDocument* CWordDocument::NewL(CEikApplication& aApp)
67 // Return a handle to a new instance of this class.
70 #if defined(ALLOC_TESTING)
71 // reserve some space on the cleanup stack
72 {for (TInt ii=0;ii<1000;++ii)
73 CleanupStack::PushL(&ii);}
74 CleanupStack::Pop(1000);
78 CWordDocument* self=NULL;
81 __UHEAP_SETFAIL(RHeap::EDeterministic,ii);
84 self=new(ELeave) CWordDocument(aApp);
87 TRAP(err,self->ConstructL());
101 CWordDocument* self=new(ELeave) CWordDocument(aApp);
102 CleanupStack::PushL(self);
109 void CWordDocument::ConstructL()
110 // Complete initialisation
115 iUiData=new(ELeave) TWordUiData;
119 CWordDocument::~CWordDocument()
127 void CWordDocument::CreateModelL()
128 {iModel=CWordModel::NewL(this,this);}
131 void CWordDocument::ConstructPrintL()
132 // Print initialisation
135 CCoeEnv* coeEnv=CCoeEnv::Static();
136 CWordModel& model=*Model();
137 CPrintSetup& printSetup=*model.PrintSetup();
138 printSetup.CreatePrinterDeviceL(KUidPrinterDevice,coeEnv->FsSession());
139 iPrint=CTextPageRegionPrinter::NewL(model.Text(),printSetup.PrinterDevice());
141 TPageMargins margins;
142 margins.iMargins.iLeft=1440;
143 margins.iMargins.iRight=1440;
144 margins.iMargins.iTop=1440;
145 margins.iMargins.iBottom=1440;
146 margins.iHeaderOffset=720;
147 margins.iFooterOffset=720;
149 pageSpec.iPortraitPageSize=TSize(11906,16838); // A4 !!
150 printSetup.iPageMarginsInTwips=margins;
151 printSetup.PrinterDevice()->SelectPageSpecInTwips(pageSpec); // A4 !!
155 void CWordDocument::NewDocumentL()
156 // Builds a new main (container) document, creating content from a standard file.
157 // If a leave occurs whilst loading the standard document, current document
158 // content will not be lost.
161 TFileName templateFileName;
162 TWordFilePath::GetNormalTemplateFolderName(templateFileName);
163 TFindFile* ff = new(ELeave) TFindFile(Process()->FsSession());
164 CleanupStack::PushL(ff);
165 TFileName* tempFileName = new(ELeave) TFileName();
166 CleanupStack::PushL(tempFileName);
167 CCoeEnv* coeEnv = CCoeEnv::Static();
168 coeEnv->ReadResource(*tempFileName, R_WORD_NORMAL_TEMPLATE_FILE_NAME);
169 templateFileName.Append(*tempFileName);
170 // look for a normal template
171 templateFileName[0] = 'Y';
172 TParsePtrC tParse(templateFileName);
173 TInt error = ff->FindByDir(templateFileName,tParse.DriveAndPath());
176 // no normal template, search ROM for blank
177 TWordFilePath::GetNormalTemplateFolderName(templateFileName);
178 coeEnv->ReadResource(*tempFileName, R_WORD_BLANK_TEMPLATE_FILE_NAME);
179 templateFileName.Append(*tempFileName);
180 templateFileName[0] = 'Z';
181 TParsePtr blankParse(templateFileName);
182 error = ff->FindByDir(blankParse.NameAndExt(),blankParse.DriveAndPath());
184 CleanupStack::PopAndDestroy(); // tempFileName
186 Panic(EDefaultTemplateNotPresent);
187 templateFileName = ff->File();
188 CleanupStack::PopAndDestroy(); // ff
189 DoNewDocumentL(templateFileName);
191 WordAppUi().NotifyNewTextL(); // edwin must know of new text for focus loss etc...
195 CFileStore* CWordDocument::DoNewDocumentL(const TDesC& aStandardDocument,TKeepStoreOpen aKeepStoreOpen/*=EKeepFalse*/)
196 // Open and restore the specified valid document.
197 // The store that is opened over the file for restoration may be kept open, or destroyed, depending on
198 // the value of aKeepStoreOpen.
201 CFileStore* store=NULL;
202 CStreamDictionary* dictionary=CApaProcess::ReadRootStreamLC(Process()->FsSession(),store,aStandardDocument,EFileShareExclusive|EFileRead); // takes ownership of store
203 CleanupStack::PushL(store);
204 iNewDocument = ETrue;
205 RestoreL(*store,*dictionary);
206 iNewDocument = EFalse;
207 iModel->Text()->DetachFromStoreL(CPicture::EDetachFull);
208 if (aKeepStoreOpen==EKeepTrue)
209 CleanupStack::Pop(); // store
211 CleanupStack::PopAndDestroy(); // store
212 CleanupStack::PopAndDestroy(); // dictionary
213 return (aKeepStoreOpen==EKeepTrue)
219 void CWordDocument::LocateTemplateL(const TDes& aFullFileName) const
220 // Verify that the template file selected by the user is still present
223 TFindFile ff(Process()->FsSession());
224 TParsePtrC tParse(aFullFileName);
225 User::LeaveIfError(ff.FindByDir(aFullFileName,tParse.DriveAndPath()));
226 VerifyDocumentTypeL(aFullFileName);
229 void CWordDocument::VerifyDocumentTypeL(const TFileName& aFileName)const
230 // Verify the document of the specified name is indeed of the
231 // same type as this document object.
235 User::LeaveIfError(Process()->FsSession().Entry(aFileName,entry));
236 if (entry.MostDerivedUid()!=Application()->AppDllUid())
237 User::Leave(KErrCorrupt);
241 const CStreamStore& CWordDocument::StreamStoreL(TInt /*aPos*/)const
242 // In this case the store does not vary with document position.
244 {return *iEditStore;}
247 void CWordDocument::DetachFromStoreL(CPicture::TDetach aDegree)
248 // Propogate the detachFromStore to all picture container components.
251 iModel->Text()->DetachFromStoreL(aDegree);
252 CRichText* text=iModel->PrintSetup()->Header()->Text();
254 text->DetachFromStoreL(aDegree);
255 text=iModel->PrintSetup()->Footer()->Text();
257 text->DetachFromStoreL(aDegree);
261 void CWordDocument::StoreUiDataL(CStreamStore& aStore,CStreamDictionary& aStreamDic)const
266 WordAppUi().GetUiData(*iUiData);
268 RStoreWriteStream stream;
269 TStreamId id=stream.CreateLC(aStore);
272 CleanupStack::PopAndDestroy(); // stream
274 aStreamDic.AssignL(KUidWordAppUiStream,id);
278 void CWordDocument::StoreL(CStreamStore& aStore,CStreamDictionary& aStreamDic)const
279 // Write this object network.
283 CEikonEnv::Static()->BusyMsgL(R_EIK_TBUF_SAVING_FILE,KFileBusyInitialDelayInMicroSeconds);
284 StoreUiDataL(aStore,aStreamDic);
285 iModel->StoreL(aStore, aStreamDic, 0);
287 CEikonEnv::Static()->BusyMsgCancel();
291 void CWordDocument::RestoreUiDataL(const CStreamStore& aStore,const CStreamDictionary& aStreamDic)
292 // Restore any ui data for future use
295 TStreamId id=aStreamDic.At(KUidWordAppUiStream);
296 if (id==KNullStreamId)
300 RStoreReadStream stream;
301 stream.OpenLC(aStore,id);
303 CleanupStack::PopAndDestroy(); // stream
308 void CWordDocument::RestoreL(const CStreamStore& aStore,const CStreamDictionary& aStreamDic)
309 // Restore this document.
310 // All model restoration is done here, to save having a temporary model member data,
311 // implementing a rollback robust model restore.
314 CEikonEnv* eikonEnv=CEikonEnv::Static();
315 if (iAppUi && !iNewDocument)
316 eikonEnv->BusyMsgL(R_EIK_TBUF_OPENING_FILE,KFileBusyInitialDelayInMicroSeconds);
317 else if (iAppUi && iNewDocument)
318 eikonEnv->BusyMsgL(R_WORD_FILE_CREATE_FILE,KFileBusyInitialDelayInMicroSeconds);
320 CWordModel* tempModel=CWordModel::NewL(this,this);
321 CleanupStack::PushL(tempModel);
323 CStreamStore* oldStore=iEditStore;
324 iEditStore=CONST_CAST(CStreamStore*,&aStore);
326 tempModel->Text()->SetPictureFactory(&iPictureFactory,this); // rich text callbacks
328 tempModel->RestoreL(aStore,aStreamDic,0,this,this,eikonEnv->PictureFactory())); // print setup field callbacks
335 iModel=tempModel; // document takes over ownership
336 CleanupStack::Pop(); // tempModel
338 SetChanged(EFalse); // this is a brand new document - it cannot yet have been changed.
341 RestoreUiDataL(aStore,aStreamDic));
343 iUiData->Reset(); // do not propogate. We can handle this.
347 WordAppUi().SetUiData();
348 // CEikonEnv::Static()->BusyMsgCancel();
353 TInt CWordDocument::UpdateFieldFileName(TPtr& aValueText)const
354 // Set aValueText with the current document filename only.
355 // (No path or extension).
358 TParsePtrC parser(Process()->MainDocFileName());
359 TPtrC pp=parser.NameAndExt();
360 if (pp.Length()>aValueText.MaxLength())
367 TInt CWordDocument::UpdateFieldNumPages()const
368 // Return the number of pages currently in this document.
369 // Precondition: pagination of the document has already occured.
371 {return iModel->PageTable()->Count();}
374 void CWordDocument::DoFileNewL(const TFileName& aNewFilename, const TFileName& aTemplateFileName)
375 // Create an initialised document instance with the specified name,
376 // and initialise a new file store to store the document in.
377 // (A new document is not created, *this* instance is re-used).
381 // Create the file store for the new document
382 LocateTemplateL(aTemplateFileName);
383 User::LeaveIfError(EikFileUtils::CopyFile(aTemplateFileName,aNewFilename));
384 CCoeEnv* coeEnv=CCoeEnv::Static();
385 User::LeaveIfError(coeEnv->FsSession().SetAtt(aNewFilename,KEntryAttNormal,KEntryAttReadOnly));
386 // turn read-only file attribute if set, just to be safe.
388 CFileStore* store=DoNewDocumentL(aNewFilename,EKeepTrue);
389 __ASSERT_DEBUG(store,Panic(ENewFileNullStore));
391 SetMainStoreAndMainDocFileName(store,aNewFilename);
393 TUint appFileMode=AppFileMode();
394 appFileMode|=EFileWrite;
395 SetAppFileMode(appFileMode);
396 WordAppUi().SetReadOnly((TBool)!(appFileMode&EFileWrite));
400 void CWordDocument::SetMainStoreAndMainDocFileName(CFileStore* aMainStore,const TDesC& aMainDocFileName)
402 CEikProcess& process=REINTERPRET_CAST(CEikProcess&,*Process());
403 delete process.MainStore(); // remove the [original] store
404 process.SetMainStore(aMainStore); // set the new file store as the main one.
405 process.SetMainDocFileName(aMainDocFileName);
409 void CWordDocument::DoFileOpenL(const TFileName& aFileName,TUint aFileMode)
410 // Open the Word document specified by aFileName.
413 VerifyDocumentTypeL(aFileName);
414 RFs session=Process()->FsSession();
415 GetFileOpenModeL(aFileMode,aFileName,session);
417 CFileStore* store=NULL;
418 CStreamDictionary* dic=CApaProcess::ReadRootStreamLC(session,store,aFileName,EFileShareExclusive|aFileMode);
419 CleanupStack::PushL(store);
420 RestoreL(*store,*dic);
421 CleanupStack::Pop(); // store
422 CleanupStack::PopAndDestroy(); // dictionary
424 SetMainStoreAndMainDocFileName(store,aFileName);
425 SetAppFileMode(aFileMode);
426 WordAppUi().SetReadOnly((TBool)!(aFileMode&EFileWrite));
430 void CWordDocument::GetFileOpenModeL(TUint& aFileMode,const TDesC& aFilename,RFs& aSession)
431 // Attempt to open the specified file in the specified mode.
432 // If this fails because write access was requested on a read-only file,
433 // the file is opened read-only.
434 // Any other error (leave) is propogated.
435 // aFileMode is set to the mode that the file was successfully opened in.
438 CFileStore* store=NULL;
440 store=CFileStore::OpenL(aSession,aFilename,aFileMode));
441 if (ret==KErrAccessDenied && aFileMode&EFileWrite)
444 aFileMode&=~EFileWrite;
445 store=CFileStore::OpenL(aSession,aFilename,aFileMode);
448 User::LeaveIfError(ret);
449 __ASSERT_DEBUG(ret==KErrNone && store,Panic(EFileOpenIntegrityError));
454 void CWordDocument::DoFileSaveToCurrentL()
460 void CWordDocument::DoFileSaveToNewL(const TFileName& aNewFileName)
462 ((CEikProcess*)Process())->SaveToDirectFileStoreL(this,&aNewFileName); // writes root stream
463 SetAppFileMode(EFileWrite);
466 void CWordDocument::DoFileSaveToNewNoSwitchL(const TFileName& aNewFileName)
467 // Save the current file to a new file, but don't open the new file
469 // From CEikProcess::SaveToDirectFileStoreL but without the close iMainDoc at the end
471 CApaProcess* proc = Process();
472 RFs& fsSession=proc->FsSession();
473 CDirectFileStore* store;
474 store = CDirectFileStore::CreateLC(fsSession,aNewFileName,EFileWrite);
475 store->SetTypeL(REINTERPRET_CAST(CEikProcess*,proc)->MainStore()->Type());
476 CStreamDictionary* streamDic=CStreamDictionary::NewL();
477 CleanupStack::PushL(streamDic);
478 proc->MainDocument()->StoreL(*store,*streamDic);
480 proc->WriteRootStreamL(*store,*streamDic,*(this->Application()));
481 CleanupStack::PopAndDestroy(); // streamDic
482 // close the new store
484 CleanupStack::PopAndDestroy(); // store
487 void CWordDocument::DoFileRevertL()
489 CStreamDictionary* streamDic=CStreamDictionary::NewL();
490 CleanupStack::PushL(streamDic);
491 CFileStore* mainStore=REINTERPRET_CAST(CEikProcess*,Process())->MainStore();
492 RStoreReadStream root;
493 root.OpenLC(*mainStore,mainStore->Root());
496 CleanupStack::PopAndDestroy(); // root
497 RestoreL(*mainStore,*streamDic);
498 CleanupStack::PopAndDestroy(); // streamDic
505 TUid CWordApplication::AppDllUid() const
507 return KUidWordAppValue;
510 CApaDocument* CWordApplication::CreateDocumentL()
511 {return CWordDocument::NewL(*this);}
514 CEikAppUi* CWordDocument::CreateAppUiL()
516 #if defined(ALLOC_TESTING)
517 // reserve some space on the cleanup stack
518 {for (TInt ii=0;ii<1000;++ii)
519 CleanupStack::PushL(&ii);}
520 CleanupStack::Pop(1000);
521 // construct the appUi before the setfail loop so that cached resources
522 // do not cause alloc failure
523 CWordAppUi* appUi=NULL;
524 appUi=new(ELeave) CWordAppUi;
525 appUi->SetDocument(this);
531 for (TInt ii=2;;++ii)
533 __UHEAP_SETFAIL(RHeap::EDeterministic,ii);
535 appUi=new(ELeave) CWordAppUi;
536 appUi->SetDocument(this);
540 TRAP(err,appUi->ConstructL());
545 User::Heap().Check();
551 User::Heap().Check();
554 return(new(ELeave) CWordAppUi);