|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 2000.
//
// File: wregion.cxx
//
// Contents: Watch region list
//
// Classes: CWatchRegion
//
// History: 20-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <wregion.hxx>
#include <seglist.hxx>
#include "tblwindo.hxx"
//+-------------------------------------------------------------------------
//
// Member: CWatchRegion::CWatchRegion
//
// Synopsis: Assign default values
//
// History: 20-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
CWatchRegion::CWatchRegion ( ULONG mode) : _mode (mode), _chapter(0), _bookmark(0), _cRows(0), _pSegment (0) { }
//+-------------------------------------------------------------------------
//
// Member: CWatchList::CWatchList
//
// Synopsis: Initialize
//
// History: 20-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
CWatchList::CWatchList(CTableSegList& segList) : _segList(segList) { }
//+-------------------------------------------------------------------------
//
// Member: CWatchList::~CWatchList
//
// Synopsis: Deletes all watch regions
//
// History: 20-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
CWatchList::~CWatchList () { CWatchRegion* p; while ( (p = _list.Pop()) != 0) delete p; }
//+-------------------------------------------------------------------------
//
// Member: CWatchList::NewRegion
//
// Synopsis: Create new empty region
//
// History: 20-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
HWATCHREGION CWatchList::NewRegion (ULONG mode) { CWatchRegion* pRegion = new CWatchRegion(mode); _list.Add (pRegion); return (HWATCHREGION) pRegion; }
//+-------------------------------------------------------------------------
//
// Member: CWatchList::ChangeMode
//
// Synopsis: Change region mode
//
// History: 20-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
void CWatchList::ChangeMode ( HWATCHREGION hRegion, ULONG mode ) { CWatchRegion* pRegion = FindVerify (hRegion); pRegion->SetMode (mode); }
//+-------------------------------------------------------------------------
//
// Member: CWatchList::GetInfo, private
//
// Synopsis: GetInfo about a watch region
//
// History: 20-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
void CWatchList::GetInfo (HWATCHREGION hRegion, CI_TBL_CHAPT* pChapter, CI_TBL_BMK* pBookmark, DBCOUNTITEM* pcRows) { CWatchRegion* pRegion = FindVerify (hRegion); *pChapter = pRegion->Chapter(); *pBookmark = pRegion->Bookmark(); *pcRows = pRegion->RowCount(); }
//+-------------------------------------------------------------------------
//
// Member: CWatchList::BuildRegion
//
// Synopsis: Build watch region
//
// History: 22-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
void CWatchList::BuildRegion ( HWATCHREGION hRegion, CTableSegment* pSegment, CI_TBL_CHAPT chapter, CI_TBL_BMK bookmark, LONG cRows ) { Win4Assert (cRows > 0); CWatchRegion* pRegion = FindVerify (hRegion); pRegion->SetSegment(pSegment); pRegion->Set (chapter, bookmark, cRows); CDoubleTableSegIter iter (pSegment); CTableWindow* pWindow = iter.GetWindow();
// Add watch to the first window in series
int cRowsAdded; if (bookmark == WORKID_TBLFIRST) { cRowsAdded = pWindow->AddWatch (hRegion, 0, cRows, _segList.IsLast(iter)); } else { TBL_OFF off; ULONG uiStart; if ( !pWindow->FindBookMark( bookmark, off, uiStart)) { Win4Assert (!"CWatchList::BuildRegion, bookmark not found" ); }
cRowsAdded = pWindow->AddWatch (hRegion, (long)uiStart, cRows, _segList.IsLast(iter)); }
while (cRowsAdded < cRows) { // continue through another segment
_segList.Advance(iter); Win4Assert ( iter.GetSegment()->IsWindow()); pWindow = iter.GetWindow(); cRowsAdded += pWindow->AddWatch (hRegion, 0, cRows - cRowsAdded, _segList.IsLast(iter)); } }
//+-------------------------------------------------------------------------
//
// Member: CWatchList::DeleteRegion
//
// Synopsis: Delete watch region
//
// History: 20-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
void CWatchList::DeleteRegion (HWATCHREGION hRegion) { ShrinkRegionToZero (hRegion); CWatchRegion* pRegion = GetRegion(hRegion); pRegion->Unlink(); delete pRegion; }
//+-------------------------------------------------------------------------
//
// Member: CWatchList::ShrinkRegionToZero
//
// Synopsis: Shrink watch region to zero but don't delete it
// (e.g., prepare to move the region discontinuously)
//
// History: 27-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
void CWatchList::ShrinkRegionToZero (HWATCHREGION hRegion) { CWatchRegion* pRegion = FindVerify (hRegion);
if (pRegion->Segment()) { CDoubleTableSegIter iter (pRegion->Segment()); long cRowsLeft = pRegion->RowCount(); do { CTableWindow* pWindow = iter.GetWindow(); cRowsLeft -= pWindow->DeleteWatch (pRegion->Handle());
if (cRowsLeft <= 0 ) break; _segList.Advance(iter); } while (!_segList.AtEnd(iter)); }
pRegion->SetSegment(0); }
//+-------------------------------------------------------------------------
//
// Member: CWatchList::ShrinkRegion
//
// Synopsis: Shrink watch region
//
// History: 20-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
void CWatchList::ShrinkRegion ( HWATCHREGION hRegion, CI_TBL_CHAPT chapter, CI_TBL_BMK bookmark, LONG cRows ) { // Werify arguments
if (cRows < 0) { THROW (CException(E_INVALIDARG)); } else if ( cRows == 0) { DeleteRegion (hRegion); return; }
// BROKENCODE: verify validity of chapter / bookmark
CWatchRegion* pRegion = FindVerify (hRegion); long cRowsLeft = pRegion->RowCount(); if (cRows > cRowsLeft) { THROW (CException(DB_E_NOTASUBREGION)); }
// Find starting window of the old region
if (pRegion->Segment() == 0) THROW (CException(E_INVALIDARG)); CDoubleTableSegIter iter (pRegion->Segment());
// find starting window of the new region
CTableWindow* pWindowBmk = 0;
if (bookmark == WORKID_TBLFIRST) { CTableSegment* pSeg = _segList.GetTop(); if (!pSeg->IsWindow()) { THROW (CException(DB_E_NOTASUBREGION)); } pWindowBmk = (CTableWindow*) pSeg; } else { CDoubleTableSegIter iter2 (iter.GetSegment()); // clone it
do { if ( iter2.GetSegment()->IsRowInSegment( bookmark ) ) break; _segList.Advance(iter2); } while (!_segList.AtEnd(iter2));
if (_segList.AtEnd(iter2)) { THROW (CException(DB_E_NOTASUBREGION)); }
pWindowBmk = iter2.GetWindow();
if (!pWindowBmk->IsWatched (hRegion, bookmark)) { THROW (CException(DB_E_NOTASUBREGION)); } }
// Real work starts here
// we know that the bookmark is within the old watch region
// delete watch regions before the bookmark
CTableWindow* pWindow = iter.GetWindow(); while ( pWindow != pWindowBmk) { cRowsLeft -= pWindow->DeleteWatch (hRegion); Win4Assert (cRowsLeft > 0); _segList.Advance(iter); Win4Assert (!_segList.AtEnd(iter)); pWindow = iter.GetWindow(); }
// Beginning of new region
pRegion->SetSegment (pWindow);
// Shrink the watch in the first window in series
long cRowsInRegion = 0;
cRowsInRegion = pWindow->ShrinkWatch( hRegion, bookmark, cRows );
// continue through windows that will stay in the watch region
while (cRowsInRegion < cRows) { _segList.Advance(iter);
if (_segList.AtEnd(iter) || !iter.GetSegment()->IsWindow() || !iter.GetWindow()->HasWatch(hRegion)) { // Leave in consistent state
pRegion->Set (chapter, bookmark, cRowsInRegion); THROW (CException(DB_E_NOTASUBREGION)); }
// the watch continues in this window
pWindow = iter.GetWindow(); cRowsInRegion += pWindow->RowsWatched (hRegion); }
// Shrink the last segment of the new watch region
if (cRowsInRegion > cRows) { long cDelta = cRowsInRegion-cRows; long cRowsRemaining = pWindow->RowsWatched(hRegion) - cDelta; Win4Assert( cRowsRemaining > 0 );
pWindow->ShrinkWatch( hRegion, cRowsRemaining); }
pRegion->Set (chapter, bookmark, cRows);
// delete the rest of the old watch region
for ( _segList.Advance(iter); !_segList.AtEnd(iter) && iter.GetSegment()->IsWindow() && iter.GetWindow()->HasWatch(hRegion); _segList.Advance(iter) ) { // the watch continues in this window
iter.GetWindow()->DeleteWatch (hRegion); }
#if CIDBG==1
CheckRegionConsistency( pRegion ); #endif // CIDBG==1
}
//+---------------------------------------------------------------------------
//
// Function: FindRegion
//
// Synopsis:
//
// Arguments: [hRegion] -
//
// Returns:
//
// Modifies:
//
// History: 7-05-95 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
CWatchRegion * CWatchList::FindRegion(HWATCHREGION hRegion) { for (CWatchIter iter(_list); !_list.AtEnd(iter); _list.Advance(iter)) { if (iter->IsEqual(hRegion)) break; }
if (_list.AtEnd(iter)) { return 0; } else { return iter.Get(); } }
//+-------------------------------------------------------------------------
//
// Member: CWatchList::FindVerify
//
// Synopsis: Find watch region, throw if not found
//
// History: 20-Jun-95 BartoszM Created
//
//--------------------------------------------------------------------------
CWatchRegion* CWatchList::FindVerify (HWATCHREGION hRegion) { CWatchRegion * pRegion = FindRegion( hRegion );
if ( 0 != pRegion ) { return pRegion; } else { THROW (CException(DB_E_BADREGIONHANDLE)); }
return 0; // Keep the compiler happy
}
//+---------------------------------------------------------------------------
//
// Member: CWatchRegion::UpdateSegment
//
// Synopsis: Updates the segment in the region to point to the new one
// if the current one is same as pOld.
//
// Arguments: [pOld] -
// [pNew] -
//
// History: 8-16-95 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
void CWatchRegion::UpdateSegment( CTableSegment * pOld, CTableWindow *pNew, CI_TBL_BMK bmkNew ) { Win4Assert( 0 != pNew );
if ( _pSegment == pOld ) { Win4Assert( pNew->HasWatch( Handle()) ); _pSegment = pNew;
// NEWFEATURE - how about chapter ??
_bookmark = bmkNew; } }
#if CIDBG == 1
//+---------------------------------------------------------------------------
//
// Member: CWatchList::CheckRegionConsistency
//
// Synopsis: Checks that the length of the region as stored in the
// region is same as the cumulative length of all the watch
// in the windows.
//
// Arguments: [pRegion] - Region which must be checked.
//
// History: 8-16-95 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
void CWatchList::CheckRegionConsistency( CWatchRegion * pRegion ) { if ( 0 != pRegion && 0 != pRegion->Segment() ) { HWATCHREGION hRegion = pRegion->Handle();
CDoubleTableSegIter iter( pRegion->Segment() ); for ( long cRegionLen = 0; !_segList.AtEnd(iter) && iter.GetSegment()->IsWindow() && iter.GetWindow()->HasWatch(hRegion); _segList.Advance(iter) ) { CTableWindow * pWindow = iter.GetWindow(); long cRowsInWindow = pWindow->RowsWatched(hRegion); Win4Assert( cRowsInWindow >= 0 ); cRegionLen += cRowsInWindow; }
Win4Assert( cRegionLen == pRegion->RowCount() ); } }
#endif // CIDBG==1
|