summaryrefslogtreecommitdiff
path: root/svtools/source/brwbox/brwbox1.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/brwbox/brwbox1.cxx')
-rw-r--r--svtools/source/brwbox/brwbox1.cxx2396
1 files changed, 2396 insertions, 0 deletions
diff --git a/svtools/source/brwbox/brwbox1.cxx b/svtools/source/brwbox/brwbox1.cxx
new file mode 100644
index 000000000000..53c90ed1e64a
--- /dev/null
+++ b/svtools/source/brwbox/brwbox1.cxx
@@ -0,0 +1,2396 @@
+/*************************************************************************
+ *
+ * $RCSfile: brwbox1.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:58:56 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <brwbox.hxx>
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <vcl/sound.hxx>
+#include "brwhead.hxx"
+#include "datwin.hxx"
+
+#pragma hdrstop
+
+#ifndef _SV_MULTISEL_HXX
+#include <tools/multisel.hxx>
+#endif
+
+DBG_NAME(BrowseBox);
+
+extern const char* BrowseBoxCheckInvariants( const void* pVoid );
+
+DECLARE_LIST( BrowserColumns, BrowserColumn* );
+
+#ifdef VCL
+#define SCROLL_FLAGS (SCROLL_CLIP | SCROLL_NOCHILDREN)
+#else
+#define SCROLL_FLAGS TRUE
+#endif
+
+//-------------------------------------------------------------------
+
+#if DBG_MI
+void DoLog_Impl( const BrowseBox *pThis, const char *pWhat, const char *pWho )
+{
+ SvFileStream aLog( "d:\\cursor.log", STREAM_WRITE|STREAM_NOCREATE );
+ if ( aLog.IsOpen() )
+ {
+ aLog.Seek( STREAM_SEEK_TO_END );
+ String aEntry( (long) pThis );
+ aEntry += "(row=";
+ aEntry += pThis->GetCurRow();
+ aEntry += "): ";
+ aEntry += pWhat;
+ aEntry += " from ";
+ aEntry += pWho;
+ aEntry += " => ";
+ aEntry += pThis->GetCursorHideCount();
+ aLog.WriteLine( aEntry );
+ }
+}
+#endif
+
+//===================================================================
+
+void BrowseBox::Construct( BrowserMode nMode )
+{
+ DBG_TRACE1( "BrowseBox: %p->Construct", this );
+ bMultiSelection = FALSE;
+ pColSel = 0;
+ pDataWin = 0;
+ pVScroll = 0;
+
+ pDataWin = new BrowserDataWin( this );
+ pCols = new BrowserColumns;
+
+ aLineColor = Color( COL_LIGHTGRAY );
+ InitSettings_Impl( this );
+ InitSettings_Impl( pDataWin );
+
+ bBootstrapped = FALSE;
+ bHasBitmapHandle = FALSE;
+ nDataRowHeight = 0;
+ nTitleLines = 1;
+ nFirstCol = 0;
+ nTopRow = 0;
+ nCurRow = BROWSER_ENDOFSELECTION;
+ nCurColId = 0;
+ bResizing = FALSE;
+ bSelect = FALSE;
+ bSelecting = FALSE;
+ bScrolling = FALSE;
+ bSelectionIsVisible = FALSE;
+ bNotToggleSel = FALSE;
+ bDrag = FALSE;
+ bHit = FALSE;
+ bRubber = FALSE;
+ bHideSelect = FALSE;
+ bHideCursor = FALSE;
+ nRowCount = 0;
+ m_bFocusOnlyCursor = TRUE;
+ m_aCursorColor = COL_TRANSPARENT;
+ m_nCurrentMode = 0;
+
+ aHScroll.SetLineSize(1);
+ aHScroll.SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
+ aHScroll.SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
+ pDataWin->Show();
+
+ SetMode( nMode );
+ bSelectionIsVisible = bKeepHighlight;
+ bHasFocus = HasChildPathFocus();
+ ((BrowserDataWin*)pDataWin)->nCursorHidden =
+ ( bHasFocus ? 0 : 1 ) + ( GetUpdateMode() ? 0 : 1 );
+ LOG( this, "Construct", "*" );
+}
+
+//-------------------------------------------------------------------
+
+BrowseBox::BrowseBox( Window* pParent, WinBits nBits, BrowserMode nMode ) :
+ Control( pParent, nBits | WB_3DLOOK ),
+ aHScroll( this, WinBits( WB_HSCROLL ) )
+{
+ DBG_CTOR( BrowseBox, NULL );
+ Construct( nMode );
+}
+
+//-------------------------------------------------------------------
+
+BrowseBox::BrowseBox( Window* pParent, const ResId& rId, BrowserMode nMode ):
+ Control( pParent, rId ),
+ aHScroll( this, WinBits(WB_HSCROLL) )
+{
+ DBG_CTOR( BrowseBox, NULL );
+ Construct(nMode);
+}
+
+//-------------------------------------------------------------------
+
+BrowseBox::~BrowseBox()
+{
+ DBG_DTOR(BrowseBox,BrowseBoxCheckInvariants);
+ DBG_TRACE1( "BrowseBox: %p~", this );
+
+ Hide();
+ delete ((BrowserDataWin*)pDataWin)->pHeaderBar;
+ delete ((BrowserDataWin*)pDataWin)->pCornerWin;
+ delete pDataWin;
+ delete pVScroll;
+
+ // free columns-space
+ for ( USHORT n = 0; n < pCols->Count(); ++n )
+ delete pCols->GetObject(n);
+ delete pCols;
+ delete pColSel;
+ if ( bMultiSelection )
+ delete uRow.pSel;
+}
+
+//-------------------------------------------------------------------
+
+short BrowseBox::GetCursorHideCount() const
+{
+ return ((BrowserDataWin*)pDataWin)->nCursorHidden;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::DoShowCursor( const char *pWhoLogs )
+{
+ short nHiddenCount = --((BrowserDataWin*)pDataWin)->nCursorHidden;
+ if (PaintCursorIfHiddenOnce())
+ {
+ if (1 == nHiddenCount)
+ DrawCursor();
+ }
+ else
+ {
+ if (0 == nHiddenCount)
+ DrawCursor();
+ }
+ LOG( this, "DoShowCursor", pWhoLogs );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::DoHideCursor( const char *pWhoLogs )
+{
+ short nHiddenCount = ++((BrowserDataWin*)pDataWin)->nCursorHidden;
+ if (PaintCursorIfHiddenOnce())
+ {
+ if (2 == nHiddenCount)
+ DrawCursor();
+ }
+ else
+ {
+ if (1 == nHiddenCount)
+ DrawCursor();
+ }
+ LOG( this, "DoHideCursor", pWhoLogs );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetRealRowCount( const String &rRealRowCount )
+{
+ ((BrowserDataWin*)pDataWin)->aRealRowCount = rRealRowCount;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetMapMode( const MapMode& rNewMapMode )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ pDataWin->SetMapMode( rNewMapMode );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetFont( const Font& rNewFont )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ pDataWin->SetFont( rNewFont );
+ ImpGetDataRowHeight();
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::InsertHandleColumn( ULONG nWidth, BOOL bBitmap )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ pCols->Insert( new BrowserColumn( 0, Image(), String(), nWidth, GetZoom(), 0 ), (ULONG) 0 );
+ FreezeColumn( 0 );
+
+ // Headerbar anpassen
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ {
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->SetPosPixel(
+ Point(nWidth, 0));
+
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->SetSizePixel(
+ Size( GetOutputSizePixel().Width() - nWidth, GetTitleHeight() ) );
+ }
+
+ /*if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->InsertItem( USHRT_MAX - 1,
+ "", nWidth, HIB_FIXEDPOS|HIB_FIXED, 0 );*/
+ ColumnInserted( 0 );
+ bHasBitmapHandle = bBitmap;
+}
+
+//-------------------------------------------------------------------
+#if SUPD<380
+void BrowseBox::InsertDataColumn( USHORT nItemId, const String &rTitle,
+ ULONG nWidth, BrowserColumnMode nFlags, USHORT nPos )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ pCols->Insert( new BrowserColumn( nItemId, Image(), rTitle, nWidth, GetZoom(), nFlags ),
+ Min( nPos, (USHORT)(pCols->Count()) ) );
+ if ( nCurColId == 0 )
+ nCurColId = nItemId;
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->InsertItem(
+ nItemId, rTitle, nWidth, HIB_STDSTYLE, nPos );
+ ColumnInserted( nPos );
+}
+#else
+//-------------------------------------------------------------------
+
+void BrowseBox::InsertDataColumn( USHORT nItemId, const Image& rImage,
+ long nWidth, HeaderBarItemBits nBits, USHORT nPos )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ pCols->Insert( new BrowserColumn( nItemId, rImage, String(), nWidth, GetZoom(), nBits ),
+ Min( nPos, (USHORT)(pCols->Count()) ) );
+ if ( nCurColId == 0 )
+ nCurColId = nItemId;
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ {
+ // Handlecolumn nicht in der Headerbar
+ USHORT nHeaderPos = nPos;
+ if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
+ nHeaderPos--;
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->InsertItem(
+ nItemId, rImage, nWidth, nBits, nHeaderPos );
+ }
+ ColumnInserted( nPos );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::InsertDataColumn( USHORT nItemId, const XubString& rText,
+ long nWidth, HeaderBarItemBits nBits, USHORT nPos )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ pCols->Insert( new BrowserColumn( nItemId, Image(), rText, nWidth, GetZoom(), nBits ),
+ Min( nPos, (USHORT)(pCols->Count()) ) );
+ if ( nCurColId == 0 )
+ nCurColId = nItemId;
+
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ {
+ // Handlecolumn nicht in der Headerbar
+ USHORT nHeaderPos = nPos;
+ if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
+ nHeaderPos--;
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->InsertItem(
+ nItemId, rText, nWidth, nBits, nHeaderPos );
+ }
+ ColumnInserted( nPos );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::InsertDataColumn( USHORT nItemId,
+ const Image& rImage, const XubString& rText,
+ long nWidth, HeaderBarItemBits nBits, USHORT nPos,
+ const String* pHelpText )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ pCols->Insert( new BrowserColumn( nItemId, rImage, rText, nWidth, GetZoom(), nBits ),
+ Min( nPos, (USHORT)(pCols->Count()) ) );
+ if ( nCurColId == 0 )
+ nCurColId = nItemId;
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ {
+ // Handlecolumn nicht in der Headerbar
+ USHORT nHeaderPos = nPos;
+ if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
+ nHeaderPos--;
+
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->InsertItem(
+ nItemId, rImage, rText, nWidth, nBits, nHeaderPos );
+ if( pHelpText && !rText.Len() )
+ {
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->SetHelpText(
+ nItemId, *pHelpText );
+ }
+ }
+ ColumnInserted( nPos );
+}
+#endif
+//-------------------------------------------------------------------
+
+void BrowseBox::FreezeColumn( USHORT nItemId, BOOL bFreeze )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // never unfreeze the handle-column
+ if ( nItemId == 0 && !bFreeze )
+ return;
+
+ // get the position in the current array
+ USHORT nItemPos = GetColumnPos( nItemId );
+ if ( nItemPos >= pCols->Count() )
+ // not available!
+ return;
+
+ // doesn't the state change?
+ if ( pCols->GetObject(nItemPos)->IsFrozen() == bFreeze )
+ return;
+
+ // remark the column selection
+ USHORT nSelectedColId = USHRT_MAX;
+ if ( pColSel && pColSel->GetSelectCount() )
+ {
+ DoHideCursor( "FreezeColumn" );
+ ToggleSelection();
+ nSelectedColId = pCols->GetObject(pColSel->FirstSelected())->GetId();
+ pColSel->SelectAll(FALSE);
+ }
+
+ // freeze or unfreeze?
+ if ( bFreeze )
+ {
+ // to be moved?
+ if ( nItemPos != 0 && !pCols->GetObject(nItemPos-1)->IsFrozen() )
+ {
+ // move to the right of the last frozen column
+ USHORT nFirstScrollable = FrozenColCount();
+ BrowserColumn *pColumn = pCols->GetObject(nItemPos);
+ pCols->Remove( (ULONG) nItemPos );
+ nItemPos = nFirstScrollable;
+ pCols->Insert( pColumn, (ULONG) nItemPos );
+ }
+
+ // adjust the number of the first scrollable and visible column
+ if ( nFirstCol <= nItemPos )
+ nFirstCol = nItemPos + 1;
+ }
+ else
+ {
+ // to be moved?
+ if ( nItemPos != FrozenColCount()-1 )
+ {
+ // move to the leftmost scrollable colum
+ USHORT nFirstScrollable = FrozenColCount();
+ BrowserColumn *pColumn = pCols->GetObject(nItemPos);
+ pCols->Remove( (ULONG) nItemPos );
+ nItemPos = nFirstScrollable;
+ pCols->Insert( pColumn, (ULONG) nItemPos );
+ }
+
+ // adjust the number of the first scrollable and visible column
+ nFirstCol = nItemPos;
+ }
+
+ // toggle the freeze-state of the column
+ pCols->GetObject(nItemPos)->Freeze( bFreeze );
+
+ // align the scrollbar-range
+ UpdateScrollbars();
+
+ // repaint
+ Control::Invalidate();
+ ((BrowserDataWin*)pDataWin)->Invalidate();
+
+ // remember the column selection
+ if ( pColSel && nSelectedColId != USHRT_MAX )
+ {
+ pColSel->Select( GetColumnPos( nSelectedColId ) );
+ ToggleSelection();
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+ DoShowCursor( "FreezeColumn" );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetColumnPos( USHORT nColumnId, USHORT nPos )
+{
+ // never set pos of the handle-column
+ if ( nColumnId == 0 )
+ return;
+
+ // do not move handle column
+ if (nPos == 0 && !pCols->GetObject(0)->GetId())
+ return;
+
+ // get the position in the current array
+ USHORT nOldPos = GetColumnPos( nColumnId );
+ if ( nOldPos >= pCols->Count() )
+ // not available!
+ return;
+
+ // does the state change?
+ BrowserColumn *pCol = pCols->GetObject(nOldPos);
+ if (nOldPos != nPos)
+ {
+ // determine old column area
+ Size aDataWinSize( pDataWin->GetSizePixel() );
+ Rectangle aFromRect( GetFieldRect( nColumnId) );
+
+ // move column internally
+ pCols->Insert( pCols->Remove( nOldPos ), nPos );
+
+ // determine new column area
+ Rectangle aToRect( GetFieldRect( nColumnId ) );
+
+ // do scroll, let redraw
+ Rectangle aForNewArea( Point( aToRect.Left(), 0 ),
+ Size( aDataWinSize.Width() - aToRect.Left(),
+ aDataWinSize.Height() ) );
+ Rectangle aForOldArea( Point( aFromRect.Right(), 0 ),
+ Size( aDataWinSize.Width() - aFromRect.Right(),
+ aDataWinSize.Height() ) );
+
+ if( pDataWin->GetBackground().IsScrollable() )
+ {
+ if ( nOldPos > nPos )
+ pDataWin->Scroll( -aFromRect.GetWidth()-4, 0, aForOldArea );
+ pDataWin->Scroll( aToRect.GetWidth()+4, 0, aForNewArea );
+ if ( nOldPos < nPos )
+ pDataWin->Scroll( -aFromRect.GetWidth()-4, 0, aForOldArea );
+ }
+ else
+ pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
+ }
+
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetColumnMode( USHORT nColumnId, BrowserColumnMode nFlags )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // never set mode of the handle-column
+ if ( nColumnId == 0 )
+ return;
+
+ // get the position in the current array
+ USHORT nColumnPos = GetColumnPos( nColumnId );
+ if ( nColumnPos >= pCols->Count() )
+ // not available!
+ return;
+
+ // does the state change?
+ BrowserColumn *pCol = pCols->GetObject(nColumnPos);
+ if ( pCol->Flags() != nFlags )
+ {
+ pCol->Flags() = nFlags;
+
+ // redraw visible colums
+ if ( GetUpdateMode() && ( pCol->IsFrozen() || nColumnPos > nFirstCol ) )
+ Invalidate( Rectangle( Point(0,0),
+ Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetColumnTitle( USHORT nItemId, const String& rTitle )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // never set title of the handle-column
+ if ( nItemId == 0 )
+ return;
+
+ // get the position in the current array
+ USHORT nItemPos = GetColumnPos( nItemId );
+ if ( nItemPos >= pCols->Count() )
+ // not available!
+ return;
+
+ // does the state change?
+ BrowserColumn *pCol = pCols->GetObject(nItemPos);
+ if ( pCol->Title() != rTitle )
+ {
+ pCol->Title() = rTitle;
+
+ // Headerbar-Column anpassen
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->SetItemText(
+ nItemId ? nItemId : USHRT_MAX - 1, rTitle );
+ else
+ {
+ // redraw visible colums
+ if ( GetUpdateMode() && ( pCol->IsFrozen() || nItemPos > nFirstCol ) )
+ Invalidate( Rectangle( Point(0,0),
+ Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
+ }
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetColumnWidth( USHORT nItemId, ULONG nWidth )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // get the position in the current array
+ USHORT nItemPos = GetColumnPos( nItemId );
+ if ( nItemPos >= pCols->Count() )
+ return;
+
+ // does the state change?
+ nWidth = QueryColumnResize( nItemId, nWidth );
+ if ( nWidth >= LONG_MAX || pCols->GetObject(nItemPos)->Width() != nWidth )
+ {
+ long nOldWidth = pCols->GetObject(nItemPos)->Width();
+
+ // ggf. letzte Spalte anpassen
+ if ( IsVisible() && nItemPos == pCols->Count() - 1 )
+ {
+ long nMaxWidth = pDataWin->GetSizePixel().Width();
+ nMaxWidth -= ((BrowserDataWin*)pDataWin)->bAutoSizeLastCol
+ ? GetFieldRect(nItemId).Left()
+ : GetFrozenWidth();
+ if ( ( (BrowserDataWin*)pDataWin )->bAutoSizeLastCol || nWidth > (ULONG)nMaxWidth )
+ {
+ nWidth = nMaxWidth > 16 ? nMaxWidth : nOldWidth;
+ nWidth = QueryColumnResize( nItemId, nWidth );
+ }
+ }
+
+ // OV
+ // In AutoSizeLastColumn() wird SetColumnWidth mit nWidth==0xffff
+ // gerufen. Deshalb muss hier nochmal geprueft werden, ob sich die
+ // Breite tatsaechlich geaendert hat.
+ if( (ULONG)nOldWidth == nWidth )
+ return;
+
+ // soll die Aenderung sofort dargestellt werden?
+ BOOL bUpdate = GetUpdateMode() &&
+ ( pCols->GetObject(nItemPos)->IsFrozen() || nItemPos >= nFirstCol );
+
+ if ( bUpdate )
+ {
+ // Selection hiden
+ DoHideCursor( "SetColumnWidth" );
+ ToggleSelection();
+ //!((BrowserDataWin*)pDataWin)->Update();
+ //!Control::Update();
+ }
+
+ // Breite setzen
+ pCols->GetObject(nItemPos)->SetWidth(nWidth, GetZoom());
+#if 0
+ if ( nItemPos != pCols->Count() - 1 )
+ {
+ long nLastColMaxWidth = pDataWin->GetSizePixel().Width() -
+ GetFieldRect(GetColumnId(pCols->Count()-1)).Left();
+ pCols->GetObject(pCols->Count()-1)->Width() = nLastColMaxWidth;
+ }
+#endif
+
+ // scroll and invalidate
+ if ( bUpdate )
+ {
+ // X-Pos der veraenderten Spalte ermitteln
+ long nX = 0;
+ for ( USHORT nCol = 0; nCol < nItemPos; ++nCol )
+ {
+ BrowserColumn *pCol = pCols->GetObject(nCol);
+ if ( pCol->IsFrozen() || nCol >= nFirstCol )
+ nX += pCol->Width();
+ }
+
+ // eigentliches scroll+invalidate
+ pDataWin->SetClipRegion();
+ BOOL bSelVis = bSelectionIsVisible;
+ bSelectionIsVisible = FALSE;
+ if( GetBackground().IsScrollable() )
+ {
+
+ Rectangle aScrRect( nX + min( (ULONG)nOldWidth, nWidth ), 0,
+ GetSizePixel().Width() , // the header is longer than the datawin
+ pDataWin->GetPosPixel().Y() - 1 );
+ Control::Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
+ aScrRect.Bottom() = pDataWin->GetSizePixel().Height();
+ ((BrowserDataWin*)pDataWin)->Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
+ Rectangle aInvRect( nX, 0, nX + max( nWidth, (ULONG)nOldWidth ), USHRT_MAX );
+ Control::Invalidate( aInvRect );
+ ( (BrowserDataWin*)pDataWin )->Invalidate( aInvRect );
+ }
+ else
+ {
+ Control::Invalidate( INVALIDATE_NOCHILDREN );
+ ((BrowserDataWin*)pDataWin)->Window::Invalidate( INVALIDATE_NOCHILDREN );
+ }
+
+
+ //!((BrowserDataWin*)pDataWin)->Update();
+ //!Control::Update();
+ bSelectionIsVisible = bSelVis;
+ ToggleSelection();
+ DoShowCursor( "SetColumnWidth" );
+ }
+ UpdateScrollbars();
+
+ // Headerbar-Column anpassen
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->SetItemSize(
+ nItemId ? nItemId : USHRT_MAX - 1, nWidth );
+
+ // adjust last column
+ if ( nItemPos != pCols->Count() - 1 )
+ AutoSizeLastColumn();
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::AutoSizeLastColumn()
+{
+ if ( ((BrowserDataWin*)pDataWin)->bAutoSizeLastCol &&
+ ((BrowserDataWin*)pDataWin)->GetUpdateMode() )
+ {
+ USHORT nId = GetColumnId( (USHORT)pCols->Count() - 1 );
+ SetColumnWidth( nId, LONG_MAX );
+ ColumnResized( nId );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::RemoveColumn( USHORT nItemId )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // Spaltenposition ermitteln
+ USHORT nPos = GetColumnPos(nItemId);
+ if ( nPos >= ColCount() )
+ // nicht vorhanden
+ return;
+
+ // Spaltenselektion korrigieren
+ if ( pColSel )
+ pColSel->Remove( nPos );
+
+ // Spaltencursor korrigieren
+ if ( nCurColId == nItemId )
+ nCurColId = 0;
+
+ if ( nFirstCol >= nPos && nFirstCol > 0 )
+ --nFirstCol;
+
+ // Spalte entfernen
+ delete( pCols->Remove( (ULONG) nPos ));
+
+ // Handlecolumn nicht in der Headerbar
+ if (nItemId)
+ {
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->RemoveItem( nItemId );
+ }
+ else
+ {
+ // Headerbar anpassen
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ {
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->SetPosPixel(
+ Point(0, 0));
+
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->SetSizePixel(
+ Size( GetOutputSizePixel().Width(), GetTitleHeight() ) );
+ }
+ }
+
+ // vertikalen Scrollbar korrigieren
+ UpdateScrollbars();
+
+ // ggf. Repaint ausl"osen
+ if ( GetUpdateMode() )
+ {
+ ((BrowserDataWin*)pDataWin)->Invalidate();
+ Control::Invalidate();
+ if ( ((BrowserDataWin*)pDataWin)->bAutoSizeLastCol && nPos ==ColCount() )
+ SetColumnWidth( GetColumnId( nPos - 1 ), LONG_MAX );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::RemoveColumns()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // alle Spalten entfernen
+ while ( pCols->Count() )
+ delete ( pCols->Remove( (ULONG) 0 ));
+
+ // Spaltenselektion korrigieren
+ if ( pColSel )
+ {
+ pColSel->SelectAll(FALSE);
+ pColSel->SetTotalRange( Range( 0, 0 ) );
+ }
+
+ // Spaltencursor korrigieren
+ nCurColId = 0;
+ nFirstCol = 0;
+
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->Clear( );
+
+ // vertikalen Scrollbar korrigieren
+ UpdateScrollbars();
+
+ // ggf. Repaint ausl"osen
+ if ( GetUpdateMode() )
+ {
+ ((BrowserDataWin*)pDataWin)->Invalidate();
+ Control::Invalidate();
+ }
+}
+
+//-------------------------------------------------------------------
+
+String BrowseBox::GetColumnTitle( USHORT nId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ USHORT nItemPos = GetColumnPos( nId );
+ if ( nItemPos >= pCols->Count() )
+ return String();
+ return pCols->GetObject(nItemPos)->Title();
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::GetRowCount() const
+{
+ return nRowCount;
+}
+
+//-------------------------------------------------------------------
+
+USHORT BrowseBox::ColCount() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return (USHORT) pCols->Count();
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::ImpGetDataRowHeight() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ BrowseBox *pThis = (BrowseBox*)this;
+ pThis->nDataRowHeight = pThis->CalcReverseZoom(pDataWin->GetTextHeight() + 2);
+ pThis->Resize();
+ ((BrowserDataWin*)pDataWin)->Invalidate();
+ return nDataRowHeight;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetDataRowHeight( long nPixel )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ nDataRowHeight = CalcReverseZoom(nPixel);
+ Resize();
+ ((BrowserDataWin*)pDataWin)->Invalidate();
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetTitleLines( USHORT nLines )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ nTitleLines = nLines;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ToTop()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ToBottom()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::ScrollColumns( long nCols )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( nFirstCol + nCols < 0 ||
+ nFirstCol + nCols >= (long)pCols->Count() )
+ //?MI: pCols->GetObject( nFirstCol + nCols )->IsFrozen() )
+ return 0;
+
+ // implicitly hides cursor while scrolling
+ StartScroll();
+ bScrolling = TRUE;
+ BOOL bScrollable = pDataWin->GetBackground().IsScrollable();
+ BOOL bInvalidateView = FALSE;
+
+ // eine Spalte nach links scrollen?
+ if ( nCols == 1 )
+ {
+ // update internal value and scrollbar
+ ++nFirstCol;
+ aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
+
+ long nDelta = pCols->GetObject(nFirstCol-1)->Width();
+ long nFrozenWidth = GetFrozenWidth();
+
+ // scroll the title-line
+ Rectangle aScrollRect(
+ Point( nFrozenWidth + nDelta, 0 ),
+ Size( GetOutputSizePixel().Width() - nFrozenWidth - nDelta,
+ GetTitleHeight() - 1 ) );
+
+ // ggf. Headerbar mitscrollen
+ if ( !((BrowserDataWin*)pDataWin)->pHeaderBar && nTitleLines )
+ {
+ if( bScrollable )
+ Scroll( -nDelta, 0, aScrollRect );
+ else
+ bInvalidateView = TRUE;
+ }
+
+
+ long nSkippedWidth = GetOutputSizePixel().Width() -
+ 2 * aScrollRect.GetWidth() - nFrozenWidth;
+ if ( nSkippedWidth > 0 )
+ {
+ aScrollRect.Right() = aScrollRect.Left()-1;
+ aScrollRect.Left() -= nSkippedWidth;
+ Invalidate( aScrollRect );
+ }
+
+ // scroll the data-area
+ aScrollRect = Rectangle(
+ Point( nFrozenWidth + nDelta, 0 ),
+ Size( pDataWin->GetOutputSizePixel().Width() - nFrozenWidth -
+ nDelta, pDataWin->GetSizePixel().Height() ) );
+ if( bScrollable )
+ pDataWin->Scroll( -nDelta, 0, aScrollRect );
+ else
+ bInvalidateView = TRUE;
+ nSkippedWidth = pDataWin->GetOutputSizePixel().Width() -
+ 2 * aScrollRect.GetWidth() - nFrozenWidth;
+ if ( nSkippedWidth > 0 )
+ {
+ aScrollRect.Right() = aScrollRect.Left()-1;
+ aScrollRect.Left() -= nSkippedWidth;
+ ((BrowserDataWin*)pDataWin)->Invalidate( aScrollRect );
+ }
+ }
+
+ // eine Spalte nach rechts scrollen?
+ else if ( nCols == -1 )
+ {
+ --nFirstCol;
+ aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
+
+ long nDelta = pCols->GetObject(nFirstCol)->Width();
+ long nFrozenWidth = GetFrozenWidth();
+
+ // ggf. Headerbar mitscrollen
+ if ( !((BrowserDataWin*)pDataWin)->pHeaderBar && nTitleLines )
+ {
+ if( bScrollable )
+ {
+ Scroll( nDelta, 0, Rectangle(
+ Point( nFrozenWidth, 0 ),
+ Size( GetOutputSizePixel().Width() - nFrozenWidth,
+ GetTitleHeight() - 1 ) ) );
+ }
+ else
+ bInvalidateView = TRUE;
+ }
+ if( bScrollable )
+ {
+ pDataWin->Scroll( nDelta, 0, Rectangle(
+ Point( nFrozenWidth, 0 ),
+ Size( pDataWin->GetSizePixel().Width() - nFrozenWidth,
+ pDataWin->GetSizePixel().Height() ) ) );
+ }
+ else
+ bInvalidateView = TRUE;
+
+ }
+ else
+ {
+ if ( GetUpdateMode() )
+ {
+ Invalidate( Rectangle(
+ Point( GetFrozenWidth(), 0 ),
+ Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
+ ((BrowserDataWin*)pDataWin)->Invalidate( Rectangle(
+ Point( GetFrozenWidth(), 0 ),
+ pDataWin->GetSizePixel() ) );
+ }
+
+ nFirstCol += (USHORT)nCols;
+ aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
+ }
+
+ // ggf. externe Headerbar anpassen
+ if ( ((BrowserDataWin*)pDataWin)->pHeaderBar )
+ {
+ long nWidth = 0;
+ for ( USHORT nCol = 0;
+ nCol < pCols->Count() && nCol < nFirstCol;
+ ++nCol )
+ {
+ // HandleColumn nicht
+ if ( pCols->GetObject(nCol)->GetId() )
+ nWidth += pCols->GetObject(nCol)->Width();
+ }
+
+ ((BrowserDataWin*)pDataWin)->pHeaderBar->SetOffset( nWidth );
+ }
+
+ if( bInvalidateView )
+ {
+ Control::Invalidate( INVALIDATE_NOCHILDREN );
+ pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
+ }
+
+ // implicitly show cursor after scrolling
+ if ( nCols )
+ {
+ ((BrowserDataWin*)pDataWin)->Update();
+ Update();
+ }
+ bScrolling = FALSE;
+ EndScroll();
+
+ return nCols;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::ScrollRows( long nRows )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // out of range?
+ if ( ((BrowserDataWin*)pDataWin)->bNoScrollBack && nRows < 0 )
+ return 0;
+
+ // compute new top row
+ long nTmpMin = Min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
+
+ long nNewTopRow = Max( (long)nTmpMin, (long)0 );
+
+ if ( nNewTopRow == nTopRow )
+ return 0;
+
+ USHORT nVisibleRows =
+ (USHORT)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
+
+ VisibleRowsChanged(nNewTopRow, nVisibleRows);
+
+ // compute new top row again (nTopRow might have changed!)
+ nTmpMin = Min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
+
+ nNewTopRow = Max( (long)nTmpMin, (long)0 );
+
+ StartScroll();
+
+ // scroll area on screen and/or repaint
+ long nDeltaY = GetDataRowHeight() * ( nNewTopRow - nTopRow );
+ long nOldTopRow = nTopRow;
+ nTopRow = nNewTopRow;
+
+ if ( GetUpdateMode() )
+ {
+ pVScroll->SetRange( Range( 0L, nRowCount ) );
+ pVScroll->SetThumbPos( nTopRow );
+
+ if( pDataWin->GetBackground().IsScrollable() &&
+ Abs( nDeltaY ) > 0 &&
+ Abs( nDeltaY ) < pDataWin->GetSizePixel().Height() )
+ {
+ pDataWin->Scroll( 0, (short)-nDeltaY );
+ }
+ else
+ ((BrowserDataWin*)pDataWin)->Invalidate();
+
+ if ( nTopRow - nOldTopRow )
+ ((BrowserDataWin*)pDataWin)->Update();
+ }
+
+ EndScroll();
+
+ return nTopRow - nOldTopRow;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::ScrollPages( long nPagesY )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return ScrollRows( pDataWin->GetSizePixel().Height() / GetDataRowHeight() );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::RowModified( long nRow, USHORT nColId )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( !GetUpdateMode() )
+ return;
+
+ Rectangle aRect;
+ if ( nColId == USHRT_MAX )
+ // invalidate the whole row
+ aRect = Rectangle( Point( 0, (nRow-nTopRow) * GetDataRowHeight() ),
+ Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
+ else
+ {
+ // invalidate the specific field
+ aRect = GetFieldRectPixel( nRow, nColId, FALSE );
+ }
+ ((BrowserDataWin*)pDataWin)->Invalidate( aRect );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::Clear()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // adjust the total number of rows
+ DoHideCursor( "Clear" );
+ nRowCount = 0;
+ nCurRow = BROWSER_ENDOFSELECTION;
+ nTopRow = 0;
+ nCurColId = 0;
+
+ // nFirstCol darf nicht zurueckgesetzt werden, da ansonsten das Scrollen
+ // total durcheinander kommt
+ // nFirstCol darf nur beim Hinzufuegen oder Loeschen von Spalten geaendert werden
+ // nFirstCol = 0; ->Falsch!!!!
+ aHScroll.SetThumbPos( 0 );
+ pVScroll->SetThumbPos( 0 );
+
+ Invalidate();
+ UpdateScrollbars();
+ SetNoSelection();
+ DoShowCursor( "Clear" );
+ CursorMoved();
+}
+
+//-------------------------------------------------------------------
+#if SUPD > 511
+
+#else
+
+void BrowseBox::RowInserted( long nRow, long nNumRows, BOOL bDoPaint )
+{
+ RowInserted( nRow, nNumRows, bDoPaint, FALSE );
+}
+
+#endif
+
+void BrowseBox::RowInserted( long nRow, long nNumRows, BOOL bDoPaint, BOOL bKeepSelection )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if (nRow < 0)
+ nRow = 0;
+ else if (nRow > nRowCount) // maximal = nRowCount
+ nRow = nRowCount;
+
+ if ( nNumRows <= 0 )
+ return;
+
+#if 0
+ // Zerlegung in einzelne RowInserted-Aufrufe:
+ if (nNumRows > 1)
+ {
+ for (long i = 0; i < nNumRows; i++)
+ RowInserted(nRow + i,1,bDoPaint);
+ return;
+ }
+#endif
+
+ // adjust total row count
+ BOOL bLastRow = nRow >= nRowCount;
+ nRowCount += nNumRows;
+
+ DoHideCursor( "RowInserted" );
+
+ // must we paint the new rows?
+ long nOldCurRow = nCurRow;
+ Size aSz = pDataWin->GetOutputSizePixel();
+ if ( bDoPaint && nRow >= nTopRow &&
+ nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
+ {
+ long nY = (nRow-nTopRow) * GetDataRowHeight();
+ if ( !bLastRow )
+ {
+ // scroll down the rows behind the new row
+ pDataWin->SetClipRegion();
+ if( pDataWin->GetBackground().IsScrollable() )
+ {
+ pDataWin->Scroll( 0, GetDataRowHeight() * nNumRows,
+ Rectangle( Point( 0, nY ),
+ Size( aSz.Width(), aSz.Height() - nY ) ),
+ SCROLL_CLIP );
+ }
+ else
+ pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
+ }
+ else
+ // scroll would cause a repaint, so we must explicitly invalidate
+ pDataWin->Invalidate( Rectangle( Point( 0, nY ),
+ Size( aSz.Width(), nNumRows * GetDataRowHeight() ) ) );
+ }
+
+ // ggf. Top-Row korrigieren
+ if ( nRow < nTopRow )
+ nTopRow += nNumRows;
+
+ // adjust the selection
+ if ( bMultiSelection )
+ uRow.pSel->Insert( nRow, nNumRows );
+ else if ( uRow.nSel != BROWSER_ENDOFSELECTION && nRow <= uRow.nSel )
+ uRow.nSel += nNumRows;
+
+ // adjust the cursor
+ if ( nCurRow == BROWSER_ENDOFSELECTION )
+ GoToRow( 0, FALSE, bKeepSelection );
+ else if ( nRow <= nCurRow )
+ GoToRow( nCurRow += nNumRows, FALSE, bKeepSelection );
+
+ // adjust the vertical scrollbar
+ if ( bDoPaint )
+ {
+ UpdateScrollbars();
+ AutoSizeLastColumn();
+ }
+
+ DoShowCursor( "RowInserted" );
+ if ( nCurRow != nOldCurRow )
+ CursorMoved();
+
+ DBG_ASSERT(nRowCount > 0,"BrowseBox: nRowCount <= 0");
+ DBG_ASSERT(nCurRow >= 0,"BrowseBox: nCurRow < 0");
+ DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::RowRemoved( long nRow, long nNumRows, BOOL bDoPaint )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( nRow < 0 )
+ nRow = 0;
+ else if ( nRow >= nRowCount )
+ nRow = nRowCount - 1;
+
+ if ( nNumRows <= 0 )
+ return;
+
+ if ( nRowCount <= 0 )
+ return;
+
+ if ( bDoPaint )
+ {
+ // hide cursor and selection
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ ToggleSelection();
+ DoHideCursor( "RowRemoved" );
+ }
+
+ // adjust total row count
+ nRowCount -= nNumRows;
+ if (nRowCount < 0) nRowCount = 0;
+ long nOldCurRow = nCurRow;
+
+ // adjust the selection
+ if ( bMultiSelection )
+ // uRow.pSel->Remove( nRow, nNumRows );
+ for ( long i = 0; i < nNumRows; i++ )
+ uRow.pSel->Remove( nRow );
+ else if ( nRow < uRow.nSel && uRow.nSel >= nNumRows )
+ uRow.nSel -= nNumRows;
+ else if ( nRow <= uRow.nSel )
+ uRow.nSel = BROWSER_ENDOFSELECTION;
+
+ // adjust the cursor
+ if ( nRowCount == 0 ) // don't compare nRowCount with nNumRows as nNumRows already was subtracted from nRowCount
+ nCurRow = BROWSER_ENDOFSELECTION;
+ else if ( nRow < nCurRow )
+ {
+ nCurRow -= Min( nCurRow - nRow, nNumRows );
+ // with the above nCurRow points a) to the first row after the removed block or b) to the same line
+ // as before, but moved up nNumRows
+ // case a) needs an additional correction if the last n lines were deleted, as 'the first row after the
+ // removed block' is an invalid position then
+ // FS - 09/28/99 - 68429
+ if (nCurRow == nRowCount)
+ --nCurRow;
+ }
+ else if( nRow == nCurRow && nCurRow == nRowCount )
+ nCurRow = nRowCount-1;
+
+ // is the deleted row visible?
+ Size aSz = pDataWin->GetOutputSizePixel();
+ if ( nRow >= nTopRow &&
+ nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
+ {
+ if ( bDoPaint )
+ {
+ // scroll up the rows behind the deleted row
+ // if there are Rows behind
+ if (nRow < nRowCount)
+ {
+ long nY = (nRow-nTopRow) * GetDataRowHeight();
+ pDataWin->SetClipRegion();
+ if( pDataWin->GetBackground().IsScrollable() )
+ {
+ pDataWin->Scroll( 0, - (short) GetDataRowHeight() * nNumRows,
+ Rectangle( Point( 0, nY ), Size( aSz.Width(),
+ aSz.Height() - nY + nNumRows*GetDataRowHeight() ) ),
+ SCROLL_CLIP );
+ }
+ else
+ pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
+ }
+ else
+ {
+ // Repaint the Rect of the deleted row
+ Rectangle aRect(
+ Point( 0, (nRow-nTopRow)*GetDataRowHeight() ),
+ Size( pDataWin->GetSizePixel().Width(),
+ nNumRows * GetDataRowHeight() ) );
+ pDataWin->Invalidate( aRect );
+ }
+ }
+ }
+ // is the deleted row above of the visible area?
+ else if ( nRow < nTopRow )
+ nTopRow = nTopRow >= nNumRows ? nTopRow-nNumRows : 0;
+
+ if ( bDoPaint )
+ {
+ // reshow cursor and selection
+ ToggleSelection();
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+ DoShowCursor( "RowRemoved" );
+
+ // adjust the vertical scrollbar
+ UpdateScrollbars();
+ AutoSizeLastColumn();
+ }
+
+ if ( nOldCurRow != nCurRow )
+ CursorMoved();
+
+ DBG_ASSERT(nRowCount >= 0,"BrowseBox: nRowCount < 0");
+ DBG_ASSERT(nCurRow >= 0 || nRowCount == 0,"BrowseBox: nCurRow < 0 && nRowCount != 0");
+ DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::GoToRow( long nRow)
+{
+ return GoToRow(nRow, FALSE, FALSE);
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::GoToRowAndDoNotModifySelection( long nRow )
+{
+ return GoToRow( nRow, FALSE, TRUE );
+}
+
+//-------------------------------------------------------------------
+
+#if SUPD > 511
+
+#else
+BOOL BrowseBox::GoToRow( long nRow, BOOL bRowColMove )
+{
+ return GoToRow( nRow, bRowColMove, FALSE );
+}
+#endif
+
+BOOL BrowseBox::GoToRow( long nRow, BOOL bRowColMove, BOOL bKeepSelection )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ long nOldCurRow = nCurRow;
+
+ // nothing to do?
+ if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) )
+ return TRUE;
+
+ // out of range?
+ if ( nRow < 0 || nRow >= nRowCount )
+ return FALSE;
+
+ // nicht erlaubt?
+ if ( ( !bRowColMove && !IsCursorMoveAllowed( nRow, nCurColId ) ) )
+ return FALSE;
+
+ if ( ((BrowserDataWin*)pDataWin)->bNoScrollBack && nRow < nTopRow )
+ nRow = nTopRow;
+
+ // compute the last visible row
+ Size aSz( pDataWin->GetSizePixel() );
+ USHORT nVisibleRows = USHORT( aSz.Height() ) / GetDataRowHeight() - 1;
+ long nLastRow = nTopRow + nVisibleRows;
+
+ // suspend Updates
+ ((BrowserDataWin*)pDataWin)->EnterUpdateLock();
+
+ // ggf. altes Highlight weg
+ if ( !bMultiSelection && !bKeepSelection )
+ ToggleSelection();
+ DoHideCursor( "GoToRow" );
+
+ // must we scroll?
+ BOOL bWasVisible = bSelectionIsVisible;
+ if (! bMultiSelection)
+ {
+ if( !bKeepSelection )
+ bSelectionIsVisible = FALSE;
+ }
+ if ( nRow < nTopRow )
+ ScrollRows( nRow - nTopRow );
+ else if ( nRow > nLastRow )
+ ScrollRows( nRow - nLastRow );
+ bSelectionIsVisible = bWasVisible;
+
+ // adjust cursor (selection) and thumb
+ if ( GetUpdateMode() )
+ pVScroll->SetThumbPos( nTopRow );
+
+ // relative positioning (because nCurRow might have changed in the meantime)!
+ if (nCurRow != BROWSER_ENDOFSELECTION )
+ nCurRow = nCurRow + (nRow - nOldCurRow);
+
+ // make sure that the current position is valid
+ if (nCurRow == BROWSER_ENDOFSELECTION && nRowCount > 0)
+ nCurRow = 0;
+ else if ( nCurRow >= nRowCount )
+ nCurRow = nRowCount - 1;
+ aSelRange = Range( nCurRow, nCurRow );
+
+ // ggf. neues Highlight anzeigen
+ if ( !bMultiSelection && !bKeepSelection )
+ uRow.nSel = nRow;
+
+ // resume Updates
+ ((BrowserDataWin*)pDataWin)->LeaveUpdateLock();
+
+ // Cursor+Highlight
+ if ( !bMultiSelection && !bKeepSelection)
+ ToggleSelection();
+ DoShowCursor( "GoToRow" );
+ if ( !bRowColMove && nOldCurRow != nCurRow )
+ CursorMoved();
+
+ if ( !bMultiSelection && !bKeepSelection )
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+ return TRUE;
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::GoToColumnId( USHORT nColId)
+{
+ return GoToColumnId(nColId,TRUE,FALSE);
+}
+
+
+BOOL BrowseBox::GoToColumnId( USHORT nColId, BOOL bMakeVisible, BOOL bRowColMove)
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if (!bColumnCursor)
+ return FALSE;
+
+ // erlaubt?
+ if (!bRowColMove && !IsCursorMoveAllowed( nCurRow, nColId ) )
+ return FALSE;
+
+ if ( nColId != nCurColId || bMakeVisible && !IsFieldVisible(nCurRow, nColId, TRUE))
+ {
+ DoHideCursor( "GoToColumnId" );
+ nCurColId = nColId;
+
+ USHORT nNewPos = GetColumnPos(nColId);
+ DBG_ASSERT( nNewPos != USHRT_MAX, "unknown column-id" );
+ USHORT nFirstPos = nFirstCol;
+ USHORT nWidth = (USHORT)pCols->GetObject( nNewPos )->Width();
+ USHORT nLastPos = GetColumnAtXPosPixel(
+ pDataWin->GetSizePixel().Width()-nWidth, FALSE );
+ USHORT nFrozen = FrozenColCount();
+ if ( bMakeVisible && nLastPos &&
+ nNewPos >= nFrozen && ( nNewPos < nFirstPos || nNewPos > nLastPos ) )
+ if ( nNewPos < nFirstPos )
+ ScrollColumns( nNewPos-nFirstPos );
+ else if ( nNewPos > nLastPos )
+ ScrollColumns( nNewPos-nLastPos );
+
+ DoShowCursor( "GoToColumnId" );
+ if (!bRowColMove)
+ CursorMoved();
+ return TRUE;
+ }
+ return TRUE;
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::GoToRowColumnId( long nRow, USHORT nColId )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ long nOldCurRow = nCurRow;
+
+ // out of range?
+ if ( nRow < 0 || nRow >= nRowCount )
+ return FALSE;
+
+ if (!bColumnCursor)
+ return FALSE;
+
+ // nothing to do ?
+ if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) &&
+ nColId == nCurColId && IsFieldVisible(nCurRow, nColId, TRUE))
+ return TRUE;
+
+ // erlaubt?
+ if (!IsCursorMoveAllowed(nRow, nColId))
+ return FALSE;
+
+ DoHideCursor( "GoToRowColumnId" );
+ BOOL bMoved = GoToRow(nRow, TRUE) && GoToColumnId(nColId, TRUE, TRUE);
+ DoShowCursor( "GoToRowColumnId" );
+
+ if (bMoved)
+ CursorMoved();
+
+ return bMoved;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetNoSelection()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // is there no selection
+ if ( ( !pColSel || !pColSel->GetSelectCount() ) &&
+ ( ( !bMultiSelection && uRow.nSel == BROWSER_ENDOFSELECTION ) ||
+ ( bMultiSelection && !uRow.pSel->GetSelectCount() ) ) )
+ // nothing to do
+ return;
+
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ ToggleSelection();
+
+ // unselect all
+ if ( bMultiSelection )
+ uRow.pSel->SelectAll(FALSE);
+ else
+ uRow.nSel = BROWSER_ENDOFSELECTION;
+ if ( pColSel )
+ pColSel->SelectAll(FALSE);
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+
+ // restore screen
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetSelection( const MultiSelection &rSel )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+ DBG_ASSERT( bMultiSelection, "SetSelection only allowed with Multi-Selection-Mode" );
+
+ // prepare inverted areas
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ ToggleSelection();
+
+ // assign Selection
+ *uRow.pSel = rSel;
+
+ // only highlight painted areas
+ pDataWin->Update();
+
+ // notify derived class
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+
+ // restore screen
+ ToggleSelection();
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SelectAll()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( !bMultiSelection )
+ return;
+
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ ToggleSelection();
+
+ // select all rows
+ if ( pColSel )
+ pColSel->SelectAll(FALSE);
+ uRow.pSel->SelectAll(TRUE);
+
+ // Handle-Column nicht highlighten
+ BrowserColumn *pFirstCol = pCols->GetObject(0);
+ long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
+
+ // highlight the row selection
+ if ( !bHideSelect )
+ {
+ Rectangle aHighlightRect;
+ USHORT nVisibleRows =
+ (USHORT)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
+ for ( long nRow = Max( nTopRow, uRow.pSel->FirstSelected() );
+ nRow != BROWSER_ENDOFSELECTION && nRow < nTopRow + nVisibleRows;
+ nRow = uRow.pSel->NextSelected() )
+ aHighlightRect.Union( Rectangle(
+ Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
+ Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) ) );
+ pDataWin->Invalidate( aHighlightRect );
+ }
+
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+
+ // restore screen
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SelectRow( long nRow, BOOL bSelect, BOOL bExpand )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( !bMultiSelection )
+ {
+ // deselecting is impossible, selecting via cursor
+ if ( bSelect )
+ GoToRow(nRow, FALSE);
+ return;
+ }
+
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+
+ // remove old selection?
+ if ( !bExpand || !bMultiSelection )
+ {
+ ToggleSelection();
+ if ( bMultiSelection )
+ uRow.pSel->SelectAll(FALSE);
+ else
+ uRow.nSel = BROWSER_ENDOFSELECTION;
+ if ( pColSel )
+ pColSel->SelectAll(FALSE);
+ }
+
+ // set new selection
+ if ( !bHideSelect &&
+ ( (bMultiSelection && uRow.pSel->GetTotalRange().Max() >= nRow && uRow.pSel->Select(nRow,bSelect)) ||
+ (!bMultiSelection && ( uRow.nSel = nRow ) != BROWSER_ENDOFSELECTION ) ) )
+ {
+ // Handle-Column nicht highlighten
+ BrowserColumn *pFirstCol = pCols->GetObject(0);
+ long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
+
+ // highlight only newly selected part
+ Rectangle aRect(
+ Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
+ Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
+ pDataWin->Invalidate( aRect );
+ }
+
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+
+ // restore screen
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::GetSelectRowCount() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->GetSelectCount() :
+ uRow.nSel == BROWSER_ENDOFSELECTION ? 0 : 1;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SelectColumnPos( USHORT nNewColPos, BOOL bSelect, BOOL bMakeVisible )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( !bColumnCursor )
+ return;
+
+ if ( !bMultiSelection )
+ {
+ if ( bSelect )
+ GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
+ return;
+ }
+ else if (!GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible ))
+ return;
+
+ DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
+ ToggleSelection();
+ if ( bMultiSelection )
+ uRow.pSel->SelectAll(FALSE);
+ else
+ uRow.nSel = BROWSER_ENDOFSELECTION;
+ pColSel->SelectAll(FALSE);
+
+ if ( pColSel->Select( nNewColPos ) )
+ {
+ // GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
+
+ // only highlight painted areas
+ pDataWin->Update();
+ Rectangle aFieldRectPix( GetFieldRectPixel( nCurRow, nCurColId, FALSE ) );
+ Rectangle aRect(
+ Point( aFieldRectPix.Left() - MIN_COLUMNWIDTH, 0 ),
+ Size( pCols->GetObject(nNewColPos)->Width(),
+ pDataWin->GetOutputSizePixel().Height() ) );
+ pDataWin->Invalidate( aRect );
+ if ( !bSelecting )
+ Select();
+ else
+ bSelect = TRUE;
+ }
+
+ // restore screen
+ DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
+}
+
+//-------------------------------------------------------------------
+
+USHORT BrowseBox::GetSelectColumnCount() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // while bAutoSelect (==!pColSel), 1 if any rows (yes rows!) else none
+ return pColSel ? (USHORT) pColSel->GetSelectCount() :
+ nCurRow >= 0 ? 1 : 0;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::FirstSelectedRow( BOOL bInverse )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->FirstSelected(bInverse) : uRow.nSel;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::NextSelectedRow()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::PrevSelectedRow()
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->PrevSelected() : BROWSER_ENDOFSELECTION;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::LastSelectedRow( BOOL bInverse )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->LastSelected(bInverse) : uRow.nSel;
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::IsRowSelected( long nRow ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return bMultiSelection ? uRow.pSel->IsSelected(nRow) : nRow == uRow.nSel;
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::IsColumnSelected( USHORT nColumnId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return pColSel ? pColSel->IsSelected( GetColumnPos(nColumnId) ) :
+ nCurColId == nColumnId;
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::MakeFieldVisible
+(
+ long nRow, // Zeilen-Nr des Feldes (beginnend mit 0)
+ USHORT nColId, // Spalten-Id des Feldes
+ BOOL bComplete // (== FALSE), TRUE => vollst"andig sichtbar machen
+)
+
+/* [Beschreibung]
+
+ Macht das durch 'nRow' und 'nColId' beschriebene Feld durch
+ entsprechendes scrollen sichtbar. Ist 'bComplete' gesetzt, dann wird
+ gefordert, da\s das Feld ganz sichtbar wird.
+
+ [R"uckgabewert]
+
+ BOOL TRUE
+ Das angegebene Feld wurde sichtbar gemacht, bzw. war
+ bereits sichtbar.
+
+ FALSE
+ Das angegebene Feld konnte nicht sichtbar bzw. bei
+ 'bComplete' nicht vollst"andig sichtbar gemacht werden.
+*/
+
+{
+ Size aTestSize = pDataWin->GetSizePixel();
+
+ if ( !bBootstrapped ||
+ ( aTestSize.Width() == 0 && aTestSize.Height() == 0 ) )
+ return FALSE;
+
+ // ist es schon sichtbar?
+ BOOL bVisible = IsFieldVisible( nRow, nColId, bComplete );
+ if ( bVisible )
+ return TRUE;
+
+ // Spaltenposition und Feld-Rechteck und Ausgabebereich berechnen
+ USHORT nColPos = GetColumnPos( nColId );
+ Rectangle aFieldRect = GetFieldRectPixel( nRow, nColId, FALSE );
+ Rectangle aDataRect = Rectangle( Point(0, 0), pDataWin->GetSizePixel() );
+
+ // links au\serhalb?
+ if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
+ // => nach rechts scrollen
+ ScrollColumns( nColPos - nFirstCol );
+
+ // solange rechts au\serhalb
+ while ( aDataRect.Right() < ( bComplete
+ ? aFieldRect.Right()
+ : aFieldRect.Left()+aFieldRect.GetWidth()/2 ) )
+ {
+ // => nach links scrollen
+ if ( ScrollColumns( 1 ) != 1 )
+ // nichts mehr zu scrollen
+ break;
+ aFieldRect = GetFieldRectPixel( nRow, nColId, FALSE );
+ }
+
+ // oben au\serhalb?
+ if ( nRow < nTopRow )
+ // nach unten scrollen
+ ScrollRows( nRow - nTopRow );
+
+ // unten au\serhalb?
+ long nBottomRow = nTopRow + GetVisibleRows();
+ // OV: damit nBottomRow die Nummer der letzten sichtbaren Zeile ist
+ // (Zaehlung ab Null!), muss sie dekrementiert werden.
+ // Beispiel: BrowseBox enthaelt genau einen Eintrag. nBottomRow := 0 + 1 - 1
+ if( nBottomRow )
+ nBottomRow--;
+
+ if ( nRow > nBottomRow )
+ // nach oben scrollen
+ ScrollRows( nRow - nBottomRow );
+
+ // jetzt kann es immer noch nicht passen, z.B. weil Window zu klein
+ return IsFieldVisible( nRow, nColId, bComplete );
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::IsFieldVisible( long nRow, USHORT nColumnId,
+ BOOL bCompletely ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // durch frozen-Column verdeckt?
+ USHORT nColPos = GetColumnPos( nColumnId );
+ if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
+ return FALSE;
+
+ Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
+ if ( aRect.IsEmpty() )
+ return FALSE;
+
+ // get the visible area
+ Rectangle aOutRect( Point(0, 0), pDataWin->GetOutputSizePixel() );
+
+ if ( bCompletely )
+ // test if the field is completely visible
+ return aOutRect.IsInside( aRect );
+ else
+ // test if the field is partly of completely visible
+ return !aOutRect.Intersection( aRect ).IsEmpty();
+}
+
+//-------------------------------------------------------------------
+
+Rectangle BrowseBox::GetFieldRectPixel( long nRow, USHORT nColumnId,
+ BOOL bRelToBrowser ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // get the rectangle relative to DataWin
+ Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
+ if ( aRect.IsEmpty() )
+ return aRect;
+
+ // adjust relative to BrowseBox's output area
+ Point aTopLeft( aRect.TopLeft() );
+ if ( bRelToBrowser )
+ {
+ aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
+ aTopLeft = ScreenToOutputPixel( aTopLeft );
+ }
+
+ return Rectangle( aTopLeft, aRect.GetSize() );
+}
+
+//-------------------------------------------------------------------
+
+Rectangle BrowseBox::GetRowRectPixel( long nRow, BOOL bRelToBrowser ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // get the rectangle relative to DataWin
+ Rectangle aRect;
+ if ( nTopRow > nRow )
+ // row is above visible area
+ return aRect;
+ aRect = Rectangle(
+ Point( 0, GetDataRowHeight() * (nRow-nTopRow) ),
+ Size( pDataWin->GetOutputSizePixel().Width(), GetDataRowHeight() ) );
+ if ( aRect.TopLeft().Y() > pDataWin->GetOutputSizePixel().Height() )
+ // row is below visible area
+ return aRect;
+
+ // adjust relative to BrowseBox's output area
+ Point aTopLeft( aRect.TopLeft() );
+ if ( bRelToBrowser )
+ {
+ aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
+ aTopLeft = ScreenToOutputPixel( aTopLeft );
+ }
+
+ return Rectangle( aTopLeft, aRect.GetSize() );
+}
+
+//-------------------------------------------------------------------
+
+Rectangle BrowseBox::ImplFieldRectPixel( long nRow, USHORT nColumnId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // compute the X-coordinte realtiv to DataWin by accumulation
+ long nColX = 0;
+ USHORT nFrozenCols = FrozenColCount();
+ USHORT nCol;
+ for ( nCol = 0;
+ nCol < pCols->Count() && pCols->GetObject(nCol)->GetId() != nColumnId;
+ ++nCol )
+ if ( pCols->GetObject(nCol)->IsFrozen() || nCol >= nFirstCol )
+ nColX += pCols->GetObject(nCol)->Width();
+
+ if ( nCol >= pCols->Count() || ( nCol >= nFrozenCols && nCol < nFirstCol ) )
+ return Rectangle();
+
+ // compute the Y-coordinate relative to DataWin
+ long nRowY = ( nRow - nTopRow ) * GetDataRowHeight();
+
+ // assemble the Rectangle relative to DataWin
+ return Rectangle(
+ Point( nColX + MIN_COLUMNWIDTH, nRowY ),
+ Size( pCols->GetObject(nCol)->Width() - 2*MIN_COLUMNWIDTH,
+ GetDataRowHeight() - 1 ) );
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::GetRowAtYPosPixel( long nY, BOOL bRelToBrowser ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // compute the Y-coord
+ if ( bRelToBrowser )
+ {
+ Point aDataTopLeft = pDataWin->OutputToScreenPixel( Point(0, 0) );
+ Point aTopLeft = OutputToScreenPixel( Point(0, 0) );
+ nY -= aDataTopLeft.Y() - aTopLeft.Y();
+ }
+
+ // no row there (e.g. in the header)
+ if ( nY < 0 || nY >= pDataWin->GetOutputSizePixel().Height() )
+ return -1;
+
+ return nY / GetDataRowHeight() + nTopRow;
+}
+
+//-------------------------------------------------------------------
+
+Rectangle BrowseBox::GetFieldRect( USHORT nColumnId ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return GetFieldRectPixel( nCurRow, nColumnId );
+}
+
+//-------------------------------------------------------------------
+
+USHORT BrowseBox::GetColumnAtXPosPixel( long nX, BOOL ) const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // accumulate the withds of the visible columns
+ long nColX = 0;
+ USHORT nCol;
+ for ( nCol = 0; nCol < USHORT(pCols->Count()); ++nCol )
+ {
+ BrowserColumn *pCol = pCols->GetObject(nCol);
+ if ( pCol->IsFrozen() || nCol >= nFirstCol )
+ nColX += pCol->Width();
+
+ if ( nColX > nX )
+ return nCol;
+ }
+
+ return BROWSER_INVALIDID;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::ReserveControlArea( USHORT nWidth )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ if ( nWidth != nControlAreaWidth )
+ {
+ nControlAreaWidth = nWidth;
+ UpdateScrollbars();
+ }
+}
+
+//-------------------------------------------------------------------
+
+Rectangle BrowseBox::GetControlArea() const
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ return Rectangle(
+ Point( 0, GetOutputSizePixel().Height() - aHScroll.GetSizePixel().Height() ),
+ Size( GetOutputSizePixel().Width() - aHScroll.GetSizePixel().Width(),
+ aHScroll.GetSizePixel().Height() ) );
+}
+
+#if SUPD<558
+//-------------------------------------------------------------------
+
+BrowserMode BrowseBox::GetMode( ) const
+{
+ return m_nCurrentMode;
+}
+#endif
+
+//-------------------------------------------------------------------
+
+void BrowseBox::SetMode( BrowserMode nMode )
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+#ifdef DBG_MIx
+ Sound::Beep();
+ nMode =
+// BROWSER_COLUMNSELECTION |
+// BROWSER_MULTISELECTION |
+ BROWSER_THUMBDRAGGING |
+ BROWSER_KEEPHIGHLIGHT |
+ BROWSER_HLINES |
+ BROWSER_VLINES |
+// BROWSER_HIDECURSOR |
+// BROWSER_NO_HSCROLL |
+// BROWSER_NO_SCROLLBACK |
+ BROWSER_AUTO_VSCROLL |
+ BROWSER_AUTO_HSCROLL |
+ BROWSER_TRACKING_TIPS |
+// BROWSER_HIGHLIGHT_NONE |
+ BROWSER_HIGHLIGHT_AUTO |
+// BROWSER_HIGHLIGHT_MANU |
+ BROWSER_HEADERBAR_NEW |
+// BROWSER_AUTOSIZE_LASTCOL |
+ 0;
+#endif
+
+ ((BrowserDataWin*)pDataWin)->bAutoHScroll =
+ BROWSER_AUTO_HSCROLL == ( nMode & BROWSER_AUTO_HSCROLL);
+ ((BrowserDataWin*)pDataWin)->bAutoVScroll =
+ BROWSER_AUTO_VSCROLL == ( nMode & BROWSER_AUTO_VSCROLL);
+
+ ((BrowserDataWin*)pDataWin)->bNoHScroll =
+ BROWSER_NO_HSCROLL == ( nMode & BROWSER_NO_HSCROLL);
+ if ( ((BrowserDataWin*)pDataWin)->bNoHScroll )
+ {
+ aHScroll.Hide();
+ nControlAreaWidth = 0;
+ }
+ else
+ nControlAreaWidth = USHRT_MAX;
+
+ ((BrowserDataWin*)pDataWin)->bNoScrollBack =
+ BROWSER_NO_SCROLLBACK == ( nMode & BROWSER_NO_SCROLLBACK);
+
+ long nOldRowSel = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel;
+ MultiSelection *pOldRowSel = bMultiSelection ? uRow.pSel : 0;
+ MultiSelection *pOldColSel = pColSel;
+
+ delete pVScroll;
+
+ bThumbDragging = ( nMode & BROWSER_THUMBDRAGGING ) == BROWSER_THUMBDRAGGING;
+ bMultiSelection = ( nMode & BROWSER_MULTISELECTION ) == BROWSER_MULTISELECTION;
+ bColumnCursor = ( nMode & BROWSER_COLUMNSELECTION ) == BROWSER_COLUMNSELECTION;
+ bKeepHighlight = ( nMode & BROWSER_KEEPSELECTION ) == BROWSER_KEEPSELECTION;
+
+ bHideSelect = ((nMode & BROWSER_HIDESELECT) == BROWSER_HIDESELECT);
+ bHideCursor = ((nMode & BROWSER_HIDECURSOR) == BROWSER_HIDECURSOR);
+ m_bFocusOnlyCursor = ((nMode & BROWSER_CURSOR_WO_FOCUS) == 0);
+
+ bHLines = ( nMode & BROWSER_HLINESFULL ) == BROWSER_HLINESFULL;
+ bVLines = ( nMode & BROWSER_VLINESFULL ) == BROWSER_VLINESFULL;
+ bHDots = ( nMode & BROWSER_HLINESDOTS ) == BROWSER_HLINESDOTS;
+ bVDots = ( nMode & BROWSER_VLINESDOTS ) == BROWSER_VLINESDOTS;
+
+ WinBits nVScrollWinBits =
+ WB_VSCROLL | ( ( nMode & BROWSER_THUMBDRAGGING ) ? WB_DRAG : 0 );
+ pVScroll = ( nMode & BROWSER_TRACKING_TIPS ) == BROWSER_TRACKING_TIPS
+ ? new BrowserScrollBar( this, nVScrollWinBits,
+ (BrowserDataWin*) pDataWin )
+ : new ScrollBar( this, nVScrollWinBits );
+ pVScroll->SetLineSize( 1 );
+ pVScroll->SetPageSize(1);
+ pVScroll->SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
+ pVScroll->SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
+
+ ((BrowserDataWin*)pDataWin)->bHighlightAuto =
+ BROWSER_HIGHLIGHT_AUTO == ( nMode & BROWSER_HIGHLIGHT_AUTO ) ||
+ BROWSER_HIGHLIGHT_MANU != ( nMode & BROWSER_HIGHLIGHT_MANU );
+ ((BrowserDataWin*)pDataWin)->bAutoSizeLastCol =
+ BROWSER_AUTOSIZE_LASTCOL == ( nMode & BROWSER_AUTOSIZE_LASTCOL );
+ ((BrowserDataWin*)pDataWin)->bOwnDataChangedHdl =
+ BROWSER_OWN_DATACHANGED == ( nMode & BROWSER_OWN_DATACHANGED );
+
+ // Headerbar erzeugen, was passiert, wenn eine erzeugt werden muß und schon Spalten bestehen ?
+ if ( BROWSER_HEADERBAR_NEW == ( nMode & BROWSER_HEADERBAR_NEW ) )
+ {
+ if (!((BrowserDataWin*)pDataWin)->pHeaderBar)
+ ((BrowserDataWin*)pDataWin)->pHeaderBar = CreateHeaderBar( this );
+ }
+ else
+ {
+ DELETEZ(((BrowserDataWin*)pDataWin)->pHeaderBar);
+ }
+
+
+
+ if ( bColumnCursor )
+ {
+ pColSel = pOldColSel ? pOldColSel : new MultiSelection;
+ pColSel->SetTotalRange( Range( 0, pCols->Count()-1 ) );
+ }
+ else
+ {
+ pColSel = 0;
+ delete pColSel;
+ }
+
+ if ( bMultiSelection )
+ {
+ if ( pOldRowSel )
+ uRow.pSel = pOldRowSel;
+ else
+ uRow.pSel = new MultiSelection;
+ }
+ else
+ {
+ uRow.nSel = nOldRowSel;
+ delete pOldRowSel;
+ }
+
+ if ( bBootstrapped )
+ {
+ StateChanged( STATE_CHANGE_INITSHOW );
+ if ( bMultiSelection && !pOldRowSel &&
+ nOldRowSel != BROWSER_ENDOFSELECTION )
+ uRow.pSel->Select( nOldRowSel );
+ }
+
+ if ( pDataWin )
+ pDataWin->Invalidate();
+
+ // kein Cursor auf Handle-Column
+ if ( nCurColId == 0 )
+ nCurColId = GetColumnId( 1 );
+
+ m_nCurrentMode = nMode;
+}
+
+//-------------------------------------------------------------------
+
+void BrowseBox::VisibleRowsChanged( long nNewTopRow, USHORT nNumRows)
+{
+ DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
+
+ // Das alte Verhalten: NumRows automatisch korrigieren:
+ if ( nRowCount < GetRowCount() )
+ {
+ RowInserted(nRowCount,GetRowCount() - nRowCount,FALSE);
+ }
+ else if ( nRowCount > GetRowCount() )
+ {
+ RowRemoved(nRowCount-(nRowCount - GetRowCount()),nRowCount - GetRowCount(),FALSE);
+ }
+}
+
+//-------------------------------------------------------------------
+
+BOOL BrowseBox::IsCursorMoveAllowed( long nNewRow, USHORT nNewColId ) const
+
+/* [Beschreibung]
+
+ Diese virtuelle Methode wird immer gerufen bevor der Cursor direkt
+ bewegt werden soll. Durch 'return FALSE' kann verhindert werden, da\s
+ dies geschieht, wenn z.B. ein Datensatz irgendwelchen Rules widerspricht.
+
+ Diese Methode wird nicht gerufen, wenn die Cursorbewegung durch
+ ein L"oschen oder Einf"ugen (einer Zeile/Spalte) ausgel"ost wird, also
+ genaugenommen nur eine Cursor-Korrektur vorliegt.
+
+ Die Basisimplementierung liefert derzeit immer TRUE.
+*/
+
+{
+ return TRUE;
+}
+
+//-------------------------------------------------------------------
+
+long BrowseBox::GetDataRowHeight() const
+{
+ return CalcZoom(nDataRowHeight ? nDataRowHeight : ImpGetDataRowHeight());
+}
+
+//-------------------------------------------------------------------
+
+Window& BrowseBox::GetEventWindow() const
+{
+ return *((BrowserDataWin*)pDataWin)->pEventWin;
+}
+
+//-------------------------------------------------------------------
+
+#if SUPD >= 376
+
+BrowserHeader* BrowseBox::CreateHeaderBar( BrowseBox* pParent )
+{
+ BrowserHeader* pNewBar = new BrowserHeader( pParent );
+ pNewBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
+ return pNewBar;
+}
+
+void BrowseBox::SetHeaderBar( BrowserHeader* pHeaderBar )
+{
+ delete ( (BrowserDataWin*)pDataWin )->pHeaderBar;
+ ( (BrowserDataWin*)pDataWin )->pHeaderBar = pHeaderBar;
+ ( (BrowserDataWin*)pDataWin )->pHeaderBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
+}
+
+#endif
+
+//-------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+const char* BrowseBoxCheckInvariants( const void * pVoid )
+{
+ const BrowseBox * p = (const BrowseBox *)pVoid;
+
+ if (p->nRowCount < 0) return "BrowseBox: nRowCount < 0";
+ if (p->nTopRow < 0) return "BrowseBox: nTopRow < 0";
+ if (p->nTopRow >= p->nRowCount && p->nRowCount != 0) return "BrowseBox: nTopRow >= nRowCount && nRowCount != 0";
+ if (p->nCurRow < -1) return "BrowseBox: nCurRow < -1";
+ if (p->nCurRow > p->nRowCount) return "BrowseBox: nCurRow > nRowCount";
+
+ // Leider waehrend der Bearbeitung nicht immer der Fall:
+ //if (p->nCurRow < 0 && p->nRowCount != 0) return "nCurRow < 0 && nRowCount != 0";
+ //if (p->nCurRow >= p->nRowCount && p->nRowCount != 0) return "nCurRow >= nRowCount && nRowCount != 0";
+
+ return NULL;
+}
+#endif
+
+//-------------------------------------------------------------------
+long BrowseBox::GetTitleHeight() const
+{
+ long nHeight;
+ // ask the header bar for the text height (if possible), as the header bar's font is adjusted with
+ // our (and the header's) zoom factor
+ HeaderBar* pHeaderBar = ( (BrowserDataWin*)pDataWin )->pHeaderBar;
+ if ( pHeaderBar )
+ nHeight = pHeaderBar->GetTextHeight();
+ else
+ nHeight = GetTextHeight();
+
+ return nTitleLines ? nTitleLines * nHeight + 4 : 0;
+}
+
+//-------------------------------------------------------------------
+long BrowseBox::CalcReverseZoom(long nVal)
+{
+ if (IsZoom())
+ {
+ const Fraction& rZoom = GetZoom();
+ double n = (double)nVal;
+ n *= (double)rZoom.GetDenominator();
+ n /= (double)rZoom.GetNumerator();
+ nVal = n>0 ? (long)(n + 0.5) : -(long)(-n + 0.5);
+ }
+
+ return nVal;
+}
+
+//-------------------------------------------------------------------
+HeaderBar* BrowseBox::GetHeaderBar() const
+{
+ return ((BrowserDataWin*)pDataWin)->pHeaderBar;
+}
+
+