OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ocdoc.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectComponents
3// Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of TOcDocument Class
7//----------------------------------------------------------------------------
8#include <ocf/pch.h>
9
10#include <ocf/oleutil.h>
11#include <ocf/ocstorag.h>
12#include <ocf/ocdoc.h>
13#include <ocf/ocpart.h>
14#include <ocf/ocapp.h>
15#include <ocf/ocremvie.h>
16#include <owl/defs.h>
17
18namespace ocf {
19
20using namespace owl;
21
23
24namespace
25{
26 constexpr _TCHAR DocStreamName_[] = _T("OcDocument");
27
28 // There are (or used to be) some API that do not allow longer names.
29 //
30 constexpr auto MaxPartNameSize_ = 32;
31} // anonymous namespace
32
33//
34//
35//
37:
38 OcApp(app),
40 PartCollection(),
41 LinkCollection()
42{
43 // Host support...
44 //
45 ActiveView = 0;
46 PartID = 0;
47 Storage = 0;
48
49 bool createNew = ToBool(!fileName || !fileName[0]);
50 Storage = new TOcStorage(fileName, createNew);
51 TRACEX(OcfRefCount, 1, "TOcDocument() @" << (void*)this);
52}
53
54//
55//
56//
58:
59 OcApp(app),
61 PartCollection(),
62 LinkCollection()
63{
64 // Host support...
65 //
66 ActiveView = 0;
67 PartID = 0;
68 Storage = 0;
69 OrgStorage = 0;
70
71 if (storageI) // Storage already created by host application
72 Storage = new TOcStorage(storageI);
73 else
74 Storage = 0; // No storage yet, wait until a SetStorage() is called
75 TRACEX(OcfRefCount, 1, "TOcDocument() @" << (void*)this);
76}
77
78//
79//
80//
82{
83 delete Storage;
84}
85
86//----------------------------------------------------------------------------
87
88//
89/// Set the storage for this document
90//
91void
93{
94 if (Storage && storage == Storage->GetIStorage())
95 return;
96
97 if (remember) {
98 delete Storage;
99 OrgStorage = 0;
100 }
101 else
102 OrgStorage = Storage;
103
104 if (storage)
105 Storage = new TOcStorage(storage);
106 else
107 Storage = 0;
108}
109
110//
111/// Set the storage for this document
112//
113void
115{
116 delete Storage;
117 Storage = new TOcStorage(path, false);
118 SetName(path); // new Storage now has path as a name
119}
120
121//
122/// Restore the original root IStorage before the save operation
123//
124bool
126{
127 if (OrgStorage) {
128 delete Storage;
129
130 Storage = OrgStorage;
131 OrgStorage = 0;
132 }
133
134 return true;
135}
136
137//
138/// Perform saveas operation
139//
140bool
142{
144
146 Name = newName;
147 return SaveParts(newStorage.GetIStorage(), false);
148}
149
150//
151/// Save the embedded parts to the provided storage. 'remember' flag is not
152/// really used here, as our save/restore is done outside here.
153//
154bool
156{
157 if (!Storage)
158 return true;
159
161
162 // If the storage passed is not the same as the one we loaded, wrap the new
163 // one & use it in here.
164 //
165 if (!sameAsLoaded) {
166 CHECK(storage);
167
168 // If we are switching storages, make sure parts all all pulled in now
169 //
170 for (TOcPartCollectionIter i(PartCollection); i; i++) {
171 TOcPart& part = *i.Current();
172 part.FinishLoading();
173 }
174 oldStorage = Storage;
175 Storage = new TOcStorage(storage);
176 }
177
178 // Create a stream for part information
179 //
181 if (!HRSucceeded(Storage->Stat(&statstg, STATFLAG_NONAME)))
182 return false;
183
184 TOcStream stream(*Storage, DocStreamName_, true, statstg.grfMode);
185
186 // Write TOcDocument data into stream
187 //
188 ulong count;
189 bool ok;
190 ulong value = PartCollection.Count();
191 ok = ToBool(HRSucceeded(stream.Write(&PartID, sizeof PartID, &count)) &&
192 HRSucceeded(stream.Write(&value, sizeof value, &count)));
193
194 if (ok) {
195 for (TOcPartCollectionIter i(PartCollection); i; i++) {
196 TOcPart& part = *i.Current();
197 int16 len = int16(part.GetName().Length());
198
199 // Write the part name string, pascal style [len]+chars, no 0
200 //
201 ok = ToBool(HRSucceeded(stream.Write(&len, sizeof len, &count)) &&
202 HRSucceeded(stream.Write(static_cast<const char*>(part.GetName()), len, &count)) &&
203 part.Save(sameAsLoaded, remember));
204
205 if (!ok)
206 break;
207 }
208 }
209
210 // Deal with the alloc'd storage if there was one. Either put things back on
211 // failure, or keep the new storage around for a while
212 //
213 if (!sameAsLoaded) {
214 if (!ok) {
215 delete Storage;
216 Storage = oldStorage;
217 }
218 else
219 delete oldStorage;
220 }
221
222 return ok;
223}
224
225//
226/// Loads the parts from the current storage into the PartCollection. Return
227/// false if a serious error occurs. Having no part stream at all is OK.
228//
229bool
231{
232 if (!Storage)
233 return true;
234
235 /// Clear the part collection
236 ///
237 /// PartCollection.Clear(); ///DR clear before make a new one.
238 /// There is a case when clearing now causes a crash
239
240 // Open a stream with part information
241 //
243 if (!HRSucceeded(Storage->Stat(&statstg, STATFLAG_NONAME)))
244 return false;
245
246 try {
247 TOcStream stream(*Storage, DocStreamName_, false, statstg.grfMode);
248
249 // Read TOcDocument data from stream. Return false if any of the data
250 // is missing--something must have been corrupted.
251 //
252 if (!HRSucceeded(stream.Read(&PartID, sizeof PartID)))
253 return false;
254
255 ulong value;
256 if (!HRSucceeded(stream.Read(&value, sizeof value)))
257 return false;
258
259 // Clear the part collection
260 //
261 PartCollection.Clear();
262
263 // Rebuild the part collection
264 //
265 for (int i = (int)value; i; i--) {
266 char name[MaxPartNameSize_ + 1];
267 int16 len;
268
269 // Read the part name string, pascal style [len]+chars, no 0
270 //
271 if (!HRSucceeded(stream.Read(&len, sizeof(len))))
272 return false;
273
275 // NOTE: Should *never* happen!
276 //
277 return false;
278 }
279
280 if (!HRSucceeded(stream.Read(name, len)))
281 return false;
282 name[len] = 0; // 0 was not written
283
284 // !BB Something's wrong here for controls -- can't just create
285 // !BB a TOcPart for OCXes..
286 // !BB
287 new TOcPart(*this, to_tstring(const_cast<LPCSTR>(name)).c_str());
288 }
289 }
290 catch (TXObjComp&) {
291 // There is no part related info stream. Thats OK, we then have a document
292 // with no parts
293 }
294 return true;
295}
296
297//
298//
299//
300void
302{
303 if (Name.empty())
304 return; // Temporary file does not have moniker
305
306 for (TOcPartCollectionIter i(PartCollection); i; i++) {
307 TOcPart& part = *i.Current();
308
310 if (HRSucceeded(part.QueryInterface(IID_IBLinkable, (LPVOID *)&linkI))) {
311 linkI->OnRename(bLDocumentI, part.GetName());
312 linkI->Release();
313 }
314 }
315}
316
317//
318//
319//
320void
322{
323 for (TOcPartCollectionIter i(PartCollection); i; i++) {
324 TOcPart& part = *i.Current();
325 part.Close();
326 }
327
328 for (TOcLinkCollectionIter j((TPtrArray<TOcLinkView*>&)LinkCollection); j; j++) {
329 TOcLinkView& link = *j.Current();
330 link.Disconnect();
331 }
332
333 LinkCollection.Clear(); // Remove the link views now
334}
335
336//
337//
338//
339void
341{
342 ActiveView = view;
343}
344
345//
346/// Notify container that doc pathname has changed
347//
348void
350{
351 Name = newName;
352
353 // Create a moniker for this document
354 //
355 if (!Name.empty() && ActiveView)
356 ActiveView->Rename();
357}
358
359} // OCF namespace
360
361//==============================================================================
362
363
#define CHECK(condition)
Definition checks.h:239
#define PRECONDITION(condition)
Definition checks.h:227
#define DIAG_DECLARE_GROUP(group)
Definition checks.h:404
#define TRACEX(group, level, message)
Definition checks.h:263
ILinkable abstract base class.
Definition ocbocole.h:321
OCF Application class.
Definition ocapp.h:144
void SetActiveView(TOcView *view)
Definition ocdoc.cpp:340
void RenameParts(IBRootLinkable *bLDocumentI)
Definition ocdoc.cpp:301
bool SaveParts(IStorage *storage=0, bool sameAsLoaded=true, bool remember=true)
Save the embedded parts to the provided storage.
Definition ocdoc.cpp:155
TOcDocument(TOcApp &app, LPCTSTR fileName=0)
Definition ocdoc.cpp:36
void SetStorage(IStorage *storage, bool remember=true)
Set the storage for this document.
Definition ocdoc.cpp:92
bool SaveToFile(LPCTSTR newName)
Perform saveas operation.
Definition ocdoc.cpp:141
bool RestoreStorage()
Restore the original root IStorage before the save operation.
Definition ocdoc.cpp:125
bool LoadParts()
Loads the parts from the current storage into the PartCollection.
Definition ocdoc.cpp:230
void SetName(const owl::tstring &newName)
Notify container that doc pathname has changed.
Definition ocdoc.cpp:349
virtual unsigned Count() const
Definition ocpart.h:185
void Clear()
Release parts in the collection.
Definition ocpart.cpp:817
OC part class represents an embeded or linked part in a document.
Definition ocpart.h:38
IStorage * GetIStorage()
Definition ocstorag.cpp:383
HRESULT Stat(STATSTG *pstatstg, owl::uint32 grfStatFlag)
Definition ocstorag.cpp:484
The TOcView partner is a container (viewer) of a given (server/client) document.
Definition ocview.h:136
virtual void Rename()
Definition ocview.cpp:393
Base OC exception class.
Definition except.h:90
Iterator for Pointer Container.
Definition template.h:602
#define _T(x)
Definition cygwin.h:51
Include for OC, gets common headers when precompiled headers are enabled.
Object Component Framework (COM encapsulation)
Definition appdesc.h:22
class _ICLASS TOcPart
Definition ocapp.h:34
bool HRSucceeded(HRESULT hr)
Definition defs.h:131
class _ICLASS TOcStorage
Definition ocdoc.h:32
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
bool ToBool(const T &t)
Definition defs.h:291
signed short int16
Definition number.h:29
std::string tstring
Definition defs.h:79
auto to_tstring(const T &v) -> tstring
Definition defs.h:82
Definition of TOcApp application connection class.
Definition of TOcDocument Class.
interface _ICLASS IStorage
Definition ocdoc.h:25
Definition of TOcPart class.
Definition of TOcRemView Class.
Definition of TOcStorage & TOcStream classes.
Low level OLE Utility class definitions.
General definitions used by all ObjectWindows programs.