//----------------------------------------------------------------------------
// ObjectWindows
// Copyright (c) 1993, 1996 by Borland International, All Rights Reserved
//
/// \file
/// Implementation of classes TView & TWindowView
//----------------------------------------------------------------------------
#include <owl/pch.h>
#include <owl/defs.h>
#include <owl/docmanag.h>
#include <owl/appdict.h>
#include <owl/bardescr.h>
#include <owl/docview.rh>
#if defined(__BORLANDC__)
# pragma option -w-ccc // Disable "Condition is always true/false"
#endif
namespace owl {
OWL_DIAGINFO;
DIAG_DECLARE_GROUP(OwlDocView); // General Doc/View diagnostic group
const uint MinUniqueViewId = 0x8000;
uint TView::NextViewId = MinUniqueViewId;
//
/// Constructs a TView object of the document associated with the view. Sets the
/// private data member ViewId to NextViewId. Calls TDocument's private member
/// function AttachView to attach the view to the associated document.
//
TView::TView(TDocument& doc)
:
Tag(0),
ViewMenu(0),
ViewBar(0)
{
ViewId = NextViewId;
doc.AttachView(*this);
}
//
/// Frees a TView object and calls TDocument's private member function DetachView to
/// detach the view from the associated document.
//
TView::~TView()
{
delete ViewMenu;
delete ViewBar;
const auto ok = Doc != nullptr;
WARN(!ok, _T("TView::~TView: Terminating due to failed precondition."));
if (!ok) std::terminate();
if (Doc->DetachView(*this)) {
delete Doc;
}
}
//
// Detach the view from the current document and attach it to another.
// (Added by Vidar Hasfjord, 2007-08-27.)
//
void
TView::SetDocument(TDocument& new_doc)
{
if (&new_doc == Doc) return; // Guard against reassignment.
// Detach and register whether the document should be deleted.
// The actual deletion is postponed to later to avoid any side-effects
// from the deletion that may affect the validity of the new document.
TDocument* delete_doc = 0;
if (Doc && Doc->DetachView(*this))
delete_doc = Doc;
// Update the new document and existing views as if this was a new view.
new_doc.AttachView(*this);
CHECK(Doc == &new_doc);
Doc->ReindexFrames();
// Deletion of the old doc should be safe now.
if (delete_doc)
delete delete_doc;
}
//
//
//
void
TView::SetViewMenu(TMenuDescr* menu)
{
delete ViewMenu;
ViewMenu = menu;
TDocTemplate* tpl = Doc->GetTemplate();
//if (tpl && ViewMenu && *ViewMenu->GetModule() == *tpl->GetModule())
// must check also if template is static becouse as module = 0;
if (tpl && ViewMenu && !tpl->IsStatic() && *ViewMenu->GetModule() == *tpl->GetModule())
ViewMenu->SetModule(tpl->GetModule());// force same module alias as template
}
//
/// Sets the menu descriptor for this view. This can be any existing TMenuDescr
/// object. If no descriptor exists, ViewMenu is 0.
//
void
TView::SetViewBar(TBarDescr* bar)
{
delete ViewBar;
ViewBar = bar;
}
static const tchar* const TView_PropertyNames[] = {
_T("View Class"), // ViewClass
_T("View Name"), // ViewName
};
static const int TView_PropertyFlags[] = {
pfGetText|pfConstant, // ViewClass
pfGetText|pfConstant, // ViewName
};
//
/// Returns the text name of the property given the index value.
//
const tchar*
TView::PropertyName(int index)
{
if (index <= PrevProperty) {
TRACEX(OwlDocView, 0, _T("PropertyName(): index <= PrevProperty!"));
return 0;
}
else if (index < NextProperty)
return TView_PropertyNames[index-PrevProperty-1];
else {
TRACEX(OwlDocView, 0, _T("PropertyName(): index >= NextProperty!"));
return 0;
}
}
//
/// Returns the attributes of a specified property given the index of the property
/// whose attributes you want to retrieve.
//
int
TView::PropertyFlags(int index)
{
if (index <= PrevProperty) {
TRACEX(OwlDocView, 0, _T("PropertyFlags(): index <= PrevProperty!"));
return 0;
}
else if (index < NextProperty)
return TView_PropertyFlags[index-PrevProperty-1];
else {
TRACEX(OwlDocView, 0, _T("PropertyFlags(): index >= NextProperty!"));
return 0;
}
}
//
/// Gets the property index, given the property name (name). Returns 0 if the name
/// is not found.
//
int
TView::FindProperty(LPCTSTR name)
{
PRECONDITION(name != nullptr);
int i;
for (i=0; i < NextProperty-PrevProperty-1; i++)
if (_tcscmp(TView_PropertyNames[i], name) == 0)
return i+PrevProperty+1;
TRACEX(OwlDocView, 0, _T("FindProperty: Index of [") << name << _T("] not found") );
return 0;
}
//
/// Retrieves the property identified by the given index.
/// If the requested property is text, then `dest` should point to a text buffer, and `textlen`
/// should specify the maximum number of characters the buffer can hold, excluding the terminating
/// null-character, i.e. the buffer must have room for (`textlen` + 1) characters.
///
/// If the requested property is numerical, then it may be requested either as text or in its
/// binary form. To request the property as text, pass a text buffer as described above. To request
/// the property in binary form, `dest` should point to storage of sufficent size, and `textlen`
/// should be zero.
///
/// Non-text properties without textual representation, e.g. file handles, may only be requested
/// in binary form, i.e. `dest` must point to sufficient storage, and `textlen` must be zero.
///
/// \return If the parameter `textlen` is non-zero, which means that the property is requested in
/// string form, the function returns the length of the string, i.e. the character count excluding
/// the terminating null-character. If the parameter `textlen` is zero, which means that property
/// is requested in binary form, the return value is the size of the data in bytes.
///
/// If the property is text, and `textlen` is zero, the function fails and returns 0. The function
/// also fails and returns 0 if `textlen` is non-zero and the property requested can not be
/// expressed as text. It also returns 0 if the property is not defined.
///
/// \sa TView::TViewProp
//
int
TView::GetProperty(int index, void * dest, int textlen)
{
LPCTSTR src;
switch (index) {
case ViewClass:{
_USES_CONVERSION;
src = _A2W(_OBJ_FULLTYPENAME(this));
}
break;
case ViewName:
src = GetViewName();
break;
default:
TRACEX(OwlDocView, 0, _T("GetProperty(): ") \
_T("invalid property [") << index << _T("] specified!") );
return 0;
}
if (!textlen) {
TRACEX(OwlDocView, 0, _T("GetProperty(): 0-Length buffer specified!"));
return 0;
}
int srclen = src ? static_cast<int>(::_tcslen(src)) : 0;
if (textlen > srclen)
textlen = srclen;
if (textlen)
memcpy(dest, src, textlen*sizeof(tchar));
*((tchar *)dest + textlen) = 0;
return srclen;
}
//
/// Increments an internal count used by the Doc/View subsystem to identify each
/// view.
//
void
TView::BumpNextViewId()
{
if (++NextViewId < MinUniqueViewId)
NextViewId = MinUniqueViewId;
}
IMPLEMENT_ABSTRACT_STREAMABLE(TView);
#if OWL_PERSISTENT_STREAMS
//
//
//
void*
TView::Streamer::Read(ipstream& is, uint32 /*version*/) const
{
TView* o = GetObject();
bool hasViewMenu = is.readByte();
if (hasViewMenu) {
o->ViewMenu = new TMenuDescr;
is >> *o->ViewMenu;
}
else
o->ViewMenu = 0;
o->ViewBar = 0;
is >> o->ViewId;
is >> o->Doc;
is >> o->NextView;
return o;
}
//
//
//
void
TView::Streamer::Write(opstream& os) const
{
TView* o = GetObject();
os.writeByte(uint8(o->ViewMenu ? 1 : 0));
if (o->ViewMenu)
os << *o->ViewMenu;
os << o->ViewId;
os << o->Doc;
os << o->NextView;
}
#endif
//----------------------------------------------------------------------------
// TWindowView Implementation
//
DEFINE_RESPONSE_TABLE1(TWindowView, TWindow)
EV_VN_ISWINDOW,
END_RESPONSE_TABLE;
//
/// Constructs a TWindowView interface object associated with the window view. Sets
/// ViewId to NextViewId. Calls the associated document's AttachView() function (a
/// private TDocument function) to attach the view to the document.
//
TWindowView::TWindowView(TDocument& doc, TWindow* parent)
:
TWindow(parent, 0, doc.GetDocManager().GetApplication()),
TView(doc)
{
}
IMPLEMENT_STREAMABLE2(TWindowView, TWindow, TView);
#if OWL_PERSISTENT_STREAMS
//
//
//
void*
TWindowView::Streamer::Read(ipstream& is, uint32 /*version*/) const
{
ReadBaseObject((TWindow*)GetObject(), is);
ReadBaseObject((TView*)GetObject(), is);
return GetObject();
}
//
//
//
void
TWindowView::Streamer::Write(opstream& os) const
{
WriteBaseObject((TWindow*)GetObject(), os);
WriteBaseObject((TView*)GetObject(), os);
}
#endif
//----------------------------------------------------------------------------
// TDialogView Implementation
//
DEFINE_RESPONSE_TABLE1(TDialogView, TDialog)
EV_VN_ISWINDOW,
END_RESPONSE_TABLE;
//
//
//
TDialogView::TDialogView(TDocument& doc, TWindow* parent, TResId resId, TModule* module)
:
TDialog(parent, resId, module),
TView(doc)
{
}
//
TDialogView::TDialogView(TDocument& doc, TWindow* parent, const DLGTEMPLATE& dlgTemplate,
TAutoDelete del, TModule* module)
:
TDialog(parent, dlgTemplate, del, module),
TView(doc)
{
}
//
TDialogView::TDialogView(TDocument& doc, TWindow* parent, TModule* module,
HGLOBAL hTemplate, TAutoDelete del)
:
TDialog(hTemplate, parent, del, module),
TView(doc)
{
}
IMPLEMENT_STREAMABLE2(TDialogView, TDialog, TView);
#if OWL_PERSISTENT_STREAMS
//
//
//
void*
TDialogView::Streamer::Read(ipstream& is, uint32 /*version*/) const
{
ReadBaseObject((TDialog*)GetObject(), is);
ReadBaseObject((TView*)GetObject(), is);
return GetObject();
}
//
//
//
void
TDialogView::Streamer::Write(opstream& os) const
{
WriteBaseObject((TDialog*)GetObject(), os);
WriteBaseObject((TView*)GetObject(), os);
}
#endif
//----------------------------------------------------------------------------
} // OWL namespace
/* ========================================================================== */
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: Doc, NextView.
↑ V1004 The 'src' pointer was used unsafely after it was verified against nullptr. Check lines: 233, 237.