Files
TeslaRel410/BORLAND/BC45/SOURCE/OWL/LISTVIEW.CPP
T
CydandClaude Fable 5 63312e07f9 source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived
- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
  is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
  Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
  (extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
  BT game source (never mixed into CODE/). Round 1-3 state:
  * 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
    (BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
    since 1996.
  * BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
    its binary-recorded line 400 exactly.
  * BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
    (Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
    TeamScore=12 flagged [T4]).
  * MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
    (VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
    the period compiler is the drift detector).
  * Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
    (per-TU verification sweep under authentic OPT.MAK flags).
  * README: corrected roadmap - MECH.HPP is the capstone grown with the mech
    TU reconstructions; BTREG.CPP green = the header-family milestone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 07:33:26 -05:00

356 lines
8.2 KiB
C++

//----------------------------------------------------------------------------
// ObjectWindows
// (C) Copyright 1993, 1994 by Borland International, All Rights Reserved
//
// Implements class TListView
//----------------------------------------------------------------------------
#pragma hdrignore SECTION
#include <owl/owlpch.h>
#include <owl/listview.h>
#include <owl/listview.rh>
#include <owl/docview.rh>
#include <owl/inputdia.h>
DIAG_DECLARE_GROUP(OwlDocView); // General Doc/View diagnostic group
#if !defined(SECTION) || SECTION == 1
const char VirtualLastLineStr[] = "---"; // Last virtual line appended to list
// class TListView
// ----- ---------
//
DEFINE_RESPONSE_TABLE1(TListView, TListBox)
EV_COMMAND(CM_EDITUNDO, CmEditUndo),
EV_COMMAND(CM_EDITCUT, CmEditCut),
EV_COMMAND(CM_EDITCOPY, CmEditCopy),
EV_COMMAND(CM_EDITPASTE, CmEditPaste),
EV_COMMAND(CM_EDITCLEAR, CmEditClear),
EV_COMMAND(CM_EDITDELETE, CmEditDelete),
EV_COMMAND(CM_EDITADD, CmEditAdd),
EV_COMMAND(CM_EDITEDIT, CmEditItem),
EV_WM_GETDLGCODE,
EV_NOTIFY_AT_CHILD(LBN_DBLCLK, CmEditItem),
EV_NOTIFY_AT_CHILD(LBN_SELCHANGE, CmSelChange),
EV_VN_DOCCLOSED,
EV_VN_ISWINDOW,
EV_VN_ISDIRTY,
EV_VN_COMMIT,
EV_VN_REVERT,
END_RESPONSE_TABLE;
TListView::TListView(TDocument& doc, TWindow* parent)
:
TView(doc),
TListBox(parent, GetNextViewId(), 0,0,0,0),
Origin(0),
MaxWidth(0),
DirtyFlag(false)
{
Attr.Style &= ~(LBS_SORT);
Attr.Style |= (WS_HSCROLL | LBS_NOINTEGRALHEIGHT);
Attr.AccelTable = IDA_LISTVIEW;
if (::FindResource(*GetModule(), TResId(IDM_LISTVIEW), RT_MENU))
SetViewMenu(new TMenuDescr(IDM_LISTVIEW, 0,1,0,0,0,1, GetModule()));
}
int
TListView::AddString(const char far* str)
{
long style = GetWindowLong(GWL_STYLE);
if (!(style & LBS_SORT)) {
int itemsInListBox = GetCount();
if (itemsInListBox > 0) {
// before the end of list marker
return InsertString(str, itemsInListBox-1);
}
}
return TListBox::AddString(str);
}
void
TListView::SetExtent(const char far* str)
{
int len;
if ((len = strlen(str)) == 0)
return;
HDC hdc = ::GetDC(HWindow);
TSize extent;
::GetTextExtentPoint(hdc, str, len, &extent);
extent.cx += 2; // room for focus rectangle
if (extent.cx > MaxWidth)
SetHorizontalExtent(MaxWidth = extent.cx);
::ReleaseDC(HWindow, hdc);
}
bool
TListView::VnDocClosed(int omode)
{
if (DirtyFlag == 2 || !(omode & ofWrite)) // make sure someone else's write
return false;
int top = GetTopIndex();
int sel = GetSelIndex();
LoadData(top, sel);
return true;
}
bool
TListView::LoadData(int top, int sel)
{
CmEditClear(); // Clear list & remove virtual last line temporarily
DeleteString(0);
long style = GetWindowLong(GWL_STYLE);
if (!(style & LBS_SORT))
TListBox::AddString(VirtualLastLineStr); // Append virtual last line
DirtyFlag = false;
bool status = true;
istream* inStream;
if ((inStream = Doc->InStream(ios::in)) == 0) {
Doc->PostError(IDS_UNABLEOPEN, MB_OK);
return false;
}
for (;;) {
char buf[100+1];
inStream->getline(buf, sizeof(buf)-1);
if (!inStream->gcount() && !inStream->good()) {
status = ToBool(inStream->eof());
break;
}
AddString(buf);
SetExtent(buf);
}
SetTopIndex(top);
SetSelIndex(sel);
delete inStream; // close file in case process switch
if (!status)
Doc->PostError(IDS_READERROR, MB_OK);
return status;
}
bool
TListView::Create()
{
TRY {
TListBox::Create(); // throws exception TWindow::TXWindow
}
CATCH( (TXOwl& x) {
Doc->PostError(IDS_NOMEMORYFORVIEW, MB_OK);
return true; // cannot return false - throws another exception
})
if (Doc->GetDocPath() == 0) {
CmEditClear(); // perform any clearing initialization
return true; // new file, no data to display
}
if (!LoadData(0, 0))
NotOK();
return true;
}
bool
TListView::VnCommit(bool force)
{
if (!force && !DirtyFlag)
return true;
ostream* outStream = Doc->OutStream(ios::out);
if (outStream == 0) {
Doc->PostError(IDS_UNABLEOPEN, MB_OK);
return false;
}
outStream->seekp(Origin);
int count = GetCount();
for (int index = 0; index < count-1; index++) { // don't write last virtual line
int len = GetStringLen(index);
char* buf = new char[len+1];
GetString(buf, index);
*outStream << buf << '\n';
delete buf;
}
DirtyFlag = 2; // to detect our own close notification
bool status = ToBool(outStream->good());
delete outStream;
DirtyFlag = false;
if (!status)
Doc->PostError(IDS_WRITEERROR, MB_OK);
return status;
}
bool
TListView::VnRevert(bool clear)
{
if (!clear && Doc->GetDocPath() != 0)
return LoadData(0,0);
CmEditClear();
DirtyFlag = false;
return true;
}
uint
TListView::EvGetDlgCode(MSG far*)
{
uint retVal = (uint)DefaultProcessing();
retVal |= DLGC_WANTCHARS;
return retVal;
}
void
TListView::CmEditUndo()
{
MessageBox("Feature not implemented", "Undo", MB_OK);
}
void
TListView::CmEditCut()
{
CmEditCopy();
CmEditDelete();
}
void
TListView::CmEditCopy()
{
int index = GetSelIndex();
int count = GetCount();
if (count <= 1 || index >= count-1)
return;
TClipboard cb(*this);
if (cb.EmptyClipboard()) {
int len = GetStringLen(index);
HANDLE cbhdl = ::GlobalAlloc(GHND,len+0+1);
char far* buf = (char far*)::GlobalLock(cbhdl);
GetString(buf, index);
::GlobalUnlock(cbhdl);
cb.SetClipboardData(CF_TEXT, cbhdl);
}
}
void
TListView::CmEditPaste()
{
int index = GetSelIndex();
if (index < 0)
index = 0;
TClipboard cb(*this);
if (!cb)
return; // clipboard open by another program
HANDLE cbhdl = cb.GetClipboardData(CF_TEXT);
if (cbhdl) {
char far* text = (char far*)::GlobalLock(cbhdl);
InsertString(text, index);
SetSelIndex(index+1);
DirtyFlag = true;
::GlobalUnlock(cbhdl);
}
}
void
TListView::CmEditDelete()
{
int count = GetCount();
int index = GetSelIndex();
if (count <= 1 || index >= count-1)
return;
DeleteString(index);
SetSelIndex(index);
DirtyFlag = true;
}
void
TListView::CmEditClear()
{
int count = GetCount();
if (count == 1)
return;
if (count) {
ClearList();
DirtyFlag = true;
SetHorizontalExtent(MaxWidth = 0);
}
long style = GetWindowLong(GWL_STYLE);
if (!(style & LBS_SORT))
TListBox::AddString(VirtualLastLineStr);
}
static int linePrompt(TWindow* parent, int index, UINT id,
char far* buf, int buflen)
{
char msg[41];
wsprintf(msg, parent->GetModule()->LoadString(IDS_LISTNUM).c_str(), index);
return TInputDialog(parent, msg,
parent->GetModule()->LoadString(id).c_str(),
buf, buflen).Execute();
}
void
TListView::CmEditAdd()
{
char inputText[101];
*inputText = 0;
int index = GetSelIndex();
if (index < 0)
index = 0;
if (linePrompt(this,index+1,CM_EDITADD,inputText,sizeof(inputText)) == IDOK) {
InsertString(inputText, index);
SetSelIndex(index+1);
SetExtent(inputText);
DirtyFlag = true;
}
}
void
TListView::CmEditItem()
{
int index = GetSelIndex();
if (index < 0 || index >= GetCount()-1)
return;
char inputText[101];
GetSelString(inputText, sizeof(inputText)-1);
if (linePrompt(this,index+1,CM_EDITEDIT,inputText,sizeof(inputText))==IDOK) {
DeleteString(index);
InsertString(inputText, index);
SetExtent(inputText);
SetSelIndex(index);
DirtyFlag = true;
}
}
#endif
#if !defined(SECTION) || SECTION == 2
IMPLEMENT_STREAMABLE2(TListView, TListBox, TView);
void*
TListView::Streamer::Read(ipstream& is, uint32 /*version*/) const
{
ReadBaseObject((TListBox*)GetObject(), is);
ReadBaseObject((TView*)GetObject(), is);
is >> GetObject()->Origin;
return GetObject();
}
void
TListView::Streamer::Write(opstream &os) const
{
WriteBaseObject((TListBox*)GetObject(), os);
WriteBaseObject((TView*)GetObject(), os);
os << GetObject()->Origin;
}
#endif