OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
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:543
#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.