//---------------------------------------------------------------------------- // ObjectWindows // (C) Copyright 1994 by Borland International, All Rights Reserved // // Implementation of TOleDocument. Doc/View document that supports Ole2 // using OCF TOcDocument //---------------------------------------------------------------------------- #define INC_OLE2 #include #include #include #include #include #include #include #include #include TOleDocument::TOleDocument(TDocument* parent) : TStorageDocument(parent), OcDoc(0), Closing(false) { } // // For an OLE container the compound file remains open // until the application shuts down // TOleDocument::~TOleDocument() { delete OcDoc; } // // Prepare document shutdown // bool TOleDocument::CanClose() { // Just say yes if we are already in the closing process, or are embedded, // or have multiple views open // if (Closing || IsEmbedded()) return true; return TDocument::CanClose(); } // // Shut down the TOleView's // void TOleDocument::OleViewClose() { TView* curView = GetViewList(); while (curView) { TOleView* oleView = TYPESAFE_DOWNCAST(curView, TOleView); if (oleView) oleView->OleShutDown(); curView = curView->GetNextView(); } } // // Close the compound file // bool TOleDocument::Close() { // Make sure that TOleView's are closed first // OleViewClose(); OcDoc->Close(); return TStorageDocument::Close(); } // // Close the OLE document when the server is done with the // given IStorage from its container // bool TOleDocument::ReleaseDoc() { PRECONDITION(OcDoc); TStorageDocument::ReleaseDoc(); OcDoc->SetStorage((IStorage*)0); return true; } // // Open the OLE document when the server is provided with an // IStorage from its container // bool TOleDocument::SetStorage(IStorage* stg, bool remember) { PRECONDITION(OcDoc); // If a storage is provided, then we are now using container's IStorage // if (stg) Embedded = true; OcDoc->SetStorage(stg, remember); TStorageDocument::SetStorage(stg, remember); return true; } // // Restores the original root IStorage before the save operation // bool TOleDocument::RestoreStorage() { PRECONDITION(OcDoc); OcDoc->RestoreStorage(); TStorageDocument::RestoreStorage(); return true; } // // Set the initial open mode // void TOleDocument::PreOpen() { SetOpenMode(ofReadWrite | ofTransacted); } // // Open the compound file so that we have an IStorage for use // with embedded objects. A document partner is created // to handle OLE related stuff. // bool TOleDocument::InitDoc() { if (IsOpen()) return true; // compound file already open // Give user a chance to set a different open mode // PreOpen(); if (GetDocPath()) SetOpenMode(GetOpenMode() | ofNoCreate); else SetOpenMode(GetOpenMode() | ofTemporary); if (TStorageDocument::Open(GetOpenMode(), GetDocPath())) { if (OcDoc) { // use the existing ocdoc OcDoc->SetStorage(StorageI); } else if (GetOcApp()) { OcDoc = new TOcDocument(*GetOcApp(), GetDocPath(), StorageI); } return true; } return false; } // // Save the embedded objects, if any // bool TOleDocument::Commit(bool force) { if (Write()) return TStorageDocument::Commit(force); else return false; } // // Load the embedded objects, if any // bool TOleDocument::Open(int, const char far* path) { if (path) SetDocPath(path); return Read(); } // // Check if current document path is the same as the // OcDoc's. // bool TOleDocument::PathChanged() { string::set_case_sensitive(false); return OcDoc->GetName() != string(GetDocPath()); } // // Save embed objects to the compound file // bool TOleDocument::Write() { // Switch to new storage if path has changed & it is permanent ("SaveAs") // IStorage* newStorageI; bool saveAs = PathChanged() && !OrgStorageI; // also is 'remember' bool sameAsLoad = !PathChanged() && !OrgStorageI; // use current storage if (saveAs) { // Update link monikers // string newName(GetDocPath()); OcDoc->SetName(newName); if (IsEmbedded()) newStorageI = StorageI; // Use the one assigned by container else newStorageI = GetNewStorage(); } else newStorageI = StorageI; return newStorageI ? OcDoc->SaveParts(newStorageI, sameAsLoad, saveAs) : false; } // // Load embed objects from the compound file // bool TOleDocument::Read() { // Load the embedded objects, if any // return OcDoc->LoadParts(); } // // Get a new IStorage, typically in a SaveAs // situation. // IStorage* TOleDocument::GetNewStorage() { PRECONDITION(StorageI); // Create another root storage based on the new doc path // Should close the current document and open a new one. // IStorage* newStorage = 0; HRESULT hres; STATSTG stgInfo; if (!SUCCEEDED(StorageI->Stat(&stgInfo, STATFLAG_NONAME))) return 0; hres = ::StgOpenStorage(OleStr(GetDocPath()), 0, stgInfo.grfMode, 0, 0, &newStorage); if (!SUCCEEDED(hres)) hres = ::StgCreateDocfile(OleStr(GetDocPath()), stgInfo.grfMode, 0, &newStorage); if (SUCCEEDED(hres)) { StorageI->Release(); // Release the old root storage StorageI = newStorage; } return newStorage; } // // Revert to last saved compound file // bool TOleDocument::Revert(bool clear) { if (!StorageI) return true; // return OK if storage already released if (!TDocument::Revert(clear) || !ReleaseDoc()) return false; if (!clear) { InitDoc(); Open(0); } SetDirty(false); return true; } // // Get OCF application partner // TOcApp* TOleDocument::GetOcApp() { TOleFrame* olefr = TYPESAFE_DOWNCAST(GetDocManager().GetApplication()->GetMainWindow(), TOleFrame); return olefr->GetOcApp(); }